@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
|
@@ -37,6 +37,7 @@ const { getDirName } = 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
|
+
const frontmatterModule = require("./frontmatter.cjs");
|
|
40
41
|
const pattern_cjs_1 = require("./pattern.cjs");
|
|
41
42
|
const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
|
|
42
43
|
// #2870: install-scope.cts is a leaf-tier sibling (imports only
|
|
@@ -275,8 +276,22 @@ const kiloAgentPermissionOrder = [
|
|
|
275
276
|
'codesearch',
|
|
276
277
|
'lsp',
|
|
277
278
|
];
|
|
279
|
+
const kiloMcpPermissionPattern = /^mcp__([A-Za-z0-9_-]+)__((?:[A-Za-z0-9_-]+)|\*)$/;
|
|
280
|
+
/**
|
|
281
|
+
* Derive Kilo's native `{server}_{tool}` MCP permission key (kilo.ai/docs —
|
|
282
|
+
* external, fixed format we don't control). Not injective: both capture
|
|
283
|
+
* groups allow `_`, so e.g. `mcp__a_b__c` and `mcp__a__b_c` derive the same
|
|
284
|
+
* key. `buildKiloAgentPermissionBlock`'s `Set` resolves any such collision
|
|
285
|
+
* deterministically to first-seen-wins — see its regression test. Changing
|
|
286
|
+
* the derivation to avoid the collision isn't an option: Kilo's own runtime
|
|
287
|
+
* only recognizes this exact key shape.
|
|
288
|
+
*/
|
|
278
289
|
function convertClaudeToKiloPermissionTool(claudeTool) {
|
|
279
|
-
|
|
290
|
+
const builtinPermission = claudeToKiloAgentPermissions[claudeTool];
|
|
291
|
+
if (builtinPermission)
|
|
292
|
+
return builtinPermission;
|
|
293
|
+
const mcpPermission = kiloMcpPermissionPattern.exec(claudeTool);
|
|
294
|
+
return mcpPermission ? `${mcpPermission[1]}_${mcpPermission[2]}` : null;
|
|
280
295
|
}
|
|
281
296
|
function buildKiloAgentPermissionBlock(claudeTools) {
|
|
282
297
|
const allowedPermissions = new Set();
|
|
@@ -290,6 +305,11 @@ function buildKiloAgentPermissionBlock(claudeTools) {
|
|
|
290
305
|
for (const permission of kiloAgentPermissionOrder) {
|
|
291
306
|
lines.push(` ${permission}: ${allowedPermissions.has(permission) ? 'allow' : 'deny'}`);
|
|
292
307
|
}
|
|
308
|
+
for (const permission of allowedPermissions) {
|
|
309
|
+
if (kiloAgentPermissionOrder.includes(permission))
|
|
310
|
+
continue;
|
|
311
|
+
lines.push(` ${permission}: allow`);
|
|
312
|
+
}
|
|
293
313
|
return lines;
|
|
294
314
|
}
|
|
295
315
|
function replaceRelativePathReference(content, fromPath, toPath) {
|
|
@@ -644,6 +664,137 @@ function convertClaudeCommandToKimiCodeSkill(content, skillName, _runtime = null
|
|
|
644
664
|
return convertClaudeCommandToKimiSkill(content, skillName, _runtime, cmdNames);
|
|
645
665
|
}
|
|
646
666
|
const KIMI_CANONICAL_GSD_AGENT_RE = /^gsd-[a-z0-9-]+$/;
|
|
667
|
+
/** Split a `tools:` comma list without tearing a quoted scalar that contains a literal comma. */
|
|
668
|
+
function splitToolScalars(text) {
|
|
669
|
+
const parts = [];
|
|
670
|
+
let current = '';
|
|
671
|
+
let quote = null;
|
|
672
|
+
for (const ch of text) {
|
|
673
|
+
if (quote) {
|
|
674
|
+
current += ch;
|
|
675
|
+
if (ch === quote)
|
|
676
|
+
quote = null;
|
|
677
|
+
}
|
|
678
|
+
else if (ch === '"' || ch === "'") {
|
|
679
|
+
quote = ch;
|
|
680
|
+
current += ch;
|
|
681
|
+
}
|
|
682
|
+
else if (ch === ',') {
|
|
683
|
+
parts.push(current);
|
|
684
|
+
current = '';
|
|
685
|
+
}
|
|
686
|
+
else {
|
|
687
|
+
current += ch;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
parts.push(current);
|
|
691
|
+
return parts;
|
|
692
|
+
}
|
|
693
|
+
/** Normalize one complete frontmatter tool scalar through the shared YAML parser. */
|
|
694
|
+
function decodeToolScalar(raw) {
|
|
695
|
+
if (typeof raw !== 'string')
|
|
696
|
+
return null;
|
|
697
|
+
const value = raw.trim();
|
|
698
|
+
if (!value)
|
|
699
|
+
return null;
|
|
700
|
+
if (value.startsWith('"') || value.startsWith("'")) {
|
|
701
|
+
try {
|
|
702
|
+
const decoded = frontmatterModule.parseFrontmatter('---\ntool: ' + value + '\n---\n').tool;
|
|
703
|
+
return typeof decoded === 'string' && decoded.trim() ? decoded.trim() : null;
|
|
704
|
+
}
|
|
705
|
+
catch {
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
// A bare (unquoted) scalar may carry a trailing ` # comment` (YAML requires
|
|
710
|
+
// whitespace before `#` to start a comment) — every caller here passes a
|
|
711
|
+
// single already-comma-split token, never the whole `tools:` line, so this
|
|
712
|
+
// is safe to strip unconditionally rather than pushing the concern onto
|
|
713
|
+
// each call site. Strip BEFORE the malformed-quote check below: a comment
|
|
714
|
+
// may itself contain a `"`/`'` (e.g. `Bash # note: "internal"`), which is
|
|
715
|
+
// not a real YAML quote delimiter and must not cause a false rejection.
|
|
716
|
+
const commentIndex = value.search(/[ \t]#/);
|
|
717
|
+
const stripped = commentIndex === -1 ? value : value.slice(0, commentIndex).trimEnd();
|
|
718
|
+
if (!stripped)
|
|
719
|
+
return null;
|
|
720
|
+
if (stripped.endsWith('"') || stripped.endsWith("'"))
|
|
721
|
+
return null;
|
|
722
|
+
return stripped;
|
|
723
|
+
}
|
|
724
|
+
/** Append validated canonical grants without reserializing unrelated frontmatter. */
|
|
725
|
+
function appendAgentTools(content, grants) {
|
|
726
|
+
if (grants.length === 0)
|
|
727
|
+
return content;
|
|
728
|
+
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
729
|
+
const lines = content.split(eol);
|
|
730
|
+
if (lines[0] !== '---')
|
|
731
|
+
return content;
|
|
732
|
+
const frontmatterEnd = lines.indexOf('---', 1);
|
|
733
|
+
if (frontmatterEnd === -1)
|
|
734
|
+
return content;
|
|
735
|
+
const toolsIndex = lines.findIndex((line, index) => index < frontmatterEnd && /^tools:[ \t]*(.*)$/.test(line));
|
|
736
|
+
if (toolsIndex === -1)
|
|
737
|
+
return content;
|
|
738
|
+
const toolsMatch = /^tools:[ \t]*(.*)$/.exec(lines[toolsIndex]);
|
|
739
|
+
if (!toolsMatch)
|
|
740
|
+
return content;
|
|
741
|
+
// Plain (non-leading-quote) YAML scalars have no internal quoting — a `#`
|
|
742
|
+
// after whitespace is a real comment start regardless of nearby quote
|
|
743
|
+
// characters (verified: real YAML truncates `Read, "x #1"` at the space
|
|
744
|
+
// before `#` too), so this scan does not need to be quote-aware. The one
|
|
745
|
+
// case that DOES need protection — a value that IS a leading quoted scalar
|
|
746
|
+
// — is refused outright below rather than parsed past.
|
|
747
|
+
const commentIndex = toolsMatch[1].search(/[ \t]#/);
|
|
748
|
+
let inlineValue = commentIndex === -1 ? toolsMatch[1] : toolsMatch[1].slice(0, commentIndex);
|
|
749
|
+
let inlineComment = commentIndex === -1 ? '' : toolsMatch[1].slice(commentIndex);
|
|
750
|
+
// A header that is ONLY a comment (`tools: # note`) has no leading space in
|
|
751
|
+
// the captured group — the outer regex's `[ \t]*` already consumed it — so
|
|
752
|
+
// the `[ \t]#` scan above never fires. Reclassify as no inline value so the
|
|
753
|
+
// block-list scan below runs instead of swallowing the comment as content.
|
|
754
|
+
if (inlineValue.trim().startsWith('#')) {
|
|
755
|
+
inlineComment = toolsMatch[1];
|
|
756
|
+
inlineValue = '';
|
|
757
|
+
}
|
|
758
|
+
// A value that STARTS with a quote is a YAML quoted scalar occupying the
|
|
759
|
+
// whole node — nothing may follow it on the same line except a comment
|
|
760
|
+
// (`tools: "Bash"` is valid; `tools: "Bash", Read` is not, even before this
|
|
761
|
+
// function touches it). Appending in place would corrupt otherwise-valid
|
|
762
|
+
// frontmatter, so refuse rather than emit invalid YAML. A value that STARTS
|
|
763
|
+
// with `[` is a YAML flow sequence (`tools: [Bash, Read]`) — its own commas
|
|
764
|
+
// are node-internal, not scalar separators, and content cannot follow its
|
|
765
|
+
// closing `]` on the same line either, so the same refusal applies.
|
|
766
|
+
if (/^["'[]/.test(inlineValue.trim()))
|
|
767
|
+
return content;
|
|
768
|
+
const existing = [];
|
|
769
|
+
let insertAt = toolsIndex + 1;
|
|
770
|
+
if (inlineValue.trim()) {
|
|
771
|
+
existing.push(...splitToolScalars(inlineValue).map(decodeToolScalar).filter((value) => value !== null));
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
while (insertAt < frontmatterEnd) {
|
|
775
|
+
const item = /^([ \t]+)-[ \t]*(\S.*)$/.exec(lines[insertAt]);
|
|
776
|
+
if (!item)
|
|
777
|
+
break;
|
|
778
|
+
const decoded = decodeToolScalar(item[2]);
|
|
779
|
+
if (decoded !== null)
|
|
780
|
+
existing.push(decoded);
|
|
781
|
+
insertAt += 1;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
const present = new Set(existing);
|
|
785
|
+
const additions = grants.filter((grant) => !present.has(grant) && (present.add(grant), true));
|
|
786
|
+
if (additions.length === 0)
|
|
787
|
+
return content;
|
|
788
|
+
if (inlineValue.trim()) {
|
|
789
|
+
lines[toolsIndex] = `tools: ${inlineValue.trimEnd()}, ${additions.join(', ')}${inlineComment}`;
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
const firstItem = /^([ \t]+)-/.exec(lines[toolsIndex + 1]);
|
|
793
|
+
const indent = firstItem ? firstItem[1] : ' ';
|
|
794
|
+
lines.splice(insertAt, 0, ...additions.map((grant) => `${indent}- ${JSON.stringify(grant)}`));
|
|
795
|
+
}
|
|
796
|
+
return lines.join(eol);
|
|
797
|
+
}
|
|
647
798
|
function parseKimiAgentSource(source) {
|
|
648
799
|
if (typeof source === 'string') {
|
|
649
800
|
return {
|
|
@@ -671,7 +822,9 @@ function parseFrontmatterTools(frontmatter) {
|
|
|
671
822
|
continue;
|
|
672
823
|
if (collecting) {
|
|
673
824
|
if (trimmed.startsWith('- ')) {
|
|
674
|
-
|
|
825
|
+
const tool = decodeToolScalar(trimmed.slice(2));
|
|
826
|
+
if (tool !== null)
|
|
827
|
+
tools.push(tool);
|
|
675
828
|
continue;
|
|
676
829
|
}
|
|
677
830
|
collecting = false;
|
|
@@ -682,10 +835,13 @@ function parseFrontmatterTools(frontmatter) {
|
|
|
682
835
|
}
|
|
683
836
|
if (trimmed.startsWith('tools:') || trimmed.startsWith('allowed-tools:')) {
|
|
684
837
|
const value = trimmed.slice(trimmed.indexOf(':') + 1).trim();
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
838
|
+
// A comment-only value (`tools: # note`) has no real inline content —
|
|
839
|
+
// fall through to the block-list scan below instead of decoding the
|
|
840
|
+
// comment text as a bogus tool name and silently dropping the list.
|
|
841
|
+
if (value && !value.startsWith('#')) {
|
|
842
|
+
for (const tool of splitToolScalars(value)) {
|
|
843
|
+
const name = decodeToolScalar(tool);
|
|
844
|
+
if (name !== null)
|
|
689
845
|
tools.push(name);
|
|
690
846
|
}
|
|
691
847
|
}
|
|
@@ -847,7 +1003,8 @@ function buildKimiAgentArtifacts({ rootAgent = '', subagents = [], requestedSuba
|
|
|
847
1003
|
/**
|
|
848
1004
|
* Apply Antigravity-specific content conversion — path replacement + command name conversion.
|
|
849
1005
|
* Path mappings depend on install mode:
|
|
850
|
-
* Global: ~/.claude/ → ~/.gemini/
|
|
1006
|
+
* Global: ~/.claude/skills/ → ~/.gemini/config/skills/ (#3738),
|
|
1007
|
+
* ~/.claude/ → ~/.gemini/antigravity/, ./.claude/ → ./.agents/
|
|
851
1008
|
* Local: ~/.claude/ → .agents/, ./.claude/ → ./.agents/
|
|
852
1009
|
* Applied to ALL Antigravity content (skills, agents, engine files).
|
|
853
1010
|
* @param {string} content - Source content to convert
|
|
@@ -856,6 +1013,18 @@ function buildKimiAgentArtifacts({ rootAgent = '', subagents = [], requestedSuba
|
|
|
856
1013
|
function convertClaudeToAntigravityContent(content, isGlobal = false) {
|
|
857
1014
|
let c = content;
|
|
858
1015
|
if (isGlobal) {
|
|
1016
|
+
// #3738: global skills install under ~/.gemini/config/skills (the dir AGY
|
|
1017
|
+
// scans for global discovery), so skills-path references must divert there
|
|
1018
|
+
// — BEFORE the configHome rewrite below, which is correct for gsd-core
|
|
1019
|
+
// runtime-file references (settings, workflows, VERSION) but wrong for the
|
|
1020
|
+
// skills dir itself.
|
|
1021
|
+
c = c.replace(/\$HOME\/\.claude\/skills\//g, '$HOME/.gemini/config/skills/');
|
|
1022
|
+
c = c.replace(/~\/\.claude\/skills\//g, '~/.gemini/config/skills/');
|
|
1023
|
+
// Bare skills form (no trailing slash) — must also precede the generic
|
|
1024
|
+
// slash rule, which would otherwise divert it to the retired configHome
|
|
1025
|
+
// path ($HOME/.gemini/antigravity/skills).
|
|
1026
|
+
c = c.replace(/\$HOME\/\.claude\/skills\b/g, '$HOME/.gemini/config/skills');
|
|
1027
|
+
c = c.replace(/~\/\.claude\/skills\b/g, '~/.gemini/config/skills');
|
|
859
1028
|
c = c.replace(/\$HOME\/\.claude\//g, '$HOME/.gemini/antigravity/');
|
|
860
1029
|
c = c.replace(/~\/\.claude\//g, '~/.gemini/antigravity/');
|
|
861
1030
|
// Bare form (no trailing slash) — must come after slash form to avoid double-replace
|
|
@@ -1609,26 +1778,37 @@ Execute mode fallback:
|
|
|
1609
1778
|
## C. Task() → spawn_agent Mapping
|
|
1610
1779
|
GSD workflows use \`Task(...)\` (Claude Code syntax). Translate to Codex collaboration tools:
|
|
1611
1780
|
|
|
1612
|
-
**Schema detection (required first step):**
|
|
1613
|
-
|
|
1614
|
-
|
|
1781
|
+
**Schema detection (required first step):** Before spawning, inspect the \`spawn_agent\`
|
|
1782
|
+
tool's visible parameter schema (via \`tool_search\` or the tool list). Use the presence
|
|
1783
|
+
of \`agent_type\` only to choose typed dispatch versus the generic-agent workaround.
|
|
1784
|
+
Detect optional fields independently: \`model\`, \`reasoning_effort\`, \`task_name\`,
|
|
1785
|
+
\`fork_turns\`, and \`fork_context\` may be added or removed without \`agent_type\` changing.
|
|
1786
|
+
Never infer one field from a schema/version label or from the presence of another field.
|
|
1615
1787
|
|
|
1616
|
-
|
|
1788
|
+
- **agent_type-capable schema:** \`spawn_agent\` advertises \`agent_type\` — typed GSD agent dispatch is available.
|
|
1789
|
+
- **Generic schema:** \`spawn_agent\` does not advertise \`agent_type\` — typed GSD agent dispatch is unavailable in this session, even if other optional fields are present.
|
|
1617
1790
|
|
|
1618
1791
|
Typed mapping (agent_type-capable schema only):
|
|
1619
1792
|
- \`Task(subagent_type="X", prompt="Y")\` → \`spawn_agent(agent_type="X", message="Y")\`
|
|
1620
1793
|
- \`Agent(subagent_type="X", prompt="Y")\` → \`spawn_agent(agent_type="X", message="Y")\`
|
|
1621
|
-
- \`Task(model="
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1794
|
+
- \`Task(model="{resolved_model}")\` → pass \`model="{resolved_model}"\` when the
|
|
1795
|
+
visible \`spawn_agent\` schema advertises \`model\` and the resolved value is explicit.
|
|
1796
|
+
This is how \`model_profile\` tier routing, including \`adaptive\`, reaches the child agent.
|
|
1797
|
+
Omit \`model\` only when the schema does not advertise \`model\`, or when the value is
|
|
1798
|
+
missing, empty, or \`"inherit"\`; omission deliberately inherits the session/static agent
|
|
1799
|
+
configuration. Explicit \`model_overrides\` may also be embedded in agent \`.toml\` files,
|
|
1800
|
+
but ordinary profile-resolved models are not, so a TOML file is not a reason to discard
|
|
1801
|
+
an available inline value.
|
|
1802
|
+
- Before each typed spawn, obtain the paired effort for its role with
|
|
1803
|
+
\`gsd_run query resolve-model <subagent_type> --pick effort\` when the workflow has not
|
|
1804
|
+
already exposed it. The resolver's unified \`effort\` field maps to the Codex spawn argument
|
|
1805
|
+
\`reasoning_effort\`; do not look for a resolver field named \`reasoning_effort\`.
|
|
1806
|
+
Pass it when the visible \`spawn_agent\` schema advertises \`reasoning_effort\`. Omit the
|
|
1807
|
+
field when it is not advertised, or when the value is missing, empty, \`"inherit"\`, or
|
|
1808
|
+
unsupported; do not invent one-off effort literals in workflow prose.
|
|
1629
1809
|
- \`fork_context: false\` by default — GSD agents load their own context via \`<required_reading>\` blocks
|
|
1630
|
-
- \`task_name\` —
|
|
1631
|
-
- \`fork_turns\` —
|
|
1810
|
+
- \`task_name\` — when advertised, provide a descriptive name for each spawned task
|
|
1811
|
+
- \`fork_turns\` — when advertised, controls turn-forking depth; coexists with \`fork_context\` (not a replacement)
|
|
1632
1812
|
- \`Task(isolation="worktree")\` / \`Agent(isolation="worktree")\` → no direct \`spawn_agent\` mapping,
|
|
1633
1813
|
but Codex declares \`dispatch.isolation: orchestrator-worktree\` (#2584). Codex
|
|
1634
1814
|
\`spawn_agent\` still does not create or bind a git worktree; instead GSD itself
|
|
@@ -1702,7 +1882,26 @@ function neutralizeAgentReferences(content, instructionFile) {
|
|
|
1702
1882
|
c = c.replace(/Do NOT load full `AGENTS\.md` files[^\n]*/g, '');
|
|
1703
1883
|
return c;
|
|
1704
1884
|
}
|
|
1705
|
-
|
|
1885
|
+
/**
|
|
1886
|
+
* Render one frontmatter `key: value` line whose value came from user config.
|
|
1887
|
+
*
|
|
1888
|
+
* #3706: both `model:` and `variant:` interpolate a value read from
|
|
1889
|
+
* `.planning/config.json` / `~/.gsd/defaults.json`. Raw interpolation lets a value
|
|
1890
|
+
* containing a newline inject additional TOP-LEVEL frontmatter keys into the
|
|
1891
|
+
* generated agent file — proven by execution during the #3705 security review
|
|
1892
|
+
* (`"sonnet\ntools: [\"*\"]\npermission: bypass"` produced two extra keys).
|
|
1893
|
+
*
|
|
1894
|
+
* That sink predates #3706, but this change adds a SECOND write to it, so it is
|
|
1895
|
+
* closed here rather than doubled. Both the decision and the escaping live in
|
|
1896
|
+
* frontmatter.cts so there is exactly one set of YAML scalar rules; a value that
|
|
1897
|
+
* round-trips bare is still emitted bare, so generated files do not churn.
|
|
1898
|
+
*/
|
|
1899
|
+
function frontmatterScalar(key, value) {
|
|
1900
|
+
return frontmatterModule.agentScalarNeedsDoubleQuoting(value)
|
|
1901
|
+
? `${key} "${frontmatterModule.escapeDoubleQuotedScalar(value)}"`
|
|
1902
|
+
: `${key} ${value}`;
|
|
1903
|
+
}
|
|
1904
|
+
function convertClaudeToOpencodeFrontmatter(content, { isAgent = false, modelOverride = null, variant = null } = {}) {
|
|
1706
1905
|
// Replace tool name references in content (applies to all files)
|
|
1707
1906
|
let convertedContent = content;
|
|
1708
1907
|
convertedContent = convertedContent.replace(/\bAskUserQuestion\b/g, 'question');
|
|
@@ -1827,7 +2026,23 @@ function convertClaudeToOpencodeFrontmatter(content, { isAgent = false, modelOve
|
|
|
1827
2026
|
// respected on OpenCode (which uses static agent frontmatter, not inline
|
|
1828
2027
|
// Task() model parameters). See #2256.
|
|
1829
2028
|
if (modelOverride) {
|
|
1830
|
-
newLines.push(
|
|
2029
|
+
newLines.push(frontmatterScalar('model:', modelOverride));
|
|
2030
|
+
}
|
|
2031
|
+
// #3706: deliver the RESOLVED reasoning effort to the spawned subagent.
|
|
2032
|
+
// `query resolve-model` reported an effort that never reached OpenCode, so
|
|
2033
|
+
// every subagent ran at whatever opencode.jsonc defaults the model to — for
|
|
2034
|
+
// a custom provider commonly the most expensive setting.
|
|
2035
|
+
//
|
|
2036
|
+
// OpenCode ONLY: `EFFORT_ARGV` declares surfaces for claude/opencode/codex
|
|
2037
|
+
// and NO kilo entry, so the Kilo converter below deliberately does not emit
|
|
2038
|
+
// this. Unlike the model side — where #2794 J8 requires kilo and opencode to
|
|
2039
|
+
// resolve identically — there is no kilo effort surface to render into, and
|
|
2040
|
+
// inventing one would emit a key that runtime never documented.
|
|
2041
|
+
//
|
|
2042
|
+
// Omitted entirely when absent, per #1156's rule for `model: inherit`:
|
|
2043
|
+
// never an empty or sentinel value, let the runtime use its own default.
|
|
2044
|
+
if (variant) {
|
|
2045
|
+
newLines.push(frontmatterScalar('variant:', variant));
|
|
1831
2046
|
}
|
|
1832
2047
|
}
|
|
1833
2048
|
// For commands: add tools object if we had allowed-tools or tools
|
|
@@ -1899,7 +2114,9 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
1899
2114
|
}
|
|
1900
2115
|
if (isAgent && inAgentTools) {
|
|
1901
2116
|
if (trimmed.startsWith('- ')) {
|
|
1902
|
-
|
|
2117
|
+
const tool = decodeToolScalar(trimmed.substring(2));
|
|
2118
|
+
if (tool !== null)
|
|
2119
|
+
agentTools.push(tool);
|
|
1903
2120
|
continue;
|
|
1904
2121
|
}
|
|
1905
2122
|
if (trimmed && !trimmed.startsWith('-')) {
|
|
@@ -1910,8 +2127,11 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
1910
2127
|
if (trimmed.startsWith('tools:')) {
|
|
1911
2128
|
if (isAgent) {
|
|
1912
2129
|
const toolsValue = trimmed.substring(6).trim();
|
|
1913
|
-
|
|
1914
|
-
|
|
2130
|
+
// A comment-only value (`tools: # note`) is not real inline content —
|
|
2131
|
+
// fall through to the block-list scan (`inAgentTools`) instead of
|
|
2132
|
+
// decoding the comment as a bogus tool name and dropping the list.
|
|
2133
|
+
if (toolsValue && !toolsValue.startsWith('#')) {
|
|
2134
|
+
const tools = splitToolScalars(toolsValue).map(decodeToolScalar).filter((tool) => tool !== null);
|
|
1915
2135
|
agentTools.push(...tools);
|
|
1916
2136
|
}
|
|
1917
2137
|
else {
|
|
@@ -1973,7 +2193,9 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
1973
2193
|
if (trimmed.startsWith('- ')) {
|
|
1974
2194
|
const tool = trimmed.substring(2).trim();
|
|
1975
2195
|
if (isAgent) {
|
|
1976
|
-
|
|
2196
|
+
const decoded = decodeToolScalar(tool);
|
|
2197
|
+
if (decoded !== null)
|
|
2198
|
+
agentTools.push(decoded);
|
|
1977
2199
|
}
|
|
1978
2200
|
else {
|
|
1979
2201
|
allowedTools.push(tool);
|
|
@@ -1999,7 +2221,7 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
1999
2221
|
// model emission exactly (#2093 UPGRADE 2 / ADR-1239; Kilo is an OpenCode
|
|
2000
2222
|
// fork with the same static-frontmatter model constraint). See #2256.
|
|
2001
2223
|
if (modelOverride) {
|
|
2002
|
-
newLines.push(
|
|
2224
|
+
newLines.push(frontmatterScalar('model:', modelOverride));
|
|
2003
2225
|
}
|
|
2004
2226
|
newLines.push(...buildKiloAgentPermissionBlock(agentTools));
|
|
2005
2227
|
}
|
|
@@ -2306,11 +2528,16 @@ function convertClaudeAgentToQwenAgent(content) {
|
|
|
2306
2528
|
* Byte-identical for an agent with no `mcp__*` grants (the common case) and
|
|
2307
2529
|
* for an agent with no frontmatter at all.
|
|
2308
2530
|
*/
|
|
2531
|
+
/** Fail-closed: an undecodable scalar is dropped, never kept (ZCode's contract is "never emit mcp__*"). */
|
|
2532
|
+
function zcodeKeepsGrant(rawTool) {
|
|
2533
|
+
const decoded = decodeToolScalar(rawTool);
|
|
2534
|
+
return decoded !== null && !decoded.startsWith('mcp__');
|
|
2535
|
+
}
|
|
2309
2536
|
function convertClaudeAgentToZcodeAgent(content) {
|
|
2310
|
-
//
|
|
2311
|
-
//
|
|
2312
|
-
//
|
|
2313
|
-
if (!content.includes('mcp__'))
|
|
2537
|
+
// A double-quoted YAML scalar may encode the leading "m" in mcp__ as an
|
|
2538
|
+
// escape, so only skip the shared scalar-decoder scan when neither form is
|
|
2539
|
+
// present. The unchanged scan below still preserves byte-identical content.
|
|
2540
|
+
if (!content.includes('mcp__') && !content.includes('\\'))
|
|
2314
2541
|
return content;
|
|
2315
2542
|
const lines = content.split('\n');
|
|
2316
2543
|
if (lines[0] !== '---')
|
|
@@ -2330,9 +2557,14 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2330
2557
|
while (i < fmEnd) {
|
|
2331
2558
|
const line = lines[i];
|
|
2332
2559
|
const inlineTools = /^tools:[ \t]*(.+)$/.exec(line);
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2560
|
+
// A header that is ONLY a comment (`tools: # note`) is not real inline
|
|
2561
|
+
// content — fall through to the block-list scan below instead of
|
|
2562
|
+
// matching here, or a following block list's mcp__* items never get
|
|
2563
|
+
// scanned and leak through unstripped.
|
|
2564
|
+
const commentOnlyHeader = inlineTools !== null && inlineTools[1].trim().startsWith('#');
|
|
2565
|
+
if (inlineTools && !commentOnlyHeader) {
|
|
2566
|
+
const grants = splitToolScalars(inlineTools[1]).map((tool) => tool.trim()).filter((tool) => tool !== '');
|
|
2567
|
+
const kept = grants.filter((tool) => zcodeKeepsGrant(tool));
|
|
2336
2568
|
if (kept.length === grants.length) {
|
|
2337
2569
|
out.push(line); // no mcp__* grants — keep the line byte-identical
|
|
2338
2570
|
}
|
|
@@ -2346,7 +2578,7 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2346
2578
|
i++;
|
|
2347
2579
|
continue;
|
|
2348
2580
|
}
|
|
2349
|
-
if (/^tools:[ \t]*$/.test(line)) {
|
|
2581
|
+
if (/^tools:[ \t]*$/.test(line) || commentOnlyHeader) {
|
|
2350
2582
|
// Block-list form: collect the following `- item` lines.
|
|
2351
2583
|
const items = [];
|
|
2352
2584
|
let j = i + 1;
|
|
@@ -2356,7 +2588,7 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2356
2588
|
}
|
|
2357
2589
|
const kept = items.filter((item) => {
|
|
2358
2590
|
const name = /^([ \t]*)-[ \t]*(\S.*)$/.exec(item)[2].trim();
|
|
2359
|
-
return
|
|
2591
|
+
return zcodeKeepsGrant(name);
|
|
2360
2592
|
});
|
|
2361
2593
|
if (kept.length !== items.length) {
|
|
2362
2594
|
changed = true;
|
|
@@ -2692,7 +2924,13 @@ function restoreClaudeGlobalAtRefTilde(content, pathPrefix) {
|
|
|
2692
2924
|
return content;
|
|
2693
2925
|
const tildeEquivalent = '~' + pathPrefix.slice('$HOME'.length);
|
|
2694
2926
|
const atRefRe = new RegExp(`(?<!["'])@${(0, pattern_cjs_1.escapeRegex)(pathPrefix)}`, 'g');
|
|
2695
|
-
|
|
2927
|
+
// Function replacement, not a string. A string replacement treats `$&` and the
|
|
2928
|
+
// backtick-dollar form in the SUBSTITUTION as special patterns, so a --config-dir
|
|
2929
|
+
// containing either corrupts output: `$HOME/.cl$&ude/` yielded
|
|
2930
|
+
// `@~/.cl@$HOME/.cl$&ude/ude/x`, and the backtick form silently DROPPED text.
|
|
2931
|
+
// Pre-existing, and #3719 adds a THIRD call site to this sink — which is how the
|
|
2932
|
+
// previous two came to share the defect in the first place.
|
|
2933
|
+
return content.replace(atRefRe, () => `@${tildeEquivalent}`);
|
|
2696
2934
|
}
|
|
2697
2935
|
/**
|
|
2698
2936
|
* Apply the per-runtime rewrite table to a single content string.
|
|
@@ -2885,6 +3123,20 @@ function _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal = false, a
|
|
|
2885
3123
|
content = content.replace(/\.\/\.claude\b/g, `./${dirName}`);
|
|
2886
3124
|
content = processAttribution(content, attribution);
|
|
2887
3125
|
break;
|
|
3126
|
+
case 'zcode':
|
|
3127
|
+
// #4002: ZCode is a Claude-Code-shaped host (dot-home `.zcode`, `@~`-ref
|
|
3128
|
+
// expansion, `~/.zcode/...` documented paths) whose commands install with
|
|
3129
|
+
// `converter: null` — this pass is their only chance to receive
|
|
3130
|
+
// runtime-correct paths. Same shape as `claude`, including the tilde
|
|
3131
|
+
// restore: the tilde form is what ZCode expands and what its docs use.
|
|
3132
|
+
// `${_GSD_RUNTIME_ROOT}/.claude/…` matches none of these regexes and
|
|
3133
|
+
// survives as the project-local fallback, exactly as on every sibling.
|
|
3134
|
+
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3135
|
+
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3136
|
+
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
3137
|
+
content = restoreClaudeGlobalAtRefTilde(content, pathPrefix);
|
|
3138
|
+
content = processAttribution(content, attribution);
|
|
3139
|
+
break;
|
|
2888
3140
|
default:
|
|
2889
3141
|
// Unknown runtime — no rewrites (OpenCode/Kilo handled by their own install path).
|
|
2890
3142
|
break;
|
|
@@ -3124,8 +3376,34 @@ function applyAgentPathRewrites(content, runtime, pathPrefix) {
|
|
|
3124
3376
|
const normalizedPathPrefix = pathPrefix.replace(/\/$/, '');
|
|
3125
3377
|
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3126
3378
|
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3127
|
-
|
|
3128
|
-
|
|
3379
|
+
// #3719 review (MAJOR): a bare `\b` is satisfied by ANY non-word character,
|
|
3380
|
+
// including '-' — for a --config-dir whose name EXTENDS '.claude' (e.g.
|
|
3381
|
+
// '.claude-work'), this re-matched the '.claude' PREFIX of the emitted
|
|
3382
|
+
// '.claude-work' path and corrupted it to '.claude-work-work'. Guard with
|
|
3383
|
+
// the SAME negative-lookahead convention already used at
|
|
3384
|
+
// copyWithPathReplacement's call site (bin/install.js:7729-7730).
|
|
3385
|
+
content = content.replace(/~\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
|
3386
|
+
content = content.replace(/\$HOME\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
|
3387
|
+
// #3719: the THIRD emit path that needed this restore. #3133 added it to the
|
|
3388
|
+
// skill/command pipeline (`_applyRuntimeRewrites` case 'claude') and #3544 to
|
|
3389
|
+
// bin/install.js's spec-tree copy; the agents pipeline never got it, so every
|
|
3390
|
+
// `@~/.claude/...` include in a global Claude install shipped as `@$HOME/...`
|
|
3391
|
+
// and resolved to NOTHING (27 of 34 emitted agents, 103 lines).
|
|
3392
|
+
//
|
|
3393
|
+
// Guarded on `claude` for the same reason the sibling call site lives inside
|
|
3394
|
+
// `case 'claude'`: the helper self-guards only on the `$HOME` PREFIX, and every
|
|
3395
|
+
// runtime's global prefix is a `$HOME` form (`$HOME/.cursor/`, ...), so an
|
|
3396
|
+
// unguarded call would rewrite `@`-refs for runtimes whose resolver has no
|
|
3397
|
+
// documented `~` expansion at all.
|
|
3398
|
+
//
|
|
3399
|
+
// Passed the NORMALIZED prefix, not `pathPrefix`. The two word-boundary
|
|
3400
|
+
// replaces above emit the trailing-slash-free form, and the helper's regex is
|
|
3401
|
+
// anchored to the exact prefix string it is handed — so `restore(pathPrefix)`
|
|
3402
|
+
// fixes `@$HOME/.claude/x` and leaves a bare `@$HOME/.claude` broken. The
|
|
3403
|
+
// normalized form is a PREFIX of both, so one call covers both.
|
|
3404
|
+
if (runtime === 'claude') {
|
|
3405
|
+
content = restoreClaudeGlobalAtRefTilde(content, normalizedPathPrefix);
|
|
3406
|
+
}
|
|
3129
3407
|
return content;
|
|
3130
3408
|
}
|
|
3131
3409
|
// ── End rewrite engine ────────────────────────────────────────────────────────
|
|
@@ -3243,7 +3521,14 @@ function applyAgentFrontmatterExtensions(content, { runtime, agentName, targetDi
|
|
|
3243
3521
|
// effort key, so skipping injection is the whole job.
|
|
3244
3522
|
if (universalEffort !== 'inherit') {
|
|
3245
3523
|
const renderedEffort = _getGsdEffortCatalog().renderEffortForRuntime(runtime, universalEffort).value;
|
|
3246
|
-
|
|
3524
|
+
// #3007: `value` is `string | null` — a rejected/unrenderable level (e.g.
|
|
3525
|
+
// 'ultra', or a catalog with no advertised level at or above the request)
|
|
3526
|
+
// renders null. Same posture as the 'inherit' case above: omit the key
|
|
3527
|
+
// entirely rather than writing a literal `effort: null`, so the host
|
|
3528
|
+
// falls back to its own default instead of failing to parse.
|
|
3529
|
+
if (renderedEffort !== null) {
|
|
3530
|
+
result = injectEffortFrontmatter(result, renderedEffort);
|
|
3531
|
+
}
|
|
3247
3532
|
}
|
|
3248
3533
|
const disallowedTools = READONLY_AGENT_DISALLOWED_TOOLS[agentName];
|
|
3249
3534
|
if (disallowedTools)
|
|
@@ -3276,6 +3561,7 @@ function processAttribution(content, attribution) {
|
|
|
3276
3561
|
}
|
|
3277
3562
|
module.exports = {
|
|
3278
3563
|
processAttribution,
|
|
3564
|
+
appendAgentTools,
|
|
3279
3565
|
// #2103: public accessor for hostBehaviors.agentFileExtension, exported so
|
|
3280
3566
|
// surface.cts's _syncGsdDir can derive the .agent.md rename from the SAME
|
|
3281
3567
|
// descriptor read as install-engine.cts (folds a duplicated hardcoded
|
|
@@ -3332,6 +3618,8 @@ module.exports = {
|
|
|
3332
3618
|
// opencode/kilo command install through the engine instead of the bespoke path).
|
|
3333
3619
|
convertClaudeToOpencodeFrontmatter,
|
|
3334
3620
|
convertClaudeToKiloFrontmatter,
|
|
3621
|
+
_decodeToolScalar: decodeToolScalar,
|
|
3622
|
+
_splitToolScalars: splitToolScalars,
|
|
3335
3623
|
readGsdCommandNames,
|
|
3336
3624
|
transformContentToHyphen,
|
|
3337
3625
|
// #1383: version resolver (exported for regression test of the Codex
|
|
@@ -51,7 +51,7 @@ function addCleanupDir(cleanupDirs, stagedDir, rewrittenDir) {
|
|
|
51
51
|
return sourceDir;
|
|
52
52
|
}
|
|
53
53
|
function createRuntimeArtifactInstallPlan(args) {
|
|
54
|
-
const { layout, resolvedProfile, homedir, platform, resolveAttribution, deps = {}, } = args;
|
|
54
|
+
const { layout, resolvedProfile, homedir, platform, resolveAttribution, projectDir, deps = {}, } = args;
|
|
55
55
|
const conversionExports = _require('./runtime-artifact-conversion.cjs');
|
|
56
56
|
const rewriteStagedSkillBodies = deps.rewriteStagedSkillBodies ?? conversionExports.rewriteStagedSkillBodies;
|
|
57
57
|
const rewriteStagedCommandBodies = deps.rewriteStagedCommandBodies ?? conversionExports.rewriteStagedCommandBodies;
|
|
@@ -66,11 +66,10 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
66
66
|
platform,
|
|
67
67
|
resolveAttribution,
|
|
68
68
|
};
|
|
69
|
-
// ADR-1235 §1: build
|
|
70
|
-
// the CORRECT pre-converter cross-cutting (path rewrites → attribution →
|
|
71
|
-
// → normalize). This
|
|
72
|
-
//
|
|
73
|
-
// to kind.stage() for agents kind entries with a converter (convertedAgentsKind).
|
|
69
|
+
// ADR-1235 §1: build the staging context once per plan. Agent kinds apply
|
|
70
|
+
// the CORRECT pre-converter cross-cutting (path rewrites → attribution →
|
|
71
|
+
// converter → normalize). This
|
|
72
|
+
// mirrors the exact per-file order in the former inline agent loop.
|
|
74
73
|
// NO _stampNonClaudeRuntimeDefaults — agents are NOT stamped in the inline loop.
|
|
75
74
|
const os = _require('node:os');
|
|
76
75
|
const { posixNormalize } = _require('./shell-command-projection.cjs');
|
|
@@ -88,19 +87,19 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
88
87
|
const attribution = resolveAttribution ? resolveAttribution(layout.runtime) : undefined;
|
|
89
88
|
// #2875 Part 2 (row I1): layout.configDir IS the install root the inline
|
|
90
89
|
// agent loop called `targetDir` — same value, same resolution.
|
|
91
|
-
const agentCtx = {
|
|
90
|
+
const agentCtx = {
|
|
91
|
+
runtime: layout.runtime,
|
|
92
|
+
pathPrefix,
|
|
93
|
+
attribution,
|
|
94
|
+
targetDir: layout.configDir,
|
|
95
|
+
projectDir: projectDir ?? layout.configDir,
|
|
96
|
+
};
|
|
92
97
|
for (const kind of layout.kinds) {
|
|
93
98
|
let stagedDir;
|
|
94
99
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// The cross-cutting is now PRE-converter (inside staging), not POST.
|
|
99
|
-
stagedDir = kind.stage(resolvedProfile, agentCtx);
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
stagedDir = kind.stage(resolvedProfile);
|
|
103
|
-
}
|
|
100
|
+
// Agent kinds use the context for their pre-converter cross-cutting
|
|
101
|
+
// sequence; other kinds ignore it.
|
|
102
|
+
stagedDir = kind.stage(resolvedProfile, agentCtx);
|
|
104
103
|
}
|
|
105
104
|
catch (err) {
|
|
106
105
|
return { ok: false, kind: 'stage_failed', message: errorMessage(err), cleanupDirs, failedKind: kind.kind };
|
|
@@ -115,7 +114,7 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
115
114
|
const rewrittenDir = rewriteStagedSkillBodies(stagedDir, rewriteOpts);
|
|
116
115
|
sourceDir = addCleanupDir(cleanupDirs, stagedDir, rewrittenDir);
|
|
117
116
|
}
|
|
118
|
-
//
|
|
117
|
+
// Agent kinds: cross-cutting already applied INSIDE kind.stage() via agentCtx.
|
|
119
118
|
// No POST-step needed. sourceDir stays as stagedDir.
|
|
120
119
|
}
|
|
121
120
|
catch (err) {
|