@opengsd/gsd-core 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +12 -0
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +78 -42
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +0 -1
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +3 -1
- package/agents/gsd-plan-checker.md +91 -112
- package/agents/gsd-planner.md +20 -4
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.md +2 -2
- package/agents/gsd-roadmapper.md +15 -11
- package/agents/gsd-ui-checker.md +82 -7
- package/agents/gsd-ui-researcher.md +70 -3
- package/agents/gsd-verifier.md +24 -2
- package/bin/install.js +847 -200
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/phase.md +1 -1
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/quick.md +8 -4
- package/commands/gsd/surface.md +18 -8
- package/gsd-core/bin/gsd-tools.cjs +761 -100
- package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
- package/gsd-core/bin/lib/api-coverage.cjs +30 -9
- package/gsd-core/bin/lib/artifacts.cjs +2 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
- package/gsd-core/bin/lib/audit.cjs +163 -41
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +785 -144
- package/gsd-core/bin/lib/capability-state.cjs +25 -4
- package/gsd-core/bin/lib/capability-validator.cjs +321 -18
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +229 -6
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
- package/gsd-core/bin/lib/command-aliases.cjs +16 -0
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +877 -54
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +121 -29
- package/gsd-core/bin/lib/config.cjs +92 -2
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +118 -14
- package/gsd-core/bin/lib/decisions.cjs +213 -1
- package/gsd-core/bin/lib/edge-probe.cjs +23 -2
- package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
- package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
- package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +975 -326
- package/gsd-core/bin/lib/gap-checker.cjs +41 -8
- package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
- package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
- package/gsd-core/bin/lib/host-integration.cjs +96 -11
- package/gsd-core/bin/lib/init-command-router.cjs +132 -21
- package/gsd-core/bin/lib/init.cjs +252 -56
- package/gsd-core/bin/lib/install-engine.cjs +252 -15
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
- package/gsd-core/bin/lib/install-profiles.cjs +100 -18
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +195 -15
- package/gsd-core/bin/lib/learnings.cjs +85 -14
- package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
- package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
- package/gsd-core/bin/lib/markdown-table.cjs +175 -4
- package/gsd-core/bin/lib/milestone.cjs +112 -7
- package/gsd-core/bin/lib/model-catalog.cjs +177 -19
- package/gsd-core/bin/lib/model-resolver.cjs +10 -28
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +321 -13
- package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
- package/gsd-core/bin/lib/phase-locator.cjs +138 -17
- package/gsd-core/bin/lib/phase.cjs +1175 -115
- package/gsd-core/bin/lib/plan-document.cjs +273 -0
- package/gsd-core/bin/lib/plan-scan.cjs +13 -2
- package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
- package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
- package/gsd-core/bin/lib/probe-core.cjs +4 -1
- package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
- package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
- package/gsd-core/bin/lib/quick-batch.cjs +840 -0
- package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
- package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
- package/gsd-core/bin/lib/roadmap.cjs +248 -64
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -31
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +47 -18
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +216 -5
- package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
- package/gsd-core/bin/lib/state-transition.cjs +850 -145
- package/gsd-core/bin/lib/state.cjs +1629 -287
- package/gsd-core/bin/lib/surface.cjs +33 -10
- package/gsd-core/bin/lib/task-command-router.cjs +111 -1
- package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
- package/gsd-core/bin/lib/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
- package/gsd-core/bin/lib/uat.cjs +2542 -387
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
- package/gsd-core/bin/lib/unusable-input.cjs +13 -0
- package/gsd-core/bin/lib/update-context.cjs +6 -2
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +230 -12
- package/gsd-core/bin/lib/vendor/README.md +43 -5
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -13
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +441 -56
- package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
- package/gsd-core/bin/shared/exit-codes.json +8 -0
- package/gsd-core/bin/shared/exit-codes.sh +20 -0
- package/gsd-core/bin/shared/model-catalog.json +8 -1
- package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
- package/gsd-core/references/agent-contracts.md +6 -5
- package/gsd-core/references/api-coverage.md +24 -2
- package/gsd-core/references/autonomous-smart-discuss.md +3 -3
- package/gsd-core/references/checkpoints.md +37 -19
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/edge-probe.md +17 -5
- package/gsd-core/references/execute-mvp-tdd.md +18 -18
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-integration.md +5 -5
- package/gsd-core/references/git-planning-commit.md +3 -3
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +22 -0
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/mvp-concepts.md +2 -2
- package/gsd-core/references/nyquist-compliance.md +74 -0
- package/gsd-core/references/offer-next.md +3 -5
- package/gsd-core/references/phase-argument-parsing.md +3 -3
- package/gsd-core/references/plan-checker-examples.md +41 -0
- package/gsd-core/references/planner-antipatterns.md +25 -0
- package/gsd-core/references/planner-chunked.md +5 -1
- package/gsd-core/references/planner-coupling.md +42 -0
- package/gsd-core/references/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +76 -3
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +39 -9
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +15 -12
- package/gsd-core/references/ui-brand.md +65 -21
- package/gsd-core/references/ui-consideration-probe.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +2 -2
- package/gsd-core/references/verifier-evidence-gate.md +160 -0
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +11 -11
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/SECURITY.md +3 -3
- package/gsd-core/templates/UI-SPEC.md +25 -3
- package/gsd-core/templates/VALIDATION.md +3 -3
- package/gsd-core/templates/phase-prompt.md +7 -0
- package/gsd-core/templates/state.md +7 -0
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +3 -1
- package/gsd-core/workflows/add-phase.md +5 -3
- package/gsd-core/workflows/add-tests.md +4 -9
- package/gsd-core/workflows/add-todo.md +2 -2
- package/gsd-core/workflows/ai-integration-phase.md +5 -10
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +14 -3
- package/gsd-core/workflows/audit-milestone.md +11 -9
- package/gsd-core/workflows/audit-uat.md +19 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +12 -26
- package/gsd-core/workflows/check-todos.md +2 -2
- package/gsd-core/workflows/cleanup.md +3 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
- package/gsd-core/workflows/code-review-fix.md +3 -1
- package/gsd-core/workflows/code-review.md +192 -69
- package/gsd-core/workflows/complete-milestone.md +28 -14
- package/gsd-core/workflows/debug.md +6 -4
- package/gsd-core/workflows/diagnose-issues.md +17 -7
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
- package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
- package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
- package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
- package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +46 -19
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +3 -1
- package/gsd-core/workflows/eval-review.md +5 -10
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +29 -5
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +68 -66
- package/gsd-core/workflows/execute-plan.md +25 -20
- package/gsd-core/workflows/explore.md +3 -1
- package/gsd-core/workflows/extract-learnings.md +3 -1
- package/gsd-core/workflows/fast.md +8 -2
- package/gsd-core/workflows/forensics.md +3 -1
- package/gsd-core/workflows/graduation.md +6 -6
- package/gsd-core/workflows/health.md +4 -7
- package/gsd-core/workflows/help/modes/brief.md +2 -0
- package/gsd-core/workflows/help/modes/default.md +2 -0
- package/gsd-core/workflows/help/modes/full.md +12 -0
- package/gsd-core/workflows/help/modes/topic.md +2 -0
- package/gsd-core/workflows/help.md +2 -0
- package/gsd-core/workflows/import.md +17 -14
- package/gsd-core/workflows/inbox.md +5 -6
- package/gsd-core/workflows/ingest-docs.md +45 -12
- package/gsd-core/workflows/insert-phase.md +7 -5
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +7 -3
- package/gsd-core/workflows/list-workspaces.md +3 -1
- package/gsd-core/workflows/manager.md +15 -26
- package/gsd-core/workflows/map-codebase.md +3 -1
- package/gsd-core/workflows/milestone-summary.md +3 -1
- package/gsd-core/workflows/mvp-phase.md +3 -3
- package/gsd-core/workflows/new-milestone.md +10 -22
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +17 -29
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +4 -2
- package/gsd-core/workflows/node-repair.md +2 -0
- package/gsd-core/workflows/note.md +2 -0
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +20 -5
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
- package/gsd-core/workflows/plan-phase.md +251 -54
- package/gsd-core/workflows/plan-review-convergence.md +148 -19
- package/gsd-core/workflows/plant-seed.md +3 -3
- package/gsd-core/workflows/pr-branch.md +195 -51
- package/gsd-core/workflows/profile-user.md +17 -15
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +52 -15
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
- package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
- package/gsd-core/workflows/quick-batch.md +203 -0
- package/gsd-core/workflows/quick.md +33 -32
- package/gsd-core/workflows/reapply-patches.md +2 -0
- package/gsd-core/workflows/remove-phase.md +6 -4
- package/gsd-core/workflows/remove-workspace.md +3 -3
- package/gsd-core/workflows/resume-project.md +14 -14
- package/gsd-core/workflows/review.md +404 -21
- package/gsd-core/workflows/scan.md +3 -1
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +9 -9
- package/gsd-core/workflows/settings-integrations.md +66 -32
- package/gsd-core/workflows/settings.md +4 -6
- package/gsd-core/workflows/ship.md +22 -16
- package/gsd-core/workflows/sketch-wrap-up.md +13 -17
- package/gsd-core/workflows/sketch.md +13 -19
- package/gsd-core/workflows/smart-entry.md +4 -6
- package/gsd-core/workflows/spec-phase.md +31 -4
- package/gsd-core/workflows/spike-wrap-up.md +9 -11
- package/gsd-core/workflows/spike.md +21 -32
- package/gsd-core/workflows/stats.md +4 -2
- package/gsd-core/workflows/sync-skills.md +13 -5
- package/gsd-core/workflows/thread.md +13 -7
- package/gsd-core/workflows/transition.md +7 -5
- package/gsd-core/workflows/ui-phase.md +36 -21
- package/gsd-core/workflows/ui-review.md +7 -11
- package/gsd-core/workflows/ultraplan-phase.md +7 -13
- package/gsd-core/workflows/undo.md +9 -17
- package/gsd-core/workflows/update.md +47 -48
- package/gsd-core/workflows/validate-phase.md +3 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +106 -21
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +302 -22
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
- package/hooks/dist/gsd-cursor-session-start.js +2 -1
- package/hooks/dist/gsd-cursor-stop.js +2 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
- package/hooks/dist/gsd-graphify-update.sh +22 -18
- package/hooks/dist/gsd-node-runner.sh +77 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +46 -12
- package/hooks/dist/gsd-read-guard.js +18 -7
- package/hooks/dist/gsd-read-injection-scanner.js +22 -13
- package/hooks/dist/gsd-secret-read-guard.js +1079 -0
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +222 -29
- package/hooks/dist/gsd-validate-commit.sh +523 -12
- package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
- package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
- package/hooks/dist/gsd-workflow-guard.js +36 -17
- package/hooks/dist/gsd-worktree-path-guard.js +36 -21
- package/hooks/dist/gsd-write-guard.js +35 -25
- package/hooks/dist/lib/cli-exit.js +560 -0
- package/hooks/dist/lib/exit-code-registry.js +98 -0
- package/hooks/dist/lib/git-cmd.js +210 -1
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/managed-hooks-registry.cjs +4 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +302 -22
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +3 -1
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +28 -23
- package/hooks/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +77 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +46 -12
- package/hooks/gsd-read-guard.js +18 -7
- package/hooks/gsd-read-injection-scanner.js +22 -13
- package/hooks/gsd-secret-read-guard.js +1079 -0
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +222 -29
- package/hooks/gsd-validate-commit.sh +523 -12
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +36 -17
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/hooks.json +6 -0
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/managed-hooks-registry.cjs +4 -0
- package/package.json +14 -9
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +12 -0
- package/scripts/check-glossary-refs.cjs +77 -15
- package/scripts/check-mutation-score-ratchet.cjs +156 -0
- package/scripts/ci-check-job-near-cap.cjs +49 -0
- package/scripts/ci-pr-mergeability.cjs +262 -0
- package/scripts/ci-test-scope.cjs +52 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +406 -0
- package/scripts/gen-capability-registry.cjs +8 -6
- package/scripts/gen-exit-code-docs.cjs +318 -0
- package/scripts/gen-exit-code-registry.cjs +891 -0
- package/scripts/gen-features.cjs +836 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-loop-host-contract.cjs +189 -4
- package/scripts/gen-scripts-cli-exit.cjs +185 -0
- package/scripts/gen-state-md-docs.cjs +727 -0
- package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +32 -2
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +45 -14
- package/scripts/lint-phase-id-drift.cjs +133 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-response-language-coverage.cjs +524 -0
- package/scripts/lint-seam-enforcement.cjs +182 -0
- package/scripts/lint-slug-derivation-drift.cjs +921 -0
- package/scripts/lint-source-test-name-collision.cjs +241 -0
- package/scripts/lint-state-write-path-drift.cjs +337 -432
- package/scripts/lint-test-file-count.allowlist.json +124 -4
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +51 -64
- package/scripts/lint-vendored-deps.cjs +208 -35
- package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +83 -14
- package/scripts/require-issue-link-policy.cjs +16 -1
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +22 -3
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -109
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/state-write-path-drift-baseline.json +0 -19
|
@@ -25,6 +25,10 @@ const node_os_1 = __importDefault(require("node:os"));
|
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
26
26
|
const installFsAdapter = require("./install-fs-adapter.cjs");
|
|
27
27
|
const { installFs, mkInstallTempDir } = installFsAdapter;
|
|
28
|
+
// Reuse the install manifest's existing parser and streamed SHA-256
|
|
29
|
+
// classification instead of deriving a second integrity implementation here.
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
31
|
+
const installerMigrations = require("./installer-migrations.cjs");
|
|
28
32
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
33
|
const installProfiles = require("./install-profiles.cjs");
|
|
30
34
|
const { stageSkillsForProfile, stageAgentsForRuntimeWithConverter, stageSkillsForRuntimeAsSkills, stageCommandsForRuntimeFlat, } = installProfiles;
|
|
@@ -36,6 +40,10 @@ const conversionExports = runtimeArtifactConversion;
|
|
|
36
40
|
// rather than re-deriving the chain per runtime.
|
|
37
41
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
42
|
const installModelOverrideResolver = require("./install-model-override-resolver.cjs");
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- export= CommonJS module, same as the sibling resolver import above
|
|
44
|
+
const installEffortResolver = require("./install-effort-resolver.cjs");
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- export= CommonJS module, same as the sibling resolver import above
|
|
46
|
+
const modelCatalog = require("./model-catalog.cjs");
|
|
39
47
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
40
48
|
// #2870: `isGlobalScope` centralizes the `scope === 'global'` boolean
|
|
41
49
|
// projection both kind-builder closures below need at the converters'
|
|
@@ -44,127 +52,288 @@ const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs")
|
|
|
44
52
|
const install_scope_cjs_1 = require("./install-scope.cjs");
|
|
45
53
|
// In .cts (CommonJS output) files, `require` is available as a global.
|
|
46
54
|
const _require = require;
|
|
55
|
+
function requiredRuntimeSurfaceSourceClasses(kinds) {
|
|
56
|
+
const required = new Set();
|
|
57
|
+
for (const kind of kinds) {
|
|
58
|
+
if (kind.kind === 'commands' || kind.kind === 'skills')
|
|
59
|
+
required.add('commands');
|
|
60
|
+
if (kind.kind === 'agents' || kind.kind === 'kimi-agents')
|
|
61
|
+
required.add('agents');
|
|
62
|
+
}
|
|
63
|
+
return required;
|
|
64
|
+
}
|
|
47
65
|
// ---------------------------------------------------------------------------
|
|
48
66
|
// Source root finders
|
|
49
67
|
// ---------------------------------------------------------------------------
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
function isReadableDirectory(candidate, routed) {
|
|
69
|
+
try {
|
|
70
|
+
const io = routed ? installFs() : node_fs_1.default;
|
|
71
|
+
const stat = io.lstatSync(candidate);
|
|
72
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
73
|
+
return false;
|
|
74
|
+
const entries = io.readdirSync(candidate);
|
|
75
|
+
let readableFiles = 0;
|
|
76
|
+
for (const name of entries) {
|
|
77
|
+
const child = node_path_1.default.join(candidate, name);
|
|
78
|
+
const childStat = io.lstatSync(child);
|
|
79
|
+
if (childStat.isSymbolicLink())
|
|
80
|
+
return false;
|
|
81
|
+
if (childStat.isDirectory()) {
|
|
82
|
+
if (!isReadableDirectory(child, routed))
|
|
83
|
+
return false;
|
|
84
|
+
readableFiles += 1;
|
|
85
|
+
}
|
|
86
|
+
else if (childStat.isFile()) {
|
|
87
|
+
if (routed)
|
|
88
|
+
io.readFileSync(child);
|
|
89
|
+
else
|
|
90
|
+
node_fs_1.default.accessSync(child, node_fs_1.default.constants.R_OK);
|
|
91
|
+
readableFiles += 1;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
return false;
|
|
69
95
|
}
|
|
70
|
-
catch { /* fall through */ }
|
|
71
96
|
}
|
|
97
|
+
return readableFiles > 0;
|
|
72
98
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function isPhysicallyConfinedTo(root, candidate) {
|
|
104
|
+
try {
|
|
105
|
+
const physicalRoot = installFs().realpathSync(root);
|
|
106
|
+
const physicalCandidate = installFs().realpathSync(candidate);
|
|
107
|
+
return physicalCandidate === physicalRoot || physicalCandidate.startsWith(physicalRoot + node_path_1.default.sep);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function installedManifestIsComplete(runtimeConfigDir, required) {
|
|
114
|
+
// This synchronous admission check binds provider selection to the corpus
|
|
115
|
+
// observed here. Same-user mutation after resolution is outside #4132's
|
|
116
|
+
// threat model and would require a broader snapshot/transaction design.
|
|
117
|
+
const io = installFs();
|
|
118
|
+
const manifestPath = node_path_1.default.join(runtimeConfigDir, 'gsd-file-manifest.json');
|
|
119
|
+
if (!io.existsSync(manifestPath))
|
|
120
|
+
return false;
|
|
121
|
+
if (!isPhysicallyConfinedTo(runtimeConfigDir, manifestPath))
|
|
122
|
+
return false;
|
|
123
|
+
try {
|
|
124
|
+
const manifest = installerMigrations.readInstallManifest(runtimeConfigDir);
|
|
125
|
+
if (manifest.manifestVersion === null)
|
|
126
|
+
return false;
|
|
127
|
+
const keys = Object.keys(manifest.files);
|
|
128
|
+
const prefixes = [];
|
|
129
|
+
if (required.has('commands'))
|
|
130
|
+
prefixes.push('gsd-core/commands/gsd/');
|
|
131
|
+
if (required.has('agents'))
|
|
132
|
+
prefixes.push('gsd-core/agents/');
|
|
133
|
+
for (const prefix of prefixes) {
|
|
134
|
+
const expected = keys.filter((key) => key.startsWith(prefix));
|
|
135
|
+
if (expected.length === 0)
|
|
136
|
+
return false;
|
|
137
|
+
const expectedSet = new Set(expected);
|
|
138
|
+
const corpusRoot = node_path_1.default.resolve(runtimeConfigDir, ...prefix.slice(0, -1).split('/'));
|
|
139
|
+
if (!isPhysicallyConfinedTo(runtimeConfigDir, corpusRoot))
|
|
140
|
+
return false;
|
|
141
|
+
let actualFiles = 0;
|
|
142
|
+
const visit = (dir) => {
|
|
143
|
+
for (const name of io.readdirSync(dir)) {
|
|
144
|
+
const candidate = node_path_1.default.join(dir, name);
|
|
145
|
+
const stat = io.lstatSync(candidate);
|
|
146
|
+
if (stat.isSymbolicLink())
|
|
147
|
+
return false;
|
|
148
|
+
if (stat.isDirectory()) {
|
|
149
|
+
if (!visit(candidate))
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
else if (stat.isFile()) {
|
|
153
|
+
const relative = node_path_1.default.relative(corpusRoot, candidate).split(node_path_1.default.sep).join('/');
|
|
154
|
+
if (!expectedSet.has(prefix + relative))
|
|
155
|
+
return false;
|
|
156
|
+
actualFiles += 1;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
};
|
|
164
|
+
if (!visit(corpusRoot) || actualFiles !== expected.length)
|
|
165
|
+
return false;
|
|
166
|
+
for (const key of expected) {
|
|
167
|
+
const parts = key.split('/');
|
|
168
|
+
if (parts.some((part) => part === '' || part === '.' || part === '..'))
|
|
169
|
+
return false;
|
|
170
|
+
const candidate = node_path_1.default.resolve(runtimeConfigDir, ...parts);
|
|
171
|
+
const root = node_path_1.default.resolve(runtimeConfigDir);
|
|
172
|
+
if (!candidate.startsWith(root + node_path_1.default.sep))
|
|
173
|
+
return false;
|
|
174
|
+
const stat = io.lstatSync(candidate);
|
|
175
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
176
|
+
return false;
|
|
177
|
+
if (installerMigrations.classifyArtifact(runtimeConfigDir, key, manifest).classification !== 'managed-pristine') {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
102
181
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
dir = parent;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return false;
|
|
108
186
|
}
|
|
109
|
-
throw new Error(`findInstallSourceRoot: could not locate commands/gsd from ${__dirname}`);
|
|
110
187
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
188
|
+
function providerHasRequiredClasses(provider, required, routed, runtimeConfigDir) {
|
|
189
|
+
if (provider.kind === 'installed' && runtimeConfigDir) {
|
|
190
|
+
return installedManifestIsComplete(runtimeConfigDir, required);
|
|
191
|
+
}
|
|
192
|
+
return (!required.has('commands') || isReadableDirectory(provider.commandsRoot, routed)) &&
|
|
193
|
+
(!required.has('agents') || isReadableDirectory(provider.agentsRoot, routed));
|
|
194
|
+
}
|
|
195
|
+
function providersShareRequiredRoots(left, right, required) {
|
|
196
|
+
const leftFs = left.kind === 'package' ? node_fs_1.default : installFs();
|
|
197
|
+
const rightFs = right.kind === 'package' ? node_fs_1.default : installFs();
|
|
198
|
+
const physicalRootsOverlap = (leftRoot, rightRoot) => {
|
|
199
|
+
const canonicalize = (io, root) => {
|
|
200
|
+
let existing = node_path_1.default.resolve(root);
|
|
201
|
+
const missingSegments = [];
|
|
202
|
+
while (true) {
|
|
203
|
+
try {
|
|
204
|
+
return node_path_1.default.resolve(io.realpathSync(existing), ...missingSegments);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (error.code !== 'ENOENT')
|
|
208
|
+
return null;
|
|
209
|
+
const parent = node_path_1.default.dirname(existing);
|
|
210
|
+
if (parent === existing)
|
|
211
|
+
return null;
|
|
212
|
+
missingSegments.unshift(node_path_1.default.basename(existing));
|
|
213
|
+
existing = parent;
|
|
131
214
|
}
|
|
132
215
|
}
|
|
133
|
-
|
|
216
|
+
};
|
|
217
|
+
const overlap = (leftPath, rightPath) => {
|
|
218
|
+
const relative = node_path_1.default.relative(leftPath, rightPath);
|
|
219
|
+
return relative === '' ||
|
|
220
|
+
(relative !== '..' && !relative.startsWith(`..${node_path_1.default.sep}`) && !node_path_1.default.isAbsolute(relative));
|
|
221
|
+
};
|
|
222
|
+
const physicalLeft = canonicalize(leftFs, leftRoot);
|
|
223
|
+
const physicalRight = canonicalize(rightFs, rightRoot);
|
|
224
|
+
if (!physicalLeft || !physicalRight)
|
|
225
|
+
return true;
|
|
226
|
+
return overlap(physicalLeft, physicalRight) || overlap(physicalRight, physicalLeft);
|
|
227
|
+
};
|
|
228
|
+
return (required.has('commands') && physicalRootsOverlap(left.commandsRoot, right.commandsRoot)) ||
|
|
229
|
+
(required.has('agents') && physicalRootsOverlap(left.agentsRoot, right.agentsRoot));
|
|
230
|
+
}
|
|
231
|
+
function markerProvider(runtimeConfigDir) {
|
|
232
|
+
const markerPath = node_path_1.default.join(runtimeConfigDir, '.gsd-source');
|
|
233
|
+
try {
|
|
234
|
+
if (!installFs().existsSync(markerPath))
|
|
235
|
+
return null;
|
|
236
|
+
const markerStat = installFs().lstatSync(markerPath);
|
|
237
|
+
if (!markerStat.isFile() || markerStat.isSymbolicLink())
|
|
238
|
+
return null;
|
|
239
|
+
const commandsRoot = installFs().readFileSync(markerPath, 'utf8').trim();
|
|
240
|
+
if (!commandsRoot)
|
|
241
|
+
return null;
|
|
242
|
+
// A marker written by the installer may point at this process's executing
|
|
243
|
+
// package. Preserve package-source IO on real fs so the existing injected
|
|
244
|
+
// destination adapter remains destination-only (#2874).
|
|
245
|
+
const packaged = packageProvider(new Set(['commands']));
|
|
246
|
+
if (packaged && node_path_1.default.resolve(commandsRoot) === node_path_1.default.resolve(packaged.commandsRoot)) {
|
|
247
|
+
return packaged;
|
|
134
248
|
}
|
|
249
|
+
return {
|
|
250
|
+
kind: 'marker',
|
|
251
|
+
commandsRoot,
|
|
252
|
+
agentsRoot: node_path_1.default.resolve(node_path_1.default.dirname(commandsRoot), '..', 'agents'),
|
|
253
|
+
};
|
|
135
254
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
255
|
+
catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function packageProvider(required) {
|
|
260
|
+
// Package-source IO deliberately stays on real fs; injected install adapters
|
|
261
|
+
// model destinations, not the executing package tree (#2874).
|
|
141
262
|
let dir = __dirname;
|
|
142
263
|
for (let i = 0; i < 6; i++) {
|
|
143
|
-
const candidate =
|
|
144
|
-
|
|
145
|
-
|
|
264
|
+
const candidate = {
|
|
265
|
+
kind: 'package',
|
|
266
|
+
commandsRoot: node_path_1.default.join(dir, 'commands', 'gsd'),
|
|
267
|
+
agentsRoot: node_path_1.default.join(dir, 'agents'),
|
|
268
|
+
};
|
|
269
|
+
if (providerHasRequiredClasses(candidate, required, false))
|
|
146
270
|
return candidate;
|
|
147
|
-
}
|
|
148
|
-
catch { /* not here — keep walking up */ }
|
|
149
271
|
const parent = node_path_1.default.dirname(dir);
|
|
150
272
|
if (parent === dir)
|
|
151
273
|
break;
|
|
152
274
|
dir = parent;
|
|
153
275
|
}
|
|
154
|
-
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Select one complete source provider for an entire resolved layout.
|
|
280
|
+
* Provider mixing is forbidden: a skills+agents layout cannot take commands
|
|
281
|
+
* from one package version and agents from another.
|
|
282
|
+
*/
|
|
283
|
+
function resolveSourceProvider(runtimeConfigDir, requiredClasses, scope = 'global', authority = 'compatible') {
|
|
284
|
+
const required = new Set(requiredClasses);
|
|
285
|
+
let rejectedInstalled = null;
|
|
286
|
+
if (required.size === 0) {
|
|
287
|
+
return { kind: 'package', commandsRoot: '', agentsRoot: '' };
|
|
288
|
+
}
|
|
289
|
+
if (runtimeConfigDir && scope === 'global') {
|
|
290
|
+
const installed = {
|
|
291
|
+
kind: 'installed',
|
|
292
|
+
commandsRoot: node_path_1.default.join(runtimeConfigDir, 'gsd-core', 'commands', 'gsd'),
|
|
293
|
+
agentsRoot: node_path_1.default.join(runtimeConfigDir, 'gsd-core', 'agents'),
|
|
294
|
+
};
|
|
295
|
+
if (providerHasRequiredClasses(installed, required, true, runtimeConfigDir))
|
|
296
|
+
return installed;
|
|
297
|
+
rejectedInstalled = installed;
|
|
298
|
+
const marker = markerProvider(runtimeConfigDir);
|
|
299
|
+
if (marker && !providersShareRequiredRoots(marker, installed, required) && providerHasRequiredClasses(marker, required, marker.kind !== 'package')) {
|
|
300
|
+
return marker;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else if (runtimeConfigDir) {
|
|
304
|
+
const marker = markerProvider(runtimeConfigDir);
|
|
305
|
+
if (marker && providerHasRequiredClasses(marker, required, marker.kind !== 'package'))
|
|
306
|
+
return marker;
|
|
307
|
+
}
|
|
308
|
+
if (authority === 'compatible') {
|
|
309
|
+
const packaged = packageProvider(required);
|
|
310
|
+
if (packaged &&
|
|
311
|
+
(!rejectedInstalled || !providersShareRequiredRoots(packaged, rejectedInstalled, required))) {
|
|
312
|
+
return packaged;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
throw new Error(`Runtime Surface source is unavailable or incomplete for ${[...required].sort().join('+')}; ` +
|
|
316
|
+
'install or upgrade gsd-core before materializing this surface.');
|
|
317
|
+
}
|
|
318
|
+
function sourceRootFor(context, sourceClass) {
|
|
319
|
+
context.provider ??= resolveSourceProvider(context.runtimeConfigDir, context.required, context.scope, context.authority);
|
|
320
|
+
return sourceClass === 'commands' ? context.provider.commandsRoot : context.provider.agentsRoot;
|
|
321
|
+
}
|
|
322
|
+
function findInstallSourceRoot(runtimeConfigDir) {
|
|
323
|
+
return resolveSourceProvider(runtimeConfigDir, ['commands']).commandsRoot;
|
|
155
324
|
}
|
|
156
325
|
// ---------------------------------------------------------------------------
|
|
157
326
|
// Layout table builders
|
|
158
327
|
// ---------------------------------------------------------------------------
|
|
159
|
-
function commandsKind(destSubpath, prefix,
|
|
328
|
+
function commandsKind(destSubpath, prefix, sourceContext) {
|
|
160
329
|
return {
|
|
161
330
|
kind: 'commands',
|
|
162
331
|
destSubpath,
|
|
163
332
|
prefix,
|
|
164
|
-
stage: (resolved) => stageSkillsForProfile(
|
|
333
|
+
stage: (resolved) => stageSkillsForProfile(sourceRootFor(sourceContext, 'commands'), resolved),
|
|
165
334
|
};
|
|
166
335
|
}
|
|
167
|
-
function agentsKind(destSubpath, prefix, configDir) {
|
|
336
|
+
function agentsKind(destSubpath, prefix, configDir, sourceContext) {
|
|
168
337
|
return {
|
|
169
338
|
kind: 'agents',
|
|
170
339
|
destSubpath,
|
|
@@ -187,7 +356,7 @@ function agentsKind(destSubpath, prefix, configDir) {
|
|
|
187
356
|
// signature silently dropped the second arg every caller already passed —
|
|
188
357
|
// a caller with NO agentCtx in scope is unaffected (row I2: converter-only,
|
|
189
358
|
// as today), matching stageAgentsForRuntimeWithConverter's own contract.
|
|
190
|
-
stage: (resolved, agentCtx) => stageAgentsForRuntimeWithConverter(
|
|
359
|
+
stage: (resolved, agentCtx) => stageAgentsForRuntimeWithConverter(sourceRootFor(sourceContext, 'agents'), resolved, (content) => content, false, agentCtx?.runtime ? agentCtx : undefined),
|
|
191
360
|
};
|
|
192
361
|
}
|
|
193
362
|
/**
|
|
@@ -319,7 +488,7 @@ function _resolveNamedConverter(converterName, kindLabel) {
|
|
|
319
488
|
* @param converterName name of converter function in Runtime Artifact Conversion exports
|
|
320
489
|
* @param configDir runtime config dir (for .gsd-source marker resolution)
|
|
321
490
|
*/
|
|
322
|
-
function convertedAgentsKind(destSubpath, prefix, converterName, configDir, scope
|
|
491
|
+
function convertedAgentsKind(destSubpath, prefix, converterName, configDir, sourceContext, scope) {
|
|
323
492
|
return {
|
|
324
493
|
kind: 'agents',
|
|
325
494
|
destSubpath,
|
|
@@ -346,11 +515,40 @@ function convertedAgentsKind(destSubpath, prefix, converterName, configDir, scop
|
|
|
346
515
|
const overrideTargetDir = agentCtx?.targetDir ?? configDir;
|
|
347
516
|
const modelOverrides = installModelOverrideResolver.readGsdEffectiveModelOverrides(overrideTargetDir);
|
|
348
517
|
const runtimeResolver = installModelOverrideResolver.readGsdRuntimeProfileResolver(overrideTargetDir);
|
|
518
|
+
// #3706: the resolved reasoning effort, threaded exactly as the model is —
|
|
519
|
+
// config read ONCE per stage(), per-agent value resolved per file.
|
|
520
|
+
//
|
|
521
|
+
// Gated on the effort config being PRESENT, not on a value coming back.
|
|
522
|
+
// `resolveInstallTimeEffort` always returns something (measured: 'high'
|
|
523
|
+
// even with no project config and no effort block), so "skip when
|
|
524
|
+
// resolution yields no value" has no trigger and would stamp `variant:`
|
|
525
|
+
// into every generated agent file for every existing install. OpenCode's
|
|
526
|
+
// built-in variant sets are provider-specific upstream (Anthropic ships
|
|
527
|
+
// only `high`/`max`), so a level GSD resolved is not guaranteed to name a
|
|
528
|
+
// variant the user's provider actually has — emitting one unasked-for is
|
|
529
|
+
// the risk this gate avoids. #1156's rule for `model: inherit` is the
|
|
530
|
+
// precedent: do not emit a key the runtime may not understand.
|
|
531
|
+
//
|
|
532
|
+
// OpenCode only; the kilo converter ignores the field (no EFFORT_ARGV.kilo).
|
|
533
|
+
const effortConfig = converterName === 'convertClaudeToOpencodeFrontmatter'
|
|
534
|
+
? installEffortResolver.readGsdEffectiveEffortConfig(overrideTargetDir)
|
|
535
|
+
: null;
|
|
349
536
|
converter = (content, _isGlobal, meta) => {
|
|
350
537
|
const modelOverride = meta
|
|
351
538
|
? installModelOverrideResolver.resolveAgentModelOverride(meta.agentName, modelOverrides, runtimeResolver)
|
|
352
539
|
: null;
|
|
353
|
-
|
|
540
|
+
// The universal level is NOT emitted raw. `clampEffortForHost` is the
|
|
541
|
+
// declared OpenCode effort capability (EFFORT_ARGV.opencode: its own
|
|
542
|
+
// `supported` set + `clamp`), and it is what rejects a level that is
|
|
543
|
+
// not a wire value — most importantly `inherit`, which per #3533 (10d)
|
|
544
|
+
// means "omit the key and follow the host default" and must never be
|
|
545
|
+
// written literally. Anything unsupported clamps to null, which omits
|
|
546
|
+
// the key rather than inventing one.
|
|
547
|
+
const universal = effortConfig && meta
|
|
548
|
+
? installEffortResolver.resolveInstallTimeEffort(effortConfig, meta.agentName)
|
|
549
|
+
: null;
|
|
550
|
+
const variant = universal ? modelCatalog.clampEffortForHost('opencode', universal) : null;
|
|
551
|
+
return rawConverter(content, { isAgent: true, modelOverride, variant });
|
|
354
552
|
};
|
|
355
553
|
}
|
|
356
554
|
else {
|
|
@@ -363,20 +561,20 @@ function convertedAgentsKind(destSubpath, prefix, converterName, configDir, scop
|
|
|
363
561
|
// ADR-1235 §1: when agentCtx is provided (by createRuntimeArtifactInstallPlan
|
|
364
562
|
// for descriptor-driven runtimes), thread it through so stageAgentsForRuntimeWithConverter
|
|
365
563
|
// can apply the full pre-converter + post-converter sequence in the correct order.
|
|
366
|
-
return stageAgentsForRuntimeWithConverter(
|
|
564
|
+
return stageAgentsForRuntimeWithConverter(sourceRootFor(sourceContext, 'agents'), resolved, converter, (0, install_scope_cjs_1.isGlobalScope)(scope), agentCtx?.runtime ? agentCtx : undefined);
|
|
367
565
|
},
|
|
368
566
|
};
|
|
369
567
|
}
|
|
370
|
-
function kimiAgentsKind(destSubpath, prefix, configDir) {
|
|
568
|
+
function kimiAgentsKind(destSubpath, prefix, configDir, sourceContext) {
|
|
371
569
|
return {
|
|
372
570
|
kind: 'kimi-agents',
|
|
373
571
|
destSubpath,
|
|
374
572
|
prefix,
|
|
375
|
-
stage: (resolved) => {
|
|
573
|
+
stage: (resolved, agentCtx) => {
|
|
376
574
|
const buildKimiAgentArtifacts = conversionExports['buildKimiAgentArtifacts'];
|
|
377
575
|
// #2995: compose at staging (identity converter) so the readFileSync below
|
|
378
576
|
// sees marker-free content — same single composing stager as agentsKind.
|
|
379
|
-
const stagedAgents = stageAgentsForRuntimeWithConverter(
|
|
577
|
+
const stagedAgents = stageAgentsForRuntimeWithConverter(sourceRootFor(sourceContext, 'agents'), resolved, (content) => content, false, agentCtx);
|
|
380
578
|
const subagents = [];
|
|
381
579
|
if (installFs().existsSync(stagedAgents)) {
|
|
382
580
|
for (const entry of installFs().readdirSync(stagedAgents, { withFileTypes: true })) {
|
|
@@ -423,7 +621,7 @@ function kimiAgentsKind(destSubpath, prefix, configDir) {
|
|
|
423
621
|
* their declaring capId at staging time. Absent -> stage() stages
|
|
424
622
|
* nothing third-party (fail closed).
|
|
425
623
|
*/
|
|
426
|
-
function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nested
|
|
624
|
+
function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nested, scope, sourceContext, capabilityRegistry) {
|
|
427
625
|
return {
|
|
428
626
|
kind: 'skills',
|
|
429
627
|
destSubpath,
|
|
@@ -456,7 +654,7 @@ function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nest
|
|
|
456
654
|
// it must run AFTER it instead, once the `@`-include is in its final
|
|
457
655
|
// rewritten shape.
|
|
458
656
|
const wrappedConverter = (content, skillName) => realConverter(content, skillName, runtime, cmdNames, isGlobal);
|
|
459
|
-
return stageSkillsForRuntimeAsSkills(
|
|
657
|
+
return stageSkillsForRuntimeAsSkills(sourceRootFor(sourceContext, 'commands'), resolved, wrappedConverter, prefix, nested, capabilityRegistry);
|
|
460
658
|
},
|
|
461
659
|
};
|
|
462
660
|
}
|
|
@@ -476,14 +674,14 @@ function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nest
|
|
|
476
674
|
* @param converterName name of converter function in Runtime Artifact Conversion exports
|
|
477
675
|
* @param configDir runtime config dir (for .gsd-source marker resolution)
|
|
478
676
|
*/
|
|
479
|
-
function convertedCommandsKind(destSubpath, prefix, converterName,
|
|
677
|
+
function convertedCommandsKind(destSubpath, prefix, converterName, sourceContext) {
|
|
480
678
|
return {
|
|
481
679
|
kind: 'commands',
|
|
482
680
|
destSubpath,
|
|
483
681
|
prefix,
|
|
484
682
|
stage: (resolved) => {
|
|
485
683
|
const converter = _resolveNamedConverter(converterName, 'commands');
|
|
486
|
-
return stageCommandsForRuntimeFlat(
|
|
684
|
+
return stageCommandsForRuntimeFlat(sourceRootFor(sourceContext, 'commands'), resolved, converter, prefix);
|
|
487
685
|
},
|
|
488
686
|
};
|
|
489
687
|
}
|
|
@@ -494,29 +692,29 @@ function getRegistry() {
|
|
|
494
692
|
* Map a single ArtifactKindDescriptor entry to an ArtifactKind using the
|
|
495
693
|
* matching builder function. Mirrors the hand-built calls in the old switch.
|
|
496
694
|
*/
|
|
497
|
-
function dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry) {
|
|
695
|
+
function dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry, sourceContext) {
|
|
498
696
|
const { kind, destSubpath, prefix, nesting, converter } = entry;
|
|
499
697
|
const nested = nesting === 'nested';
|
|
500
698
|
let result;
|
|
501
699
|
switch (kind) {
|
|
502
700
|
case 'commands':
|
|
503
701
|
result = converter == null
|
|
504
|
-
? commandsKind(destSubpath, prefix,
|
|
505
|
-
: convertedCommandsKind(destSubpath, prefix, converter,
|
|
702
|
+
? commandsKind(destSubpath, prefix, sourceContext)
|
|
703
|
+
: convertedCommandsKind(destSubpath, prefix, converter, sourceContext);
|
|
506
704
|
break;
|
|
507
705
|
case 'agents':
|
|
508
706
|
result = converter == null
|
|
509
|
-
? agentsKind(destSubpath, prefix, configDir)
|
|
510
|
-
: convertedAgentsKind(destSubpath, prefix, converter, configDir, scope);
|
|
707
|
+
? agentsKind(destSubpath, prefix, configDir, sourceContext)
|
|
708
|
+
: convertedAgentsKind(destSubpath, prefix, converter, configDir, sourceContext, scope);
|
|
511
709
|
break;
|
|
512
710
|
case 'skills':
|
|
513
711
|
if (converter == null) {
|
|
514
712
|
throw new TypeError(`resolveRuntimeArtifactLayout: skills entry for '${runtime}' has converter=null (converter is required for skills)`);
|
|
515
713
|
}
|
|
516
|
-
result = skillsKind(destSubpath, prefix, converter, runtime, configDir, nested, scope, capabilityRegistry);
|
|
714
|
+
result = skillsKind(destSubpath, prefix, converter, runtime, configDir, nested, scope, sourceContext, capabilityRegistry);
|
|
517
715
|
break;
|
|
518
716
|
case 'kimi-agents':
|
|
519
|
-
result = kimiAgentsKind(destSubpath, prefix, configDir);
|
|
717
|
+
result = kimiAgentsKind(destSubpath, prefix, configDir, sourceContext);
|
|
520
718
|
break;
|
|
521
719
|
default:
|
|
522
720
|
throw new TypeError(`resolveRuntimeArtifactLayout: unknown kind '${kind}' in descriptor for runtime '${runtime}'`);
|
|
@@ -561,7 +759,20 @@ function resolveRuntimeArtifactLayoutFromRegistry(registry, runtime, configDir,
|
|
|
561
759
|
throw new TypeError(`Unknown runtime: '${runtime}' — add to runtime-artifact-layout.cjs table`);
|
|
562
760
|
}
|
|
563
761
|
const entries = desc[scope] ?? [];
|
|
564
|
-
const
|
|
762
|
+
const required = requiredRuntimeSurfaceSourceClasses(entries);
|
|
763
|
+
// Stage closures share one lazy source-resolution context, so the first kind
|
|
764
|
+
// to stage selects and caches one complete provider for every required source
|
|
765
|
+
// class. Global layouts accept only installed or marker providers; the
|
|
766
|
+
// installer owns its private package fallback by retrying through a transient
|
|
767
|
+
// compatibility marker after source resolution fails. Local layouts retain
|
|
768
|
+
// compatible marker/package resolution and never provision the global corpus.
|
|
769
|
+
const sourceContext = {
|
|
770
|
+
runtimeConfigDir: configDir,
|
|
771
|
+
scope,
|
|
772
|
+
required,
|
|
773
|
+
authority: scope === 'local' ? 'compatible' : 'runtime',
|
|
774
|
+
};
|
|
775
|
+
const kinds = entries.map((entry) => dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry, sourceContext));
|
|
565
776
|
return { runtime, configDir, scope, kinds };
|
|
566
777
|
}
|
|
567
778
|
function getTriggerRegistry() {
|