@opengsd/gsd-core 1.11.0 → 1.13.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 +12 -0
- 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 +78 -42
- 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 +91 -112
- package/agents/gsd-planner.md +20 -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 +82 -7
- package/agents/gsd-ui-researcher.md +70 -3
- package/agents/gsd-verifier.md +24 -2
- package/bin/install.js +847 -200
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/phase.md +1 -1
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/quick.md +8 -4
- package/commands/gsd/surface.md +18 -8
- package/gsd-core/bin/gsd-tools.cjs +761 -100
- 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-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +785 -144
- package/gsd-core/bin/lib/capability-state.cjs +25 -4
- package/gsd-core/bin/lib/capability-validator.cjs +321 -18
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +229 -6
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- 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-aliases.cjs +16 -0
- 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 +877 -54
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +121 -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 +118 -14
- package/gsd-core/bin/lib/decisions.cjs +213 -1
- package/gsd-core/bin/lib/edge-probe.cjs +23 -2
- 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/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +975 -326
- package/gsd-core/bin/lib/gap-checker.cjs +41 -8
- package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
- 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 +96 -11
- package/gsd-core/bin/lib/init-command-router.cjs +132 -21
- package/gsd-core/bin/lib/init.cjs +252 -56
- package/gsd-core/bin/lib/install-engine.cjs +252 -15
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
- package/gsd-core/bin/lib/install-profiles.cjs +100 -18
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -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 +195 -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/loop-resolver.cjs +14 -8
- package/gsd-core/bin/lib/markdown-table.cjs +175 -4
- package/gsd-core/bin/lib/milestone.cjs +112 -7
- 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-command-router.cjs +13 -6
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +321 -13
- 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 +1175 -115
- package/gsd-core/bin/lib/plan-document.cjs +273 -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 +165 -34
- package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
- 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/quick-batch-command-router.cjs +285 -0
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
- package/gsd-core/bin/lib/quick-batch.cjs +840 -0
- 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 +62 -14
- package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
- package/gsd-core/bin/lib/roadmap.cjs +248 -64
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
- 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 +75 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -31
- 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 +216 -5
- package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
- package/gsd-core/bin/lib/state-transition.cjs +850 -145
- package/gsd-core/bin/lib/state.cjs +1629 -287
- package/gsd-core/bin/lib/surface.cjs +33 -10
- 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/tdd-red-evidence.cjs +133 -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 +2542 -387
- 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/update-context.cjs +6 -2
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +230 -12
- 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-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -13
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +441 -56
- package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
- 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 +185 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -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/bin/verify-reapply-patches.cjs +70 -3
- package/gsd-core/references/agent-contracts.md +6 -5
- 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 +17 -5
- package/gsd-core/references/execute-mvp-tdd.md +18 -18
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- 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/mvp-concepts.md +2 -2
- 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/plan-checker-examples.md +41 -0
- package/gsd-core/references/planner-antipatterns.md +25 -0
- package/gsd-core/references/planner-chunked.md +5 -1
- package/gsd-core/references/planner-coupling.md +42 -0
- 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-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +76 -3
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +39 -9
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +15 -12
- 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/verifier-evidence-gate.md +160 -0
- 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 +7 -0
- package/gsd-core/templates/state.md +7 -0
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +3 -1
- package/gsd-core/workflows/add-phase.md +5 -3
- package/gsd-core/workflows/add-tests.md +4 -9
- package/gsd-core/workflows/add-todo.md +2 -2
- package/gsd-core/workflows/ai-integration-phase.md +5 -10
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +14 -3
- package/gsd-core/workflows/audit-milestone.md +11 -9
- package/gsd-core/workflows/audit-uat.md +19 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +12 -26
- package/gsd-core/workflows/check-todos.md +2 -2
- package/gsd-core/workflows/cleanup.md +3 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
- package/gsd-core/workflows/code-review-fix.md +3 -1
- package/gsd-core/workflows/code-review.md +192 -69
- package/gsd-core/workflows/complete-milestone.md +28 -14
- package/gsd-core/workflows/debug.md +6 -4
- package/gsd-core/workflows/diagnose-issues.md +17 -7
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
- package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
- package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
- package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
- package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +46 -19
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +3 -1
- package/gsd-core/workflows/eval-review.md +5 -10
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -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 +29 -5
- 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 +4 -2
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +68 -66
- package/gsd-core/workflows/execute-plan.md +25 -20
- package/gsd-core/workflows/explore.md +3 -1
- package/gsd-core/workflows/extract-learnings.md +3 -1
- package/gsd-core/workflows/fast.md +8 -2
- package/gsd-core/workflows/forensics.md +3 -1
- package/gsd-core/workflows/graduation.md +6 -6
- package/gsd-core/workflows/health.md +4 -7
- package/gsd-core/workflows/help/modes/brief.md +2 -0
- package/gsd-core/workflows/help/modes/default.md +2 -0
- package/gsd-core/workflows/help/modes/full.md +12 -0
- package/gsd-core/workflows/help/modes/topic.md +2 -0
- package/gsd-core/workflows/help.md +2 -0
- package/gsd-core/workflows/import.md +17 -14
- package/gsd-core/workflows/inbox.md +5 -6
- package/gsd-core/workflows/ingest-docs.md +45 -12
- package/gsd-core/workflows/insert-phase.md +7 -5
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +7 -3
- package/gsd-core/workflows/list-workspaces.md +3 -1
- package/gsd-core/workflows/manager.md +15 -26
- package/gsd-core/workflows/map-codebase.md +3 -1
- package/gsd-core/workflows/milestone-summary.md +3 -1
- package/gsd-core/workflows/mvp-phase.md +3 -3
- package/gsd-core/workflows/new-milestone.md +10 -22
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +17 -29
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +4 -2
- package/gsd-core/workflows/node-repair.md +2 -0
- package/gsd-core/workflows/note.md +2 -0
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +20 -5
- 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 +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
- package/gsd-core/workflows/plan-phase.md +251 -54
- package/gsd-core/workflows/plan-review-convergence.md +148 -19
- package/gsd-core/workflows/plant-seed.md +3 -3
- package/gsd-core/workflows/pr-branch.md +195 -51
- package/gsd-core/workflows/profile-user.md +17 -15
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +52 -15
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
- package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
- package/gsd-core/workflows/quick-batch.md +203 -0
- package/gsd-core/workflows/quick.md +33 -32
- package/gsd-core/workflows/reapply-patches.md +2 -0
- package/gsd-core/workflows/remove-phase.md +6 -4
- package/gsd-core/workflows/remove-workspace.md +3 -3
- package/gsd-core/workflows/resume-project.md +14 -14
- package/gsd-core/workflows/review.md +404 -21
- package/gsd-core/workflows/scan.md +3 -1
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +9 -9
- package/gsd-core/workflows/settings-integrations.md +66 -32
- package/gsd-core/workflows/settings.md +4 -6
- package/gsd-core/workflows/ship.md +22 -16
- package/gsd-core/workflows/sketch-wrap-up.md +13 -17
- package/gsd-core/workflows/sketch.md +13 -19
- package/gsd-core/workflows/smart-entry.md +4 -6
- package/gsd-core/workflows/spec-phase.md +31 -4
- package/gsd-core/workflows/spike-wrap-up.md +9 -11
- package/gsd-core/workflows/spike.md +21 -32
- package/gsd-core/workflows/stats.md +4 -2
- package/gsd-core/workflows/sync-skills.md +13 -5
- package/gsd-core/workflows/thread.md +13 -7
- package/gsd-core/workflows/transition.md +7 -5
- package/gsd-core/workflows/ui-phase.md +36 -21
- package/gsd-core/workflows/ui-review.md +7 -11
- package/gsd-core/workflows/ultraplan-phase.md +7 -13
- package/gsd-core/workflows/undo.md +9 -17
- package/gsd-core/workflows/update.md +47 -48
- package/gsd-core/workflows/validate-phase.md +3 -3
- 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 +106 -21
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +302 -22
- 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 +77 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +46 -12
- package/hooks/dist/gsd-read-guard.js +18 -7
- package/hooks/dist/gsd-read-injection-scanner.js +22 -13
- package/hooks/dist/gsd-secret-read-guard.js +1079 -0
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +222 -29
- package/hooks/dist/gsd-validate-commit.sh +523 -12
- 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 +36 -17
- 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-cmd.js +210 -1
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/managed-hooks-registry.cjs +4 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +302 -22
- 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 +77 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +46 -12
- package/hooks/gsd-read-guard.js +18 -7
- package/hooks/gsd-read-injection-scanner.js +22 -13
- package/hooks/gsd-secret-read-guard.js +1079 -0
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +222 -29
- package/hooks/gsd-validate-commit.sh +523 -12
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +36 -17
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/hooks.json +6 -0
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/managed-hooks-registry.cjs +4 -0
- package/package.json +14 -9
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +12 -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 +52 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +406 -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 +189 -4
- 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/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
- 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-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -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 +45 -14
- package/scripts/lint-phase-id-drift.cjs +133 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-response-language-coverage.cjs +524 -0
- 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 +124 -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/lint-workflow-shellcheck-baseline.json +1027 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +83 -14
- package/scripts/require-issue-link-policy.cjs +16 -1
- 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-execute-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- 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
|
@@ -34,6 +34,9 @@ const phaseId = require("./phase-id.cjs");
|
|
|
34
34
|
const worktreeSafety = require("./worktree-safety.cjs");
|
|
35
35
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- planning-workspace.cjs is an export= CommonJS module
|
|
36
36
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const planningScopeMod = require("./planning-scope.cjs");
|
|
39
|
+
const { SCOPE } = planningScopeMod;
|
|
37
40
|
const secrets_cjs_1 = require("./secrets.cjs");
|
|
38
41
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- plan-scan.cjs is an export= CommonJS module
|
|
39
42
|
const scanPhasePlans = require("./plan-scan.cjs");
|
|
@@ -74,13 +77,16 @@ const resolution_cjs_1 = require("./resolution.cjs");
|
|
|
74
77
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- onboard-projection.cjs is an export= CommonJS module
|
|
75
78
|
const onboardProjection = require("./onboard-projection.cjs");
|
|
76
79
|
const { REQUIRED_CODEBASE_MAP_FILES, buildOnboardProjection, hasCodeFilesInternal, hasPackageFileInternal, listCodebaseMapFiles, } = onboardProjection;
|
|
77
|
-
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- verify-command-grounding.cjs is an export= CommonJS module
|
|
81
|
+
const verifyCommandGrounding = require("./verify-command-grounding.cjs");
|
|
82
|
+
const { harvestPriorVerifyCommands } = verifyCommandGrounding;
|
|
83
|
+
const { output, error, ERROR_REASON, formatDiagnosticToken } = io;
|
|
78
84
|
const { loadConfig, loadConfigResolved } = configLoader;
|
|
79
85
|
const { resolveModelInternal, resolveGranularityInternal, assertValidGranularityOverride } = modelResolver;
|
|
80
|
-
const { findPhaseInternal, listMilestonePhaseDirs } = phaseLocator;
|
|
86
|
+
const { findPhaseInternal, listMilestonePhaseDirs, listAllPhaseDirs } = phaseLocator;
|
|
81
87
|
const { getRoadmapPhaseInternal, getMilestoneInfo, stripShippedMilestones, extractCurrentMilestone, } = roadmapParser;
|
|
82
88
|
const { pathExistsInternal, generateSlugInternal, toPosixPath } = coreUtils;
|
|
83
|
-
const { normalizePhaseName, matchPhaseDirs, stripProjectCodePrefix, PHASE_NUMBER_TOKEN_SOURCE, isForeignPrefixedPhaseQuery, isSentinelPhaseId, extractPhaseToken, scopeToPhase } = phaseId;
|
|
89
|
+
const { comparePhaseNum, normalizePhaseName, matchPhaseDirs, stripProjectCodePrefix, PHASE_NUMBER_TOKEN_SOURCE, isForeignPrefixedPhaseQuery, isSentinelPhaseId, extractPhaseToken, scopeToPhase } = phaseId;
|
|
84
90
|
const { pruneOrphanedWorktrees } = worktreeSafety;
|
|
85
91
|
const { planningPaths, planningDir, planningRoot, listAvailableWorkstreams, peekActiveWorkstream, diagnoseUnresolvedActiveWorkstream, describeUnresolvedWorkstreamReason, findContextMdIn, } = planningWorkspace;
|
|
86
92
|
const { determinePhaseStatus } = commandsMod;
|
|
@@ -129,9 +135,12 @@ function guardedGetRoadmapPhase(cwd, phase, projectCode) {
|
|
|
129
135
|
// directory exists yet) identically at every synthetic-fallback call site
|
|
130
136
|
// below — factored out once so the slugification formula itself cannot drift.
|
|
131
137
|
function slugifyPhaseName(phaseName) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
139
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing it.
|
|
140
|
+
// `maxLen: null` preserves this site's pre-migration untruncated contract —
|
|
141
|
+
// the 60-char default would collapse two distinct >60-char phase names onto
|
|
142
|
+
// the same reported phase_slug.
|
|
143
|
+
return phaseName ? coreUtils.generateSlugInternal(phaseName, null) : null;
|
|
135
144
|
}
|
|
136
145
|
/**
|
|
137
146
|
* #2994 (review finding, DEFECT.GENERATIVE-FIX): shared archived/not-found
|
|
@@ -765,7 +774,6 @@ function cmdInitExecutePhase(cwd, phase, raw, options = {}) {
|
|
|
765
774
|
? reqMatch[1].replace(/[\[\]]/g, '').split(',').map((s) => s.trim()).filter(Boolean).join(', ')
|
|
766
775
|
: null;
|
|
767
776
|
const phase_req_ids = reqExtracted && reqExtracted !== 'TBD' ? reqExtracted : null;
|
|
768
|
-
const wf = (config.workflow ?? {});
|
|
769
777
|
// #3188: these paths are null when the file is absent, matching the contract
|
|
770
778
|
// the conditional sibling fields (context_path, patterns_path, ...) already
|
|
771
779
|
// honour and that ultraplan-phase.md / execute-phase.md gate on. Hoisted so
|
|
@@ -776,7 +784,7 @@ function cmdInitExecutePhase(cwd, phase, raw, options = {}) {
|
|
|
776
784
|
const result = {
|
|
777
785
|
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
|
778
786
|
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
|
779
|
-
tdd_mode: options['tdd'] || Boolean(
|
|
787
|
+
tdd_mode: options['tdd'] || Boolean(config.tdd_mode) || false,
|
|
780
788
|
commit_docs: config.commit_docs,
|
|
781
789
|
sub_repos: config.sub_repos,
|
|
782
790
|
parallelization: config.parallelization,
|
|
@@ -918,7 +926,6 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
918
926
|
const granularityOverride = options['granularity'];
|
|
919
927
|
assertValidGranularityOverride(granularityOverride, error);
|
|
920
928
|
const granularity = resolveGranularityInternal(cwd, 'planning', granularityOverride || undefined);
|
|
921
|
-
const wf = (config.workflow ?? {});
|
|
922
929
|
// #3188: see cmdInitExecutePhase — null when absent, parity with the
|
|
923
930
|
// conditional sibling fields in this same result object.
|
|
924
931
|
const statePath = node_path_1.default.join(planningDir(cwd), 'STATE.md');
|
|
@@ -928,11 +935,11 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
928
935
|
researcher_model: resolveModelInternal(cwd, 'gsd-phase-researcher'),
|
|
929
936
|
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
|
930
937
|
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
|
931
|
-
tdd_mode: options['tdd'] || Boolean(
|
|
938
|
+
tdd_mode: options['tdd'] || Boolean(config.tdd_mode) || false,
|
|
932
939
|
granularity,
|
|
933
|
-
research_enabled:
|
|
940
|
+
research_enabled: config.research,
|
|
934
941
|
plan_checker_enabled: config.plan_checker,
|
|
935
|
-
nyquist_validation_enabled:
|
|
942
|
+
nyquist_validation_enabled: config.nyquist_validation,
|
|
936
943
|
commit_docs: config.commit_docs,
|
|
937
944
|
text_mode: config.text_mode,
|
|
938
945
|
auto_advance: !!(config.auto_advance),
|
|
@@ -954,6 +961,11 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
954
961
|
: 'Pending',
|
|
955
962
|
has_research: phaseInfo?.['has_research'] || false,
|
|
956
963
|
has_context: phaseInfo?.['has_context'] || false,
|
|
964
|
+
// #4014 (epic #3473 B4-unreadable): additive scope signal adjacent to
|
|
965
|
+
// has_context — SCOPE.COMPLETE by default (no phase directory to read is
|
|
966
|
+
// a genuine, not-unreadable answer), overwritten below to whatever
|
|
967
|
+
// findContextMdIn(phaseDirFull) reports once a directory is known.
|
|
968
|
+
context_scope: SCOPE.COMPLETE,
|
|
957
969
|
has_reviews: phaseInfo?.['has_reviews'] || false,
|
|
958
970
|
has_plans: (phaseInfo?.['plans']?.length || 0) > 0,
|
|
959
971
|
plan_count: phaseInfo?.['plans']?.length || 0,
|
|
@@ -968,6 +980,13 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
968
980
|
};
|
|
969
981
|
if (phaseInfo?.['directory']) {
|
|
970
982
|
const phaseDirFull = node_path_1.default.join(cwd, phaseInfo['directory']);
|
|
983
|
+
// #4014 (epic #3473 B4-unreadable): findContextMdIn's directory-string
|
|
984
|
+
// form never throws, so this can record the real scope BEFORE the
|
|
985
|
+
// pre-existing `fs.readdirSync(phaseDirFull)` immediately below
|
|
986
|
+
// (unchanged) throws on the same unreadable directory and is caught
|
|
987
|
+
// exactly as before — additive only, the failure control-flow for
|
|
988
|
+
// context_path/research_path/etc. is untouched.
|
|
989
|
+
result['context_scope'] = findContextMdIn(phaseDirFull).scope;
|
|
971
990
|
try {
|
|
972
991
|
const files = node_fs_1.default.readdirSync(phaseDirFull);
|
|
973
992
|
const phaseDirName = node_path_1.default.basename(phaseDirFull);
|
|
@@ -1028,8 +1047,21 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
1028
1047
|
result['patterns_path'] = toPosixPath(node_path_1.default.join(phaseDirFull, patternsFile));
|
|
1029
1048
|
}
|
|
1030
1049
|
}
|
|
1031
|
-
catch {
|
|
1032
|
-
|
|
1050
|
+
catch (err) {
|
|
1051
|
+
// #3885 (ADR-3473 §8.5): this branch means `phaseInfo['directory']` was
|
|
1052
|
+
// set (the phase was already resolved to an on-disk directory) yet
|
|
1053
|
+
// `readdirSync` still failed — ENOENT here would be a genuine race
|
|
1054
|
+
// (the directory vanished between resolution and this read) and stays
|
|
1055
|
+
// a silent degrade like the prior behavior; any other errno
|
|
1056
|
+
// (EACCES/EIO/...) is an unreadable-not-absent directory and must be
|
|
1057
|
+
// named, or every conditional field this block sets (context_path,
|
|
1058
|
+
// research_path, verification_path, uat_path, reviews_path,
|
|
1059
|
+
// patterns_path) silently reads as "none of these exist".
|
|
1060
|
+
const code = err?.code;
|
|
1061
|
+
if (code !== 'ENOENT') {
|
|
1062
|
+
result['context_read_error'] =
|
|
1063
|
+
`Could not read phase directory ${formatDiagnosticToken(phaseDirFull)}: ${formatDiagnosticToken(err?.message ?? String(err))}`;
|
|
1064
|
+
}
|
|
1033
1065
|
}
|
|
1034
1066
|
}
|
|
1035
1067
|
if (options['validate']) {
|
|
@@ -1056,8 +1088,59 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
|
|
1056
1088
|
}
|
|
1057
1089
|
// #2992 (Phase 6.1): additive, optional field — degrades to null, never throws.
|
|
1058
1090
|
result['section_manifest'] = buildSectionManifestField(cwd, phaseInfo, options, 'plan-phase');
|
|
1091
|
+
// #2401: prior-phase verify commands, surfaced UNGATED — additive field, never
|
|
1092
|
+
// conditioned on context_window. Before this, the planner only inherited
|
|
1093
|
+
// prior-phase verify-command context when context_window >= 500000, so at
|
|
1094
|
+
// lower context windows it re-invented (and mis-resolved) the command. The
|
|
1095
|
+
// harvest already degrades to `{commands: [], readError}` rather than
|
|
1096
|
+
// throwing; the try/catch is defense-in-depth so init never breaks on this.
|
|
1097
|
+
let priorVerifyCommands = [];
|
|
1098
|
+
try {
|
|
1099
|
+
// #2401 review fix: harvestPriorVerifyCommands accepts a phase-id token
|
|
1100
|
+
// (string) directly, so a decimal phase like '2.1' is no longer silently
|
|
1101
|
+
// dropped by `Number('2.1')` producing a value the old `number`-only
|
|
1102
|
+
// parameter mishandled for lettered/decimal tokens.
|
|
1103
|
+
if (phaseNumberPlan !== null) {
|
|
1104
|
+
priorVerifyCommands = harvestPriorVerifyCommands({
|
|
1105
|
+
planningDir: planningPaths(cwd).phases,
|
|
1106
|
+
beforePhase: phaseNumberPlan,
|
|
1107
|
+
}).commands;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
catch {
|
|
1111
|
+
priorVerifyCommands = [];
|
|
1112
|
+
}
|
|
1113
|
+
result['prior_verify_commands'] = priorVerifyCommands;
|
|
1059
1114
|
output(withProjectRoot(cwd, result), raw);
|
|
1060
1115
|
}
|
|
1116
|
+
// #4040: shared partial-init discriminator for the init.progress / init.resume /
|
|
1117
|
+
// init.new-project payloads. A bootstrap interrupted before the core quartet
|
|
1118
|
+
// (PROJECT.md / REQUIREMENTS.md / ROADMAP.md / STATE.md) all landed is a
|
|
1119
|
+
// DISTINCT routing state from "new project" and from "between milestones";
|
|
1120
|
+
// pre-#4040 the payloads could not express it, so progress.md mis-routed it to
|
|
1121
|
+
// Route F and resume-project.md offered STATE.md reconstruction.
|
|
1122
|
+
//
|
|
1123
|
+
// Negative-space guard: `milestone.complete` archives ROADMAP.md (and
|
|
1124
|
+
// REQUIREMENTS.md) but always leaves MILESTONES.md behind — so MILESTONES.md
|
|
1125
|
+
// present proves missing core files are archival (between-milestones), never an
|
|
1126
|
+
// unfinished bootstrap. REQUIREMENTS.md is written by new-project BEFORE
|
|
1127
|
+
// ROADMAP/STATE, so its absence also proves init never finished.
|
|
1128
|
+
function buildInitCompletenessFields(cwd) {
|
|
1129
|
+
const dir = planningDir(cwd);
|
|
1130
|
+
const planningExists = node_fs_1.default.existsSync(dir);
|
|
1131
|
+
const requirementsExists = node_fs_1.default.existsSync(node_path_1.default.join(dir, 'REQUIREMENTS.md'));
|
|
1132
|
+
const milestonesExists = node_fs_1.default.existsSync(node_path_1.default.join(dir, 'MILESTONES.md'));
|
|
1133
|
+
const coreComplete = node_fs_1.default.existsSync(node_path_1.default.join(dir, 'PROJECT.md')) &&
|
|
1134
|
+
requirementsExists &&
|
|
1135
|
+
node_fs_1.default.existsSync(node_path_1.default.join(dir, 'ROADMAP.md')) &&
|
|
1136
|
+
node_fs_1.default.existsSync(node_path_1.default.join(dir, 'STATE.md'));
|
|
1137
|
+
return {
|
|
1138
|
+
planning_exists: planningExists,
|
|
1139
|
+
requirements_exists: requirementsExists,
|
|
1140
|
+
milestones_exists: milestonesExists,
|
|
1141
|
+
init_incomplete: planningExists && !coreComplete && !milestonesExists,
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1061
1144
|
function cmdInitNewProject(cwd, raw, options = {}) {
|
|
1062
1145
|
const config = loadConfig(cwd);
|
|
1063
1146
|
const homedir = node_os_1.default.homedir();
|
|
@@ -1077,7 +1160,12 @@ function cmdInitNewProject(cwd, raw, options = {}) {
|
|
|
1077
1160
|
synthesizer_model: resolveModelInternal(cwd, 'gsd-research-synthesizer'),
|
|
1078
1161
|
roadmapper_model: resolveModelInternal(cwd, 'gsd-roadmapper'),
|
|
1079
1162
|
commit_docs: config.commit_docs,
|
|
1080
|
-
|
|
1163
|
+
// #4040: partial-init discriminator (see buildInitCompletenessFields).
|
|
1164
|
+
// Spread BEFORE this literal's own planning_exists so the existing
|
|
1165
|
+
// root-scoped (`pathExistsInternal(cwd, '.planning')`) semantics for that
|
|
1166
|
+
// one key stay byte-identical for existing consumers.
|
|
1167
|
+
...buildInitCompletenessFields(cwd),
|
|
1168
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1081
1169
|
has_codebase_map: hasCodebaseMap,
|
|
1082
1170
|
planning_exists: pathExistsInternal(cwd, '.planning'),
|
|
1083
1171
|
has_existing_code: hasCode,
|
|
@@ -1116,13 +1204,12 @@ function cmdInitNewMilestone(cwd, raw, options = {}) {
|
|
|
1116
1204
|
// owns — routed through it instead of a local readdirSync + hand-rolled
|
|
1117
1205
|
// window filter (which also never excluded sentinels, unlike the owner).
|
|
1118
1206
|
const phaseDirCount = listMilestonePhaseDirs(phasesDir, { cwd }).value.length;
|
|
1119
|
-
const wf = (config.workflow ?? {});
|
|
1120
1207
|
const result = {
|
|
1121
1208
|
researcher_model: resolveModelInternal(cwd, 'gsd-project-researcher'),
|
|
1122
1209
|
synthesizer_model: resolveModelInternal(cwd, 'gsd-research-synthesizer'),
|
|
1123
1210
|
roadmapper_model: resolveModelInternal(cwd, 'gsd-roadmapper'),
|
|
1124
1211
|
commit_docs: config.commit_docs,
|
|
1125
|
-
research_enabled:
|
|
1212
|
+
research_enabled: config.research,
|
|
1126
1213
|
// #3216 review Finding 2: `?? null` so an unresolved milestone still emits
|
|
1127
1214
|
// the key with an explicit `null` rather than letting JSON.stringify drop
|
|
1128
1215
|
// it — an omitted key reaches the prompt layer's `{current_milestone}`
|
|
@@ -1136,7 +1223,7 @@ function cmdInitNewMilestone(cwd, raw, options = {}) {
|
|
|
1136
1223
|
phase_archive_path: latestCompleted
|
|
1137
1224
|
? toPosixPath(node_path_1.default.join(planningRoot(cwd), 'milestones', `${latestCompleted.version}-phases`))
|
|
1138
1225
|
: null,
|
|
1139
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1226
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1140
1227
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1141
1228
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
1142
1229
|
project_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'PROJECT.md')),
|
|
@@ -1204,6 +1291,10 @@ function cmdInitQuick(cwd, description, raw, options = {}) {
|
|
|
1204
1291
|
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
|
1205
1292
|
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
|
1206
1293
|
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
|
1294
|
+
// #3936: Step 4.75 dispatches gsd-phase-researcher; resolve its own tier
|
|
1295
|
+
// (parity with cmdInitPlanPhase) so the research spawn stops pinning
|
|
1296
|
+
// planner_model.
|
|
1297
|
+
researcher_model: resolveModelInternal(cwd, 'gsd-phase-researcher'),
|
|
1207
1298
|
// #2072: the quick review step spawns gsd-code-reviewer; resolve its own model
|
|
1208
1299
|
// so model_overrides / models.verification apply (was reusing executor_model).
|
|
1209
1300
|
reviewer_model: resolveModelInternal(cwd, 'gsd-code-reviewer'),
|
|
@@ -1239,10 +1330,49 @@ function cmdInitQuick(cwd, description, raw, options = {}) {
|
|
|
1239
1330
|
result['section_manifest'] = buildSectionManifestField(cwd, null, sectionManifestOptions, 'quick');
|
|
1240
1331
|
output(withProjectRoot(cwd, result), raw);
|
|
1241
1332
|
}
|
|
1333
|
+
/**
|
|
1334
|
+
* `init.quick-batch` (#3676, Phase 4 of epic #3344, ADR-1239 "Quick-batch
|
|
1335
|
+
* binding"). Unlike `cmdInitQuick`, this init bundle does NOT allocate a
|
|
1336
|
+
* quick id / slug / task directory itself — batch-level id allocation and
|
|
1337
|
+
* `BATCH.json` creation is the job of the `quick-batch create` CLI verb
|
|
1338
|
+
* (`src/quick-batch-command-router.cts`, wrapping `createBatch` in
|
|
1339
|
+
* `src/quick-batch.cts`). This bundle supplies the per-role model profiles,
|
|
1340
|
+
* `commit_docs`, the roadmap/planning existence checks `quick-batch.md`'s
|
|
1341
|
+
* ROADMAP.md gate needs (same check `cmdInitQuick` runs), the `.planning/quick`
|
|
1342
|
+
* directory path, and the `section_manifest` field gating the optional
|
|
1343
|
+
* `--research`/`--validate` step fragments — the same `flag:--research`/
|
|
1344
|
+
* `flag:--validate` atoms `quick`'s own section manifest already uses
|
|
1345
|
+
* (`WHEN_VOCABULARY` is workflow-agnostic; no new atom is needed). `--discuss`/
|
|
1346
|
+
* `--full` are rejected by `quick-batch-dispatch.cts`'s `parseQuickBatchArgs`
|
|
1347
|
+
* before this init bundle is ever reached, so no `discuss`/`full` flag key is
|
|
1348
|
+
* accepted here (unlike `cmdInitQuick`, which still supports both).
|
|
1349
|
+
*/
|
|
1350
|
+
function cmdInitQuickBatch(cwd, raw, options = {}) {
|
|
1351
|
+
const config = loadConfig(cwd);
|
|
1352
|
+
const result = {
|
|
1353
|
+
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
|
1354
|
+
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
|
1355
|
+
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
|
1356
|
+
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
|
1357
|
+
researcher_model: resolveModelInternal(cwd, 'gsd-phase-researcher'),
|
|
1358
|
+
reviewer_model: resolveModelInternal(cwd, 'gsd-code-reviewer'),
|
|
1359
|
+
commit_docs: config.commit_docs,
|
|
1360
|
+
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase; a
|
|
1361
|
+
// per-item task_dir is re-derived by the workflow itself (quick_id +
|
|
1362
|
+
// generate-slug over that item's description), never allocated here.
|
|
1363
|
+
quick_dir: toPosixPath(node_path_1.default.join(planningDir(cwd), 'quick')),
|
|
1364
|
+
quick_batches_dir: toPosixPath(node_path_1.default.join(planningDir(cwd), 'quick-batches')),
|
|
1365
|
+
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1366
|
+
planning_exists: node_fs_1.default.existsSync(planningRoot(cwd)),
|
|
1367
|
+
};
|
|
1368
|
+
// #2992 (Phase 6.1): additive, optional field — degrades to null, never throws.
|
|
1369
|
+
result['section_manifest'] = buildSectionManifestField(cwd, null, options, 'quick-batch');
|
|
1370
|
+
output(withProjectRoot(cwd, result), raw);
|
|
1371
|
+
}
|
|
1242
1372
|
function cmdInitIngestDocs(cwd, raw) {
|
|
1243
1373
|
const config = loadConfig(cwd);
|
|
1244
1374
|
const result = {
|
|
1245
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1375
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1246
1376
|
planning_exists: node_fs_1.default.existsSync(planningRoot(cwd)),
|
|
1247
1377
|
...getInitGitState(cwd),
|
|
1248
1378
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase. The
|
|
@@ -1263,12 +1393,11 @@ function cmdInitIngestDocs(cwd, raw) {
|
|
|
1263
1393
|
}
|
|
1264
1394
|
function cmdInitOnboard(cwd, raw, options = {}) {
|
|
1265
1395
|
const config = loadConfig(cwd);
|
|
1266
|
-
const workflowConfig = (config.workflow ?? {});
|
|
1267
1396
|
const result = {
|
|
1268
1397
|
...buildOnboardProjection(cwd, {
|
|
1269
1398
|
commitDocs: !!config.commit_docs,
|
|
1270
1399
|
fast: options['fast'] === true,
|
|
1271
|
-
textMode: options['text'] === true || !!config.text_mode
|
|
1400
|
+
textMode: options['text'] === true || !!config.text_mode,
|
|
1272
1401
|
}),
|
|
1273
1402
|
...getInitGitState(cwd),
|
|
1274
1403
|
};
|
|
@@ -1281,9 +1410,14 @@ function cmdInitResume(cwd, raw) {
|
|
|
1281
1410
|
if (agentIdRaw !== null)
|
|
1282
1411
|
interruptedAgentId = agentIdRaw.trim();
|
|
1283
1412
|
const result = {
|
|
1413
|
+
// #4040: partial-init discriminator (see buildInitCompletenessFields).
|
|
1414
|
+
// Spread FIRST so this literal's own root-scoped planning_exists
|
|
1415
|
+
// (planningRoot) keeps its existing semantics; init_incomplete itself
|
|
1416
|
+
// keys off the artifact dir (planningDir) where the core docs live.
|
|
1417
|
+
...buildInitCompletenessFields(cwd),
|
|
1284
1418
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
1285
1419
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1286
|
-
project_exists: pathExistsInternal(cwd, '
|
|
1420
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1287
1421
|
planning_exists: node_fs_1.default.existsSync(planningRoot(cwd)),
|
|
1288
1422
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
|
1289
1423
|
state_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
@@ -1600,9 +1734,11 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1600
1734
|
directory: null,
|
|
1601
1735
|
phase_number: roadmapPhase['phase_number'],
|
|
1602
1736
|
phase_name: phaseName,
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1737
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
1738
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing
|
|
1739
|
+
// it. `maxLen: null` preserves this site's pre-migration untruncated
|
|
1740
|
+
// contract.
|
|
1741
|
+
phase_slug: phaseName ? coreUtils.generateSlugInternal(phaseName, null) : null,
|
|
1606
1742
|
plans: [],
|
|
1607
1743
|
summaries: [],
|
|
1608
1744
|
incomplete_plans: [],
|
|
@@ -1621,9 +1757,11 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1621
1757
|
directory: null,
|
|
1622
1758
|
phase_number: roadmapPhase['phase_number'],
|
|
1623
1759
|
phase_name: phaseName,
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1760
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
1761
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing
|
|
1762
|
+
// it. `maxLen: null` preserves this site's pre-migration untruncated
|
|
1763
|
+
// contract.
|
|
1764
|
+
phase_slug: phaseName ? coreUtils.generateSlugInternal(phaseName, null) : null,
|
|
1627
1765
|
plans: [],
|
|
1628
1766
|
summaries: [],
|
|
1629
1767
|
incomplete_plans: [],
|
|
@@ -1674,6 +1812,9 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1674
1812
|
padded_phase: phaseNumber ? normalizePhaseName(phaseNumber) : null,
|
|
1675
1813
|
has_research: phaseInfo?.['has_research'] || false,
|
|
1676
1814
|
has_context: phaseInfo?.['has_context'] || false,
|
|
1815
|
+
// #4014 (epic #3473 B4-unreadable): see the parallel field in
|
|
1816
|
+
// cmdInitPlanPhase — additive scope signal adjacent to has_context.
|
|
1817
|
+
context_scope: SCOPE.COMPLETE,
|
|
1677
1818
|
has_plans: (phaseInfo?.['plans']?.length || 0) > 0,
|
|
1678
1819
|
has_verification: phaseInfo?.['has_verification'] || false,
|
|
1679
1820
|
has_reviews: phaseInfo?.['has_reviews'] || false,
|
|
@@ -1688,6 +1829,9 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1688
1829
|
};
|
|
1689
1830
|
if (phaseInfo?.['directory']) {
|
|
1690
1831
|
const phaseDirFull = node_path_1.default.join(cwd, phaseInfo['directory']);
|
|
1832
|
+
// #4014 (epic #3473 B4-unreadable): see the parallel site in
|
|
1833
|
+
// cmdInitPlanPhase — additive only, failure control-flow below unchanged.
|
|
1834
|
+
result['context_scope'] = findContextMdIn(phaseDirFull).scope;
|
|
1691
1835
|
try {
|
|
1692
1836
|
const files = node_fs_1.default.readdirSync(phaseDirFull);
|
|
1693
1837
|
const phaseDirName = node_path_1.default.basename(phaseDirFull);
|
|
@@ -1738,8 +1882,18 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
1738
1882
|
result['reviews_path'] = toPosixPath(node_path_1.default.join(phaseDirFull, reviewsFile));
|
|
1739
1883
|
}
|
|
1740
1884
|
}
|
|
1741
|
-
catch {
|
|
1742
|
-
|
|
1885
|
+
catch (err) {
|
|
1886
|
+
// #3885 (ADR-3473 §8.5): see the parallel site in cmdInitPlanPhase —
|
|
1887
|
+
// ENOENT here is a genuine race (directory vanished after resolution)
|
|
1888
|
+
// and stays a silent degrade; any other errno (EACCES/EIO/...) means
|
|
1889
|
+
// the directory exists but could not be read, and must be named rather
|
|
1890
|
+
// than silently reported the same as "none of context_path/
|
|
1891
|
+
// research_path/verification_path/uat_path/reviews_path exist".
|
|
1892
|
+
const code = err?.code;
|
|
1893
|
+
if (code !== 'ENOENT') {
|
|
1894
|
+
result['context_read_error'] =
|
|
1895
|
+
`Could not read phase directory ${formatDiagnosticToken(phaseDirFull)}: ${formatDiagnosticToken(err?.message ?? String(err))}`;
|
|
1896
|
+
}
|
|
1743
1897
|
}
|
|
1744
1898
|
}
|
|
1745
1899
|
output(withProjectRoot(cwd, result), raw);
|
|
@@ -1828,20 +1982,23 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
1828
1982
|
const m = tok.match(/^(\d+)([A-Z]?(?:\.\d+)*)$/);
|
|
1829
1983
|
return m ? String(parseInt(m[1], 10)) + m[2] : tok;
|
|
1830
1984
|
};
|
|
1985
|
+
// #3882 (ADR-3473 §8.2): this used to hand-roll a readdirSync over the
|
|
1986
|
+
// phases directory (a heading->directory LOOKUP INDEX, same role as
|
|
1987
|
+
// cmdRoadmapAnalyze's `_phaseDirNames` — `roadmapPhaseNumbers` above is
|
|
1988
|
+
// already scoped/sentinel-excluded, so this map must see the PHYSICAL set
|
|
1989
|
+
// to resolve each heading's phase number to its actual directory name;
|
|
1990
|
+
// scoping it again would look up inside an already-scoped set for no
|
|
1991
|
+
// benefit). Routed through the named "physical set, sentinels included"
|
|
1992
|
+
// axis instead: every `num` looked up below came from `roadmapPhaseNumbers`
|
|
1993
|
+
// (sentinels already excluded there), so a sentinel entry surviving in
|
|
1994
|
+
// this map is never read — inclusion is output-invariant, this only
|
|
1995
|
+
// removes the re-derivation.
|
|
1831
1996
|
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 */
|
|
1997
|
+
for (const name of listAllPhaseDirs(phasesDir, { includeSentinels: true }).value) {
|
|
1998
|
+
const m = stripProjectCodePrefix(name).match(new RegExp(`^(${PHASE_NUMBER_TOKEN_SOURCE})`));
|
|
1999
|
+
if (!m)
|
|
2000
|
+
continue;
|
|
2001
|
+
diskPhaseDirs.set(canonicalizePhase(m[1]), name);
|
|
1845
2002
|
}
|
|
1846
2003
|
if (roadmapPhaseNumbers.length > 0) {
|
|
1847
2004
|
phaseCount = roadmapPhaseNumbers.length;
|
|
@@ -1908,7 +2065,7 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
1908
2065
|
all_phases_complete: phaseCount > 0 && phaseCount === completedPhases,
|
|
1909
2066
|
archived_milestones: archivedMilestones,
|
|
1910
2067
|
archive_count: archivedMilestones.length,
|
|
1911
|
-
project_exists: pathExistsInternal(cwd, '
|
|
2068
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
1912
2069
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
1913
2070
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
1914
2071
|
archive_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningRoot(cwd), 'archive')),
|
|
@@ -1918,7 +2075,12 @@ function cmdInitMilestoneOp(cwd, raw) {
|
|
|
1918
2075
|
}
|
|
1919
2076
|
function cmdInitMapCodebase(cwd, raw) {
|
|
1920
2077
|
const config = loadConfig(cwd);
|
|
1921
|
-
|
|
2078
|
+
// #3964: scoped like the payload's own codebase_dir/codebase_dir_exists
|
|
2079
|
+
// below (and verify.cts's codebase drift check) — has_maps/existing_maps
|
|
2080
|
+
// reading the flat root made the same payload claim a scoped codebase dir
|
|
2081
|
+
// exists while reporting zero maps, so map-codebase's Refresh/Skip gate
|
|
2082
|
+
// always forced a re-map under GSD_PROJECT.
|
|
2083
|
+
const codebaseDir = node_path_1.default.join(planningDir(cwd), 'codebase');
|
|
1922
2084
|
let existingMaps = [];
|
|
1923
2085
|
try {
|
|
1924
2086
|
existingMaps = node_fs_1.default.readdirSync(codebaseDir).filter((f) => f.endsWith('.md'));
|
|
@@ -1935,11 +2097,14 @@ function cmdInitMapCodebase(cwd, raw) {
|
|
|
1935
2097
|
date: clock_cjs_1.realClock.localToday(),
|
|
1936
2098
|
timestamp: clock_cjs_1.realClock.nowIso(),
|
|
1937
2099
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
|
1938
|
-
|
|
2100
|
+
// #3964: scoped like verify.cts's codebase drift check (planningDir, not
|
|
2101
|
+
// the flat planningRoot) so the two surfaces cannot disagree under
|
|
2102
|
+
// GSD_PROJECT.
|
|
2103
|
+
codebase_dir: toPosixPath(node_path_1.default.join(planningDir(cwd), 'codebase')),
|
|
1939
2104
|
existing_maps: existingMaps,
|
|
1940
2105
|
has_maps: existingMaps.length > 0,
|
|
1941
2106
|
planning_exists: pathExistsInternal(cwd, '.planning'),
|
|
1942
|
-
codebase_dir_exists: pathExistsInternal(cwd, '
|
|
2107
|
+
codebase_dir_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'codebase')))),
|
|
1943
2108
|
};
|
|
1944
2109
|
output(withProjectRoot(cwd, result), raw);
|
|
1945
2110
|
}
|
|
@@ -1995,6 +2160,9 @@ function cmdInitManager(cwd, raw) {
|
|
|
1995
2160
|
let hasResearch = false;
|
|
1996
2161
|
let lastActivity = null;
|
|
1997
2162
|
let isActive = false;
|
|
2163
|
+
// #4014 (epic #3473 B4-unreadable): default COMPLETE — no directory at
|
|
2164
|
+
// all (dirMatch not found) is a genuine, not-unreadable answer.
|
|
2165
|
+
let contextScope = SCOPE.COMPLETE;
|
|
1998
2166
|
let completion = buildPhaseCompletionProjection(cwd, phaseNum, null, planCount, summaryCount, _slashRuntime);
|
|
1999
2167
|
try {
|
|
2000
2168
|
// #3185 (ADR-3180 Decision 2) moved this lookup off the
|
|
@@ -2005,6 +2173,17 @@ function cmdInitManager(cwd, raw) {
|
|
|
2005
2173
|
if (dirMatch) {
|
|
2006
2174
|
const fullDir = node_path_1.default.join(phasesDir, dirMatch);
|
|
2007
2175
|
const phaseDirRel = toPosixPath(node_path_1.default.relative(cwd, fullDir));
|
|
2176
|
+
// #4014 (epic #3473 B4-unreadable): this whole block used to swallow
|
|
2177
|
+
// ANY readdirSync failure below into the bare `catch { /* empty */ }`
|
|
2178
|
+
// at the bottom — an unreadable phase directory reported the exact
|
|
2179
|
+
// same `has_context: false` / `disk_status: 'no_directory'` as a
|
|
2180
|
+
// directory that never existed. findContextMdIn's directory-string
|
|
2181
|
+
// form never throws, so it can record the real scope (COMPLETE vs
|
|
2182
|
+
// UNREADABLE) here, BEFORE the pre-existing `fs.readdirSync(fullDir)`
|
|
2183
|
+
// immediately below (unchanged) throws on the exact same unreadable
|
|
2184
|
+
// directory and is caught exactly as before — this line is additive
|
|
2185
|
+
// only, the failure control-flow is untouched.
|
|
2186
|
+
contextScope = findContextMdIn(fullDir).scope;
|
|
2008
2187
|
const phaseFiles = node_fs_1.default.readdirSync(fullDir);
|
|
2009
2188
|
planCount = listPhasePlanFiles(fullDir).length;
|
|
2010
2189
|
summaryCount = listPhaseSummaryFiles(fullDir).length;
|
|
@@ -2079,6 +2258,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2079
2258
|
...completion,
|
|
2080
2259
|
last_activity: lastActivity,
|
|
2081
2260
|
is_active: isActive,
|
|
2261
|
+
context_scope: contextScope,
|
|
2082
2262
|
});
|
|
2083
2263
|
}
|
|
2084
2264
|
const MAX_NAME_WIDTH = 20;
|
|
@@ -2156,7 +2336,13 @@ function cmdInitManager(cwd, raw) {
|
|
|
2156
2336
|
}
|
|
2157
2337
|
let waitingSignal = null;
|
|
2158
2338
|
try {
|
|
2159
|
-
|
|
2339
|
+
// #3964: mirror cmdSignalWaiting's write locations exactly — `.gsd/`
|
|
2340
|
+
// first when it exists, else the project-aware planning dir — so the
|
|
2341
|
+
// signal is read from the project (and location) it is written to.
|
|
2342
|
+
const gsdWaiting = node_path_1.default.join(cwd, '.gsd', 'WAITING.json');
|
|
2343
|
+
const waitingPath = node_fs_1.default.existsSync(node_path_1.default.join(cwd, '.gsd'))
|
|
2344
|
+
? gsdWaiting
|
|
2345
|
+
: node_path_1.default.join(planningDir(cwd), 'WAITING.json');
|
|
2160
2346
|
const waitingRaw = (0, shell_command_projection_cjs_1.platformReadSync)(waitingPath);
|
|
2161
2347
|
if (waitingRaw !== null) {
|
|
2162
2348
|
waitingSignal = JSON.parse(waitingRaw);
|
|
@@ -2261,7 +2447,7 @@ function cmdInitManager(cwd, raw) {
|
|
|
2261
2447
|
recommended_actions: filteredActions,
|
|
2262
2448
|
waiting_signal: waitingSignal,
|
|
2263
2449
|
all_complete: completedCount === nonBacklogPhases.length && nonBacklogPhases.length > 0,
|
|
2264
|
-
project_exists: pathExistsInternal(cwd, '
|
|
2450
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
2265
2451
|
roadmap_exists: true,
|
|
2266
2452
|
state_exists: true,
|
|
2267
2453
|
manager_flags: managerFlags,
|
|
@@ -2449,7 +2635,7 @@ function cmdInitTransition(cwd, raw, options = {}) {
|
|
|
2449
2635
|
* location has one source instead of two kept in sync by hand.
|
|
2450
2636
|
* - `debugger_model` — `resolveModelInternal`, which IS what `query
|
|
2451
2637
|
* resolve-model --pick model` returns (`cmdResolveModel`, src/commands.cts).
|
|
2452
|
-
* - `tdd_mode` — the `Boolean(
|
|
2638
|
+
* - `tdd_mode` — the `Boolean(config.tdd_mode)` idiom `cmdInitExecutePhase` and
|
|
2453
2639
|
* `cmdInitPlanPhase` already use. `/gsd:debug` has no `--tdd` flag, so the
|
|
2454
2640
|
* sibling handlers' `options['tdd'] ||` disjunct is deliberately omitted
|
|
2455
2641
|
* rather than carried as a phantom.
|
|
@@ -2467,7 +2653,6 @@ function cmdInitTransition(cwd, raw, options = {}) {
|
|
|
2467
2653
|
*/
|
|
2468
2654
|
function cmdInitDebug(cwd, raw, options = {}) {
|
|
2469
2655
|
const config = loadConfig(cwd);
|
|
2470
|
-
const wf = (config.workflow ?? {});
|
|
2471
2656
|
const result = {
|
|
2472
2657
|
commit_docs: config.commit_docs,
|
|
2473
2658
|
// #2376: absolute — debug.md builds `debug_file_path` as
|
|
@@ -2475,7 +2660,7 @@ function cmdInitDebug(cwd, raw, options = {}) {
|
|
|
2475
2660
|
// own cwd may differ from the orchestrator's.
|
|
2476
2661
|
debug_dir: toPosixPath(planningPaths(cwd).debug),
|
|
2477
2662
|
debugger_model: resolveModelInternal(cwd, 'gsd-debugger'),
|
|
2478
|
-
tdd_mode: Boolean(
|
|
2663
|
+
tdd_mode: Boolean(config.tdd_mode),
|
|
2479
2664
|
diagnose: options['diagnose'] === true,
|
|
2480
2665
|
};
|
|
2481
2666
|
// Additive, optional field — degrades to null while `debug` has no key in
|
|
@@ -2617,7 +2802,11 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
2617
2802
|
const status = 'not_started';
|
|
2618
2803
|
const phaseInfo = {
|
|
2619
2804
|
number: num,
|
|
2620
|
-
|
|
2805
|
+
// #3883 (ADR-3473 §8.3): delegate to the canonical slug formula
|
|
2806
|
+
// (generateSlugInternal, core-utils.cts) rather than re-implementing
|
|
2807
|
+
// it. `maxLen: null` preserves this site's pre-migration untruncated
|
|
2808
|
+
// contract.
|
|
2809
|
+
name: coreUtils.generateSlugInternal(name, null) ?? '',
|
|
2621
2810
|
directory: null,
|
|
2622
2811
|
status,
|
|
2623
2812
|
plan_count: 0,
|
|
@@ -2632,7 +2821,7 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
2632
2821
|
}
|
|
2633
2822
|
}
|
|
2634
2823
|
}
|
|
2635
|
-
phases.sort((a, b) =>
|
|
2824
|
+
phases.sort((a, b) => comparePhaseNum(a['number'], b['number']));
|
|
2636
2825
|
// #3581: the frontier is ROADMAP ORDER, not artifact presence. The disk loop
|
|
2637
2826
|
// above could claim nextPhase from a stray out-of-order artifact directory
|
|
2638
2827
|
// (a phase-9 UAT evidence dir while roadmap phase 8 was pending and
|
|
@@ -2691,9 +2880,13 @@ function cmdInitProgress(cwd, raw, options = {}) {
|
|
|
2691
2880
|
paused_at: pausedAt,
|
|
2692
2881
|
has_work_in_progress: !!currentPhase,
|
|
2693
2882
|
phase_mvp_mode: phaseMvpMode,
|
|
2694
|
-
project_exists: pathExistsInternal(cwd, '
|
|
2883
|
+
project_exists: pathExistsInternal(cwd, toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planningDir(cwd), 'PROJECT.md')))),
|
|
2695
2884
|
roadmap_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
2696
2885
|
state_exists: node_fs_1.default.existsSync(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
2886
|
+
// #4040: partial-init discriminator (see buildInitCompletenessFields) —
|
|
2887
|
+
// also adds planning_exists / requirements_exists / milestones_exists so
|
|
2888
|
+
// progress.md's init_context routing never has to fall back to Glob.
|
|
2889
|
+
...buildInitCompletenessFields(cwd),
|
|
2697
2890
|
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
|
2698
2891
|
state_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'STATE.md')),
|
|
2699
2892
|
roadmap_path: toPosixPath(node_path_1.default.join(planningDir(cwd), 'ROADMAP.md')),
|
|
@@ -3326,7 +3519,9 @@ function cmdSkillManifest(cwd, args, raw) {
|
|
|
3326
3519
|
const skillsDir = skillsDirIdx >= 0 && args[skillsDirIdx + 1] ? args[skillsDirIdx + 1] : null;
|
|
3327
3520
|
const manifest = buildSkillManifest(cwd, skillsDir);
|
|
3328
3521
|
if (args.includes('--write')) {
|
|
3329
|
-
|
|
3522
|
+
// #3964: write beside the project's own artifacts (planningDir is
|
|
3523
|
+
// project- and workstream-aware), not the flat root.
|
|
3524
|
+
const planDir = planningDir(cwd);
|
|
3330
3525
|
if (node_fs_1.default.existsSync(planDir)) {
|
|
3331
3526
|
const manifestPath = node_path_1.default.join(planDir, 'skill-manifest.json');
|
|
3332
3527
|
(0, shell_command_projection_cjs_1.platformWriteSync)(manifestPath, JSON.stringify(manifest, null, 2));
|
|
@@ -3340,6 +3535,7 @@ module.exports = {
|
|
|
3340
3535
|
cmdInitNewProject,
|
|
3341
3536
|
cmdInitNewMilestone,
|
|
3342
3537
|
cmdInitQuick,
|
|
3538
|
+
cmdInitQuickBatch,
|
|
3343
3539
|
cmdInitIngestDocs,
|
|
3344
3540
|
cmdInitOnboard,
|
|
3345
3541
|
cmdInitResume,
|