@opengsd/gsd-core 1.11.0 → 1.12.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/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +17 -9
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +0 -1
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +3 -1
- package/agents/gsd-plan-checker.md +15 -55
- package/agents/gsd-planner.md +6 -4
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.md +2 -2
- package/agents/gsd-roadmapper.md +15 -11
- package/agents/gsd-ui-checker.md +63 -4
- package/agents/gsd-ui-researcher.md +41 -3
- package/agents/gsd-verifier.md +1 -1
- package/bin/install.js +609 -134
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/quick.md +8 -4
- package/gsd-core/bin/gsd-tools.cjs +567 -51
- package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
- package/gsd-core/bin/lib/api-coverage.cjs +30 -9
- package/gsd-core/bin/lib/artifacts.cjs +2 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
- package/gsd-core/bin/lib/audit.cjs +163 -41
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +336 -95
- package/gsd-core/bin/lib/capability-state.cjs +18 -3
- package/gsd-core/bin/lib/capability-validator.cjs +205 -18
- package/gsd-core/bin/lib/check-command-router.cjs +145 -5
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +543 -44
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +118 -29
- package/gsd-core/bin/lib/config.cjs +92 -2
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +84 -7
- package/gsd-core/bin/lib/edge-probe.cjs +9 -1
- package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
- package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
- package/gsd-core/bin/lib/frontmatter.cjs +840 -305
- package/gsd-core/bin/lib/gap-checker.cjs +27 -3
- package/gsd-core/bin/lib/git-base-branch.cjs +174 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +6 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
- package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
- package/gsd-core/bin/lib/host-integration.cjs +39 -6
- package/gsd-core/bin/lib/init-command-router.cjs +118 -21
- package/gsd-core/bin/lib/init.cjs +120 -41
- package/gsd-core/bin/lib/install-engine.cjs +68 -3
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +33 -1
- package/gsd-core/bin/lib/install-profiles.cjs +78 -4
- package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +160 -15
- package/gsd-core/bin/lib/learnings.cjs +85 -14
- package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
- package/gsd-core/bin/lib/markdown-table.cjs +52 -4
- package/gsd-core/bin/lib/milestone.cjs +90 -5
- package/gsd-core/bin/lib/model-catalog.cjs +177 -19
- package/gsd-core/bin/lib/model-resolver.cjs +10 -28
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +70 -4
- package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
- package/gsd-core/bin/lib/phase-locator.cjs +138 -17
- package/gsd-core/bin/lib/phase.cjs +405 -84
- package/gsd-core/bin/lib/plan-document.cjs +263 -0
- package/gsd-core/bin/lib/plan-scan.cjs +13 -2
- package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -14
- package/gsd-core/bin/lib/planning-workspace.cjs +56 -0
- package/gsd-core/bin/lib/probe-core.cjs +4 -1
- package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
- package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
- package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +9 -9
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +79 -16
- package/gsd-core/bin/lib/roadmap.cjs +74 -19
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +96 -8
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +34 -1
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +287 -55
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +71 -8
- package/gsd-core/bin/lib/smart-entry.cjs +12 -22
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +47 -18
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +186 -0
- package/gsd-core/bin/lib/state-md-schema.cjs +221 -0
- package/gsd-core/bin/lib/state-transition.cjs +517 -101
- package/gsd-core/bin/lib/state.cjs +946 -163
- package/gsd-core/bin/lib/surface.cjs +10 -2
- package/gsd-core/bin/lib/task-command-router.cjs +111 -1
- package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
- package/gsd-core/bin/lib/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
- package/gsd-core/bin/lib/uat.cjs +1376 -125
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
- package/gsd-core/bin/lib/unusable-input.cjs +13 -0
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/vendor/README.md +43 -5
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/verification.cjs +14 -1
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify.cjs +95 -40
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +177 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
- package/gsd-core/bin/shared/exit-codes.json +8 -0
- package/gsd-core/bin/shared/exit-codes.sh +20 -0
- package/gsd-core/bin/shared/model-catalog.json +8 -1
- package/gsd-core/references/agent-contracts.md +3 -2
- package/gsd-core/references/api-coverage.md +24 -2
- package/gsd-core/references/autonomous-smart-discuss.md +3 -3
- package/gsd-core/references/checkpoints.md +37 -19
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/edge-probe.md +8 -0
- package/gsd-core/references/execute-mvp-tdd.md +1 -3
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-integration.md +5 -5
- package/gsd-core/references/git-planning-commit.md +3 -3
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +22 -0
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/nyquist-compliance.md +74 -0
- package/gsd-core/references/offer-next.md +3 -5
- package/gsd-core/references/phase-argument-parsing.md +3 -3
- package/gsd-core/references/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-revision.md +1 -1
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +37 -8
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +1 -3
- package/gsd-core/references/ui-brand.md +65 -21
- package/gsd-core/references/ui-consideration-probe.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +2 -2
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +11 -11
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/SECURITY.md +3 -3
- package/gsd-core/templates/UI-SPEC.md +25 -3
- package/gsd-core/templates/VALIDATION.md +3 -3
- package/gsd-core/templates/phase-prompt.md +3 -0
- package/gsd-core/templates/state.md +7 -0
- 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 +3 -3
- package/gsd-core/workflows/add-tests.md +3 -8
- package/gsd-core/workflows/add-todo.md +1 -1
- package/gsd-core/workflows/ai-integration-phase.md +4 -9
- package/gsd-core/workflows/audit-fix.md +12 -3
- package/gsd-core/workflows/audit-milestone.md +9 -9
- package/gsd-core/workflows/audit-uat.md +17 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +10 -26
- package/gsd-core/workflows/check-todos.md +1 -1
- package/gsd-core/workflows/cleanup.md +2 -2
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +1 -1
- package/gsd-core/workflows/code-review-fix.md +1 -1
- package/gsd-core/workflows/code-review.md +121 -40
- package/gsd-core/workflows/complete-milestone.md +15 -10
- package/gsd-core/workflows/debug.md +5 -3
- package/gsd-core/workflows/diagnose-issues.md +12 -6
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +3 -7
- package/gsd-core/workflows/discuss-phase/modes/text.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +2 -2
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +3 -6
- package/gsd-core/workflows/docs-update.md +5 -4
- package/gsd-core/workflows/edit-phase.md +1 -1
- package/gsd-core/workflows/eval-review.md +4 -9
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +113 -11
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
- 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 +22 -4
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase.md +38 -54
- package/gsd-core/workflows/execute-plan.md +17 -12
- package/gsd-core/workflows/explore.md +1 -1
- package/gsd-core/workflows/extract-learnings.md +1 -1
- package/gsd-core/workflows/fast.md +2 -2
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +5 -5
- package/gsd-core/workflows/health.md +3 -6
- package/gsd-core/workflows/import.md +14 -11
- package/gsd-core/workflows/inbox.md +4 -5
- package/gsd-core/workflows/ingest-docs.md +44 -11
- package/gsd-core/workflows/insert-phase.md +5 -5
- package/gsd-core/workflows/list-seeds.md +5 -3
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +12 -23
- package/gsd-core/workflows/map-codebase.md +1 -1
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +2 -2
- package/gsd-core/workflows/new-milestone.md +9 -21
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +12 -26
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +2 -2
- package/gsd-core/workflows/pause-work.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +3 -3
- package/gsd-core/workflows/plan-phase.md +121 -42
- package/gsd-core/workflows/plan-review-convergence.md +46 -9
- package/gsd-core/workflows/plant-seed.md +2 -2
- package/gsd-core/workflows/pr-branch.md +187 -51
- package/gsd-core/workflows/profile-user.md +16 -14
- package/gsd-core/workflows/progress.md +27 -12
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -3
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +2 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick.md +20 -29
- package/gsd-core/workflows/remove-phase.md +4 -4
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +8 -12
- package/gsd-core/workflows/review.md +193 -15
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +2 -2
- package/gsd-core/workflows/settings-advanced.md +7 -9
- package/gsd-core/workflows/settings-integrations.md +64 -31
- package/gsd-core/workflows/settings.md +3 -5
- package/gsd-core/workflows/ship.md +12 -6
- package/gsd-core/workflows/sketch-wrap-up.md +11 -17
- package/gsd-core/workflows/sketch.md +12 -18
- package/gsd-core/workflows/smart-entry.md +3 -5
- package/gsd-core/workflows/spec-phase.md +23 -1
- package/gsd-core/workflows/spike-wrap-up.md +7 -11
- package/gsd-core/workflows/spike.md +20 -31
- package/gsd-core/workflows/stats.md +2 -2
- package/gsd-core/workflows/sync-skills.md +1 -1
- package/gsd-core/workflows/thread.md +11 -7
- package/gsd-core/workflows/transition.md +5 -5
- package/gsd-core/workflows/ui-phase.md +10 -16
- package/gsd-core/workflows/ui-review.md +6 -10
- package/gsd-core/workflows/ultraplan-phase.md +5 -13
- package/gsd-core/workflows/undo.md +8 -16
- package/gsd-core/workflows/update.md +6 -10
- package/gsd-core/workflows/validate-phase.md +2 -2
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +57 -18
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +19 -10
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
- package/hooks/dist/gsd-cursor-session-start.js +2 -1
- package/hooks/dist/gsd-cursor-stop.js +2 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
- package/hooks/dist/gsd-graphify-update.sh +22 -18
- package/hooks/dist/gsd-node-runner.sh +76 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +16 -7
- package/hooks/dist/gsd-read-guard.js +16 -7
- package/hooks/dist/gsd-read-injection-scanner.js +17 -8
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +215 -26
- package/hooks/dist/gsd-validate-commit.sh +80 -6
- package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
- package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
- package/hooks/dist/gsd-workflow-guard.js +34 -16
- package/hooks/dist/gsd-worktree-path-guard.js +36 -21
- package/hooks/dist/gsd-write-guard.js +35 -25
- package/hooks/dist/lib/cli-exit.js +560 -0
- package/hooks/dist/lib/exit-code-registry.js +98 -0
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/managed-hooks-registry.cjs +3 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +19 -10
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +3 -1
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +28 -23
- package/hooks/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +76 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +16 -7
- package/hooks/gsd-read-guard.js +16 -7
- package/hooks/gsd-read-injection-scanner.js +17 -8
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +215 -26
- package/hooks/gsd-validate-commit.sh +80 -6
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +34 -16
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/managed-hooks-registry.cjs +3 -0
- package/package.json +12 -7
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +5 -0
- package/scripts/check-glossary-refs.cjs +77 -15
- package/scripts/check-mutation-score-ratchet.cjs +156 -0
- package/scripts/ci-check-job-near-cap.cjs +49 -0
- package/scripts/ci-pr-mergeability.cjs +262 -0
- package/scripts/ci-test-scope.cjs +45 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +396 -0
- package/scripts/gen-capability-registry.cjs +8 -6
- package/scripts/gen-exit-code-docs.cjs +318 -0
- package/scripts/gen-exit-code-registry.cjs +891 -0
- package/scripts/gen-features.cjs +836 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-loop-host-contract.cjs +134 -1
- package/scripts/gen-scripts-cli-exit.cjs +185 -0
- package/scripts/gen-state-md-docs.cjs +727 -0
- package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +32 -2
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +193 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +21 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-seam-enforcement.cjs +182 -0
- package/scripts/lint-slug-derivation-drift.cjs +921 -0
- package/scripts/lint-source-test-name-collision.cjs +241 -0
- package/scripts/lint-state-write-path-drift.cjs +337 -432
- package/scripts/lint-test-file-count.allowlist.json +122 -4
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +51 -64
- package/scripts/lint-vendored-deps.cjs +208 -35
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/prompt-injection-scan.sh +75 -14
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +22 -3
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -109
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/state-write-path-drift-baseline.json +0 -19
|
@@ -21,6 +21,51 @@ const cjsCommandRouterAdapter = require("./cjs-command-router-adapter.cjs");
|
|
|
21
21
|
const { routeCjsCommandFamily } = cjsCommandRouterAdapter;
|
|
22
22
|
const command_arg_projection_cjs_1 = require("./command-arg-projection.cjs");
|
|
23
23
|
// ─── Implementation ───────────────────────────────────────────────────────────
|
|
24
|
+
/**
|
|
25
|
+
* #3865: `--phase <N>` / `--phase=<N>` alias for the positional phase token
|
|
26
|
+
* the phase-taking init.* queries read at args[2]. Normalizes the pair into
|
|
27
|
+
* that caller-owned slot so (a) the handler's own args[2] read sees the
|
|
28
|
+
* value, and (b) the strict flag validation it runs sees exactly the argv
|
|
29
|
+
* the positional form produces (a bare `--phase 60` at index 2-3 would
|
|
30
|
+
* otherwise leave `60` as a rejected stray positional — or, pre-ADR-3473
|
|
31
|
+
* §8.4, silently answer `phase_found:false, plan_count:0` for a phase with
|
|
32
|
+
* plans on disk). A valueless `--phase` is a usage error naming the flag.
|
|
33
|
+
* Any other flag-shaped args[2] resolves to `undefined` — the commands'
|
|
34
|
+
* no-position-given input (execute-phase/plan-phase/verify-work usage-error
|
|
35
|
+
* "phase required"; the find-based queries answer phase_found:false; todos
|
|
36
|
+
* drops its area filter) — instead of passing the flag text down as a phase
|
|
37
|
+
* name.
|
|
38
|
+
*/
|
|
39
|
+
function normalizePhaseAlias(args, error) {
|
|
40
|
+
const tok = args[2];
|
|
41
|
+
if (tok === undefined)
|
|
42
|
+
return { args, phase: undefined };
|
|
43
|
+
if (tok === '--phase=') {
|
|
44
|
+
error('--phase requires a value: use --phase <N> (or the positional form <N>)');
|
|
45
|
+
// Fail-closed backstop, mirroring parseNamedArgsOrExit: the wired error()
|
|
46
|
+
// exits, but a returning fail() must not fall through to the splices below.
|
|
47
|
+
throw new Error('normalizePhaseAlias: error() returned instead of exiting');
|
|
48
|
+
}
|
|
49
|
+
if (tok.startsWith('--phase=')) {
|
|
50
|
+
const value = tok.slice('--phase='.length);
|
|
51
|
+
const out = args.slice();
|
|
52
|
+
out.splice(2, 1, value);
|
|
53
|
+
return { args: out, phase: value };
|
|
54
|
+
}
|
|
55
|
+
if (tok === '--phase') {
|
|
56
|
+
const next = args[3];
|
|
57
|
+
if (next === undefined || (0, command_arg_projection_cjs_1.isFlagToken)(next)) {
|
|
58
|
+
error('--phase requires a value: use --phase <N> (or the positional form <N>)');
|
|
59
|
+
throw new Error('normalizePhaseAlias: error() returned instead of exiting');
|
|
60
|
+
}
|
|
61
|
+
const out = args.slice();
|
|
62
|
+
out.splice(2, 2, next);
|
|
63
|
+
return { args: out, phase: next };
|
|
64
|
+
}
|
|
65
|
+
if ((0, command_arg_projection_cjs_1.isFlagToken)(tok))
|
|
66
|
+
return { args, phase: undefined };
|
|
67
|
+
return { args, phase: tok };
|
|
68
|
+
}
|
|
24
69
|
function routeInitCommand({ init, args, cwd, raw, error }) {
|
|
25
70
|
routeCjsCommandFamily({
|
|
26
71
|
args,
|
|
@@ -34,17 +79,37 @@ function routeInitCommand({ init, args, cwd, raw, error }) {
|
|
|
34
79
|
// `buildSectionManifestField`'s flags-Set builder (src/init.cts) is the
|
|
35
80
|
// single source of truth for flag ABSENCE and gates on value truthiness,
|
|
36
81
|
// so `namedArgs` is passed through here uncoerced.
|
|
82
|
+
//
|
|
83
|
+
// #3865: the phase-taking init.* queries accept `--phase <N>` /
|
|
84
|
+
// `--phase=<N>` as an alias for the positional form (matching
|
|
85
|
+
// `phase list-plans`, which accepts both). Pre-normalizing here moves
|
|
86
|
+
// the value into the caller-owned args[2] slot every handler below
|
|
87
|
+
// already reads, so the strict flag validation those handlers run sees
|
|
88
|
+
// exactly the argv the positional form produces. A valueless --phase is
|
|
89
|
+
// a usage error naming the flag — never a silent `phase_found:false`
|
|
90
|
+
// for a phase that has plans (the reported incident: 7 plans read as 0).
|
|
37
91
|
'execute-phase': () => {
|
|
38
|
-
const
|
|
39
|
-
|
|
92
|
+
const norm = normalizePhaseAlias(args, error);
|
|
93
|
+
// `wave` is an optionalValueFlags entry, not a booleanFlags entry:
|
|
94
|
+
// `--wave N` is a documented, shipped form (commands/gsd/execute-phase.md:4,48)
|
|
95
|
+
// whose value is consumed by the workflow layer
|
|
96
|
+
// (gsd-core/workflows/execute-phase.md:84), not by this CLI seam — see
|
|
97
|
+
// NamedArgSpec.optionalValueFlags in command-arg-projection.cts.
|
|
98
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { booleanFlags: ['validate', 'tdd'], optionalValueFlags: ['wave'], positionals: 3 }, error);
|
|
99
|
+
init.cmdInitExecutePhase(cwd, norm.phase, raw, {
|
|
40
100
|
validate: namedArgs['validate'],
|
|
41
101
|
tdd: namedArgs['tdd'],
|
|
42
102
|
wave: namedArgs['wave'],
|
|
43
103
|
});
|
|
44
104
|
},
|
|
45
105
|
'plan-phase': () => {
|
|
46
|
-
const
|
|
47
|
-
|
|
106
|
+
const norm = normalizePhaseAlias(args, error);
|
|
107
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, {
|
|
108
|
+
valueFlags: ['granularity', 'prd', 'ingest', 'research-phase'],
|
|
109
|
+
booleanFlags: ['validate', 'tdd', 'reviews', 'chunked'],
|
|
110
|
+
positionals: 3,
|
|
111
|
+
}, error);
|
|
112
|
+
init.cmdInitPlanPhase(cwd, norm.phase, raw, {
|
|
48
113
|
validate: namedArgs['validate'],
|
|
49
114
|
tdd: namedArgs['tdd'],
|
|
50
115
|
granularity: namedArgs['granularity'],
|
|
@@ -56,21 +121,25 @@ function routeInitCommand({ init, args, cwd, raw, error }) {
|
|
|
56
121
|
});
|
|
57
122
|
},
|
|
58
123
|
'new-project': () => {
|
|
59
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
124
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['auto'], positionals: 2 }, error);
|
|
60
125
|
init.cmdInitNewProject(cwd, raw, { auto: namedArgs['auto'] });
|
|
61
126
|
},
|
|
62
127
|
'new-milestone': () => {
|
|
63
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
128
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['reset-phase-numbers'], positionals: 2 }, error);
|
|
64
129
|
init.cmdInitNewMilestone(cwd, raw, {
|
|
65
130
|
'reset-phase-numbers': namedArgs['reset-phase-numbers'],
|
|
66
131
|
});
|
|
67
132
|
},
|
|
68
133
|
onboard: () => {
|
|
69
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
134
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['fast', 'text'], positionals: 2 }, error);
|
|
70
135
|
init.cmdInitOnboard(cwd, raw, { fast: namedArgs['fast'], text: namedArgs['text'] });
|
|
71
136
|
},
|
|
72
137
|
quick: () => {
|
|
73
|
-
|
|
138
|
+
// #3180 Decision 4a / L2 (ADR-3473 §8.4): `positionals: 'rest'` because
|
|
139
|
+
// everything after `init quick` is a free-text description — strict
|
|
140
|
+
// undeclared-flag rejection would break
|
|
141
|
+
// `/gsd-quick add a --dry-run option`, which works today.
|
|
142
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['discuss', 'research', 'validate', 'full'], positionals: 'rest' }, error);
|
|
74
143
|
// #2994: `args.slice(2)` is the free-text description, but section-manifest
|
|
75
144
|
// gating (buildSectionManifestField, src/init.cts) now requires forwarding
|
|
76
145
|
// --discuss/--research/--validate/--full alongside it — a plain `.join(' ')`
|
|
@@ -91,22 +160,47 @@ function routeInitCommand({ init, args, cwd, raw, error }) {
|
|
|
91
160
|
},
|
|
92
161
|
'ingest-docs': () => init.cmdInitIngestDocs(cwd, raw),
|
|
93
162
|
resume: () => init.cmdInitResume(cwd, raw),
|
|
94
|
-
|
|
95
|
-
|
|
163
|
+
// ADR-3473 §8.4 / #3358 gap: these handlers read args[2] positionally
|
|
164
|
+
// without ever calling parseNamedArgsOrExit, so an unrecognized flag or
|
|
165
|
+
// stray positional was silently dropped instead of rejected. No flags
|
|
166
|
+
// are declared because none are documented for these subcommands
|
|
167
|
+
// (docs/CLI-TOOLS.md); `--ws` seen in shipped workflows targets the
|
|
168
|
+
// separate `query init.verify-work` seam and is stripped before
|
|
169
|
+
// reaching `init verify-work` (gsd-core/workflows/verify-work.md:42-45).
|
|
170
|
+
'verify-work': () => {
|
|
171
|
+
const norm = normalizePhaseAlias(args, error);
|
|
172
|
+
(0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { positionals: 3 }, error);
|
|
173
|
+
init.cmdInitVerifyWork(cwd, norm.phase, raw);
|
|
174
|
+
},
|
|
175
|
+
'phase-op': () => {
|
|
176
|
+
const norm = normalizePhaseAlias(args, error);
|
|
177
|
+
(0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { positionals: 3 }, error);
|
|
178
|
+
init.cmdInitPhaseOp(cwd, norm.phase, raw);
|
|
179
|
+
},
|
|
96
180
|
'code-review': () => {
|
|
97
|
-
const
|
|
98
|
-
|
|
181
|
+
const norm = normalizePhaseAlias(args, error);
|
|
182
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { booleanFlags: ['fix'], positionals: 3 }, error);
|
|
183
|
+
init.cmdInitCodeReview(cwd, norm.phase, raw, { fix: namedArgs['fix'] });
|
|
184
|
+
},
|
|
185
|
+
review: () => {
|
|
186
|
+
const norm = normalizePhaseAlias(args, error);
|
|
187
|
+
(0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { positionals: 3 }, error);
|
|
188
|
+
init.cmdInitReview(cwd, norm.phase, raw, {});
|
|
99
189
|
},
|
|
100
|
-
review: () => init.cmdInitReview(cwd, args[2], raw, {}),
|
|
101
190
|
'discuss-phase-assumptions': () => {
|
|
102
|
-
const
|
|
103
|
-
|
|
191
|
+
const norm = normalizePhaseAlias(args, error);
|
|
192
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { booleanFlags: ['auto'], positionals: 3 }, error);
|
|
193
|
+
init.cmdInitDiscussPhaseAssumptions(cwd, norm.phase, raw, { auto: namedArgs['auto'] });
|
|
194
|
+
},
|
|
195
|
+
todos: () => {
|
|
196
|
+
const norm = normalizePhaseAlias(args, error);
|
|
197
|
+
(0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(norm.args, { positionals: 3 }, error);
|
|
198
|
+
init.cmdInitTodos(cwd, norm.phase, raw);
|
|
104
199
|
},
|
|
105
|
-
todos: () => init.cmdInitTodos(cwd, args[2], raw),
|
|
106
200
|
'milestone-op': () => init.cmdInitMilestoneOp(cwd, raw),
|
|
107
201
|
'map-codebase': () => init.cmdInitMapCodebase(cwd, raw),
|
|
108
202
|
progress: () => {
|
|
109
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
203
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['forensic'], positionals: 2 }, error);
|
|
110
204
|
init.cmdInitProgress(cwd, raw, { forensic: namedArgs['forensic'] });
|
|
111
205
|
},
|
|
112
206
|
// Keep manager on CJS for now so runtime-specific command rendering
|
|
@@ -114,7 +208,7 @@ function routeInitCommand({ init, args, cwd, raw, error }) {
|
|
|
114
208
|
manager: () => init.cmdInitManager(cwd, raw),
|
|
115
209
|
'complete-milestone': () => init.cmdInitCompleteMilestone(cwd, raw),
|
|
116
210
|
autonomous: () => {
|
|
117
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
211
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['converge', 'cross-ai'], positionals: 2 }, error);
|
|
118
212
|
init.cmdInitAutonomous(cwd, raw, {
|
|
119
213
|
converge: namedArgs['converge'],
|
|
120
214
|
'cross-ai': namedArgs['cross-ai'],
|
|
@@ -122,17 +216,20 @@ function routeInitCommand({ init, args, cwd, raw, error }) {
|
|
|
122
216
|
},
|
|
123
217
|
'docs-update': () => init.cmdInitDocsUpdate(cwd, raw, {}),
|
|
124
218
|
update: () => {
|
|
125
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
219
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['next', 'rc'], positionals: 2 }, error);
|
|
126
220
|
init.cmdInitUpdate(cwd, raw, { next: namedArgs['next'], rc: namedArgs['rc'] });
|
|
127
221
|
},
|
|
128
222
|
transition: () => init.cmdInitTransition(cwd, raw, {}),
|
|
129
223
|
debug: () => {
|
|
130
|
-
const namedArgs = (0, command_arg_projection_cjs_1.
|
|
224
|
+
const namedArgs = (0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { booleanFlags: ['diagnose'], positionals: 2 }, error);
|
|
131
225
|
init.cmdInitDebug(cwd, raw, { diagnose: namedArgs['diagnose'] });
|
|
132
226
|
},
|
|
133
227
|
'new-workspace': () => init.cmdInitNewWorkspace(cwd, raw),
|
|
134
228
|
'list-workspaces': () => init.cmdInitListWorkspaces(cwd, raw),
|
|
135
|
-
'remove-workspace': () =>
|
|
229
|
+
'remove-workspace': () => {
|
|
230
|
+
(0, command_arg_projection_cjs_1.parseNamedArgsOrExit)(args, { positionals: 3 }, error);
|
|
231
|
+
init.cmdInitRemoveWorkspace(cwd, args[2], raw);
|
|
232
|
+
},
|
|
136
233
|
},
|
|
137
234
|
});
|
|
138
235
|
}
|
|
@@ -74,10 +74,13 @@ const resolution_cjs_1 = require("./resolution.cjs");
|
|
|
74
74
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- onboard-projection.cjs is an export= CommonJS module
|
|
75
75
|
const onboardProjection = require("./onboard-projection.cjs");
|
|
76
76
|
const { REQUIRED_CODEBASE_MAP_FILES, buildOnboardProjection, hasCodeFilesInternal, hasPackageFileInternal, listCodebaseMapFiles, } = onboardProjection;
|
|
77
|
-
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- verify-command-grounding.cjs is an export= CommonJS module
|
|
78
|
+
const verifyCommandGrounding = require("./verify-command-grounding.cjs");
|
|
79
|
+
const { harvestPriorVerifyCommands } = verifyCommandGrounding;
|
|
80
|
+
const { output, error, ERROR_REASON, formatDiagnosticToken } = io;
|
|
78
81
|
const { loadConfig, loadConfigResolved } = configLoader;
|
|
79
82
|
const { resolveModelInternal, resolveGranularityInternal, assertValidGranularityOverride } = modelResolver;
|
|
80
|
-
const { findPhaseInternal, listMilestonePhaseDirs } = phaseLocator;
|
|
83
|
+
const { findPhaseInternal, listMilestonePhaseDirs, listAllPhaseDirs } = phaseLocator;
|
|
81
84
|
const { getRoadmapPhaseInternal, getMilestoneInfo, stripShippedMilestones, extractCurrentMilestone, } = roadmapParser;
|
|
82
85
|
const { pathExistsInternal, generateSlugInternal, toPosixPath } = coreUtils;
|
|
83
86
|
const { normalizePhaseName, matchPhaseDirs, stripProjectCodePrefix, PHASE_NUMBER_TOKEN_SOURCE, isForeignPrefixedPhaseQuery, isSentinelPhaseId, extractPhaseToken, scopeToPhase } = phaseId;
|
|
@@ -129,9 +132,12 @@ function guardedGetRoadmapPhase(cwd, phase, projectCode) {
|
|
|
129
132
|
// directory exists yet) identically at every synthetic-fallback call site
|
|
130
133
|
// below — factored out once so the slugification formula itself cannot drift.
|
|
131
134
|
function slugifyPhaseName(phaseName) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
136
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing it.
|
|
137
|
+
// `maxLen: null` preserves this site's pre-migration untruncated contract —
|
|
138
|
+
// the 60-char default would collapse two distinct >60-char phase names onto
|
|
139
|
+
// the same reported phase_slug.
|
|
140
|
+
return phaseName ? coreUtils.generateSlugInternal(phaseName, null) : null;
|
|
135
141
|
}
|
|
136
142
|
/**
|
|
137
143
|
* #2994 (review finding, DEFECT.GENERATIVE-FIX): shared archived/not-found
|
|
@@ -1028,8 +1034,21 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
1028
1034
|
result['patterns_path'] = toPosixPath(node_path_1.default.join(phaseDirFull, patternsFile));
|
|
1029
1035
|
}
|
|
1030
1036
|
}
|
|
1031
|
-
catch {
|
|
1032
|
-
|
|
1037
|
+
catch (err) {
|
|
1038
|
+
// #3885 (ADR-3473 §8.5): this branch means `phaseInfo['directory']` was
|
|
1039
|
+
// set (the phase was already resolved to an on-disk directory) yet
|
|
1040
|
+
// `readdirSync` still failed — ENOENT here would be a genuine race
|
|
1041
|
+
// (the directory vanished between resolution and this read) and stays
|
|
1042
|
+
// a silent degrade like the prior behavior; any other errno
|
|
1043
|
+
// (EACCES/EIO/...) is an unreadable-not-absent directory and must be
|
|
1044
|
+
// named, or every conditional field this block sets (context_path,
|
|
1045
|
+
// research_path, verification_path, uat_path, reviews_path,
|
|
1046
|
+
// patterns_path) silently reads as "none of these exist".
|
|
1047
|
+
const code = err?.code;
|
|
1048
|
+
if (code !== 'ENOENT') {
|
|
1049
|
+
result['context_read_error'] =
|
|
1050
|
+
`Could not read phase directory ${formatDiagnosticToken(phaseDirFull)}: ${formatDiagnosticToken(err?.message ?? String(err))}`;
|
|
1051
|
+
}
|
|
1033
1052
|
}
|
|
1034
1053
|
}
|
|
1035
1054
|
if (options['validate']) {
|
|
@@ -1056,6 +1075,29 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
1056
1075
|
}
|
|
1057
1076
|
// #2992 (Phase 6.1): additive, optional field — degrades to null, never throws.
|
|
1058
1077
|
result['section_manifest'] = buildSectionManifestField(cwd, phaseInfo, options, 'plan-phase');
|
|
1078
|
+
// #2401: prior-phase verify commands, surfaced UNGATED — additive field, never
|
|
1079
|
+
// conditioned on context_window. Before this, the planner only inherited
|
|
1080
|
+
// prior-phase verify-command context when context_window >= 500000, so at
|
|
1081
|
+
// lower context windows it re-invented (and mis-resolved) the command. The
|
|
1082
|
+
// harvest already degrades to `{commands: [], readError}` rather than
|
|
1083
|
+
// throwing; the try/catch is defense-in-depth so init never breaks on this.
|
|
1084
|
+
let priorVerifyCommands = [];
|
|
1085
|
+
try {
|
|
1086
|
+
// #2401 review fix: harvestPriorVerifyCommands accepts a phase-id token
|
|
1087
|
+
// (string) directly, so a decimal phase like '2.1' is no longer silently
|
|
1088
|
+
// dropped by `Number('2.1')` producing a value the old `number`-only
|
|
1089
|
+
// parameter mishandled for lettered/decimal tokens.
|
|
1090
|
+
if (phaseNumberPlan !== null) {
|
|
1091
|
+
priorVerifyCommands = harvestPriorVerifyCommands({
|
|
1092
|
+
planningDir: planningPaths(cwd).phases,
|
|
1093
|
+
beforePhase: phaseNumberPlan,
|
|
1094
|
+
}).commands;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
catch {
|
|
1098
|
+
priorVerifyCommands = [];
|
|
1099
|
+
}
|
|
1100
|
+
result['prior_verify_commands'] = priorVerifyCommands;
|
|
1059
1101
|
output(withProjectRoot(cwd, result), raw);
|
|
1060
1102
|
}
|
|
1061
1103
|
function cmdInitNewProject(cwd, raw, options = {}) {
|
|
@@ -1077,7 +1119,7 @@ function cmdInitNewProject(cwd, raw, options = {}) {
|
|
|
1077
1119
|
synthesizer_model: resolveModelInternal(cwd, 'gsd-research-synthesizer'),
|
|
1078
1120
|
roadmapper_model: resolveModelInternal(cwd, 'gsd-roadmapper'),
|
|
1079
1121
|
commit_docs: config.commit_docs,
|
|
1080
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1122
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1081
1123
|
has_codebase_map: hasCodebaseMap,
|
|
1082
1124
|
planning_exists: pathExistsInternal(cwd, '.planning'),
|
|
1083
1125
|
has_existing_code: hasCode,
|
|
@@ -1136,7 +1178,7 @@ function cmdInitNewMilestone(cwd, raw, options = {}) {
|
|
|
1136
1178
|
phase_archive_path: latestCompleted
|
|
1137
1179
|
? toPosixPath(node_path_1.default.join(planningRoot(cwd), 'milestones', `${latestCompleted.version}-phases`))
|
|
1138
1180
|
: null,
|
|
1139
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1181
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1140
1182
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1141
1183
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
1142
1184
|
project_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'PROJECT.md')),
|
|
@@ -1242,7 +1284,7 @@ function cmdInitQuick(cwd, description, raw, options = {}) {
|
|
|
1242
1284
|
function cmdInitIngestDocs(cwd, raw) {
|
|
1243
1285
|
const config = loadConfig(cwd);
|
|
1244
1286
|
const result = {
|
|
1245
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1287
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1246
1288
|
planning_exists: node_fs_1.default.existsSync(planningRoot(cwd)),
|
|
1247
1289
|
...getInitGitState(cwd),
|
|
1248
1290
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase. The
|
|
@@ -1283,7 +1325,7 @@ function cmdInitResume(cwd, raw) {
|
|
|
1283
1325
|
const result = {
|
|
1284
1326
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
1285
1327
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1286
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1328
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1287
1329
|
planning_exists: node_fs_1.default.existsSync(planningRoot(cwd)),
|
|
1288
1330
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
|
1289
1331
|
state_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
@@ -1600,9 +1642,11 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1600
1642
|
directory: null,
|
|
1601
1643
|
phase_number: roadmapPhase['phase_number'],
|
|
1602
1644
|
phase_name: phaseName,
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1645
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
1646
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing
|
|
1647
|
+
// it. `maxLen: null` preserves this site's pre-migration untruncated
|
|
1648
|
+
// contract.
|
|
1649
|
+
phase_slug: phaseName ? coreUtils.generateSlugInternal(phaseName, null) : null,
|
|
1606
1650
|
plans: [],
|
|
1607
1651
|
summaries: [],
|
|
1608
1652
|
incomplete_plans: [],
|
|
@@ -1621,9 +1665,11 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1621
1665
|
directory: null,
|
|
1622
1666
|
phase_number: roadmapPhase['phase_number'],
|
|
1623
1667
|
phase_name: phaseName,
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1668
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
1669
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing
|
|
1670
|
+
// it. `maxLen: null` preserves this site's pre-migration untruncated
|
|
1671
|
+
// contract.
|
|
1672
|
+
phase_slug: phaseName ? coreUtils.generateSlugInternal(phaseName, null) : null,
|
|
1627
1673
|
plans: [],
|
|
1628
1674
|
summaries: [],
|
|
1629
1675
|
incomplete_plans: [],
|
|
@@ -1738,8 +1784,18 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1738
1784
|
result['reviews_path'] = toPosixPath(node_path_1.default.join(phaseDirFull, reviewsFile));
|
|
1739
1785
|
}
|
|
1740
1786
|
}
|
|
1741
|
-
catch {
|
|
1742
|
-
|
|
1787
|
+
catch (err) {
|
|
1788
|
+
// #3885 (ADR-3473 §8.5): see the parallel site in cmdInitPlanPhase —
|
|
1789
|
+
// ENOENT here is a genuine race (directory vanished after resolution)
|
|
1790
|
+
// and stays a silent degrade; any other errno (EACCES/EIO/...) means
|
|
1791
|
+
// the directory exists but could not be read, and must be named rather
|
|
1792
|
+
// than silently reported the same as "none of context_path/
|
|
1793
|
+
// research_path/verification_path/uat_path/reviews_path exist".
|
|
1794
|
+
const code = err?.code;
|
|
1795
|
+
if (code !== 'ENOENT') {
|
|
1796
|
+
result['context_read_error'] =
|
|
1797
|
+
`Could not read phase directory ${formatDiagnosticToken(phaseDirFull)}: ${formatDiagnosticToken(err?.message ?? String(err))}`;
|
|
1798
|
+
}
|
|
1743
1799
|
}
|
|
1744
1800
|
}
|
|
1745
1801
|
output(withProjectRoot(cwd, result), raw);
|
|
@@ -1828,20 +1884,23 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
1828
1884
|
const m = tok.match(/^(\d+)([A-Z]?(?:\.\d+)*)$/);
|
|
1829
1885
|
return m ? String(parseInt(m[1], 10)) + m[2] : tok;
|
|
1830
1886
|
};
|
|
1887
|
+
// #3882 (ADR-3473 §8.2): this used to hand-roll a readdirSync over the
|
|
1888
|
+
// phases directory (a heading->directory LOOKUP INDEX, same role as
|
|
1889
|
+
// cmdRoadmapAnalyze's `_phaseDirNames` — `roadmapPhaseNumbers` above is
|
|
1890
|
+
// already scoped/sentinel-excluded, so this map must see the PHYSICAL set
|
|
1891
|
+
// to resolve each heading's phase number to its actual directory name;
|
|
1892
|
+
// scoping it again would look up inside an already-scoped set for no
|
|
1893
|
+
// benefit). Routed through the named "physical set, sentinels included"
|
|
1894
|
+
// axis instead: every `num` looked up below came from `roadmapPhaseNumbers`
|
|
1895
|
+
// (sentinels already excluded there), so a sentinel entry surviving in
|
|
1896
|
+
// this map is never read — inclusion is output-invariant, this only
|
|
1897
|
+
// removes the re-derivation.
|
|
1831
1898
|
const diskPhaseDirs = new Map();
|
|
1832
|
-
|
|
1833
|
-
const
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
const m = stripProjectCodePrefix(e.name).match(new RegExp(`^(${PHASE_NUMBER_TOKEN_SOURCE})`));
|
|
1838
|
-
if (!m)
|
|
1839
|
-
continue;
|
|
1840
|
-
diskPhaseDirs.set(canonicalizePhase(m[1]), e.name);
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
catch {
|
|
1844
|
-
/* intentionally empty */
|
|
1899
|
+
for (const name of listAllPhaseDirs(phasesDir, { includeSentinels: true }).value) {
|
|
1900
|
+
const m = stripProjectCodePrefix(name).match(new RegExp(`^(${PHASE_NUMBER_TOKEN_SOURCE})`));
|
|
1901
|
+
if (!m)
|
|
1902
|
+
continue;
|
|
1903
|
+
diskPhaseDirs.set(canonicalizePhase(m[1]), name);
|
|
1845
1904
|
}
|
|
1846
1905
|
if (roadmapPhaseNumbers.length > 0) {
|
|
1847
1906
|
phaseCount = roadmapPhaseNumbers.length;
|
|
@@ -1908,7 +1967,7 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
1908
1967
|
all_phases_complete: phaseCount > 0 && phaseCount === completedPhases,
|
|
1909
1968
|
archived_milestones: archivedMilestones,
|
|
1910
1969
|
archive_count: archivedMilestones.length,
|
|
1911
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1970
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1912
1971
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1913
1972
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
1914
1973
|
archive_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningRoot(cwd), 'archive')),
|
|
@@ -1918,7 +1977,12 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
1918
1977
|
}
|
|
1919
1978
|
function cmdInitMapCodebase(cwd, raw) {
|
|
1920
1979
|
const config = loadConfig(cwd);
|
|
1921
|
-
|
|
1980
|
+
// #3964: scoped like the payload's own codebase_dir/codebase_dir_exists
|
|
1981
|
+
// below (and verify.cts's codebase drift check) — has_maps/existing_maps
|
|
1982
|
+
// reading the flat root made the same payload claim a scoped codebase dir
|
|
1983
|
+
// exists while reporting zero maps, so map-codebase's Refresh/Skip gate
|
|
1984
|
+
// always forced a re-map under GSD_PROJECT.
|
|
1985
|
+
const codebaseDir = node_path_1.default.join(planningDir(cwd), 'codebase');
|
|
1922
1986
|
let existingMaps = [];
|
|
1923
1987
|
try {
|
|
1924
1988
|
existingMaps = node_fs_1.default.readdirSync(codebaseDir).filter((f) => f.endsWith('.md'));
|
|
@@ -1935,11 +1999,14 @@ function cmdInitMapCodebase(cwd, raw) {
|
|
|
1935
1999
|
date: clock_cjs_1.realClock.localToday(),
|
|
1936
2000
|
timestamp: clock_cjs_1.realClock.nowIso(),
|
|
1937
2001
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
|
1938
|
-
|
|
2002
|
+
// #3964: scoped like verify.cts's codebase drift check (planningDir, not
|
|
2003
|
+
// the flat planningRoot) so the two surfaces cannot disagree under
|
|
2004
|
+
// GSD_PROJECT.
|
|
2005
|
+
codebase_dir: toPosixPath(node_path_1.default.join(planningDir(cwd), 'codebase')),
|
|
1939
2006
|
existing_maps: existingMaps,
|
|
1940
2007
|
has_maps: existingMaps.length > 0,
|
|
1941
2008
|
planning_exists: pathExistsInternal(cwd, '.planning'),
|
|
1942
|
-
codebase_dir_exists: pathExistsInternal(cwd, '
|
|
2009
|
+
codebase_dir_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'codebase')))),
|
|
1943
2010
|
};
|
|
1944
2011
|
output(withProjectRoot(cwd, result), raw);
|
|
1945
2012
|
}
|
|
@@ -2156,7 +2223,13 @@ function cmdInitManager(cwd, raw) {
|
|
|
2156
2223
|
}
|
|
2157
2224
|
let waitingSignal = null;
|
|
2158
2225
|
try {
|
|
2159
|
-
|
|
2226
|
+
// #3964: mirror cmdSignalWaiting's write locations exactly — `.gsd/`
|
|
2227
|
+
// first when it exists, else the project-aware planning dir — so the
|
|
2228
|
+
// signal is read from the project (and location) it is written to.
|
|
2229
|
+
const gsdWaiting = node_path_1.default.join(cwd, '.gsd', 'WAITING.json');
|
|
2230
|
+
const waitingPath = node_fs_1.default.existsSync(node_path_1.default.join(cwd, '.gsd'))
|
|
2231
|
+
? gsdWaiting
|
|
2232
|
+
: node_path_1.default.join(planningDir(cwd), 'WAITING.json');
|
|
2160
2233
|
const waitingRaw = (0, shell_command_projection_cjs_1.platformReadSync)(waitingPath);
|
|
2161
2234
|
if (waitingRaw !== null) {
|
|
2162
2235
|
waitingSignal = JSON.parse(waitingRaw);
|
|
@@ -2261,7 +2334,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2261
2334
|
recommended_actions: filteredActions,
|
|
2262
2335
|
waiting_signal: waitingSignal,
|
|
2263
2336
|
all_complete: completedCount === nonBacklogPhases.length && nonBacklogPhases.length > 0,
|
|
2264
|
-
project_exists: pathExistsInternal(cwd, '
|
|
2337
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
2265
2338
|
roadmap_exists: true,
|
|
2266
2339
|
state_exists: true,
|
|
2267
2340
|
manager_flags: managerFlags,
|
|
@@ -2617,7 +2690,11 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
2617
2690
|
const status = 'not_started';
|
|
2618
2691
|
const phaseInfo = {
|
|
2619
2692
|
number: num,
|
|
2620
|
-
|
|
2693
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
2694
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing
|
|
2695
|
+
// it. `maxLen: null` preserves this site's pre-migration untruncated
|
|
2696
|
+
// contract.
|
|
2697
|
+
name: coreUtils.generateSlugInternal(name, null) ?? '',
|
|
2621
2698
|
directory: null,
|
|
2622
2699
|
status,
|
|
2623
2700
|
plan_count: 0,
|
|
@@ -2691,7 +2768,7 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
2691
2768
|
paused_at: pausedAt,
|
|
2692
2769
|
has_work_in_progress: !!currentPhase,
|
|
2693
2770
|
phase_mvp_mode: phaseMvpMode,
|
|
2694
|
-
project_exists: pathExistsInternal(cwd, '
|
|
2771
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
2695
2772
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
2696
2773
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
2697
2774
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
|
@@ -3326,7 +3403,9 @@ function cmdSkillManifest(cwd, args, raw) {
|
|
|
3326
3403
|
const skillsDir = skillsDirIdx >= 0 && args[skillsDirIdx + 1] ? args[skillsDirIdx + 1] : null;
|
|
3327
3404
|
const manifest = buildSkillManifest(cwd, skillsDir);
|
|
3328
3405
|
if (args.includes('--write')) {
|
|
3329
|
-
|
|
3406
|
+
// #3964: write beside the project's own artifacts (planningDir is
|
|
3407
|
+
// project- and workstream-aware), not the flat root.
|
|
3408
|
+
const planDir = planningDir(cwd);
|
|
3330
3409
|
if (node_fs_1.default.existsSync(planDir)) {
|
|
3331
3410
|
const manifestPath = node_path_1.default.join(planDir, 'skill-manifest.json');
|
|
3332
3411
|
(0, shell_command_projection_cjs_1.platformWriteSync)(manifestPath, JSON.stringify(manifest, null, 2));
|