@opengsd/gsd-core 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +85 -5
- package/agents/gsd-code-fixer.compact.md +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-code-reviewer.compact.md +5 -3
- package/agents/gsd-code-reviewer.md +8 -6
- package/agents/gsd-debug-session-manager.compact.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +2 -2
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +4 -4
- package/agents/gsd-intel-updater.compact.md +1 -1
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +2 -2
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-plan-checker.md +7 -2
- package/agents/gsd-planner.md +3 -3
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +1 -1
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +21 -30
- package/agents/gsd-ui-auditor.md +42 -51
- package/agents/gsd-ui-researcher.compact.md +1 -1
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-verifier.md +31 -9
- package/bin/install.js +126 -196
- package/commands/gsd/add-tests.md +6 -1
- package/commands/gsd/ai-integration-phase.md +6 -1
- package/commands/gsd/audit-fix.md +5 -0
- package/commands/gsd/audit-milestone.md +6 -1
- package/commands/gsd/autonomous.md +5 -0
- package/commands/gsd/capture.md +8 -4
- package/commands/gsd/code-review.md +7 -2
- package/commands/gsd/complete-milestone.md +4 -0
- package/commands/gsd/config.md +7 -3
- package/commands/gsd/debug.md +11 -7
- package/commands/gsd/discuss-phase.md +7 -3
- package/commands/gsd/docs-update.md +12 -7
- package/commands/gsd/eval-review.md +6 -1
- package/commands/gsd/execute-phase.md +12 -7
- package/commands/gsd/extract-learnings.md +5 -0
- package/commands/gsd/fast.md +4 -0
- package/commands/gsd/forensics.md +5 -1
- package/commands/gsd/graphify.md +10 -6
- package/commands/gsd/health.md +5 -0
- package/commands/gsd/help.md +7 -2
- package/commands/gsd/import.md +7 -3
- package/commands/gsd/inbox.md +5 -0
- package/commands/gsd/ingest-docs.md +5 -1
- package/commands/gsd/manager.md +6 -1
- package/commands/gsd/map-codebase.md +7 -3
- package/commands/gsd/mempalace-capture.md +5 -1
- package/commands/gsd/mempalace-recall.md +5 -1
- package/commands/gsd/milestone-summary.md +5 -1
- package/commands/gsd/mvp-phase.md +8 -3
- package/commands/gsd/new-milestone.md +6 -1
- package/commands/gsd/new-project.md +5 -0
- package/commands/gsd/next.md +6 -1
- package/commands/gsd/ns-context.md +4 -0
- package/commands/gsd/ns-ideate.md +4 -0
- package/commands/gsd/ns-manage.md +4 -0
- package/commands/gsd/ns-project.md +4 -0
- package/commands/gsd/ns-review.md +4 -0
- package/commands/gsd/ns-workflow.md +4 -0
- package/commands/gsd/onboard.md +6 -1
- package/commands/gsd/pause-work.md +5 -1
- package/commands/gsd/phase.md +8 -4
- package/commands/gsd/plan-phase.md +6 -1
- package/commands/gsd/plan-review-convergence.md +5 -1
- package/commands/gsd/pr-branch.md +4 -0
- package/commands/gsd/profile-user.md +5 -1
- package/commands/gsd/progress.md +6 -1
- package/commands/gsd/quick-batch.md +20 -8
- package/commands/gsd/quick.md +12 -7
- package/commands/gsd/review.md +5 -1
- package/commands/gsd/secure-phase.md +6 -1
- package/commands/gsd/ship.md +5 -0
- package/commands/gsd/sketch.md +7 -2
- package/commands/gsd/spec-phase.md +5 -1
- package/commands/gsd/spike.md +8 -3
- package/commands/gsd/surface.md +5 -1
- package/commands/gsd/thread.md +4 -0
- package/commands/gsd/ui-phase.md +6 -1
- package/commands/gsd/ui-review.md +6 -1
- package/commands/gsd/ultraplan-phase.md +5 -1
- package/commands/gsd/undo.md +5 -1
- package/commands/gsd/update.md +6 -2
- package/commands/gsd/validate-phase.md +6 -1
- package/commands/gsd/verify-work.md +6 -1
- package/commands/gsd/workspace.md +7 -3
- package/gsd-core/bin/gsd-tools.cjs +142 -56
- package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
- package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
- package/gsd-core/bin/lib/audit.cjs +78 -44
- package/gsd-core/bin/lib/broken-windows.cjs +13 -13
- package/gsd-core/bin/lib/capability-activation.cjs +9 -4
- package/gsd-core/bin/lib/capability-registry.cjs +183 -103
- package/gsd-core/bin/lib/capability-validator.cjs +16 -0
- package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
- package/gsd-core/bin/lib/check-command-router.cjs +164 -1712
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
- package/gsd-core/bin/lib/cli-exit.cjs +12 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +11 -8
- package/gsd-core/bin/lib/command-aliases.cjs +7 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
- package/gsd-core/bin/lib/commands.cjs +173 -170
- package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
- package/gsd-core/bin/lib/config.cjs +43 -12
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/coverage.cjs +4 -8
- package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
- package/gsd-core/bin/lib/drift.cjs +177 -42
- package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
- package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
- package/gsd-core/bin/lib/frontmatter.cjs +413 -234
- package/gsd-core/bin/lib/gap-checker.cjs +72 -29
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
- package/gsd-core/bin/lib/gate-args.cjs +53 -0
- package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
- package/gsd-core/bin/lib/gate-config.cjs +46 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
- package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
- package/gsd-core/bin/lib/gate-exit.cjs +27 -0
- package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
- package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
- package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
- package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
- package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
- package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
- package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
- package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
- package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
- package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
- package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
- package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
- package/gsd-core/bin/lib/init.cjs +162 -96
- package/gsd-core/bin/lib/install-engine.cjs +19 -35
- package/gsd-core/bin/lib/install-profiles.cjs +7 -4
- package/gsd-core/bin/lib/io.cjs +122 -3
- package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
- package/gsd-core/bin/lib/milestone.cjs +19 -1
- package/gsd-core/bin/lib/model-resolver.cjs +18 -18
- package/gsd-core/bin/lib/observability/event.cjs +1 -1
- package/gsd-core/bin/lib/observability/logger.cjs +46 -1
- package/gsd-core/bin/lib/pattern.cjs +10 -0
- package/gsd-core/bin/lib/phase-command-router.cjs +11 -4
- package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
- package/gsd-core/bin/lib/phase-id.cjs +1 -1
- package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
- package/gsd-core/bin/lib/phase-status.cjs +360 -0
- package/gsd-core/bin/lib/phase.cjs +280 -80
- package/gsd-core/bin/lib/plan-document.cjs +93 -19
- package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
- package/gsd-core/bin/lib/planning-document.cjs +273 -40
- package/gsd-core/bin/lib/planning-inspect.cjs +42 -8
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +76 -53
- package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
- package/gsd-core/bin/lib/profile-output.cjs +6 -3
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
- package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
- package/gsd-core/bin/lib/report-parser.cjs +269 -0
- package/gsd-core/bin/lib/roadmap-command-router.cjs +13 -15
- package/gsd-core/bin/lib/roadmap-parser.cjs +82 -15
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +127 -65
- package/gsd-core/bin/lib/roadmap.cjs +169 -72
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +91 -157
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -1
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
- package/gsd-core/bin/lib/runtime-homes.cjs +13 -10
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +307 -591
- package/gsd-core/bin/lib/runtime-name-policy.cjs +142 -27
- package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
- package/gsd-core/bin/lib/shell-command-projection.cjs +37 -2
- package/gsd-core/bin/lib/smart-entry.cjs +19 -3
- package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
- package/gsd-core/bin/lib/state-contract.cjs +15 -18
- package/gsd-core/bin/lib/state-document.cjs +100 -22
- package/gsd-core/bin/lib/state.cjs +214 -105
- package/gsd-core/bin/lib/surface.cjs +2 -1
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -152
- package/gsd-core/bin/lib/uat-predicate.cjs +313 -35
- package/gsd-core/bin/lib/uat.cjs +424 -7
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +94 -58
- package/gsd-core/bin/lib/vendor/README.md +31 -9
- package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
- package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +1165 -314
- package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
- package/gsd-core/bin/lib/verify.cjs +286 -567
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
- package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
- package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
- package/gsd-core/bin/lib/workstream.cjs +11 -2
- package/gsd-core/bin/shared/config-defaults.manifest.json +5 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +4 -0
- package/gsd-core/references/autonomous-smart-discuss.md +2 -1
- package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
- package/gsd-core/references/execute-mvp-tdd.md +5 -10
- package/gsd-core/references/execute-phase-between-wave-reset.md +3 -0
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +7 -1
- package/gsd-core/references/offer-next.md +1 -1
- package/gsd-core/references/planning-config.md +1 -1
- package/gsd-core/references/spidr-splitting.md +1 -1
- package/gsd-core/references/tdd.md +10 -4
- package/gsd-core/references/verifier-phase-gates.md +5 -2
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -3
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/UAT.md +17 -1
- package/gsd-core/templates/config.json +2 -11
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +8 -7
- package/gsd-core/workflows/add-tests.md +3 -2
- package/gsd-core/workflows/add-todo.md +4 -3
- package/gsd-core/workflows/ai-integration-phase.md +3 -2
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +4 -3
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous.md +28 -18
- package/gsd-core/workflows/check-todos.md +6 -5
- package/gsd-core/workflows/cleanup.md +1 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
- package/gsd-core/workflows/code-review-fix.md +5 -4
- package/gsd-core/workflows/code-review.md +84 -90
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
- package/gsd-core/workflows/complete-milestone.md +12 -7
- package/gsd-core/workflows/debug.md +30 -5
- package/gsd-core/workflows/diagnose-issues.md +3 -2
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +4 -3
- package/gsd-core/workflows/do.md +1 -1
- package/gsd-core/workflows/docs-update.md +4 -3
- package/gsd-core/workflows/edit-phase.md +4 -3
- package/gsd-core/workflows/eval-review.md +5 -3
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +4 -2
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
- package/gsd-core/workflows/execute-phase.md +78 -170
- package/gsd-core/workflows/execute-plan.md +13 -19
- package/gsd-core/workflows/explore.md +2 -2
- package/gsd-core/workflows/extract-learnings.md +3 -2
- package/gsd-core/workflows/fast.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +3 -2
- package/gsd-core/workflows/inbox.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +4 -3
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +5 -3
- package/gsd-core/workflows/map-codebase.md +4 -3
- package/gsd-core/workflows/milestone-summary.md +3 -2
- package/gsd-core/workflows/mvp-phase.md +14 -14
- package/gsd-core/workflows/new-milestone.md +10 -10
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +1 -1
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/pause-work.md +2 -2
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +1 -1
- package/gsd-core/workflows/plan-phase.md +27 -18
- package/gsd-core/workflows/plan-review-convergence.md +1 -1
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +1 -1
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress.md +19 -49
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -2
- package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
- package/gsd-core/workflows/quick-batch.md +15 -10
- package/gsd-core/workflows/quick.md +42 -31
- package/gsd-core/workflows/remove-phase.md +3 -2
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +3 -2
- package/gsd-core/workflows/review.md +3 -2
- package/gsd-core/workflows/scan.md +3 -2
- package/gsd-core/workflows/secure-phase.md +11 -12
- package/gsd-core/workflows/settings-advanced.md +1 -1
- package/gsd-core/workflows/settings-integrations.md +1 -1
- package/gsd-core/workflows/settings.md +1 -1
- package/gsd-core/workflows/ship.md +12 -12
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +1 -1
- package/gsd-core/workflows/spec-phase.md +1 -1
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/sync-skills.md +1 -1
- package/gsd-core/workflows/thread.md +2 -2
- package/gsd-core/workflows/transition.md +13 -23
- package/gsd-core/workflows/ui-phase.md +5 -4
- package/gsd-core/workflows/ui-review.md +4 -3
- package/gsd-core/workflows/ultraplan-phase.md +3 -2
- package/gsd-core/workflows/undo.md +1 -1
- package/gsd-core/workflows/validate-phase.md +10 -12
- package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
- package/gsd-core/workflows/verify-work.md +68 -59
- package/hooks/dist/gsd-agent-isolation-guard.js +8 -0
- package/hooks/dist/gsd-check-update-worker.js +8 -0
- package/hooks/dist/gsd-check-update.js +8 -0
- package/hooks/dist/gsd-context-monitor.js +31 -8
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
- package/hooks/dist/gsd-secret-read-guard.js +147 -16
- package/hooks/dist/gsd-statusline.js +15 -7
- package/hooks/dist/gsd-update-banner.js +8 -0
- package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
- package/hooks/dist/gsd-workflow-guard.js +5 -4
- package/hooks/dist/gsd-worktree-path-guard.js +6 -2
- package/hooks/dist/lib/cli-exit.js +12 -0
- package/hooks/dist/lib/git-probe.js +17 -1
- package/hooks/dist/lib/isolation-sentinel.js +2 -2
- package/hooks/gsd-agent-isolation-guard.js +8 -0
- package/hooks/gsd-check-update-worker.js +8 -0
- package/hooks/gsd-check-update.js +8 -0
- package/hooks/gsd-context-monitor.js +31 -8
- package/hooks/gsd-cursor-subagent-start.js +8 -0
- package/hooks/gsd-secret-read-guard.js +147 -16
- package/hooks/gsd-statusline.js +15 -7
- package/hooks/gsd-update-banner.js +8 -0
- package/hooks/gsd-windsurf-pre-write.js +11 -2
- package/hooks/gsd-workflow-guard.js +5 -4
- package/hooks/gsd-worktree-path-guard.js +6 -2
- package/hooks/hooks.json +5 -5
- package/hooks/lib/cli-exit.js +12 -0
- package/hooks/lib/git-probe.js +17 -1
- package/hooks/lib/isolation-sentinel.js +2 -2
- package/package.json +21 -4
- package/scripts/changeset/parse.cjs +52 -4
- package/scripts/ci-timeout-report.cjs +770 -4
- package/scripts/command-contract-helpers.cjs +12 -8
- package/scripts/docs-guard-registry.cjs +6 -0
- package/scripts/gen-features.cjs +13 -8
- package/scripts/gen-hooks-cli-exit.cjs +12 -28
- package/scripts/gen-loop-host-contract.cjs +10 -1
- package/scripts/gen-platform-conformance-tier.cjs +187 -1
- package/scripts/gen-plugin-skills.cjs +87 -1
- package/scripts/gen-research-agents.cjs +24 -31
- package/scripts/gen-scripts-cli-exit.cjs +30 -3
- package/scripts/gen-test-timings.cjs +32 -7
- package/scripts/lib/cli-exit.cjs +12 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +20 -2
- package/scripts/lib/ndjson-reporter.cjs +28 -3
- package/scripts/lib/platform-conformance-tier.generated.cjs +34 -5
- package/scripts/lib/registration-ledger-preload.cjs +155 -0
- package/scripts/lib/vendor-bundle.cjs +59 -0
- package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-completion-predicate-drift.cjs +18 -19
- package/scripts/lint-descriptions.cjs +7 -3
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +10 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
- package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
- package/scripts/lint-phase-enumeration-drift.cjs +12 -8
- package/scripts/lint-phase-id-drift.cjs +29 -0
- package/scripts/lint-planning-document-positive-control.cjs +329 -0
- package/scripts/lint-response-language-coverage.cjs +3 -0
- package/scripts/lint-skill-deps.cjs +7 -3
- package/scripts/lint-test-file-count.allowlist.json +11 -1
- package/scripts/lint-test-file-count.cjs +34 -1
- package/scripts/lint-vendored-deps.cjs +41 -5
- package/scripts/lint-workflow-shellcheck-baseline.json +10 -10
- package/scripts/mutation-matrix.cjs +50 -5
- package/scripts/require-issue-link-policy.cjs +6 -2
- package/scripts/sync-runtime-launcher.cjs +184 -2
- package/scripts/verify-npm-publish.cjs +76 -20
- package/skills/gsd-add-tests/SKILL.md +6 -1
- package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
- package/skills/gsd-audit-fix/SKILL.md +5 -0
- package/skills/gsd-audit-milestone/SKILL.md +6 -1
- package/skills/gsd-autonomous/SKILL.md +5 -0
- package/skills/gsd-capture/SKILL.md +8 -4
- package/skills/gsd-code-review/SKILL.md +7 -2
- package/skills/gsd-complete-milestone/SKILL.md +4 -0
- package/skills/gsd-config/SKILL.md +8 -4
- package/skills/gsd-debug/SKILL.md +11 -7
- package/skills/gsd-discuss-phase/SKILL.md +7 -3
- package/skills/gsd-docs-update/SKILL.md +12 -7
- package/skills/gsd-eval-review/SKILL.md +6 -1
- package/skills/gsd-execute-phase/SKILL.md +12 -7
- package/skills/gsd-extract-learnings/SKILL.md +5 -0
- package/skills/gsd-fast/SKILL.md +4 -0
- package/skills/gsd-forensics/SKILL.md +5 -1
- package/skills/gsd-graphify/SKILL.md +10 -6
- package/skills/gsd-health/SKILL.md +5 -0
- package/skills/gsd-help/SKILL.md +7 -2
- package/skills/gsd-import/SKILL.md +7 -3
- package/skills/gsd-inbox/SKILL.md +5 -0
- package/skills/gsd-ingest-docs/SKILL.md +5 -1
- package/skills/gsd-manager/SKILL.md +6 -1
- package/skills/gsd-map-codebase/SKILL.md +7 -3
- package/skills/gsd-mempalace-capture/SKILL.md +5 -1
- package/skills/gsd-mempalace-recall/SKILL.md +5 -1
- package/skills/gsd-milestone-summary/SKILL.md +5 -1
- package/skills/gsd-mvp-phase/SKILL.md +8 -3
- package/skills/gsd-new-milestone/SKILL.md +6 -1
- package/skills/gsd-new-project/SKILL.md +5 -0
- package/skills/gsd-next/SKILL.md +6 -1
- package/skills/gsd-ns-context/SKILL.md +4 -0
- package/skills/gsd-ns-ideate/SKILL.md +4 -0
- package/skills/gsd-ns-manage/SKILL.md +4 -0
- package/skills/gsd-ns-project/SKILL.md +4 -0
- package/skills/gsd-ns-review/SKILL.md +4 -0
- package/skills/gsd-ns-workflow/SKILL.md +4 -0
- package/skills/gsd-onboard/SKILL.md +6 -1
- package/skills/gsd-pause-work/SKILL.md +5 -1
- package/skills/gsd-phase/SKILL.md +8 -4
- package/skills/gsd-plan-phase/SKILL.md +6 -1
- package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
- package/skills/gsd-pr-branch/SKILL.md +4 -0
- package/skills/gsd-profile-user/SKILL.md +5 -1
- package/skills/gsd-progress/SKILL.md +6 -1
- package/skills/gsd-quick/SKILL.md +16 -10
- package/skills/gsd-quick-batch/SKILL.md +20 -8
- package/skills/gsd-review/SKILL.md +5 -1
- package/skills/gsd-review-backlog/SKILL.md +3 -2
- package/skills/gsd-secure-phase/SKILL.md +6 -1
- package/skills/gsd-ship/SKILL.md +5 -0
- package/skills/gsd-sketch/SKILL.md +7 -2
- package/skills/gsd-spec-phase/SKILL.md +5 -1
- package/skills/gsd-spike/SKILL.md +8 -3
- package/skills/gsd-surface/SKILL.md +5 -1
- package/skills/gsd-thread/SKILL.md +4 -0
- package/skills/gsd-ui-phase/SKILL.md +6 -1
- package/skills/gsd-ui-review/SKILL.md +6 -1
- package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
- package/skills/gsd-undo/SKILL.md +5 -1
- package/skills/gsd-update/SKILL.md +6 -2
- package/skills/gsd-validate-phase/SKILL.md +6 -1
- package/skills/gsd-verify-work/SKILL.md +6 -1
- package/skills/gsd-workspace/SKILL.md +7 -3
- package/skills/gsd-workstreams/SKILL.md +6 -6
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +0 -24
|
@@ -46,14 +46,19 @@ const planDocument = require("./plan-document.cjs");
|
|
|
46
46
|
const state_document_cjs_1 = require("./state-document.cjs");
|
|
47
47
|
const runtime_slash_cjs_1 = require("./runtime-slash.cjs");
|
|
48
48
|
const host_runtime_detection_cjs_1 = require("./host-runtime-detection.cjs");
|
|
49
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports -- commands.cjs is an export= CommonJS module
|
|
50
|
-
const commandsMod = require("./commands.cjs");
|
|
51
49
|
const security_cjs_1 = require("./security.cjs");
|
|
52
50
|
const runtime_homes_cjs_1 = require("./runtime-homes.cjs");
|
|
53
51
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- frontmatter.cjs is an export= CommonJS module
|
|
54
52
|
const frontmatterMod = require("./frontmatter.cjs");
|
|
55
53
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- verification.cjs is an export= CommonJS module
|
|
56
54
|
const verificationMod = require("./verification.cjs");
|
|
55
|
+
// #5060: Phase Status Module — the single owner of "what state is phase P
|
|
56
|
+
// in?" (ADR-5057 §1/§2). Replaces this file's own determinePhaseStatus/
|
|
57
|
+
// projectCompletionStatus derivations, and cmdInitMilestoneOp's
|
|
58
|
+
// summary-count-only completion check (the former listPhaseSummaryFiles
|
|
59
|
+
// helper, since removed). listPhasePlanFiles (below) is unrelated — it backs
|
|
60
|
+
// only the STATE.md disk-plan-count validation, not a completion verdict.
|
|
61
|
+
const phase_status_cjs_1 = require("./phase-status.cjs");
|
|
57
62
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- uat-predicate.cjs is an export= CommonJS module
|
|
58
63
|
const uatPredicateMod = require("./uat-predicate.cjs");
|
|
59
64
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- agent-install-check.cjs is an export= CommonJS module
|
|
@@ -91,10 +96,9 @@ const { getRoadmapPhaseInternal, getMilestoneInfo, stripShippedMilestones, extra
|
|
|
91
96
|
const { pathExistsInternal, generateSlugInternal, toPosixPath } = coreUtils;
|
|
92
97
|
const { comparePhaseNum, normalizePhaseName, stripProjectCodePrefix, PHASE_NUMBER_TOKEN_SOURCE, PHASE_DEP_REF_SOURCE, isForeignPrefixedPhaseQuery, isSentinelPhaseId, extractPhaseToken, scopeToPhase, renderPhaseBranchName, parsePhaseId, renderPhaseId, phaseHeadingPrefixSrcFor, PHASE_HEADING_BASELINE, buildPhaseHeadingScanRegex, } = phaseId;
|
|
93
98
|
const { pruneOrphanedWorktrees } = worktreeSafety;
|
|
94
|
-
const { planningPaths, planningDir, planningRoot, todosDir, listAvailableWorkstreams, peekActiveWorkstream, resolveEnvWorkstream, diagnoseUnresolvedActiveWorkstream, describeUnresolvedWorkstreamReason, findContextMdIn, resolvePhaseIdConvention, } = planningWorkspace;
|
|
95
|
-
const {
|
|
96
|
-
const {
|
|
97
|
-
const { isPhaseComplete, resolveVerificationFile, resolveUatFile } = verificationMod;
|
|
99
|
+
const { planningPaths, planningDir, planningRoot, todosDir, listAvailableWorkstreams, peekActiveWorkstream, resolveEnvWorkstream, diagnoseUnresolvedActiveWorkstream, describeUnresolvedWorkstreamReason, findContextMdIn, resolvePhaseIdConvention, worktreesOptedOut, } = planningWorkspace;
|
|
100
|
+
const { extractFrontmatter, frontmatterBlock } = frontmatterMod;
|
|
101
|
+
const { isPhaseComplete, resolveVerificationFile, resolveUatFile, VERIFICATION_STATUS, VerificationStatusError } = verificationMod;
|
|
98
102
|
const { evaluateUatPassed } = uatPredicateMod;
|
|
99
103
|
const { resolveLoopHooks } = loopResolverMod;
|
|
100
104
|
const { loadRegistry } = capabilityLoaderMod;
|
|
@@ -186,20 +190,10 @@ function applyRoadmapFallback(phaseInfo, roadmapPhase, buildFallback) {
|
|
|
186
190
|
}
|
|
187
191
|
return phaseInfo;
|
|
188
192
|
}
|
|
189
|
-
function listPhaseSummaryFiles(phaseDir) {
|
|
190
|
-
return scanPhasePlans(phaseDir)['summaryFiles'];
|
|
191
|
-
}
|
|
192
193
|
function listPhasePlanFiles(phaseDir) {
|
|
193
194
|
return scanPhasePlans(phaseDir)['planFiles'];
|
|
194
195
|
}
|
|
195
|
-
function
|
|
196
|
-
if (phaseComplete)
|
|
197
|
-
return 'complete';
|
|
198
|
-
if (implementationComplete)
|
|
199
|
-
return 'executed';
|
|
200
|
-
return 'incomplete';
|
|
201
|
-
}
|
|
202
|
-
function buildPhaseCompletionProjection(cwd, phaseNumber, phaseDir, planCount, summaryCount, slashRuntime) {
|
|
196
|
+
function buildPhaseCompletionProjection(cwd, phaseNumber, phaseDir, planCount, summaryCount, slashRuntime, convention) {
|
|
203
197
|
// ADR-3180 §7.4 (issue #3186) / DO-NOT-MIGRATE exemption
|
|
204
198
|
// (scripts/lint-completion-predicate-drift.cjs FUNCTION_SCOPED_EXEMPTIONS,
|
|
205
199
|
// declared deviation): `implementation_complete` answers "are the plans
|
|
@@ -219,20 +213,35 @@ function buildPhaseCompletionProjection(cwd, phaseNumber, phaseDir, planCount, s
|
|
|
219
213
|
// #2617: the router still owns both the message content and the runtime
|
|
220
214
|
// projection; init passes the phase number it already knows (its phaseDir
|
|
221
215
|
// is unresolved in some branches, where the router could not derive one).
|
|
222
|
-
const completionResult = isPhaseComplete(phaseFullDir, { runtime: slashRuntime, phaseNumber });
|
|
216
|
+
const completionResult = isPhaseComplete(phaseFullDir, { runtime: slashRuntime, phaseNumber, convention });
|
|
217
|
+
// #5118: the owner carried an out-of-set report status in its result
|
|
218
|
+
// (`statusError`, `verification.status: null`); an init bundle is never
|
|
219
|
+
// assembled over a report the owner refused — the carried error is raised
|
|
220
|
+
// here and every `init *` surface built on this projection fails with the
|
|
221
|
+
// error's own reason (the CLI entry seam), printing nothing.
|
|
222
|
+
if (completionResult.value.statusError)
|
|
223
|
+
throw completionResult.value.statusError;
|
|
223
224
|
const verificationStatus = completionResult.value.verification;
|
|
224
225
|
const projectedVerificationStatus = verificationStatus.status;
|
|
225
226
|
const projectedVerificationAction = verificationStatus.next_action;
|
|
226
|
-
const verificationPassed = projectedVerificationStatus ===
|
|
227
|
+
const verificationPassed = projectedVerificationStatus === VERIFICATION_STATUS.PASSED;
|
|
227
228
|
const phaseComplete = completionResult.value.complete;
|
|
228
229
|
return {
|
|
229
230
|
implementation_complete: implementationComplete,
|
|
230
231
|
verification_status: projectedVerificationStatus,
|
|
231
232
|
verification_passed: verificationPassed,
|
|
232
233
|
phase_complete: phaseComplete,
|
|
233
|
-
|
|
234
|
+
// #5060: Phase Status Module — the single owner of "what state is phase P
|
|
235
|
+
// in?" (ADR-5057 §1/§2).
|
|
236
|
+
completion_status: (0, phase_status_cjs_1.toCompletionStatus)((0, phase_status_cjs_1.phaseStatusFromFacts)({
|
|
237
|
+
planCount,
|
|
238
|
+
summaryCount,
|
|
239
|
+
complete: phaseComplete,
|
|
240
|
+
verificationStatus: projectedVerificationStatus,
|
|
241
|
+
})),
|
|
234
242
|
verification_next_action: projectedVerificationAction,
|
|
235
243
|
verification_next_command: verificationStatus.next_command,
|
|
244
|
+
verification_route: verificationStatus.route,
|
|
236
245
|
// #3057 B3: readVerificationStatus's result carries this flag when its
|
|
237
246
|
// internal staleness check could not run to completion.
|
|
238
247
|
verification_stale_check_indeterminate: 'staleCheckIndeterminate' in verificationStatus
|
|
@@ -479,7 +488,8 @@ function detectHasPriorPhases(cwd, phaseInfo) {
|
|
|
479
488
|
* `false` — strict `=== true`, never coerced, mirrors `detectHasPriorPhases`'s
|
|
480
489
|
* degrade-to-false discipline. `keyPath` is always a fixed literal supplied
|
|
481
490
|
* by this module, never attacker/user input, so a plain bracket traversal
|
|
482
|
-
* carries no prototype hazard here.
|
|
491
|
+
* carries no prototype hazard here. Only for keys whose default is OFF — a
|
|
492
|
+
* default-ON key read here silently inverts its unset value (#4977).
|
|
483
493
|
*/
|
|
484
494
|
function readConfigJsonBoolean(cwd, keyPath) {
|
|
485
495
|
try {
|
|
@@ -727,7 +737,13 @@ function buildSectionManifestField(cwd, phaseInfo, options, workflow, overrides
|
|
|
727
737
|
flags,
|
|
728
738
|
phaseNumber,
|
|
729
739
|
hasPriorPhases: detectHasPriorPhases(cwd, phaseInfo),
|
|
730
|
-
|
|
740
|
+
// #4977: `workflow.use_worktrees` defaults ON, so this fact must come from
|
|
741
|
+
// the #3972 owner `query dispatch-isolation` and the isolation guard
|
|
742
|
+
// already share — not `readConfigJsonBoolean`, whose absent ⇒ false
|
|
743
|
+
// polarity (right for the opt-in keys around it) excluded the quick
|
|
744
|
+
// pre-dispatch plan commit while the executor was still dispatched
|
|
745
|
+
// isolated. The ladder also brings root→workstream inheritance along.
|
|
746
|
+
worktreesEnabled: !worktreesOptedOut(cwd),
|
|
731
747
|
phaseMvpMode: detectPhaseMvpMode(cwd, phaseNumber),
|
|
732
748
|
needsCodebaseMap: overrides.needsCodebaseMap,
|
|
733
749
|
chunkedMode,
|
|
@@ -1075,8 +1091,10 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
1075
1091
|
phase_slug: phaseInfo?.['phase_slug'] || null,
|
|
1076
1092
|
padded_phase: phaseNumberPlan ? normalizePhaseName(phaseNumberPlan) : null,
|
|
1077
1093
|
phase_req_ids,
|
|
1094
|
+
// #5060: Phase Status Module — the single owner of "what state is phase P
|
|
1095
|
+
// in?" (ADR-5057 §1/§2).
|
|
1078
1096
|
phase_status: phaseDirPlan
|
|
1079
|
-
?
|
|
1097
|
+
? (0, phase_status_cjs_1.toDisplayLabel)((0, phase_status_cjs_1.phaseStatus)(node_path_1.default.join(cwd, phaseDirPlan), { convention: resolvePhaseIdConvention(cwd) }).value.status, { pendingWord: 'Pending' })
|
|
1080
1098
|
: 'Pending',
|
|
1081
1099
|
has_research: phaseInfo?.['has_research'] || false,
|
|
1082
1100
|
has_context: phaseInfo?.['has_context'] || false,
|
|
@@ -1273,12 +1291,15 @@ function buildInitCompletenessFields(cwd) {
|
|
|
1273
1291
|
}
|
|
1274
1292
|
function cmdInitNewProject(cwd, raw, options = {}) {
|
|
1275
1293
|
const config = loadConfig(cwd);
|
|
1276
|
-
|
|
1277
|
-
|
|
1294
|
+
// #4976: probe the GSD-owned store the config loader resolves
|
|
1295
|
+
// (`GSD_HOME || homedir()`), so these flags agree with config-new-project's
|
|
1296
|
+
// key probes in the same /gsd-new-project run.
|
|
1297
|
+
const gsdHome = process.env['GSD_HOME'] || node_os_1.default.homedir();
|
|
1298
|
+
const braveKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'brave_api_key');
|
|
1278
1299
|
const hasBraveSearch = !!(process.env['BRAVE_API_KEY'] || node_fs_1.default.existsSync(braveKeyFile));
|
|
1279
|
-
const firecrawlKeyFile = node_path_1.default.join(
|
|
1300
|
+
const firecrawlKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'firecrawl_api_key');
|
|
1280
1301
|
const hasFirecrawl = !!(process.env['FIRECRAWL_API_KEY'] || node_fs_1.default.existsSync(firecrawlKeyFile));
|
|
1281
|
-
const exaKeyFile = node_path_1.default.join(
|
|
1302
|
+
const exaKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'exa_api_key');
|
|
1282
1303
|
const hasExaSearch = !!(process.env['EXA_API_KEY'] || node_fs_1.default.existsSync(exaKeyFile));
|
|
1283
1304
|
const hasCode = hasCodeFilesInternal(cwd);
|
|
1284
1305
|
const hasPackageFile = hasPackageFileInternal(cwd);
|
|
@@ -1638,9 +1659,21 @@ function cmdInitVerifyWork(cwd, phase, raw) {
|
|
|
1638
1659
|
};
|
|
1639
1660
|
});
|
|
1640
1661
|
const phaseDir = phaseInfo?.['directory'] || null;
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1662
|
+
// #5060: Phase Status Module — matched counts from the §7.5 owner
|
|
1663
|
+
// (scanPhasePlans via phaseStatus), not phaseInfo's raw plans/summaries
|
|
1664
|
+
// arrays, so this projection's counts agree with buildPhaseCompletionProjection's
|
|
1665
|
+
// own isPhaseComplete call below (see the convention thread there).
|
|
1666
|
+
const verifyWorkConvention = resolvePhaseIdConvention(cwd);
|
|
1667
|
+
const verifyWorkPs = phaseDir
|
|
1668
|
+
? (0, phase_status_cjs_1.phaseStatus)(node_path_1.default.join(cwd, phaseDir), { convention: verifyWorkConvention })
|
|
1669
|
+
: null;
|
|
1670
|
+
const planCount = verifyWorkPs
|
|
1671
|
+
? verifyWorkPs.value.planCount
|
|
1672
|
+
: phaseInfo?.['plans']?.length || 0;
|
|
1673
|
+
const summaryCount = verifyWorkPs
|
|
1674
|
+
? verifyWorkPs.value.summaryCount
|
|
1675
|
+
: phaseInfo?.['summaries']?.length || 0;
|
|
1676
|
+
const completion = buildPhaseCompletionProjection(cwd, phaseInfo?.['phase_number'] || phase, phaseDir, planCount, summaryCount, _slashRuntime, verifyWorkConvention);
|
|
1644
1677
|
const uatReport = phaseDir
|
|
1645
1678
|
? evaluateUatPassed(node_path_1.default.join(cwd, phaseDir), {
|
|
1646
1679
|
policy: { requireVerification: true },
|
|
@@ -2314,6 +2347,12 @@ function cmdInitTodos(cwd, area, raw) {
|
|
|
2314
2347
|
function cmdInitMilestoneOp(cwd, raw) {
|
|
2315
2348
|
const config = loadConfig(cwd);
|
|
2316
2349
|
const milestone = milestoneRecord(cwd);
|
|
2350
|
+
// #5060: Phase Status Module — the single owner of "what state is phase P
|
|
2351
|
+
// in?" (ADR-5057 §1/§2). A phase counts as completed only when the ladder
|
|
2352
|
+
// itself says COMPLETE, not "has any *-SUMMARY.md" (a counts-only verdict
|
|
2353
|
+
// that bypasses isPhaseComplete and disagrees with every other completion
|
|
2354
|
+
// consumer on a stale `passed` report).
|
|
2355
|
+
const milestoneOpConvention = resolvePhaseIdConvention(cwd);
|
|
2317
2356
|
let phaseCount = 0;
|
|
2318
2357
|
let completedPhases = 0;
|
|
2319
2358
|
const phasesDir = node_path_1.default.join(planningDir(cwd), 'phases');
|
|
@@ -2325,7 +2364,7 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
2325
2364
|
// #1729: `(?:\s*\([^)\n]{0,200}\))?` tolerates a pre-colon ( ) tag, owned by
|
|
2326
2365
|
// buildPhaseHeadingScanRegex (phase-id.cts) so this scan also recognizes
|
|
2327
2366
|
// bracket-convention headings instead of hand-rolling a literal `Phase\s+`.
|
|
2328
|
-
const { regex: phasePattern, phaseNumGroup } = buildPhaseHeadingScanRegex(PHASE_HEADING_BASELINE.ANY_BRACKET,
|
|
2367
|
+
const { regex: phasePattern, phaseNumGroup } = buildPhaseHeadingScanRegex(PHASE_HEADING_BASELINE.ANY_BRACKET, milestoneOpConvention);
|
|
2329
2368
|
let m;
|
|
2330
2369
|
while ((m = phasePattern.exec(currentSection)) !== null) {
|
|
2331
2370
|
// #3185: canonical sentinel predicate (SENTINEL_RANGES [0,999]) — this was a local 999-only literal that admitted Phase 0.
|
|
@@ -2366,8 +2405,8 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
2366
2405
|
if (!dirName)
|
|
2367
2406
|
continue;
|
|
2368
2407
|
try {
|
|
2369
|
-
const
|
|
2370
|
-
if (
|
|
2408
|
+
const isComplete = (0, phase_status_cjs_1.phaseStatus)(node_path_1.default.join(phasesDir, dirName), { convention: milestoneOpConvention }).value.status === phase_status_cjs_1.PHASE_STATUS.COMPLETE;
|
|
2409
|
+
if (isComplete)
|
|
2371
2410
|
completedPhases++;
|
|
2372
2411
|
}
|
|
2373
2412
|
catch {
|
|
@@ -2386,8 +2425,8 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
2386
2425
|
phaseCount = dirs.length;
|
|
2387
2426
|
for (const dir of dirs) {
|
|
2388
2427
|
try {
|
|
2389
|
-
const
|
|
2390
|
-
if (
|
|
2428
|
+
const isComplete = (0, phase_status_cjs_1.phaseStatus)(node_path_1.default.join(phasesDir, dir), { convention: milestoneOpConvention }).value.status === phase_status_cjs_1.PHASE_STATUS.COMPLETE;
|
|
2429
|
+
if (isComplete)
|
|
2391
2430
|
completedPhases++;
|
|
2392
2431
|
}
|
|
2393
2432
|
catch {
|
|
@@ -2493,11 +2532,23 @@ function cmdInitManager(cwd, raw) {
|
|
|
2493
2532
|
// getMilestonePhaseFilter window check (which also never excluded
|
|
2494
2533
|
// sentinels, unlike the owner).
|
|
2495
2534
|
const _checkboxStates = new Map();
|
|
2496
|
-
|
|
2535
|
+
// #4982: anchored (`^`, `m`) so the phase label must be the FIRST thing
|
|
2536
|
+
// after the checkbox (tolerating only an optional `**` bold marker) —
|
|
2537
|
+
// the prior unanchored `\s*.*` let the greedy `.*` bind to the LAST
|
|
2538
|
+
// "Phase N" mentioned anywhere in the line's prose instead of the line's
|
|
2539
|
+
// own phase. First-match-wins (`if (!_checkboxStates.has(...))` below)
|
|
2540
|
+
// additionally guards against a later anchored line (e.g. a per-plan
|
|
2541
|
+
// sub-entry self-titled "Phase N ...") overwriting an already-recorded
|
|
2542
|
+
// phase's own (first) checkbox — anchoring alone does not fully close
|
|
2543
|
+
// that "last-match-wins" composition defect.
|
|
2544
|
+
const _cbPattern = new RegExp(`^[ \\t]*-[ \\t]*\\[(x| )\\][ \\t]*(?:\\*\\*)?${phaseHeadingPrefix}(${PHASE_NUMBER_TOKEN_SOURCE})[:\\s]`, 'gim');
|
|
2497
2545
|
let _cbMatch;
|
|
2498
2546
|
while ((_cbMatch = _cbPattern.exec(content)) !== null) {
|
|
2499
2547
|
const phaseGroup = capturesBracketId ? 3 : 2;
|
|
2500
|
-
|
|
2548
|
+
const _cbKey = _cbMatch[phaseGroup];
|
|
2549
|
+
if (!_checkboxStates.has(_cbKey)) {
|
|
2550
|
+
_checkboxStates.set(_cbKey, _cbMatch[1].toLowerCase() === 'x');
|
|
2551
|
+
}
|
|
2501
2552
|
}
|
|
2502
2553
|
// #1729: `(?:\s*\([^)\n]{0,200}\))?` tolerates a pre-colon ( ) tag (literal mirror of OPTIONAL_PHASE_TAG_SOURCE).
|
|
2503
2554
|
const phasePattern = new RegExp(`#{2,4}\\s*${phaseHeadingPrefix}(${PHASE_NUMBER_TOKEN_SOURCE})(?:\\s*\\([^)\\n]{0,200}\\))?\\s*:\\s*([^\\n]+)`, 'gi');
|
|
@@ -2529,7 +2580,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2529
2580
|
const goal = roadmapParser.extractPhaseFieldMultiline(section, 'Goal');
|
|
2530
2581
|
const dependsMatch = section.match(/\*\*Depends on(?::\*\*|\*\*:)\s*([^\n]+)/i);
|
|
2531
2582
|
const depends_on = dependsMatch ? dependsMatch[1].trim() : null;
|
|
2532
|
-
let diskStatus =
|
|
2583
|
+
let diskStatus = phase_status_cjs_1.DISK_STATUS.NO_DIRECTORY;
|
|
2533
2584
|
let planCount = 0;
|
|
2534
2585
|
let summaryCount = 0;
|
|
2535
2586
|
let hasContext = false;
|
|
@@ -2539,7 +2590,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2539
2590
|
// #4014 (epic #3473 B4-unreadable): default COMPLETE — no directory at
|
|
2540
2591
|
// all (dirMatch not found) is a genuine, not-unreadable answer.
|
|
2541
2592
|
let contextScope = SCOPE.COMPLETE;
|
|
2542
|
-
let completion = buildPhaseCompletionProjection(cwd, phaseNum, null, planCount, summaryCount, _slashRuntime);
|
|
2593
|
+
let completion = buildPhaseCompletionProjection(cwd, phaseNum, null, planCount, summaryCount, _slashRuntime, phaseIdConvention);
|
|
2543
2594
|
try {
|
|
2544
2595
|
// #4801: resolve through the canonical locator instead of a private
|
|
2545
2596
|
// current-milestone-only scan. findPhaseInternal searches the live
|
|
@@ -2570,8 +2621,11 @@ function cmdInitManager(cwd, raw) {
|
|
|
2570
2621
|
// only, the failure control-flow is untouched.
|
|
2571
2622
|
contextScope = findContextMdIn(fullDir).scope;
|
|
2572
2623
|
const phaseFiles = node_fs_1.default.readdirSync(fullDir);
|
|
2573
|
-
|
|
2574
|
-
|
|
2624
|
+
// #5060: Phase Status Module — the single owner of "what state is
|
|
2625
|
+
// phase P in?" (ADR-5057 §1/§2).
|
|
2626
|
+
const ps = (0, phase_status_cjs_1.phaseStatus)(fullDir, { convention: phaseIdConvention });
|
|
2627
|
+
planCount = ps.value.planCount;
|
|
2628
|
+
summaryCount = ps.value.summaryCount;
|
|
2575
2629
|
// #3511-class: scope the raw listing to THIS phase's own artifacts
|
|
2576
2630
|
// before the hasContext/hasResearch predicates run, so a stray
|
|
2577
2631
|
// cross-phase `-CONTEXT.md`/`-RESEARCH.md` sitting in this directory
|
|
@@ -2579,21 +2633,8 @@ function cmdInitManager(cwd, raw) {
|
|
|
2579
2633
|
const scopedFiles = scopeToPhase(phaseFiles, dirMatch);
|
|
2580
2634
|
hasContext = findContextMdIn(scopedFiles) !== null;
|
|
2581
2635
|
hasResearch = scopedFiles.some((f) => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
|
|
2582
|
-
completion = buildPhaseCompletionProjection(cwd, phaseNum, phaseDirRel, planCount, summaryCount, _slashRuntime);
|
|
2583
|
-
|
|
2584
|
-
diskStatus = 'complete';
|
|
2585
|
-
else if (completion.implementation_complete)
|
|
2586
|
-
diskStatus = 'executed';
|
|
2587
|
-
else if (summaryCount > 0)
|
|
2588
|
-
diskStatus = 'partial';
|
|
2589
|
-
else if (planCount > 0)
|
|
2590
|
-
diskStatus = 'planned';
|
|
2591
|
-
else if (hasResearch)
|
|
2592
|
-
diskStatus = 'researched';
|
|
2593
|
-
else if (hasContext)
|
|
2594
|
-
diskStatus = 'discussed';
|
|
2595
|
-
else
|
|
2596
|
-
diskStatus = 'empty';
|
|
2636
|
+
completion = buildPhaseCompletionProjection(cwd, phaseNum, phaseDirRel, planCount, summaryCount, _slashRuntime, phaseIdConvention);
|
|
2637
|
+
diskStatus = (0, phase_status_cjs_1.toDiskStatus)(ps.value.status, { hasResearch, hasContext });
|
|
2597
2638
|
const nowMs = clock_cjs_1.realClock.now();
|
|
2598
2639
|
let newestMtime = 0;
|
|
2599
2640
|
for (const f of phaseFiles) {
|
|
@@ -2751,7 +2792,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2751
2792
|
}
|
|
2752
2793
|
for (const phase of phases) {
|
|
2753
2794
|
phase['is_next_to_discuss'] =
|
|
2754
|
-
(phase['disk_status'] ===
|
|
2795
|
+
(phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.EMPTY || phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.NO_DIRECTORY) &&
|
|
2755
2796
|
phase['deps_satisfied'];
|
|
2756
2797
|
}
|
|
2757
2798
|
let waitingSignal = null;
|
|
@@ -2773,12 +2814,12 @@ function cmdInitManager(cwd, raw) {
|
|
|
2773
2814
|
}
|
|
2774
2815
|
const recommendedActions = [];
|
|
2775
2816
|
for (const phase of phases) {
|
|
2776
|
-
if (phase['disk_status'] ===
|
|
2817
|
+
if (phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.COMPLETE)
|
|
2777
2818
|
continue;
|
|
2778
2819
|
// #3185: canonical sentinel predicate (SENTINEL_RANGES [0,999]) — this was a local 999-only literal that admitted Phase 0.
|
|
2779
2820
|
if (isSentinelPhaseId(phase['number']))
|
|
2780
2821
|
continue;
|
|
2781
|
-
if (phase['disk_status'] ===
|
|
2822
|
+
if (phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.EXECUTED) {
|
|
2782
2823
|
recommendedActions.push({
|
|
2783
2824
|
phase: phase['number'],
|
|
2784
2825
|
phase_name: phase['name'],
|
|
@@ -2787,7 +2828,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2787
2828
|
command: phase['verification_next_command'],
|
|
2788
2829
|
});
|
|
2789
2830
|
}
|
|
2790
|
-
else if (phase['disk_status'] ===
|
|
2831
|
+
else if (phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.PLANNED && phase['deps_satisfied']) {
|
|
2791
2832
|
recommendedActions.push({
|
|
2792
2833
|
phase: phase['number'],
|
|
2793
2834
|
phase_name: phase['name'],
|
|
@@ -2796,8 +2837,8 @@ function cmdInitManager(cwd, raw) {
|
|
|
2796
2837
|
command: `${(0, runtime_slash_cjs_1.formatGsdSlash)('execute-phase', _slashRuntime)} ${phase['number']}`,
|
|
2797
2838
|
});
|
|
2798
2839
|
}
|
|
2799
|
-
else if (phase['disk_status'] ===
|
|
2800
|
-
phase['disk_status'] ===
|
|
2840
|
+
else if (phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.DISCUSSED ||
|
|
2841
|
+
phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.RESEARCHED) {
|
|
2801
2842
|
recommendedActions.push({
|
|
2802
2843
|
phase: phase['number'],
|
|
2803
2844
|
phase_name: phase['name'],
|
|
@@ -2806,7 +2847,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2806
2847
|
command: `${(0, runtime_slash_cjs_1.formatGsdSlash)('plan-phase', _slashRuntime)} ${phase['number']}`,
|
|
2807
2848
|
});
|
|
2808
2849
|
}
|
|
2809
|
-
else if ((phase['disk_status'] ===
|
|
2850
|
+
else if ((phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.EMPTY || phase['disk_status'] === phase_status_cjs_1.DISK_STATUS.NO_DIRECTORY) &&
|
|
2810
2851
|
phase['is_next_to_discuss']) {
|
|
2811
2852
|
recommendedActions.push({
|
|
2812
2853
|
phase: phase['number'],
|
|
@@ -2817,10 +2858,10 @@ function cmdInitManager(cwd, raw) {
|
|
|
2817
2858
|
});
|
|
2818
2859
|
}
|
|
2819
2860
|
}
|
|
2820
|
-
const activeExecuting = phases.filter((p) => p['disk_status'] ===
|
|
2821
|
-
(p['disk_status'] ===
|
|
2861
|
+
const activeExecuting = phases.filter((p) => p['disk_status'] === phase_status_cjs_1.DISK_STATUS.PARTIAL ||
|
|
2862
|
+
(p['disk_status'] === phase_status_cjs_1.DISK_STATUS.PLANNED && p['is_active']));
|
|
2822
2863
|
const activePlanning = phases.filter((p) => p['is_active'] &&
|
|
2823
|
-
(p['disk_status'] ===
|
|
2864
|
+
(p['disk_status'] === phase_status_cjs_1.DISK_STATUS.DISCUSSED || p['disk_status'] === phase_status_cjs_1.DISK_STATUS.RESEARCHED));
|
|
2824
2865
|
const filteredActions = recommendedActions.filter((action) => {
|
|
2825
2866
|
if (action['action'] === 'execute' && activeExecuting.length > 0) {
|
|
2826
2867
|
return activeExecuting.every((active) => !hasDepRelationship(action['phase'], active['number']));
|
|
@@ -2863,7 +2904,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2863
2904
|
phases,
|
|
2864
2905
|
phase_count: phases.length,
|
|
2865
2906
|
completed_count: completedCount,
|
|
2866
|
-
in_progress_count: phases.filter((p) => [
|
|
2907
|
+
in_progress_count: phases.filter((p) => [phase_status_cjs_1.DISK_STATUS.EXECUTED, phase_status_cjs_1.DISK_STATUS.PARTIAL, phase_status_cjs_1.DISK_STATUS.PLANNED, phase_status_cjs_1.DISK_STATUS.DISCUSSED, phase_status_cjs_1.DISK_STATUS.RESEARCHED].includes(p['disk_status'])).length,
|
|
2867
2908
|
recommended_actions: filteredActions,
|
|
2868
2909
|
waiting_signal: waitingSignal,
|
|
2869
2910
|
all_complete: completedCount === nonBacklogPhases.length && nonBacklogPhases.length > 0,
|
|
@@ -3213,10 +3254,34 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
3213
3254
|
// uncounted LABEL_ONLY consumer to init.cts's pinned
|
|
3214
3255
|
// tests/adr-612-bracket-heading-selection.test.cjs census.
|
|
3215
3256
|
// phase-id-owner: deliberately unmigrated (#4984 revert) — see comment above.
|
|
3216
|
-
|
|
3257
|
+
// #4982: anchored (`^`, `m`) — the phase label must be the FIRST thing
|
|
3258
|
+
// after the checkbox (tolerating only an optional `**` bold marker) — so
|
|
3259
|
+
// the greedy `.*` this replaces can no longer bind a line's checkbox to
|
|
3260
|
+
// the LAST "Phase N" mentioned anywhere in that line's prose. This value
|
|
3261
|
+
// feeds `roadmap_complete` AND directly gates next_phase/current_phase
|
|
3262
|
+
// selection below, so getting the wrong phase here is load-bearing, not
|
|
3263
|
+
// metadata-only (contrast the `_cbPattern` site in cmdInitManager).
|
|
3264
|
+
// First-match-wins (`if (!roadmapCheckboxStates.has(...))`) additionally
|
|
3265
|
+
// guards against a later anchored line (e.g. a per-plan sub-entry
|
|
3266
|
+
// self-titled "Phase N ...") overwriting an already-recorded phase's own
|
|
3267
|
+
// (first) checkbox — anchoring alone does not fully close that
|
|
3268
|
+
// "last-match-wins" composition defect.
|
|
3269
|
+
// `(?:\[[^\]\n]{0,200}\]\s*)?` tolerates an optional leading bracket tag
|
|
3270
|
+
// (literal mirror of BASE_ANY_BRACKET_HEADING_PREFIX_SRC, phase-id.cts)
|
|
3271
|
+
// BEFORE the literal "Phase" word — decoration tolerance only, no capture
|
|
3272
|
+
// group, no convention gating. Without it the anchor fix above regresses
|
|
3273
|
+
// a checklist line combining a bracket tag with literal "Phase N" wording
|
|
3274
|
+
// (e.g. `**[GSD.02] Phase 3: ...**`), which the old unanchored `.*`
|
|
3275
|
+
// matched (by absorbing the bracket text). This does NOT migrate the site
|
|
3276
|
+
// onto phaseHeadingPrefixSrcFor / the bracket convention — that stays
|
|
3277
|
+
// out of scope per the comment above (#4984 revert, pinned census).
|
|
3278
|
+
const cbPattern = new RegExp(`^[ \\t]*-[ \\t]*\\[(x| )\\][ \\t]*(?:\\*\\*)?(?:\\[[^\\]\\n]{0,200}\\]\\s*)?Phase\\s+(${PHASE_NUMBER_TOKEN_SOURCE})[:\\s]`, 'gim');
|
|
3217
3279
|
let cbm;
|
|
3218
3280
|
while ((cbm = cbPattern.exec(roadmapContent)) !== null) {
|
|
3219
|
-
|
|
3281
|
+
const cbKey = cbm[2];
|
|
3282
|
+
if (!roadmapCheckboxStates.has(cbKey)) {
|
|
3283
|
+
roadmapCheckboxStates.set(cbKey, cbm[1].toLowerCase() === 'x');
|
|
3284
|
+
}
|
|
3220
3285
|
}
|
|
3221
3286
|
}
|
|
3222
3287
|
catch {
|
|
@@ -3238,8 +3303,9 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
3238
3303
|
seenPhaseNums.add(phaseNumber.replace(/^0+/, '') || '0');
|
|
3239
3304
|
const phasePath = node_path_1.default.join(phasesDir, dir);
|
|
3240
3305
|
const phaseFiles = node_fs_1.default.readdirSync(phasePath);
|
|
3241
|
-
|
|
3242
|
-
|
|
3306
|
+
// #5060: Phase Status Module — the single owner of "what state is
|
|
3307
|
+
// phase P in?" (ADR-5057 §1/§2).
|
|
3308
|
+
const ps = (0, phase_status_cjs_1.phaseStatus)(phasePath, { convention: resolvePhaseIdConvention(cwd) });
|
|
3243
3309
|
// #3511-class: scope the raw listing to THIS phase's own artifacts
|
|
3244
3310
|
// before the hasResearch predicate runs, so a stray cross-phase
|
|
3245
3311
|
// `-RESEARCH.md` sitting in this directory cannot win this phase's
|
|
@@ -3247,16 +3313,8 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
3247
3313
|
const scopedPhaseFiles = scopeToPhase(phaseFiles, dir);
|
|
3248
3314
|
const hasResearch = scopedPhaseFiles.some((f) => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
|
|
3249
3315
|
const phaseDirRel = toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'phases', dir)));
|
|
3250
|
-
const completion = buildPhaseCompletionProjection(cwd, phaseNumber, phaseDirRel,
|
|
3251
|
-
const status =
|
|
3252
|
-
? 'complete'
|
|
3253
|
-
: completion.implementation_complete
|
|
3254
|
-
? 'executed'
|
|
3255
|
-
: plans.length > 0
|
|
3256
|
-
? 'in_progress'
|
|
3257
|
-
: hasResearch
|
|
3258
|
-
? 'researched'
|
|
3259
|
-
: 'pending';
|
|
3316
|
+
const completion = buildPhaseCompletionProjection(cwd, phaseNumber, phaseDirRel, ps.value.planCount, ps.value.summaryCount, _slashRuntime, resolvePhaseIdConvention(cwd));
|
|
3317
|
+
const status = (0, phase_status_cjs_1.toProgressStatus)(ps.value.status, { hasResearch });
|
|
3260
3318
|
const phaseInfo = {
|
|
3261
3319
|
number: phaseNumber,
|
|
3262
3320
|
name: phaseName,
|
|
@@ -3265,30 +3323,37 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
3265
3323
|
// above still joins it against cwd.
|
|
3266
3324
|
directory: toPosixPath(node_path_1.default.join(cwd, phaseDirRel)),
|
|
3267
3325
|
status,
|
|
3268
|
-
plan_count:
|
|
3269
|
-
summary_count:
|
|
3326
|
+
plan_count: ps.value.planCount,
|
|
3327
|
+
summary_count: ps.value.summaryCount,
|
|
3270
3328
|
has_research: hasResearch,
|
|
3271
3329
|
...completion,
|
|
3272
3330
|
};
|
|
3273
3331
|
phases.push(phaseInfo);
|
|
3274
|
-
if (!currentPhase && (status ===
|
|
3332
|
+
if (!currentPhase && (status === phase_status_cjs_1.PROGRESS_STATUS.EXECUTED || status === phase_status_cjs_1.PROGRESS_STATUS.IN_PROGRESS || status === phase_status_cjs_1.PROGRESS_STATUS.RESEARCHED)) {
|
|
3275
3333
|
currentPhase = phaseInfo;
|
|
3276
3334
|
}
|
|
3277
|
-
if (!nextPhase && status ===
|
|
3335
|
+
if (!nextPhase && status === phase_status_cjs_1.PROGRESS_STATUS.PENDING) {
|
|
3278
3336
|
nextPhase = phaseInfo;
|
|
3279
3337
|
}
|
|
3280
3338
|
}
|
|
3281
3339
|
}
|
|
3282
|
-
catch {
|
|
3283
|
-
|
|
3340
|
+
catch (err) {
|
|
3341
|
+
// #5118: the owner's out-of-set report error is not a scan failure to
|
|
3342
|
+
// degrade over — the bundle is never assembled over a refused report.
|
|
3343
|
+
if (err instanceof VerificationStatusError)
|
|
3344
|
+
throw err;
|
|
3345
|
+
/* otherwise intentionally empty */
|
|
3284
3346
|
}
|
|
3285
3347
|
for (const [num, name] of roadmapPhaseNames) {
|
|
3286
3348
|
const stripped = num.replace(/^0+/, '') || '0';
|
|
3287
3349
|
if (!seenPhaseNums.has(stripped)) {
|
|
3288
3350
|
const checkboxComplete = roadmapCheckboxStates.get(num) === true ||
|
|
3289
3351
|
roadmapCheckboxStates.get(stripped) === true;
|
|
3290
|
-
const completion = buildPhaseCompletionProjection(cwd, num, null, 0, 0, _slashRuntime);
|
|
3291
|
-
|
|
3352
|
+
const completion = buildPhaseCompletionProjection(cwd, num, null, 0, 0, _slashRuntime, resolvePhaseIdConvention(cwd));
|
|
3353
|
+
// #5060: this synthetic row has no phase directory at all — the
|
|
3354
|
+
// roadmap heading exists but no `seenPhaseNums` disk match was found —
|
|
3355
|
+
// so it is the ladder's own NOT_STARTED word, not a derived guess.
|
|
3356
|
+
const status = phase_status_cjs_1.PROGRESS_STATUS.NOT_STARTED;
|
|
3292
3357
|
const phaseInfo = {
|
|
3293
3358
|
number: num,
|
|
3294
3359
|
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
@@ -3325,7 +3390,7 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
3325
3390
|
{
|
|
3326
3391
|
const frontier = phases.find((p) => {
|
|
3327
3392
|
const st = p['status'];
|
|
3328
|
-
return (st ===
|
|
3393
|
+
return (st === phase_status_cjs_1.PROGRESS_STATUS.PENDING || st === phase_status_cjs_1.PROGRESS_STATUS.NOT_STARTED) && p['roadmap_complete'] !== true;
|
|
3329
3394
|
});
|
|
3330
3395
|
if (frontier)
|
|
3331
3396
|
nextPhase = frontier;
|
|
@@ -3362,8 +3427,8 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
3362
3427
|
milestone_name: milestone['name'] ?? null,
|
|
3363
3428
|
phases,
|
|
3364
3429
|
phase_count: phases.length,
|
|
3365
|
-
completed_count: phases.filter((p) => p['status'] ===
|
|
3366
|
-
in_progress_count: phases.filter((p) => [
|
|
3430
|
+
completed_count: phases.filter((p) => p['status'] === phase_status_cjs_1.PROGRESS_STATUS.COMPLETE).length,
|
|
3431
|
+
in_progress_count: phases.filter((p) => [phase_status_cjs_1.PROGRESS_STATUS.EXECUTED, phase_status_cjs_1.PROGRESS_STATUS.IN_PROGRESS].includes(p['status'])).length,
|
|
3367
3432
|
current_phase: currentPhase,
|
|
3368
3433
|
next_phase: nextPhase,
|
|
3369
3434
|
paused_at: pausedAt,
|
|
@@ -3955,10 +4020,11 @@ function buildSkillManifest(cwd, skillsDir = null) {
|
|
|
3955
4020
|
seenNamesInRoot.add(name);
|
|
3956
4021
|
const description = frontmatter['description'] || '';
|
|
3957
4022
|
const triggers = [];
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
4023
|
+
// TRIGGER lines are read from the body after the block `extractFrontmatter` read (the
|
|
4024
|
+
// one fence owner), so a `---` inside a frontmatter value cannot start the body early.
|
|
4025
|
+
const block = frontmatterBlock(content);
|
|
4026
|
+
if (block) {
|
|
4027
|
+
const triggerLines = block.rest.match(/^TRIGGER\s+when:\s*(.+)$/gmi);
|
|
3962
4028
|
if (triggerLines) {
|
|
3963
4029
|
for (const line of triggerLines) {
|
|
3964
4030
|
const m = line.match(/^TRIGGER\s+when:\s*(.+)$/i);
|