@opengsd/gsd-core 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +12 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-doc-synthesizer.md +2 -4
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +22 -14
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +5 -3
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +23 -2
- package/agents/gsd-plan-checker.md +50 -53
- package/agents/gsd-planner.md +50 -50
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.md +2 -2
- package/agents/gsd-roadmapper.md +15 -11
- package/agents/gsd-ui-checker.md +63 -4
- package/agents/gsd-ui-researcher.md +41 -3
- package/agents/gsd-user-profiler.md +3 -0
- package/agents/gsd-verifier.md +13 -4
- package/bin/install.js +1448 -1103
- package/commands/gsd/code-review.md +1 -1
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/map-codebase.md +1 -1
- package/commands/gsd/mempalace-capture.md +1 -1
- package/commands/gsd/mempalace-recall.md +1 -1
- package/commands/gsd/new-milestone.md +1 -1
- package/commands/gsd/quick.md +9 -5
- package/commands/gsd/review-backlog.md +2 -1
- package/commands/gsd/verify-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +1035 -138
- package/gsd-core/bin/lib/active-workstream-store.cjs +146 -22
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +392 -32
- package/gsd-core/bin/lib/api-coverage.cjs +33 -14
- package/gsd-core/bin/lib/artifacts.cjs +5 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +32 -15
- package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
- package/gsd-core/bin/lib/audit.cjs +1026 -268
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-consent.cjs +149 -15
- package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +845 -130
- package/gsd-core/bin/lib/capability-source.cjs +92 -0
- package/gsd-core/bin/lib/capability-state.cjs +18 -3
- package/gsd-core/bin/lib/capability-trust.cjs +444 -25
- package/gsd-core/bin/lib/capability-validator.cjs +700 -40
- package/gsd-core/bin/lib/capability-writer.cjs +3 -2
- package/gsd-core/bin/lib/check-command-router.cjs +216 -42
- package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +735 -0
- package/gsd-core/bin/lib/command-aliases.cjs +22 -0
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-roster.cjs +44 -1
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +1172 -108
- package/gsd-core/bin/lib/commonjs-marker.cjs +12 -6
- package/gsd-core/bin/lib/complexity-trigger.cjs +1192 -0
- package/gsd-core/bin/lib/config-loader.cjs +187 -23
- package/gsd-core/bin/lib/config.cjs +102 -3
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +208 -33
- package/gsd-core/bin/lib/decisions.cjs +23 -0
- package/gsd-core/bin/lib/edge-probe.cjs +9 -1
- package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
- package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
- package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
- package/gsd-core/bin/lib/frontmatter.cjs +899 -229
- package/gsd-core/bin/lib/gap-checker.cjs +95 -10
- package/gsd-core/bin/lib/git-base-branch.cjs +276 -39
- package/gsd-core/bin/lib/gsd2-import.cjs +10 -1
- package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +149 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +268 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +187 -0
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +451 -0
- package/gsd-core/bin/lib/host-integration.cjs +39 -6
- package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
- package/gsd-core/bin/lib/init-command-router.cjs +118 -21
- package/gsd-core/bin/lib/init.cjs +439 -168
- package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
- package/gsd-core/bin/lib/install-engine.cjs +811 -259
- package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +235 -0
- package/gsd-core/bin/lib/install-profiles.cjs +212 -61
- package/gsd-core/bin/lib/install-scope.cjs +270 -0
- package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
- package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
- package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +148 -38
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +170 -15
- package/gsd-core/bin/lib/learnings.cjs +85 -14
- package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +2 -1
- package/gsd-core/bin/lib/markdown-table.cjs +183 -22
- package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
- package/gsd-core/bin/lib/milestone.cjs +842 -73
- package/gsd-core/bin/lib/model-catalog.cjs +232 -16
- package/gsd-core/bin/lib/model-resolver.cjs +193 -68
- package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/pattern.cjs +122 -0
- package/gsd-core/bin/lib/phase-estimation.cjs +18 -9
- package/gsd-core/bin/lib/phase-id.cjs +514 -40
- package/gsd-core/bin/lib/phase-lifecycle.cjs +52 -19
- package/gsd-core/bin/lib/phase-locator.cjs +262 -34
- package/gsd-core/bin/lib/phase.cjs +1038 -214
- package/gsd-core/bin/lib/plan-dependency-graph.cjs +72 -1
- package/gsd-core/bin/lib/plan-document.cjs +263 -0
- package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
- package/gsd-core/bin/lib/plan-scan.cjs +98 -3
- package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
- package/gsd-core/bin/lib/planning-scope.cjs +31 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +894 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +112 -6
- package/gsd-core/bin/lib/probe-core.cjs +5 -2
- package/gsd-core/bin/lib/profile-output.cjs +1 -1
- package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
- package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
- package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +766 -0
- package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +11 -6
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +22 -13
- package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +421 -66
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
- package/gsd-core/bin/lib/roadmap-command-router.cjs +59 -11
- package/gsd-core/bin/lib/roadmap-parser.cjs +1006 -184
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
- package/gsd-core/bin/lib/roadmap.cjs +442 -96
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +702 -52
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +459 -55
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +69 -3
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +402 -58
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +96 -8
- package/gsd-core/bin/lib/security.cjs +104 -5
- package/gsd-core/bin/lib/shell-command-projection.cjs +342 -7
- package/gsd-core/bin/lib/smart-entry.cjs +133 -23
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +52 -19
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +338 -8
- package/gsd-core/bin/lib/state-md-schema.cjs +221 -0
- package/gsd-core/bin/lib/state-transition.cjs +846 -176
- package/gsd-core/bin/lib/state.cjs +2589 -369
- package/gsd-core/bin/lib/surface.cjs +33 -11
- package/gsd-core/bin/lib/task-command-router.cjs +111 -1
- package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
- package/gsd-core/bin/lib/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/text-lines.cjs +80 -0
- package/gsd-core/bin/lib/token-scanner.cjs +76 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +67 -23
- package/gsd-core/bin/lib/uat.cjs +1761 -167
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +51 -12
- package/gsd-core/bin/lib/unusable-input.cjs +37 -0
- package/gsd-core/bin/lib/update-context.cjs +8 -2
- package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +20 -6
- package/gsd-core/bin/lib/vendor/README.md +75 -0
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
- package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +272 -9
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify.cjs +453 -918
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +53 -32
- package/gsd-core/bin/lib/workstream-inventory.cjs +63 -10
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/workstream.cjs +2 -2
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +341 -18
- package/gsd-core/bin/shared/config-defaults.manifest.json +8 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +12 -1
- package/gsd-core/bin/shared/exit-codes.json +8 -0
- package/gsd-core/bin/shared/exit-codes.sh +20 -0
- package/gsd-core/bin/shared/model-catalog.json +8 -1
- package/gsd-core/references/agent-contracts.md +44 -26
- package/gsd-core/references/api-coverage.md +24 -2
- package/gsd-core/references/autonomous-smart-discuss.md +3 -3
- package/gsd-core/references/checkpoints.md +39 -21
- package/gsd-core/references/context-budget.md +1 -1
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/dispatch-isolation-gate.md +138 -0
- package/gsd-core/references/doc-conflict-engine.md +1 -1
- package/gsd-core/references/edge-probe.md +8 -0
- package/gsd-core/references/execute-mvp-tdd.md +4 -6
- package/gsd-core/references/execute-phase-between-wave-reset.md +15 -14
- package/gsd-core/references/execute-phase-context-guard.md +1 -1
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +17 -11
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-integration.md +5 -5
- package/gsd-core/references/git-planning-commit.md +5 -4
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +61 -2
- package/gsd-core/references/model-profiles.md +12 -4
- package/gsd-core/references/mvp-concepts.md +9 -9
- package/gsd-core/references/nyquist-compliance.md +74 -0
- package/gsd-core/references/offer-next.md +3 -5
- package/gsd-core/references/phase-argument-parsing.md +3 -3
- package/gsd-core/references/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-guidance.md +3 -9
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-preconditions.md +1 -1
- package/gsd-core/references/planner-reviews.md +1 -1
- package/gsd-core/references/planner-revision.md +1 -1
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +44 -13
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +1 -1
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/specless-probe-fallback.md +1 -1
- package/gsd-core/references/tdd.md +1 -3
- package/gsd-core/references/ui-brand.md +65 -21
- package/gsd-core/references/ui-consideration-probe.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +5 -5
- package/gsd-core/references/verifier-phase-gates.md +192 -0
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -17
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/SECURITY.md +3 -3
- package/gsd-core/templates/UI-SPEC.md +25 -3
- package/gsd-core/templates/VALIDATION.md +3 -3
- package/gsd-core/templates/discussion-log.md +1 -1
- package/gsd-core/templates/phase-prompt.md +5 -4
- package/gsd-core/templates/state.md +11 -4
- package/gsd-core/templates/verification-report.md +9 -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 +3 -3
- package/gsd-core/workflows/add-tests.md +3 -8
- package/gsd-core/workflows/add-todo.md +1 -1
- package/gsd-core/workflows/ai-integration-phase.md +13 -20
- package/gsd-core/workflows/audit-fix.md +12 -3
- package/gsd-core/workflows/audit-milestone.md +9 -9
- package/gsd-core/workflows/audit-uat.md +17 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +11 -27
- package/gsd-core/workflows/check-todos.md +1 -1
- package/gsd-core/workflows/cleanup.md +64 -5
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +14 -4
- package/gsd-core/workflows/code-review-fix.md +38 -11
- package/gsd-core/workflows/code-review.md +159 -52
- package/gsd-core/workflows/complete-milestone.md +151 -23
- package/gsd-core/workflows/debug.md +12 -8
- package/gsd-core/workflows/diagnose-issues.md +47 -15
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -8
- package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/text.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +3 -6
- package/gsd-core/workflows/docs-update.md +5 -4
- package/gsd-core/workflows/edit-phase.md +27 -2
- package/gsd-core/workflows/eval-review.md +7 -14
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +142 -15
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +24 -4
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase.md +72 -100
- package/gsd-core/workflows/execute-plan.md +52 -15
- package/gsd-core/workflows/explore.md +131 -4
- package/gsd-core/workflows/extract-learnings.md +1 -1
- package/gsd-core/workflows/fast.md +10 -2
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +5 -5
- package/gsd-core/workflows/health.md +76 -10
- package/gsd-core/workflows/import.md +18 -15
- package/gsd-core/workflows/inbox.md +4 -5
- package/gsd-core/workflows/ingest-docs.md +49 -16
- package/gsd-core/workflows/insert-phase.md +5 -5
- package/gsd-core/workflows/list-seeds.md +5 -3
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +12 -23
- package/gsd-core/workflows/map-codebase.md +1 -1
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +8 -5
- package/gsd-core/workflows/new-milestone.md +22 -29
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +26 -40
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +14 -2
- package/gsd-core/workflows/pause-work.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +3 -3
- package/gsd-core/workflows/plan-phase.md +162 -59
- package/gsd-core/workflows/plan-review-convergence.md +96 -11
- package/gsd-core/workflows/plant-seed.md +2 -2
- package/gsd-core/workflows/pr-branch.md +187 -51
- package/gsd-core/workflows/profile-user.md +16 -14
- package/gsd-core/workflows/progress.md +61 -18
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +5 -7
- package/gsd-core/workflows/quick/steps/quick-verification.md +28 -9
- package/gsd-core/workflows/quick/steps/research-phase.md +4 -6
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick.md +55 -44
- package/gsd-core/workflows/remove-phase.md +4 -4
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +8 -12
- package/gsd-core/workflows/review.md +219 -20
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -1
- package/gsd-core/workflows/settings-advanced.md +7 -9
- package/gsd-core/workflows/settings-integrations.md +64 -31
- package/gsd-core/workflows/settings.md +69 -7
- package/gsd-core/workflows/ship.md +116 -50
- package/gsd-core/workflows/sketch-wrap-up.md +11 -17
- package/gsd-core/workflows/sketch.md +12 -18
- package/gsd-core/workflows/smart-entry.md +3 -5
- package/gsd-core/workflows/spec-phase.md +53 -13
- package/gsd-core/workflows/spike-wrap-up.md +7 -11
- package/gsd-core/workflows/spike.md +20 -31
- package/gsd-core/workflows/stats.md +2 -2
- package/gsd-core/workflows/sync-skills.md +64 -9
- package/gsd-core/workflows/thread.md +11 -7
- package/gsd-core/workflows/transition.md +49 -14
- package/gsd-core/workflows/ui-phase.md +15 -21
- package/gsd-core/workflows/ui-review.md +8 -12
- package/gsd-core/workflows/ultraplan-phase.md +5 -13
- package/gsd-core/workflows/undo.md +8 -16
- package/gsd-core/workflows/update.md +7 -11
- package/gsd-core/workflows/validate-phase.md +3 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +66 -25
- package/hooks/dist/gsd-agent-isolation-guard.js +158 -30
- package/hooks/dist/gsd-check-update-worker.js +56 -13
- package/hooks/dist/gsd-check-update.js +19 -1
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +19 -10
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +2 -3
- package/hooks/dist/gsd-cursor-session-start.js +2 -1
- package/hooks/dist/gsd-cursor-stop.js +2 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +83 -3
- package/hooks/dist/gsd-cursor-subagent-stop.js +6 -3
- package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
- package/hooks/dist/gsd-graphify-update.sh +22 -18
- package/hooks/dist/gsd-node-runner.sh +76 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +37 -27
- package/hooks/dist/gsd-read-guard.js +16 -7
- package/hooks/dist/gsd-read-injection-scanner.js +55 -32
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +231 -24
- package/hooks/dist/gsd-update-banner.js +22 -1
- package/hooks/dist/gsd-validate-commit.sh +80 -6
- package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
- package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
- package/hooks/dist/gsd-workflow-guard.js +162 -46
- package/hooks/dist/gsd-worktree-path-guard.js +36 -21
- package/hooks/dist/gsd-write-guard.js +35 -25
- package/hooks/dist/lib/cli-exit.js +560 -0
- package/hooks/dist/lib/exit-code-registry.js +98 -0
- package/hooks/dist/lib/git-cmd.js +92 -59
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/lib/injection-patterns.js +45 -0
- package/hooks/dist/lib/isolation-deny-reason.js +39 -0
- package/hooks/dist/lib/isolation-sentinel.js +9 -0
- package/hooks/dist/managed-hooks-registry.cjs +3 -0
- package/hooks/gsd-agent-isolation-guard.js +158 -30
- package/hooks/gsd-check-update-worker.js +56 -13
- package/hooks/gsd-check-update.js +19 -1
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +19 -10
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +2 -3
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +83 -3
- package/hooks/gsd-cursor-subagent-stop.js +6 -3
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +76 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +37 -27
- package/hooks/gsd-read-guard.js +16 -7
- package/hooks/gsd-read-injection-scanner.js +55 -32
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +231 -24
- package/hooks/gsd-update-banner.js +22 -1
- package/hooks/gsd-validate-commit.sh +80 -6
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +162 -46
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +92 -59
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +45 -0
- package/hooks/lib/isolation-deny-reason.js +39 -0
- package/hooks/lib/isolation-sentinel.js +9 -0
- package/hooks/managed-hooks-registry.cjs +3 -0
- package/package.json +28 -11
- package/pi/gsd.cjs +19 -5
- package/scripts/base64-scan.sh +74 -12
- package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
- package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
- package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
- package/scripts/build-hooks.js +5 -0
- package/scripts/changeset/lint.cjs +60 -5
- package/scripts/check-alias-drift.cjs +7 -43
- package/scripts/check-contract-drift.cjs +297 -0
- package/scripts/check-glossary-refs.cjs +77 -15
- package/scripts/check-mutation-score-ratchet.cjs +156 -0
- package/scripts/ci-check-job-near-cap.cjs +49 -0
- package/scripts/ci-pr-mergeability.cjs +262 -0
- package/scripts/ci-test-scope.cjs +64 -14
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/command-contract-helpers.cjs +903 -1
- package/scripts/docs-guard-registry.cjs +396 -0
- package/scripts/gen-adr-index.cjs +728 -38
- package/scripts/gen-capability-registry.cjs +11 -21
- package/scripts/gen-context-index.cjs +2 -11
- package/scripts/gen-exit-code-docs.cjs +318 -0
- package/scripts/gen-exit-code-registry.cjs +891 -0
- package/scripts/gen-features.cjs +836 -0
- package/scripts/gen-health-docs.cjs +390 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-inventory-manifest.cjs +50 -4
- package/scripts/gen-loop-host-contract.cjs +138 -25
- package/scripts/gen-registry.cjs +3 -14
- package/scripts/gen-scripts-cli-exit.cjs +185 -0
- package/scripts/gen-state-md-docs.cjs +727 -0
- package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
- package/scripts/lib/alias-drift-families.cjs +46 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +308 -0
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -26
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
- package/scripts/lint-canary-version-leak.cjs +73 -0
- package/scripts/lint-command-contract.cjs +96 -13
- package/scripts/lint-completion-predicate-drift.cjs +933 -0
- package/scripts/lint-completion-ratio-drift.cjs +214 -0
- package/scripts/lint-default-flip-documentation.cjs +193 -0
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +193 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +38 -0
- package/scripts/lint-eslint-glob-coverage.cjs +340 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
- package/scripts/lint-health-diagnostic-rule-table.cjs +461 -0
- package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
- package/scripts/lint-milestone-window-drift.cjs +468 -0
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +492 -0
- package/scripts/lint-plan-count-drift.cjs +318 -0
- package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
- package/scripts/lint-planning-prompt-drift.cjs +471 -0
- package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
- package/scripts/lint-regression-test-names.cjs +15 -13
- package/scripts/lint-removed-but-needed.cjs +488 -0
- package/scripts/lint-seam-enforcement.cjs +182 -0
- package/scripts/lint-slug-derivation-drift.cjs +921 -0
- package/scripts/lint-source-test-name-collision.cjs +241 -0
- package/scripts/lint-state-field-drift.cjs +805 -0
- package/scripts/lint-state-write-path-drift.cjs +950 -0
- package/scripts/lint-test-file-count.allowlist.json +137 -8
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +830 -0
- package/scripts/lint-vendored-deps.cjs +297 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/pr-changed-files.cjs +63 -0
- package/scripts/pr-template-policy.cjs +14 -4
- package/scripts/prompt-injection-scan.sh +100 -14
- package/scripts/require-issue-link-policy.cjs +192 -0
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +24 -7
- package/skills/gsd-autonomous/SKILL.md +0 -1
- package/skills/gsd-code-review/SKILL.md +1 -1
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -2
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-map-codebase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +1 -1
- package/skills/gsd-mempalace-recall/SKILL.md +1 -1
- package/skills/gsd-new-milestone/SKILL.md +1 -1
- package/skills/gsd-next/SKILL.md +0 -1
- package/skills/gsd-plan-phase/SKILL.md +0 -1
- package/skills/gsd-progress/SKILL.md +0 -1
- package/skills/gsd-quick/SKILL.md +9 -5
- package/skills/gsd-review-backlog/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +0 -1
- package/skills/gsd-verify-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -107
- package/gsd-core/workflows/discovery-phase.md +0 -298
- package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
- package/gsd-core/workflows/verify-phase.md +0 -574
- package/scripts/affected-tests-lib.cjs +0 -554
- package/scripts/lint-allow-test-rule-refs.cjs +0 -162
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/run-affected-tests.cjs +0 -7
- package/scripts/run-tests.cjs +0 -1051
package/gsd-core/bin/lib/io.cjs
CHANGED
|
@@ -15,6 +15,9 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
15
15
|
const node_os_1 = __importDefault(require("node:os"));
|
|
16
16
|
const node_path_1 = __importDefault(require("node:path"));
|
|
17
17
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
19
|
+
const cliExitModule = require("./cli-exit.cjs");
|
|
20
|
+
const { setJsonErrorMode, getJsonErrorMode, EXIT_ENVELOPE_REASON, ExitError, setPendingOutcome, projectOutcome, getContractVersion, } = cliExitModule;
|
|
18
21
|
// ─── Temp-file helpers (needed by output()) ──────────────────────────────────
|
|
19
22
|
/**
|
|
20
23
|
* Dedicated GSD temp directory: path.join(os.tmpdir(), 'gsd').
|
|
@@ -134,7 +137,48 @@ function writeAllSync(fd, data) {
|
|
|
134
137
|
function serializeForOutput(result) {
|
|
135
138
|
return JSON.stringify(result, null, 2);
|
|
136
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* A payload-carried error, per ADR-2980's own definition (#3912, ADR-3889
|
|
142
|
+
* §4): `result` is an object carrying a SERIALIZABLE `error` property, in
|
|
143
|
+
* ANY key order — `{ found: false, error }` counts exactly the same as
|
|
144
|
+
* `{ error, found: false }`. The discriminator is a serializable error
|
|
145
|
+
* value, NOT mere key presence: `result.error`'s own truthiness is
|
|
146
|
+
* irrelevant (falsy `0`/`null`/`''` all count), and neither is `result`'s
|
|
147
|
+
* prototype (a plain object literal is all any call site here ever
|
|
148
|
+
* passes) — but `error: undefined` does NOT count, because
|
|
149
|
+
* `JSON.stringify` (the exact serializer `serializeForOutput` uses to
|
|
150
|
+
* build the payload the caller actually receives) drops an object
|
|
151
|
+
* property whose value is `undefined` entirely. A payload built as
|
|
152
|
+
* `{ found: false, error: undefined }` therefore reaches the wire as
|
|
153
|
+
* `{"found":false}` — no error at all — and recording DEGRADED for it
|
|
154
|
+
* would be a false verdict: exit 80 under v2 for output the user sees as
|
|
155
|
+
* clean. `hasOwnProperty` alone is not enough to answer "does this payload
|
|
156
|
+
* declare an error"; it must also survive `JSON.stringify`.
|
|
157
|
+
*/
|
|
158
|
+
function isPayloadCarriedError(result) {
|
|
159
|
+
return typeof result === 'object' && result !== null
|
|
160
|
+
&& Object.prototype.hasOwnProperty.call(result, 'error')
|
|
161
|
+
&& result.error !== undefined;
|
|
162
|
+
}
|
|
137
163
|
function output(result, raw, rawValue) {
|
|
164
|
+
// #3912 (ADR-3889 §4): a payload-carried error declares DEGRADED into the
|
|
165
|
+
// pending-outcome cell runMain reads. This is the ONLY new thing output()
|
|
166
|
+
// does — it still just writes fd 1 and returns; the exit code stays
|
|
167
|
+
// whatever it already was under v1 (DEGRADED projects to 0), and nothing
|
|
168
|
+
// here touches process.exitCode directly.
|
|
169
|
+
//
|
|
170
|
+
// LAST-WRITE-WINS (review fix): a clean (non-error-shaped) payload CLEARS
|
|
171
|
+
// the cell rather than leaving a prior degraded declaration in place. A
|
|
172
|
+
// handler that calls output() more than once per invocation — a
|
|
173
|
+
// diagnostic error payload followed by a clean final payload — must have
|
|
174
|
+
// its LATEST declaration win, not its first: the cell reflects "is a
|
|
175
|
+
// degraded outcome pending right now", not "was one ever declared".
|
|
176
|
+
if (isPayloadCarriedError(result)) {
|
|
177
|
+
setPendingOutcome('DEGRADED');
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
setPendingOutcome(undefined);
|
|
181
|
+
}
|
|
138
182
|
let data;
|
|
139
183
|
if (raw && rawValue !== undefined) {
|
|
140
184
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
@@ -178,7 +222,7 @@ const ERROR_REASON = Object.freeze({
|
|
|
178
222
|
CONFIG_PARSE_FAILED: 'config_parse_failed',
|
|
179
223
|
CONFIG_INVALID_KEY: 'config_invalid_key',
|
|
180
224
|
// SDK / gsd-tools dispatch
|
|
181
|
-
SDK_FAIL_FAST:
|
|
225
|
+
SDK_FAIL_FAST: EXIT_ENVELOPE_REASON,
|
|
182
226
|
SDK_UNKNOWN_COMMAND: 'sdk_unknown_command',
|
|
183
227
|
SDK_MISSING_ARG: 'sdk_missing_arg',
|
|
184
228
|
// workflow / phase
|
|
@@ -186,29 +230,38 @@ const ERROR_REASON = Object.freeze({
|
|
|
186
230
|
PHASE_VERIFICATION_INCOMPLETE: 'phase_verification_incomplete',
|
|
187
231
|
PHASE_PLAN_COVERAGE_INCOMPLETE: 'phase_plan_coverage_incomplete',
|
|
188
232
|
SUMMARY_NO_PLANNING: 'summary_no_planning',
|
|
233
|
+
// #3579: workstream-mode fail-safe guards (init.progress, phase.complete) —
|
|
234
|
+
// distinguishes "no marker/pointer anywhere" from "a marker exists but
|
|
235
|
+
// didn't resolve" so a JSON-error-mode caller can branch on `reason`
|
|
236
|
+
// instead of regexing the human message.
|
|
237
|
+
WORKSTREAM_MODE_NONE_ACTIVE: 'workstream_mode_none_active',
|
|
238
|
+
WORKSTREAM_MODE_MARKER_UNRESOLVED: 'workstream_mode_marker_unresolved',
|
|
189
239
|
// graphify
|
|
190
240
|
GRAPHIFY_NO_GRAPH: 'graphify_no_graph',
|
|
191
241
|
GRAPHIFY_INVALID_QUERY: 'graphify_invalid_query',
|
|
242
|
+
// estimate-calibrate (#3882, ADR-3473 §8.2): the phases directory exists
|
|
243
|
+
// but could not be read — a NON-answer, distinct from a project that
|
|
244
|
+
// genuinely has zero completed phases yet.
|
|
245
|
+
ESTIMATE_PHASES_UNREADABLE: 'estimate_phases_unreadable',
|
|
192
246
|
// hooks
|
|
193
247
|
HOOKS_OPT_OUT: 'hooks_opt_out',
|
|
248
|
+
// commit-docs-guard (#3588)
|
|
249
|
+
COMMIT_DOCS_GUARD_NOT_A_REPO: 'commit_docs_guard_not_a_repo',
|
|
250
|
+
COMMIT_DOCS_GUARD_FOREIGN_HOOK: 'commit_docs_guard_foreign_hook',
|
|
251
|
+
COMMIT_DOCS_GUARD_HOOKS_PATH_SET: 'commit_docs_guard_hooks_path_set',
|
|
194
252
|
// security-scan
|
|
195
253
|
SECURITY_SCAN_FAILED: 'security_scan_failed',
|
|
254
|
+
// --pick (#3365 / #3358, ADR-3473 §8.4): an absent field or non-JSON
|
|
255
|
+
// command output is a failure, never a demotion to an empty answer at
|
|
256
|
+
// exit 0. See .gsd/phase/feat-3884-failure-is-a-value/40-design.md.
|
|
257
|
+
PICK_FIELD_ABSENT: 'pick_field_absent',
|
|
258
|
+
PICK_OUTPUT_NOT_JSON: 'pick_output_not_json',
|
|
196
259
|
// generic
|
|
197
260
|
USAGE: 'usage',
|
|
198
261
|
UNKNOWN: 'unknown',
|
|
199
262
|
});
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
* instead of plain "Error: <message>" text. Set by gsd-tools.cjs when the
|
|
203
|
-
* CLI is invoked with `--json-errors`. Tests opt in to typed-IR error
|
|
204
|
-
* assertions by passing that flag and parsing the JSON.
|
|
205
|
-
*
|
|
206
|
-
* Default off so existing callers and human operators keep their plain-text
|
|
207
|
-
* diagnostics. The structured form is opt-in for tooling and tests (#2974).
|
|
208
|
-
*/
|
|
209
|
-
let _jsonErrorMode = false;
|
|
210
|
-
function setJsonErrorMode(v) { _jsonErrorMode = !!v; }
|
|
211
|
-
function getJsonErrorMode() { return _jsonErrorMode; }
|
|
263
|
+
// setJsonErrorMode / getJsonErrorMode now live in cli-exit.cts (imported above)
|
|
264
|
+
// and are re-exported here for the callers that already import them from io.
|
|
212
265
|
/**
|
|
213
266
|
* Emit an error and exit. When the second argument is provided it must be
|
|
214
267
|
* a value from ERROR_REASON; tests can assert on `result.reason`. When the
|
|
@@ -223,15 +276,116 @@ function getJsonErrorMode() { return _jsonErrorMode; }
|
|
|
223
276
|
* human-readable text. Ignored entirely in plain-text mode — the human
|
|
224
277
|
* message is the only thing an operator sees there.
|
|
225
278
|
*/
|
|
279
|
+
/**
|
|
280
|
+
* Render an UNTRUSTED string for embedding inside a human-readable,
|
|
281
|
+
* plain-text diagnostic (the `'Error: ' + message` line `error()` writes in
|
|
282
|
+
* non-JSON mode).
|
|
283
|
+
*
|
|
284
|
+
* WHY THIS EXISTS AND WHY `error()` DOES NOT DO IT ITSELF: `error()`
|
|
285
|
+
* deliberately writes its `message` argument verbatim — several callers in
|
|
286
|
+
* this repo intentionally emit multi-line diagnostics (e.g. the phase-gate
|
|
287
|
+
* messages), and `error()` has no way to distinguish a legitimate multi-line
|
|
288
|
+
* message from a hostile one, so it must not mangle newlines generically.
|
|
289
|
+
* That means any UNTRUSTED substring a caller interpolates into `message`
|
|
290
|
+
* (an argv token, a JSON key/value read back from a command's own output,
|
|
291
|
+
* etc.) can smuggle its own `\n` and forge a second `Error: ` line on
|
|
292
|
+
* stderr — a caller that parses stderr line-by-line would then see a second,
|
|
293
|
+
* attacker-authored error. Every call site that interpolates untrusted data
|
|
294
|
+
* into a diagnostic MUST pass that substring through this function first;
|
|
295
|
+
* `error()` itself stays a dumb, faithful writer.
|
|
296
|
+
*
|
|
297
|
+
* `JSON.stringify` is the primitive: it wraps the value in quotes and
|
|
298
|
+
* escapes control characters (`\n`, `\r`, `\t`, and the rest of the C0
|
|
299
|
+
* range, plus the quote character itself), so the result can never span
|
|
300
|
+
* more than one line or introduce an unescaped `"`. Callers embedding the
|
|
301
|
+
* result MUST NOT add their own surrounding quotes — that would
|
|
302
|
+
* double-quote it.
|
|
303
|
+
*/
|
|
304
|
+
function formatDiagnosticToken(value) {
|
|
305
|
+
return JSON.stringify(value);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Map an ERROR_REASON wire value onto a declared outcome name (#3912,
|
|
309
|
+
* ADR-3889 §4). Closed over the 25-member enum: every reason gets an
|
|
310
|
+
* explicit entry below, so a 26th member added without a mapping falls
|
|
311
|
+
* through to the `?? 'FAIL'` default rather than silently mis-projecting —
|
|
312
|
+
* and tests/A1 iterates `Object.values(ERROR_REASON)`, so that default is
|
|
313
|
+
* exactly what makes an unmapped addition visible instead of invisible.
|
|
314
|
+
*
|
|
315
|
+
* This function's result is ONLY consulted under v2 (see `error()` below) —
|
|
316
|
+
* it is deliberately never routed through `projectOutcome` under v1, which
|
|
317
|
+
* is what keeps the v1 pin intact (`projectOutcome` treats registered names
|
|
318
|
+
* as version-invariant, so e.g. USAGE would otherwise become 64 today).
|
|
319
|
+
*
|
|
320
|
+
* Each non-FAIL choice below is justified inline; `UNKNOWN` and anything
|
|
321
|
+
* with no clearly better fit stays `FAIL` — the honest default the design
|
|
322
|
+
* calls for, not a guess dressed up as a specific outcome.
|
|
323
|
+
*/
|
|
324
|
+
const REASON_TO_OUTCOME = Object.freeze({
|
|
325
|
+
// Bad argv/subcommand/argument — the caller, not the run, is at fault.
|
|
326
|
+
[ERROR_REASON.CONFIG_INVALID_KEY]: 'USAGE',
|
|
327
|
+
[ERROR_REASON.SDK_UNKNOWN_COMMAND]: 'USAGE',
|
|
328
|
+
[ERROR_REASON.SDK_MISSING_ARG]: 'USAGE',
|
|
329
|
+
[ERROR_REASON.GRAPHIFY_INVALID_QUERY]: 'USAGE',
|
|
330
|
+
[ERROR_REASON.USAGE]: 'USAGE',
|
|
331
|
+
// A specific, named thing does not exist / nothing was there to find —
|
|
332
|
+
// genuine, known emptiness rather than a broken prerequisite.
|
|
333
|
+
[ERROR_REASON.CONFIG_KEY_NOT_FOUND]: 'NO_INPUT',
|
|
334
|
+
[ERROR_REASON.SUMMARY_NO_PLANNING]: 'NO_INPUT',
|
|
335
|
+
[ERROR_REASON.WORKSTREAM_MODE_NONE_ACTIVE]: 'NO_INPUT',
|
|
336
|
+
// A prerequisite is absent, unreadable, or otherwise not in a state the
|
|
337
|
+
// run could proceed from — distinct from NO_INPUT's genuine emptiness.
|
|
338
|
+
[ERROR_REASON.CONFIG_NO_FILE]: 'UNAVAILABLE',
|
|
339
|
+
[ERROR_REASON.CONFIG_PARSE_FAILED]: 'UNAVAILABLE',
|
|
340
|
+
[ERROR_REASON.PHASE_NOT_FOUND]: 'UNAVAILABLE',
|
|
341
|
+
[ERROR_REASON.PHASE_VERIFICATION_INCOMPLETE]: 'UNAVAILABLE',
|
|
342
|
+
[ERROR_REASON.PHASE_PLAN_COVERAGE_INCOMPLETE]: 'UNAVAILABLE',
|
|
343
|
+
// Its own docstring: "a marker exists but didn't resolve" — a broken
|
|
344
|
+
// prerequisite, not the "no marker anywhere" emptiness NONE_ACTIVE covers.
|
|
345
|
+
[ERROR_REASON.WORKSTREAM_MODE_MARKER_UNRESOLVED]: 'UNAVAILABLE',
|
|
346
|
+
[ERROR_REASON.GRAPHIFY_NO_GRAPH]: 'UNAVAILABLE',
|
|
347
|
+
// Its own docstring: "a NON-answer, distinct from a project that
|
|
348
|
+
// genuinely has zero completed phases yet" — UNAVAILABLE, not NO_INPUT.
|
|
349
|
+
[ERROR_REASON.ESTIMATE_PHASES_UNREADABLE]: 'UNAVAILABLE',
|
|
350
|
+
[ERROR_REASON.COMMIT_DOCS_GUARD_NOT_A_REPO]: 'UNAVAILABLE',
|
|
351
|
+
[ERROR_REASON.COMMIT_DOCS_GUARD_FOREIGN_HOOK]: 'UNAVAILABLE',
|
|
352
|
+
[ERROR_REASON.COMMIT_DOCS_GUARD_HOOKS_PATH_SET]: 'UNAVAILABLE',
|
|
353
|
+
// Its own docstring: "an absent field or non-JSON command output is a
|
|
354
|
+
// failure, never a demotion to an empty answer" — the field/output was
|
|
355
|
+
// supposed to be there and was not; a prerequisite of the query failed.
|
|
356
|
+
[ERROR_REASON.PICK_FIELD_ABSENT]: 'UNAVAILABLE',
|
|
357
|
+
[ERROR_REASON.PICK_OUTPUT_NOT_JSON]: 'UNAVAILABLE',
|
|
358
|
+
// Self-failure: the run itself broke, not its inputs.
|
|
359
|
+
[ERROR_REASON.SDK_FAIL_FAST]: 'INTERNAL',
|
|
360
|
+
[ERROR_REASON.SECURITY_SCAN_FAILED]: 'INTERNAL',
|
|
361
|
+
// No clearly better fit — the honest default, per design.
|
|
362
|
+
[ERROR_REASON.HOOKS_OPT_OUT]: 'FAIL',
|
|
363
|
+
[ERROR_REASON.UNKNOWN]: 'FAIL',
|
|
364
|
+
});
|
|
365
|
+
function outcomeForReason(reason) {
|
|
366
|
+
return REASON_TO_OUTCOME[reason] ?? 'FAIL';
|
|
367
|
+
}
|
|
226
368
|
function error(message, reason = ERROR_REASON.UNKNOWN, extra) {
|
|
227
|
-
if (
|
|
369
|
+
if (getJsonErrorMode()) {
|
|
228
370
|
const payload = JSON.stringify({ ok: false, reason, message, ...(extra || {}) }) + '\n';
|
|
229
371
|
writeAllSync(2, payload);
|
|
230
372
|
}
|
|
231
373
|
else {
|
|
232
374
|
writeAllSync(2, 'Error: ' + message + '\n');
|
|
233
375
|
}
|
|
234
|
-
|
|
376
|
+
// #3912 (ADR-3889 §4): the declaration is version-gated HERE, not inside
|
|
377
|
+
// projectOutcome — registered names are version-invariant there, so
|
|
378
|
+
// routing every reason through it unconditionally would change v1 exit
|
|
379
|
+
// codes today (e.g. USAGE -> 64) and break the pin. Under v1 the exit
|
|
380
|
+
// stays ExitError(1) unconditionally, byte-identical to every prior
|
|
381
|
+
// release; only v2 projects the declared outcome through the registry.
|
|
382
|
+
if (getContractVersion() === 'v2') {
|
|
383
|
+
throw new ExitError(projectOutcome(outcomeForReason(reason), 'v2'));
|
|
384
|
+
}
|
|
385
|
+
// No message passed to ExitError: the stderr write above is already done,
|
|
386
|
+
// byte-identical to the prior process.exit(1) behavior, and ExitError with
|
|
387
|
+
// no message means runMain's catch adds nothing further to stderr.
|
|
388
|
+
throw new ExitError(1);
|
|
235
389
|
}
|
|
236
390
|
module.exports = {
|
|
237
391
|
GSD_TEMP_DIR,
|
|
@@ -243,4 +397,5 @@ module.exports = {
|
|
|
243
397
|
setJsonErrorMode,
|
|
244
398
|
getJsonErrorMode,
|
|
245
399
|
error,
|
|
400
|
+
formatDiagnosticToken,
|
|
246
401
|
};
|
|
@@ -21,6 +21,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
21
21
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
22
22
|
const node_path_1 = __importDefault(require("node:path"));
|
|
23
23
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
25
|
+
const phaseLocator = require("./phase-locator.cjs");
|
|
24
26
|
const node_os_1 = __importDefault(require("node:os"));
|
|
25
27
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
26
28
|
const ioMod = require("./io.cjs");
|
|
@@ -145,9 +147,55 @@ function learningsDelete(id, opts) {
|
|
|
145
147
|
node_fs_1.default.unlinkSync(filePath);
|
|
146
148
|
return true;
|
|
147
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* #3683 — resolve which learnings artifact a copy reads. The extractor writes
|
|
152
|
+
* phase-scoped `{PHASE_DIR}/{PADDED}-LEARNINGS.md`; the legacy shape is a
|
|
153
|
+
* project-root `LEARNINGS.md`. The MOST RECENT phase-scoped artifact wins (a
|
|
154
|
+
* gated completion copies the phase it just wrote); the project-root file is
|
|
155
|
+
* the fallback when no phase artifact exists. Returns null when neither shape
|
|
156
|
+
* is present.
|
|
157
|
+
*/
|
|
158
|
+
function resolveLearningsSource(planningDir) {
|
|
159
|
+
let best = null;
|
|
160
|
+
const phasesDir = node_path_1.default.join(planningDir, 'phases');
|
|
161
|
+
// Phase enumeration routes through the sanctioned seam (the #3185 drift
|
|
162
|
+
// guard rejects ad-hoc re-derivations): no cwd → every phase dir in the
|
|
163
|
+
// tree, sentinel dirs excluded, unreadable phases dir already degraded to
|
|
164
|
+
// an empty list by the locator itself.
|
|
165
|
+
const { value: phaseDirNames } = phaseLocator.listMilestonePhaseDirs(phasesDir);
|
|
166
|
+
for (const entry of phaseDirNames) {
|
|
167
|
+
const phaseDir = node_path_1.default.join(phasesDir, entry);
|
|
168
|
+
let files;
|
|
169
|
+
try {
|
|
170
|
+
files = node_fs_1.default.readdirSync(phaseDir);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// An unreadable phase dir (ACL, removal race) must not crash the copy —
|
|
174
|
+
// skip it and keep scanning.
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
for (const f of files) {
|
|
178
|
+
if (!/-LEARNINGS\.md$/i.test(f))
|
|
179
|
+
continue;
|
|
180
|
+
const p = node_path_1.default.join(phaseDir, f);
|
|
181
|
+
try {
|
|
182
|
+
const m = node_fs_1.default.statSync(p).mtimeMs;
|
|
183
|
+
if (best === null || m > best.m)
|
|
184
|
+
best = { p, m };
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (best !== null)
|
|
192
|
+
return best.p;
|
|
193
|
+
const rootPath = node_path_1.default.join(planningDir, 'LEARNINGS.md');
|
|
194
|
+
return node_fs_1.default.existsSync(rootPath) ? rootPath : null;
|
|
195
|
+
}
|
|
148
196
|
function learningsCopyFromProject(planningDir, opts) {
|
|
149
|
-
const learningsPath =
|
|
150
|
-
if (
|
|
197
|
+
const learningsPath = resolveLearningsSource(planningDir);
|
|
198
|
+
if (learningsPath === null) {
|
|
151
199
|
return { total: 0, created: 0, skipped: 0 };
|
|
152
200
|
}
|
|
153
201
|
const content = node_fs_1.default.readFileSync(learningsPath, 'utf-8');
|
|
@@ -167,29 +215,52 @@ function learningsCopyFromProject(planningDir, opts) {
|
|
|
167
215
|
dedupeIndex.set(existing.content_hash, existing.id);
|
|
168
216
|
}
|
|
169
217
|
}
|
|
170
|
-
// Parse markdown: split on ## headings
|
|
218
|
+
// Parse markdown: split on ## category headings.
|
|
219
|
+
// #3683: the real producer (extract-learnings.md write_learnings) writes ##
|
|
220
|
+
// categories containing ### item headings — each item is ONE learning (the
|
|
221
|
+
// store's relevance contract caps injection by count, so category-sized
|
|
222
|
+
// blobs defeat it). A bare ## section with no ### items keeps the legacy
|
|
223
|
+
// single-learning shape.
|
|
171
224
|
const sections = content.split(/^## /m).slice(1); // skip preamble before first ##
|
|
172
225
|
let created = 0;
|
|
173
226
|
let skipped = 0;
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
continue;
|
|
180
|
-
// Extract tags from title (simple: use words as tags)
|
|
181
|
-
const tags = title.toLowerCase().split(/\s+/).filter(w => w.length > 2);
|
|
227
|
+
const writeOne = (title, body, extraTags) => {
|
|
228
|
+
const tags = Array.from(new Set([
|
|
229
|
+
...extraTags,
|
|
230
|
+
...title.toLowerCase().split(/\s+/).filter(w => w.length > 2),
|
|
231
|
+
]));
|
|
182
232
|
const result = learningsWrite({
|
|
183
233
|
source_project: sourceProject,
|
|
184
234
|
learning: body,
|
|
185
235
|
context: title,
|
|
186
236
|
tags,
|
|
187
237
|
}, { ...opts, dedupeIndex });
|
|
188
|
-
if (result.created)
|
|
238
|
+
if (result.created)
|
|
189
239
|
created++;
|
|
190
|
-
|
|
191
|
-
else {
|
|
240
|
+
else
|
|
192
241
|
skipped++;
|
|
242
|
+
};
|
|
243
|
+
for (const section of sections) {
|
|
244
|
+
const lines = section.trim().split('\n');
|
|
245
|
+
const category = lines[0].trim();
|
|
246
|
+
const body = lines.slice(1).join('\n').trim();
|
|
247
|
+
if (!body)
|
|
248
|
+
continue;
|
|
249
|
+
const categoryTag = category.toLowerCase().split(/\s+/)[0] || '';
|
|
250
|
+
// Split into ### items when present; otherwise one learning per section.
|
|
251
|
+
const items = body.split(/^### /m).map(s => s.trim()).filter(s => s.length > 0);
|
|
252
|
+
const hasItemHeadings = /^### /m.test(body);
|
|
253
|
+
if (!hasItemHeadings) {
|
|
254
|
+
writeOne(category, body, categoryTag ? [categoryTag] : []);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
for (const item of items) {
|
|
258
|
+
const itemLines = item.split('\n');
|
|
259
|
+
const title = itemLines[0].trim();
|
|
260
|
+
const itemBody = itemLines.slice(1).join('\n').trim();
|
|
261
|
+
if (!itemBody && !title)
|
|
262
|
+
continue;
|
|
263
|
+
writeOne(title, itemBody || title, categoryTag ? [categoryTag] : []);
|
|
193
264
|
}
|
|
194
265
|
}
|
|
195
266
|
return { total: created + skipped, created, skipped };
|
|
@@ -262,8 +262,14 @@ function planLegacyCleanup(configDirs, opts = {}) {
|
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
// Legacy shared cache (fixed name from the old package)
|
|
266
|
-
|
|
265
|
+
// Legacy shared cache (fixed name from the old package). #3799: under an
|
|
266
|
+
// explicit configDirs override the cache lives under the SCOPE root(s), not
|
|
267
|
+
// the default home — the override means "clean only what this redirected
|
|
268
|
+
// install owns", and the default home's cache belongs to the live install.
|
|
269
|
+
const cacheRoot = (Array.isArray(opts.configDirs) && opts.configDirs.length > 0)
|
|
270
|
+
? opts.configDirs[0]
|
|
271
|
+
: homeDir;
|
|
272
|
+
const legacyCachePath = path.join(cacheRoot, '.cache', 'gsd', 'gsd-update-check.json');
|
|
267
273
|
try {
|
|
268
274
|
const stat = fsMod.statSync(legacyCachePath);
|
|
269
275
|
if (stat.isFile()) {
|
|
@@ -26,6 +26,7 @@ exports.stripTaggedBlocks = stripTaggedBlocks;
|
|
|
26
26
|
exports.replaceSection = replaceSection;
|
|
27
27
|
exports.withSection = withSection;
|
|
28
28
|
exports.deleteSection = deleteSection;
|
|
29
|
+
const pattern_cjs_1 = require("./pattern.cjs");
|
|
29
30
|
// ─── stripFencedCode ──────────────────────────────────────────────────────────
|
|
30
31
|
/**
|
|
31
32
|
* CommonMark-correct fenced-code-block stripper.
|
|
@@ -792,7 +793,7 @@ function extractTaggedBlocks(content, tagName, allowAttributes = false) {
|
|
|
792
793
|
* open>` marks the ACTIVE milestone and must be preserved, not stripped (#557).
|
|
793
794
|
*/
|
|
794
795
|
function taggedBlockPattern(tagName, flags, allowAttributes) {
|
|
795
|
-
const esc =
|
|
796
|
+
const esc = (0, pattern_cjs_1.escapeRegex)(tagName);
|
|
796
797
|
const open = allowAttributes ? `<${esc}(?:\\s[^>]{0,1000})?>` : `<${esc}>`;
|
|
797
798
|
const boundary = allowAttributes ? `<${esc}[\\s>]` : `<${esc}>`;
|
|
798
799
|
return new RegExp(`${open}((?:(?!${boundary})[\\s\\S])*?)</${esc}>`, flags);
|