@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
|
@@ -43,8 +43,9 @@
|
|
|
43
43
|
// authoritative — `none`/`orchestrator-worktree` ALLOW immediately
|
|
44
44
|
// (sequential/orchestrator-managed dispatch is legitimate, not a bug); an
|
|
45
45
|
// absent/stale sentinel falls back to a conservative registry+config check
|
|
46
|
-
// (GSD_RUNTIME env > .planning/config.json `runtime`
|
|
47
|
-
//
|
|
46
|
+
// (GSD_RUNTIME env > .planning/config.json `runtime` > the per-install
|
|
47
|
+
// `.gsd-runtime` marker, #3566 — no confident signal degrades to inert rather
|
|
48
|
+
// than guessing 'claude', see resolveRegistryIsolation)
|
|
48
49
|
// gated additionally by `workflow.use_worktrees` — read directly, in-process,
|
|
49
50
|
// no subprocess spawn.
|
|
50
51
|
//
|
|
@@ -63,6 +64,32 @@ const fs = require('fs');
|
|
|
63
64
|
const path = require('path');
|
|
64
65
|
const os = require('os');
|
|
65
66
|
const { readSentinel, VALID_ISOLATION, extractDispatchIdentifiers, sentinelAppliesToDispatch } = require('./lib/isolation-sentinel.js');
|
|
67
|
+
const { REASON_CODE } = require('./lib/isolation-deny-reason.js');
|
|
68
|
+
const { HOOK_ON_CRASH, allow, deny, crash } = require('./lib/hook-exit.js');
|
|
69
|
+
|
|
70
|
+
// Required at module top, alongside the other ./lib requires — NOT behind
|
|
71
|
+
// ensureRuntimeBuild() below. Terminating on a parse/timeout failure must
|
|
72
|
+
// never depend on the gitignored build artifacts this hook self-heals for
|
|
73
|
+
// its own registry lookups (#3911).
|
|
74
|
+
//
|
|
75
|
+
// This guard's outer catch (main(), below) has always exited 0 (fail open):
|
|
76
|
+
// that outer catch only covers payload PARSING failing before applicability
|
|
77
|
+
// could even be determined (malformed stdin JSON, etc.) — the guard's real
|
|
78
|
+
// fail-closed logic (a GSD project whose dispatch-isolation configuration
|
|
79
|
+
// cannot be verified) is handled separately, inside evaluateDispatch/
|
|
80
|
+
// resolveIsolationState, and already returns a 'block' decision through the
|
|
81
|
+
// normal exit-2 path rather than through this catch. So an unparseable
|
|
82
|
+
// payload has nothing to enforce; allowing it preserves today's behavior
|
|
83
|
+
// exactly.
|
|
84
|
+
const ON_CRASH = HOOK_ON_CRASH.ALLOW;
|
|
85
|
+
// #3582: gsd-core/bin/lib/*.cjs (runtime-name-policy.cjs, capability-registry.cjs
|
|
86
|
+
// below) are tsc build artifacts (ADR-457), gitignored and absent on a raw
|
|
87
|
+
// plugin-marketplace / git-clone install that never ran `npm run build:lib`.
|
|
88
|
+
// Self-heal before the first such require (resolveRegistryIsolation, below) —
|
|
89
|
+
// see ensureRuntimeBuild's own header for the full rationale. This module
|
|
90
|
+
// itself (gsd-core/bin/ensure-runtime-build.cjs) depends on nothing under
|
|
91
|
+
// ./lib, so requiring it here is always safe.
|
|
92
|
+
const { ensureRuntimeBuild, RuntimeBuildError } = require('../gsd-core/bin/ensure-runtime-build.cjs');
|
|
66
93
|
|
|
67
94
|
// No other executor-shaped subagent_type exists in agents/ today
|
|
68
95
|
// (verified: only agents/gsd-executor.md). A Set, not a bare string compare,
|
|
@@ -85,6 +112,42 @@ function parseHarnessFlag(flag) {
|
|
|
85
112
|
return { param: m[1], value: m[2] };
|
|
86
113
|
}
|
|
87
114
|
|
|
115
|
+
// ─── #3897 rung 2: per-install runtime marker, single canonical owner ────────
|
|
116
|
+
// bin/install.js writes `<install>/gsd-core/.gsd-runtime` for EVERY runtime
|
|
117
|
+
// install (#2297), co-located with VERSION. Unlike `~/.gsd/defaults.json` —
|
|
118
|
+
// which is host-wide and names whichever runtime's install ran LAST, the exact
|
|
119
|
+
// leakage #2840's config.cjs change exists to prevent — the marker describes
|
|
120
|
+
// THIS install, which is the property runtime identity needs on a machine
|
|
121
|
+
// with 2+ runtimes. Previously this hook held its own private reader/cache
|
|
122
|
+
// (one of four #3897 found); it now delegates to the single canonical owner,
|
|
123
|
+
// `src/runtime-slash.cts` (compiled to gsd-core/bin/lib/runtime-slash.cjs),
|
|
124
|
+
// reached through `ensureRuntimeBuild()` like every other compiled-lib require
|
|
125
|
+
// in this file (`scripts/lint-hooks-runtime-build-seam.cjs`).
|
|
126
|
+
function readInstallRuntimeMarker() {
|
|
127
|
+
try {
|
|
128
|
+
ensureRuntimeBuild();
|
|
129
|
+
const runtimeSlash = require('../gsd-core/bin/lib/runtime-slash.cjs');
|
|
130
|
+
return runtimeSlash.readInstallRuntimeMarker();
|
|
131
|
+
} catch {
|
|
132
|
+
// Unbuilt runtime library, or any other failure reaching the canonical
|
|
133
|
+
// owner — "no signal from this rung" (N4), never a resolution failure.
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Test seam for the marker rung — forwards to the canonical owner's seam so
|
|
139
|
+
// this hook and runtime-slash.cjs always share one cache (#3897 rung 2).
|
|
140
|
+
function _setInstallRuntimeMarkerForTests(value) {
|
|
141
|
+
try {
|
|
142
|
+
ensureRuntimeBuild();
|
|
143
|
+
const runtimeSlash = require('../gsd-core/bin/lib/runtime-slash.cjs');
|
|
144
|
+
runtimeSlash._setInstallRuntimeMarkerForTests(value);
|
|
145
|
+
} catch {
|
|
146
|
+
// Test-only seam; an unbuilt library here means the test itself will fail
|
|
147
|
+
// downstream, which is a louder and more actionable signal than throwing here.
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
88
151
|
/**
|
|
89
152
|
* Resolve this project's declared `runtime` identity WITHOUT defaulting to
|
|
90
153
|
* 'claude' when no explicit signal exists (#3045 MAJOR 2).
|
|
@@ -100,9 +163,10 @@ function parseHarnessFlag(flag) {
|
|
|
100
163
|
*
|
|
101
164
|
* Returns `{ runtimeId, confident }`. `confident` is true only when an
|
|
102
165
|
* explicit signal exists (GSD_RUNTIME env override, a `runtime` key literally
|
|
103
|
-
* present in config.json,
|
|
104
|
-
* by the installer — see
|
|
105
|
-
*
|
|
166
|
+
* present in config.json, the per-install `.gsd-runtime` marker, or a
|
|
167
|
+
* `runtime` persisted to `~/.gsd/defaults.json` by the installer — see
|
|
168
|
+
* below); false means "cannot determine" and callers must NOT silently
|
|
169
|
+
* substitute 'claude' — see resolveRegistryIsolation.
|
|
106
170
|
*
|
|
107
171
|
* #3045 BLOCKER 2 fix: precedence is GSD_RUNTIME env > config.json `runtime`
|
|
108
172
|
* key > `~/.gsd/defaults.json` `runtime`. The first two are unchanged; the
|
|
@@ -117,6 +181,17 @@ function parseHarnessFlag(flag) {
|
|
|
117
181
|
* (`nativeModelAliases` short-circuits it) and therefore correctly still rely
|
|
118
182
|
* on config.json/env. Reading the installer's own persisted signal makes
|
|
119
183
|
* "confident" the common case instead.
|
|
184
|
+
*
|
|
185
|
+
* #3566: the per-install `.gsd-runtime` marker now sits BETWEEN config.json
|
|
186
|
+
* and defaults.json. defaults.json is host-wide and names whichever runtime
|
|
187
|
+
* installed LAST — on a 2-runtime machine that confidently resolves the WRONG
|
|
188
|
+
* runtime (a Codex install's `runtime:"codex"` leaking into Claude projects),
|
|
189
|
+
* and when the wrong runtime declares no harnessIsolationFlag the guard goes
|
|
190
|
+
* silently inert. The marker describes THIS install (written for every
|
|
191
|
+
* runtime since #2297), which is the source #2840's config.cjs change names
|
|
192
|
+
* as correct. defaults.json stays as the final rung so single-runtime default
|
|
193
|
+
* installs and pre-#2297 installs (no marker on disk) keep the #3045
|
|
194
|
+
* BLOCKER 2 behavior.
|
|
120
195
|
*/
|
|
121
196
|
function resolveRuntimeIdentity(cwd, configPath, resolveRuntimeNameFromCandidates) {
|
|
122
197
|
const envRuntime = resolveRuntimeNameFromCandidates(process.env.GSD_RUNTIME);
|
|
@@ -132,6 +207,13 @@ function resolveRuntimeIdentity(cwd, configPath, resolveRuntimeNameFromCandidate
|
|
|
132
207
|
if (configRuntime) return { runtimeId: configRuntime, confident: true };
|
|
133
208
|
}
|
|
134
209
|
|
|
210
|
+
// #3566: the per-install marker, above the host-wide defaults — see the
|
|
211
|
+
// block comment on readInstallRuntimeMarker. An empty/whitespace-only file
|
|
212
|
+
// or an unknown value degrades exactly like the other rungs (no signal /
|
|
213
|
+
// future-runtime tolerance via resolveRuntimeNameFromCandidates).
|
|
214
|
+
const markerRuntime = resolveRuntimeNameFromCandidates(readInstallRuntimeMarker());
|
|
215
|
+
if (markerRuntime) return { runtimeId: markerRuntime, confident: true };
|
|
216
|
+
|
|
135
217
|
// #3045 BLOCKER 2: fall back to the installer-persisted default. Read
|
|
136
218
|
// defensively — an absent/corrupt/non-object defaults.json is "no signal",
|
|
137
219
|
// never a resolution failure (this function only ever throws for the
|
|
@@ -183,6 +265,15 @@ function resolveHarnessFlag(runtimeId, runtimes) {
|
|
|
183
265
|
* run, e.g. a manual Agent() call before any sentinel has been written).
|
|
184
266
|
*/
|
|
185
267
|
function resolveRegistryIsolation(cwd, configPath) {
|
|
268
|
+
// #3582: self-heal the compiled runtime library BEFORE either require
|
|
269
|
+
// below — this is the only reaching path to both (resolveRegistryIsolation
|
|
270
|
+
// is the sole caller of each), so one call here covers both. Throws
|
|
271
|
+
// RuntimeBuildError on an unbuildable tree; the caller (resolveIsolationState)
|
|
272
|
+
// already wraps this whole function in try/catch and folds any error into
|
|
273
|
+
// its fail-closed `error` result — evaluateDispatch below distinguishes a
|
|
274
|
+
// RuntimeBuildError there so it surfaces this seam's actionable message
|
|
275
|
+
// instead of being misreported as an unreadable config.json (#3050 lesson).
|
|
276
|
+
ensureRuntimeBuild();
|
|
186
277
|
const { resolveRuntimeNameFromCandidates } = require('../gsd-core/bin/lib/runtime-name-policy.cjs');
|
|
187
278
|
const { runtimes } = require('../gsd-core/bin/lib/capability-registry.cjs');
|
|
188
279
|
|
|
@@ -208,18 +299,40 @@ function resolveRegistryIsolation(cwd, configPath) {
|
|
|
208
299
|
|
|
209
300
|
if (isolation === 'harness-worktree') {
|
|
210
301
|
let useWorktrees = true;
|
|
302
|
+
// #3972: the opt-out read shares the ONE owner every other
|
|
303
|
+
// isolation-deciding surface uses — planning-workspace's
|
|
304
|
+
// worktreesOptedOut ladder (scoped own-key wins; root inherited under
|
|
305
|
+
// the GSD_WORKSTREAM gate; strict === false). A flat single-file read
|
|
306
|
+
// here made a workstream-LOCAL opt-out invisible, so the sentinel-absent
|
|
307
|
+
// fallback denied a sequential dispatch the config explicitly allowed.
|
|
308
|
+
// Reached through ensureRuntimeBuild() like every other compiled-lib
|
|
309
|
+
// require in this file (scripts/lint-hooks-runtime-build-seam.cjs); if
|
|
310
|
+
// the library is unreachable the flat-root read below remains as the
|
|
311
|
+
// degraded fallback — today's behavior, never worse.
|
|
312
|
+
let ladderAnswered = false;
|
|
211
313
|
try {
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
useWorktrees = false;
|
|
217
|
-
}
|
|
314
|
+
ensureRuntimeBuild();
|
|
315
|
+
const { worktreesOptedOut } = require('../gsd-core/bin/lib/planning-workspace.cjs');
|
|
316
|
+
useWorktrees = !worktreesOptedOut(cwd);
|
|
317
|
+
ladderAnswered = true;
|
|
218
318
|
} catch {
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
|
|
222
|
-
|
|
319
|
+
// Unbuilt runtime library or a ladder failure — fall through to the
|
|
320
|
+
// legacy flat-root read (conservative: keep enforcing).
|
|
321
|
+
}
|
|
322
|
+
if (!ladderAnswered) {
|
|
323
|
+
try {
|
|
324
|
+
const raw = fs.readFileSync(configPath, 'utf-8');
|
|
325
|
+
const parsedCfg = JSON.parse(raw);
|
|
326
|
+
if (parsedCfg && typeof parsedCfg === 'object' && parsedCfg.workflow &&
|
|
327
|
+
typeof parsedCfg.workflow === 'object' && parsedCfg.workflow.use_worktrees === false) {
|
|
328
|
+
useWorktrees = false;
|
|
329
|
+
}
|
|
330
|
+
} catch {
|
|
331
|
+
// Unreadable config already propagated to the outer caller's catch
|
|
332
|
+
// before this point in practice (resolveRuntimeIdentity reads it
|
|
333
|
+
// first); tolerate defensively and keep the conservative (enforce)
|
|
334
|
+
// default rather than silently disabling the guard.
|
|
335
|
+
}
|
|
223
336
|
}
|
|
224
337
|
if (!useWorktrees) isolation = 'none';
|
|
225
338
|
}
|
|
@@ -360,13 +473,27 @@ function evaluateDispatch(data, { clock = Date } = {}) {
|
|
|
360
473
|
if (!state.gsdProject) return { action: 'allow' };
|
|
361
474
|
|
|
362
475
|
if (state.error) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
476
|
+
// #3582: a missing/unbuildable compiled runtime library (RuntimeBuildError,
|
|
477
|
+
// thrown by ensureRuntimeBuild in resolveRegistryIsolation) is a DIFFERENT,
|
|
478
|
+
// actionable failure from an unreadable/unparsable config.json — surface
|
|
479
|
+
// its own message instead of misreporting it as the generic
|
|
480
|
+
// "could not read or resolve ... configuration" text (the exact #3050
|
|
481
|
+
// misreport this issue exists to fix). Both cases still fail closed
|
|
482
|
+
// (block); only the message differs.
|
|
483
|
+
const isBuildFailure = state.error instanceof RuntimeBuildError;
|
|
484
|
+
const reason = isBuildFailure
|
|
485
|
+
? `Agent isolation guard: cannot resolve this project's dispatch-isolation ` +
|
|
486
|
+
`configuration because the GSD runtime library failed to self-build. ` +
|
|
487
|
+
`${state.error.message} Refusing to dispatch subagent_type="${subagentType}" until ` +
|
|
488
|
+
`the runtime library is built — a guard that cannot verify must not answer "safe" ` +
|
|
489
|
+
`(#3050).`
|
|
490
|
+
: `Agent isolation guard: could not read or resolve this project's dispatch-isolation ` +
|
|
491
|
+
`configuration ('.planning/config.json' under '${cwd}'). Refusing to dispatch ` +
|
|
492
|
+
`subagent_type="${subagentType}" without being able to verify whether isolation is ` +
|
|
493
|
+
`required — a guard that cannot verify must not answer "safe" (#3050). Retry once the ` +
|
|
494
|
+
`project configuration is readable.`;
|
|
495
|
+
const reasonCode = isBuildFailure ? REASON_CODE.RUNTIME_BUILD_FAILED : REASON_CODE.CONFIG_UNREADABLE;
|
|
496
|
+
return { action: 'block', reason, reasonCode };
|
|
370
497
|
}
|
|
371
498
|
|
|
372
499
|
if (state.isolation !== 'harness-worktree') return { action: 'allow' };
|
|
@@ -382,13 +509,13 @@ function evaluateDispatch(data, { clock = Date } = {}) {
|
|
|
382
509
|
`${parsed.param}="${parsed.value}". Add ${parsed.param}="${parsed.value}" to the Agent() ` +
|
|
383
510
|
`call so the executor runs in an isolated worktree instead of the primary checkout ` +
|
|
384
511
|
`(gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md).`;
|
|
385
|
-
return { action: 'block', reason };
|
|
512
|
+
return { action: 'block', reason, reasonCode: REASON_CODE.HARNESS_FLAG_MISSING };
|
|
386
513
|
}
|
|
387
514
|
|
|
388
515
|
/* istanbul ignore next -- stdin adapter, exercised via spawnSync in tests */
|
|
389
516
|
function main() {
|
|
390
517
|
let input = '';
|
|
391
|
-
const stdinTimeout = setTimeout(() =>
|
|
518
|
+
const stdinTimeout = setTimeout(() => allow(undefined), 3000);
|
|
392
519
|
process.stdin.setEncoding('utf8');
|
|
393
520
|
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
394
521
|
process.stdin.on('end', () => {
|
|
@@ -397,19 +524,19 @@ function main() {
|
|
|
397
524
|
const data = JSON.parse(input);
|
|
398
525
|
const decision = evaluateDispatch(data);
|
|
399
526
|
if (decision.action === 'block') {
|
|
400
|
-
const out = { decision: 'block', reason: decision.reason };
|
|
401
|
-
process.stdout.write(JSON.stringify(out));
|
|
527
|
+
const out = { decision: 'block', reason: decision.reason, reason_code: decision.reasonCode };
|
|
402
528
|
// Kimi feeds stderr (not stdout) back to the model on exit 2.
|
|
403
|
-
|
|
404
|
-
process.exit(2);
|
|
529
|
+
deny(out, decision.reason);
|
|
405
530
|
}
|
|
406
|
-
|
|
531
|
+
allow(undefined);
|
|
407
532
|
} catch {
|
|
408
533
|
// Silent fail — never block valid tool calls due to hook errors
|
|
409
534
|
// (malformed payload, etc.). This is distinct from resolveIsolationState's
|
|
410
535
|
// internal error handling, which DOES deny — this outer catch only
|
|
411
536
|
// covers payload parsing before applicability could even be determined.
|
|
412
|
-
|
|
537
|
+
// ON_CRASH is declared ALLOW at module top: this preserves today's
|
|
538
|
+
// exit(0) fail-open behavior exactly (#3911).
|
|
539
|
+
crash(ON_CRASH, undefined);
|
|
413
540
|
}
|
|
414
541
|
});
|
|
415
542
|
}
|
|
@@ -425,4 +552,5 @@ module.exports = {
|
|
|
425
552
|
resolveHarnessFlag,
|
|
426
553
|
resolveRegistryIsolation,
|
|
427
554
|
parseHarnessFlag,
|
|
555
|
+
_setInstallRuntimeMarkerForTests,
|
|
428
556
|
};
|
|
@@ -11,18 +11,61 @@
|
|
|
11
11
|
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
const path = require('path');
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
|
|
15
|
+
// #3582: gsd-core/bin/lib/semver-compare.cjs and package-identity.cjs (and,
|
|
16
|
+
// transitively, check-latest-version.cjs's own gsd-core/bin/lib/cli-exit.cjs
|
|
17
|
+
// + shell-command-projection.cjs) are tsc build artifacts (ADR-457),
|
|
18
|
+
// gitignored and absent on a raw plugin-marketplace / git-clone install that
|
|
19
|
+
// never ran `npm run build:lib`. This worker is a DETACHED SessionStart
|
|
20
|
+
// background process (spawned with stdio: 'ignore') — a build failure here
|
|
21
|
+
// must DEGRADE to the no-signal fallbacks below (mirroring the
|
|
22
|
+
// managed-hooks-registry.cjs degrade just below) so the worker still runs to
|
|
23
|
+
// completion and writes a result cache record, rather than dying silently
|
|
24
|
+
// with no visible signal and no cache-file write at all.
|
|
25
|
+
//
|
|
26
|
+
// This try/require/ensureRuntimeBuild/require/catch shape repeats (with
|
|
27
|
+
// different destructured names) in hooks/gsd-check-update.js and
|
|
28
|
+
// hooks/gsd-update-banner.js. It is deliberately NOT extracted into a shared
|
|
29
|
+
// hooks/lib/ helper: scripts/lint-hooks-runtime-build-seam.cjs enforces this
|
|
30
|
+
// exact seam textually, PER FILE — it greps each hooks/ file for its OWN
|
|
31
|
+
// literal `require('.../ensure-runtime-build.cjs')` + `ensureRuntimeBuild(`
|
|
32
|
+
// call co-occurring with its OWN literal `require('.../gsd-core/bin/lib/*.cjs')`.
|
|
33
|
+
// A generic helper taking the compiled module's path as a variable would move
|
|
34
|
+
// the literal compiled-lib require OUT of this file and into the helper,
|
|
35
|
+
// called with a non-literal argument — the scan's regex (see that script's
|
|
36
|
+
// "Known limitations") cannot see a require() called with a variable, so this
|
|
37
|
+
// file would then read as "requires nothing" and the lint would stop
|
|
38
|
+
// protecting it. A ceremony-only helper (just the ensureRuntimeBuild call,
|
|
39
|
+
// each caller keeping its own literal compiled-lib require) fails the SAME
|
|
40
|
+
// way from the other side: it would remove this file's own literal
|
|
41
|
+
// `require('.../ensure-runtime-build.cjs')` + `ensureRuntimeBuild(` call,
|
|
42
|
+
// which the lint also requires to be textually present in THIS file. Either
|
|
43
|
+
// shape needs the lint script itself widened to special-case the helper,
|
|
44
|
+
// which is a bigger, riskier change than the ~6 duplicated lines it would
|
|
45
|
+
// save; kept inline instead.
|
|
46
|
+
let isSemverNewer = () => false;
|
|
47
|
+
let checkLatestVersion = () => ({ ok: false });
|
|
48
|
+
let PACKAGE_NAME = null;
|
|
49
|
+
try {
|
|
50
|
+
const { ensureRuntimeBuild } = require('../gsd-core/bin/ensure-runtime-build.cjs');
|
|
51
|
+
ensureRuntimeBuild();
|
|
52
|
+
({ isSemverNewer } = require('../gsd-core/bin/lib/semver-compare.cjs'));
|
|
53
|
+
// Latest-version lookup is delegated to the single deterministic adapter
|
|
54
|
+
// (#498). checkLatestVersion() owns the npm-view call, the timeout/semver
|
|
55
|
+
// policy, and the package name — sourced from the baked Package Identity seam.
|
|
56
|
+
// The previous `require('../package.json').name` (#378) never yielded a name in
|
|
57
|
+
// the installed tree — at the time it resolved to the synthetic
|
|
58
|
+
// {"type":"commonjs"} marker GSD wrote at the config root, which has no `.name`,
|
|
59
|
+
// so the background check never reported updates. Since #2544 GSD writes no
|
|
60
|
+
// marker there at all, so that require would now fail to resolve outright.
|
|
61
|
+
// Either way the name must come from the baked seam, never a walk-up.
|
|
62
|
+
({ checkLatestVersion } = require('../gsd-core/bin/check-latest-version.cjs'));
|
|
63
|
+
({ PACKAGE_NAME } = require('../gsd-core/bin/lib/package-identity.cjs'));
|
|
64
|
+
} catch (e) {
|
|
65
|
+
// Runtime library missing/broken and could not self-build — degrade to the
|
|
66
|
+
// no-signal fallbacks declared above; the worker still writes a result
|
|
67
|
+
// cache record (package_name: null, update_available: false).
|
|
68
|
+
}
|
|
26
69
|
// Authoritative list of managed hooks — shared with tests to retire source-grep
|
|
27
70
|
// assertions (pending-migration-to-typed-ir [#455]).
|
|
28
71
|
// NOTE: managed-hooks-registry.cjs must be in HOOKS_TO_COPY (scripts/build-hooks.js)
|
|
@@ -63,7 +106,7 @@ try {
|
|
|
63
106
|
// (e.g., gsd-intel-*.js) must be ignored to avoid permanent stale warnings (#1750)
|
|
64
107
|
// MANAGED_HOOKS is imported from ./managed-hooks-registry.cjs above.
|
|
65
108
|
|
|
66
|
-
|
|
109
|
+
const staleHooks = [];
|
|
67
110
|
if (configDir) {
|
|
68
111
|
// #3023: the bundle's directory name is runtime-descriptor-driven (pi stages
|
|
69
112
|
// it as `gsd-hooks/`), so deriving it as `<configDir>/hooks` silently scanned
|
|
@@ -8,7 +8,25 @@ const path = require('path');
|
|
|
8
8
|
const os = require('os');
|
|
9
9
|
const { spawn } = require('child_process');
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
// #3582: gsd-core/bin/lib/package-identity.cjs is a tsc build artifact
|
|
12
|
+
// (ADR-457), gitignored and absent on a raw plugin-marketplace / git-clone
|
|
13
|
+
// install that never ran `npm run build:lib`. This SessionStart hook must
|
|
14
|
+
// DEGRADE (fall back to a generic cache filename) rather than crash session
|
|
15
|
+
// start. gsd-check-update-worker.js — the process this hook spawns — degrades
|
|
16
|
+
// identically and independently, so the shared fallback literal keeps the
|
|
17
|
+
// cache path consistent between writer and reader even in the (rare)
|
|
18
|
+
// doubly-degraded case. This try/require/ensureRuntimeBuild/require/catch
|
|
19
|
+
// shape is deliberately duplicated (not extracted to hooks/lib/) — see
|
|
20
|
+
// gsd-check-update-worker.js's identical #3582 comment for why.
|
|
21
|
+
let updateCacheFileName = 'gsd-update-check.json';
|
|
22
|
+
try {
|
|
23
|
+
const { ensureRuntimeBuild } = require('../gsd-core/bin/ensure-runtime-build.cjs');
|
|
24
|
+
ensureRuntimeBuild();
|
|
25
|
+
({ updateCacheFileName } = require('../gsd-core/bin/lib/package-identity.cjs'));
|
|
26
|
+
} catch (e) {
|
|
27
|
+
// Runtime library missing/broken and could not self-build — degrade to the
|
|
28
|
+
// fallback filename above rather than crash the SessionStart hook.
|
|
29
|
+
}
|
|
12
30
|
|
|
13
31
|
const homeDir = os.homedir();
|
|
14
32
|
const cwd = process.cwd();
|
|
@@ -20,11 +20,17 @@
|
|
|
20
20
|
|
|
21
21
|
const fs = require('fs');
|
|
22
22
|
const path = require('path');
|
|
23
|
+
const { HOOK_ON_CRASH, allow, crash } = require('./lib/hook-exit.js');
|
|
24
|
+
|
|
25
|
+
// This hook only injects an advisory config-reload summary; a crash mid-parse
|
|
26
|
+
// must not block the session or the FileChanged event that triggered it — the
|
|
27
|
+
// agent simply keeps using the config context it already had (#3911).
|
|
28
|
+
const ON_CRASH = HOOK_ON_CRASH.ALLOW;
|
|
23
29
|
|
|
24
30
|
let input = '';
|
|
25
31
|
// Timeout guard: if stdin does not close within 8s exit silently rather than
|
|
26
32
|
// hanging until Claude Code kills the process and reports "hook error".
|
|
27
|
-
const stdinTimeout = setTimeout(() =>
|
|
33
|
+
const stdinTimeout = setTimeout(() => allow(undefined), 8000);
|
|
28
34
|
process.stdin.setEncoding('utf8');
|
|
29
35
|
process.stdin.on('data', chunk => (input += chunk));
|
|
30
36
|
process.stdin.on('end', () => {
|
|
@@ -42,24 +48,23 @@ process.stdin.on('end', () => {
|
|
|
42
48
|
// inject spurious additionalContext.
|
|
43
49
|
const basename = path.basename(filePath);
|
|
44
50
|
if (basename !== 'config.json') {
|
|
45
|
-
|
|
51
|
+
allow(undefined);
|
|
46
52
|
}
|
|
47
53
|
const expectedPath = path.resolve(cwd, '.planning', 'config.json');
|
|
48
54
|
if (path.resolve(filePath) !== expectedPath) {
|
|
49
|
-
|
|
55
|
+
allow(undefined);
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
// On unlink (deletion) emit a brief notice and exit
|
|
53
59
|
if (event === 'unlink') {
|
|
54
|
-
|
|
60
|
+
allow({
|
|
55
61
|
hookSpecificOutput: {
|
|
56
62
|
hookEventName: 'FileChanged',
|
|
57
63
|
additionalContext:
|
|
58
64
|
'GSD config (.planning/config.json) was deleted. ' +
|
|
59
65
|
'Falling back to built-in defaults for this session.',
|
|
60
66
|
},
|
|
61
|
-
})
|
|
62
|
-
process.exit(0);
|
|
67
|
+
});
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
// Read the updated config file
|
|
@@ -68,17 +73,16 @@ process.stdin.on('end', () => {
|
|
|
68
73
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
69
74
|
config = JSON.parse(raw);
|
|
70
75
|
} catch (e) {
|
|
71
|
-
if (e && e.code === 'ENOENT')
|
|
76
|
+
if (e && e.code === 'ENOENT') allow(undefined);
|
|
72
77
|
// Malformed JSON — inform the agent without crashing
|
|
73
|
-
|
|
78
|
+
allow({
|
|
74
79
|
hookSpecificOutput: {
|
|
75
80
|
hookEventName: 'FileChanged',
|
|
76
81
|
additionalContext:
|
|
77
82
|
'GSD config (.planning/config.json) was modified but could not be parsed. ' +
|
|
78
83
|
'Check the file for JSON syntax errors.',
|
|
79
84
|
},
|
|
80
|
-
})
|
|
81
|
-
process.exit(0);
|
|
85
|
+
});
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
// Build a concise summary of key config fields the agent cares about
|
|
@@ -127,7 +131,9 @@ process.stdin.on('end', () => {
|
|
|
127
131
|
},
|
|
128
132
|
}));
|
|
129
133
|
} catch (e) {
|
|
130
|
-
// Silent fail — never block the session on a config reload error
|
|
131
|
-
|
|
134
|
+
// Silent fail — never block the session on a config reload error.
|
|
135
|
+
// ON_CRASH is declared ALLOW at module top: this preserves today's
|
|
136
|
+
// exit(0) fail-open behavior exactly (#3911).
|
|
137
|
+
crash(ON_CRASH, undefined);
|
|
132
138
|
}
|
|
133
139
|
});
|
|
@@ -22,6 +22,13 @@ const fs = require('fs');
|
|
|
22
22
|
const os = require('os');
|
|
23
23
|
const path = require('path');
|
|
24
24
|
const { spawn } = require('child_process');
|
|
25
|
+
const { HOOK_ON_CRASH, allow, crash } = require('./lib/hook-exit.js');
|
|
26
|
+
|
|
27
|
+
// This hook only injects an advisory context-usage warning; it never blocks
|
|
28
|
+
// the tool call it rides in on. A crash here (e.g. a malformed bridge file)
|
|
29
|
+
// must not turn a PostToolUse advisory into a blocked tool call — losing a
|
|
30
|
+
// context warning is far cheaper than stalling the agent's work (#3911).
|
|
31
|
+
const ON_CRASH = HOOK_ON_CRASH.ALLOW;
|
|
25
32
|
|
|
26
33
|
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35%
|
|
27
34
|
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25%
|
|
@@ -33,7 +40,7 @@ let input = '';
|
|
|
33
40
|
// Windows/Git Bash, or slow Claude Code piping during large outputs),
|
|
34
41
|
// exit silently instead of hanging until Claude Code kills the process
|
|
35
42
|
// and reports "hook error". See #775, #1162.
|
|
36
|
-
const stdinTimeout = setTimeout(() =>
|
|
43
|
+
const stdinTimeout = setTimeout(() => allow(undefined), 10000);
|
|
37
44
|
process.stdin.setEncoding('utf8');
|
|
38
45
|
process.stdin.on('data', chunk => input += chunk);
|
|
39
46
|
process.stdin.on('end', () => {
|
|
@@ -43,14 +50,14 @@ process.stdin.on('end', () => {
|
|
|
43
50
|
const sessionId = data.session_id;
|
|
44
51
|
|
|
45
52
|
if (!sessionId) {
|
|
46
|
-
|
|
53
|
+
allow(undefined);
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
// Reject session IDs that contain path traversal sequences or path separators.
|
|
50
57
|
// session_id is used to construct file paths in /tmp — an unsanitized value
|
|
51
58
|
// could escape the temp directory and read or write arbitrary files.
|
|
52
59
|
if (/[/\\]|\.\./.test(sessionId)) {
|
|
53
|
-
|
|
60
|
+
allow(undefined);
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
// Check if context warnings are disabled via config.
|
|
@@ -61,7 +68,7 @@ process.stdin.on('end', () => {
|
|
|
61
68
|
const configPath = path.join(cwd, '.planning', 'config.json');
|
|
62
69
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
63
70
|
if (config.hooks?.context_warnings === false) {
|
|
64
|
-
|
|
71
|
+
allow(undefined);
|
|
65
72
|
}
|
|
66
73
|
} catch (e) {
|
|
67
74
|
// Missing or unparseable config → proceed with defaults (context warnings enabled)
|
|
@@ -77,7 +84,7 @@ process.stdin.on('end', () => {
|
|
|
77
84
|
try {
|
|
78
85
|
metricsRaw = fs.readFileSync(metricsPath, 'utf8');
|
|
79
86
|
} catch (e) {
|
|
80
|
-
if (e && e.code === 'ENOENT')
|
|
87
|
+
if (e && e.code === 'ENOENT') allow(undefined);
|
|
81
88
|
throw e;
|
|
82
89
|
}
|
|
83
90
|
const metrics = JSON.parse(metricsRaw);
|
|
@@ -85,7 +92,7 @@ process.stdin.on('end', () => {
|
|
|
85
92
|
|
|
86
93
|
// Ignore stale metrics
|
|
87
94
|
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
88
|
-
|
|
95
|
+
allow(undefined);
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
const remaining = metrics.remaining_percentage;
|
|
@@ -93,7 +100,7 @@ process.stdin.on('end', () => {
|
|
|
93
100
|
|
|
94
101
|
// No warning needed
|
|
95
102
|
if (remaining > WARNING_THRESHOLD) {
|
|
96
|
-
|
|
103
|
+
allow(undefined);
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
// Debounce: check if we warned recently
|
|
@@ -121,7 +128,7 @@ process.stdin.on('end', () => {
|
|
|
121
128
|
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
122
129
|
// Update counter and exit without warning
|
|
123
130
|
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
124
|
-
|
|
131
|
+
allow(undefined);
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
// Reset debounce counter
|
|
@@ -208,7 +215,9 @@ process.stdin.on('end', () => {
|
|
|
208
215
|
process.stdout.write(JSON.stringify(output));
|
|
209
216
|
}
|
|
210
217
|
} catch (e) {
|
|
211
|
-
// Silent fail -- never block tool execution
|
|
212
|
-
|
|
218
|
+
// Silent fail -- never block tool execution.
|
|
219
|
+
// ON_CRASH is declared ALLOW at module top: this preserves today's
|
|
220
|
+
// exit(0) fail-open behavior exactly (#3911).
|
|
221
|
+
crash(ON_CRASH, undefined);
|
|
213
222
|
}
|
|
214
223
|
});
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
'use strict';
|
|
24
24
|
|
|
25
|
+
const { allow } = require('./lib/hook-exit.js');
|
|
26
|
+
|
|
25
27
|
const WRITE_TOOL_RE = /write|edit|replace|create|delete|remove|append|apply|patch|insert|mkdir/i;
|
|
26
28
|
const PATH_KEY_RE = /^(path|file|file_?path|filepath|target_?path|target|dir|directory|uri|filename)$/i;
|
|
27
29
|
const PLANNING_PATH_RE = /(^|[\\/])\.planning([\\/]|$)/;
|
|
@@ -29,7 +31,7 @@ const PLANNING_PATH_RE = /(^|[\\/])\.planning([\\/]|$)/;
|
|
|
29
31
|
let raw = '';
|
|
30
32
|
const stdinTimeout = setTimeout(() => {
|
|
31
33
|
// Timeout guard: exit silently rather than hanging.
|
|
32
|
-
|
|
34
|
+
allow(undefined);
|
|
33
35
|
}, 10000);
|
|
34
36
|
|
|
35
37
|
process.stdin.setEncoding('utf8');
|
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
'use strict';
|
|
24
24
|
|
|
25
|
-
const
|
|
26
|
-
const path = require('path');
|
|
25
|
+
const { allow } = require('./lib/hook-exit.js');
|
|
27
26
|
|
|
28
27
|
const WRITE_TOOL_RE = /write|edit|replace|create|delete|remove|append|apply|patch|insert|mkdir/i;
|
|
29
28
|
const PATH_KEY_RE = /^(path|file|file_?path|filepath|target_?path|target|dir|directory|uri|filename)$/i;
|
|
@@ -31,7 +30,7 @@ const PLANNING_PATH_RE = /(^|[\\/])\.planning([\\/]|$)/;
|
|
|
31
30
|
|
|
32
31
|
let raw = '';
|
|
33
32
|
const stdinTimeout = setTimeout(() => {
|
|
34
|
-
|
|
33
|
+
allow(undefined);
|
|
35
34
|
}, 10000);
|
|
36
35
|
|
|
37
36
|
process.stdin.setEncoding('utf8');
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
'use strict';
|
|
24
24
|
|
|
25
25
|
const fs = require('fs');
|
|
26
|
+
const { allow } = require('./lib/hook-exit.js');
|
|
26
27
|
|
|
27
28
|
const MSG_PRESENT =
|
|
28
29
|
'GSD: .planning/STATE.md is present — review the current phase and any blockers before acting.';
|
|
@@ -37,7 +38,7 @@ const { resolveStatePath } = require('./lib/cursor-workspace.js');
|
|
|
37
38
|
let raw = '';
|
|
38
39
|
const stdinTimeout = setTimeout(() => {
|
|
39
40
|
// Timeout guard: exit silently rather than hanging.
|
|
40
|
-
|
|
41
|
+
allow(undefined);
|
|
41
42
|
}, 10000);
|
|
42
43
|
|
|
43
44
|
process.stdin.setEncoding('utf8');
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
'use strict';
|
|
22
22
|
|
|
23
23
|
const fs = require('fs');
|
|
24
|
+
const { allow } = require('./lib/hook-exit.js');
|
|
24
25
|
|
|
25
26
|
// Workspace resolution is shared across the Cursor hooks (#2587) — see
|
|
26
27
|
// hooks/lib/cursor-workspace.js. Staged next to these scripts by
|
|
@@ -29,7 +30,7 @@ const { resolveStatePath } = require('./lib/cursor-workspace.js');
|
|
|
29
30
|
|
|
30
31
|
let raw = '';
|
|
31
32
|
const stdinTimeout = setTimeout(() => {
|
|
32
|
-
|
|
33
|
+
allow(undefined);
|
|
33
34
|
}, 10000);
|
|
34
35
|
|
|
35
36
|
process.stdin.setEncoding('utf8');
|