@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,830 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const childProcess = require('child_process');
|
|
6
|
+
const { execGit, getMilestoneInfo, findPhaseInternal, loadConfig, resolveModelForAgent, MODEL_PROFILES: _MODEL_PROFILES_FOR_REFINEMENT, } = require('./utils');
|
|
7
|
+
const { getEffectiveTierForDispatch, } = require('./backend');
|
|
8
|
+
const { pushAndCreatePR, } = require('./worktree');
|
|
9
|
+
const { completePhaseAfterPostPipeline } = require('./phase-complete');
|
|
10
|
+
const { collectMetrics: _collectMetrics, checkConvergence: _checkConvergence, classifyBranch: _classifyBranch, detectMinima: _detectMinima, buildCritiquePrompt: _buildCritiquePromptFn, } = require('./refinement');
|
|
11
|
+
const { atomicWriteFileSync, } = require('./autopilot-waves');
|
|
12
|
+
/** Normalize SchedulerSpawnResult to SpawnResult for drop-in compatibility. */
|
|
13
|
+
function toSpawnResult(sr) {
|
|
14
|
+
return { exitCode: sr.exitCode, timedOut: sr.timedOut, stdout: sr.stdout, stderr: sr.stderr };
|
|
15
|
+
}
|
|
16
|
+
// ─── Status Markers ───────────────────────────────────────────────────────────
|
|
17
|
+
const AUTOPILOT_DIR = 'autopilot';
|
|
18
|
+
/**
|
|
19
|
+
* Write a status marker JSON file for tracking autopilot progress.
|
|
20
|
+
*/
|
|
21
|
+
function writeStatusMarker(cwd, phaseNum, step, status) {
|
|
22
|
+
const dir = path.join(cwd, '.planning', AUTOPILOT_DIR);
|
|
23
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
24
|
+
const marker = {
|
|
25
|
+
phase: phaseNum,
|
|
26
|
+
step,
|
|
27
|
+
status,
|
|
28
|
+
timestamp: new Date().toISOString(),
|
|
29
|
+
};
|
|
30
|
+
const filename = `phase-${phaseNum}-${step}.json`;
|
|
31
|
+
atomicWriteFileSync(path.join(dir, filename), JSON.stringify(marker, null, 2));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Update STATE.md current phase and status fields.
|
|
35
|
+
*/
|
|
36
|
+
function updateStateProgress(cwd, phaseNum, step) {
|
|
37
|
+
const statePath = path.join(cwd, '.planning', 'STATE.md');
|
|
38
|
+
if (!fs.existsSync(statePath))
|
|
39
|
+
return;
|
|
40
|
+
// Use synchronous file locking for safe concurrent access under parallel execution.
|
|
41
|
+
// Lock file prevents races when multiple phases update STATE.md concurrently.
|
|
42
|
+
const lockPath = `${statePath}.lock`;
|
|
43
|
+
const maxRetries = 50;
|
|
44
|
+
let lockAcquired = false;
|
|
45
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
46
|
+
try {
|
|
47
|
+
const fd = fs.openSync(lockPath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY);
|
|
48
|
+
fs.closeSync(fd);
|
|
49
|
+
lockAcquired = true;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
if (e.code === 'EEXIST') {
|
|
54
|
+
// Check for stale lock (older than 30 seconds)
|
|
55
|
+
try {
|
|
56
|
+
const stat = fs.statSync(lockPath);
|
|
57
|
+
if (Date.now() - stat.mtimeMs > 30000) {
|
|
58
|
+
fs.unlinkSync(lockPath);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (statErr) {
|
|
63
|
+
if (statErr.code !== 'ENOENT')
|
|
64
|
+
throw statErr;
|
|
65
|
+
// Lock file gone between check — retry
|
|
66
|
+
}
|
|
67
|
+
// Brief synchronous wait
|
|
68
|
+
const start = Date.now();
|
|
69
|
+
while (Date.now() - start < 10) {
|
|
70
|
+
/* spin */
|
|
71
|
+
}
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
throw e;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!lockAcquired) {
|
|
78
|
+
process.stderr.write(`[autopilot] Warning: failed to acquire lock on ${statePath} after ${maxRetries} retries, skipping state update\n`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
let content = fs.readFileSync(statePath, 'utf-8');
|
|
83
|
+
// Update Current Phase field
|
|
84
|
+
content = content.replace(/(\*\*Current Phase:\*\*)\s*[^\n]*/, `$1 Phase ${phaseNum} (autopilot: ${step})`);
|
|
85
|
+
atomicWriteFileSync(statePath, content);
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
try {
|
|
89
|
+
fs.unlinkSync(lockPath);
|
|
90
|
+
}
|
|
91
|
+
catch (unlockErr) {
|
|
92
|
+
// Only ENOENT is expected (lock already removed); other errors indicate
|
|
93
|
+
// a real problem but we cannot throw from finally — log instead.
|
|
94
|
+
if (unlockErr.code !== 'ENOENT') {
|
|
95
|
+
process.stderr.write(`[autopilot] Warning: failed to release lock ${lockPath}: ${unlockErr.message}\n`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ─── Spawn Infrastructure ─────────────────────────────────────────────────────
|
|
101
|
+
/**
|
|
102
|
+
* Build the shared spawn configuration for `claude -p` invocations.
|
|
103
|
+
* Returns the args array and sanitized env object used by both the sync
|
|
104
|
+
* and async spawn helpers.
|
|
105
|
+
*/
|
|
106
|
+
function _buildSpawnConfig(prompt, opts = {}) {
|
|
107
|
+
const args = ['-p', prompt, '--verbose', '--dangerously-skip-permissions'];
|
|
108
|
+
if (opts.maxTurns) {
|
|
109
|
+
args.push('--max-turns', String(opts.maxTurns));
|
|
110
|
+
}
|
|
111
|
+
if (opts.model) {
|
|
112
|
+
args.push('--model', opts.model);
|
|
113
|
+
}
|
|
114
|
+
if (opts.outputFormat) {
|
|
115
|
+
args.push('--output-format', opts.outputFormat);
|
|
116
|
+
}
|
|
117
|
+
const env = { ...process.env };
|
|
118
|
+
// Strip ALL Claude Code env vars to prevent nested-session detection.
|
|
119
|
+
// Uses prefix match so future env vars are automatically handled.
|
|
120
|
+
for (const key of Object.keys(env)) {
|
|
121
|
+
if (key === 'CLAUDECODE' || key.startsWith('CLAUDE_CODE_') || key.startsWith('CLAUDECODE_')) {
|
|
122
|
+
delete env[key];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { args, env };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Spawn a `claude -p` subprocess synchronously.
|
|
129
|
+
*/
|
|
130
|
+
function spawnClaude(cwd, prompt, opts = {}) {
|
|
131
|
+
const { args, env } = _buildSpawnConfig(prompt, opts);
|
|
132
|
+
const timeout = opts.timeout;
|
|
133
|
+
const spawnOpts = {
|
|
134
|
+
cwd,
|
|
135
|
+
stdio: 'pipe',
|
|
136
|
+
env,
|
|
137
|
+
encoding: 'utf-8',
|
|
138
|
+
};
|
|
139
|
+
if (timeout) {
|
|
140
|
+
spawnOpts.timeout = timeout;
|
|
141
|
+
}
|
|
142
|
+
const result = childProcess.spawnSync('claude', args, spawnOpts);
|
|
143
|
+
// Print subprocess output so callers (Claude Code TUI, terminal) can see it
|
|
144
|
+
if (result.stdout)
|
|
145
|
+
process.stdout.write(result.stdout);
|
|
146
|
+
if (result.stderr)
|
|
147
|
+
process.stderr.write(result.stderr);
|
|
148
|
+
const timedOut = !!(result.error && result.error.code === 'ETIMEDOUT');
|
|
149
|
+
const exitCode = timedOut ? 124 : (result.status ?? 1);
|
|
150
|
+
return { exitCode, timedOut };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Spawn a `claude -p` subprocess asynchronously (non-blocking).
|
|
154
|
+
* Used for parallel planning where multiple processes run concurrently.
|
|
155
|
+
*/
|
|
156
|
+
function spawnClaudeAsync(cwd, prompt, opts = {}) {
|
|
157
|
+
const { args, env } = _buildSpawnConfig(prompt, opts);
|
|
158
|
+
const timeout = opts.timeout;
|
|
159
|
+
const captureOutput = opts.captureOutput || false;
|
|
160
|
+
const captureStderr = opts.captureStderr || false;
|
|
161
|
+
return new Promise((resolve) => {
|
|
162
|
+
const child = childProcess.spawn('claude', args, {
|
|
163
|
+
cwd,
|
|
164
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
165
|
+
env,
|
|
166
|
+
});
|
|
167
|
+
let stdoutBuf = '';
|
|
168
|
+
let stderrBuf = '';
|
|
169
|
+
// Stream subprocess output to parent so it's visible in the terminal/TUI
|
|
170
|
+
if (child.stdout && typeof child.stdout.on === 'function') {
|
|
171
|
+
child.stdout.on('data', (chunk) => {
|
|
172
|
+
if (captureOutput) {
|
|
173
|
+
stdoutBuf += chunk.toString();
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
process.stdout.write(chunk);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (child.stderr && typeof child.stderr.on === 'function') {
|
|
181
|
+
child.stderr.on('data', (chunk) => {
|
|
182
|
+
// Always forward to parent stderr for real-time visibility
|
|
183
|
+
process.stderr.write(chunk);
|
|
184
|
+
if (captureStderr) {
|
|
185
|
+
stderrBuf += chunk.toString();
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
let timedOut = false;
|
|
190
|
+
let timer;
|
|
191
|
+
let killTimer;
|
|
192
|
+
if (timeout) {
|
|
193
|
+
timer = setTimeout(() => {
|
|
194
|
+
timedOut = true;
|
|
195
|
+
child.kill('SIGTERM');
|
|
196
|
+
// Escalate to SIGKILL if process doesn't exit within 5 seconds
|
|
197
|
+
killTimer = setTimeout(() => {
|
|
198
|
+
try {
|
|
199
|
+
child.kill('SIGKILL');
|
|
200
|
+
}
|
|
201
|
+
catch (_e) {
|
|
202
|
+
/* already dead */
|
|
203
|
+
}
|
|
204
|
+
}, 5000);
|
|
205
|
+
}, timeout);
|
|
206
|
+
}
|
|
207
|
+
child.on('close', (code) => {
|
|
208
|
+
if (timer)
|
|
209
|
+
clearTimeout(timer);
|
|
210
|
+
if (killTimer)
|
|
211
|
+
clearTimeout(killTimer);
|
|
212
|
+
const result = {
|
|
213
|
+
exitCode: timedOut ? 124 : (code ?? 1),
|
|
214
|
+
timedOut,
|
|
215
|
+
};
|
|
216
|
+
if (captureOutput) {
|
|
217
|
+
result.stdout = stdoutBuf;
|
|
218
|
+
}
|
|
219
|
+
if (captureStderr) {
|
|
220
|
+
result.stderr = stderrBuf;
|
|
221
|
+
}
|
|
222
|
+
resolve(result);
|
|
223
|
+
});
|
|
224
|
+
child.on('error', () => {
|
|
225
|
+
if (timer)
|
|
226
|
+
clearTimeout(timer);
|
|
227
|
+
if (killTimer)
|
|
228
|
+
clearTimeout(killTimer);
|
|
229
|
+
const result = { exitCode: 1, timedOut: false };
|
|
230
|
+
if (captureOutput) {
|
|
231
|
+
result.stdout = stdoutBuf;
|
|
232
|
+
}
|
|
233
|
+
if (captureStderr) {
|
|
234
|
+
result.stderr = stderrBuf;
|
|
235
|
+
}
|
|
236
|
+
resolve(result);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Spawn a claude -p subprocess, routing through the scheduler when available.
|
|
242
|
+
* Unifies the scheduler vs. direct spawn branching used across pipeline steps.
|
|
243
|
+
*/
|
|
244
|
+
async function spawnStep(prompt, stepCwd, workItemId, scheduler, opts, reportCwd) {
|
|
245
|
+
if (scheduler) {
|
|
246
|
+
const schedResult = await scheduler.spawn(prompt, {
|
|
247
|
+
timeout: opts.timeout,
|
|
248
|
+
maxTurns: opts.maxTurns,
|
|
249
|
+
model: opts.model,
|
|
250
|
+
cwd: stepCwd,
|
|
251
|
+
workItemId,
|
|
252
|
+
agentType: opts.agentType,
|
|
253
|
+
});
|
|
254
|
+
// Codex r15 P2 / r16 P2: when the scheduler reports a spin, write
|
|
255
|
+
// the SPIN-REPORT into the canonical phase dir under the main cwd
|
|
256
|
+
// (reportCwd) rather than the temporary worktree (stepCwd) — the
|
|
257
|
+
// worktree gets cleaned up after the pipeline, deleting the
|
|
258
|
+
// report before the user can read it.
|
|
259
|
+
if (schedResult.spinEvent && schedResult.spinEvent.detected) {
|
|
260
|
+
try {
|
|
261
|
+
const { handleSpinEvent } = require('./autopilot');
|
|
262
|
+
const { findPhaseInternal } = require('./utils');
|
|
263
|
+
// Codex r16/r17 P2: 1) trim worktree path back to the project
|
|
264
|
+
// root so the report survives worktree cleanup; 2) derive the
|
|
265
|
+
// phase dir from workItemId (`phase-N-step`) and pass the
|
|
266
|
+
// ABSOLUTE phase dir to handleSpinEvent — which writes
|
|
267
|
+
// SPIN-REPORT.md directly under the path it receives.
|
|
268
|
+
let projectCwd = reportCwd ?? stepCwd;
|
|
269
|
+
const wtIdx = projectCwd.indexOf('/.worktrees/');
|
|
270
|
+
if (wtIdx > 0)
|
|
271
|
+
projectCwd = projectCwd.slice(0, wtIdx);
|
|
272
|
+
const phaseMatch = workItemId.match(/phase-([\d.]+)/);
|
|
273
|
+
let targetDir = projectCwd;
|
|
274
|
+
if (phaseMatch) {
|
|
275
|
+
const info = findPhaseInternal(projectCwd, phaseMatch[1]);
|
|
276
|
+
if (info && info.found) {
|
|
277
|
+
const path = require('path');
|
|
278
|
+
targetDir = path.join(projectCwd, info.directory);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
handleSpinEvent(targetDir, schedResult.spinEvent, workItemId);
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
/* spin handling is best-effort; never block the step */
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return toSpawnResult(schedResult);
|
|
288
|
+
}
|
|
289
|
+
return spawnClaudeAsync(stepCwd, prompt, opts);
|
|
290
|
+
}
|
|
291
|
+
// ─── Conflict Resolution ───────────────────────────────────────────────────────
|
|
292
|
+
/** Get list of conflicting files from a worktree mid-rebase. */
|
|
293
|
+
function getConflictingFiles(wtPath) {
|
|
294
|
+
try {
|
|
295
|
+
const result = execGit(wtPath, ['diff', '--name-only', '--diff-filter=U']);
|
|
296
|
+
if (result.exitCode === 0 && result.stdout.trim()) {
|
|
297
|
+
return result.stdout.trim().split('\n').filter(Boolean);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (_err) {
|
|
301
|
+
// no conflict info available
|
|
302
|
+
}
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
// ─── Prompt Builders ──────────────────────────────────────────────────────────
|
|
306
|
+
/** Simplify step: code quality review before PR creation. */
|
|
307
|
+
function buildSimplifyPrompt(phaseNum) {
|
|
308
|
+
return `You are reviewing code changes from phase ${phaseNum}. Examine all changed files (use git diff main...HEAD). For each file, check for: duplicated logic that can be extracted, overly complex code that can be simplified, unused imports or dead code, inconsistent naming or style. Make targeted improvements while preserving all functionality. Do not add comments or documentation unless the logic is truly non-obvious.`;
|
|
309
|
+
}
|
|
310
|
+
/** Code review step: review PR diff and fix findings. */
|
|
311
|
+
function buildCodeReviewPrompt(prUrl) {
|
|
312
|
+
return `You are a code reviewer. Review the PR at ${prUrl}. Use gh pr diff to see the changes. Focus on: correctness bugs, security vulnerabilities, performance issues, and style violations. For each issue found, classify as BLOCKER (must fix) or WARNING (should fix). After the review, fix all BLOCKER and WARNING issues directly in the code, then commit and push the fixes.`;
|
|
313
|
+
}
|
|
314
|
+
/** Rebase conflict resolution via LLM subprocess. */
|
|
315
|
+
function buildConflictResolvePrompt(phaseNum, cwd, wtPath) {
|
|
316
|
+
// Gather phase context — all reads wrapped in try/catch for graceful fallback
|
|
317
|
+
let phaseGoal = `Phase ${phaseNum} implementation`;
|
|
318
|
+
let planSummary = `See phase plans for details`;
|
|
319
|
+
try {
|
|
320
|
+
const roadmapPath = path.join(cwd, '.planning', 'ROADMAP.md');
|
|
321
|
+
const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
|
|
322
|
+
const phaseSection = roadmapContent.split('\n');
|
|
323
|
+
let inPhaseSection = false;
|
|
324
|
+
for (const line of phaseSection) {
|
|
325
|
+
if (line.includes(`#### Phase ${phaseNum}:`) || line.includes(`| ${phaseNum} `)) {
|
|
326
|
+
inPhaseSection = true;
|
|
327
|
+
}
|
|
328
|
+
if (inPhaseSection && line.includes('**Goal**:')) {
|
|
329
|
+
const goalMatch = line.match(/\*\*Goal\*\*:\s*(.+)/);
|
|
330
|
+
if (goalMatch) {
|
|
331
|
+
phaseGoal = goalMatch[1].trim();
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (inPhaseSection && line.startsWith('####') && !line.includes(`Phase ${phaseNum}:`)) {
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch (_err) {
|
|
341
|
+
// fallback already set
|
|
342
|
+
}
|
|
343
|
+
try {
|
|
344
|
+
const phaseInfo = findPhaseInternal(cwd, phaseNum);
|
|
345
|
+
if (phaseInfo && phaseInfo.plans.length > 0) {
|
|
346
|
+
const planPath = path.join(cwd, phaseInfo.directory, phaseInfo.plans[0]);
|
|
347
|
+
const firstPlan = fs.readFileSync(planPath, 'utf-8');
|
|
348
|
+
const objectiveMatch = firstPlan.match(/<objective>([\s\S]*?)<\/objective>/);
|
|
349
|
+
if (objectiveMatch) {
|
|
350
|
+
planSummary = objectiveMatch[1].trim();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
catch (_err) {
|
|
355
|
+
// fallback already set
|
|
356
|
+
}
|
|
357
|
+
const conflictingFiles = getConflictingFiles(wtPath);
|
|
358
|
+
let conflictDiffs = '';
|
|
359
|
+
for (const filePath of conflictingFiles.slice(0, 5)) {
|
|
360
|
+
try {
|
|
361
|
+
const diffResult = execGit(wtPath, ['diff', '--', filePath]);
|
|
362
|
+
conflictDiffs += `\n### ${filePath}\n\`\`\`\n${diffResult.stdout}\n\`\`\`\n`;
|
|
363
|
+
}
|
|
364
|
+
catch (_err) {
|
|
365
|
+
conflictDiffs += `\n### ${filePath}\n(diff unavailable)\n`;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const fileList = conflictingFiles.length > 0
|
|
369
|
+
? conflictingFiles.map((f) => `- ${f}`).join('\n')
|
|
370
|
+
: '(unable to determine — check git status)';
|
|
371
|
+
return `You are resolving merge conflicts from rebasing phase ${phaseNum}'s branch onto main.
|
|
372
|
+
|
|
373
|
+
## Phase Context
|
|
374
|
+
|
|
375
|
+
**Phase Goal:** ${phaseGoal}
|
|
376
|
+
**Plan Summary:** ${planSummary}
|
|
377
|
+
|
|
378
|
+
## Conflicting Files
|
|
379
|
+
|
|
380
|
+
The following files have conflicts:
|
|
381
|
+
${fileList}
|
|
382
|
+
|
|
383
|
+
## Conflict Diffs
|
|
384
|
+
${conflictDiffs || '\n(run `git diff` to see conflict details)\n'}
|
|
385
|
+
## Instructions
|
|
386
|
+
|
|
387
|
+
For each conflicting file:
|
|
388
|
+
1. Examine both the incoming changes (from phase ${phaseNum}'s branch) and the changes from main
|
|
389
|
+
2. Resolve by PRESERVING CHANGES FROM BOTH VERSIONS — do not discard either side unless they are truly redundant
|
|
390
|
+
3. The phase's intent was: ${phaseGoal} — ensure the resolution maintains this intent
|
|
391
|
+
4. After resolving all conflicts, run \`git add\` on each resolved file
|
|
392
|
+
5. Complete the rebase with \`git rebase --continue\`
|
|
393
|
+
|
|
394
|
+
If a conflict cannot be automatically resolved (e.g., fundamentally incompatible changes), exit with a non-zero status code.`;
|
|
395
|
+
}
|
|
396
|
+
/** Build the prompt string for the knowledge miner agent. */
|
|
397
|
+
function buildKnowledgeMiningPrompt(phaseNum) {
|
|
398
|
+
return `You are the GRD knowledge miner agent for phase ${phaseNum}.
|
|
399
|
+
|
|
400
|
+
Your task:
|
|
401
|
+
1. Read the SUMMARY.md file for phase ${phaseNum} (look in .planning/milestones/*/phases/*${phaseNum}*/).
|
|
402
|
+
2. Analyze the code changes, decisions, and techniques described in the summary.
|
|
403
|
+
3. Identify 2-5 reusable patterns or techniques that future phases could benefit from.
|
|
404
|
+
4. For each pattern, produce a ---KNOWHOW-ENTRY--- block in this format:
|
|
405
|
+
|
|
406
|
+
---KNOWHOW-ENTRY---
|
|
407
|
+
pattern_name: <descriptive name>
|
|
408
|
+
source: <file path or paper slug where pattern was used>
|
|
409
|
+
applicability: <when this pattern is useful>
|
|
410
|
+
code_snippet: <short representative code example>
|
|
411
|
+
phase_number: ${phaseNum}
|
|
412
|
+
created_at: <ISO timestamp>
|
|
413
|
+
---END-KNOWHOW-ENTRY---
|
|
414
|
+
|
|
415
|
+
5. Call appendKnowhowEntries (from lib/knowledge.ts) to write the entries to KNOWHOW.md at the project root.
|
|
416
|
+
|
|
417
|
+
Focus on patterns that are specific, reusable, and non-obvious — not general best practices.`;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Build the prompt string for the critique agent invocation.
|
|
421
|
+
*
|
|
422
|
+
* Wraps the refinement critique prompt (from lib/refinement.ts) in the standard
|
|
423
|
+
* agent invocation format, prepending agent role context and phase information.
|
|
424
|
+
*
|
|
425
|
+
* @param phaseNum - Phase number for file path context
|
|
426
|
+
* @param branch - The classified refinement branch to execute
|
|
427
|
+
* @param metrics - Current metric measurements
|
|
428
|
+
* @param targets - Target metric thresholds
|
|
429
|
+
* @param minimaRegions - Detected minima/maxima regions from metric history
|
|
430
|
+
* @returns Formatted prompt string for the grd-critique-agent
|
|
431
|
+
*/
|
|
432
|
+
function buildCritiqueAgentPrompt(phaseNum, branch, metrics, targets, minimaRegions, agentDefPath) {
|
|
433
|
+
const critiquePrompt = _buildCritiquePromptFn(branch, metrics, targets, minimaRegions);
|
|
434
|
+
// Codex r44 P1 #1: embed the agent definition file content into the
|
|
435
|
+
// prompt. Previously the file's existence was checked but the
|
|
436
|
+
// markdown content (constraints, output schema, guardrails) was
|
|
437
|
+
// never sent to the subprocess — only a one-line "You are the
|
|
438
|
+
// grd-critique-agent" preamble was. `agentType` is just model/
|
|
439
|
+
// scheduler routing metadata, not a system-prompt loader.
|
|
440
|
+
let agentDefinition = '';
|
|
441
|
+
if (agentDefPath) {
|
|
442
|
+
try {
|
|
443
|
+
agentDefinition = fs.readFileSync(agentDefPath, 'utf-8');
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
/* fall through: prompt still works with just the preamble */
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
const definitionBlock = agentDefinition
|
|
450
|
+
? `\n\n<agent-definition>\n${agentDefinition}\n</agent-definition>\n`
|
|
451
|
+
: '';
|
|
452
|
+
return `You are the grd-critique-agent. Your branch is ${branch}.
|
|
453
|
+
|
|
454
|
+
Phase: ${phaseNum}
|
|
455
|
+
Working directory: project root (all paths are relative to it)
|
|
456
|
+
${definitionBlock}
|
|
457
|
+
${critiquePrompt}
|
|
458
|
+
|
|
459
|
+
Apply the targeted fixes described above. Focus on the ${branch} branch instructions. Emit the CRITIQUE-RESULT block at the end of your response.`;
|
|
460
|
+
}
|
|
461
|
+
// ─── Knowledge Mining ─────────────────────────────────────────────────────────
|
|
462
|
+
/**
|
|
463
|
+
* Run the knowledge mining step for a phase.
|
|
464
|
+
* Checks for agent definition existence, spawns the miner, and marks status.
|
|
465
|
+
* Non-blocking — errors are caught and logged; pipeline always continues.
|
|
466
|
+
*/
|
|
467
|
+
async function runKnowledgeMining(cwd, phaseNum, options) {
|
|
468
|
+
const { scheduler, log } = options;
|
|
469
|
+
const agentDefPath = path.resolve(cwd, 'agents', 'grd-knowledge-miner.md');
|
|
470
|
+
if (!fs.existsSync(agentDefPath)) {
|
|
471
|
+
log(`Phase ${phaseNum}: knowledge mining skipped — agent definition not found`);
|
|
472
|
+
writeStatusMarker(cwd, phaseNum, 'knowledge-mining', 'skipped');
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
writeStatusMarker(cwd, phaseNum, 'knowledge-mining', 'started');
|
|
476
|
+
try {
|
|
477
|
+
await spawnStep(buildKnowledgeMiningPrompt(phaseNum), cwd, `phase-${phaseNum}-knowledge-mining`, scheduler ?? null, { captureOutput: true, agentType: 'grd-knowledge-miner' });
|
|
478
|
+
writeStatusMarker(cwd, phaseNum, 'knowledge-mining', 'completed');
|
|
479
|
+
log(`Phase ${phaseNum}: knowledge mining completed`);
|
|
480
|
+
}
|
|
481
|
+
catch (_err) {
|
|
482
|
+
log(`Phase ${phaseNum}: knowledge mining failed (non-blocking): ${String(_err)}`);
|
|
483
|
+
writeStatusMarker(cwd, phaseNum, 'knowledge-mining', 'failed');
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// ─── Refinement Loop ──────────────────────────────────────────────────────────
|
|
487
|
+
/**
|
|
488
|
+
* Run the iterative metric-driven refinement loop for a phase.
|
|
489
|
+
*
|
|
490
|
+
* Implements the closed-loop: collect metrics -> classify branch -> spawn critique
|
|
491
|
+
* agent -> re-measure -> check convergence. Adapts NERFIFY's 3-branch refinement
|
|
492
|
+
* (Macro/Geometry/Generative) to GRD's domain.
|
|
493
|
+
*
|
|
494
|
+
* Non-blocking — the entire loop is wrapped in try/catch; failures are logged and
|
|
495
|
+
* the pipeline always continues.
|
|
496
|
+
*
|
|
497
|
+
* @param cwd - Absolute path to the project root directory
|
|
498
|
+
* @param phaseNum - Phase number (used in status markers and prompts)
|
|
499
|
+
* @param options - Configuration including scheduler, log function, and targets
|
|
500
|
+
*/
|
|
501
|
+
/**
|
|
502
|
+
* Run the configured metric command via real shell execution (NOT
|
|
503
|
+
* `claude -p`). Captures stdout+stderr concatenated so jest's
|
|
504
|
+
* threshold-failure block and tsc's error output are both visible
|
|
505
|
+
* to `collectMetrics`.
|
|
506
|
+
*
|
|
507
|
+
* Codex r43 P1 #1: previously the refinement loop sent the strings
|
|
508
|
+
* "npm test", "tsc", "eslint" through `spawnStep` which routes to
|
|
509
|
+
* `claude -p`. The LLM then *described* what those commands might
|
|
510
|
+
* output, and `collectMetrics` regex-parsed that description.
|
|
511
|
+
*/
|
|
512
|
+
function _measureMetrics(measureCwd, log) {
|
|
513
|
+
const { spawnSync } = require('child_process');
|
|
514
|
+
const runShell = (cmd, args) => {
|
|
515
|
+
try {
|
|
516
|
+
const r = spawnSync(cmd, args, {
|
|
517
|
+
cwd: measureCwd,
|
|
518
|
+
encoding: 'utf-8',
|
|
519
|
+
env: { ...process.env, FORCE_COLOR: '0', CI: '1' },
|
|
520
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
521
|
+
});
|
|
522
|
+
return (r.stdout ?? '') + '\n' + (r.stderr ?? '');
|
|
523
|
+
}
|
|
524
|
+
catch (e) {
|
|
525
|
+
log(`Phase metric command failed (non-blocking): ${cmd} ${args.join(' ')}: ${String(e)}`);
|
|
526
|
+
return '';
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
return {
|
|
530
|
+
testOutput: runShell('npx', ['jest', '--coverage', '--silent', '--ci', '--passWithNoTests']),
|
|
531
|
+
tscOutput: runShell('npx', ['tsc', '--noEmit']),
|
|
532
|
+
lintOutput: runShell('npx', ['eslint', 'bin/', 'lib/']),
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* True iff the second snapshot regressed on any dimension. Coverage
|
|
537
|
+
* dropping or error counts rising counts as regression.
|
|
538
|
+
*/
|
|
539
|
+
function _critiqueRegressed(before, after) {
|
|
540
|
+
const reasons = [];
|
|
541
|
+
if (after.test_coverage_pct < before.test_coverage_pct - 0.5) {
|
|
542
|
+
reasons.push(`coverage ${before.test_coverage_pct.toFixed(1)}% → ${after.test_coverage_pct.toFixed(1)}%`);
|
|
543
|
+
}
|
|
544
|
+
if (after.type_error_count > before.type_error_count) {
|
|
545
|
+
reasons.push(`type_errors ${before.type_error_count} → ${after.type_error_count}`);
|
|
546
|
+
}
|
|
547
|
+
if (after.lint_violation_count > before.lint_violation_count) {
|
|
548
|
+
reasons.push(`lint ${before.lint_violation_count} → ${after.lint_violation_count}`);
|
|
549
|
+
}
|
|
550
|
+
return { regressed: reasons.length > 0, reasons };
|
|
551
|
+
}
|
|
552
|
+
async function runRefinementLoop(cwd, phaseNum, options) {
|
|
553
|
+
const { scheduler, log } = options;
|
|
554
|
+
// Codex r43 P1 #2: refinement must run in the same worktree the
|
|
555
|
+
// phase implementation ran in, so critique edits land on the
|
|
556
|
+
// phase branch the post-pipeline merges. Fall back to cwd only
|
|
557
|
+
// when no worktree was supplied (legacy callers + tests).
|
|
558
|
+
const workCwd = options.workCwd ?? cwd;
|
|
559
|
+
// Skip when not explicitly enabled via config (opt-in, same as citation_gate pattern)
|
|
560
|
+
if (loadConfig(cwd).refinement_loop !== true) {
|
|
561
|
+
log(`Phase ${phaseNum}: refinement loop skipped — refinement_loop config not enabled`);
|
|
562
|
+
// Codex r43 P2 #5: status marker even on config-skip so users
|
|
563
|
+
// inspecting .planning/autopilot can tell why no refinement ran.
|
|
564
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', 'skipped-disabled');
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
const agentDefPath = path.resolve(cwd, 'agents', 'grd-critique-agent.md');
|
|
568
|
+
if (!fs.existsSync(agentDefPath)) {
|
|
569
|
+
log(`Phase ${phaseNum}: refinement loop skipped — grd-critique-agent.md not found`);
|
|
570
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', 'skipped-no-agent');
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
const maxIterations = options.maxIterations ?? 3;
|
|
574
|
+
const convergenceConfig = {
|
|
575
|
+
epsilon_coverage: 0.5,
|
|
576
|
+
epsilon_type_errors: 0,
|
|
577
|
+
epsilon_lint: 1,
|
|
578
|
+
max_iterations: maxIterations,
|
|
579
|
+
};
|
|
580
|
+
const targets = options.targets ?? {
|
|
581
|
+
test_coverage_pct: 80,
|
|
582
|
+
type_error_count: 0,
|
|
583
|
+
lint_violation_count: 0,
|
|
584
|
+
timestamp: new Date().toISOString(),
|
|
585
|
+
};
|
|
586
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', 'started');
|
|
587
|
+
log(`Phase ${phaseNum}: refinement loop started (maxIterations=${maxIterations}, cwd=${workCwd})`);
|
|
588
|
+
try {
|
|
589
|
+
const history = [];
|
|
590
|
+
for (let iteration = 1; iteration <= maxIterations; iteration++) {
|
|
591
|
+
log(`Phase ${phaseNum}: refinement loop iteration ${iteration}/${maxIterations}`);
|
|
592
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', `iteration-${iteration}`);
|
|
593
|
+
// Step 1: REAL metric collection via child_process — not claude -p.
|
|
594
|
+
const { testOutput, tscOutput, lintOutput } = _measureMetrics(workCwd, log);
|
|
595
|
+
// Step 2: Parse metrics from captured tool outputs.
|
|
596
|
+
const currentMetrics = _collectMetrics(testOutput, tscOutput, lintOutput);
|
|
597
|
+
// Step 3: Push snapshot to history.
|
|
598
|
+
const snapshot = {
|
|
599
|
+
metrics: currentMetrics,
|
|
600
|
+
phase: phaseNum,
|
|
601
|
+
plan: String(iteration),
|
|
602
|
+
};
|
|
603
|
+
history.push(snapshot);
|
|
604
|
+
log(`Phase ${phaseNum}: metrics collected — coverage=${currentMetrics.test_coverage_pct.toFixed(1)}%, ` +
|
|
605
|
+
`type_errors=${currentMetrics.type_error_count}, lint=${currentMetrics.lint_violation_count}`);
|
|
606
|
+
// Step 4: Check convergence (now returns false on all-zero
|
|
607
|
+
// sentinel — see lib/refinement.ts).
|
|
608
|
+
const convergenceResult = _checkConvergence(history, convergenceConfig);
|
|
609
|
+
if (convergenceResult.converged) {
|
|
610
|
+
log(`Phase ${phaseNum}: refinement loop converged — ${convergenceResult.reason}`);
|
|
611
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', 'converged');
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
// Step 5: Classify branch and detect minima.
|
|
615
|
+
const branch = _classifyBranch(currentMetrics, targets);
|
|
616
|
+
const minimaRegions = _detectMinima(history);
|
|
617
|
+
log(`Phase ${phaseNum}: refinement loop classifying branch as '${branch}'`);
|
|
618
|
+
// Step 6: Snapshot worktree HEAD so we can revert a regressing
|
|
619
|
+
// critique. Codex r43 P1 #4.
|
|
620
|
+
const headBefore = (() => {
|
|
621
|
+
try {
|
|
622
|
+
return execGit(workCwd, ['rev-parse', 'HEAD']).stdout.trim();
|
|
623
|
+
}
|
|
624
|
+
catch {
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
})();
|
|
628
|
+
// Step 7: Build critique prompt and spawn the critique agent.
|
|
629
|
+
// Codex r43 P2 #7: agentType is grd-critique-agent (not
|
|
630
|
+
// grd-verifier), so model + scheduler routing pick the right
|
|
631
|
+
// profile and the agent definition file is honored.
|
|
632
|
+
const critiquePrompt = buildCritiqueAgentPrompt(phaseNum, branch, currentMetrics, targets, minimaRegions, agentDefPath);
|
|
633
|
+
const critiqueConfig = loadConfig(cwd);
|
|
634
|
+
const critiqueTier = getEffectiveTierForDispatch({
|
|
635
|
+
agentType: 'grd-critique-agent',
|
|
636
|
+
prompt: critiquePrompt,
|
|
637
|
+
config: critiqueConfig,
|
|
638
|
+
scheduler: scheduler ?? null,
|
|
639
|
+
schedulerConfig: critiqueConfig.scheduler,
|
|
640
|
+
superpowersConfig: critiqueConfig.superpowers,
|
|
641
|
+
modelProfiles: _MODEL_PROFILES_FOR_REFINEMENT,
|
|
642
|
+
retry_attempt: iteration - 1,
|
|
643
|
+
});
|
|
644
|
+
const critiqueModel = resolveModelForAgent(critiqueConfig, 'grd-critique-agent', cwd, {
|
|
645
|
+
effectiveTierOverride: critiqueTier,
|
|
646
|
+
});
|
|
647
|
+
const critiqueResult = await spawnStep(critiquePrompt, workCwd, `phase-${phaseNum}-critique-${iteration}`, scheduler ?? null, {
|
|
648
|
+
captureOutput: true,
|
|
649
|
+
agentType: 'grd-critique-agent',
|
|
650
|
+
model: critiqueModel,
|
|
651
|
+
});
|
|
652
|
+
if (critiqueResult.exitCode !== 0) {
|
|
653
|
+
log(`Phase ${phaseNum}: critique exited ${critiqueResult.exitCode}; skipping regression check`);
|
|
654
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', `iteration-${iteration}-critique-failed`);
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
// Step 8: Re-measure and reject regressions. Codex r43 P1 #4.
|
|
658
|
+
const afterMeasure = _measureMetrics(workCwd, log);
|
|
659
|
+
const afterMetrics = _collectMetrics(afterMeasure.testOutput, afterMeasure.tscOutput, afterMeasure.lintOutput);
|
|
660
|
+
const regression = _critiqueRegressed(currentMetrics, afterMetrics);
|
|
661
|
+
if (regression.regressed) {
|
|
662
|
+
log(`Phase ${phaseNum}: critique regressed metrics (${regression.reasons.join('; ')}) — rolling back`);
|
|
663
|
+
if (headBefore) {
|
|
664
|
+
try {
|
|
665
|
+
execGit(workCwd, ['reset', '--hard', headBefore]);
|
|
666
|
+
}
|
|
667
|
+
catch (e) {
|
|
668
|
+
log(`Phase ${phaseNum}: rollback failed (non-blocking): ${String(e)}`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', `iteration-${iteration}-rolled-back`);
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', `iteration-${iteration}-complete`);
|
|
675
|
+
}
|
|
676
|
+
// Reached max iterations without convergence
|
|
677
|
+
log(`Phase ${phaseNum}: refinement loop reached max iterations (${maxIterations})`);
|
|
678
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', 'max-iterations');
|
|
679
|
+
}
|
|
680
|
+
catch (_err) {
|
|
681
|
+
log(`Phase ${phaseNum}: refinement loop failed (non-blocking): ${String(_err)}`);
|
|
682
|
+
writeStatusMarker(cwd, phaseNum, 'refinement-loop', 'failed');
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
// ─── Post-Phase Pipeline ──────────────────────────────────────────────────────
|
|
686
|
+
/**
|
|
687
|
+
* Run the post-phase pipeline: simplify -> create PR -> code review -> rebase & merge.
|
|
688
|
+
* Each step runs sequentially on the phase's worktree branch.
|
|
689
|
+
* Halts on any failure and returns the failed step.
|
|
690
|
+
*/
|
|
691
|
+
async function runPostPhasePipeline(cwd, phaseNum, wtPath, opts) {
|
|
692
|
+
const { timeout, maxTurns, model, scheduler, log, mergeQueue } = opts;
|
|
693
|
+
const timeoutMs = timeout ? timeout * 60 * 1000 : undefined;
|
|
694
|
+
const spawnOpts = { timeout: timeoutMs, maxTurns, model, captureOutput: true };
|
|
695
|
+
// Step 1: Simplify
|
|
696
|
+
log(`Phase ${phaseNum}: post-pipeline — simplify`);
|
|
697
|
+
const simplifyResult = await spawnStep(buildSimplifyPrompt(phaseNum), wtPath, `phase-${phaseNum}-simplify`, scheduler ?? null, { ...spawnOpts, agentType: 'grd-integration-checker' });
|
|
698
|
+
if (simplifyResult.exitCode !== 0) {
|
|
699
|
+
return {
|
|
700
|
+
status: 'failed',
|
|
701
|
+
failedStep: 'simplify',
|
|
702
|
+
reason: simplifyResult.timedOut ? 'timeout' : `exit code ${simplifyResult.exitCode}`,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
// Step 2: Create PR
|
|
706
|
+
log(`Phase ${phaseNum}: post-pipeline — create PR`);
|
|
707
|
+
const milestoneInfo = getMilestoneInfo(cwd);
|
|
708
|
+
const prResult = pushAndCreatePR(cwd, wtPath, {
|
|
709
|
+
title: `Phase ${phaseNum}: ${milestoneInfo.version}`,
|
|
710
|
+
body: `Automated PR from autopilot phase ${phaseNum} execution.\n\nMilestone: ${milestoneInfo.version} (${milestoneInfo.name})`,
|
|
711
|
+
});
|
|
712
|
+
if ('error' in prResult) {
|
|
713
|
+
return { status: 'failed', failedStep: 'create-pr', reason: prResult.error };
|
|
714
|
+
}
|
|
715
|
+
const prUrl = prResult.pr_url;
|
|
716
|
+
log(`Phase ${phaseNum}: PR created — ${prUrl}`);
|
|
717
|
+
// Step 3: Code review + fix
|
|
718
|
+
log(`Phase ${phaseNum}: post-pipeline — code review`);
|
|
719
|
+
const reviewResult = await spawnStep(buildCodeReviewPrompt(prUrl), wtPath, `phase-${phaseNum}-review`, scheduler ?? null, { ...spawnOpts, agentType: 'grd-code-reviewer' });
|
|
720
|
+
if (reviewResult.exitCode !== 0) {
|
|
721
|
+
return {
|
|
722
|
+
status: 'failed',
|
|
723
|
+
failedStep: 'code-review',
|
|
724
|
+
prUrl,
|
|
725
|
+
reason: reviewResult.timedOut ? 'timeout' : `exit code ${reviewResult.exitCode}`,
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
// Step 4: Rebase & merge (serialized through mergeQueue when provided)
|
|
729
|
+
const runStep4 = async () => {
|
|
730
|
+
log(`Phase ${phaseNum}: post-pipeline — rebase & merge`);
|
|
731
|
+
const rebaseResult = execGit(wtPath, ['rebase', 'main']);
|
|
732
|
+
if (rebaseResult.exitCode !== 0) {
|
|
733
|
+
// Merge conflicts — spawn claude -p to resolve
|
|
734
|
+
log(`Phase ${phaseNum}: rebase conflicts detected, attempting auto-resolution`);
|
|
735
|
+
const conflictResult = await spawnStep(buildConflictResolvePrompt(phaseNum, cwd, wtPath), wtPath, `phase-${phaseNum}-conflicts`, scheduler ?? null, { ...spawnOpts, agentType: 'grd-integration-checker' });
|
|
736
|
+
if (conflictResult.exitCode !== 0) {
|
|
737
|
+
// Gather conflict info BEFORE aborting (abort clears conflict state)
|
|
738
|
+
const conflictFiles = getConflictingFiles(wtPath);
|
|
739
|
+
const branch = execGit(wtPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
740
|
+
const branchName = branch.exitCode === 0 ? branch.stdout.trim() : `phase-${phaseNum}`;
|
|
741
|
+
execGit(wtPath, ['rebase', '--abort']);
|
|
742
|
+
return {
|
|
743
|
+
status: 'failed',
|
|
744
|
+
failedStep: 'rebase',
|
|
745
|
+
prUrl,
|
|
746
|
+
reason: `conflict resolution failed for phase ${phaseNum} — conflicting files: ${conflictFiles.join(', ') || 'unknown'}. Manual steps: git checkout ${branchName}, git rebase main, resolve conflicts manually, git rebase --continue`,
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
// Force-push the rebased branch and merge the PR
|
|
751
|
+
const branch = execGit(wtPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
752
|
+
if (branch.exitCode !== 0) {
|
|
753
|
+
return {
|
|
754
|
+
status: 'failed',
|
|
755
|
+
failedStep: 'push-rebased',
|
|
756
|
+
prUrl,
|
|
757
|
+
reason: 'failed to determine branch name',
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
const pushResult = execGit(wtPath, ['push', '--force-with-lease', 'origin', branch.stdout.trim()], {
|
|
761
|
+
allowBlocked: true,
|
|
762
|
+
});
|
|
763
|
+
if (pushResult.exitCode !== 0) {
|
|
764
|
+
return {
|
|
765
|
+
status: 'failed',
|
|
766
|
+
failedStep: 'push-rebased',
|
|
767
|
+
prUrl,
|
|
768
|
+
reason: `push failed: ${pushResult.stderr}`,
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
// Merge the PR via gh CLI
|
|
772
|
+
try {
|
|
773
|
+
childProcess.execFileSync('gh', ['pr', 'merge', prUrl, '--merge', '--delete-branch'], {
|
|
774
|
+
cwd: wtPath,
|
|
775
|
+
stdio: 'pipe',
|
|
776
|
+
encoding: 'utf-8',
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
catch (mergeErr) {
|
|
780
|
+
return {
|
|
781
|
+
status: 'failed',
|
|
782
|
+
failedStep: 'merge',
|
|
783
|
+
prUrl,
|
|
784
|
+
reason: String(mergeErr.stderr || mergeErr),
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
log(`Phase ${phaseNum}: post-pipeline complete — merged ${prUrl}`);
|
|
788
|
+
return { status: 'completed', prUrl };
|
|
789
|
+
};
|
|
790
|
+
return mergeQueue ? mergeQueue.enqueue(runStep4) : runStep4();
|
|
791
|
+
}
|
|
792
|
+
// ─── Phase Finalize ───────────────────────────────────────────────────────────
|
|
793
|
+
/**
|
|
794
|
+
* Finalize a phase after a successful post-pipeline run.
|
|
795
|
+
* Calls completePhaseAfterPostPipeline and writes status markers.
|
|
796
|
+
* Returns the PhaseCompleteResult or null on failure.
|
|
797
|
+
*/
|
|
798
|
+
async function finalizePhaseAfterPipeline(cwd, phaseNum, scheduler, log) {
|
|
799
|
+
writeStatusMarker(cwd, phaseNum, 'phase-finalize', 'started');
|
|
800
|
+
const finalizeResult = await completePhaseAfterPostPipeline(cwd, phaseNum, scheduler);
|
|
801
|
+
if (finalizeResult) {
|
|
802
|
+
writeStatusMarker(cwd, phaseNum, 'phase-finalize', 'completed');
|
|
803
|
+
log(`Phase ${phaseNum}: phase-finalize complete — ${finalizeResult.plans_executed} plans, ${finalizeResult.next_phase ? `next phase ${finalizeResult.next_phase}` : 'milestone complete'}`);
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
writeStatusMarker(cwd, phaseNum, 'phase-finalize', 'failed');
|
|
807
|
+
log(`Phase ${phaseNum}: phase-finalize failed — run 'gd phase complete ${phaseNum}' manually to finalize`);
|
|
808
|
+
}
|
|
809
|
+
return finalizeResult;
|
|
810
|
+
}
|
|
811
|
+
module.exports = {
|
|
812
|
+
toSpawnResult,
|
|
813
|
+
spawnClaude,
|
|
814
|
+
spawnClaudeAsync,
|
|
815
|
+
spawnStep,
|
|
816
|
+
_buildSpawnConfig,
|
|
817
|
+
writeStatusMarker,
|
|
818
|
+
updateStateProgress,
|
|
819
|
+
getConflictingFiles,
|
|
820
|
+
buildSimplifyPrompt,
|
|
821
|
+
buildCodeReviewPrompt,
|
|
822
|
+
buildConflictResolvePrompt,
|
|
823
|
+
buildKnowledgeMiningPrompt,
|
|
824
|
+
buildCritiqueAgentPrompt,
|
|
825
|
+
runKnowledgeMining,
|
|
826
|
+
runRefinementLoop,
|
|
827
|
+
runPostPhasePipeline,
|
|
828
|
+
finalizePhaseAfterPipeline,
|
|
829
|
+
};
|
|
830
|
+
//# sourceMappingURL=autopilot-pipeline.js.map
|