@opengsd/gsd-core 1.15.0 → 1.17.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 -2
- package/.opencode/plugins/gsd-core.js +336 -6
- package/.opencode/plugins/gsd-statusline/tui.tsx +55 -0
- package/GEMINI.md +1 -1
- package/agents/gsd-code-fixer.compact.md +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-code-reviewer.compact.md +5 -3
- package/agents/gsd-code-reviewer.md +8 -6
- package/agents/gsd-debug-session-manager.compact.md +7 -1
- package/agents/gsd-debug-session-manager.md +7 -1
- package/agents/gsd-debugger.md +2 -2
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +4 -4
- package/agents/gsd-intel-updater.compact.md +1 -1
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +2 -2
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-plan-checker.md +7 -2
- package/agents/gsd-planner.md +3 -3
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +1 -1
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +21 -30
- package/agents/gsd-ui-auditor.md +42 -51
- package/agents/gsd-ui-researcher.compact.md +1 -1
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-verifier.md +31 -9
- package/bin/gsd-mcp-server.js +3 -1
- package/bin/install.js +487 -290
- package/commands/gsd/add-tests.md +6 -1
- package/commands/gsd/ai-integration-phase.md +6 -1
- package/commands/gsd/audit-fix.md +5 -0
- package/commands/gsd/audit-milestone.md +6 -1
- package/commands/gsd/autonomous.md +5 -0
- package/commands/gsd/capture.md +8 -4
- package/commands/gsd/code-review.md +7 -2
- package/commands/gsd/complete-milestone.md +4 -0
- package/commands/gsd/config.md +7 -3
- package/commands/gsd/debug.md +11 -7
- package/commands/gsd/discuss-phase.md +7 -3
- package/commands/gsd/docs-update.md +12 -7
- package/commands/gsd/eval-review.md +6 -1
- package/commands/gsd/execute-phase.md +12 -7
- package/commands/gsd/extract-learnings.md +5 -0
- package/commands/gsd/fast.md +4 -0
- package/commands/gsd/forensics.md +5 -1
- package/commands/gsd/graphify.md +10 -6
- package/commands/gsd/health.md +5 -0
- package/commands/gsd/help.md +7 -2
- package/commands/gsd/import.md +7 -3
- package/commands/gsd/inbox.md +5 -0
- package/commands/gsd/ingest-docs.md +5 -1
- package/commands/gsd/manager.md +6 -1
- package/commands/gsd/map-codebase.md +7 -3
- package/commands/gsd/mempalace-capture.md +5 -1
- package/commands/gsd/mempalace-recall.md +5 -1
- package/commands/gsd/milestone-summary.md +5 -1
- package/commands/gsd/mvp-phase.md +8 -3
- package/commands/gsd/new-milestone.md +6 -1
- package/commands/gsd/new-project.md +5 -0
- package/commands/gsd/next.md +6 -1
- package/commands/gsd/ns-context.md +4 -0
- package/commands/gsd/ns-ideate.md +4 -0
- package/commands/gsd/ns-manage.md +4 -0
- package/commands/gsd/ns-project.md +4 -0
- package/commands/gsd/ns-review.md +4 -0
- package/commands/gsd/ns-workflow.md +4 -0
- package/commands/gsd/onboard.md +6 -1
- package/commands/gsd/pause-work.md +5 -1
- package/commands/gsd/phase.md +8 -4
- package/commands/gsd/plan-phase.md +6 -1
- package/commands/gsd/plan-review-convergence.md +5 -1
- package/commands/gsd/pr-branch.md +4 -0
- package/commands/gsd/profile-user.md +5 -1
- package/commands/gsd/progress.md +6 -1
- package/commands/gsd/quick-batch.md +20 -8
- package/commands/gsd/quick.md +12 -7
- package/commands/gsd/review.md +5 -1
- package/commands/gsd/secure-phase.md +6 -1
- package/commands/gsd/ship.md +5 -0
- package/commands/gsd/sketch.md +7 -2
- package/commands/gsd/spec-phase.md +5 -1
- package/commands/gsd/spike.md +8 -3
- package/commands/gsd/surface.md +5 -1
- package/commands/gsd/thread.md +4 -0
- package/commands/gsd/ui-phase.md +6 -1
- package/commands/gsd/ui-review.md +6 -1
- package/commands/gsd/ultraplan-phase.md +5 -1
- package/commands/gsd/undo.md +5 -1
- package/commands/gsd/update.md +6 -2
- package/commands/gsd/validate-phase.md +6 -1
- package/commands/gsd/verify-work.md +6 -1
- package/commands/gsd/workspace.md +7 -3
- package/gsd-core/bin/gsd-tools.cjs +159 -58
- package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
- package/gsd-core/bin/lib/adr-parser.cjs +37 -5
- package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
- package/gsd-core/bin/lib/audit.cjs +78 -44
- package/gsd-core/bin/lib/broken-windows.cjs +13 -13
- package/gsd-core/bin/lib/capability-activation.cjs +9 -4
- package/gsd-core/bin/lib/capability-registry.cjs +249 -117
- package/gsd-core/bin/lib/capability-validator.cjs +18 -1
- package/gsd-core/bin/lib/capability-writer.cjs +2 -1
- package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
- package/gsd-core/bin/lib/check-command-router.cjs +164 -1712
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
- package/gsd-core/bin/lib/cli-exit.cjs +12 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +11 -8
- package/gsd-core/bin/lib/command-aliases.cjs +7 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
- package/gsd-core/bin/lib/commands.cjs +201 -178
- package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
- package/gsd-core/bin/lib/config.cjs +43 -12
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/coverage.cjs +4 -8
- package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
- package/gsd-core/bin/lib/drift.cjs +177 -42
- package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
- package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
- package/gsd-core/bin/lib/frontmatter.cjs +413 -234
- package/gsd-core/bin/lib/gap-checker.cjs +72 -29
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
- package/gsd-core/bin/lib/gate-args.cjs +53 -0
- package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
- package/gsd-core/bin/lib/gate-config.cjs +46 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +142 -0
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
- package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
- package/gsd-core/bin/lib/gate-exit.cjs +27 -0
- package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
- package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
- package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
- package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
- package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
- package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
- package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
- package/gsd-core/bin/lib/gate-ui-safety.cjs +81 -0
- package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
- package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
- package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
- package/gsd-core/bin/lib/graphify.cjs +3 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
- package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
- package/gsd-core/bin/lib/init.cjs +194 -108
- package/gsd-core/bin/lib/install-engine.cjs +30 -35
- package/gsd-core/bin/lib/install-profiles.cjs +7 -4
- package/gsd-core/bin/lib/install-shadow-report.cjs +12 -0
- package/gsd-core/bin/lib/installer-migrations/011-opencode-mcp-no-prompts.cjs +99 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +54 -1
- package/gsd-core/bin/lib/io.cjs +122 -3
- package/gsd-core/bin/lib/jsonc-edit.cjs +418 -0
- package/gsd-core/bin/lib/loop-host-contract.cjs +2 -1
- package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
- package/gsd-core/bin/lib/mcp-server.cjs +5 -1
- package/gsd-core/bin/lib/milestone.cjs +19 -1
- package/gsd-core/bin/lib/model-resolver.cjs +18 -18
- package/gsd-core/bin/lib/observability/event.cjs +1 -1
- package/gsd-core/bin/lib/observability/logger.cjs +46 -1
- package/gsd-core/bin/lib/opencode-mcp-entry.cjs +39 -0
- package/gsd-core/bin/lib/opencode-version.cjs +486 -0
- package/gsd-core/bin/lib/pattern.cjs +10 -0
- package/gsd-core/bin/lib/phase-command-router.cjs +11 -4
- package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
- package/gsd-core/bin/lib/phase-id.cjs +1 -1
- package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
- package/gsd-core/bin/lib/phase-status.cjs +360 -0
- package/gsd-core/bin/lib/phase.cjs +301 -80
- package/gsd-core/bin/lib/plan-document.cjs +93 -19
- package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
- package/gsd-core/bin/lib/planning-document.cjs +273 -40
- package/gsd-core/bin/lib/planning-inspect.cjs +42 -8
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +76 -53
- package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
- package/gsd-core/bin/lib/profile-output.cjs +6 -3
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +13 -9
- package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
- package/gsd-core/bin/lib/report-parser.cjs +269 -0
- package/gsd-core/bin/lib/roadmap-command-router.cjs +13 -15
- package/gsd-core/bin/lib/roadmap-parser.cjs +82 -15
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +127 -65
- package/gsd-core/bin/lib/roadmap.cjs +169 -72
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +186 -161
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -1
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
- package/gsd-core/bin/lib/runtime-homes.cjs +13 -10
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +365 -594
- package/gsd-core/bin/lib/runtime-name-policy.cjs +142 -27
- package/gsd-core/bin/lib/runtime-slash.cjs +60 -30
- package/gsd-core/bin/lib/shell-command-projection.cjs +37 -2
- package/gsd-core/bin/lib/smart-entry.cjs +111 -56
- package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
- package/gsd-core/bin/lib/state-contract.cjs +15 -18
- package/gsd-core/bin/lib/state-document.cjs +100 -22
- package/gsd-core/bin/lib/state-transition.cjs +67 -9
- package/gsd-core/bin/lib/state.cjs +668 -171
- package/gsd-core/bin/lib/surface.cjs +2 -1
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -152
- package/gsd-core/bin/lib/uat-predicate.cjs +313 -35
- package/gsd-core/bin/lib/uat.cjs +424 -7
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +94 -58
- package/gsd-core/bin/lib/update-context.cjs +18 -1
- package/gsd-core/bin/lib/vendor/README.md +31 -9
- package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
- package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +1265 -324
- package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
- package/gsd-core/bin/lib/verify.cjs +286 -567
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
- package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
- package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
- package/gsd-core/bin/lib/workstream.cjs +11 -2
- package/gsd-core/bin/shared/config-defaults.manifest.json +5 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +4 -0
- package/gsd-core/references/autonomous-smart-discuss.md +2 -1
- package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
- package/gsd-core/references/execute-mvp-tdd.md +5 -10
- package/gsd-core/references/execute-phase-between-wave-reset.md +3 -0
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +7 -1
- package/gsd-core/references/offer-next.md +1 -1
- package/gsd-core/references/planning-config.md +1 -1
- package/gsd-core/references/spidr-splitting.md +1 -1
- package/gsd-core/references/tdd.md +10 -4
- package/gsd-core/references/verifier-phase-gates.md +5 -2
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -3
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/UAT.md +17 -1
- package/gsd-core/templates/config.json +2 -11
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +8 -7
- package/gsd-core/workflows/add-tests.md +3 -2
- package/gsd-core/workflows/add-todo.md +4 -3
- package/gsd-core/workflows/ai-integration-phase.md +3 -2
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +4 -3
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous.md +28 -18
- package/gsd-core/workflows/check-todos.md +6 -5
- package/gsd-core/workflows/cleanup.md +1 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
- package/gsd-core/workflows/code-review-fix.md +5 -4
- package/gsd-core/workflows/code-review.md +100 -91
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
- package/gsd-core/workflows/complete-milestone.md +12 -7
- package/gsd-core/workflows/debug.md +30 -5
- package/gsd-core/workflows/diagnose-issues.md +3 -2
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +4 -3
- package/gsd-core/workflows/do.md +1 -1
- package/gsd-core/workflows/docs-update.md +4 -3
- package/gsd-core/workflows/edit-phase.md +4 -3
- package/gsd-core/workflows/eval-review.md +5 -3
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +4 -2
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
- package/gsd-core/workflows/execute-phase.md +81 -171
- package/gsd-core/workflows/execute-plan.md +13 -19
- package/gsd-core/workflows/explore.md +2 -2
- package/gsd-core/workflows/extract-learnings.md +3 -2
- package/gsd-core/workflows/fast.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +3 -2
- package/gsd-core/workflows/inbox.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +4 -3
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +5 -3
- package/gsd-core/workflows/map-codebase.md +4 -3
- package/gsd-core/workflows/milestone-summary.md +3 -2
- package/gsd-core/workflows/mvp-phase.md +14 -14
- package/gsd-core/workflows/new-milestone.md +10 -10
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +1 -1
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/pause-work.md +2 -2
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +1 -1
- package/gsd-core/workflows/plan-phase.md +27 -18
- package/gsd-core/workflows/plan-review-convergence.md +1 -1
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +1 -1
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress.md +19 -49
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -2
- package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
- package/gsd-core/workflows/quick-batch.md +15 -10
- package/gsd-core/workflows/quick.md +42 -31
- package/gsd-core/workflows/remove-phase.md +3 -2
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +17 -12
- package/gsd-core/workflows/review.md +3 -2
- package/gsd-core/workflows/scan.md +3 -2
- package/gsd-core/workflows/secure-phase.md +11 -12
- package/gsd-core/workflows/settings-advanced.md +1 -1
- package/gsd-core/workflows/settings-integrations.md +1 -1
- package/gsd-core/workflows/settings.md +1 -1
- package/gsd-core/workflows/ship.md +12 -12
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +1 -1
- package/gsd-core/workflows/spec-phase.md +1 -1
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/sync-skills.md +1 -1
- package/gsd-core/workflows/thread.md +2 -2
- package/gsd-core/workflows/transition.md +13 -23
- package/gsd-core/workflows/ui-phase.md +5 -4
- package/gsd-core/workflows/ui-review.md +4 -3
- package/gsd-core/workflows/ultraplan-phase.md +3 -2
- package/gsd-core/workflows/undo.md +1 -1
- package/gsd-core/workflows/validate-phase.md +10 -12
- package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
- package/gsd-core/workflows/verify-work.md +68 -59
- package/hooks/dist/gsd-agent-isolation-guard.js +8 -0
- package/hooks/dist/gsd-check-update-worker.js +8 -0
- package/hooks/dist/gsd-check-update.js +34 -20
- package/hooks/dist/gsd-context-monitor.js +45 -13
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
- package/hooks/dist/gsd-secret-read-guard.js +263 -16
- package/hooks/dist/gsd-statusline.js +336 -29
- package/hooks/dist/gsd-update-banner.js +8 -0
- package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
- package/hooks/dist/gsd-workflow-guard.js +5 -4
- package/hooks/dist/gsd-worktree-path-guard.js +6 -2
- package/hooks/dist/lib/cli-exit.js +12 -0
- package/hooks/dist/lib/git-probe.js +17 -1
- package/hooks/dist/lib/isolation-sentinel.js +2 -2
- package/hooks/gsd-agent-isolation-guard.js +8 -0
- package/hooks/gsd-check-update-worker.js +8 -0
- package/hooks/gsd-check-update.js +34 -20
- package/hooks/gsd-context-monitor.js +45 -13
- package/hooks/gsd-cursor-subagent-start.js +8 -0
- package/hooks/gsd-secret-read-guard.js +263 -16
- package/hooks/gsd-statusline.js +336 -29
- package/hooks/gsd-update-banner.js +8 -0
- package/hooks/gsd-windsurf-pre-write.js +11 -2
- package/hooks/gsd-workflow-guard.js +5 -4
- package/hooks/gsd-worktree-path-guard.js +6 -2
- package/hooks/hooks.json +5 -5
- package/hooks/lib/cli-exit.js +12 -0
- package/hooks/lib/git-probe.js +17 -1
- package/hooks/lib/isolation-sentinel.js +2 -2
- package/package.json +21 -4
- package/scripts/changeset/parse.cjs +52 -4
- package/scripts/ci-timeout-report.cjs +770 -4
- package/scripts/command-contract-helpers.cjs +12 -8
- package/scripts/docs-guard-registry.cjs +6 -0
- package/scripts/gen-capability-registry.cjs +7 -1
- package/scripts/gen-features.cjs +13 -8
- package/scripts/gen-hooks-cli-exit.cjs +12 -28
- package/scripts/gen-loop-host-contract.cjs +14 -2
- package/scripts/gen-platform-conformance-tier.cjs +187 -1
- package/scripts/gen-plugin-skills.cjs +87 -1
- package/scripts/gen-research-agents.cjs +24 -31
- package/scripts/gen-scripts-cli-exit.cjs +30 -3
- package/scripts/gen-test-timings.cjs +32 -7
- package/scripts/lib/cli-exit.cjs +12 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +24 -2
- package/scripts/lib/ndjson-reporter.cjs +28 -3
- package/scripts/lib/platform-conformance-tier.generated.cjs +44 -5
- package/scripts/lib/registration-ledger-preload.cjs +155 -0
- package/scripts/lib/vendor-bundle.cjs +59 -0
- package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-completion-predicate-drift.cjs +18 -19
- package/scripts/lint-descriptions.cjs +7 -3
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +10 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
- package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
- package/scripts/lint-phase-enumeration-drift.cjs +12 -8
- package/scripts/lint-phase-id-drift.cjs +29 -0
- package/scripts/lint-planning-document-positive-control.cjs +329 -0
- package/scripts/lint-response-language-coverage.cjs +3 -0
- package/scripts/lint-skill-deps.cjs +7 -3
- package/scripts/lint-test-file-count.allowlist.json +11 -1
- package/scripts/lint-test-file-count.cjs +34 -1
- package/scripts/lint-vendored-deps.cjs +41 -5
- package/scripts/lint-workflow-shellcheck-baseline.json +10 -10
- package/scripts/mutation-matrix.cjs +53 -6
- package/scripts/release-tarball-smoke.cjs +14 -7
- package/scripts/require-issue-link-policy.cjs +6 -2
- package/scripts/sync-runtime-launcher.cjs +184 -2
- package/scripts/verify-npm-publish.cjs +76 -20
- package/skills/gsd-add-tests/SKILL.md +6 -1
- package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
- package/skills/gsd-audit-fix/SKILL.md +5 -0
- package/skills/gsd-audit-milestone/SKILL.md +6 -1
- package/skills/gsd-autonomous/SKILL.md +5 -0
- package/skills/gsd-capture/SKILL.md +8 -4
- package/skills/gsd-code-review/SKILL.md +7 -2
- package/skills/gsd-complete-milestone/SKILL.md +4 -0
- package/skills/gsd-config/SKILL.md +8 -4
- package/skills/gsd-debug/SKILL.md +11 -7
- package/skills/gsd-discuss-phase/SKILL.md +7 -3
- package/skills/gsd-docs-update/SKILL.md +12 -7
- package/skills/gsd-eval-review/SKILL.md +6 -1
- package/skills/gsd-execute-phase/SKILL.md +12 -7
- package/skills/gsd-extract-learnings/SKILL.md +5 -0
- package/skills/gsd-fast/SKILL.md +4 -0
- package/skills/gsd-forensics/SKILL.md +5 -1
- package/skills/gsd-graphify/SKILL.md +10 -6
- package/skills/gsd-health/SKILL.md +5 -0
- package/skills/gsd-help/SKILL.md +7 -2
- package/skills/gsd-import/SKILL.md +7 -3
- package/skills/gsd-inbox/SKILL.md +5 -0
- package/skills/gsd-ingest-docs/SKILL.md +5 -1
- package/skills/gsd-manager/SKILL.md +6 -1
- package/skills/gsd-map-codebase/SKILL.md +7 -3
- package/skills/gsd-mempalace-capture/SKILL.md +5 -1
- package/skills/gsd-mempalace-recall/SKILL.md +5 -1
- package/skills/gsd-milestone-summary/SKILL.md +5 -1
- package/skills/gsd-mvp-phase/SKILL.md +8 -3
- package/skills/gsd-new-milestone/SKILL.md +6 -1
- package/skills/gsd-new-project/SKILL.md +5 -0
- package/skills/gsd-next/SKILL.md +6 -1
- package/skills/gsd-ns-context/SKILL.md +4 -0
- package/skills/gsd-ns-ideate/SKILL.md +4 -0
- package/skills/gsd-ns-manage/SKILL.md +4 -0
- package/skills/gsd-ns-project/SKILL.md +4 -0
- package/skills/gsd-ns-review/SKILL.md +4 -0
- package/skills/gsd-ns-workflow/SKILL.md +4 -0
- package/skills/gsd-onboard/SKILL.md +6 -1
- package/skills/gsd-pause-work/SKILL.md +5 -1
- package/skills/gsd-phase/SKILL.md +8 -4
- package/skills/gsd-plan-phase/SKILL.md +6 -1
- package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
- package/skills/gsd-pr-branch/SKILL.md +4 -0
- package/skills/gsd-profile-user/SKILL.md +5 -1
- package/skills/gsd-progress/SKILL.md +6 -1
- package/skills/gsd-quick/SKILL.md +16 -10
- package/skills/gsd-quick-batch/SKILL.md +20 -8
- package/skills/gsd-review/SKILL.md +5 -1
- package/skills/gsd-review-backlog/SKILL.md +3 -2
- package/skills/gsd-secure-phase/SKILL.md +6 -1
- package/skills/gsd-ship/SKILL.md +5 -0
- package/skills/gsd-sketch/SKILL.md +7 -2
- package/skills/gsd-spec-phase/SKILL.md +5 -1
- package/skills/gsd-spike/SKILL.md +8 -3
- package/skills/gsd-surface/SKILL.md +5 -1
- package/skills/gsd-thread/SKILL.md +4 -0
- package/skills/gsd-ui-phase/SKILL.md +6 -1
- package/skills/gsd-ui-review/SKILL.md +6 -1
- package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
- package/skills/gsd-undo/SKILL.md +5 -1
- package/skills/gsd-update/SKILL.md +6 -2
- package/skills/gsd-validate-phase/SKILL.md +6 -1
- package/skills/gsd-verify-work/SKILL.md +6 -1
- package/skills/gsd-workspace/SKILL.md +7 -3
- package/skills/gsd-workstreams/SKILL.md +6 -6
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +0 -24
|
@@ -43,6 +43,7 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
43
43
|
const node_path_1 = __importDefault(require("node:path"));
|
|
44
44
|
const node_child_process_1 = require("node:child_process");
|
|
45
45
|
const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
|
|
46
|
+
const runtime_slash_cjs_1 = require("./runtime-slash.cjs");
|
|
46
47
|
// #3696: the calendar-validity predicate moved to the STATE.md document module
|
|
47
48
|
// so `state validate` can assert the same `last_activity` invariant this reader
|
|
48
49
|
// already enforces (ADR-227). Two copies would let the two surfaces disagree
|
|
@@ -52,14 +53,17 @@ const ioMod = require("./io.cjs");
|
|
|
52
53
|
const { output } = ioMod;
|
|
53
54
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
54
55
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
55
|
-
const { planningPaths } = planningWorkspace;
|
|
56
|
+
const { planningPaths, resolvePhaseIdConvention } = planningWorkspace;
|
|
56
57
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
57
58
|
const frontmatter = require("./frontmatter.cjs");
|
|
58
|
-
const { extractFrontmatter } = frontmatter;
|
|
59
|
+
const { extractFrontmatter, frontmatterBlock } = frontmatter;
|
|
59
60
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- phase-lifecycle.cjs is an export= CommonJS module
|
|
60
61
|
const phaseLifecycle = require("./phase-lifecycle.cjs");
|
|
61
62
|
const { deriveProgressFromRoadmap } = phaseLifecycle;
|
|
62
63
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
64
|
+
const roadmapParser = require("./roadmap-parser.cjs");
|
|
65
|
+
const { extractCurrentMilestone, scanMilestonePhaseIds } = roadmapParser;
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
63
67
|
const stateDocument = require("./state-document.cjs");
|
|
64
68
|
const { stateFieldValue } = stateDocument;
|
|
65
69
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -71,6 +75,10 @@ const { readStateHeadFreshness } = stateMod;
|
|
|
71
75
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
72
76
|
const unusableInput = require("./unusable-input.cjs");
|
|
73
77
|
const { warnUnusableInput, UNUSABLE_REASON } = unusableInput;
|
|
78
|
+
// #5118: the verification-status owner's frontmatter-only report check.
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
80
|
+
const verificationMod = require("./verification.cjs");
|
|
81
|
+
const { findVerificationStatusError } = verificationMod;
|
|
74
82
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
75
83
|
/**
|
|
76
84
|
* Staleness threshold for idle-stranded detection. A clean tree whose last
|
|
@@ -285,11 +293,20 @@ function detectVerifyFailed(cwd, currentPhaseRaw) {
|
|
|
285
293
|
catch {
|
|
286
294
|
return false;
|
|
287
295
|
}
|
|
296
|
+
// #5118: this phase's VERIFICATION report `status` is judged by its owner
|
|
297
|
+
// (src/verification.cts, the same frontmatter-only, containment-checked
|
|
298
|
+
// locator every reader shares) — an out-of-set value is the owner's hard
|
|
299
|
+
// error here as at every other reader, never a silent "not failed". The
|
|
300
|
+
// body `STATUS:` marker scan below is this probe's own signal.
|
|
301
|
+
const statusError = findVerificationStatusError([latestDir]);
|
|
302
|
+
if (statusError)
|
|
303
|
+
throw statusError;
|
|
288
304
|
const candidates = files.filter((f) => /summary|verif(?:y|ication)|uat/i.test(f));
|
|
289
305
|
for (const name of candidates) {
|
|
290
306
|
let content = '';
|
|
307
|
+
const filePath = node_path_1.default.join(latestDir, name);
|
|
291
308
|
try {
|
|
292
|
-
content = node_fs_1.default.readFileSync(
|
|
309
|
+
content = node_fs_1.default.readFileSync(filePath, 'utf-8');
|
|
293
310
|
}
|
|
294
311
|
catch {
|
|
295
312
|
continue;
|
|
@@ -311,7 +328,10 @@ function readStateFile(statePath) {
|
|
|
311
328
|
return null;
|
|
312
329
|
}
|
|
313
330
|
const fm = extractFrontmatter(content, statePath);
|
|
314
|
-
|
|
331
|
+
// The body starts after the block `extractFrontmatter` just read (the one fence owner), so a
|
|
332
|
+
// `---` inside a value, a BOM, or an adjacent empty block cannot cut it somewhere else.
|
|
333
|
+
const block = frontmatterBlock(content);
|
|
334
|
+
const body = block ? block.rest.replace(/^\s+/, '') : content;
|
|
315
335
|
return { fm, body };
|
|
316
336
|
}
|
|
317
337
|
/** Collect the full signal set from disk for `cwd`. Exported for unit tests. */
|
|
@@ -336,6 +356,7 @@ function detectSignals(cwd, now = Date.now) {
|
|
|
336
356
|
stale_activity: false,
|
|
337
357
|
roadmap_total_phases: null,
|
|
338
358
|
roadmap_completed_phases: null,
|
|
359
|
+
milestone_phases: [],
|
|
339
360
|
// No STATE.md (or unreadable) → no stamp to compare. Unknown, not fresh.
|
|
340
361
|
state_commits_behind: null,
|
|
341
362
|
state_commit_stale: null,
|
|
@@ -409,12 +430,18 @@ function detectSignals(cwd, now = Date.now) {
|
|
|
409
430
|
// Progress table — isComplete falls back to the legacy comparison in that case.
|
|
410
431
|
let roadmapTotalPhases = null;
|
|
411
432
|
let roadmapCompletedPhases = null;
|
|
433
|
+
let milestonePhases = [];
|
|
412
434
|
if (hasRoadmap) {
|
|
413
435
|
try {
|
|
414
436
|
const roadmapContent = node_fs_1.default.readFileSync(paths.roadmap, 'utf8');
|
|
415
437
|
const derived = deriveProgressFromRoadmap(roadmapContent);
|
|
416
438
|
roadmapTotalPhases = derived.totalPhases;
|
|
417
439
|
roadmapCompletedPhases = derived.completedPhases;
|
|
440
|
+
// #5228: the ordered phase list of the current milestone, from the same
|
|
441
|
+
// scan the milestone-scoped commands use.
|
|
442
|
+
milestonePhases = [
|
|
443
|
+
...scanMilestonePhaseIds(extractCurrentMilestone(roadmapContent, cwd), resolvePhaseIdConvention(cwd)),
|
|
444
|
+
].sort(comparePhaseNum);
|
|
418
445
|
}
|
|
419
446
|
catch {
|
|
420
447
|
/* ROADMAP.md unreadable — leave null; isComplete falls back to legacy. */
|
|
@@ -441,6 +468,7 @@ function detectSignals(cwd, now = Date.now) {
|
|
|
441
468
|
stale_activity: staleActivity,
|
|
442
469
|
roadmap_total_phases: roadmapTotalPhases,
|
|
443
470
|
roadmap_completed_phases: roadmapCompletedPhases,
|
|
471
|
+
milestone_phases: milestonePhases,
|
|
444
472
|
state_commits_behind: freshness.commits_behind,
|
|
445
473
|
state_commit_stale: freshness.commit_stale,
|
|
446
474
|
};
|
|
@@ -472,10 +500,21 @@ function isComplete(s) {
|
|
|
472
500
|
// Legacy path: STATE.md comparison. It only fires when ROADMAP.md is
|
|
473
501
|
// absent or has no Progress table, and uses canonical phase-id ordering
|
|
474
502
|
// so dotted phase ids are never coerced to JavaScript numbers.
|
|
475
|
-
if (s.
|
|
476
|
-
return false;
|
|
477
|
-
if (comparePhaseNum(s.current_phase, s.total_phases) < 0)
|
|
503
|
+
if (s.current_phase === null)
|
|
478
504
|
return false;
|
|
505
|
+
if (s.milestone_phases.length > 0) {
|
|
506
|
+
// #5228: compare against the milestone's LAST phase. The phase count is
|
|
507
|
+
// not a phase number once numbering continues from an earlier milestone.
|
|
508
|
+
const last = s.milestone_phases[s.milestone_phases.length - 1];
|
|
509
|
+
if (comparePhaseNum(s.current_phase, last) < 0)
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
if (s.total_phases === null)
|
|
514
|
+
return false;
|
|
515
|
+
if (comparePhaseNum(s.current_phase, s.total_phases) < 0)
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
479
518
|
}
|
|
480
519
|
// Status regex: require milestone-level completion language. The pre-fix
|
|
481
520
|
// regex matched any "shipped" / "done" substring (per-phase language).
|
|
@@ -542,52 +581,54 @@ function rec(id, label, command) {
|
|
|
542
581
|
return action(id, label, command, true);
|
|
543
582
|
}
|
|
544
583
|
/** Per-situation ordered action list; recommended action first. */
|
|
545
|
-
function actionsFor(situation, s) {
|
|
584
|
+
function actionsFor(situation, s, runtime = 'claude') {
|
|
585
|
+
// #4859: commands are printed verbatim, so name them the way this runtime registers them.
|
|
586
|
+
const cmd = (name) => (0, runtime_slash_cjs_1.formatGsdSlash)(name, runtime);
|
|
546
587
|
const phaseN = s.current_phase ?? '';
|
|
547
588
|
const execLabel = phaseN === '' ? 'Continue executing' : `Continue executing phase ${phaseN}`;
|
|
548
589
|
switch (situation) {
|
|
549
590
|
case 'no-project':
|
|
550
591
|
return [
|
|
551
|
-
rec('new-project', 'Start a new project', '
|
|
552
|
-
action('map-codebase', 'Map an existing codebase', '
|
|
553
|
-
action('quick', 'Quick task', '
|
|
554
|
-
action('help', 'Show help', '
|
|
592
|
+
rec('new-project', 'Start a new project', cmd('new-project')),
|
|
593
|
+
action('map-codebase', 'Map an existing codebase', cmd('map-codebase')),
|
|
594
|
+
action('quick', 'Quick task', cmd('quick')),
|
|
595
|
+
action('help', 'Show help', cmd('help')),
|
|
555
596
|
];
|
|
556
597
|
case 'paused':
|
|
557
598
|
return [
|
|
558
|
-
rec('resume-work', 'Resume work', '
|
|
559
|
-
action('progress', 'Show progress', '
|
|
560
|
-
action('quick', 'Quick task', '
|
|
561
|
-
action('help', 'Show help', '
|
|
599
|
+
rec('resume-work', 'Resume work', cmd('resume-work')),
|
|
600
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
601
|
+
action('quick', 'Quick task', cmd('quick')),
|
|
602
|
+
action('help', 'Show help', cmd('help')),
|
|
562
603
|
];
|
|
563
604
|
case 'blocked':
|
|
564
605
|
return [
|
|
565
|
-
rec('debug', 'Debug the blocker', '
|
|
566
|
-
action('verify-work', 'Verify current work', '
|
|
567
|
-
action('capture', 'Capture a note', '
|
|
568
|
-
action('progress', 'Show progress', '
|
|
606
|
+
rec('debug', 'Debug the blocker', cmd('debug')),
|
|
607
|
+
action('verify-work', 'Verify current work', cmd('verify-work')),
|
|
608
|
+
action('capture', 'Capture a note', cmd('capture')),
|
|
609
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
569
610
|
];
|
|
570
611
|
case 'verify-failed':
|
|
571
612
|
return [
|
|
572
|
-
rec('verify-work', 'Re-verify work', '
|
|
573
|
-
action('debug', 'Debug the failure', '
|
|
574
|
-
action('code-review', 'Review recent work', '
|
|
575
|
-
action('progress', 'Show progress', '
|
|
613
|
+
rec('verify-work', 'Re-verify work', cmd('verify-work')),
|
|
614
|
+
action('debug', 'Debug the failure', cmd('debug')),
|
|
615
|
+
action('code-review', 'Review recent work', cmd('code-review')),
|
|
616
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
576
617
|
];
|
|
577
618
|
case 'needs-first-phase':
|
|
578
619
|
return [
|
|
579
|
-
rec('discuss-phase', 'Discuss the first phase', '
|
|
580
|
-
action('plan-phase', 'Plan phase 1', '
|
|
581
|
-
action('quick', 'Quick task', '
|
|
582
|
-
action('progress', 'Show progress', '
|
|
620
|
+
rec('discuss-phase', 'Discuss the first phase', cmd('discuss-phase')),
|
|
621
|
+
action('plan-phase', 'Plan phase 1', cmd('plan-phase')),
|
|
622
|
+
action('quick', 'Quick task', cmd('quick')),
|
|
623
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
583
624
|
];
|
|
584
625
|
case 'planning':
|
|
585
626
|
// Forward motion → delegate to the single gated engine (see 'executing').
|
|
586
627
|
return [
|
|
587
|
-
rec('progress-next', `Advance to the next step (plan phase ${phaseN || 1})`, '
|
|
588
|
-
action('plan-phase', `Plan phase ${phaseN || 1}`, '
|
|
589
|
-
action('discuss-phase', 'Discuss before planning', '
|
|
590
|
-
action('progress', 'Show progress', '
|
|
628
|
+
rec('progress-next', `Advance to the next step (plan phase ${phaseN || 1})`, cmd('progress --next')),
|
|
629
|
+
action('plan-phase', `Plan phase ${phaseN || 1}`, cmd('plan-phase')),
|
|
630
|
+
action('discuss-phase', 'Discuss before planning', cmd('discuss-phase')),
|
|
631
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
591
632
|
];
|
|
592
633
|
case 'executing':
|
|
593
634
|
// In-project forward motion delegates to the single gated engine
|
|
@@ -596,40 +637,40 @@ function actionsFor(situation, s) {
|
|
|
596
637
|
// /gsd:execute-phase here — that divergence is why the old flat /gsd-next
|
|
597
638
|
// was removed (#3054). Direct execute stays as an explicit secondary choice.
|
|
598
639
|
return [
|
|
599
|
-
rec('progress-next', 'Advance to the next step', '
|
|
600
|
-
action('execute-phase', execLabel, '
|
|
601
|
-
action('quick', 'Quick task', '
|
|
602
|
-
action('code-review', 'Review recent work', '
|
|
640
|
+
rec('progress-next', 'Advance to the next step', cmd('progress --next')),
|
|
641
|
+
action('execute-phase', execLabel, cmd('execute-phase')),
|
|
642
|
+
action('quick', 'Quick task', cmd('quick')),
|
|
643
|
+
action('code-review', 'Review recent work', cmd('code-review')),
|
|
603
644
|
];
|
|
604
645
|
case 'verify-pending':
|
|
605
646
|
// Forward motion → delegate to the single gated engine (see 'executing').
|
|
606
647
|
return [
|
|
607
|
-
rec('progress-next', 'Advance to the next step (verify)', '
|
|
608
|
-
action('verify-work', 'Verify work', '
|
|
609
|
-
action('code-review', 'Review recent work', '
|
|
610
|
-
action('ship', 'Ship completed work', '
|
|
648
|
+
rec('progress-next', 'Advance to the next step (verify)', cmd('progress --next')),
|
|
649
|
+
action('verify-work', 'Verify work', cmd('verify-work')),
|
|
650
|
+
action('code-review', 'Review recent work', cmd('code-review')),
|
|
651
|
+
action('ship', 'Ship completed work', cmd('ship')),
|
|
611
652
|
];
|
|
612
653
|
case 'idle-stranded':
|
|
613
654
|
return [
|
|
614
|
-
rec('ship', 'Ship committed work', '
|
|
615
|
-
action('complete-milestone', 'Complete the milestone', '
|
|
616
|
-
action('progress', 'Show progress', '
|
|
617
|
-
action('capture', 'Capture a note', '
|
|
655
|
+
rec('ship', 'Ship committed work', cmd('ship')),
|
|
656
|
+
action('complete-milestone', 'Complete the milestone', cmd('complete-milestone')),
|
|
657
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
658
|
+
action('capture', 'Capture a note', cmd('capture')),
|
|
618
659
|
];
|
|
619
660
|
case 'complete':
|
|
620
661
|
return [
|
|
621
|
-
rec('new-milestone', 'Start a new milestone', '
|
|
622
|
-
action('extract-learnings', 'Extract learnings', '
|
|
623
|
-
action('quick', 'Quick task', '
|
|
624
|
-
action('progress', 'Show progress', '
|
|
662
|
+
rec('new-milestone', 'Start a new milestone', cmd('new-milestone')),
|
|
663
|
+
action('extract-learnings', 'Extract learnings', cmd('extract-learnings')),
|
|
664
|
+
action('quick', 'Quick task', cmd('quick')),
|
|
665
|
+
action('progress', 'Show progress', cmd('progress')),
|
|
625
666
|
];
|
|
626
667
|
case 'unknown':
|
|
627
668
|
default:
|
|
628
669
|
return [
|
|
629
|
-
rec('progress', 'Show progress', '
|
|
630
|
-
action('progress-next', 'Advance to the next step', '
|
|
631
|
-
action('quick', 'Quick task', '
|
|
632
|
-
action('help', 'Show help', '
|
|
670
|
+
rec('progress', 'Show progress', cmd('progress')),
|
|
671
|
+
action('progress-next', 'Advance to the next step', cmd('progress --next')),
|
|
672
|
+
action('quick', 'Quick task', cmd('quick')),
|
|
673
|
+
action('help', 'Show help', cmd('help')),
|
|
633
674
|
];
|
|
634
675
|
}
|
|
635
676
|
}
|
|
@@ -647,7 +688,7 @@ function buildSummary(situation, s) {
|
|
|
647
688
|
case 'needs-first-phase':
|
|
648
689
|
return 'Project initialized — plan your first phase';
|
|
649
690
|
case 'planning':
|
|
650
|
-
return
|
|
691
|
+
return `${phasePosition(s)} — needs a plan`;
|
|
651
692
|
case 'executing':
|
|
652
693
|
return progressLine('executing', s);
|
|
653
694
|
case 'verify-pending':
|
|
@@ -661,10 +702,24 @@ function buildSummary(situation, s) {
|
|
|
661
702
|
return 'Unsure of state — showing progress';
|
|
662
703
|
}
|
|
663
704
|
}
|
|
705
|
+
/**
|
|
706
|
+
* "Phase N of M" for the current phase. N is the phase's 1-based position in
|
|
707
|
+
* the current milestone's ordered phase list (#5228), so a milestone that
|
|
708
|
+
* continues the numbering of an earlier one (phases 9-17) reads "Phase 1 of 9",
|
|
709
|
+
* not "Phase 9 of 9". When the phase is not in that list (or the roadmap lists
|
|
710
|
+
* none) the STATE.md figures are printed as recorded.
|
|
711
|
+
*/
|
|
712
|
+
function phasePosition(s) {
|
|
713
|
+
const current = s.current_phase;
|
|
714
|
+
const at = current === null ? -1 : s.milestone_phases.findIndex((id) => comparePhaseNum(id, current) === 0);
|
|
715
|
+
if (at >= 0)
|
|
716
|
+
return `Phase ${at + 1} of ${s.milestone_phases.length}`;
|
|
717
|
+
return `Phase ${s.current_phase ?? '?'} of ${s.total_phases ?? '?'}`;
|
|
718
|
+
}
|
|
664
719
|
function progressLine(tail, s) {
|
|
665
720
|
const parts = [];
|
|
666
721
|
if (s.current_phase !== null && s.total_phases !== null) {
|
|
667
|
-
parts.push(
|
|
722
|
+
parts.push(phasePosition(s));
|
|
668
723
|
}
|
|
669
724
|
else if (s.current_phase !== null) {
|
|
670
725
|
parts.push(`Phase ${s.current_phase}`);
|
|
@@ -683,7 +738,7 @@ function progressLine(tail, s) {
|
|
|
683
738
|
function classifyProject(cwd, now = Date.now) {
|
|
684
739
|
const signals = detectSignals(cwd, now);
|
|
685
740
|
const situation = classify(signals);
|
|
686
|
-
const actions = actionsFor(situation, signals);
|
|
741
|
+
const actions = actionsFor(situation, signals, (0, runtime_slash_cjs_1.resolveRuntime)(cwd));
|
|
687
742
|
const recommended = actions.find((a) => a.recommended)?.id ?? 'progress';
|
|
688
743
|
const summary = buildSummary(situation, signals);
|
|
689
744
|
return { situation, recommended, summary, signals, actions };
|
|
@@ -702,6 +757,6 @@ function runSmartEntry(cwd, args, raw) {
|
|
|
702
757
|
return;
|
|
703
758
|
}
|
|
704
759
|
// Human mode: a compact one-liner plus the recommended action.
|
|
705
|
-
const human = `${result.summary}\nRecommended: ${result.recommended} → ${result.actions.find((a) => a.id === result.recommended)?.command ?? '
|
|
760
|
+
const human = `${result.summary}\nRecommended: ${result.recommended} → ${result.actions.find((a) => a.id === result.recommended)?.command ?? (0, runtime_slash_cjs_1.runtimeCommand)(cwd, 'progress')}`;
|
|
706
761
|
output(null, true, human);
|
|
707
762
|
}
|
|
@@ -21,22 +21,23 @@
|
|
|
21
21
|
const fs = require('fs');
|
|
22
22
|
const path = require('path');
|
|
23
23
|
const os = require('os');
|
|
24
|
+
const capabilityRegistry = require('./capability-registry.cjs');
|
|
25
|
+
const { hostBehaviorsFor } = require('./runtime-name-policy.cjs');
|
|
26
|
+
const { resolveConfigHomeFromDescriptor } = require('./runtime-homes.cjs');
|
|
27
|
+
const { resolveActiveRuntime } = require('./runtime-slash.cjs');
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
|
-
* Runtimes whose agent config is static frontmatter/TOML baked at install time
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* and #2093 (kilo).
|
|
30
|
+
* Runtimes whose agent config is static frontmatter/TOML baked at install time,
|
|
31
|
+
* DERIVED from the runtime descriptors (`hostBehaviors.bakesStaticAgentModel`,
|
|
32
|
+
* #5169) instead of a hand-kept list: line id #2256 (opencode), #49/#2256
|
|
33
|
+
* (codex), and #2093 (kilo) declare it, and a new baking runtime does too.
|
|
31
34
|
*/
|
|
32
|
-
const STATIC_FRONTMATTER_RUNTIMES = Object.freeze(
|
|
35
|
+
const STATIC_FRONTMATTER_RUNTIMES = Object.freeze(
|
|
36
|
+
Object.keys(capabilityRegistry.runtimes)
|
|
37
|
+
.filter((id) => hostBehaviorsFor(id).bakesStaticAgentModel === true)
|
|
38
|
+
.sort(),
|
|
39
|
+
);
|
|
33
40
|
|
|
34
|
-
/** Per-runtime `gsd install` flag, for the remediation hint in the warning. */
|
|
35
|
-
const INSTALL_FLAG_BY_RUNTIME = Object.freeze({
|
|
36
|
-
codex: '--codex',
|
|
37
|
-
opencode: '--opencode',
|
|
38
|
-
kilo: '--kilo',
|
|
39
|
-
});
|
|
40
41
|
|
|
41
42
|
const _warnedKeys = new Set();
|
|
42
43
|
|
|
@@ -64,7 +65,7 @@ function formatStaleBakeWarning({ runtime, configPath, configMtimeMs, agentMtime
|
|
|
64
65
|
const signal = detectStaleBake({ runtime, configMtimeMs, agentMtimeMs });
|
|
65
66
|
if (!signal) return '';
|
|
66
67
|
const configDate = new Date(configMtimeMs).toISOString();
|
|
67
|
-
const installFlag =
|
|
68
|
+
const installFlag = `--${runtime}`;
|
|
68
69
|
return [
|
|
69
70
|
`gsd: model config in ${configPath} changed since agents were last baked (${configDate}).`,
|
|
70
71
|
` Static-frontmatter runtime '${runtime}' ignores the new model_overrides`,
|
|
@@ -74,44 +75,27 @@ function formatStaleBakeWarning({ runtime, configPath, configMtimeMs, agentMtime
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
78
|
+
* Resolve the active runtime id for the guard: the SAME chain every consumer of
|
|
79
|
+
* "which runtime is this install" reads — GSD_RUNTIME → config.runtime →
|
|
80
|
+
* per-install `.gsd-runtime` marker → `'claude'` (#5169, #4690). Returns
|
|
81
|
+
* `'claude'` when nothing is declared (the spawn-time default for which the
|
|
82
|
+
* guard is a no-op).
|
|
80
83
|
*/
|
|
81
|
-
function resolveRuntimeFromConfig(config) {
|
|
82
|
-
|
|
83
|
-
&& typeof config.runtime === 'string' && config.runtime) {
|
|
84
|
-
return config.runtime;
|
|
85
|
-
}
|
|
86
|
-
return 'claude';
|
|
84
|
+
function resolveRuntimeFromConfig(config, env = process.env) {
|
|
85
|
+
return resolveActiveRuntime(config, env);
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
/**
|
|
90
|
-
* Resolve the install root for a runtime's agent files
|
|
91
|
-
*
|
|
92
|
-
*
|
|
89
|
+
* Resolve the install root for a runtime's agent files from the runtime
|
|
90
|
+
* descriptor's `configHome` (the same resolution the installer uses), then
|
|
91
|
+
* append `agents` — the installer writes agents to `<configHome>/agents`
|
|
92
|
+
* (plural; #2093). Returns the absolute directory or `null` for runtimes that
|
|
93
|
+
* do not bake a static agent model.
|
|
93
94
|
*/
|
|
94
95
|
function resolveAgentDir(runtime, { env = process.env, homedir = os.homedir } = {}) {
|
|
95
|
-
if (runtime
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// bin/install.js's universal `agentsDest = path.join(targetDir, 'agents')`,
|
|
99
|
-
// verified against a live `--opencode --global` install). The prior
|
|
100
|
-
// singular `agent` never matched the real install output, so this guard's
|
|
101
|
-
// `findOldestAgentMtime` always hit ENOENT and warnIfStaleBake was a
|
|
102
|
-
// silent no-op for opencode in production — discovered while wiring the
|
|
103
|
-
// parallel kilo entry below (same bake mechanism, #2093).
|
|
104
|
-
return path.join(base, 'agents');
|
|
105
|
-
}
|
|
106
|
-
if (runtime === 'kilo') {
|
|
107
|
-
const base = (env.KILO_CONFIG_DIR && String(env.KILO_CONFIG_DIR).trim()) || path.join(homedir(), '.config', 'kilo');
|
|
108
|
-
return path.join(base, 'agents');
|
|
109
|
-
}
|
|
110
|
-
if (runtime === 'codex') {
|
|
111
|
-
const base = (env.CODEX_HOME && String(env.CODEX_HOME).trim()) || path.join(homedir(), '.codex');
|
|
112
|
-
return path.join(base, 'agents');
|
|
113
|
-
}
|
|
114
|
-
return null;
|
|
96
|
+
if (!STATIC_FRONTMATTER_RUNTIMES.includes(runtime)) return null;
|
|
97
|
+
const configHome = capabilityRegistry.runtimes[runtime].runtime.configHome;
|
|
98
|
+
return path.join(resolveConfigHomeFromDescriptor(configHome, { env, home: homedir() }), 'agents');
|
|
115
99
|
}
|
|
116
100
|
|
|
117
101
|
/**
|
|
@@ -168,8 +152,8 @@ function findOldestAgentMtime(runtime, { env = process.env, homedir = os.homedir
|
|
|
168
152
|
for (const entry of entries) {
|
|
169
153
|
if (!entry.isFile()) continue;
|
|
170
154
|
if (!entry.name.startsWith('gsd-')) continue;
|
|
171
|
-
const
|
|
172
|
-
|
|
155
|
+
const bakedExts = hostBehaviorsFor(runtime).bakedAgentFileExtensions;
|
|
156
|
+
const isAgentFile = Array.isArray(bakedExts) && bakedExts.some((ext) => entry.name.endsWith(ext));
|
|
173
157
|
if (!isAgentFile) continue;
|
|
174
158
|
try {
|
|
175
159
|
const st = fsStatSync(path.join(dir, entry.name));
|
|
@@ -209,7 +193,7 @@ function warnIfStaleBake(cwd, options = {}) {
|
|
|
209
193
|
} = options;
|
|
210
194
|
try {
|
|
211
195
|
const resolvedConfig = config || _readRuntimeConfig(cwd, { fsStatSync });
|
|
212
|
-
const runtime = resolveRuntimeFromConfig(resolvedConfig);
|
|
196
|
+
const runtime = resolveRuntimeFromConfig(resolvedConfig, env);
|
|
213
197
|
if (!STATIC_FRONTMATTER_RUNTIMES.includes(runtime)) return false;
|
|
214
198
|
|
|
215
199
|
const dedupKey = `${runtime}::${path.resolve(cwd || '.')}`;
|
|
@@ -73,6 +73,12 @@ exports.buildStateContract = buildStateContract;
|
|
|
73
73
|
exports.publishStateContract = publishStateContract;
|
|
74
74
|
const node_path_1 = __importDefault(require("node:path"));
|
|
75
75
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
76
|
+
// #5060: `phase-status.cjs` is a LOAD-TIME LEAF — no top-level requires of
|
|
77
|
+
// its own (verification.cjs/plan-scan.cjs are required lazily, only inside
|
|
78
|
+
// `phaseStatus()`) — so importing it here at top level does not reopen the
|
|
79
|
+
// documented `state.cjs -> state-contract.cjs -> smart-entry.cjs -> state.cjs`
|
|
80
|
+
// require cycle the file header warns about.
|
|
81
|
+
const phase_status_cjs_1 = require("./phase-status.cjs");
|
|
76
82
|
// ─── Public wire vocabulary ────────────────────────────────────────────────
|
|
77
83
|
exports.STATE_CONTRACT_VERSION = '1.0.0';
|
|
78
84
|
exports.STATE_CONTRACT_FLAVOR = 'core';
|
|
@@ -80,12 +86,14 @@ exports.STATE_CONTRACT_FLAVOR = 'core';
|
|
|
80
86
|
exports.CONTRACT_KEY_ORDER = Object.freeze(['contract', 'flavor', 'milestone', 'phases', 'next', 'updated_at']);
|
|
81
87
|
/** Key order of each emitted phase object — an observable, pinned by test. */
|
|
82
88
|
exports.PHASE_KEY_ORDER = Object.freeze(['number', 'name', 'status']);
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Frozen three-value phase status vocabulary. Conservative in what we send
|
|
91
|
+
* (Postel's Law). #5060: identity-pinned to the Phase Status Module's own
|
|
92
|
+
* `WIRE_STATUS` — this is not a copy, it IS that frozen object, so
|
|
93
|
+
* `state-contract`'s `PHASE_STATUS` and `phase-status.cjs`'s `WIRE_STATUS`
|
|
94
|
+
* can never independently drift.
|
|
95
|
+
*/
|
|
96
|
+
exports.PHASE_STATUS = phase_status_cjs_1.WIRE_STATUS;
|
|
89
97
|
/** Frozen `publishStateContract` result reasons. */
|
|
90
98
|
exports.PUBLISH_REASON = Object.freeze({
|
|
91
99
|
PUBLISHED: 'published',
|
|
@@ -146,17 +154,6 @@ function buildMilestone(cwd) {
|
|
|
146
154
|
}
|
|
147
155
|
// ─── phases: Progress-table (primary) enumerator ───────────────────────────
|
|
148
156
|
const PHASE_CELL_RE = /^(\d+(?:\.\d+)*)\s*[.:)–—-]?\s*(.*)$/;
|
|
149
|
-
function statusFromProgressCell(raw) {
|
|
150
|
-
const normalized = (raw ?? '').trim().toLowerCase().replace(/\s+/g, ' ');
|
|
151
|
-
if (normalized === 'complete')
|
|
152
|
-
return exports.PHASE_STATUS.COMPLETE;
|
|
153
|
-
if (normalized === 'in progress')
|
|
154
|
-
return exports.PHASE_STATUS.IN_PROGRESS;
|
|
155
|
-
// Everything else — 'not started', 'deferred' (design row 12, lossy by
|
|
156
|
-
// design), '', and any unrecognized word — folds to pending. An
|
|
157
|
-
// unrecognized status must never reach the wire as a 4th value.
|
|
158
|
-
return exports.PHASE_STATUS.PENDING;
|
|
159
|
-
}
|
|
160
157
|
function phasesFromProgressTable(table) {
|
|
161
158
|
const { isSentinelPhaseId } = owners();
|
|
162
159
|
const phases = [];
|
|
@@ -169,7 +166,7 @@ function phasesFromProgressTable(table) {
|
|
|
169
166
|
const m = PHASE_CELL_RE.exec(cell);
|
|
170
167
|
const number = m ? m[1] : cell;
|
|
171
168
|
const name = m && m[2].trim().length > 0 ? m[2].trim() : null;
|
|
172
|
-
phases.push({ number, name, status:
|
|
169
|
+
phases.push({ number, name, status: (0, phase_status_cjs_1.parseRoadmapStatusCell)(row['Status']) });
|
|
173
170
|
}
|
|
174
171
|
return phases;
|
|
175
172
|
}
|