@jokerized/getresearchdone 0.4.1
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/.claude-plugin/plugin.json +103 -0
- package/README.md +211 -0
- package/agents/grd-baseline-assessor.md +684 -0
- package/agents/grd-code-reviewer.md +300 -0
- package/agents/grd-codebase-mapper.md +355 -0
- package/agents/grd-critique-agent.md +119 -0
- package/agents/grd-debugger.md +519 -0
- package/agents/grd-deep-diver.md +737 -0
- package/agents/grd-eval-planner.md +913 -0
- package/agents/grd-eval-reporter.md +717 -0
- package/agents/grd-executor.md +683 -0
- package/agents/grd-feasibility-analyst.md +624 -0
- package/agents/grd-integration-checker.md +367 -0
- package/agents/grd-knowledge-miner.md +81 -0
- package/agents/grd-migrator.md +88 -0
- package/agents/grd-phase-researcher.md +697 -0
- package/agents/grd-plan-checker.md +443 -0
- package/agents/grd-planner.md +1532 -0
- package/agents/grd-product-owner.md +562 -0
- package/agents/grd-project-researcher.md +513 -0
- package/agents/grd-research-synthesizer.md +273 -0
- package/agents/grd-roadmapper.md +798 -0
- package/agents/grd-surveyor.md +566 -0
- package/agents/grd-verifier.md +893 -0
- package/bin/gd.js +4 -0
- package/bin/gd.ts +227 -0
- package/bin/grd-manifest.js +4 -0
- package/bin/grd-manifest.ts +286 -0
- package/bin/grd-mcp-server.js +4 -0
- package/bin/grd-mcp-server.ts +124 -0
- package/bin/grd-tools.js +4 -0
- package/bin/grd-tools.ts +2471 -0
- package/bin/postinstall.js +4 -0
- package/bin/postinstall.ts +80 -0
- package/commands/add-phase.md +123 -0
- package/commands/add-todo.md +87 -0
- package/commands/assess-baseline.md +289 -0
- package/commands/autopilot.md +100 -0
- package/commands/autoplan.md +55 -0
- package/commands/check-todos.md +87 -0
- package/commands/compare-methods.md +262 -0
- package/commands/complete-milestone.md +225 -0
- package/commands/debug.md +372 -0
- package/commands/deep-dive.md +288 -0
- package/commands/discover.md +281 -0
- package/commands/discuss-phase.md +188 -0
- package/commands/discuss.md +55 -0
- package/commands/eval-report.md +310 -0
- package/commands/evolve.md +79 -0
- package/commands/execute-phase.md +1017 -0
- package/commands/feasibility.md +292 -0
- package/commands/help.md +407 -0
- package/commands/init.md +1508 -0
- package/commands/insert-phase.md +113 -0
- package/commands/iterate.md +327 -0
- package/commands/list-phase-assumptions.md +217 -0
- package/commands/long-term-roadmap.md +202 -0
- package/commands/map-codebase.md +111 -0
- package/commands/migrate.md +159 -0
- package/commands/new-milestone.md +169 -0
- package/commands/pause-work.md +83 -0
- package/commands/plan-milestone-gaps.md +373 -0
- package/commands/plan-phase.md +655 -0
- package/commands/principles.md +328 -0
- package/commands/product-plan.md +319 -0
- package/commands/progress.md +481 -0
- package/commands/quick.md +167 -0
- package/commands/reapply-patches.md +154 -0
- package/commands/remove-phase.md +97 -0
- package/commands/requirement.md +96 -0
- package/commands/resume-project.md +113 -0
- package/commands/settings.md +1144 -0
- package/commands/survey.md +242 -0
- package/commands/sync.md +246 -0
- package/commands/tracker-setup.md +322 -0
- package/commands/update.md +202 -0
- package/commands/verify-phase.md +335 -0
- package/commands/verify-work.md +701 -0
- package/commands/wireup.md +29 -0
- package/dist/bin/gd.d.ts +3 -0
- package/dist/bin/gd.d.ts.map +1 -0
- package/dist/bin/gd.js +178 -0
- package/dist/bin/gd.js.map +1 -0
- package/dist/bin/grd-manifest.d.ts +3 -0
- package/dist/bin/grd-manifest.d.ts.map +1 -0
- package/dist/bin/grd-manifest.js +202 -0
- package/dist/bin/grd-manifest.js.map +1 -0
- package/dist/bin/grd-mcp-server.d.ts +3 -0
- package/dist/bin/grd-mcp-server.d.ts.map +1 -0
- package/dist/bin/grd-mcp-server.js +71 -0
- package/dist/bin/grd-mcp-server.js.map +1 -0
- package/dist/bin/grd-tools.d.ts +3 -0
- package/dist/bin/grd-tools.d.ts.map +1 -0
- package/dist/bin/grd-tools.js +1680 -0
- package/dist/bin/grd-tools.js.map +1 -0
- package/dist/bin/postinstall.d.ts +3 -0
- package/dist/bin/postinstall.d.ts.map +1 -0
- package/dist/bin/postinstall.js +61 -0
- package/dist/bin/postinstall.js.map +1 -0
- package/dist/lib/autopilot-milestone.d.ts +2 -0
- package/dist/lib/autopilot-milestone.d.ts.map +1 -0
- package/dist/lib/autopilot-milestone.js +94 -0
- package/dist/lib/autopilot-milestone.js.map +1 -0
- package/dist/lib/autopilot-pipeline.d.ts +2 -0
- package/dist/lib/autopilot-pipeline.d.ts.map +1 -0
- package/dist/lib/autopilot-pipeline.js +830 -0
- package/dist/lib/autopilot-pipeline.js.map +1 -0
- package/dist/lib/autopilot-waves.d.ts +2 -0
- package/dist/lib/autopilot-waves.d.ts.map +1 -0
- package/dist/lib/autopilot-waves.js +266 -0
- package/dist/lib/autopilot-waves.js.map +1 -0
- package/dist/lib/autopilot.d.ts +2 -0
- package/dist/lib/autopilot.d.ts.map +1 -0
- package/dist/lib/autopilot.js +1314 -0
- package/dist/lib/autopilot.js.map +1 -0
- package/dist/lib/autoplan.d.ts +2 -0
- package/dist/lib/autoplan.d.ts.map +1 -0
- package/dist/lib/autoplan.js +198 -0
- package/dist/lib/autoplan.js.map +1 -0
- package/dist/lib/autoresearch.d.ts +2 -0
- package/dist/lib/autoresearch.d.ts.map +1 -0
- package/dist/lib/autoresearch.js +626 -0
- package/dist/lib/autoresearch.js.map +1 -0
- package/dist/lib/backend.d.ts +2 -0
- package/dist/lib/backend.d.ts.map +1 -0
- package/dist/lib/backend.js +1036 -0
- package/dist/lib/backend.js.map +1 -0
- package/dist/lib/benchmark.d.ts +99 -0
- package/dist/lib/benchmark.d.ts.map +1 -0
- package/dist/lib/benchmark.js +278 -0
- package/dist/lib/benchmark.js.map +1 -0
- package/dist/lib/citations.d.ts +2 -0
- package/dist/lib/citations.d.ts.map +1 -0
- package/dist/lib/citations.js +642 -0
- package/dist/lib/citations.js.map +1 -0
- package/dist/lib/cleanup.d.ts +2 -0
- package/dist/lib/cleanup.d.ts.map +1 -0
- package/dist/lib/cleanup.js +1222 -0
- package/dist/lib/cleanup.js.map +1 -0
- package/dist/lib/cli/adapters.d.ts +10 -0
- package/dist/lib/cli/adapters.d.ts.map +1 -0
- package/dist/lib/cli/adapters.js +27 -0
- package/dist/lib/cli/adapters.js.map +1 -0
- package/dist/lib/cli/agent.d.ts +17 -0
- package/dist/lib/cli/agent.d.ts.map +1 -0
- package/dist/lib/cli/agent.js +53 -0
- package/dist/lib/cli/agent.js.map +1 -0
- package/dist/lib/cli/index.d.ts +21 -0
- package/dist/lib/cli/index.d.ts.map +1 -0
- package/dist/lib/cli/index.js +264 -0
- package/dist/lib/cli/index.js.map +1 -0
- package/dist/lib/cli/output.d.ts +20 -0
- package/dist/lib/cli/output.d.ts.map +1 -0
- package/dist/lib/cli/output.js +22 -0
- package/dist/lib/cli/output.js.map +1 -0
- package/dist/lib/cli/scan-dispatch.d.ts +9 -0
- package/dist/lib/cli/scan-dispatch.d.ts.map +1 -0
- package/dist/lib/cli/scan-dispatch.js +107 -0
- package/dist/lib/cli/scan-dispatch.js.map +1 -0
- package/dist/lib/cli/tools.d.ts +16 -0
- package/dist/lib/cli/tools.d.ts.map +1 -0
- package/dist/lib/cli/tools.js +168 -0
- package/dist/lib/cli/tools.js.map +1 -0
- package/dist/lib/commands/_dashboard-parsers.d.ts +2 -0
- package/dist/lib/commands/_dashboard-parsers.d.ts.map +1 -0
- package/dist/lib/commands/_dashboard-parsers.js +192 -0
- package/dist/lib/commands/_dashboard-parsers.js.map +1 -0
- package/dist/lib/commands/analysis.d.ts +2 -0
- package/dist/lib/commands/analysis.d.ts.map +1 -0
- package/dist/lib/commands/analysis.js +1418 -0
- package/dist/lib/commands/analysis.js.map +1 -0
- package/dist/lib/commands/assumptions.d.ts +2 -0
- package/dist/lib/commands/assumptions.d.ts.map +1 -0
- package/dist/lib/commands/assumptions.js +166 -0
- package/dist/lib/commands/assumptions.js.map +1 -0
- package/dist/lib/commands/blame.d.ts +2 -0
- package/dist/lib/commands/blame.d.ts.map +1 -0
- package/dist/lib/commands/blame.js +133 -0
- package/dist/lib/commands/blame.js.map +1 -0
- package/dist/lib/commands/budget.d.ts +2 -0
- package/dist/lib/commands/budget.d.ts.map +1 -0
- package/dist/lib/commands/budget.js +100 -0
- package/dist/lib/commands/budget.js.map +1 -0
- package/dist/lib/commands/check-plans.d.ts +2 -0
- package/dist/lib/commands/check-plans.d.ts.map +1 -0
- package/dist/lib/commands/check-plans.js +190 -0
- package/dist/lib/commands/check-plans.js.map +1 -0
- package/dist/lib/commands/config.d.ts +2 -0
- package/dist/lib/commands/config.d.ts.map +1 -0
- package/dist/lib/commands/config.js +188 -0
- package/dist/lib/commands/config.js.map +1 -0
- package/dist/lib/commands/dashboard.d.ts +2 -0
- package/dist/lib/commands/dashboard.d.ts.map +1 -0
- package/dist/lib/commands/dashboard.js +466 -0
- package/dist/lib/commands/dashboard.js.map +1 -0
- package/dist/lib/commands/estimate.d.ts +2 -0
- package/dist/lib/commands/estimate.d.ts.map +1 -0
- package/dist/lib/commands/estimate.js +148 -0
- package/dist/lib/commands/estimate.js.map +1 -0
- package/dist/lib/commands/eval-diff.d.ts +2 -0
- package/dist/lib/commands/eval-diff.d.ts.map +1 -0
- package/dist/lib/commands/eval-diff.js +213 -0
- package/dist/lib/commands/eval-diff.js.map +1 -0
- package/dist/lib/commands/freshness.d.ts +2 -0
- package/dist/lib/commands/freshness.d.ts.map +1 -0
- package/dist/lib/commands/freshness.js +163 -0
- package/dist/lib/commands/freshness.js.map +1 -0
- package/dist/lib/commands/health.d.ts +2 -0
- package/dist/lib/commands/health.d.ts.map +1 -0
- package/dist/lib/commands/health.js +435 -0
- package/dist/lib/commands/health.js.map +1 -0
- package/dist/lib/commands/index.d.ts +2 -0
- package/dist/lib/commands/index.d.ts.map +1 -0
- package/dist/lib/commands/index.js +128 -0
- package/dist/lib/commands/index.js.map +1 -0
- package/dist/lib/commands/install.d.ts +56 -0
- package/dist/lib/commands/install.d.ts.map +1 -0
- package/dist/lib/commands/install.js +214 -0
- package/dist/lib/commands/install.js.map +1 -0
- package/dist/lib/commands/knowhow-aggregator.d.ts +2 -0
- package/dist/lib/commands/knowhow-aggregator.d.ts.map +1 -0
- package/dist/lib/commands/knowhow-aggregator.js +279 -0
- package/dist/lib/commands/knowhow-aggregator.js.map +1 -0
- package/dist/lib/commands/knowledge-search.d.ts +2 -0
- package/dist/lib/commands/knowledge-search.d.ts.map +1 -0
- package/dist/lib/commands/knowledge-search.js +113 -0
- package/dist/lib/commands/knowledge-search.js.map +1 -0
- package/dist/lib/commands/long-term-roadmap.d.ts +2 -0
- package/dist/lib/commands/long-term-roadmap.d.ts.map +1 -0
- package/dist/lib/commands/long-term-roadmap.js +272 -0
- package/dist/lib/commands/long-term-roadmap.js.map +1 -0
- package/dist/lib/commands/patterns.d.ts +91 -0
- package/dist/lib/commands/patterns.d.ts.map +1 -0
- package/dist/lib/commands/patterns.js +391 -0
- package/dist/lib/commands/patterns.js.map +1 -0
- package/dist/lib/commands/phase-info.d.ts +2 -0
- package/dist/lib/commands/phase-info.d.ts.map +1 -0
- package/dist/lib/commands/phase-info.js +509 -0
- package/dist/lib/commands/phase-info.js.map +1 -0
- package/dist/lib/commands/plan-lint.d.ts +56 -0
- package/dist/lib/commands/plan-lint.d.ts.map +1 -0
- package/dist/lib/commands/plan-lint.js +481 -0
- package/dist/lib/commands/plan-lint.js.map +1 -0
- package/dist/lib/commands/plan-phase.d.ts +53 -0
- package/dist/lib/commands/plan-phase.d.ts.map +1 -0
- package/dist/lib/commands/plan-phase.js +288 -0
- package/dist/lib/commands/plan-phase.js.map +1 -0
- package/dist/lib/commands/progress.d.ts +2 -0
- package/dist/lib/commands/progress.d.ts.map +1 -0
- package/dist/lib/commands/progress.js +266 -0
- package/dist/lib/commands/progress.js.map +1 -0
- package/dist/lib/commands/quality.d.ts +2 -0
- package/dist/lib/commands/quality.d.ts.map +1 -0
- package/dist/lib/commands/quality.js +80 -0
- package/dist/lib/commands/quality.js.map +1 -0
- package/dist/lib/commands/rollback.d.ts +2 -0
- package/dist/lib/commands/rollback.d.ts.map +1 -0
- package/dist/lib/commands/rollback.js +145 -0
- package/dist/lib/commands/rollback.js.map +1 -0
- package/dist/lib/commands/scan.d.ts +25 -0
- package/dist/lib/commands/scan.d.ts.map +1 -0
- package/dist/lib/commands/scan.js +28 -0
- package/dist/lib/commands/scan.js.map +1 -0
- package/dist/lib/commands/search.d.ts +2 -0
- package/dist/lib/commands/search.d.ts.map +1 -0
- package/dist/lib/commands/search.js +212 -0
- package/dist/lib/commands/search.js.map +1 -0
- package/dist/lib/commands/select-candidate.d.ts +128 -0
- package/dist/lib/commands/select-candidate.d.ts.map +1 -0
- package/dist/lib/commands/select-candidate.js +518 -0
- package/dist/lib/commands/select-candidate.js.map +1 -0
- package/dist/lib/commands/singularity.d.ts +2 -0
- package/dist/lib/commands/singularity.d.ts.map +1 -0
- package/dist/lib/commands/singularity.js +185 -0
- package/dist/lib/commands/singularity.js.map +1 -0
- package/dist/lib/commands/slug-timestamp.d.ts +2 -0
- package/dist/lib/commands/slug-timestamp.d.ts.map +1 -0
- package/dist/lib/commands/slug-timestamp.js +54 -0
- package/dist/lib/commands/slug-timestamp.js.map +1 -0
- package/dist/lib/commands/tail.d.ts +2 -0
- package/dist/lib/commands/tail.d.ts.map +1 -0
- package/dist/lib/commands/tail.js +100 -0
- package/dist/lib/commands/tail.js.map +1 -0
- package/dist/lib/commands/todo.d.ts +2 -0
- package/dist/lib/commands/todo.d.ts.map +1 -0
- package/dist/lib/commands/todo.js +200 -0
- package/dist/lib/commands/todo.js.map +1 -0
- package/dist/lib/commands/watch.d.ts +2 -0
- package/dist/lib/commands/watch.d.ts.map +1 -0
- package/dist/lib/commands/watch.js +72 -0
- package/dist/lib/commands/watch.js.map +1 -0
- package/dist/lib/complexity.d.ts +55 -0
- package/dist/lib/complexity.d.ts.map +1 -0
- package/dist/lib/complexity.js +80 -0
- package/dist/lib/complexity.js.map +1 -0
- package/dist/lib/context/agents.d.ts +2 -0
- package/dist/lib/context/agents.d.ts.map +1 -0
- package/dist/lib/context/agents.js +344 -0
- package/dist/lib/context/agents.js.map +1 -0
- package/dist/lib/context/base.d.ts +2 -0
- package/dist/lib/context/base.d.ts.map +1 -0
- package/dist/lib/context/base.js +81 -0
- package/dist/lib/context/base.js.map +1 -0
- package/dist/lib/context/execute.d.ts +2 -0
- package/dist/lib/context/execute.d.ts.map +1 -0
- package/dist/lib/context/execute.js +753 -0
- package/dist/lib/context/execute.js.map +1 -0
- package/dist/lib/context/index.d.ts +2 -0
- package/dist/lib/context/index.d.ts.map +1 -0
- package/dist/lib/context/index.js +88 -0
- package/dist/lib/context/index.js.map +1 -0
- package/dist/lib/context/progress.d.ts +2 -0
- package/dist/lib/context/progress.d.ts.map +1 -0
- package/dist/lib/context/progress.js +178 -0
- package/dist/lib/context/progress.js.map +1 -0
- package/dist/lib/context/project.d.ts +2 -0
- package/dist/lib/context/project.d.ts.map +1 -0
- package/dist/lib/context/project.js +413 -0
- package/dist/lib/context/project.js.map +1 -0
- package/dist/lib/context/research.d.ts +2 -0
- package/dist/lib/context/research.d.ts.map +1 -0
- package/dist/lib/context/research.js +466 -0
- package/dist/lib/context/research.js.map +1 -0
- package/dist/lib/dead-ends.d.ts +28 -0
- package/dist/lib/dead-ends.d.ts.map +1 -0
- package/dist/lib/dead-ends.js +451 -0
- package/dist/lib/dead-ends.js.map +1 -0
- package/dist/lib/deps.d.ts +2 -0
- package/dist/lib/deps.d.ts.map +1 -0
- package/dist/lib/deps.js +630 -0
- package/dist/lib/deps.js.map +1 -0
- package/dist/lib/discussion.d.ts +2 -0
- package/dist/lib/discussion.d.ts.map +1 -0
- package/dist/lib/discussion.js +1041 -0
- package/dist/lib/discussion.js.map +1 -0
- package/dist/lib/drift.d.ts +36 -0
- package/dist/lib/drift.d.ts.map +1 -0
- package/dist/lib/drift.js +481 -0
- package/dist/lib/drift.js.map +1 -0
- package/dist/lib/evolve/_dimensions-features.d.ts +2 -0
- package/dist/lib/evolve/_dimensions-features.d.ts.map +1 -0
- package/dist/lib/evolve/_dimensions-features.js +369 -0
- package/dist/lib/evolve/_dimensions-features.js.map +1 -0
- package/dist/lib/evolve/_dimensions.d.ts +2 -0
- package/dist/lib/evolve/_dimensions.d.ts.map +1 -0
- package/dist/lib/evolve/_dimensions.js +358 -0
- package/dist/lib/evolve/_dimensions.js.map +1 -0
- package/dist/lib/evolve/_product-ideation.d.ts +2 -0
- package/dist/lib/evolve/_product-ideation.d.ts.map +1 -0
- package/dist/lib/evolve/_product-ideation.js +281 -0
- package/dist/lib/evolve/_product-ideation.js.map +1 -0
- package/dist/lib/evolve/_prompts.d.ts +2 -0
- package/dist/lib/evolve/_prompts.d.ts.map +1 -0
- package/dist/lib/evolve/_prompts.js +153 -0
- package/dist/lib/evolve/_prompts.js.map +1 -0
- package/dist/lib/evolve/cli.d.ts +2 -0
- package/dist/lib/evolve/cli.d.ts.map +1 -0
- package/dist/lib/evolve/cli.js +224 -0
- package/dist/lib/evolve/cli.js.map +1 -0
- package/dist/lib/evolve/discovery.d.ts +2 -0
- package/dist/lib/evolve/discovery.d.ts.map +1 -0
- package/dist/lib/evolve/discovery.js +391 -0
- package/dist/lib/evolve/discovery.js.map +1 -0
- package/dist/lib/evolve/index.d.ts +2 -0
- package/dist/lib/evolve/index.d.ts.map +1 -0
- package/dist/lib/evolve/index.js +88 -0
- package/dist/lib/evolve/index.js.map +1 -0
- package/dist/lib/evolve/orchestrator.d.ts +2 -0
- package/dist/lib/evolve/orchestrator.d.ts.map +1 -0
- package/dist/lib/evolve/orchestrator.js +851 -0
- package/dist/lib/evolve/orchestrator.js.map +1 -0
- package/dist/lib/evolve/scoring.d.ts +2 -0
- package/dist/lib/evolve/scoring.d.ts.map +1 -0
- package/dist/lib/evolve/scoring.js +118 -0
- package/dist/lib/evolve/scoring.js.map +1 -0
- package/dist/lib/evolve/state.d.ts +2 -0
- package/dist/lib/evolve/state.d.ts.map +1 -0
- package/dist/lib/evolve/state.js +264 -0
- package/dist/lib/evolve/state.js.map +1 -0
- package/dist/lib/evolve/types.d.ts +249 -0
- package/dist/lib/evolve/types.d.ts.map +1 -0
- package/dist/lib/evolve/types.js +3 -0
- package/dist/lib/evolve/types.js.map +1 -0
- package/dist/lib/frontmatter.d.ts +2 -0
- package/dist/lib/frontmatter.d.ts.map +1 -0
- package/dist/lib/frontmatter.js +513 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/gates.d.ts +2 -0
- package/dist/lib/gates.d.ts.map +1 -0
- package/dist/lib/gates.js +578 -0
- package/dist/lib/gates.js.map +1 -0
- package/dist/lib/genome.d.ts +10 -0
- package/dist/lib/genome.d.ts.map +1 -0
- package/dist/lib/genome.js +368 -0
- package/dist/lib/genome.js.map +1 -0
- package/dist/lib/got.d.ts +2 -0
- package/dist/lib/got.d.ts.map +1 -0
- package/dist/lib/got.js +280 -0
- package/dist/lib/got.js.map +1 -0
- package/dist/lib/invariants.d.ts +2 -0
- package/dist/lib/invariants.d.ts.map +1 -0
- package/dist/lib/invariants.js +298 -0
- package/dist/lib/invariants.js.map +1 -0
- package/dist/lib/knowledge.d.ts +2 -0
- package/dist/lib/knowledge.d.ts.map +1 -0
- package/dist/lib/knowledge.js +658 -0
- package/dist/lib/knowledge.js.map +1 -0
- package/dist/lib/long-term-roadmap.d.ts +2 -0
- package/dist/lib/long-term-roadmap.d.ts.map +1 -0
- package/dist/lib/long-term-roadmap.js +602 -0
- package/dist/lib/long-term-roadmap.js.map +1 -0
- package/dist/lib/markdown-split.d.ts +2 -0
- package/dist/lib/markdown-split.d.ts.map +1 -0
- package/dist/lib/markdown-split.js +199 -0
- package/dist/lib/markdown-split.js.map +1 -0
- package/dist/lib/mcp-server.d.ts +2 -0
- package/dist/lib/mcp-server.d.ts.map +1 -0
- package/dist/lib/mcp-server.js +2424 -0
- package/dist/lib/mcp-server.js.map +1 -0
- package/dist/lib/metrics.d.ts +16 -0
- package/dist/lib/metrics.d.ts.map +1 -0
- package/dist/lib/metrics.js +48 -0
- package/dist/lib/metrics.js.map +1 -0
- package/dist/lib/overstory.d.ts +2 -0
- package/dist/lib/overstory.d.ts.map +1 -0
- package/dist/lib/overstory.js +211 -0
- package/dist/lib/overstory.js.map +1 -0
- package/dist/lib/parallel.d.ts +2 -0
- package/dist/lib/parallel.d.ts.map +1 -0
- package/dist/lib/parallel.js +349 -0
- package/dist/lib/parallel.js.map +1 -0
- package/dist/lib/paths.d.ts +2 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +254 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/phase-complete-llm.d.ts +22 -0
- package/dist/lib/phase-complete-llm.d.ts.map +1 -0
- package/dist/lib/phase-complete-llm.js +331 -0
- package/dist/lib/phase-complete-llm.js.map +1 -0
- package/dist/lib/phase-complete.d.ts +46 -0
- package/dist/lib/phase-complete.d.ts.map +1 -0
- package/dist/lib/phase-complete.js +278 -0
- package/dist/lib/phase-complete.js.map +1 -0
- package/dist/lib/phase-io.d.ts +2 -0
- package/dist/lib/phase-io.d.ts.map +1 -0
- package/dist/lib/phase-io.js +126 -0
- package/dist/lib/phase-io.js.map +1 -0
- package/dist/lib/phase.d.ts +2 -0
- package/dist/lib/phase.d.ts.map +1 -0
- package/dist/lib/phase.js +1344 -0
- package/dist/lib/phase.js.map +1 -0
- package/dist/lib/plan-tournament.d.ts +63 -0
- package/dist/lib/plan-tournament.d.ts.map +1 -0
- package/dist/lib/plan-tournament.js +353 -0
- package/dist/lib/plan-tournament.js.map +1 -0
- package/dist/lib/refinement.d.ts +74 -0
- package/dist/lib/refinement.d.ts.map +1 -0
- package/dist/lib/refinement.js +283 -0
- package/dist/lib/refinement.js.map +1 -0
- package/dist/lib/requirements.d.ts +2 -0
- package/dist/lib/requirements.d.ts.map +1 -0
- package/dist/lib/requirements.js +355 -0
- package/dist/lib/requirements.js.map +1 -0
- package/dist/lib/research-bundle.d.ts +2 -0
- package/dist/lib/research-bundle.d.ts.map +1 -0
- package/dist/lib/research-bundle.js +246 -0
- package/dist/lib/research-bundle.js.map +1 -0
- package/dist/lib/roadmap.d.ts +2 -0
- package/dist/lib/roadmap.d.ts.map +1 -0
- package/dist/lib/roadmap.js +541 -0
- package/dist/lib/roadmap.js.map +1 -0
- package/dist/lib/sample.d.ts +16 -0
- package/dist/lib/sample.d.ts.map +1 -0
- package/dist/lib/sample.js +20 -0
- package/dist/lib/sample.js.map +1 -0
- package/dist/lib/scaffold.d.ts +2 -0
- package/dist/lib/scaffold.d.ts.map +1 -0
- package/dist/lib/scaffold.js +355 -0
- package/dist/lib/scaffold.js.map +1 -0
- package/dist/lib/scan/_utils.d.ts +11 -0
- package/dist/lib/scan/_utils.d.ts.map +1 -0
- package/dist/lib/scan/_utils.js +36 -0
- package/dist/lib/scan/_utils.js.map +1 -0
- package/dist/lib/scan/base64.d.ts +15 -0
- package/dist/lib/scan/base64.d.ts.map +1 -0
- package/dist/lib/scan/base64.js +66 -0
- package/dist/lib/scan/base64.js.map +1 -0
- package/dist/lib/scan/ignorefile.d.ts +30 -0
- package/dist/lib/scan/ignorefile.d.ts.map +1 -0
- package/dist/lib/scan/ignorefile.js +101 -0
- package/dist/lib/scan/ignorefile.js.map +1 -0
- package/dist/lib/scan/injection.d.ts +14 -0
- package/dist/lib/scan/injection.d.ts.map +1 -0
- package/dist/lib/scan/injection.js +39 -0
- package/dist/lib/scan/injection.js.map +1 -0
- package/dist/lib/scan/patterns.d.ts +17 -0
- package/dist/lib/scan/patterns.d.ts.map +1 -0
- package/dist/lib/scan/patterns.js +123 -0
- package/dist/lib/scan/patterns.js.map +1 -0
- package/dist/lib/scan/strip-markdown.d.ts +7 -0
- package/dist/lib/scan/strip-markdown.d.ts.map +1 -0
- package/dist/lib/scan/strip-markdown.js +38 -0
- package/dist/lib/scan/strip-markdown.js.map +1 -0
- package/dist/lib/scan/types.d.ts +23 -0
- package/dist/lib/scan/types.d.ts.map +1 -0
- package/dist/lib/scan/types.js +3 -0
- package/dist/lib/scan/types.js.map +1 -0
- package/dist/lib/scheduler-wait.d.ts +2 -0
- package/dist/lib/scheduler-wait.d.ts.map +1 -0
- package/dist/lib/scheduler-wait.js +59 -0
- package/dist/lib/scheduler-wait.js.map +1 -0
- package/dist/lib/scheduler.d.ts +254 -0
- package/dist/lib/scheduler.d.ts.map +1 -0
- package/dist/lib/scheduler.js +1147 -0
- package/dist/lib/scheduler.js.map +1 -0
- package/dist/lib/state.d.ts +2 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +744 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/think.d.ts +18 -0
- package/dist/lib/think.d.ts.map +1 -0
- package/dist/lib/think.js +317 -0
- package/dist/lib/think.js.map +1 -0
- package/dist/lib/tracker.d.ts +2 -0
- package/dist/lib/tracker.d.ts.map +1 -0
- package/dist/lib/tracker.js +1121 -0
- package/dist/lib/tracker.js.map +1 -0
- package/dist/lib/types.d.ts +1514 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +4 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +1363 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/verify.d.ts +2 -0
- package/dist/lib/verify.d.ts.map +1 -0
- package/dist/lib/verify.js +1153 -0
- package/dist/lib/verify.js.map +1 -0
- package/dist/lib/wireup/autofix.d.ts +2 -0
- package/dist/lib/wireup/autofix.d.ts.map +1 -0
- package/dist/lib/wireup/autofix.js +188 -0
- package/dist/lib/wireup/autofix.js.map +1 -0
- package/dist/lib/wireup/cli.d.ts +2 -0
- package/dist/lib/wireup/cli.d.ts.map +1 -0
- package/dist/lib/wireup/cli.js +194 -0
- package/dist/lib/wireup/cli.js.map +1 -0
- package/dist/lib/wireup/detection.d.ts +47 -0
- package/dist/lib/wireup/detection.d.ts.map +1 -0
- package/dist/lib/wireup/detection.js +410 -0
- package/dist/lib/wireup/detection.js.map +1 -0
- package/dist/lib/wireup/discovery.d.ts +2 -0
- package/dist/lib/wireup/discovery.d.ts.map +1 -0
- package/dist/lib/wireup/discovery.js +934 -0
- package/dist/lib/wireup/discovery.js.map +1 -0
- package/dist/lib/wireup/execution.d.ts +2 -0
- package/dist/lib/wireup/execution.d.ts.map +1 -0
- package/dist/lib/wireup/execution.js +573 -0
- package/dist/lib/wireup/execution.js.map +1 -0
- package/dist/lib/wireup/index.d.ts +2 -0
- package/dist/lib/wireup/index.d.ts.map +1 -0
- package/dist/lib/wireup/index.js +85 -0
- package/dist/lib/wireup/index.js.map +1 -0
- package/dist/lib/wireup/orchestrator.d.ts +2 -0
- package/dist/lib/wireup/orchestrator.d.ts.map +1 -0
- package/dist/lib/wireup/orchestrator.js +366 -0
- package/dist/lib/wireup/orchestrator.js.map +1 -0
- package/dist/lib/wireup/report.d.ts +47 -0
- package/dist/lib/wireup/report.d.ts.map +1 -0
- package/dist/lib/wireup/report.js +201 -0
- package/dist/lib/wireup/report.js.map +1 -0
- package/dist/lib/wireup/scenarios.d.ts +2 -0
- package/dist/lib/wireup/scenarios.d.ts.map +1 -0
- package/dist/lib/wireup/scenarios.js +516 -0
- package/dist/lib/wireup/scenarios.js.map +1 -0
- package/dist/lib/wireup/state.d.ts +2 -0
- package/dist/lib/wireup/state.d.ts.map +1 -0
- package/dist/lib/wireup/state.js +102 -0
- package/dist/lib/wireup/state.js.map +1 -0
- package/dist/lib/wireup/types.d.ts +376 -0
- package/dist/lib/wireup/types.d.ts.map +1 -0
- package/dist/lib/wireup/types.js +3 -0
- package/dist/lib/wireup/types.js.map +1 -0
- package/dist/lib/worktree.d.ts +2 -0
- package/dist/lib/worktree.d.ts.map +1 -0
- package/dist/lib/worktree.js +999 -0
- package/dist/lib/worktree.js.map +1 -0
- package/lib/autopilot-milestone.ts +136 -0
- package/lib/autopilot-pipeline.ts +1179 -0
- package/lib/autopilot-waves.ts +361 -0
- package/lib/autopilot.ts +1874 -0
- package/lib/autoplan.ts +280 -0
- package/lib/autoresearch.js +4 -0
- package/lib/autoresearch.ts +886 -0
- package/lib/backend.ts +1252 -0
- package/lib/benchmark.ts +341 -0
- package/lib/citations.ts +760 -0
- package/lib/cleanup.ts +1588 -0
- package/lib/cli/adapters.ts +41 -0
- package/lib/cli/agent.ts +83 -0
- package/lib/cli/index.ts +273 -0
- package/lib/cli/output.ts +33 -0
- package/lib/cli/scan-dispatch.ts +130 -0
- package/lib/cli/tools.ts +198 -0
- package/lib/commands/_dashboard-parsers.ts +275 -0
- package/lib/commands/analysis.ts +1851 -0
- package/lib/commands/assumptions.ts +232 -0
- package/lib/commands/blame.ts +174 -0
- package/lib/commands/budget.ts +148 -0
- package/lib/commands/check-plans.ts +233 -0
- package/lib/commands/config.ts +287 -0
- package/lib/commands/dashboard.ts +680 -0
- package/lib/commands/estimate.ts +204 -0
- package/lib/commands/eval-diff.ts +252 -0
- package/lib/commands/freshness.ts +213 -0
- package/lib/commands/health.ts +607 -0
- package/lib/commands/index.ts +266 -0
- package/lib/commands/install.ts +307 -0
- package/lib/commands/knowhow-aggregator.ts +345 -0
- package/lib/commands/knowledge-search.ts +153 -0
- package/lib/commands/long-term-roadmap.ts +390 -0
- package/lib/commands/patterns.ts +465 -0
- package/lib/commands/phase-info.ts +698 -0
- package/lib/commands/plan-lint.ts +546 -0
- package/lib/commands/plan-phase.ts +375 -0
- package/lib/commands/progress.ts +319 -0
- package/lib/commands/quality.ts +138 -0
- package/lib/commands/rollback.ts +195 -0
- package/lib/commands/scan.ts +72 -0
- package/lib/commands/search.ts +300 -0
- package/lib/commands/select-candidate.ts +687 -0
- package/lib/commands/singularity.ts +222 -0
- package/lib/commands/slug-timestamp.ts +74 -0
- package/lib/commands/tail.ts +129 -0
- package/lib/commands/todo.ts +273 -0
- package/lib/commands/watch.ts +80 -0
- package/lib/complexity.ts +117 -0
- package/lib/context/agents.ts +505 -0
- package/lib/context/base.ts +123 -0
- package/lib/context/execute.ts +977 -0
- package/lib/context/index.ts +110 -0
- package/lib/context/progress.ts +278 -0
- package/lib/context/project.ts +531 -0
- package/lib/context/research.ts +646 -0
- package/lib/dead-ends.ts +506 -0
- package/lib/deps.ts +773 -0
- package/lib/discussion.ts +1275 -0
- package/lib/drift.ts +519 -0
- package/lib/evolve/_dimensions-features.ts +525 -0
- package/lib/evolve/_dimensions.ts +511 -0
- package/lib/evolve/_product-ideation.ts +405 -0
- package/lib/evolve/_prompts.ts +178 -0
- package/lib/evolve/cli.ts +330 -0
- package/lib/evolve/discovery.ts +571 -0
- package/lib/evolve/index.ts +105 -0
- package/lib/evolve/orchestrator.ts +1139 -0
- package/lib/evolve/scoring.ts +167 -0
- package/lib/evolve/state.ts +330 -0
- package/lib/evolve/types.ts +290 -0
- package/lib/frontmatter.ts +615 -0
- package/lib/gates.ts +695 -0
- package/lib/genome.ts +402 -0
- package/lib/got.js +4 -0
- package/lib/got.ts +361 -0
- package/lib/invariants.ts +378 -0
- package/lib/knowledge.ts +768 -0
- package/lib/long-term-roadmap.ts +806 -0
- package/lib/markdown-split.ts +273 -0
- package/lib/mcp-server.ts +3292 -0
- package/lib/metrics.ts +49 -0
- package/lib/overstory.ts +270 -0
- package/lib/parallel.ts +570 -0
- package/lib/paths.ts +293 -0
- package/lib/phase-complete-llm.ts +376 -0
- package/lib/phase-complete.ts +366 -0
- package/lib/phase-io.ts +101 -0
- package/lib/phase.ts +1981 -0
- package/lib/plan-tournament.ts +426 -0
- package/lib/refinement.ts +349 -0
- package/lib/requirements.ts +469 -0
- package/lib/research-bundle.ts +300 -0
- package/lib/roadmap.ts +775 -0
- package/lib/scaffold.ts +480 -0
- package/lib/scan/_utils.ts +37 -0
- package/lib/scan/base64.ts +90 -0
- package/lib/scan/ignorefile.ts +109 -0
- package/lib/scan/injection.ts +67 -0
- package/lib/scan/patterns.ts +139 -0
- package/lib/scan/strip-markdown.ts +39 -0
- package/lib/scan/types.ts +28 -0
- package/lib/scheduler-wait.ts +58 -0
- package/lib/scheduler.ts +1370 -0
- package/lib/state.ts +1000 -0
- package/lib/think.ts +365 -0
- package/lib/tracker.ts +1591 -0
- package/lib/types.ts +1663 -0
- package/lib/utils.ts +1479 -0
- package/lib/verify.ts +1434 -0
- package/lib/wireup/autofix.ts +241 -0
- package/lib/wireup/cli.ts +278 -0
- package/lib/wireup/detection.ts +542 -0
- package/lib/wireup/discovery.ts +1063 -0
- package/lib/wireup/execution.ts +686 -0
- package/lib/wireup/index.ts +117 -0
- package/lib/wireup/orchestrator.ts +519 -0
- package/lib/wireup/report.ts +286 -0
- package/lib/wireup/scenarios.ts +616 -0
- package/lib/wireup/state.ts +139 -0
- package/lib/wireup/types.ts +436 -0
- package/lib/worktree.ts +1309 -0
- package/package.json +67 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GRD Frontmatter Operations -- YAML frontmatter parse/reconstruct/splice/validate
|
|
5
|
+
*
|
|
6
|
+
* Extracted from bin/grd-tools.js during Phase 03 modularization.
|
|
7
|
+
* Depends on: lib/utils.ts (safeReadFile, output, error)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import type { FrontmatterObject } from './types';
|
|
12
|
+
|
|
13
|
+
const { safeReadFile, output, error } = require('./utils');
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
// ─── Domain Types ─────────────────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Parsed result from parseMustHavesBlock for artifact entries.
|
|
21
|
+
*/
|
|
22
|
+
interface MustHavesArtifact {
|
|
23
|
+
path: string;
|
|
24
|
+
provides?: string;
|
|
25
|
+
exports?: string[];
|
|
26
|
+
min_lines?: number;
|
|
27
|
+
contains?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parsed result from parseMustHavesBlock for key_links entries.
|
|
32
|
+
*/
|
|
33
|
+
interface MustHavesKeyLink {
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
via: string;
|
|
37
|
+
pattern?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Schema definition for frontmatter validation.
|
|
42
|
+
*/
|
|
43
|
+
interface FrontmatterSchemaDefinition {
|
|
44
|
+
required: string[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Validation result from cmdFrontmatterValidate.
|
|
49
|
+
*/
|
|
50
|
+
interface FrontmatterValidationResult {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
missing: string[];
|
|
53
|
+
present: string[];
|
|
54
|
+
schema: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Internal stack frame for YAML frontmatter parsing.
|
|
59
|
+
*/
|
|
60
|
+
interface ParseStackFrame {
|
|
61
|
+
obj: Record<string, unknown> | unknown[];
|
|
62
|
+
key: string | null;
|
|
63
|
+
indent: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ─── Schema Constant ──────────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
const FRONTMATTER_SCHEMAS: Record<string, FrontmatterSchemaDefinition> = {
|
|
69
|
+
plan: {
|
|
70
|
+
required: [
|
|
71
|
+
'phase',
|
|
72
|
+
'plan',
|
|
73
|
+
'type',
|
|
74
|
+
'wave',
|
|
75
|
+
'depends_on',
|
|
76
|
+
'files_modified',
|
|
77
|
+
'autonomous',
|
|
78
|
+
'must_haves',
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
summary: { required: ['phase', 'plan', 'subsystem', 'tags', 'duration', 'completed'] },
|
|
82
|
+
verification: { required: ['phase', 'verified', 'status', 'score'] },
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// ─── Core Frontmatter Functions ─────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Parse a raw YAML value string into a typed JavaScript value.
|
|
89
|
+
* Strips surrounding quotes and returns the cleaned string.
|
|
90
|
+
*/
|
|
91
|
+
function parseYamlValue(rawValue: string): string {
|
|
92
|
+
return rawValue.replace(/^["']|["']$/g, '');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parse YAML frontmatter from markdown content into a JavaScript object.
|
|
97
|
+
* @param content - Markdown content with optional YAML frontmatter between --- delimiters
|
|
98
|
+
* @returns Parsed frontmatter as a FrontmatterObject, or empty object if no frontmatter found
|
|
99
|
+
*/
|
|
100
|
+
function extractFrontmatter(content: string): FrontmatterObject {
|
|
101
|
+
const frontmatter: FrontmatterObject = {};
|
|
102
|
+
const match = content.match(/^---\n([\s\S]+?)\n---/);
|
|
103
|
+
if (!match) return frontmatter;
|
|
104
|
+
|
|
105
|
+
const yaml = match[1];
|
|
106
|
+
const lines = yaml.split('\n');
|
|
107
|
+
|
|
108
|
+
// Stack to track nested objects: [{obj, key, indent}]
|
|
109
|
+
// obj = object to write to, key = current key collecting array items, indent = indentation level
|
|
110
|
+
const stack: ParseStackFrame[] = [{ obj: frontmatter, key: null, indent: -1 }];
|
|
111
|
+
|
|
112
|
+
for (const line of lines) {
|
|
113
|
+
// Skip empty lines
|
|
114
|
+
if (line.trim() === '') continue;
|
|
115
|
+
|
|
116
|
+
// Calculate indentation (number of leading spaces)
|
|
117
|
+
const indentMatch = line.match(/^(\s*)/);
|
|
118
|
+
const indent = indentMatch ? indentMatch[1].length : 0;
|
|
119
|
+
|
|
120
|
+
// Pop stack back to appropriate level
|
|
121
|
+
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
122
|
+
stack.pop();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const current = stack[stack.length - 1];
|
|
126
|
+
const currentObj = current.obj as Record<string, unknown>;
|
|
127
|
+
|
|
128
|
+
// Check for key: value pattern
|
|
129
|
+
const keyMatch = line.match(/^(\s*)([a-zA-Z0-9_-]+):\s*(.*)/);
|
|
130
|
+
if (keyMatch) {
|
|
131
|
+
const key = keyMatch[2];
|
|
132
|
+
const value = keyMatch[3].trim();
|
|
133
|
+
|
|
134
|
+
if (value === '' || value === '[') {
|
|
135
|
+
// Key with no value or opening bracket -- could be nested object or array
|
|
136
|
+
// We'll determine based on next lines, for now create placeholder
|
|
137
|
+
currentObj[key] = value === '[' ? [] : {};
|
|
138
|
+
current.key = null;
|
|
139
|
+
// Push new context for potential nested content
|
|
140
|
+
stack.push({ obj: currentObj[key] as Record<string, unknown>, key: null, indent });
|
|
141
|
+
} else if (value.startsWith('[') && value.endsWith(']')) {
|
|
142
|
+
// Inline array: key: [a, b, c]
|
|
143
|
+
currentObj[key] = value
|
|
144
|
+
.slice(1, -1)
|
|
145
|
+
.split(',')
|
|
146
|
+
.map((s: string) => s.trim().replace(/^["']|["']$/g, ''))
|
|
147
|
+
.filter(Boolean);
|
|
148
|
+
current.key = null;
|
|
149
|
+
} else {
|
|
150
|
+
// Simple key: value
|
|
151
|
+
currentObj[key] = parseYamlValue(value);
|
|
152
|
+
current.key = null;
|
|
153
|
+
}
|
|
154
|
+
} else if (line.trim().startsWith('- ')) {
|
|
155
|
+
// Array item
|
|
156
|
+
const itemValue = parseYamlValue(line.trim().slice(2));
|
|
157
|
+
|
|
158
|
+
// If current context is an empty object, convert to array
|
|
159
|
+
if (
|
|
160
|
+
typeof current.obj === 'object' &&
|
|
161
|
+
!Array.isArray(current.obj) &&
|
|
162
|
+
Object.keys(current.obj as Record<string, unknown>).length === 0
|
|
163
|
+
) {
|
|
164
|
+
// Find the key in parent that points to this object and convert it
|
|
165
|
+
const parent = stack.length > 1 ? stack[stack.length - 2] : null;
|
|
166
|
+
if (parent) {
|
|
167
|
+
const parentObj = parent.obj as Record<string, unknown>;
|
|
168
|
+
for (const k of Object.keys(parentObj)) {
|
|
169
|
+
if (parentObj[k] === current.obj) {
|
|
170
|
+
parentObj[k] = [itemValue];
|
|
171
|
+
current.obj = parentObj[k] as unknown[];
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
} else if (Array.isArray(current.obj)) {
|
|
177
|
+
current.obj.push(itemValue);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return frontmatter;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Serialize a JavaScript object to YAML frontmatter body lines.
|
|
187
|
+
*
|
|
188
|
+
* The returned string is the BODY only — no leading/trailing `---`
|
|
189
|
+
* delimiters and no trailing newline. Callers are responsible for
|
|
190
|
+
* wrapping it. The canonical usage is:
|
|
191
|
+
*
|
|
192
|
+
* const body = reconstructFrontmatter(obj);
|
|
193
|
+
* const block = `---\n${body}\n---\n`; // note the newline before `---`
|
|
194
|
+
*
|
|
195
|
+
* Concatenating `'---\n' + body + '---\n'` without the extra newline
|
|
196
|
+
* glues the closing `---` onto the last field's line and produces
|
|
197
|
+
* malformed YAML. See spliceFrontmatter (this file) for a worked
|
|
198
|
+
* example.
|
|
199
|
+
*
|
|
200
|
+
* @param obj - Object to serialize into YAML-like frontmatter format
|
|
201
|
+
* @returns YAML-formatted body lines joined by `\n`, no trailing newline
|
|
202
|
+
*/
|
|
203
|
+
function reconstructFrontmatter(obj: FrontmatterObject): string {
|
|
204
|
+
const lines: string[] = [];
|
|
205
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
206
|
+
if (value === null || value === undefined) continue;
|
|
207
|
+
if (Array.isArray(value)) {
|
|
208
|
+
if (value.length === 0) {
|
|
209
|
+
lines.push(`${key}: []`);
|
|
210
|
+
} else if (
|
|
211
|
+
value.every((v: unknown) => typeof v === 'string') &&
|
|
212
|
+
value.length <= 3 &&
|
|
213
|
+
(value as string[]).join(', ').length < 60
|
|
214
|
+
) {
|
|
215
|
+
lines.push(`${key}: [${(value as string[]).join(', ')}]`);
|
|
216
|
+
} else {
|
|
217
|
+
lines.push(`${key}:`);
|
|
218
|
+
for (const item of value) {
|
|
219
|
+
lines.push(
|
|
220
|
+
` - ${typeof item === 'string' && (item.includes(':') || item.includes('#')) ? `"${item}"` : item}`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
} else if (typeof value === 'object') {
|
|
225
|
+
lines.push(`${key}:`);
|
|
226
|
+
const valueObj = value as Record<string, unknown>;
|
|
227
|
+
for (const [subkey, subval] of Object.entries(valueObj)) {
|
|
228
|
+
if (subval === null || subval === undefined) continue;
|
|
229
|
+
if (Array.isArray(subval)) {
|
|
230
|
+
if (subval.length === 0) {
|
|
231
|
+
lines.push(` ${subkey}: []`);
|
|
232
|
+
} else if (
|
|
233
|
+
subval.every((v: unknown) => typeof v === 'string') &&
|
|
234
|
+
subval.length <= 3 &&
|
|
235
|
+
(subval as string[]).join(', ').length < 60
|
|
236
|
+
) {
|
|
237
|
+
lines.push(` ${subkey}: [${(subval as string[]).join(', ')}]`);
|
|
238
|
+
} else {
|
|
239
|
+
lines.push(` ${subkey}:`);
|
|
240
|
+
for (const item of subval) {
|
|
241
|
+
lines.push(
|
|
242
|
+
` - ${typeof item === 'string' && (item.includes(':') || item.includes('#')) ? `"${item}"` : item}`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
} else if (typeof subval === 'object') {
|
|
247
|
+
lines.push(` ${subkey}:`);
|
|
248
|
+
const subvalObj = subval as Record<string, unknown>;
|
|
249
|
+
for (const [subsubkey, subsubval] of Object.entries(subvalObj)) {
|
|
250
|
+
if (subsubval === null || subsubval === undefined) continue;
|
|
251
|
+
if (Array.isArray(subsubval)) {
|
|
252
|
+
if (subsubval.length === 0) {
|
|
253
|
+
lines.push(` ${subsubkey}: []`);
|
|
254
|
+
} else {
|
|
255
|
+
lines.push(` ${subsubkey}:`);
|
|
256
|
+
for (const item of subsubval) {
|
|
257
|
+
lines.push(` - ${item}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
lines.push(` ${subsubkey}: ${subsubval}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
const sv = String(subval);
|
|
266
|
+
lines.push(` ${subkey}: ${sv.includes(':') || sv.includes('#') ? `"${sv}"` : sv}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
const sv = String(value);
|
|
271
|
+
if (sv.includes(':') || sv.includes('#') || sv.startsWith('[') || sv.startsWith('{')) {
|
|
272
|
+
lines.push(`${key}: "${sv}"`);
|
|
273
|
+
} else {
|
|
274
|
+
lines.push(`${key}: ${sv}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return lines.join('\n');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Replace or prepend frontmatter in markdown content with new object data.
|
|
283
|
+
* @param content - Original markdown content
|
|
284
|
+
* @param newObj - New frontmatter object to serialize and splice in
|
|
285
|
+
* @returns Updated markdown content with replaced frontmatter
|
|
286
|
+
*/
|
|
287
|
+
function spliceFrontmatter(content: string, newObj: FrontmatterObject): string {
|
|
288
|
+
const yamlStr = reconstructFrontmatter(newObj);
|
|
289
|
+
const match = content.match(/^---\n[\s\S]+?\n---/);
|
|
290
|
+
if (match) {
|
|
291
|
+
return `---\n${yamlStr}\n---` + content.slice(match[0].length);
|
|
292
|
+
}
|
|
293
|
+
return `---\n${yamlStr}\n---\n\n` + content;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Parse a specific block from must_haves in raw frontmatter YAML.
|
|
298
|
+
* Handles 3-level nesting: must_haves > artifacts/key_links > [{path, provides, ...}].
|
|
299
|
+
* @param content - Full markdown content with frontmatter
|
|
300
|
+
* @param blockName - Block name within must_haves (e.g., 'truths', 'artifacts', 'key_links')
|
|
301
|
+
* @returns Array of parsed items from the block, or empty array if not found
|
|
302
|
+
*/
|
|
303
|
+
function parseMustHavesBlock(
|
|
304
|
+
content: string,
|
|
305
|
+
blockName: string
|
|
306
|
+
): Array<string | MustHavesArtifact | MustHavesKeyLink> {
|
|
307
|
+
// Extract a specific block from must_haves in raw frontmatter YAML.
|
|
308
|
+
// Handles 3-level nesting: must_haves > artifacts/key_links > [{path, ...}].
|
|
309
|
+
//
|
|
310
|
+
// Block indent is auto-detected (2 or 4 spaces). Both indentation styles
|
|
311
|
+
// appear in the wild: the canonical planner emits 2-space, while older
|
|
312
|
+
// verify.test.ts fixtures use 4-space. Item indent is always blockIndent+2;
|
|
313
|
+
// continuation +2; array items under a continuation key +2.
|
|
314
|
+
const fmMatch = content.match(/^---\n([\s\S]+?)\n---/);
|
|
315
|
+
if (!fmMatch) return [];
|
|
316
|
+
|
|
317
|
+
const yaml = fmMatch[1];
|
|
318
|
+
const blockMatch = yaml.match(new RegExp(`^(\\s+)${blockName}:\\s*$`, 'm'));
|
|
319
|
+
if (!blockMatch || blockMatch.index === undefined) return [];
|
|
320
|
+
|
|
321
|
+
const blockIndent: number = blockMatch[1].length;
|
|
322
|
+
// Only accept 2 or 4 (the two styles seen in the repo). Bail on others
|
|
323
|
+
// rather than risk misparsing unrelated YAML.
|
|
324
|
+
if (blockIndent !== 2 && blockIndent !== 4) return [];
|
|
325
|
+
|
|
326
|
+
const itemIndent: number = blockIndent + 2;
|
|
327
|
+
const contIndent: number = itemIndent + 2;
|
|
328
|
+
const arrIndent: number = contIndent + 2;
|
|
329
|
+
|
|
330
|
+
const itemDashPattern = new RegExp(`^\\s{${itemIndent}}-\\s+`);
|
|
331
|
+
const itemSimplePattern = new RegExp(`^\\s{${itemIndent}}-\\s+"?([^"]+)"?\\s*$`);
|
|
332
|
+
const itemKvPattern = new RegExp(`^\\s{${itemIndent}}-\\s+(\\w+):\\s*"?([^"]*)"?\\s*$`);
|
|
333
|
+
// Inline-array continuation: `exports: ["foo", "bar"]` — must be tried
|
|
334
|
+
// BEFORE the scalar contKvPattern, which would capture only `[`.
|
|
335
|
+
const contInlineArrPattern = new RegExp(`^\\s{${contIndent},}(\\w+):\\s*\\[(.*)\\]\\s*$`);
|
|
336
|
+
const contKvPattern = new RegExp(`^\\s{${contIndent},}(\\w+):\\s*"?([^"]*)"?\\s*$`);
|
|
337
|
+
const arrItemPattern = new RegExp(`^\\s{${arrIndent},}-\\s+"?([^"]+)"?\\s*$`);
|
|
338
|
+
|
|
339
|
+
const splitInlineArray = (body: string): string[] =>
|
|
340
|
+
body
|
|
341
|
+
.split(',')
|
|
342
|
+
.map((s) => s.trim().replace(/^["']|["']$/g, ''))
|
|
343
|
+
.filter((s) => s.length > 0);
|
|
344
|
+
|
|
345
|
+
const afterBlock = yaml.slice(blockMatch.index);
|
|
346
|
+
const blockLines = afterBlock.split('\n').slice(1); // skip the header line
|
|
347
|
+
|
|
348
|
+
const items: Array<string | Record<string, unknown>> = [];
|
|
349
|
+
let current: Record<string, unknown> | string | null = null;
|
|
350
|
+
|
|
351
|
+
for (const line of blockLines) {
|
|
352
|
+
if (line.trim() === '') continue;
|
|
353
|
+
const indentMatch = line.match(/^(\s*)/);
|
|
354
|
+
const indent: number = indentMatch ? indentMatch[1].length : 0;
|
|
355
|
+
// Stop at the block header level or shallower — we've left this block.
|
|
356
|
+
if (indent <= blockIndent && line.trim() !== '') break;
|
|
357
|
+
|
|
358
|
+
if (itemDashPattern.test(line)) {
|
|
359
|
+
// New list item at itemIndent.
|
|
360
|
+
if (current !== null) items.push(current);
|
|
361
|
+
current = {};
|
|
362
|
+
const simpleMatch = line.match(itemSimplePattern);
|
|
363
|
+
if (simpleMatch && !line.includes(':')) {
|
|
364
|
+
current = simpleMatch[1];
|
|
365
|
+
} else {
|
|
366
|
+
const kvMatch = line.match(itemKvPattern);
|
|
367
|
+
if (kvMatch) {
|
|
368
|
+
current = {} as Record<string, unknown>;
|
|
369
|
+
current[kvMatch[1]] = kvMatch[2];
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
} else if (current !== null && typeof current === 'object') {
|
|
373
|
+
// Inline-array (e.g. `exports: ["foo", "bar"]`) MUST be matched before
|
|
374
|
+
// the scalar pattern, which would otherwise capture only the opening `[`.
|
|
375
|
+
const inlineArrMatch = line.match(contInlineArrPattern);
|
|
376
|
+
if (inlineArrMatch) {
|
|
377
|
+
(current as Record<string, unknown>)[inlineArrMatch[1]] = splitInlineArray(
|
|
378
|
+
inlineArrMatch[2]
|
|
379
|
+
);
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
const kvMatch = line.match(contKvPattern);
|
|
383
|
+
if (kvMatch) {
|
|
384
|
+
const val = kvMatch[2];
|
|
385
|
+
(current as Record<string, unknown>)[kvMatch[1]] = /^\d+$/.test(val)
|
|
386
|
+
? parseInt(val, 10)
|
|
387
|
+
: val;
|
|
388
|
+
}
|
|
389
|
+
const arrMatch = line.match(arrItemPattern);
|
|
390
|
+
if (arrMatch) {
|
|
391
|
+
const keys = Object.keys(current as Record<string, unknown>);
|
|
392
|
+
const lastKey = keys[keys.length - 1];
|
|
393
|
+
if (lastKey && !Array.isArray((current as Record<string, unknown>)[lastKey])) {
|
|
394
|
+
const existing = (current as Record<string, unknown>)[lastKey];
|
|
395
|
+
(current as Record<string, unknown>)[lastKey] = existing ? [existing] : [];
|
|
396
|
+
}
|
|
397
|
+
if (lastKey) ((current as Record<string, unknown>)[lastKey] as unknown[]).push(arrMatch[1]);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (current !== null) items.push(current);
|
|
402
|
+
|
|
403
|
+
return items as Array<string | MustHavesArtifact | MustHavesKeyLink>;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// ─── Frontmatter Command Functions ──────────────────────────────────────────
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* CLI command: Get frontmatter field(s) from a markdown file.
|
|
410
|
+
* @param cwd - Project working directory
|
|
411
|
+
* @param filePath - Path to the markdown file
|
|
412
|
+
* @param field - Specific field to extract, or null for all fields
|
|
413
|
+
* @param raw - Output raw text instead of JSON
|
|
414
|
+
*/
|
|
415
|
+
function cmdFrontmatterGet(
|
|
416
|
+
cwd: string,
|
|
417
|
+
filePath: string,
|
|
418
|
+
field: string | null,
|
|
419
|
+
raw: boolean
|
|
420
|
+
): void {
|
|
421
|
+
if (!filePath) {
|
|
422
|
+
error('file path required');
|
|
423
|
+
}
|
|
424
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
425
|
+
const content = safeReadFile(fullPath);
|
|
426
|
+
if (!content) {
|
|
427
|
+
output({ error: 'File not found', path: filePath }, raw);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const fm = extractFrontmatter(content);
|
|
431
|
+
if (field) {
|
|
432
|
+
const value = fm[field];
|
|
433
|
+
if (value === undefined) {
|
|
434
|
+
output({ error: 'Field not found', field }, raw);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
output({ [field]: value }, raw, JSON.stringify(value));
|
|
438
|
+
} else {
|
|
439
|
+
output(fm, raw, `${Object.keys(fm).length} fields: ${Object.keys(fm).join(', ')}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* CLI command: Set a frontmatter field in a markdown file.
|
|
445
|
+
* @param cwd - Project working directory
|
|
446
|
+
* @param filePath - Path to the markdown file
|
|
447
|
+
* @param field - Field name to set
|
|
448
|
+
* @param value - Value to set (JSON-parsed if valid JSON, otherwise stored as string)
|
|
449
|
+
* @param raw - Output raw text instead of JSON
|
|
450
|
+
* @returns void — writes the updated file to disk and outputs result via the output helper
|
|
451
|
+
*/
|
|
452
|
+
function cmdFrontmatterSet(
|
|
453
|
+
cwd: string,
|
|
454
|
+
filePath: string,
|
|
455
|
+
field: string,
|
|
456
|
+
value: string,
|
|
457
|
+
raw: boolean
|
|
458
|
+
): void {
|
|
459
|
+
if (!filePath || !field || value === undefined) {
|
|
460
|
+
error('file, field, and value required. Usage: frontmatter set <file> <field> <value>');
|
|
461
|
+
}
|
|
462
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
463
|
+
if (!fs.existsSync(fullPath)) {
|
|
464
|
+
output({ error: 'File not found', path: filePath }, raw);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const content = fs.readFileSync(fullPath, 'utf-8') as string;
|
|
468
|
+
const fm = extractFrontmatter(content);
|
|
469
|
+
let parsedValue: unknown;
|
|
470
|
+
try {
|
|
471
|
+
parsedValue = JSON.parse(value);
|
|
472
|
+
} catch {
|
|
473
|
+
parsedValue = value;
|
|
474
|
+
}
|
|
475
|
+
fm[field] = parsedValue;
|
|
476
|
+
const newContent = spliceFrontmatter(content, fm);
|
|
477
|
+
fs.writeFileSync(fullPath, newContent, 'utf-8');
|
|
478
|
+
output({ updated: true, field, value: parsedValue }, raw, 'true');
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* CLI command: Merge JSON data into existing frontmatter of a markdown file.
|
|
483
|
+
* @param cwd - Project working directory
|
|
484
|
+
* @param filePath - Path to the markdown file
|
|
485
|
+
* @param data - JSON string of key-value pairs to merge into frontmatter
|
|
486
|
+
* @param raw - Output raw text instead of JSON
|
|
487
|
+
* @returns void — writes the updated file to disk and outputs result via the output helper
|
|
488
|
+
*/
|
|
489
|
+
function cmdFrontmatterMerge(cwd: string, filePath: string, data: string, raw: boolean): void {
|
|
490
|
+
if (!filePath || !data) {
|
|
491
|
+
error('file and data required');
|
|
492
|
+
}
|
|
493
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
494
|
+
if (!fs.existsSync(fullPath)) {
|
|
495
|
+
output({ error: 'File not found', path: filePath }, raw);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
const content = fs.readFileSync(fullPath, 'utf-8') as string;
|
|
499
|
+
const fm = extractFrontmatter(content);
|
|
500
|
+
let mergeData: Record<string, unknown>;
|
|
501
|
+
try {
|
|
502
|
+
mergeData = JSON.parse(data) as Record<string, unknown>;
|
|
503
|
+
} catch {
|
|
504
|
+
error('Invalid JSON for --data');
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
Object.assign(fm, mergeData);
|
|
508
|
+
const newContent = spliceFrontmatter(content, fm);
|
|
509
|
+
fs.writeFileSync(fullPath, newContent, 'utf-8');
|
|
510
|
+
output({ merged: true, fields: Object.keys(mergeData) }, raw, 'true');
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* CLI command: Validate frontmatter against a named schema.
|
|
515
|
+
* @param cwd - Project working directory
|
|
516
|
+
* @param filePath - Path to the markdown file to validate
|
|
517
|
+
* @param schemaName - Schema name ('plan', 'summary', or 'verification')
|
|
518
|
+
* @param raw - Output raw text instead of JSON
|
|
519
|
+
* @returns void — outputs validation result (valid/invalid, missing fields) via the output helper
|
|
520
|
+
*/
|
|
521
|
+
function cmdFrontmatterValidate(
|
|
522
|
+
cwd: string,
|
|
523
|
+
filePath: string,
|
|
524
|
+
schemaName: string,
|
|
525
|
+
raw: boolean
|
|
526
|
+
): void {
|
|
527
|
+
if (!filePath || !schemaName) {
|
|
528
|
+
error('file and schema required');
|
|
529
|
+
}
|
|
530
|
+
const schema = FRONTMATTER_SCHEMAS[schemaName];
|
|
531
|
+
if (!schema) {
|
|
532
|
+
error(
|
|
533
|
+
`Unknown schema: ${schemaName}. Available: ${Object.keys(FRONTMATTER_SCHEMAS).join(', ')}`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
537
|
+
const content = safeReadFile(fullPath);
|
|
538
|
+
if (!content) {
|
|
539
|
+
output({ error: 'File not found', path: filePath }, raw);
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
const fm = extractFrontmatter(content);
|
|
543
|
+
const missing = schema.required.filter((f: string) => fm[f] === undefined);
|
|
544
|
+
const present = schema.required.filter((f: string) => fm[f] !== undefined);
|
|
545
|
+
const result: FrontmatterValidationResult = {
|
|
546
|
+
valid: missing.length === 0,
|
|
547
|
+
missing,
|
|
548
|
+
present,
|
|
549
|
+
schema: schemaName,
|
|
550
|
+
};
|
|
551
|
+
output(result, raw, missing.length === 0 ? 'valid' : 'invalid');
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// ─── Phase Roadmap Metadata ───────────────────────────────────────────────────
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Extract metadata fields from the ROADMAP.md section for a specific phase.
|
|
558
|
+
* @param cwd - Project working directory
|
|
559
|
+
* @param phaseNum - Phase number (e.g., '1', '01', '2.1')
|
|
560
|
+
* @returns Metadata object with fields like verification_level, eval_targets
|
|
561
|
+
*/
|
|
562
|
+
function getPhaseRoadmapMetadata(cwd: string, phaseNum: string): Record<string, string> {
|
|
563
|
+
const roadmapPath = path.join(cwd, '.planning', 'ROADMAP.md');
|
|
564
|
+
let roadmapContent: string;
|
|
565
|
+
try {
|
|
566
|
+
roadmapContent = fs.readFileSync(roadmapPath, 'utf-8') as string;
|
|
567
|
+
} catch {
|
|
568
|
+
return {};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Find the phase section
|
|
572
|
+
const phaseEscaped = String(phaseNum).replace(/\./g, '\\.');
|
|
573
|
+
const phaseSectionPattern = new RegExp(
|
|
574
|
+
`#{2,3}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?(?=\\n#{2,3}\\s|$)`,
|
|
575
|
+
'i'
|
|
576
|
+
);
|
|
577
|
+
const sectionMatch = roadmapContent.match(phaseSectionPattern);
|
|
578
|
+
if (!sectionMatch) return {};
|
|
579
|
+
|
|
580
|
+
const section = sectionMatch[0];
|
|
581
|
+
const metadata: Record<string, string> = {};
|
|
582
|
+
|
|
583
|
+
// Extract verification_level
|
|
584
|
+
const verificationMatch = section.match(/\*\*Verification level:\*\*\s*(.+)/i);
|
|
585
|
+
if (verificationMatch) {
|
|
586
|
+
metadata.verification_level = verificationMatch[1].trim();
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Extract eval_targets
|
|
590
|
+
const evalTargetsMatch = section.match(/\*\*Eval targets:\*\*\s*(.+)/i);
|
|
591
|
+
if (evalTargetsMatch) {
|
|
592
|
+
metadata.eval_targets = evalTargetsMatch[1].trim();
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
return metadata;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// ─── Exports ─────────────────────────────────────────────────────────────────
|
|
599
|
+
|
|
600
|
+
module.exports = {
|
|
601
|
+
// Core functions
|
|
602
|
+
extractFrontmatter,
|
|
603
|
+
reconstructFrontmatter,
|
|
604
|
+
spliceFrontmatter,
|
|
605
|
+
parseMustHavesBlock,
|
|
606
|
+
// Command functions
|
|
607
|
+
cmdFrontmatterGet,
|
|
608
|
+
cmdFrontmatterSet,
|
|
609
|
+
cmdFrontmatterMerge,
|
|
610
|
+
cmdFrontmatterValidate,
|
|
611
|
+
// Constants
|
|
612
|
+
FRONTMATTER_SCHEMAS,
|
|
613
|
+
// Roadmap metadata
|
|
614
|
+
getPhaseRoadmapMetadata,
|
|
615
|
+
};
|