@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
|
@@ -223,6 +223,8 @@
|
|
|
223
223
|
* Loop Extension Point Queries (ADR-857 phase 3c):
|
|
224
224
|
* loop render-hooks <point> Resolve + render active Capability hooks at a loop point
|
|
225
225
|
* [--config-dir <path>] [--runtime <r>] [--active-cap <capId>]
|
|
226
|
+
* [--after-fingerprint <phaseDir>] (#5105: skip verify:post
|
|
227
|
+
* steps whose declared artifact already exists in phaseDir)
|
|
226
228
|
* Returns JSON envelope { point, activeHooks, rendered }
|
|
227
229
|
* Valid points: discuss:pre/post, plan:pre/post,
|
|
228
230
|
* execute:pre/wave:pre/wave:post/post, verify:pre/post, ship:pre/post
|
|
@@ -245,6 +247,14 @@
|
|
|
245
247
|
* Import a GSD-2 (.gsd/) project back to GSD v1 (.planning/) format
|
|
246
248
|
*/
|
|
247
249
|
|
|
250
|
+
// #5183: Node's on-disk compile cache, so later runs reuse V8's compiled code
|
|
251
|
+
// for unchanged modules. Only as the entry (a test require() is unaffected),
|
|
252
|
+
// skipped under V8 coverage, optional (Bun stubs it), and never fatal.
|
|
253
|
+
// NODE_DISABLE_COMPILE_CACHE (any value) turns it off.
|
|
254
|
+
if (require.main === module && !process.env.NODE_V8_COVERAGE) {
|
|
255
|
+
try { require('node:module').enableCompileCache?.(); } catch { /* optimization only */ }
|
|
256
|
+
}
|
|
257
|
+
|
|
248
258
|
const fs = require('fs');
|
|
249
259
|
const path = require('path');
|
|
250
260
|
|
|
@@ -276,7 +286,7 @@ try {
|
|
|
276
286
|
|
|
277
287
|
const { ExitError, runMain, resolveContractVersion } = require('./lib/cli-exit.cjs');
|
|
278
288
|
const io = require('./lib/io.cjs');
|
|
279
|
-
const { error, ERROR_REASON, setJsonErrorMode, output, formatDiagnosticToken } = io;
|
|
289
|
+
const { error, ERROR_REASON, setJsonErrorMode, output, formatDiagnosticToken, captureStdoutSyncWrites, resolveAtFileOutput } = io;
|
|
280
290
|
const projectRoot = require('./lib/project-root.cjs');
|
|
281
291
|
// Resolve findProjectRoot lazily at call time rather than binding it at module
|
|
282
292
|
// load. It is sourced from project-root.cjs; a call-time lookup is robust
|
|
@@ -491,6 +501,7 @@ function dispatchCapabilityCommand({ command, args, cwd, raw, error, registry, r
|
|
|
491
501
|
_result = fn({ args, cwd, raw, error });
|
|
492
502
|
} catch (e) {
|
|
493
503
|
if (e instanceof ExitError) throw e; // intentional structured error from the router (honors --json-errors) — propagate untouched
|
|
504
|
+
if (isVerificationStatusError(e)) throw e; // #5118: translated once, centrally, by main()
|
|
494
505
|
error(
|
|
495
506
|
'capability command "' + command + '" router "' + entry.router + '" in module "' + entry.module + '" threw: ' + (e && e.message ? e.message : String(e)),
|
|
496
507
|
ERROR_REASON.SDK_FAIL_FAST,
|
|
@@ -606,6 +617,7 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
606
617
|
_result = fn({ args, cwd, raw, error });
|
|
607
618
|
} catch (e) {
|
|
608
619
|
if (e instanceof ExitError) throw e;
|
|
620
|
+
if (isVerificationStatusError(e)) throw e; // #5118: translated once, centrally, by main()
|
|
609
621
|
error(
|
|
610
622
|
'capability command "' + command + '" router "' + entry.router + '" in module "' + entry.module + '" threw: ' + (e && e.message ? e.message : String(e)),
|
|
611
623
|
ERROR_REASON.SDK_FAIL_FAST,
|
|
@@ -1512,7 +1524,10 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
1512
1524
|
error(`quick-tasks-append: STATE.md not found at ${statePath}`, ERROR_REASON.USAGE);
|
|
1513
1525
|
}
|
|
1514
1526
|
|
|
1515
|
-
|
|
1527
|
+
// #4905: an operator-facing date, so the local calendar day (#2136)
|
|
1528
|
+
// through the clock seam, which honors the GSD_NOW_MS pin (#474).
|
|
1529
|
+
const { realClock } = require('./lib/clock.cjs');
|
|
1530
|
+
const date = realClock.localToday();
|
|
1516
1531
|
const { execGit } = require('./lib/shell-command-projection.cjs');
|
|
1517
1532
|
const hashResult = execGit(['rev-parse', '--short', 'HEAD'], { cwd });
|
|
1518
1533
|
const commit = hashResult.exitCode === 0 && hashResult.stdout ? hashResult.stdout : '—';
|
|
@@ -1578,7 +1593,16 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
1578
1593
|
const fsx = require('node:fs');
|
|
1579
1594
|
const os = require('node:os');
|
|
1580
1595
|
const { REVIEWER_LANES, mergeReviewerLanes } = require('./lib/review-lane-descriptor.cjs');
|
|
1581
|
-
const { resolveLanePlan, resolveLaneEffort, resolveLaneBudget } = require('./lib/review-lane-invocation.cjs');
|
|
1596
|
+
const { resolveLanePlan: resolveLanePlanBase, resolveLaneEffort, resolveLaneBudget } = require('./lib/review-lane-invocation.cjs');
|
|
1597
|
+
// OpenCode 2.x argv differs from 1.x (no --variant; effort rides on the model as `#variant`;
|
|
1598
|
+
// ADR-5331 D5/D8). The generation is probed lazily, only when the opencode lane is resolved.
|
|
1599
|
+
const resolveLanePlan = (laneInput) => {
|
|
1600
|
+
if (!laneInput || !laneInput.lane || laneInput.lane.slug !== 'opencode') return resolveLanePlanBase(laneInput);
|
|
1601
|
+
const ocv = require('./lib/opencode-version.cjs');
|
|
1602
|
+
const adapted = ocv.adaptLaneInputForGeneration(laneInput, ocv.detectOpencodeGeneration().generation);
|
|
1603
|
+
for (const w of adapted.warnings) process.stderr.write('gsd: ' + w + '\n');
|
|
1604
|
+
return ocv.adaptLanePlanForGeneration(resolveLanePlanBase(adapted.input), ocv.detectOpencodeGeneration().generation);
|
|
1605
|
+
};
|
|
1582
1606
|
const modelCatalog = require('./lib/model-catalog.cjs');
|
|
1583
1607
|
const runner = require('./lib/review-lane-runner.cjs');
|
|
1584
1608
|
const cfgLoader = require('./lib/config-loader.cjs');
|
|
@@ -2660,8 +2684,14 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
2660
2684
|
'gsd-executor', readGsdEffectiveModelOverrides(cwd), null);
|
|
2661
2685
|
model = resolveDispatchModelPin('gsd-executor', pinned);
|
|
2662
2686
|
}
|
|
2687
|
+
let orchestratorExec = runtimeEntry?.runtime?.orchestratorExec;
|
|
2688
|
+
if (orchestratorExec && orchestratorExec.cwdFlag === '--dir' && runtimeId === 'opencode') {
|
|
2689
|
+
// OpenCode 2.x `run` has no --dir: bind the worktree through the process cwd (ADR-5331 D5).
|
|
2690
|
+
const ocv = require('./lib/opencode-version.cjs');
|
|
2691
|
+
orchestratorExec = ocv.adaptOrchestratorExecForGeneration(orchestratorExec, ocv.detectOpencodeGeneration().generation);
|
|
2692
|
+
}
|
|
2663
2693
|
const resolution = hostIntegration.resolveOrchestratorExec(
|
|
2664
|
-
|
|
2694
|
+
orchestratorExec,
|
|
2665
2695
|
cwdTarget,
|
|
2666
2696
|
promptArg,
|
|
2667
2697
|
model,
|
|
@@ -2766,6 +2796,63 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
2766
2796
|
};
|
|
2767
2797
|
try {
|
|
2768
2798
|
nodeFs.mkdirSync(sentinelDir, { recursive: true });
|
|
2799
|
+
// Never write through a project-supplied .gsd symlink. Resolve the
|
|
2800
|
+
// directory as well so an ancestor redirect cannot escape this project.
|
|
2801
|
+
if (nodeFs.lstatSync(sentinelDir).isSymbolicLink() ||
|
|
2802
|
+
nodePath.relative(nodeFs.realpathSync(cwd), nodeFs.realpathSync(sentinelDir)) !== '.gsd') {
|
|
2803
|
+
throw new Error('sentinel directory is a symlink or resolves outside the project');
|
|
2804
|
+
}
|
|
2805
|
+
// User projects do not inherit gsd-core's root .gitignore. Ignore this
|
|
2806
|
+
// tool-owned directory locally before writing the first sentinel. An
|
|
2807
|
+
// ordinary ignore-file IO failure must not prevent recording isolation.
|
|
2808
|
+
const ignorePath = nodePath.join(sentinelDir, '.gitignore');
|
|
2809
|
+
try {
|
|
2810
|
+
nodeFs.writeFileSync(ignorePath, '*\n', { flag: 'wx' });
|
|
2811
|
+
} catch (ignoreError) {
|
|
2812
|
+
if (ignoreError.code === 'EEXIST') {
|
|
2813
|
+
// Keep a pre-existing ignore file. A bare '*' already ignores the
|
|
2814
|
+
// whole directory, including this file and the sentinel temp file.
|
|
2815
|
+
// Read through an fd opened without following links where supported;
|
|
2816
|
+
// replace by rename rather than append through the path, so a link
|
|
2817
|
+
// swapped in after the check cannot redirect a write elsewhere.
|
|
2818
|
+
let fd;
|
|
2819
|
+
let ignoreTmpPath;
|
|
2820
|
+
try {
|
|
2821
|
+
if (nodeFs.lstatSync(ignorePath).isSymbolicLink()) {
|
|
2822
|
+
throw new Error('sentinel ignore file is a symlink');
|
|
2823
|
+
}
|
|
2824
|
+
fd = nodeFs.openSync(ignorePath, nodeFs.constants.O_RDONLY | (nodeFs.constants.O_NOFOLLOW || 0));
|
|
2825
|
+
if (!nodeFs.fstatSync(fd).isFile()) throw new Error('sentinel ignore file is not a regular file');
|
|
2826
|
+
const current = nodeFs.readFileSync(fd, 'utf8');
|
|
2827
|
+
nodeFs.closeSync(fd);
|
|
2828
|
+
fd = undefined;
|
|
2829
|
+
if (!current.includes('# gsd-core dispatch sentinel') && !/^\*\r?$/m.test(current)) {
|
|
2830
|
+
const additionalRules = `${current.endsWith('\n') ? '' : '\n'}# gsd-core dispatch sentinel\n` +
|
|
2831
|
+
'/dispatch-isolation-sentinel.json\n' +
|
|
2832
|
+
'/dispatch-isolation-sentinel.json.tmp-*\n' +
|
|
2833
|
+
'/.gitignore\n';
|
|
2834
|
+
ignoreTmpPath = `${ignorePath}.tmp-${process.pid}-${require('crypto').randomBytes(6).toString('hex')}`;
|
|
2835
|
+
nodeFs.writeFileSync(ignoreTmpPath, current + additionalRules, { flag: 'wx' });
|
|
2836
|
+
if (nodeFs.lstatSync(ignorePath).isSymbolicLink()) {
|
|
2837
|
+
throw new Error('sentinel ignore file is a symlink');
|
|
2838
|
+
}
|
|
2839
|
+
nodeFs.renameSync(ignoreTmpPath, ignorePath);
|
|
2840
|
+
ignoreTmpPath = null;
|
|
2841
|
+
}
|
|
2842
|
+
} catch (existingIgnoreError) {
|
|
2843
|
+
if (existingIgnoreError.code === 'ELOOP' || existingIgnoreError.message === 'sentinel ignore file is a symlink') {
|
|
2844
|
+
throw new Error('sentinel ignore file is a symlink');
|
|
2845
|
+
}
|
|
2846
|
+
// Ignore seeding is best-effort; the sentinel is still useful if
|
|
2847
|
+
// this path cannot be read or updated.
|
|
2848
|
+
} finally {
|
|
2849
|
+
if (fd !== undefined) nodeFs.closeSync(fd);
|
|
2850
|
+
if (ignoreTmpPath) {
|
|
2851
|
+
try { nodeFs.unlinkSync(ignoreTmpPath); } catch (_) { /* best-effort cleanup */ }
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2769
2856
|
// Atomic write: unique temp file + rename, so a concurrent reader (a
|
|
2770
2857
|
// guard hook firing mid-write) never observes a partially-written
|
|
2771
2858
|
// sentinel. Unique per-process+time so concurrent orchestrator-worktree
|
|
@@ -3076,8 +3163,13 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
3076
3163
|
const coverage = require('./lib/coverage.cjs');
|
|
3077
3164
|
const options = parseNamedArgsOrExit(args, { valueFlags: ['summary', 'file'], positionals: 2 }, error);
|
|
3078
3165
|
coverage.cmdClassify(cwd, options, raw);
|
|
3166
|
+
} else if (subcommand === 'complete-session') {
|
|
3167
|
+
const uat = require('./lib/uat.cjs');
|
|
3168
|
+
const uatPath = args[2];
|
|
3169
|
+
const options = parseNamedArgsOrExit(args, { valueFlags: ['message'], positionals: 3 }, error);
|
|
3170
|
+
return uat.cmdUatCompleteSession(cwd, uatPath, { message: options.message }, raw);
|
|
3079
3171
|
} else {
|
|
3080
|
-
error('Unknown uat subcommand. Available: render-checkpoint, classify-coverage', ERROR_REASON.SDK_UNKNOWN_COMMAND);
|
|
3172
|
+
error('Unknown uat subcommand. Available: render-checkpoint, classify-coverage, complete-session', ERROR_REASON.SDK_UNKNOWN_COMMAND);
|
|
3081
3173
|
}
|
|
3082
3174
|
}
|
|
3083
3175
|
|
|
@@ -3175,10 +3267,27 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
3175
3267
|
}
|
|
3176
3268
|
loopRuntime = value;
|
|
3177
3269
|
}
|
|
3270
|
+
// --after-fingerprint <phaseDir> (#5105 R2): gate out verify:post
|
|
3271
|
+
// steps whose declared artifact already exists in phaseDir.
|
|
3272
|
+
let loopAfterFingerprint = undefined;
|
|
3273
|
+
const afterFpEqArg = args.find(arg => arg.startsWith('--after-fingerprint='));
|
|
3274
|
+
const afterFpIdx = args.indexOf('--after-fingerprint');
|
|
3275
|
+
if (afterFpEqArg) {
|
|
3276
|
+
const value = afterFpEqArg.slice('--after-fingerprint='.length).trim();
|
|
3277
|
+
if (!value) error('Missing value for --after-fingerprint', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
3278
|
+
loopAfterFingerprint = value;
|
|
3279
|
+
} else if (afterFpIdx !== -1) {
|
|
3280
|
+
const value = args[afterFpIdx + 1];
|
|
3281
|
+
if (!value || value.startsWith('--')) {
|
|
3282
|
+
error('Missing value for --after-fingerprint', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
3283
|
+
}
|
|
3284
|
+
loopAfterFingerprint = value;
|
|
3285
|
+
}
|
|
3178
3286
|
loopResolver.cmdLoopRenderHooks(cwd, args[2], raw, {
|
|
3179
3287
|
configDir: loopConfigDir ? path.resolve(loopConfigDir) : undefined,
|
|
3180
3288
|
activeCap: loopActiveCap,
|
|
3181
3289
|
runtime: loopRuntime,
|
|
3290
|
+
afterFingerprint: loopAfterFingerprint,
|
|
3182
3291
|
});
|
|
3183
3292
|
} else {
|
|
3184
3293
|
error(
|
|
@@ -3720,13 +3829,14 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
3720
3829
|
|| relPath.startsWith('agents/')
|
|
3721
3830
|
|| relPath.startsWith('commands/');
|
|
3722
3831
|
if (isFrontmatterSurface) {
|
|
3723
|
-
|
|
3832
|
+
// The block is the one the one fence owner finds (found while implementing #5105).
|
|
3833
|
+
const found = frontmatter.frontmatterRegion(content);
|
|
3724
3834
|
const missingFields = [];
|
|
3725
|
-
if (!
|
|
3835
|
+
if (!found || !found.terminated) {
|
|
3726
3836
|
missingFields.push('name', 'description');
|
|
3727
3837
|
} else {
|
|
3728
|
-
if (!/^name:\s*\S/m.test(
|
|
3729
|
-
if (!/^description:\s*\S/m.test(
|
|
3838
|
+
if (!/^name:\s*\S/m.test(found.region)) missingFields.push('name');
|
|
3839
|
+
if (!/^description:\s*\S/m.test(found.region)) missingFields.push('description');
|
|
3730
3840
|
}
|
|
3731
3841
|
if (missingFields.length > 0) {
|
|
3732
3842
|
warnings.push({
|
|
@@ -4510,7 +4620,19 @@ function dispatchOverlayCapabilityCommand({ command, args, cwd, raw, error, load
|
|
|
4510
4620
|
}
|
|
4511
4621
|
|
|
4512
4622
|
const roadmapStatus = matchedRow.Status;
|
|
4513
|
-
|
|
4623
|
+
// #5060: normalize the raw Status cell through the Phase Status
|
|
4624
|
+
// Module's `matchRoadmapStatusCell` owner before comparing ranks —
|
|
4625
|
+
// this recognizes a cell with trailing operator prose after its
|
|
4626
|
+
// leading token (e.g. "Complete — shipped") the same way the
|
|
4627
|
+
// ROADMAP writers/readers already do, rather than requiring the
|
|
4628
|
+
// WHOLE cell to equal a bare token. The raw `roadmapStatus` in the
|
|
4629
|
+
// output stays untouched — only the comparison input changes.
|
|
4630
|
+
const { matchRoadmapStatusCell } = require('./lib/phase-status.cjs');
|
|
4631
|
+
const matched = matchRoadmapStatusCell(roadmapStatus);
|
|
4632
|
+
const result = comparePhaseStatus({
|
|
4633
|
+
stateStatus,
|
|
4634
|
+
roadmapStatus: matched ? matched.token.toLowerCase() : roadmapStatus,
|
|
4635
|
+
});
|
|
4514
4636
|
output({
|
|
4515
4637
|
verdict: result.verdict,
|
|
4516
4638
|
phase,
|
|
@@ -5092,6 +5214,28 @@ function resolveMainWorktreeCwd(cwd, deps = {}) {
|
|
|
5092
5214
|
return worktreeRoot;
|
|
5093
5215
|
}
|
|
5094
5216
|
|
|
5217
|
+
// ─── #5118: an out-of-set verification status thrown past a command ─────────
|
|
5218
|
+
// ADR-5057 Phase 4 closed the verification-status vocabulary: a
|
|
5219
|
+
// *-VERIFICATION.md whose frontmatter `status` is outside `passed |
|
|
5220
|
+
// gaps_found | human_needed` is a hard error (verification.cjs's
|
|
5221
|
+
// VerificationStatusError). A command that reads one report directly
|
|
5222
|
+
// (`verification status`, `phase uat-passed`, `phase complete`) lets it throw;
|
|
5223
|
+
// aggregates carry it in their own results and fail themselves. Either way
|
|
5224
|
+
// the CLI fails through the owner's `failOnVerificationStatusError` — the
|
|
5225
|
+
// error's own message and its own `.reason`; nothing here restates either.
|
|
5226
|
+
function isVerificationStatusError(err) {
|
|
5227
|
+
return err instanceof verification.VerificationStatusError;
|
|
5228
|
+
}
|
|
5229
|
+
|
|
5230
|
+
async function captureTranslatingVerificationStatus(run) {
|
|
5231
|
+
try {
|
|
5232
|
+
return await captureStdoutSyncWrites(run);
|
|
5233
|
+
} catch (err) {
|
|
5234
|
+
if (isVerificationStatusError(err)) verification.failOnVerificationStatusError(err);
|
|
5235
|
+
throw err;
|
|
5236
|
+
}
|
|
5237
|
+
}
|
|
5238
|
+
|
|
5095
5239
|
async function main() {
|
|
5096
5240
|
let args = process.argv.slice(2);
|
|
5097
5241
|
|
|
@@ -5357,7 +5501,7 @@ async function main() {
|
|
|
5357
5501
|
// themselves JSON text, so resolving late would make every large result a
|
|
5358
5502
|
// false "output was not JSON" (negative space N8).
|
|
5359
5503
|
if (pickField) {
|
|
5360
|
-
const captured = await
|
|
5504
|
+
const captured = await captureTranslatingVerificationStatus(async () => {
|
|
5361
5505
|
await runCommand(command, args, cwd, raw, defaultValue, originalCommand, workstreamContext, preWorktreeRemapCwd);
|
|
5362
5506
|
});
|
|
5363
5507
|
const resolved = resolveAtFileOutput(captured);
|
|
@@ -5389,58 +5533,15 @@ async function main() {
|
|
|
5389
5533
|
// already resolves this, but the normal path wrote @file: to stdout, forcing
|
|
5390
5534
|
// every workflow to have a bash-specific `if [[ "$INIT" == @file:* ]]` check
|
|
5391
5535
|
// that breaks on PowerShell and other non-bash shells.
|
|
5392
|
-
const captured = await
|
|
5536
|
+
const captured = await captureTranslatingVerificationStatus(async () => {
|
|
5393
5537
|
await runCommand(command, args, cwd, raw, defaultValue, originalCommand, workstreamContext, preWorktreeRemapCwd);
|
|
5394
5538
|
});
|
|
5395
5539
|
fs.writeSync(1, resolveAtFileOutput(captured));
|
|
5396
5540
|
}
|
|
5397
5541
|
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
fs.writeSync = function patchedWriteSync(fd, data, ...rest) {
|
|
5403
|
-
if (fd === 1) {
|
|
5404
|
-
if (Buffer.isBuffer(data)) {
|
|
5405
|
-
captured += data.toString('utf-8');
|
|
5406
|
-
return data.length;
|
|
5407
|
-
}
|
|
5408
|
-
const text = String(data);
|
|
5409
|
-
captured += text;
|
|
5410
|
-
let encoding = 'utf-8';
|
|
5411
|
-
if (typeof rest[1] === 'string') encoding = rest[1];
|
|
5412
|
-
return Buffer.byteLength(text, encoding);
|
|
5413
|
-
}
|
|
5414
|
-
return originalWriteSync.call(fs, fd, data, ...rest);
|
|
5415
|
-
};
|
|
5416
|
-
|
|
5417
|
-
const restore = () => {
|
|
5418
|
-
fs.writeSync = originalWriteSync;
|
|
5419
|
-
};
|
|
5420
|
-
|
|
5421
|
-
return Promise.resolve()
|
|
5422
|
-
.then(() => run())
|
|
5423
|
-
.then(() => {
|
|
5424
|
-
restore();
|
|
5425
|
-
return captured;
|
|
5426
|
-
}, (err) => {
|
|
5427
|
-
restore();
|
|
5428
|
-
// The wrapped command may have written to stdout BEFORE it threw — e.g. a --raw
|
|
5429
|
-
// command that emits a JSON result/error envelope and THEN throws ExitError to set a
|
|
5430
|
-
// non-zero exit code (capability set/disable on an unknown id). Without this flush that
|
|
5431
|
-
// captured output is silently discarded (the success-path flush at the call site never
|
|
5432
|
-
// runs on a throw). Emit it now; the error still propagates so the exit code is preserved.
|
|
5433
|
-
if (captured) {
|
|
5434
|
-
try { originalWriteSync.call(fs, 1, resolveAtFileOutput(captured)); } catch { /* best-effort flush */ }
|
|
5435
|
-
}
|
|
5436
|
-
throw err;
|
|
5437
|
-
});
|
|
5438
|
-
}
|
|
5439
|
-
|
|
5440
|
-
function resolveAtFileOutput(captured) {
|
|
5441
|
-
if (!captured.startsWith('@file:')) return captured;
|
|
5442
|
-
return fs.readFileSync(captured.slice(6), 'utf-8');
|
|
5443
|
-
}
|
|
5542
|
+
// captureStdoutSyncWrites and resolveAtFileOutput moved to src/io.cts
|
|
5543
|
+
// (gsd-core/bin/lib/io.cjs) — the ONE shared pair (#5105 S9, review finding
|
|
5544
|
+
// 7), also used by uat.cts's cmdUatCompleteSession.
|
|
5444
5545
|
|
|
5445
5546
|
// A plain object root/intermediate value — everything else (null, an array,
|
|
5446
5547
|
// a number, a string, a boolean) is treated as non-object for NAMED-key
|
|
@@ -395,6 +395,14 @@ function parseCliWorkstream(args) {
|
|
|
395
395
|
args: args.slice(),
|
|
396
396
|
};
|
|
397
397
|
}
|
|
398
|
+
function workstreamDirectoryExists(cwd, name) {
|
|
399
|
+
try {
|
|
400
|
+
return node_fs_1.default.readdirSync(node_path_1.default.join(planningRoot(cwd), 'workstreams')).includes(name);
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
398
406
|
function resolveActiveWorkstream(cwd, args, env = process.env, deps = {}) {
|
|
399
407
|
const parsed = parseCliWorkstream(args);
|
|
400
408
|
const getStored = deps.getStored || ((dir) => getActiveWorkstream(dir, deps));
|
|
@@ -415,6 +423,13 @@ function resolveActiveWorkstream(cwd, args, env = process.env, deps = {}) {
|
|
|
415
423
|
if (ws && !validateWorkstreamName(ws)) {
|
|
416
424
|
throw new Error('Invalid workstream name: must be alphanumeric, hyphens, underscores, or dots');
|
|
417
425
|
}
|
|
426
|
+
// #4772: a reserved name (`none`) is rejected from every source (--ws, env,
|
|
427
|
+
// pointer) unless a directory of that name already exists (grandfathered).
|
|
428
|
+
// Grandfathering compares the directory listing exactly, so a case-insensitive
|
|
429
|
+
// filesystem (macOS, Windows) cannot let `NONE` through on the strength of `none`.
|
|
430
|
+
if (ws && (0, workstream_name_policy_cjs_1.isReservedWorkstreamName)(ws) && !workstreamDirectoryExists(cwd, ws)) {
|
|
431
|
+
throw new Error((0, workstream_name_policy_cjs_1.reservedWorkstreamNameMessage)(ws, source));
|
|
432
|
+
}
|
|
418
433
|
return {
|
|
419
434
|
ws,
|
|
420
435
|
source,
|
|
@@ -221,13 +221,45 @@ function classifyHeader(normalizedHeader) {
|
|
|
221
221
|
}
|
|
222
222
|
return null;
|
|
223
223
|
}
|
|
224
|
+
// A list item starts with a bullet (-, *, +) or an ordered marker (1. or 1)).
|
|
225
|
+
const LIST_MARKER = /^([-*+]|\d+[.)])\s+/;
|
|
226
|
+
/**
|
|
227
|
+
* Split a section body into one entry per top-level list item (#5227).
|
|
228
|
+
*
|
|
229
|
+
* A line that opens a list item starts a new entry with its marker stripped. Any
|
|
230
|
+
* other non-blank line, and any marker line indented deeper than the first item
|
|
231
|
+
* (a nested sub-bullet), joins the current entry with a single space, so a
|
|
232
|
+
* hard-wrapped item stays one entry. Text before the first marker is its own
|
|
233
|
+
* entry. A block with no list marker at all keeps one entry per line, so a plain
|
|
234
|
+
* `## Status` body still yields its first line.
|
|
235
|
+
*/
|
|
224
236
|
function splitEntries(blockText) {
|
|
225
|
-
|
|
237
|
+
const lines = (typeof blockText === 'string' ? blockText : '')
|
|
226
238
|
.split(/\r?\n/)
|
|
227
|
-
.
|
|
228
|
-
|
|
229
|
-
.map((line) => line.
|
|
230
|
-
|
|
239
|
+
.filter((line) => line.trim() !== '');
|
|
240
|
+
if (!lines.some((line) => LIST_MARKER.test(line.trim())))
|
|
241
|
+
return lines.map((line) => line.trim());
|
|
242
|
+
const entries = [];
|
|
243
|
+
let topIndent = -1;
|
|
244
|
+
let open = false;
|
|
245
|
+
for (const raw of lines) {
|
|
246
|
+
const text = raw.trim();
|
|
247
|
+
const indent = raw.length - raw.trimStart().length;
|
|
248
|
+
const isMarker = LIST_MARKER.test(text);
|
|
249
|
+
if (isMarker && (topIndent < 0 || indent <= topIndent)) {
|
|
250
|
+
if (topIndent < 0)
|
|
251
|
+
topIndent = indent;
|
|
252
|
+
entries.push(text.replace(LIST_MARKER, '').trim());
|
|
253
|
+
open = true;
|
|
254
|
+
}
|
|
255
|
+
else if (open) {
|
|
256
|
+
entries[entries.length - 1] = `${entries[entries.length - 1]} ${text}`;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
entries.push(text);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return entries.filter(Boolean);
|
|
231
263
|
}
|
|
232
264
|
/**
|
|
233
265
|
* Thin adapter: wraps the seam's `collectSections` to produce the same
|
|
@@ -483,7 +483,10 @@ function agentFileExists(agentsDir, name, runtime) {
|
|
|
483
483
|
// kimi requires BOTH the persona yaml and the prompt md (same as checkAgentsInstalled).
|
|
484
484
|
const kimiYaml = node_path_1.default.join(agentsDir, 'subagents', `${name}.yaml`);
|
|
485
485
|
const kimiPrompt = node_path_1.default.join(agentsDir, 'subagents', `${name}.md`);
|
|
486
|
-
|
|
486
|
+
// #5169: descriptor-declared (`hostBehaviors.requiresSubagentPair`); a label
|
|
487
|
+
// that is not a registered runtime declares nothing, so it never requires the pair.
|
|
488
|
+
return (0, runtime_name_policy_cjs_1.hostBehaviorsFor)(runtime).requiresSubagentPair === true
|
|
489
|
+
&& node_fs_1.default.existsSync(kimiYaml) && node_fs_1.default.existsSync(kimiPrompt);
|
|
487
490
|
}
|
|
488
491
|
/**
|
|
489
492
|
* Resolve a per-plan `agent_hint` specialist name to a dispatchable subagent
|