metaharness 0.1.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.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/analyze-repo.d.ts +74 -0
- package/dist/analyze-repo.d.ts.map +1 -0
- package/dist/analyze-repo.js +329 -0
- package/dist/analyze-repo.js.map +1 -0
- package/dist/audit-cmd.d.ts +6 -0
- package/dist/audit-cmd.d.ts.map +1 -0
- package/dist/audit-cmd.js +139 -0
- package/dist/audit-cmd.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +8 -0
- package/dist/bin.js.map +1 -0
- package/dist/compare-cmd.d.ts +56 -0
- package/dist/compare-cmd.d.ts.map +1 -0
- package/dist/compare-cmd.js +173 -0
- package/dist/compare-cmd.js.map +1 -0
- package/dist/completions-cmd.d.ts +6 -0
- package/dist/completions-cmd.d.ts.map +1 -0
- package/dist/completions-cmd.js +171 -0
- package/dist/completions-cmd.js.map +1 -0
- package/dist/diag.d.ts +76 -0
- package/dist/diag.d.ts.map +1 -0
- package/dist/diag.js +349 -0
- package/dist/diag.js.map +1 -0
- package/dist/eject.d.ts +33 -0
- package/dist/eject.d.ts.map +1 -0
- package/dist/eject.js +147 -0
- package/dist/eject.js.map +1 -0
- package/dist/export-config.d.ts +25 -0
- package/dist/export-config.d.ts.map +1 -0
- package/dist/export-config.js +134 -0
- package/dist/export-config.js.map +1 -0
- package/dist/external-template.d.ts +19 -0
- package/dist/external-template.d.ts.map +1 -0
- package/dist/external-template.js +37 -0
- package/dist/external-template.js.map +1 -0
- package/dist/federate.d.ts +37 -0
- package/dist/federate.d.ts.map +1 -0
- package/dist/federate.js +167 -0
- package/dist/federate.js.map +1 -0
- package/dist/genome-scorers.d.ts +33 -0
- package/dist/genome-scorers.d.ts.map +1 -0
- package/dist/genome-scorers.js +115 -0
- package/dist/genome-scorers.js.map +1 -0
- package/dist/genome.d.ts +28 -0
- package/dist/genome.d.ts.map +1 -0
- package/dist/genome.js +219 -0
- package/dist/genome.js.map +1 -0
- package/dist/harness-bin.d.ts +3 -0
- package/dist/harness-bin.d.ts.map +1 -0
- package/dist/harness-bin.js +17 -0
- package/dist/harness-bin.js.map +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +409 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +55 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +62 -0
- package/dist/manifest.js.map +1 -0
- package/dist/mcp-cmd.d.ts +19 -0
- package/dist/mcp-cmd.d.ts.map +1 -0
- package/dist/mcp-cmd.js +179 -0
- package/dist/mcp-cmd.js.map +1 -0
- package/dist/mcp-scan.d.ts +25 -0
- package/dist/mcp-scan.d.ts.map +1 -0
- package/dist/mcp-scan.js +132 -0
- package/dist/mcp-scan.js.map +1 -0
- package/dist/oia-manifest.d.ts +97 -0
- package/dist/oia-manifest.d.ts.map +1 -0
- package/dist/oia-manifest.js +241 -0
- package/dist/oia-manifest.js.map +1 -0
- package/dist/publish-cmd.d.ts +9 -0
- package/dist/publish-cmd.d.ts.map +1 -0
- package/dist/publish-cmd.js +56 -0
- package/dist/publish-cmd.js.map +1 -0
- package/dist/publish.d.ts +55 -0
- package/dist/publish.d.ts.map +1 -0
- package/dist/publish.js +104 -0
- package/dist/publish.js.map +1 -0
- package/dist/registry.d.ts +60 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +67 -0
- package/dist/registry.js.map +1 -0
- package/dist/rename.d.ts +26 -0
- package/dist/rename.d.ts.map +1 -0
- package/dist/rename.js +86 -0
- package/dist/rename.js.map +1 -0
- package/dist/renderer.d.ts +39 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +75 -0
- package/dist/renderer.js.map +1 -0
- package/dist/sbom-cmd.d.ts +6 -0
- package/dist/sbom-cmd.d.ts.map +1 -0
- package/dist/sbom-cmd.js +125 -0
- package/dist/sbom-cmd.js.map +1 -0
- package/dist/score.d.ts +32 -0
- package/dist/score.d.ts.map +1 -0
- package/dist/score.js +381 -0
- package/dist/score.js.map +1 -0
- package/dist/secrets.d.ts +27 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +228 -0
- package/dist/secrets.js.map +1 -0
- package/dist/subcommands.d.ts +32 -0
- package/dist/subcommands.d.ts.map +1 -0
- package/dist/subcommands.js +335 -0
- package/dist/subcommands.js.map +1 -0
- package/dist/tarball.d.ts +14 -0
- package/dist/tarball.d.ts.map +1 -0
- package/dist/tarball.js +121 -0
- package/dist/tarball.js.map +1 -0
- package/dist/threat-model.d.ts +32 -0
- package/dist/threat-model.d.ts.map +1 -0
- package/dist/threat-model.js +236 -0
- package/dist/threat-model.js.map +1 -0
- package/dist/upgrade-cmd.d.ts +9 -0
- package/dist/upgrade-cmd.d.ts.map +1 -0
- package/dist/upgrade-cmd.js +90 -0
- package/dist/upgrade-cmd.js.map +1 -0
- package/dist/upgrade.d.ts +37 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +124 -0
- package/dist/upgrade.js.map +1 -0
- package/dist/validate.d.ts +7 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +240 -0
- package/dist/validate.js.map +1 -0
- package/dist/walker.d.ts +24 -0
- package/dist/walker.d.ts.map +1 -0
- package/dist/walker.js +76 -0
- package/dist/walker.js.map +1 -0
- package/dist/witness-client.d.ts +40 -0
- package/dist/witness-client.d.ts.map +1 -0
- package/dist/witness-client.js +99 -0
- package/dist/witness-client.js.map +1 -0
- package/dist/wizard.d.ts +37 -0
- package/dist/wizard.d.ts.map +1 -0
- package/dist/wizard.js +137 -0
- package/dist/wizard.js.map +1 -0
- package/dist/writer.d.ts +13 -0
- package/dist/writer.d.ts.map +1 -0
- package/dist/writer.js +43 -0
- package/dist/writer.js.map +1 -0
- package/package.json +114 -0
- package/templates/catalog.def.mjs +542 -0
- package/templates/catalog.json +1274 -0
- package/templates/minimal/.claude/settings.json.tmpl +18 -0
- package/templates/minimal/CLAUDE.md.tmpl +23 -0
- package/templates/minimal/README.md.tmpl +20 -0
- package/templates/minimal/manifest.json +16 -0
- package/templates/minimal/package.json.tmpl +30 -0
- package/templates/minimal/src/init.ts.tmpl +21 -0
- package/templates/vertical_advertising/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_advertising/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_advertising/.claude/skills/media-plan/SKILL.md.tmpl +13 -0
- package/templates/vertical_advertising/CLAUDE.md.tmpl +30 -0
- package/templates/vertical_advertising/README.md.tmpl +29 -0
- package/templates/vertical_advertising/manifest.json +81 -0
- package/templates/vertical_advertising/package.json.tmpl +30 -0
- package/templates/vertical_advertising/src/agents/copywriter.ts.tmpl +7 -0
- package/templates/vertical_advertising/src/agents/media-planner.ts.tmpl +7 -0
- package/templates/vertical_advertising/src/agents/performance-analyst.ts.tmpl +7 -0
- package/templates/vertical_advertising/src/init.ts.tmpl +21 -0
- package/templates/vertical_agentics/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_agentics/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_agentics/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_agentics/.claude/skills/run-swarm/SKILL.md.tmpl +14 -0
- package/templates/vertical_agentics/CLAUDE.md.tmpl +32 -0
- package/templates/vertical_agentics/README.md.tmpl +30 -0
- package/templates/vertical_agentics/manifest.json +91 -0
- package/templates/vertical_agentics/package.json.tmpl +30 -0
- package/templates/vertical_agentics/src/agents/critic.ts.tmpl +7 -0
- package/templates/vertical_agentics/src/agents/orchestrator.ts.tmpl +7 -0
- package/templates/vertical_agentics/src/agents/planner.ts.tmpl +7 -0
- package/templates/vertical_agentics/src/agents/worker.ts.tmpl +7 -0
- package/templates/vertical_agentics/src/init.ts.tmpl +21 -0
- package/templates/vertical_ai/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_ai/.claude/settings.json.tmpl +35 -0
- package/templates/vertical_ai/.claude/skills/eval-report/SKILL.md.tmpl +13 -0
- package/templates/vertical_ai/CLAUDE.md.tmpl +31 -0
- package/templates/vertical_ai/README.md.tmpl +30 -0
- package/templates/vertical_ai/manifest.json +86 -0
- package/templates/vertical_ai/package.json.tmpl +30 -0
- package/templates/vertical_ai/src/agents/data-curator.ts.tmpl +7 -0
- package/templates/vertical_ai/src/agents/deployer.ts.tmpl +7 -0
- package/templates/vertical_ai/src/agents/evaluator.ts.tmpl +7 -0
- package/templates/vertical_ai/src/agents/trainer.ts.tmpl +7 -0
- package/templates/vertical_ai/src/init.ts.tmpl +21 -0
- package/templates/vertical_business/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_business/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_business/.claude/skills/quarterly-plan/SKILL.md.tmpl +13 -0
- package/templates/vertical_business/CLAUDE.md.tmpl +30 -0
- package/templates/vertical_business/README.md.tmpl +29 -0
- package/templates/vertical_business/manifest.json +81 -0
- package/templates/vertical_business/package.json.tmpl +30 -0
- package/templates/vertical_business/src/agents/analyst.ts.tmpl +7 -0
- package/templates/vertical_business/src/agents/ops-coordinator.ts.tmpl +7 -0
- package/templates/vertical_business/src/agents/strategist.ts.tmpl +7 -0
- package/templates/vertical_business/src/init.ts.tmpl +21 -0
- package/templates/vertical_coding/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_coding/.claude/commands/review-diff.md.tmpl +10 -0
- package/templates/vertical_coding/.claude/settings.json.tmpl +40 -0
- package/templates/vertical_coding/.claude/skills/plan-change/SKILL.md.tmpl +15 -0
- package/templates/vertical_coding/CLAUDE.md.tmpl +32 -0
- package/templates/vertical_coding/README.md.tmpl +30 -0
- package/templates/vertical_coding/manifest.json +91 -0
- package/templates/vertical_coding/package.json.tmpl +30 -0
- package/templates/vertical_coding/src/agents/architect.ts.tmpl +7 -0
- package/templates/vertical_coding/src/agents/implementer.ts.tmpl +7 -0
- package/templates/vertical_coding/src/agents/reviewer.ts.tmpl +7 -0
- package/templates/vertical_coding/src/agents/test-writer.ts.tmpl +7 -0
- package/templates/vertical_coding/src/init.ts.tmpl +21 -0
- package/templates/vertical_crm/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_crm/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_crm/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_crm/CLAUDE.md.tmpl +30 -0
- package/templates/vertical_crm/README.md.tmpl +29 -0
- package/templates/vertical_crm/manifest.json +81 -0
- package/templates/vertical_crm/package.json.tmpl +30 -0
- package/templates/vertical_crm/src/agents/account-manager.ts.tmpl +7 -0
- package/templates/vertical_crm/src/agents/churn-watcher.ts.tmpl +7 -0
- package/templates/vertical_crm/src/agents/lead-qualifier.ts.tmpl +7 -0
- package/templates/vertical_crm/src/init.ts.tmpl +21 -0
- package/templates/vertical_devops/.claude/settings.json.tmpl +36 -0
- package/templates/vertical_devops/CLAUDE.md.tmpl +34 -0
- package/templates/vertical_devops/README.md.tmpl +27 -0
- package/templates/vertical_devops/manifest.json +22 -0
- package/templates/vertical_devops/package.json.tmpl +26 -0
- package/templates/vertical_devops/runbooks/README.md.tmpl +32 -0
- package/templates/vertical_devops/src/agents/escalator.ts.tmpl +19 -0
- package/templates/vertical_devops/src/agents/postmortem.ts.tmpl +23 -0
- package/templates/vertical_devops/src/agents/responder.ts.tmpl +14 -0
- package/templates/vertical_devops/src/agents/runbook-runner.ts.tmpl +17 -0
- package/templates/vertical_devops/src/init.ts.tmpl +23 -0
- package/templates/vertical_education/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_education/.claude/commands/mastery-report.md.tmpl +12 -0
- package/templates/vertical_education/.claude/settings.json.tmpl +45 -0
- package/templates/vertical_education/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_education/.claude/skills/teach-next/SKILL.md.tmpl +16 -0
- package/templates/vertical_education/CLAUDE.md.tmpl +33 -0
- package/templates/vertical_education/README.md.tmpl +30 -0
- package/templates/vertical_education/manifest.json +96 -0
- package/templates/vertical_education/package.json.tmpl +30 -0
- package/templates/vertical_education/src/agents/explainer.ts.tmpl +7 -0
- package/templates/vertical_education/src/agents/grader.ts.tmpl +7 -0
- package/templates/vertical_education/src/agents/quiz-master.ts.tmpl +7 -0
- package/templates/vertical_education/src/agents/tutor.ts.tmpl +7 -0
- package/templates/vertical_education/src/init.ts.tmpl +21 -0
- package/templates/vertical_exotic/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_exotic/.claude/settings.json.tmpl +44 -0
- package/templates/vertical_exotic/.claude/skills/evolve/SKILL.md.tmpl +14 -0
- package/templates/vertical_exotic/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_exotic/CLAUDE.md.tmpl +31 -0
- package/templates/vertical_exotic/README.md.tmpl +29 -0
- package/templates/vertical_exotic/manifest.json +86 -0
- package/templates/vertical_exotic/package.json.tmpl +30 -0
- package/templates/vertical_exotic/src/agents/experimenter.ts.tmpl +7 -0
- package/templates/vertical_exotic/src/agents/federator.ts.tmpl +7 -0
- package/templates/vertical_exotic/src/agents/hypothesizer.ts.tmpl +7 -0
- package/templates/vertical_exotic/src/init.ts.tmpl +21 -0
- package/templates/vertical_gaming/.claude/commands/design-doc-diff.md.tmpl +13 -0
- package/templates/vertical_gaming/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_gaming/.claude/settings.json.tmpl +45 -0
- package/templates/vertical_gaming/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_gaming/.claude/skills/playtest-recap/SKILL.md.tmpl +16 -0
- package/templates/vertical_gaming/CLAUDE.md.tmpl +33 -0
- package/templates/vertical_gaming/README.md.tmpl +30 -0
- package/templates/vertical_gaming/manifest.json +96 -0
- package/templates/vertical_gaming/package.json.tmpl +30 -0
- package/templates/vertical_gaming/src/agents/balance-critic.ts.tmpl +7 -0
- package/templates/vertical_gaming/src/agents/economy-modeler.ts.tmpl +7 -0
- package/templates/vertical_gaming/src/agents/narrative-keeper.ts.tmpl +7 -0
- package/templates/vertical_gaming/src/agents/playtest-reader.ts.tmpl +7 -0
- package/templates/vertical_gaming/src/init.ts.tmpl +21 -0
- package/templates/vertical_health/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_health/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_health/.claude/skills/wellness-intake/SKILL.md.tmpl +15 -0
- package/templates/vertical_health/CLAUDE.md.tmpl +30 -0
- package/templates/vertical_health/README.md.tmpl +29 -0
- package/templates/vertical_health/manifest.json +81 -0
- package/templates/vertical_health/package.json.tmpl +30 -0
- package/templates/vertical_health/src/agents/care-coordinator.ts.tmpl +7 -0
- package/templates/vertical_health/src/agents/intake.ts.tmpl +7 -0
- package/templates/vertical_health/src/agents/triage.ts.tmpl +7 -0
- package/templates/vertical_health/src/init.ts.tmpl +21 -0
- package/templates/vertical_legal/.claude/settings.json.tmpl +10 -0
- package/templates/vertical_legal/CLAUDE.md.tmpl +24 -0
- package/templates/vertical_legal/README.md.tmpl +21 -0
- package/templates/vertical_legal/manifest.json +20 -0
- package/templates/vertical_legal/package.json.tmpl +13 -0
- package/templates/vertical_legal/src/agents/citation-checker.ts.tmpl +7 -0
- package/templates/vertical_legal/src/agents/redline.ts.tmpl +7 -0
- package/templates/vertical_legal/src/agents/risk-rater.ts.tmpl +8 -0
- package/templates/vertical_legal/src/init.ts.tmpl +13 -0
- package/templates/vertical_marketing/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_marketing/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_marketing/.claude/skills/campaign-brief/SKILL.md.tmpl +13 -0
- package/templates/vertical_marketing/CLAUDE.md.tmpl +30 -0
- package/templates/vertical_marketing/README.md.tmpl +29 -0
- package/templates/vertical_marketing/manifest.json +81 -0
- package/templates/vertical_marketing/package.json.tmpl +30 -0
- package/templates/vertical_marketing/src/agents/content-creator.ts.tmpl +7 -0
- package/templates/vertical_marketing/src/agents/seo-analyst.ts.tmpl +7 -0
- package/templates/vertical_marketing/src/agents/strategist.ts.tmpl +7 -0
- package/templates/vertical_marketing/src/init.ts.tmpl +21 -0
- package/templates/vertical_repo-maintainer/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_repo-maintainer/.claude/commands/release-check.md.tmpl +13 -0
- package/templates/vertical_repo-maintainer/.claude/commands/repo-triage.md.tmpl +16 -0
- package/templates/vertical_repo-maintainer/.claude/settings.json.tmpl +44 -0
- package/templates/vertical_repo-maintainer/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_repo-maintainer/.claude/skills/plan-change/SKILL.md.tmpl +15 -0
- package/templates/vertical_repo-maintainer/CLAUDE.md.tmpl +34 -0
- package/templates/vertical_repo-maintainer/README.md.tmpl +30 -0
- package/templates/vertical_repo-maintainer/manifest.json +101 -0
- package/templates/vertical_repo-maintainer/package.json.tmpl +30 -0
- package/templates/vertical_repo-maintainer/src/agents/benchmarker.ts.tmpl +7 -0
- package/templates/vertical_repo-maintainer/src/agents/maintainer.ts.tmpl +7 -0
- package/templates/vertical_repo-maintainer/src/agents/release.ts.tmpl +7 -0
- package/templates/vertical_repo-maintainer/src/agents/security.ts.tmpl +7 -0
- package/templates/vertical_repo-maintainer/src/init.ts.tmpl +21 -0
- package/templates/vertical_research/.claude/settings.json.tmpl +9 -0
- package/templates/vertical_research/CLAUDE.md.tmpl +33 -0
- package/templates/vertical_research/README.md.tmpl +17 -0
- package/templates/vertical_research/manifest.json +23 -0
- package/templates/vertical_research/package.json.tmpl +13 -0
- package/templates/vertical_research/src/agents/citer.ts.tmpl +8 -0
- package/templates/vertical_research/src/agents/fact-checker.ts.tmpl +8 -0
- package/templates/vertical_research/src/agents/scout.ts.tmpl +7 -0
- package/templates/vertical_research/src/agents/source-grader.ts.tmpl +10 -0
- package/templates/vertical_research/src/agents/synthesizer.ts.tmpl +8 -0
- package/templates/vertical_research/src/agents/web-searcher.ts.tmpl +6 -0
- package/templates/vertical_research/src/init.ts.tmpl +13 -0
- package/templates/vertical_ruview/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_ruview/.claude/settings.json.tmpl +33 -0
- package/templates/vertical_ruview/.claude/skills/index-and-ask/SKILL.md.tmpl +15 -0
- package/templates/vertical_ruview/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_ruview/CLAUDE.md.tmpl +31 -0
- package/templates/vertical_ruview/README.md.tmpl +29 -0
- package/templates/vertical_ruview/manifest.json +86 -0
- package/templates/vertical_ruview/package.json.tmpl +30 -0
- package/templates/vertical_ruview/src/agents/indexer.ts.tmpl +7 -0
- package/templates/vertical_ruview/src/agents/retriever.ts.tmpl +7 -0
- package/templates/vertical_ruview/src/agents/reviewer.ts.tmpl +7 -0
- package/templates/vertical_ruview/src/init.ts.tmpl +21 -0
- package/templates/vertical_sales/.claude/commands/doctor.md.tmpl +12 -0
- package/templates/vertical_sales/.claude/commands/pipeline-report.md.tmpl +13 -0
- package/templates/vertical_sales/.claude/settings.json.tmpl +45 -0
- package/templates/vertical_sales/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
- package/templates/vertical_sales/.claude/skills/qualify-lead/SKILL.md.tmpl +15 -0
- package/templates/vertical_sales/CLAUDE.md.tmpl +33 -0
- package/templates/vertical_sales/README.md.tmpl +30 -0
- package/templates/vertical_sales/manifest.json +96 -0
- package/templates/vertical_sales/package.json.tmpl +30 -0
- package/templates/vertical_sales/src/agents/closer.ts.tmpl +7 -0
- package/templates/vertical_sales/src/agents/demo-coach.ts.tmpl +7 -0
- package/templates/vertical_sales/src/agents/prospector.ts.tmpl +7 -0
- package/templates/vertical_sales/src/agents/qualifier.ts.tmpl +7 -0
- package/templates/vertical_sales/src/init.ts.tmpl +21 -0
- package/templates/vertical_support/.claude/settings.json.tmpl +25 -0
- package/templates/vertical_support/CLAUDE.md.tmpl +34 -0
- package/templates/vertical_support/README.md.tmpl +16 -0
- package/templates/vertical_support/kb/README.md.tmpl +23 -0
- package/templates/vertical_support/manifest.json +22 -0
- package/templates/vertical_support/package.json.tmpl +24 -0
- package/templates/vertical_support/src/agents/escalator.ts.tmpl +6 -0
- package/templates/vertical_support/src/agents/kb-searcher.ts.tmpl +6 -0
- package/templates/vertical_support/src/agents/responder.ts.tmpl +7 -0
- package/templates/vertical_support/src/agents/triager.ts.tmpl +6 -0
- package/templates/vertical_support/src/init.ts.tmpl +16 -0
- package/templates/vertical_trading/.claude/settings.json.tmpl +20 -0
- package/templates/vertical_trading/CLAUDE.md.tmpl +24 -0
- package/templates/vertical_trading/README.md.tmpl +17 -0
- package/templates/vertical_trading/manifest.json +22 -0
- package/templates/vertical_trading/package.json.tmpl +13 -0
- package/templates/vertical_trading/src/agents/executor.ts.tmpl +8 -0
- package/templates/vertical_trading/src/agents/market-watcher.ts.tmpl +7 -0
- package/templates/vertical_trading/src/agents/postmortem.ts.tmpl +8 -0
- package/templates/vertical_trading/src/agents/risk-checker.ts.tmpl +11 -0
- package/templates/vertical_trading/src/agents/signal-gen.ts.tmpl +8 -0
- package/templates/vertical_trading/src/init.ts.tmpl +20 -0
package/dist/validate.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// `harness validate` — umbrella check that runs every gate a release-ready
|
|
4
|
+
// harness should pass, fail-fast with a structured per-check verdict.
|
|
5
|
+
//
|
|
6
|
+
// Checks (in order):
|
|
7
|
+
// 1. doctor file-shape + manifest hash + at-least-one-host-artifact
|
|
8
|
+
// 2. verify witness manifest signature check
|
|
9
|
+
// 3. path-guard no hardcoded /tmp/, C:\, /Users/, /home/ in production
|
|
10
|
+
// 4. mcp-server every entry in .mcp/servers.json passes kernel schema
|
|
11
|
+
// 5. secrets (optional) gcloud + project + secret exist (--skip-gcp to skip)
|
|
12
|
+
// 6. diag kernel-version skew check (iter 76 — informational,
|
|
13
|
+
// WARN on skew, never fails the umbrella because kernel
|
|
14
|
+
// skew is a deploy-side issue, not a release-readiness
|
|
15
|
+
// block for the harness being validated)
|
|
16
|
+
//
|
|
17
|
+
// Exits non-zero if any check fails. Structured output suits both human eyes
|
|
18
|
+
// and `grep PASS|FAIL` for CI.
|
|
19
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
20
|
+
import { readFile } from 'node:fs/promises';
|
|
21
|
+
import { join, resolve } from 'node:path';
|
|
22
|
+
import { doctor, verify } from './subcommands.js';
|
|
23
|
+
import { check as secretsCheck } from './secrets.js';
|
|
24
|
+
import { buildDiagReport } from './diag.js';
|
|
25
|
+
async function runDoctor(dir) {
|
|
26
|
+
const r = await doctor([dir]);
|
|
27
|
+
return {
|
|
28
|
+
name: 'doctor',
|
|
29
|
+
code: r.code,
|
|
30
|
+
detail: r.lines.join(' | '),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function runVerify(dir) {
|
|
34
|
+
if (!existsSync(join(dir, '.harness', 'witness.json'))) {
|
|
35
|
+
return { name: 'verify', code: 0, detail: 'no witness — skipped (sign first)' };
|
|
36
|
+
}
|
|
37
|
+
const r = await verify([dir]);
|
|
38
|
+
return { name: 'verify', code: r.code, detail: r.lines.slice(-2).join(' | ') };
|
|
39
|
+
}
|
|
40
|
+
/** Scan a harness's user-authored files for hardcoded paths. */
|
|
41
|
+
async function runPathGuard(dir) {
|
|
42
|
+
const bannedPatterns = [
|
|
43
|
+
/['"`]\/tmp\//,
|
|
44
|
+
/['"`]C:\\\\/,
|
|
45
|
+
/['"`]\/Users\//,
|
|
46
|
+
/['"`]\/home\//,
|
|
47
|
+
];
|
|
48
|
+
const offenders = [];
|
|
49
|
+
async function walk(d) {
|
|
50
|
+
const entries = await import('node:fs/promises').then(m => m.readdir(d, { withFileTypes: true }));
|
|
51
|
+
for (const ent of entries) {
|
|
52
|
+
if (ent.name === 'node_modules' || ent.name === '.git' || ent.name === 'dist')
|
|
53
|
+
continue;
|
|
54
|
+
const p = join(d, ent.name);
|
|
55
|
+
if (ent.isDirectory()) {
|
|
56
|
+
await walk(p);
|
|
57
|
+
}
|
|
58
|
+
else if (/\.(ts|tsx|js|mjs|cjs|rs)$/.test(ent.name)) {
|
|
59
|
+
const content = await readFile(p, 'utf-8').catch(() => '');
|
|
60
|
+
for (const line of content.split('\n')) {
|
|
61
|
+
// Skip comment lines
|
|
62
|
+
if (/^\s*\/\//.test(line) || /^\s*\*/.test(line))
|
|
63
|
+
continue;
|
|
64
|
+
for (const pat of bannedPatterns) {
|
|
65
|
+
if (pat.test(line)) {
|
|
66
|
+
offenders.push(`${p}: ${line.trim().slice(0, 80)}`);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
await walk(dir).catch(() => undefined);
|
|
75
|
+
if (offenders.length === 0) {
|
|
76
|
+
return { name: 'path-guard', code: 0, detail: 'no hardcoded /tmp, C:\\, /Users, /home in TS/JS/Rust' };
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
name: 'path-guard',
|
|
80
|
+
code: 1,
|
|
81
|
+
detail: `${offenders.length} hardcoded path${offenders.length === 1 ? '' : 's'}: ${offenders.slice(0, 3).join('; ')}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** Validate `.mcp/servers.json` (if present) against kernel MCP schema. */
|
|
85
|
+
async function runMcpCheck(dir) {
|
|
86
|
+
const mcpPath = join(dir, '.mcp', 'servers.json');
|
|
87
|
+
if (!existsSync(mcpPath)) {
|
|
88
|
+
return { name: 'mcp', code: 0, detail: 'no .mcp/servers.json — skipped' };
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const raw = JSON.parse(await readFile(mcpPath, 'utf-8'));
|
|
92
|
+
const servers = Array.isArray(raw) ? raw : Array.isArray(raw?.mcpServers) ? raw.mcpServers : [];
|
|
93
|
+
if (servers.length === 0) {
|
|
94
|
+
return { name: 'mcp', code: 0, detail: '.mcp/servers.json present but empty — skipped' };
|
|
95
|
+
}
|
|
96
|
+
// Best-effort: each server must have name + command. Real schema check
|
|
97
|
+
// would need the kernel NAPI binding — out of scope for the umbrella.
|
|
98
|
+
const problems = [];
|
|
99
|
+
for (const [i, s] of servers.entries()) {
|
|
100
|
+
if (typeof s?.name !== 'string')
|
|
101
|
+
problems.push(`server[${i}] missing name`);
|
|
102
|
+
if (!Array.isArray(s?.command) && typeof s?.command !== 'string') {
|
|
103
|
+
problems.push(`server[${i}] missing command`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (problems.length === 0) {
|
|
107
|
+
return { name: 'mcp', code: 0, detail: `${servers.length} server${servers.length === 1 ? '' : 's'} valid` };
|
|
108
|
+
}
|
|
109
|
+
return { name: 'mcp', code: 1, detail: problems.join('; ') };
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
return { name: 'mcp', code: 1, detail: `invalid JSON: ${e instanceof Error ? e.message : e}` };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* iter 76: diag check inside the validate umbrella. Returns code 0
|
|
117
|
+
* always so a kernel skew never blocks the umbrella verdict; surfaces
|
|
118
|
+
* the state via the tag override field (PASS / WARN / SKIP).
|
|
119
|
+
*/
|
|
120
|
+
/**
|
|
121
|
+
* iter 123: check #7 (informational). ADR-034 §134 specifies the OIA
|
|
122
|
+
* manifest should be shape-validated by `harness validate` so a drifted
|
|
123
|
+
* .harness/oia-manifest.json gets surfaced alongside the other gates.
|
|
124
|
+
*
|
|
125
|
+
* Informational on purpose:
|
|
126
|
+
* - manifest absent → SKIP (OIA opt-in, not required)
|
|
127
|
+
* - manifest valid → PASS
|
|
128
|
+
* - manifest drifted → WARN (reported but does NOT fail the umbrella;
|
|
129
|
+
* OIA v0.1 is pre-stable, drift may be a v1.0 migration in progress)
|
|
130
|
+
* - manifest corrupt → WARN (same reasoning)
|
|
131
|
+
*
|
|
132
|
+
* The user can promote this to FAIL by running `harness oia-manifest
|
|
133
|
+
* <dir> --check` directly in CI.
|
|
134
|
+
*/
|
|
135
|
+
async function runOiaManifest(dir) {
|
|
136
|
+
const manifestPath = join(dir, '.harness', 'oia-manifest.json');
|
|
137
|
+
if (!existsSync(manifestPath)) {
|
|
138
|
+
return { name: 'oia', code: 0, tag: 'SKIP', detail: 'no .harness/oia-manifest.json (OIA opt-in)' };
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const { checkOiaManifest } = await import('./oia-manifest.js');
|
|
142
|
+
const m = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
143
|
+
const r = checkOiaManifest(m);
|
|
144
|
+
if (r.ok) {
|
|
145
|
+
return { name: 'oia', code: 0, tag: 'PASS', detail: `oia-manifest shape ok (oiaVersion=${m.oiaVersion ?? '?'})` };
|
|
146
|
+
}
|
|
147
|
+
return { name: 'oia', code: 0, tag: 'WARN', detail: `oia-manifest drift: ${r.reasons.length} issue(s) — run \`harness oia-manifest ${dir} --check\` for detail` };
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
return { name: 'oia', code: 0, tag: 'WARN', detail: `oia-manifest parse error (${String(e).slice(0, 50)})` };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function runDiag(dir) {
|
|
154
|
+
if (!existsSync(join(dir, '.harness', 'manifest.json'))) {
|
|
155
|
+
return { name: 'diag', code: 0, tag: 'SKIP', detail: 'no manifest at path' };
|
|
156
|
+
}
|
|
157
|
+
const r = await buildDiagReport(dir);
|
|
158
|
+
if (!r.manifestKernelVersion) {
|
|
159
|
+
return { name: 'diag', code: 0, tag: 'SKIP', detail: 'manifest pre-iter-58 (no kernel_version)' };
|
|
160
|
+
}
|
|
161
|
+
if (!r.localKernelVersion) {
|
|
162
|
+
return {
|
|
163
|
+
name: 'diag', code: 0, tag: 'SKIP',
|
|
164
|
+
detail: `@ruflo/kernel not installed locally (manifest pins ${r.manifestKernelVersion})`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (r.verdict === 'match' || r.verdict === 'patch-diff') {
|
|
168
|
+
return {
|
|
169
|
+
name: 'diag', code: 0, tag: 'PASS',
|
|
170
|
+
detail: `kernel manifest=${r.manifestKernelVersion} local=${r.localKernelVersion} (${r.verdict})`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// minor-diff / major-diff / unparseable → WARN but DON'T fail
|
|
174
|
+
return {
|
|
175
|
+
name: 'diag', code: 0, tag: 'WARN',
|
|
176
|
+
detail: `kernel manifest=${r.manifestKernelVersion} local=${r.localKernelVersion} (${r.verdict})`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/** Top-level dispatcher: `harness validate [path] [--skip-gcp] [--secret=NAME]`. */
|
|
180
|
+
export async function validate(args) {
|
|
181
|
+
const dir = resolve(args.find(a => !a.startsWith('--')) ?? process.cwd());
|
|
182
|
+
const skipGcp = args.includes('--skip-gcp');
|
|
183
|
+
const secret = args.find(a => a.startsWith('--secret='))?.slice('--secret='.length);
|
|
184
|
+
const lines = [`harness validate — ${dir}`];
|
|
185
|
+
const results = [];
|
|
186
|
+
results.push(await runDoctor(dir));
|
|
187
|
+
results.push(await runVerify(dir));
|
|
188
|
+
results.push(await runPathGuard(dir));
|
|
189
|
+
results.push(await runMcpCheck(dir));
|
|
190
|
+
if (!skipGcp) {
|
|
191
|
+
const sc = await secretsCheck(secret ? [`--secret=${secret}`] : []);
|
|
192
|
+
results.push({
|
|
193
|
+
name: 'secrets',
|
|
194
|
+
code: sc.code,
|
|
195
|
+
detail: sc.lines.slice(-2).join(' | ').replace(/\s+/g, ' '),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
results.push({ name: 'secrets', code: 0, detail: 'skipped (--skip-gcp)' });
|
|
200
|
+
}
|
|
201
|
+
// iter 76: diag (kernel-version skew) as informational signal.
|
|
202
|
+
// Never fails the umbrella — kernel skew is a deploy-side runtime
|
|
203
|
+
// issue, not a release-readiness block for the harness being
|
|
204
|
+
// validated. PASS on match/patch, WARN on minor/major, SKIP when
|
|
205
|
+
// no kernel installed locally.
|
|
206
|
+
results.push(await runDiag(dir));
|
|
207
|
+
// iter 123: OIA manifest shape check (ADR-034 §134) as informational
|
|
208
|
+
// signal. Never fails the umbrella — OIA at v0.1 is pre-stable, and
|
|
209
|
+
// the manifest is opt-in (no manifest = SKIP). PASS on valid shape,
|
|
210
|
+
// WARN on drift or parse error. Users who want CI-blocking validation
|
|
211
|
+
// run `harness oia-manifest <dir> --check` directly.
|
|
212
|
+
results.push(await runOiaManifest(dir));
|
|
213
|
+
let problems = 0;
|
|
214
|
+
for (const r of results) {
|
|
215
|
+
const tag = r.tag ?? (r.code === 0 ? 'PASS' : 'FAIL');
|
|
216
|
+
lines.push(` ${tag.padEnd(4)} ${r.name.padEnd(10)} — ${r.detail}`);
|
|
217
|
+
if (r.code !== 0)
|
|
218
|
+
problems++;
|
|
219
|
+
}
|
|
220
|
+
lines.push('');
|
|
221
|
+
if (problems === 0) {
|
|
222
|
+
lines.push('Result: HEALTHY (release-ready)');
|
|
223
|
+
return { code: 0, lines };
|
|
224
|
+
}
|
|
225
|
+
lines.push(`Result: ${problems} check${problems === 1 ? '' : 's'} FAILED — fix before publish`);
|
|
226
|
+
// iter 94: symmetric with iter 93 — when the umbrella FAILs, point
|
|
227
|
+
// the user at the bundle. Doctor already does this for its own
|
|
228
|
+
// failures, but the umbrella aggregates 7 checks (doctor + verify +
|
|
229
|
+
// path-guard + mcp + secrets + diag + oia) — any of them failing
|
|
230
|
+
// should surface the bundle as the next user action. The diag and
|
|
231
|
+
// oia checks are informational — they never fail the umbrella.
|
|
232
|
+
lines.push('');
|
|
233
|
+
lines.push(`Next: capture the full diagnostic state for a support ticket:`);
|
|
234
|
+
lines.push(` harness diag ${dir} --bundle > bundle.json`);
|
|
235
|
+
lines.push(`(then attach bundle.json to a GitHub issue at`);
|
|
236
|
+
lines.push(` https://github.com/ruvnet/agent-harness-generator/issues — the`);
|
|
237
|
+
lines.push(` bundle is sanitised; secret_/token_/key_/password_ fields are redacted)`);
|
|
238
|
+
return { code: 1, lines };
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/walker.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type TemplateVars } from './renderer.js';
|
|
2
|
+
export interface RenderedFile {
|
|
3
|
+
/** Posix-style relative path inside the destination directory. */
|
|
4
|
+
path: string;
|
|
5
|
+
/** Final UTF-8 content. */
|
|
6
|
+
content: string;
|
|
7
|
+
/** Did this file go through the Mustache renderer? */
|
|
8
|
+
rendered: boolean;
|
|
9
|
+
/** Variables that were referenced but had no value. Empty = clean render. */
|
|
10
|
+
unresolved: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Walk a template directory and return one RenderedFile per file found.
|
|
14
|
+
* Throws on any file with unresolved vars when `strict` is true.
|
|
15
|
+
*/
|
|
16
|
+
export declare function walkTemplate(templateDir: string, vars: TemplateVars, opts?: {
|
|
17
|
+
strict?: boolean;
|
|
18
|
+
}): Promise<RenderedFile[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Convert a RenderedFile[] to the flat path -> content map that
|
|
21
|
+
* fingerprintFiles() in manifest.ts expects.
|
|
22
|
+
*/
|
|
23
|
+
export declare function asFileMap(files: RenderedFile[]): Record<string, string>;
|
|
24
|
+
//# sourceMappingURL=walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walker.d.ts","sourceRoot":"","sources":["../src/walker.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAOD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,YAAY,EAClB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,OAAO,CAAC,YAAY,EAAE,CAAC,CAWzB;AAkCD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvE"}
|
package/dist/walker.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// Recursive template walker. Walks a templates/<id>/ directory, renders
|
|
4
|
+
// every .tmpl file through the Mustache engine, and emits a flat
|
|
5
|
+
// path -> content map keyed by the destination paths.
|
|
6
|
+
//
|
|
7
|
+
// Convention (per templates/minimal/manifest.json files[].src/dst):
|
|
8
|
+
// - <file>.tmpl -> render through Mustache, drop the .tmpl suffix
|
|
9
|
+
// - <file> -> copy verbatim (binary-safe via Uint8Array)
|
|
10
|
+
//
|
|
11
|
+
// The walker does NOT touch the filesystem of the destination — it returns
|
|
12
|
+
// an in-memory map. The CLI commits to disk in a single batch so failures
|
|
13
|
+
// can roll back atomically (ADR-008 §atomic-generation).
|
|
14
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
15
|
+
import { join, relative, sep, posix } from 'node:path';
|
|
16
|
+
import { render } from './renderer.js';
|
|
17
|
+
/** Normalise OS-specific separators to posix for stable manifest keys. */
|
|
18
|
+
function toPosix(p) {
|
|
19
|
+
return p.split(sep).join(posix.sep);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Walk a template directory and return one RenderedFile per file found.
|
|
23
|
+
* Throws on any file with unresolved vars when `strict` is true.
|
|
24
|
+
*/
|
|
25
|
+
export async function walkTemplate(templateDir, vars, opts = {}) {
|
|
26
|
+
const out = [];
|
|
27
|
+
await walk(templateDir, templateDir, vars, out);
|
|
28
|
+
if (opts.strict) {
|
|
29
|
+
const offenders = out.filter(f => f.unresolved.length > 0);
|
|
30
|
+
if (offenders.length > 0) {
|
|
31
|
+
const list = offenders.map(o => ` ${o.path}: ${o.unresolved.join(', ')}`).join('\n');
|
|
32
|
+
throw new Error(`Template has unresolved variables (strict mode):\n${list}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
async function walk(root, current, vars, out) {
|
|
38
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
39
|
+
for (const e of entries) {
|
|
40
|
+
const full = join(current, e.name);
|
|
41
|
+
if (e.isDirectory()) {
|
|
42
|
+
await walk(root, full, vars, out);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!e.isFile())
|
|
46
|
+
continue;
|
|
47
|
+
const rel = toPosix(relative(root, full));
|
|
48
|
+
if (rel.endsWith('/manifest.json') || rel === 'manifest.json')
|
|
49
|
+
continue;
|
|
50
|
+
if (rel.endsWith('.tmpl')) {
|
|
51
|
+
const raw = await readFile(full, 'utf-8');
|
|
52
|
+
const { output, unresolved } = render(raw, vars);
|
|
53
|
+
out.push({
|
|
54
|
+
path: rel.slice(0, -'.tmpl'.length),
|
|
55
|
+
content: output,
|
|
56
|
+
rendered: true,
|
|
57
|
+
unresolved,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const raw = await readFile(full, 'utf-8');
|
|
62
|
+
out.push({ path: rel, content: raw, rendered: false, unresolved: [] });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Convert a RenderedFile[] to the flat path -> content map that
|
|
68
|
+
* fingerprintFiles() in manifest.ts expects.
|
|
69
|
+
*/
|
|
70
|
+
export function asFileMap(files) {
|
|
71
|
+
const out = {};
|
|
72
|
+
for (const f of files)
|
|
73
|
+
out[f.path] = f.content;
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walker.js","sourceRoot":"","sources":["../src/walker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface WitnessEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
desc: string;
|
|
4
|
+
marker: string;
|
|
5
|
+
sha256: string;
|
|
6
|
+
}
|
|
7
|
+
export interface WitnessManifest {
|
|
8
|
+
schema: 1;
|
|
9
|
+
harness: string;
|
|
10
|
+
version: string;
|
|
11
|
+
entries: WitnessEntry[];
|
|
12
|
+
public_key: string;
|
|
13
|
+
signature: string;
|
|
14
|
+
}
|
|
15
|
+
export interface VerificationResult {
|
|
16
|
+
valid: boolean;
|
|
17
|
+
reason?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Verify a witness manifest by delegating to the kernel's wasm/native
|
|
21
|
+
* verify_manifest(). Returns {valid: boolean, reason?: string}.
|
|
22
|
+
*
|
|
23
|
+
* The kernel is the security boundary — TS only does shape validation
|
|
24
|
+
* before handing off.
|
|
25
|
+
*/
|
|
26
|
+
export declare function verifyWitness(manifest: unknown): Promise<VerificationResult>;
|
|
27
|
+
/**
|
|
28
|
+
* Read and verify a witness.json file. Returns the parsed manifest on
|
|
29
|
+
* success.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readAndVerify(witnessPath: string): Promise<{
|
|
32
|
+
manifest: WitnessManifest;
|
|
33
|
+
result: VerificationResult;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Find a harness's witness.json. Convention: <harnessDir>/witness.json
|
|
37
|
+
* or <harnessDir>/.harness/witness.json.
|
|
38
|
+
*/
|
|
39
|
+
export declare function findWitness(harnessDir: string): string | null;
|
|
40
|
+
//# sourceMappingURL=witness-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"witness-client.d.ts","sourceRoot":"","sources":["../src/witness-client.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,CAAC,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0ClF;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAChE,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CAAC,CAaD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ7D"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// TypeScript wrapper around the kernel's witness verification primitive.
|
|
4
|
+
//
|
|
5
|
+
// Per ADR-011, every harness ships with a `witness.json` next to its
|
|
6
|
+
// `.harness/manifest.json`. The publish gate verifies that signature
|
|
7
|
+
// BEFORE pushing the harness to npm or pinning it to IPFS — there is
|
|
8
|
+
// no path to publish an unsigned or tampered harness.
|
|
9
|
+
//
|
|
10
|
+
// The kernel's verify_manifest() does the real Ed25519 work; this TS
|
|
11
|
+
// layer only handles the JSON I/O and the publish-time check.
|
|
12
|
+
import { readFile } from 'node:fs/promises';
|
|
13
|
+
import { existsSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
/**
|
|
16
|
+
* Verify a witness manifest by delegating to the kernel's wasm/native
|
|
17
|
+
* verify_manifest(). Returns {valid: boolean, reason?: string}.
|
|
18
|
+
*
|
|
19
|
+
* The kernel is the security boundary — TS only does shape validation
|
|
20
|
+
* before handing off.
|
|
21
|
+
*/
|
|
22
|
+
export async function verifyWitness(manifest) {
|
|
23
|
+
// Shape gate: never hand a malformed object to the kernel.
|
|
24
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
25
|
+
return { valid: false, reason: 'manifest is not an object' };
|
|
26
|
+
}
|
|
27
|
+
const m = manifest;
|
|
28
|
+
if (m.schema !== 1) {
|
|
29
|
+
return { valid: false, reason: `unsupported schema version ${m.schema}` };
|
|
30
|
+
}
|
|
31
|
+
if (!m.public_key || typeof m.public_key !== 'string' || m.public_key.length !== 64) {
|
|
32
|
+
return { valid: false, reason: 'public_key must be 64-char hex string' };
|
|
33
|
+
}
|
|
34
|
+
if (!m.signature || typeof m.signature !== 'string' || m.signature.length !== 128) {
|
|
35
|
+
return { valid: false, reason: 'signature must be 128-char hex string' };
|
|
36
|
+
}
|
|
37
|
+
if (!Array.isArray(m.entries)) {
|
|
38
|
+
return { valid: false, reason: 'entries must be an array' };
|
|
39
|
+
}
|
|
40
|
+
if (!m.harness || typeof m.harness !== 'string') {
|
|
41
|
+
return { valid: false, reason: 'harness must be a string' };
|
|
42
|
+
}
|
|
43
|
+
if (!m.version || typeof m.version !== 'string') {
|
|
44
|
+
return { valid: false, reason: 'version must be a string' };
|
|
45
|
+
}
|
|
46
|
+
// Delegate to the kernel for the cryptographic check.
|
|
47
|
+
try {
|
|
48
|
+
const { loadKernel } = await import('@ruflo/kernel');
|
|
49
|
+
const kernel = await loadKernel();
|
|
50
|
+
if (typeof kernel.witnessVerify === 'function') {
|
|
51
|
+
const result = kernel.witnessVerify(JSON.stringify(m));
|
|
52
|
+
if (result === true)
|
|
53
|
+
return { valid: true };
|
|
54
|
+
if (result === false)
|
|
55
|
+
return { valid: false, reason: 'kernel signature check failed' };
|
|
56
|
+
return { valid: false, reason: String(result) };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Kernel not available in this environment — fall through to
|
|
61
|
+
// shape-only verification as a degraded mode (CI is the source of
|
|
62
|
+
// truth; local-dev can skip the crypto verify).
|
|
63
|
+
}
|
|
64
|
+
return { valid: true, reason: 'shape verified; kernel not loaded (degraded)' };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Read and verify a witness.json file. Returns the parsed manifest on
|
|
68
|
+
* success.
|
|
69
|
+
*/
|
|
70
|
+
export async function readAndVerify(witnessPath) {
|
|
71
|
+
if (!existsSync(witnessPath)) {
|
|
72
|
+
throw new Error(`no witness at ${witnessPath}`);
|
|
73
|
+
}
|
|
74
|
+
const raw = await readFile(witnessPath, 'utf-8');
|
|
75
|
+
let parsed;
|
|
76
|
+
try {
|
|
77
|
+
parsed = JSON.parse(raw);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
throw new Error(`witness.json not valid JSON: ${err}`);
|
|
81
|
+
}
|
|
82
|
+
const result = await verifyWitness(parsed);
|
|
83
|
+
return { manifest: parsed, result };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Find a harness's witness.json. Convention: <harnessDir>/witness.json
|
|
87
|
+
* or <harnessDir>/.harness/witness.json.
|
|
88
|
+
*/
|
|
89
|
+
export function findWitness(harnessDir) {
|
|
90
|
+
for (const cand of [
|
|
91
|
+
join(harnessDir, 'witness.json'),
|
|
92
|
+
join(harnessDir, '.harness', 'witness.json'),
|
|
93
|
+
]) {
|
|
94
|
+
if (existsSync(cand))
|
|
95
|
+
return cand;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=witness-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"witness-client.js","sourceRoot":"","sources":["../src/witness-client.ts"],"names":[],"mappings":"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"}
|
package/dist/wizard.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface WizardAnswers {
|
|
2
|
+
name: string;
|
|
3
|
+
template: string;
|
|
4
|
+
host: string;
|
|
5
|
+
description: string;
|
|
6
|
+
}
|
|
7
|
+
interface WizardCatalogEntry {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface WizardCatalog {
|
|
13
|
+
templates: WizardCatalogEntry[];
|
|
14
|
+
hosts: ReadonlyArray<string>;
|
|
15
|
+
}
|
|
16
|
+
export type Asker = (prompt: string) => Promise<string>;
|
|
17
|
+
export declare function makeReadlineAsker(): {
|
|
18
|
+
ask: Asker;
|
|
19
|
+
close: () => void;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Run the wizard against a catalog + an asker. Returns the validated
|
|
23
|
+
* answers ready to feed into scaffold().
|
|
24
|
+
*
|
|
25
|
+
* The wizard does NOT scaffold — it just collects answers. The caller
|
|
26
|
+
* (the bin) decides whether to scaffold immediately or print the
|
|
27
|
+
* equivalent CLI invocation for copy-pasting.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runWizard(catalog: WizardCatalog, ask: Asker): Promise<WizardAnswers>;
|
|
30
|
+
/**
|
|
31
|
+
* Build the equivalent `npx create-agent-harness ...` invocation for
|
|
32
|
+
* the answers. Useful for the "next time, you can skip the wizard with
|
|
33
|
+
* this command:" hint we print after a successful scaffold.
|
|
34
|
+
*/
|
|
35
|
+
export declare function answersToInvocation(answers: WizardAnswers): string;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=wizard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAChC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B;AAKD,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAExD,wBAAgB,iBAAiB,IAAI;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAIrE;AAgBD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,CA2E1F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAMlE"}
|