@opengsd/gsd-core 1.15.0 → 1.16.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 +85 -5
- package/agents/gsd-code-fixer.compact.md +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-code-reviewer.compact.md +5 -3
- package/agents/gsd-code-reviewer.md +8 -6
- package/agents/gsd-debug-session-manager.compact.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +2 -2
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +4 -4
- package/agents/gsd-intel-updater.compact.md +1 -1
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +2 -2
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-plan-checker.md +7 -2
- package/agents/gsd-planner.md +3 -3
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +1 -1
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +21 -30
- package/agents/gsd-ui-auditor.md +42 -51
- package/agents/gsd-ui-researcher.compact.md +1 -1
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-verifier.md +31 -9
- package/bin/install.js +126 -196
- package/commands/gsd/add-tests.md +6 -1
- package/commands/gsd/ai-integration-phase.md +6 -1
- package/commands/gsd/audit-fix.md +5 -0
- package/commands/gsd/audit-milestone.md +6 -1
- package/commands/gsd/autonomous.md +5 -0
- package/commands/gsd/capture.md +8 -4
- package/commands/gsd/code-review.md +7 -2
- package/commands/gsd/complete-milestone.md +4 -0
- package/commands/gsd/config.md +7 -3
- package/commands/gsd/debug.md +11 -7
- package/commands/gsd/discuss-phase.md +7 -3
- package/commands/gsd/docs-update.md +12 -7
- package/commands/gsd/eval-review.md +6 -1
- package/commands/gsd/execute-phase.md +12 -7
- package/commands/gsd/extract-learnings.md +5 -0
- package/commands/gsd/fast.md +4 -0
- package/commands/gsd/forensics.md +5 -1
- package/commands/gsd/graphify.md +10 -6
- package/commands/gsd/health.md +5 -0
- package/commands/gsd/help.md +7 -2
- package/commands/gsd/import.md +7 -3
- package/commands/gsd/inbox.md +5 -0
- package/commands/gsd/ingest-docs.md +5 -1
- package/commands/gsd/manager.md +6 -1
- package/commands/gsd/map-codebase.md +7 -3
- package/commands/gsd/mempalace-capture.md +5 -1
- package/commands/gsd/mempalace-recall.md +5 -1
- package/commands/gsd/milestone-summary.md +5 -1
- package/commands/gsd/mvp-phase.md +8 -3
- package/commands/gsd/new-milestone.md +6 -1
- package/commands/gsd/new-project.md +5 -0
- package/commands/gsd/next.md +6 -1
- package/commands/gsd/ns-context.md +4 -0
- package/commands/gsd/ns-ideate.md +4 -0
- package/commands/gsd/ns-manage.md +4 -0
- package/commands/gsd/ns-project.md +4 -0
- package/commands/gsd/ns-review.md +4 -0
- package/commands/gsd/ns-workflow.md +4 -0
- package/commands/gsd/onboard.md +6 -1
- package/commands/gsd/pause-work.md +5 -1
- package/commands/gsd/phase.md +8 -4
- package/commands/gsd/plan-phase.md +6 -1
- package/commands/gsd/plan-review-convergence.md +5 -1
- package/commands/gsd/pr-branch.md +4 -0
- package/commands/gsd/profile-user.md +5 -1
- package/commands/gsd/progress.md +6 -1
- package/commands/gsd/quick-batch.md +20 -8
- package/commands/gsd/quick.md +12 -7
- package/commands/gsd/review.md +5 -1
- package/commands/gsd/secure-phase.md +6 -1
- package/commands/gsd/ship.md +5 -0
- package/commands/gsd/sketch.md +7 -2
- package/commands/gsd/spec-phase.md +5 -1
- package/commands/gsd/spike.md +8 -3
- package/commands/gsd/surface.md +5 -1
- package/commands/gsd/thread.md +4 -0
- package/commands/gsd/ui-phase.md +6 -1
- package/commands/gsd/ui-review.md +6 -1
- package/commands/gsd/ultraplan-phase.md +5 -1
- package/commands/gsd/undo.md +5 -1
- package/commands/gsd/update.md +6 -2
- package/commands/gsd/validate-phase.md +6 -1
- package/commands/gsd/verify-work.md +6 -1
- package/commands/gsd/workspace.md +7 -3
- package/gsd-core/bin/gsd-tools.cjs +142 -56
- package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
- package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
- package/gsd-core/bin/lib/audit.cjs +78 -44
- package/gsd-core/bin/lib/broken-windows.cjs +13 -13
- package/gsd-core/bin/lib/capability-activation.cjs +9 -4
- package/gsd-core/bin/lib/capability-registry.cjs +183 -103
- package/gsd-core/bin/lib/capability-validator.cjs +16 -0
- package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
- package/gsd-core/bin/lib/check-command-router.cjs +164 -1712
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
- package/gsd-core/bin/lib/cli-exit.cjs +12 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +11 -8
- package/gsd-core/bin/lib/command-aliases.cjs +7 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
- package/gsd-core/bin/lib/commands.cjs +173 -170
- package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
- package/gsd-core/bin/lib/config.cjs +43 -12
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/coverage.cjs +4 -8
- package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
- package/gsd-core/bin/lib/drift.cjs +177 -42
- package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
- package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
- package/gsd-core/bin/lib/frontmatter.cjs +413 -234
- package/gsd-core/bin/lib/gap-checker.cjs +72 -29
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
- package/gsd-core/bin/lib/gate-args.cjs +53 -0
- package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
- package/gsd-core/bin/lib/gate-config.cjs +46 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
- package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
- package/gsd-core/bin/lib/gate-exit.cjs +27 -0
- package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
- package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
- package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
- package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
- package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
- package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
- package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
- package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
- package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
- package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
- package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
- package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
- package/gsd-core/bin/lib/init.cjs +162 -96
- package/gsd-core/bin/lib/install-engine.cjs +19 -35
- package/gsd-core/bin/lib/install-profiles.cjs +7 -4
- package/gsd-core/bin/lib/io.cjs +122 -3
- package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
- package/gsd-core/bin/lib/milestone.cjs +19 -1
- package/gsd-core/bin/lib/model-resolver.cjs +18 -18
- package/gsd-core/bin/lib/observability/event.cjs +1 -1
- package/gsd-core/bin/lib/observability/logger.cjs +46 -1
- package/gsd-core/bin/lib/pattern.cjs +10 -0
- package/gsd-core/bin/lib/phase-command-router.cjs +11 -4
- package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
- package/gsd-core/bin/lib/phase-id.cjs +1 -1
- package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
- package/gsd-core/bin/lib/phase-status.cjs +360 -0
- package/gsd-core/bin/lib/phase.cjs +280 -80
- package/gsd-core/bin/lib/plan-document.cjs +93 -19
- package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
- package/gsd-core/bin/lib/planning-document.cjs +273 -40
- package/gsd-core/bin/lib/planning-inspect.cjs +42 -8
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +76 -53
- package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
- package/gsd-core/bin/lib/profile-output.cjs +6 -3
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
- package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
- package/gsd-core/bin/lib/report-parser.cjs +269 -0
- package/gsd-core/bin/lib/roadmap-command-router.cjs +13 -15
- package/gsd-core/bin/lib/roadmap-parser.cjs +82 -15
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +127 -65
- package/gsd-core/bin/lib/roadmap.cjs +169 -72
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +91 -157
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -1
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
- package/gsd-core/bin/lib/runtime-homes.cjs +13 -10
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +307 -591
- package/gsd-core/bin/lib/runtime-name-policy.cjs +142 -27
- package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
- package/gsd-core/bin/lib/shell-command-projection.cjs +37 -2
- package/gsd-core/bin/lib/smart-entry.cjs +19 -3
- package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
- package/gsd-core/bin/lib/state-contract.cjs +15 -18
- package/gsd-core/bin/lib/state-document.cjs +100 -22
- package/gsd-core/bin/lib/state.cjs +214 -105
- package/gsd-core/bin/lib/surface.cjs +2 -1
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -152
- package/gsd-core/bin/lib/uat-predicate.cjs +313 -35
- package/gsd-core/bin/lib/uat.cjs +424 -7
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +94 -58
- package/gsd-core/bin/lib/vendor/README.md +31 -9
- package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
- package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +1165 -314
- package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
- package/gsd-core/bin/lib/verify.cjs +286 -567
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
- package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
- package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
- package/gsd-core/bin/lib/workstream.cjs +11 -2
- package/gsd-core/bin/shared/config-defaults.manifest.json +5 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +4 -0
- package/gsd-core/references/autonomous-smart-discuss.md +2 -1
- package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
- package/gsd-core/references/execute-mvp-tdd.md +5 -10
- package/gsd-core/references/execute-phase-between-wave-reset.md +3 -0
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +7 -1
- package/gsd-core/references/offer-next.md +1 -1
- package/gsd-core/references/planning-config.md +1 -1
- package/gsd-core/references/spidr-splitting.md +1 -1
- package/gsd-core/references/tdd.md +10 -4
- package/gsd-core/references/verifier-phase-gates.md +5 -2
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -3
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/UAT.md +17 -1
- package/gsd-core/templates/config.json +2 -11
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +8 -7
- package/gsd-core/workflows/add-tests.md +3 -2
- package/gsd-core/workflows/add-todo.md +4 -3
- package/gsd-core/workflows/ai-integration-phase.md +3 -2
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +4 -3
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous.md +28 -18
- package/gsd-core/workflows/check-todos.md +6 -5
- package/gsd-core/workflows/cleanup.md +1 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
- package/gsd-core/workflows/code-review-fix.md +5 -4
- package/gsd-core/workflows/code-review.md +84 -90
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
- package/gsd-core/workflows/complete-milestone.md +12 -7
- package/gsd-core/workflows/debug.md +30 -5
- package/gsd-core/workflows/diagnose-issues.md +3 -2
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +4 -3
- package/gsd-core/workflows/do.md +1 -1
- package/gsd-core/workflows/docs-update.md +4 -3
- package/gsd-core/workflows/edit-phase.md +4 -3
- package/gsd-core/workflows/eval-review.md +5 -3
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +4 -2
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
- package/gsd-core/workflows/execute-phase.md +78 -170
- package/gsd-core/workflows/execute-plan.md +13 -19
- package/gsd-core/workflows/explore.md +2 -2
- package/gsd-core/workflows/extract-learnings.md +3 -2
- package/gsd-core/workflows/fast.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +3 -2
- package/gsd-core/workflows/inbox.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +4 -3
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +5 -3
- package/gsd-core/workflows/map-codebase.md +4 -3
- package/gsd-core/workflows/milestone-summary.md +3 -2
- package/gsd-core/workflows/mvp-phase.md +14 -14
- package/gsd-core/workflows/new-milestone.md +10 -10
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +1 -1
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/pause-work.md +2 -2
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +1 -1
- package/gsd-core/workflows/plan-phase.md +27 -18
- package/gsd-core/workflows/plan-review-convergence.md +1 -1
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +1 -1
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress.md +19 -49
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -2
- package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
- package/gsd-core/workflows/quick-batch.md +15 -10
- package/gsd-core/workflows/quick.md +42 -31
- package/gsd-core/workflows/remove-phase.md +3 -2
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +3 -2
- package/gsd-core/workflows/review.md +3 -2
- package/gsd-core/workflows/scan.md +3 -2
- package/gsd-core/workflows/secure-phase.md +11 -12
- package/gsd-core/workflows/settings-advanced.md +1 -1
- package/gsd-core/workflows/settings-integrations.md +1 -1
- package/gsd-core/workflows/settings.md +1 -1
- package/gsd-core/workflows/ship.md +12 -12
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +1 -1
- package/gsd-core/workflows/spec-phase.md +1 -1
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/sync-skills.md +1 -1
- package/gsd-core/workflows/thread.md +2 -2
- package/gsd-core/workflows/transition.md +13 -23
- package/gsd-core/workflows/ui-phase.md +5 -4
- package/gsd-core/workflows/ui-review.md +4 -3
- package/gsd-core/workflows/ultraplan-phase.md +3 -2
- package/gsd-core/workflows/undo.md +1 -1
- package/gsd-core/workflows/validate-phase.md +10 -12
- package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
- package/gsd-core/workflows/verify-work.md +68 -59
- package/hooks/dist/gsd-agent-isolation-guard.js +8 -0
- package/hooks/dist/gsd-check-update-worker.js +8 -0
- package/hooks/dist/gsd-check-update.js +8 -0
- package/hooks/dist/gsd-context-monitor.js +31 -8
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
- package/hooks/dist/gsd-secret-read-guard.js +147 -16
- package/hooks/dist/gsd-statusline.js +15 -7
- package/hooks/dist/gsd-update-banner.js +8 -0
- package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
- package/hooks/dist/gsd-workflow-guard.js +5 -4
- package/hooks/dist/gsd-worktree-path-guard.js +6 -2
- package/hooks/dist/lib/cli-exit.js +12 -0
- package/hooks/dist/lib/git-probe.js +17 -1
- package/hooks/dist/lib/isolation-sentinel.js +2 -2
- package/hooks/gsd-agent-isolation-guard.js +8 -0
- package/hooks/gsd-check-update-worker.js +8 -0
- package/hooks/gsd-check-update.js +8 -0
- package/hooks/gsd-context-monitor.js +31 -8
- package/hooks/gsd-cursor-subagent-start.js +8 -0
- package/hooks/gsd-secret-read-guard.js +147 -16
- package/hooks/gsd-statusline.js +15 -7
- package/hooks/gsd-update-banner.js +8 -0
- package/hooks/gsd-windsurf-pre-write.js +11 -2
- package/hooks/gsd-workflow-guard.js +5 -4
- package/hooks/gsd-worktree-path-guard.js +6 -2
- package/hooks/hooks.json +5 -5
- package/hooks/lib/cli-exit.js +12 -0
- package/hooks/lib/git-probe.js +17 -1
- package/hooks/lib/isolation-sentinel.js +2 -2
- package/package.json +21 -4
- package/scripts/changeset/parse.cjs +52 -4
- package/scripts/ci-timeout-report.cjs +770 -4
- package/scripts/command-contract-helpers.cjs +12 -8
- package/scripts/docs-guard-registry.cjs +6 -0
- package/scripts/gen-features.cjs +13 -8
- package/scripts/gen-hooks-cli-exit.cjs +12 -28
- package/scripts/gen-loop-host-contract.cjs +10 -1
- package/scripts/gen-platform-conformance-tier.cjs +187 -1
- package/scripts/gen-plugin-skills.cjs +87 -1
- package/scripts/gen-research-agents.cjs +24 -31
- package/scripts/gen-scripts-cli-exit.cjs +30 -3
- package/scripts/gen-test-timings.cjs +32 -7
- package/scripts/lib/cli-exit.cjs +12 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +20 -2
- package/scripts/lib/ndjson-reporter.cjs +28 -3
- package/scripts/lib/platform-conformance-tier.generated.cjs +34 -5
- package/scripts/lib/registration-ledger-preload.cjs +155 -0
- package/scripts/lib/vendor-bundle.cjs +59 -0
- package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-completion-predicate-drift.cjs +18 -19
- package/scripts/lint-descriptions.cjs +7 -3
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +10 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
- package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
- package/scripts/lint-phase-enumeration-drift.cjs +12 -8
- package/scripts/lint-phase-id-drift.cjs +29 -0
- package/scripts/lint-planning-document-positive-control.cjs +329 -0
- package/scripts/lint-response-language-coverage.cjs +3 -0
- package/scripts/lint-skill-deps.cjs +7 -3
- package/scripts/lint-test-file-count.allowlist.json +11 -1
- package/scripts/lint-test-file-count.cjs +34 -1
- package/scripts/lint-vendored-deps.cjs +41 -5
- package/scripts/lint-workflow-shellcheck-baseline.json +10 -10
- package/scripts/mutation-matrix.cjs +50 -5
- package/scripts/require-issue-link-policy.cjs +6 -2
- package/scripts/sync-runtime-launcher.cjs +184 -2
- package/scripts/verify-npm-publish.cjs +76 -20
- package/skills/gsd-add-tests/SKILL.md +6 -1
- package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
- package/skills/gsd-audit-fix/SKILL.md +5 -0
- package/skills/gsd-audit-milestone/SKILL.md +6 -1
- package/skills/gsd-autonomous/SKILL.md +5 -0
- package/skills/gsd-capture/SKILL.md +8 -4
- package/skills/gsd-code-review/SKILL.md +7 -2
- package/skills/gsd-complete-milestone/SKILL.md +4 -0
- package/skills/gsd-config/SKILL.md +8 -4
- package/skills/gsd-debug/SKILL.md +11 -7
- package/skills/gsd-discuss-phase/SKILL.md +7 -3
- package/skills/gsd-docs-update/SKILL.md +12 -7
- package/skills/gsd-eval-review/SKILL.md +6 -1
- package/skills/gsd-execute-phase/SKILL.md +12 -7
- package/skills/gsd-extract-learnings/SKILL.md +5 -0
- package/skills/gsd-fast/SKILL.md +4 -0
- package/skills/gsd-forensics/SKILL.md +5 -1
- package/skills/gsd-graphify/SKILL.md +10 -6
- package/skills/gsd-health/SKILL.md +5 -0
- package/skills/gsd-help/SKILL.md +7 -2
- package/skills/gsd-import/SKILL.md +7 -3
- package/skills/gsd-inbox/SKILL.md +5 -0
- package/skills/gsd-ingest-docs/SKILL.md +5 -1
- package/skills/gsd-manager/SKILL.md +6 -1
- package/skills/gsd-map-codebase/SKILL.md +7 -3
- package/skills/gsd-mempalace-capture/SKILL.md +5 -1
- package/skills/gsd-mempalace-recall/SKILL.md +5 -1
- package/skills/gsd-milestone-summary/SKILL.md +5 -1
- package/skills/gsd-mvp-phase/SKILL.md +8 -3
- package/skills/gsd-new-milestone/SKILL.md +6 -1
- package/skills/gsd-new-project/SKILL.md +5 -0
- package/skills/gsd-next/SKILL.md +6 -1
- package/skills/gsd-ns-context/SKILL.md +4 -0
- package/skills/gsd-ns-ideate/SKILL.md +4 -0
- package/skills/gsd-ns-manage/SKILL.md +4 -0
- package/skills/gsd-ns-project/SKILL.md +4 -0
- package/skills/gsd-ns-review/SKILL.md +4 -0
- package/skills/gsd-ns-workflow/SKILL.md +4 -0
- package/skills/gsd-onboard/SKILL.md +6 -1
- package/skills/gsd-pause-work/SKILL.md +5 -1
- package/skills/gsd-phase/SKILL.md +8 -4
- package/skills/gsd-plan-phase/SKILL.md +6 -1
- package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
- package/skills/gsd-pr-branch/SKILL.md +4 -0
- package/skills/gsd-profile-user/SKILL.md +5 -1
- package/skills/gsd-progress/SKILL.md +6 -1
- package/skills/gsd-quick/SKILL.md +16 -10
- package/skills/gsd-quick-batch/SKILL.md +20 -8
- package/skills/gsd-review/SKILL.md +5 -1
- package/skills/gsd-review-backlog/SKILL.md +3 -2
- package/skills/gsd-secure-phase/SKILL.md +6 -1
- package/skills/gsd-ship/SKILL.md +5 -0
- package/skills/gsd-sketch/SKILL.md +7 -2
- package/skills/gsd-spec-phase/SKILL.md +5 -1
- package/skills/gsd-spike/SKILL.md +8 -3
- package/skills/gsd-surface/SKILL.md +5 -1
- package/skills/gsd-thread/SKILL.md +4 -0
- package/skills/gsd-ui-phase/SKILL.md +6 -1
- package/skills/gsd-ui-review/SKILL.md +6 -1
- package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
- package/skills/gsd-undo/SKILL.md +5 -1
- package/skills/gsd-update/SKILL.md +6 -2
- package/skills/gsd-validate-phase/SKILL.md +6 -1
- package/skills/gsd-verify-work/SKILL.md +6 -1
- package/skills/gsd-workspace/SKILL.md +7 -3
- package/skills/gsd-workstreams/SKILL.md +6 -6
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +0 -24
|
@@ -33,11 +33,12 @@ const { installFs, mkInstallTempDir } = installFsAdapter;
|
|
|
33
33
|
const commandRoster = require("./command-roster.cjs");
|
|
34
34
|
const { readGsdCommandNames, transformContentToHyphen } = commandRoster;
|
|
35
35
|
const runtimeNamePolicy = require("./runtime-name-policy.cjs");
|
|
36
|
-
const { getDirName } = runtimeNamePolicy;
|
|
36
|
+
const { getDirName, hostBehaviorsFor } = runtimeNamePolicy;
|
|
37
37
|
const capabilityRegistry = require("./capability-registry.cjs");
|
|
38
38
|
const hostIntegration = require("./host-integration.cjs");
|
|
39
39
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
40
40
|
const frontmatterModule = require("./frontmatter.cjs");
|
|
41
|
+
const frontmatter_fence_cjs_1 = require("./frontmatter-fence.cjs");
|
|
41
42
|
const pattern_cjs_1 = require("./pattern.cjs");
|
|
42
43
|
const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
|
|
43
44
|
// #2870: install-scope.cts is a leaf-tier sibling (imports only
|
|
@@ -93,24 +94,6 @@ function gsdVersion() {
|
|
|
93
94
|
cachedVersion = resolveVersionFrom(__dirname);
|
|
94
95
|
return cachedVersion;
|
|
95
96
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Host-specific install behaviors declared on the runtime descriptor
|
|
98
|
-
* (capabilities/<runtime>/capability.json -> runtime.hostBehaviors). Mirrors
|
|
99
|
-
* bin/install.js's / install-engine.cts's `_hostBehaviors` (ADR-1239 / #2086
|
|
100
|
-
* / #2092). Returns {} for runtimes that declare none, so every behavior
|
|
101
|
-
* branch degrades to the generic path by default. Unlike the bin/install.js
|
|
102
|
-
* and install-engine.cts variants, this module already imports
|
|
103
|
-
* `capabilityRegistry` statically (see NON_CLAUDE_RUNTIMES below), so this
|
|
104
|
-
* reads it directly rather than re-require()-ing inside a try/catch.
|
|
105
|
-
*/
|
|
106
|
-
function _hostBehaviors(runtime) {
|
|
107
|
-
return ((capabilityRegistry &&
|
|
108
|
-
capabilityRegistry.runtimes &&
|
|
109
|
-
capabilityRegistry.runtimes[runtime] &&
|
|
110
|
-
capabilityRegistry.runtimes[runtime].runtime &&
|
|
111
|
-
capabilityRegistry.runtimes[runtime].runtime.hostBehaviors) ||
|
|
112
|
-
{});
|
|
113
|
-
}
|
|
114
97
|
/**
|
|
115
98
|
* Public accessor for the `hostBehaviors.agentFileExtension` descriptor field
|
|
116
99
|
* (ADR-1239 / #2099 / #2103). Returns the runtime's declared agent-file
|
|
@@ -122,7 +105,7 @@ function _hostBehaviors(runtime) {
|
|
|
122
105
|
* duplicating a hardcoded `runtime === 'copilot'` check (#2103 fold).
|
|
123
106
|
*/
|
|
124
107
|
function agentFileExtensionFor(runtime) {
|
|
125
|
-
const ext =
|
|
108
|
+
const ext = hostBehaviorsFor(runtime).agentFileExtension;
|
|
126
109
|
return typeof ext === 'string' ? ext : undefined;
|
|
127
110
|
}
|
|
128
111
|
const colorNameToHex = {
|
|
@@ -485,7 +468,7 @@ function convertClaudeCommandToClaudeSkill(content, skillName, runtime = null, c
|
|
|
485
468
|
// Hermes' SKILL.md spec lists `version` as a required frontmatter field.
|
|
486
469
|
// Track GSD's package version so Hermes' skill_view() reports a stable
|
|
487
470
|
// identifier per install.
|
|
488
|
-
if (runtime
|
|
471
|
+
if (hostBehaviorsFor(runtime).skillFrontmatterVersion) {
|
|
489
472
|
const version = gsdVersion();
|
|
490
473
|
if (version)
|
|
491
474
|
fm += `version: ${yamlQuote(version)}\n`;
|
|
@@ -495,7 +478,7 @@ function convertClaudeCommandToClaudeSkill(content, skillName, runtime = null, c
|
|
|
495
478
|
// runtimes that declare the flag so Claude/Hermes skill frontmatter is
|
|
496
479
|
// unchanged (they ignore the field, but we keep their output byte-stable).
|
|
497
480
|
// skillName is the `gsd-<stem>` dir name. (ADR-1239 / #2092)
|
|
498
|
-
if (
|
|
481
|
+
if (hostBehaviorsFor(runtime).skillPriorityFrontmatter) {
|
|
499
482
|
const stem = typeof skillName === 'string' && skillName.startsWith('gsd-')
|
|
500
483
|
? skillName.slice(4)
|
|
501
484
|
: skillName;
|
|
@@ -730,10 +713,13 @@ function appendAgentTools(content, grants) {
|
|
|
730
713
|
return content;
|
|
731
714
|
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
732
715
|
const lines = content.split(eol);
|
|
733
|
-
|
|
716
|
+
// The block is the one the one fence owner finds; `frontmatterEnd` is its closing fence's
|
|
717
|
+
// line index in `lines`.
|
|
718
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(content);
|
|
719
|
+
if (!fence?.closed)
|
|
734
720
|
return content;
|
|
735
|
-
const frontmatterEnd =
|
|
736
|
-
if (frontmatterEnd
|
|
721
|
+
const frontmatterEnd = content.slice(0, fence.closingStart).split(eol).length - 1;
|
|
722
|
+
if (frontmatterEnd < 1)
|
|
737
723
|
return content;
|
|
738
724
|
const toolsIndex = lines.findIndex((line, index) => index < frontmatterEnd && /^tools:[ \t]*(.*)$/.test(line));
|
|
739
725
|
if (toolsIndex === -1)
|
|
@@ -1080,17 +1066,19 @@ function yamlIdentifier(value) {
|
|
|
1080
1066
|
}
|
|
1081
1067
|
return yamlQuote(text);
|
|
1082
1068
|
}
|
|
1069
|
+
/**
|
|
1070
|
+
* The frontmatter YAML (trimmed) and everything after the closing fence line's text, for the
|
|
1071
|
+
* block the one fence owner (`locateFrontmatterFence`) finds — so a `---` inside a value (a
|
|
1072
|
+
* description that mentions `a---b`) cannot end the block early.
|
|
1073
|
+
*/
|
|
1083
1074
|
function extractFrontmatterAndBody(content) {
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
}
|
|
1087
|
-
const endIndex = content.indexOf('---', 3);
|
|
1088
|
-
if (endIndex === -1) {
|
|
1075
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(content);
|
|
1076
|
+
if (!fence?.closed) {
|
|
1089
1077
|
return { frontmatter: null, body: content };
|
|
1090
1078
|
}
|
|
1091
1079
|
return {
|
|
1092
|
-
frontmatter: content.
|
|
1093
|
-
body: content.
|
|
1080
|
+
frontmatter: content.slice(fence.openEnd, fence.bodyEnd).trim(),
|
|
1081
|
+
body: content.slice(fence.closingFenceEnd),
|
|
1094
1082
|
};
|
|
1095
1083
|
}
|
|
1096
1084
|
function extractFrontmatterField(frontmatter, fieldName) {
|
|
@@ -1539,7 +1527,7 @@ function convertClaudeCommandToTraeSkill(content, skillName) {
|
|
|
1539
1527
|
// is not formally documented (thin SPA docs) — descriptor-driven, single
|
|
1540
1528
|
// fixed GSD-side value (runtime.hostBehaviors.soloStageMetadata), inferred/
|
|
1541
1529
|
// best-effort.
|
|
1542
|
-
const soloStage =
|
|
1530
|
+
const soloStage = hostBehaviorsFor('trae').soloStageMetadata;
|
|
1543
1531
|
if (soloStage)
|
|
1544
1532
|
fm += `stage: ${soloStage}\n`;
|
|
1545
1533
|
fm += '---';
|
|
@@ -1955,17 +1943,11 @@ function convertClaudeToOpencodeFrontmatter(content, { isAgent = false, modelOve
|
|
|
1955
1943
|
convertedContent = convertedContent.replace(/subagent_type="general-purpose"/g, 'subagent_type="general"');
|
|
1956
1944
|
// Runtime-neutral agent name replacement (#766)
|
|
1957
1945
|
convertedContent = neutralizeAgentReferences(convertedContent, 'AGENTS.md');
|
|
1958
|
-
//
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
}
|
|
1962
|
-
// Find the end of frontmatter
|
|
1963
|
-
const endIndex = convertedContent.indexOf('---', 3);
|
|
1964
|
-
if (endIndex === -1) {
|
|
1946
|
+
// The frontmatter block, as the one fence owner finds it (none → nothing to convert).
|
|
1947
|
+
const { frontmatter, body } = extractFrontmatterAndBody(convertedContent);
|
|
1948
|
+
if (frontmatter === null) {
|
|
1965
1949
|
return convertedContent;
|
|
1966
1950
|
}
|
|
1967
|
-
const frontmatter = convertedContent.substring(3, endIndex).trim();
|
|
1968
|
-
const body = convertedContent.substring(endIndex + 3);
|
|
1969
1951
|
// Parse frontmatter line by line (simple YAML parsing)
|
|
1970
1952
|
const lines = frontmatter.split('\n');
|
|
1971
1953
|
const newLines = [];
|
|
@@ -2121,17 +2103,11 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
2121
2103
|
convertedContent = convertedContent.replace(/subagent_type="general-purpose"/g, 'subagent_type="general"');
|
|
2122
2104
|
// Runtime-neutral agent name replacement (#766)
|
|
2123
2105
|
convertedContent = neutralizeAgentReferences(convertedContent, 'AGENTS.md');
|
|
2124
|
-
//
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
}
|
|
2128
|
-
// Find the end of frontmatter
|
|
2129
|
-
const endIndex = convertedContent.indexOf('---', 3);
|
|
2130
|
-
if (endIndex === -1) {
|
|
2106
|
+
// The frontmatter block, as the one fence owner finds it (none → nothing to convert).
|
|
2107
|
+
const { frontmatter, body } = extractFrontmatterAndBody(convertedContent);
|
|
2108
|
+
if (frontmatter === null) {
|
|
2131
2109
|
return convertedContent;
|
|
2132
2110
|
}
|
|
2133
|
-
const frontmatter = convertedContent.substring(3, endIndex).trim();
|
|
2134
|
-
const body = convertedContent.substring(endIndex + 3);
|
|
2135
2111
|
// Parse frontmatter line by line (simple YAML parsing)
|
|
2136
2112
|
const lines = frontmatter.split('\n');
|
|
2137
2113
|
const newLines = [];
|
|
@@ -2526,7 +2502,7 @@ function convertClaudeAgentToTraeAgent(content) {
|
|
|
2526
2502
|
* forms to avoid double-rewriting the same substring.
|
|
2527
2503
|
*/
|
|
2528
2504
|
function convertClaudeAgentToQwenAgent(content) {
|
|
2529
|
-
const _b =
|
|
2505
|
+
const _b = hostBehaviorsFor('qwen').brandingRewrites || {};
|
|
2530
2506
|
let converted = content;
|
|
2531
2507
|
if (_b['CLAUDE.md'])
|
|
2532
2508
|
converted = converted.replace(/CLAUDE\.md/g, _b['CLAUDE.md']);
|
|
@@ -2591,18 +2567,14 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2591
2567
|
// present. The unchanged scan below still preserves byte-identical content.
|
|
2592
2568
|
if (!content.includes('mcp__') && !content.includes('\\'))
|
|
2593
2569
|
return content;
|
|
2594
|
-
|
|
2595
|
-
|
|
2570
|
+
// The block is the one the one fence owner finds; unterminated (or absent) → leave verbatim.
|
|
2571
|
+
// The rewrite below re-joins lines on '\n', so a CRLF block is left verbatim too rather than
|
|
2572
|
+
// given mixed line endings.
|
|
2573
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(content);
|
|
2574
|
+
if (!fence?.closed || fence.eol !== '\n')
|
|
2596
2575
|
return content;
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
if (lines[i] === '---') {
|
|
2600
|
-
fmEnd = i;
|
|
2601
|
-
break;
|
|
2602
|
-
}
|
|
2603
|
-
}
|
|
2604
|
-
if (fmEnd === -1)
|
|
2605
|
-
return content; // unterminated frontmatter — leave verbatim
|
|
2576
|
+
const lines = content.split('\n');
|
|
2577
|
+
const fmEnd = content.slice(0, fence.closingStart).split('\n').length - 1;
|
|
2606
2578
|
const out = [];
|
|
2607
2579
|
let changed = false;
|
|
2608
2580
|
let i = 1;
|
|
@@ -2699,12 +2671,12 @@ function convertClaudeAgentToClineAgent(content) {
|
|
|
2699
2671
|
* rewrites applied automatically. A runtime with no `brandingRewrites`
|
|
2700
2672
|
* declared returns `content` unchanged (no rewrite table to apply).
|
|
2701
2673
|
*
|
|
2702
|
-
* Byte-identical to the inline loop's `else if (
|
|
2674
|
+
* Byte-identical to the inline loop's `else if (hostBehaviorsFor(runtime).brandingRewrites)`
|
|
2703
2675
|
* branch, including plain (non-word-boundary) `.replace(/\bClaude Code\b/g, ...)`
|
|
2704
2676
|
* semantics — J9.
|
|
2705
2677
|
*/
|
|
2706
2678
|
function applyAgentBrandingRewrites(content, runtime) {
|
|
2707
|
-
const _b =
|
|
2679
|
+
const _b = hostBehaviorsFor(runtime).brandingRewrites;
|
|
2708
2680
|
if (!_b)
|
|
2709
2681
|
return content;
|
|
2710
2682
|
let converted = content;
|
|
@@ -2890,7 +2862,7 @@ function projectRelativePrefixFromProjectRoot(projectRoot, resolvedTarget) {
|
|
|
2890
2862
|
* directory in a project-relative include: that directory was never created.
|
|
2891
2863
|
*/
|
|
2892
2864
|
function localIncludeDirName(runtime) {
|
|
2893
|
-
return
|
|
2865
|
+
return hostBehaviorsFor(runtime).localTargetIsProjectRoot === true ? undefined : getDirName(runtime);
|
|
2894
2866
|
}
|
|
2895
2867
|
/**
|
|
2896
2868
|
* #4377: the project-relative prefix for a local install, or `''` when the
|
|
@@ -3194,11 +3166,16 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3194
3166
|
// #1521: stamp runtime identity + use_worktrees=false for every non-Claude runtime
|
|
3195
3167
|
// before brand-specific path rewrites, so the replace operates on the pristine
|
|
3196
3168
|
// source line and is idempotent regardless of subsequent path substitutions.
|
|
3197
|
-
|
|
3169
|
+
// #5169: the descriptor declares which hosts skip the stamp
|
|
3170
|
+
// (`hostBehaviors.skipRuntimeDefaultsStamp`) and which rewrite profile applies
|
|
3171
|
+
// (`hostBehaviors.contentRewriteProfile`). The switch below is keyed by PROFILE
|
|
3172
|
+
// name, not runtime id, so two hosts that share a body share one case.
|
|
3173
|
+
const rewriteBehaviors = hostBehaviorsFor(runtime);
|
|
3174
|
+
if (!rewriteBehaviors.skipRuntimeDefaultsStamp) {
|
|
3198
3175
|
content = _stampNonClaudeRuntimeDefaults(content, runtime);
|
|
3199
3176
|
}
|
|
3200
|
-
switch (
|
|
3201
|
-
case '
|
|
3177
|
+
switch (rewriteBehaviors.contentRewriteProfile) {
|
|
3178
|
+
case 'slash-own-tilde':
|
|
3202
3179
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3203
3180
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3204
3181
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3206,7 +3183,7 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3206
3183
|
// #1515 stamp moved to _stampNonClaudeRuntimeDefaults (#1521 generalisation).
|
|
3207
3184
|
content = processAttribution(content, attribution);
|
|
3208
3185
|
break;
|
|
3209
|
-
case '
|
|
3186
|
+
case 'slash-bare-own-tilde':
|
|
3210
3187
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3211
3188
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3212
3189
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3218,7 +3195,7 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3218
3195
|
content = content.replace(/\$HOME\/\.cline\b/g, normalizedPathPrefix);
|
|
3219
3196
|
content = processAttribution(content, attribution);
|
|
3220
3197
|
break;
|
|
3221
|
-
case '
|
|
3198
|
+
case 'slash-lookahead-own-tilde':
|
|
3222
3199
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3223
3200
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3224
3201
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3228,7 +3205,7 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3228
3205
|
content = content.replace(/~\/\.cursor\//g, pathPrefix);
|
|
3229
3206
|
content = processAttribution(content, attribution);
|
|
3230
3207
|
break;
|
|
3231
|
-
case '
|
|
3208
|
+
case 'slash-lookahead-nested-own-devin': {
|
|
3232
3209
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3233
3210
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3234
3211
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3244,7 +3221,7 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3244
3221
|
content = processAttribution(content, attribution);
|
|
3245
3222
|
break;
|
|
3246
3223
|
}
|
|
3247
|
-
case '
|
|
3224
|
+
case 'slash-lookahead-own-derived': {
|
|
3248
3225
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3249
3226
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3250
3227
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3262,7 +3239,7 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3262
3239
|
content = processAttribution(content, attribution);
|
|
3263
3240
|
break;
|
|
3264
3241
|
}
|
|
3265
|
-
case '
|
|
3242
|
+
case 'slash-bare-own-derived':
|
|
3266
3243
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3267
3244
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3268
3245
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3275,7 +3252,7 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3275
3252
|
content = content.replace(new RegExp('~/' + (0, pattern_cjs_1.escapeRegex)(dirName) + '/', 'g'), pathPrefix);
|
|
3276
3253
|
content = processAttribution(content, attribution);
|
|
3277
3254
|
break;
|
|
3278
|
-
case '
|
|
3255
|
+
case 'slash-bare-own-tilde-bare':
|
|
3279
3256
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3280
3257
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3281
3258
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3288,13 +3265,14 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3288
3265
|
content = content.replace(/\$HOME\/\.codebuddy\b/g, normalizedPathPrefix);
|
|
3289
3266
|
content = processAttribution(content, attribution);
|
|
3290
3267
|
break;
|
|
3291
|
-
case '
|
|
3268
|
+
case 'attribution-only':
|
|
3292
3269
|
content = processAttribution(content, attribution);
|
|
3293
3270
|
break;
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3271
|
+
// claude and zcode share this profile. #4002: ZCode is a Claude-Code-shaped
|
|
3272
|
+
// host (dot-home `.zcode`, `@~`-ref expansion, `~/.zcode/...` documented
|
|
3273
|
+
// paths) whose commands install with `converter: null` — this pass is their
|
|
3274
|
+
// only chance to receive runtime-correct paths, including the tilde restore.
|
|
3275
|
+
case 'slash-tilde-restore':
|
|
3298
3276
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3299
3277
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3300
3278
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3308,37 +3286,15 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3308
3286
|
// brand VALUES (CLAUDE.md/Claude Code/.claude/ replacements) now read from
|
|
3309
3287
|
// runtime.hostBehaviors.brandingRewrites instead of hardcoded literals.
|
|
3310
3288
|
// EXACT regexes/order preserved — only the replacement values changed.
|
|
3311
|
-
|
|
3289
|
+
// qwen and hermes share this profile; their own dot-dir is derived from the
|
|
3290
|
+
// descriptor's `localConfigDir` (`getDirName`) rather than spelled per host.
|
|
3291
|
+
case 'branded-lookahead-own-derived': {
|
|
3312
3292
|
// Guarded (post-review #2092): brandingRewrites is undefined if the
|
|
3313
3293
|
// capability registry fails to load — degrade closed (skip the
|
|
3314
3294
|
// brand-literal replacements, still apply the non-branding path
|
|
3315
3295
|
// rewrites below) instead of throwing on `_b['CLAUDE.md']`.
|
|
3316
|
-
const _b =
|
|
3317
|
-
|
|
3318
|
-
content = content.replace(/CLAUDE\.md/g, _b['CLAUDE.md']);
|
|
3319
|
-
// #2284(b): skips <runtime_compatibility> comparison-table content (protected region).
|
|
3320
|
-
content = applyClaudeCodeBrandSwap(content, _b['Claude Code']);
|
|
3321
|
-
}
|
|
3322
|
-
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3323
|
-
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3324
|
-
content = content.replace(/~\/\.qwen\//g, pathPrefix);
|
|
3325
|
-
content = content.replace(/\$HOME\/\.qwen\//g, pathPrefix);
|
|
3326
|
-
content = content.replace(/~\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
|
3327
|
-
content = content.replace(/\$HOME\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
|
3328
|
-
content = content.replace(/~\/\.qwen(?![\w-])/g, normalizedPathPrefix);
|
|
3329
|
-
content = content.replace(/\$HOME\/\.qwen(?![\w-])/g, normalizedPathPrefix);
|
|
3330
|
-
if (_b) {
|
|
3331
|
-
content = content.replace(/\.claude\//g, _b['.claude/']);
|
|
3332
|
-
}
|
|
3333
|
-
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
3334
|
-
content = content.replace(/\.\/\.qwen\//g, `./${dirName}/`);
|
|
3335
|
-
content = processAttribution(content, attribution);
|
|
3336
|
-
break;
|
|
3337
|
-
}
|
|
3338
|
-
case 'hermes': {
|
|
3339
|
-
// Guarded (post-review #2092): see qwen case above — same degrade-closed
|
|
3340
|
-
// rationale.
|
|
3341
|
-
const _b = _hostBehaviors(runtime).brandingRewrites;
|
|
3296
|
+
const _b = rewriteBehaviors.brandingRewrites;
|
|
3297
|
+
const _own = (0, pattern_cjs_1.escapeRegex)(dirName);
|
|
3342
3298
|
if (_b) {
|
|
3343
3299
|
content = content.replace(/CLAUDE\.md/g, _b['CLAUDE.md']);
|
|
3344
3300
|
// #2284(b): skips <runtime_compatibility> comparison-table content (protected region).
|
|
@@ -3346,21 +3302,21 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3346
3302
|
}
|
|
3347
3303
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3348
3304
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3349
|
-
content = content.replace(
|
|
3350
|
-
content = content.replace(
|
|
3305
|
+
content = content.replace(new RegExp('~/' + _own + '/', 'g'), pathPrefix);
|
|
3306
|
+
content = content.replace(new RegExp('\\$HOME/' + _own + '/', 'g'), pathPrefix);
|
|
3351
3307
|
content = content.replace(/~\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
|
3352
3308
|
content = content.replace(/\$HOME\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
|
3353
|
-
content = content.replace(
|
|
3354
|
-
content = content.replace(
|
|
3309
|
+
content = content.replace(new RegExp('~/' + _own + '(?![\\w-])', 'g'), normalizedPathPrefix);
|
|
3310
|
+
content = content.replace(new RegExp('\\$HOME/' + _own + '(?![\\w-])', 'g'), normalizedPathPrefix);
|
|
3355
3311
|
if (_b) {
|
|
3356
3312
|
content = content.replace(/\.claude\//g, _b['.claude/']);
|
|
3357
3313
|
}
|
|
3358
3314
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
3359
|
-
content = content.replace(
|
|
3315
|
+
content = content.replace(new RegExp('\\./' + _own + '/', 'g'), `./${dirName}/`);
|
|
3360
3316
|
content = processAttribution(content, attribution);
|
|
3361
3317
|
break;
|
|
3362
3318
|
}
|
|
3363
|
-
case '
|
|
3319
|
+
case 'slash-bare':
|
|
3364
3320
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3365
3321
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3366
3322
|
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
@@ -3369,22 +3325,8 @@ function _applyRuntimeRewritesInner(content, runtime, pathPrefix, isGlobal = fal
|
|
|
3369
3325
|
content = content.replace(/\.\/\.claude\b/g, `./${dirName}`);
|
|
3370
3326
|
content = processAttribution(content, attribution);
|
|
3371
3327
|
break;
|
|
3372
|
-
case 'zcode':
|
|
3373
|
-
// #4002: ZCode is a Claude-Code-shaped host (dot-home `.zcode`, `@~`-ref
|
|
3374
|
-
// expansion, `~/.zcode/...` documented paths) whose commands install with
|
|
3375
|
-
// `converter: null` — this pass is their only chance to receive
|
|
3376
|
-
// runtime-correct paths. Same shape as `claude`, including the tilde
|
|
3377
|
-
// restore: the tilde form is what ZCode expands and what its docs use.
|
|
3378
|
-
// `${_GSD_RUNTIME_ROOT}/.claude/…` matches none of these regexes and
|
|
3379
|
-
// survives as the project-local fallback, exactly as on every sibling.
|
|
3380
|
-
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3381
|
-
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3382
|
-
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
3383
|
-
content = restoreClaudeGlobalAtRefTilde(content, pathPrefix);
|
|
3384
|
-
content = processAttribution(content, attribution);
|
|
3385
|
-
break;
|
|
3386
3328
|
default:
|
|
3387
|
-
//
|
|
3329
|
+
// No profile declared — no rewrites (OpenCode/Kilo handled by their own install path).
|
|
3388
3330
|
break;
|
|
3389
3331
|
}
|
|
3390
3332
|
return content;
|
|
@@ -3450,7 +3392,7 @@ function applyRuntimeContentRewritesForCommandsInPlace(stagedDir, runtime, pathP
|
|
|
3450
3392
|
content = _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal, attribution);
|
|
3451
3393
|
// #2097 (ADR-1239): descriptor-driven — commandBodyConverter name comes
|
|
3452
3394
|
// from runtime.hostBehaviors instead of a hardcoded runtime-name branch.
|
|
3453
|
-
const _cmdConv =
|
|
3395
|
+
const _cmdConv = hostBehaviorsFor(runtime).commandBodyConverter;
|
|
3454
3396
|
if (_cmdConv && COMMAND_BODY_CONVERTERS[_cmdConv]) {
|
|
3455
3397
|
content = COMMAND_BODY_CONVERTERS[_cmdConv](content);
|
|
3456
3398
|
}
|
|
@@ -3539,7 +3481,7 @@ function rewriteStagedSkillBodies(stagedDir, opts) {
|
|
|
3539
3481
|
// no skills-kind entry at local scope, so this is already structurally
|
|
3540
3482
|
// scoped to global (row 23) — the explicit isGlobal check is defense-in-depth
|
|
3541
3483
|
// against that descriptor wiring ever changing.
|
|
3542
|
-
if (runtime
|
|
3484
|
+
if (hostBehaviorsFor(runtime).specRootSkillPass && isGlobal) {
|
|
3543
3485
|
applySpecRootReferenceToStagedSkills(stagedDir);
|
|
3544
3486
|
}
|
|
3545
3487
|
}
|
|
@@ -3591,7 +3533,7 @@ function rewriteStagedCommandBodies(stagedDir, opts) {
|
|
|
3591
3533
|
* @param cmdNames gsd command names from readGsdCommandNames()
|
|
3592
3534
|
*/
|
|
3593
3535
|
function normalizeAgentBodyForRuntime(content, runtime, cmdNames) {
|
|
3594
|
-
if (
|
|
3536
|
+
if (hostBehaviorsFor(runtime).hyphenNameAgentBody !== true)
|
|
3595
3537
|
return content;
|
|
3596
3538
|
return transformContentToHyphen(content, cmdNames);
|
|
3597
3539
|
}
|
|
@@ -3621,7 +3563,7 @@ function normalizeAgentBodyForRuntime(content, runtime, cmdNames) {
|
|
|
3621
3563
|
* @returns content with path-prefix rewrites applied (or unchanged for noPathRewrite runtimes, e.g. copilot)
|
|
3622
3564
|
*/
|
|
3623
3565
|
function applyAgentPathRewrites(content, runtime, pathPrefix) {
|
|
3624
|
-
if (
|
|
3566
|
+
if (hostBehaviorsFor(runtime).noPathRewrite === true)
|
|
3625
3567
|
return content;
|
|
3626
3568
|
// #4377: the agents pipeline is the third emit path that substitutes this
|
|
3627
3569
|
// prefix (skills/commands via _applyRuntimeRewrites, the gsd-core spec tree
|
|
@@ -3663,7 +3605,7 @@ function applyAgentPathRewritesInner(content, runtime, pathPrefix) {
|
|
|
3663
3605
|
// anchored to the exact prefix string it is handed — so `restore(pathPrefix)`
|
|
3664
3606
|
// fixes `@$HOME/.claude/x` and leaves a bare `@$HOME/.claude` broken. The
|
|
3665
3607
|
// normalized form is a PREFIX of both, so one call covers both.
|
|
3666
|
-
if (runtime
|
|
3608
|
+
if (hostBehaviorsFor(runtime).restoreAtRefTildeInAgents) {
|
|
3667
3609
|
content = restoreClaudeGlobalAtRefTilde(content, normalizedPathPrefix);
|
|
3668
3610
|
}
|
|
3669
3611
|
return content;
|
|
@@ -3687,8 +3629,8 @@ function deriveAgentName(fileName) {
|
|
|
3687
3629
|
* `applyAgentFrontmatterExtensions` below for the orchestration that calls it.
|
|
3688
3630
|
*
|
|
3689
3631
|
* The function:
|
|
3690
|
-
* -
|
|
3691
|
-
* otherwise LF).
|
|
3632
|
+
* - Reads the block the one fence owner (`locateFrontmatterFence`) finds, and
|
|
3633
|
+
* its EOL (CRLF if the opening `---` line ends with \r\n, otherwise LF).
|
|
3692
3634
|
* - Skips injection if an `effort:` key already exists in the frontmatter
|
|
3693
3635
|
* (idempotent).
|
|
3694
3636
|
* - Inserts `effort: <value>` immediately before the closing `---` delimiter,
|
|
@@ -3697,19 +3639,15 @@ function deriveAgentName(fileName) {
|
|
|
3697
3639
|
* - Returns the original content unchanged when no YAML frontmatter is found.
|
|
3698
3640
|
*/
|
|
3699
3641
|
function injectEffortFrontmatter(content, effortValue) {
|
|
3700
|
-
const
|
|
3701
|
-
|
|
3702
|
-
const match = fmRe.exec(content);
|
|
3703
|
-
if (!match)
|
|
3642
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(content);
|
|
3643
|
+
if (!fence?.closed)
|
|
3704
3644
|
return content; // no YAML frontmatter — leave unchanged
|
|
3705
|
-
const fmBody =
|
|
3645
|
+
const fmBody = content.slice(fence.openEnd, fence.closingStart); // content between the two fences
|
|
3706
3646
|
if (/^effort:/m.test(fmBody))
|
|
3707
3647
|
return content;
|
|
3708
|
-
const
|
|
3709
|
-
const
|
|
3710
|
-
|
|
3711
|
-
const after = content.slice(closingStart);
|
|
3712
|
-
return `${before}effort: ${effortValue}${eol}${after}`;
|
|
3648
|
+
const before = content.slice(0, fence.closingStart);
|
|
3649
|
+
const after = content.slice(fence.closingStart);
|
|
3650
|
+
return `${before}effort: ${effortValue}${fence.eol}${after}`;
|
|
3713
3651
|
}
|
|
3714
3652
|
/**
|
|
3715
3653
|
* #767 — Inject `disallowedTools: <value>` into the YAML frontmatter of a
|
|
@@ -3719,19 +3657,15 @@ function injectEffortFrontmatter(content, effortValue) {
|
|
|
3719
3657
|
* frontmatter keys. Relocated verbatim from bin/install.js (#2875 Part 2).
|
|
3720
3658
|
*/
|
|
3721
3659
|
function injectDisallowedToolsFrontmatter(content, disallowedValue) {
|
|
3722
|
-
const
|
|
3723
|
-
|
|
3724
|
-
const match = fmRe.exec(content);
|
|
3725
|
-
if (!match)
|
|
3660
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(content);
|
|
3661
|
+
if (!fence?.closed)
|
|
3726
3662
|
return content; // no YAML frontmatter — leave unchanged
|
|
3727
|
-
const fmBody =
|
|
3663
|
+
const fmBody = content.slice(fence.openEnd, fence.closingStart); // content between the two fences
|
|
3728
3664
|
if (/^disallowedTools:/m.test(fmBody))
|
|
3729
3665
|
return content;
|
|
3730
|
-
const
|
|
3731
|
-
const
|
|
3732
|
-
|
|
3733
|
-
const after = content.slice(closingStart);
|
|
3734
|
-
return `${before}disallowedTools: ${disallowedValue}${eol}${after}`;
|
|
3666
|
+
const before = content.slice(0, fence.closingStart);
|
|
3667
|
+
const after = content.slice(fence.closingStart);
|
|
3668
|
+
return `${before}disallowedTools: ${disallowedValue}${fence.eol}${after}`;
|
|
3735
3669
|
}
|
|
3736
3670
|
// #767 — Read-only verifier/auditor agents get a Claude-Code disallowedTools deny-list.
|
|
3737
3671
|
// Group A (pure read-only) deny Write,Edit,MultiEdit. Group B report-writers Write one
|
|
@@ -3757,7 +3691,7 @@ const READONLY_AGENT_DISALLOWED_TOOLS = {
|
|
|
3757
3691
|
* OpenCode/Qwen/Hermes reject unknown frontmatter keys.
|
|
3758
3692
|
*
|
|
3759
3693
|
* Byte-identical to the inline agent loop's
|
|
3760
|
-
* `if ((
|
|
3694
|
+
* `if ((hostBehaviorsFor(runtime).agentFrontmatterExtensions || []).includes('effort'))`
|
|
3761
3695
|
* block (bin/install.js): both the effort injection AND the disallowedTools
|
|
3762
3696
|
* injection are gated behind the SAME `'effort'` extension flag — there is no
|
|
3763
3697
|
* separate `'disallowedTools'` extension key, mirroring the loop exactly.
|
|
@@ -3772,7 +3706,7 @@ const READONLY_AGENT_DISALLOWED_TOOLS = {
|
|
|
3772
3706
|
* @param targetDir install root — resolves .planning/config.json + ~/.gsd/defaults.json
|
|
3773
3707
|
*/
|
|
3774
3708
|
function applyAgentFrontmatterExtensions(content, { runtime, agentName, targetDir }) {
|
|
3775
|
-
const extensions =
|
|
3709
|
+
const extensions = hostBehaviorsFor(runtime).agentFrontmatterExtensions || [];
|
|
3776
3710
|
if (!extensions.includes('effort'))
|
|
3777
3711
|
return content;
|
|
3778
3712
|
let result = content;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
const _require = require;
|
|
11
11
|
const path = _require('node:path');
|
|
12
12
|
const { tryWithinRootLexical } = _require('./security.cjs');
|
|
13
|
+
const { hostBehaviorsFor } = _require('./runtime-name-policy.cjs');
|
|
13
14
|
// #2870: InstallScope is owned by install-scope.cts, not re-declared here.
|
|
14
15
|
// `isGlobalScope` centralizes the `scope === 'global'` boolean projection
|
|
15
16
|
// this module needs at `_computePathPrefix`'s `isGlobal: boolean` boundary
|
|
@@ -90,7 +91,7 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
90
91
|
// `undefined` here) — `isGlobalScope` projects it to the boolean
|
|
91
92
|
// `_computePathPrefix`'s existing `isGlobal: boolean` API requires.
|
|
92
93
|
const isGlobal = (0, install_scope_cjs_1.isGlobalScope)(scope);
|
|
93
|
-
const isOpencode = layout.runtime ===
|
|
94
|
+
const isOpencode = hostBehaviorsFor(layout.runtime).opencodePathPrefix === true;
|
|
94
95
|
const isWindowsHost = (platform ?? process.platform) === 'win32';
|
|
95
96
|
// #4377: descriptor-derived local dir name, so an opted-in local install
|
|
96
97
|
// emits a project-relative prefix instead of this checkout's absolute path.
|
|
@@ -957,4 +957,60 @@ function resolveTriggerSurface(runtime, scopes, opts) {
|
|
|
957
957
|
}
|
|
958
958
|
return surfaces;
|
|
959
959
|
}
|
|
960
|
-
|
|
960
|
+
// ---------------------------------------------------------------------------
|
|
961
|
+
// The advertised "next step" command (#5215, ADR-5057 §5 Phase 12).
|
|
962
|
+
//
|
|
963
|
+
// What the installer tells a user to run is a projection of what the runtime
|
|
964
|
+
// registered: the `new-project` trigger the Trigger Surface resolves for the
|
|
965
|
+
// install scope. It is never a per-runtime literal, so a runtime that registers
|
|
966
|
+
// no such trigger (pi's native extension registers only `/gsd`; windsurf's
|
|
967
|
+
// global layout registers nothing) cannot be told to run one (#4567).
|
|
968
|
+
// ---------------------------------------------------------------------------
|
|
969
|
+
/** The cross-agent default for an id GSD cannot know (ADR-5057 §5 Phase 10 amendment). */
|
|
970
|
+
const DEFAULT_NEW_PROJECT_COMMAND = '/gsd-new-project';
|
|
971
|
+
/**
|
|
972
|
+
* How a host invokes a registered trigger. Presentation only — whether the
|
|
973
|
+
* trigger exists is decided by the registered surface, not by this table. A
|
|
974
|
+
* runtime absent here is invoked as `/<trigger>`.
|
|
975
|
+
*/
|
|
976
|
+
const TRIGGER_INVOCATION = {
|
|
977
|
+
codex: (trigger) => `$${trigger}`,
|
|
978
|
+
cursor: (trigger) => `${trigger} (mention the skill name)`,
|
|
979
|
+
kimi: (trigger) => `/skill:${trigger}`,
|
|
980
|
+
};
|
|
981
|
+
/**
|
|
982
|
+
* The command a native-extension runtime registers instead of per-workflow
|
|
983
|
+
* triggers: the extension file's stem as a slash command (pi's `gsd.js`
|
|
984
|
+
* registers `/gsd`; pinned by tests/advertised-command-parity.test.cjs against
|
|
985
|
+
* the extension itself). `null` for a runtime with no native plugin.
|
|
986
|
+
*/
|
|
987
|
+
function nativePluginCommand(runtime) {
|
|
988
|
+
const descriptor = getTriggerRegistry().runtimes[runtime]?.runtime;
|
|
989
|
+
const file = descriptor?.hostBehaviors?.nativePlugin?.file;
|
|
990
|
+
if (typeof file !== 'string' || file.length === 0)
|
|
991
|
+
return null;
|
|
992
|
+
const stem = file.replace(/\.[^.]+$/, '');
|
|
993
|
+
return stem.length > 0 ? `/${stem}` : null;
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* The command the installer advertises for starting a project, generated from
|
|
997
|
+
* the registered trigger surface of `runtime` in `scope`. `unregistered` means
|
|
998
|
+
* the runtime registers no `new-project` trigger there (`nativeCommand` names
|
|
999
|
+
* what a native-extension runtime registers instead). An empty or unregistered
|
|
1000
|
+
* id keeps the documented cross-agent default: it names a runtime GSD cannot
|
|
1001
|
+
* know, so no surface exists to project from. Membership is decided up front,
|
|
1002
|
+
* so an error inside the surface resolution is a bug and propagates.
|
|
1003
|
+
*/
|
|
1004
|
+
function resolveAdvertisedNewProject(runtime, scope) {
|
|
1005
|
+
const known = Boolean(runtime) && Object.prototype.hasOwnProperty.call(getTriggerRegistry().runtimes, runtime);
|
|
1006
|
+
if (!known)
|
|
1007
|
+
return { kind: 'command', command: DEFAULT_NEW_PROJECT_COMMAND };
|
|
1008
|
+
const registered = resolveTriggerSurface(runtime, [scope], { stems: ['new-project'] })[0];
|
|
1009
|
+
if (!registered)
|
|
1010
|
+
return { kind: 'unregistered', nativeCommand: nativePluginCommand(runtime) };
|
|
1011
|
+
const render = Object.prototype.hasOwnProperty.call(TRIGGER_INVOCATION, runtime)
|
|
1012
|
+
? TRIGGER_INVOCATION[runtime]
|
|
1013
|
+
: (trigger) => `/${trigger}`;
|
|
1014
|
+
return { kind: 'command', command: render(registered.trigger) };
|
|
1015
|
+
}
|
|
1016
|
+
module.exports = { resolveRuntimeArtifactLayout, resolveRuntimeArtifactLayoutFromRegistry, findInstallSourceRoot, resolveTriggerSurface, resolveAdvertisedNewProject, isNamespacedByDir, composeCommandFilename };
|