@opengsd/gsd-core 1.12.0 → 1.14.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-advisor-researcher.compact.md +85 -0
- package/agents/gsd-ai-researcher.compact.md +96 -0
- package/agents/gsd-assumptions-analyzer.compact.md +81 -0
- package/agents/gsd-code-fixer.compact.md +458 -0
- package/agents/gsd-code-fixer.md +5 -5
- package/agents/gsd-code-reviewer.compact.md +269 -0
- package/agents/gsd-code-reviewer.md +15 -3
- package/agents/gsd-codebase-mapper.compact.md +760 -0
- package/agents/gsd-debug-session-manager.compact.md +345 -0
- package/agents/gsd-doc-classifier.compact.md +192 -0
- package/agents/gsd-doc-synthesizer.compact.md +200 -0
- package/agents/gsd-doc-verifier.compact.md +143 -0
- package/agents/gsd-doc-writer.compact.md +440 -0
- package/agents/gsd-dom-verifier.compact.md +138 -0
- package/agents/gsd-domain-researcher.compact.md +141 -0
- package/agents/gsd-eval-auditor.compact.md +160 -0
- package/agents/gsd-eval-planner.compact.md +137 -0
- package/agents/gsd-executor.md +63 -35
- package/agents/gsd-framework-selector.compact.md +82 -0
- package/agents/gsd-integration-checker.compact.md +245 -0
- package/agents/gsd-intel-updater.compact.md +226 -0
- package/agents/gsd-mempalace-curator.compact.md +45 -0
- package/agents/gsd-nyquist-auditor.compact.md +179 -0
- package/agents/gsd-pattern-mapper.compact.md +275 -0
- package/agents/gsd-plan-checker.md +76 -57
- package/agents/gsd-planner.md +14 -0
- package/agents/gsd-project-researcher.compact.md +587 -0
- package/agents/gsd-research-synthesizer.compact.md +212 -0
- package/agents/gsd-roadmapper.compact.md +454 -0
- package/agents/gsd-roadmapper.md +13 -0
- package/agents/gsd-security-auditor.compact.md +162 -0
- package/agents/gsd-ui-auditor.compact.md +404 -0
- package/agents/gsd-ui-checker.compact.md +277 -0
- package/agents/gsd-ui-checker.md +19 -3
- package/agents/gsd-ui-researcher.compact.md +282 -0
- package/agents/gsd-ui-researcher.md +29 -0
- package/agents/gsd-user-profiler.compact.md +108 -0
- package/agents/gsd-verifier.md +23 -1
- package/bin/install.js +444 -134
- package/commands/gsd/cleanup.md +1 -0
- package/commands/gsd/code-review.md +2 -1
- package/commands/gsd/complete-milestone.md +1 -0
- package/commands/gsd/config.md +1 -0
- package/commands/gsd/debug.md +1 -0
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/graphify.md +1 -0
- package/commands/gsd/health.md +1 -0
- package/commands/gsd/mempalace-capture.md +1 -0
- package/commands/gsd/mempalace-recall.md +1 -0
- package/commands/gsd/new-milestone.md +1 -0
- package/commands/gsd/new-project.md +1 -0
- package/commands/gsd/next.md +1 -0
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/pause-work.md +1 -0
- package/commands/gsd/phase.md +2 -1
- package/commands/gsd/pr-branch.md +1 -0
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/resume-work.md +1 -0
- package/commands/gsd/review-backlog.md +1 -0
- package/commands/gsd/settings.md +2 -1
- package/commands/gsd/stats.md +1 -0
- package/commands/gsd/surface.md +18 -8
- package/commands/gsd/thread.md +1 -0
- package/commands/gsd/workspace.md +1 -0
- package/commands/gsd/workstreams.md +1 -0
- package/gsd-core/bin/check-latest-version.cjs +8 -3
- package/gsd-core/bin/gsd-tools.cjs +532 -174
- package/gsd-core/bin/lib/adr-parser.cjs +1 -1
- package/gsd-core/bin/lib/artifacts.cjs +2 -1
- package/gsd-core/bin/lib/audit.cjs +39 -22
- package/gsd-core/bin/lib/broken-windows.cjs +168 -49
- package/gsd-core/bin/lib/capability-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
- package/gsd-core/bin/lib/capability-loader.cjs +135 -1
- package/gsd-core/bin/lib/capability-registry.cjs +528 -116
- package/gsd-core/bin/lib/capability-source.cjs +19 -2
- package/gsd-core/bin/lib/capability-state.cjs +7 -1
- package/gsd-core/bin/lib/capability-validator.cjs +134 -5
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +198 -38
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
- package/gsd-core/bin/lib/command-aliases.cjs +16 -0
- package/gsd-core/bin/lib/commands.cjs +981 -79
- package/gsd-core/bin/lib/config-loader.cjs +4 -0
- package/gsd-core/bin/lib/config.cjs +153 -38
- package/gsd-core/bin/lib/core-utils.cjs +34 -7
- package/gsd-core/bin/lib/coverage.cjs +1 -1
- package/gsd-core/bin/lib/decisions.cjs +343 -28
- package/gsd-core/bin/lib/edge-probe.cjs +14 -1
- package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
- package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +137 -23
- package/gsd-core/bin/lib/gap-checker.cjs +22 -13
- package/gsd-core/bin/lib/git-base-branch.cjs +10 -2
- package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
- 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 +54 -11
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +87 -23
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
- package/gsd-core/bin/lib/host-integration.cjs +57 -5
- package/gsd-core/bin/lib/init-command-router.cjs +14 -0
- package/gsd-core/bin/lib/init.cjs +539 -60
- package/gsd-core/bin/lib/install-engine.cjs +199 -14
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +45 -0
- package/gsd-core/bin/lib/install-profiles.cjs +36 -14
- package/gsd-core/bin/lib/installer-migration-report.cjs +1 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +33 -4
- package/gsd-core/bin/lib/io.cjs +35 -0
- package/gsd-core/bin/lib/loop-resolver.cjs +64 -39
- package/gsd-core/bin/lib/markdown-table.cjs +123 -0
- package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
- package/gsd-core/bin/lib/milestone.cjs +41 -10
- package/gsd-core/bin/lib/model-resolver.cjs +101 -10
- package/gsd-core/bin/lib/phase-command-router.cjs +20 -7
- package/gsd-core/bin/lib/phase-id.cjs +412 -31
- package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
- package/gsd-core/bin/lib/phase.cjs +941 -98
- package/gsd-core/bin/lib/plan-document.cjs +10 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +34 -18
- package/gsd-core/bin/lib/planning-snapshot.cjs +206 -30
- package/gsd-core/bin/lib/planning-workspace.cjs +153 -29
- package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
- 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/refactor-trigger-command-router.cjs +61 -2
- package/gsd-core/bin/lib/research-store.cjs +11 -12
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +53 -5
- package/gsd-core/bin/lib/review-lane-invocation.cjs +96 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
- package/gsd-core/bin/lib/roadmap-parser.cjs +555 -41
- package/gsd-core/bin/lib/roadmap.cjs +292 -69
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +260 -43
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +28 -20
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +294 -108
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +408 -47
- package/gsd-core/bin/lib/security.cjs +126 -7
- package/gsd-core/bin/lib/shell-command-projection.cjs +4 -0
- package/gsd-core/bin/lib/smart-entry.cjs +7 -9
- package/gsd-core/bin/lib/state-document.cjs +159 -32
- package/gsd-core/bin/lib/state-md-schema.cjs +44 -27
- package/gsd-core/bin/lib/state-transition.cjs +465 -62
- package/gsd-core/bin/lib/state.cjs +906 -151
- package/gsd-core/bin/lib/surface.cjs +83 -10
- package/gsd-core/bin/lib/task-command-router.cjs +12 -6
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
- package/gsd-core/bin/lib/uat.cjs +1420 -516
- package/gsd-core/bin/lib/update-context.cjs +36 -26
- package/gsd-core/bin/lib/validate.cjs +230 -12
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +316 -23
- package/gsd-core/bin/lib/verify-command-grounding.cjs +1 -1
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +531 -36
- package/gsd-core/bin/lib/workstream-inventory.cjs +21 -2
- package/gsd-core/bin/lib/worktree-safety.cjs +21 -7
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +507 -81
- package/gsd-core/references/agent-contracts.md +3 -3
- package/gsd-core/references/compact-content-gate.md +66 -0
- package/gsd-core/references/edge-probe.md +17 -13
- package/gsd-core/references/execute-mvp-tdd.md +18 -16
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- package/gsd-core/references/loop-hook-dispatch.md +18 -0
- package/gsd-core/references/model-profiles.md +12 -3
- package/gsd-core/references/mvp-concepts.md +2 -2
- 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-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +75 -2
- package/gsd-core/references/planning-config.md +5 -1
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/tdd.md +17 -9
- package/gsd-core/references/thinking-models-planning.md +18 -2
- package/gsd-core/references/verification-patterns.md +17 -4
- package/gsd-core/references/verifier-evidence-gate.md +160 -0
- package/gsd-core/references/worktree-path-safety.md +112 -2
- package/gsd-core/templates/README.md +7 -1
- package/gsd-core/templates/phase-prompt.md +4 -0
- package/gsd-core/templates/state.md +6 -3
- package/gsd-core/templates/summary.compact.md +212 -0
- package/gsd-core/templates/user-setup.compact.md +199 -0
- package/gsd-core/templates/user-setup.md +0 -9
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/add-backlog.md +2 -0
- package/gsd-core/workflows/add-phase.md +2 -0
- package/gsd-core/workflows/add-tests.md +1 -1
- package/gsd-core/workflows/add-todo.md +4 -3
- package/gsd-core/workflows/ai-integration-phase.md +1 -1
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +2 -0
- package/gsd-core/workflows/audit-milestone.md +2 -0
- package/gsd-core/workflows/audit-uat.md +2 -0
- package/gsd-core/workflows/autonomous.md +15 -10
- package/gsd-core/workflows/check-todos.md +5 -3
- package/gsd-core/workflows/cleanup.md +4 -2
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +22 -13
- package/gsd-core/workflows/code-review-fix.md +5 -3
- package/gsd-core/workflows/code-review.md +211 -43
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
- package/gsd-core/workflows/complete-milestone.md +40 -254
- package/gsd-core/workflows/debug.md +1 -1
- package/gsd-core/workflows/diagnose-issues.md +5 -1
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -0
- 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 +2 -0
- 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 +2 -0
- 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.md +1 -1
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +43 -13
- package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
- package/gsd-core/workflows/docs-update.md +15 -156
- package/gsd-core/workflows/edit-phase.md +2 -0
- package/gsd-core/workflows/eval-review.md +1 -1
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +20 -3
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +24 -3
- package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +8 -2
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +78 -159
- package/gsd-core/workflows/execute-plan.md +28 -15
- package/gsd-core/workflows/explore.md +2 -0
- package/gsd-core/workflows/extract-learnings.md +2 -0
- package/gsd-core/workflows/fast.md +6 -0
- package/gsd-core/workflows/forensics.md +2 -0
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +1 -1
- 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.compact.md +398 -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 +3 -1
- package/gsd-core/workflows/import.md +3 -3
- package/gsd-core/workflows/inbox.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +2 -0
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +2 -0
- package/gsd-core/workflows/list-workspaces.md +2 -0
- package/gsd-core/workflows/manager.md +3 -3
- package/gsd-core/workflows/map-codebase.md +52 -3
- package/gsd-core/workflows/milestone-summary.md +2 -0
- package/gsd-core/workflows/mvp-phase.md +1 -1
- package/gsd-core/workflows/new-milestone.md +55 -13
- package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
- package/gsd-core/workflows/new-project.md +37 -205
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +2 -0
- 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 +19 -4
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -0
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +9 -0
- package/gsd-core/workflows/plan-phase.md +144 -185
- package/gsd-core/workflows/plan-review-convergence.md +102 -10
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +30 -10
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +25 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +37 -2
- package/gsd-core/workflows/quick/steps/research-phase.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 +21 -4
- package/gsd-core/workflows/reapply-patches.md +79 -3
- package/gsd-core/workflows/remove-phase.md +2 -0
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +6 -2
- package/gsd-core/workflows/review.md +215 -10
- package/gsd-core/workflows/scan.md +2 -0
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +2 -0
- package/gsd-core/workflows/settings-integrations.md +9 -8
- package/gsd-core/workflows/settings.md +19 -6
- package/gsd-core/workflows/ship.md +10 -10
- package/gsd-core/workflows/sketch-wrap-up.md +2 -0
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +1 -1
- package/gsd-core/workflows/spec-phase.md +24 -19
- package/gsd-core/workflows/spike-wrap-up.md +2 -0
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +2 -0
- package/gsd-core/workflows/sync-skills.md +12 -4
- package/gsd-core/workflows/thread.md +2 -0
- package/gsd-core/workflows/transition.md +2 -0
- package/gsd-core/workflows/ui-phase.md +26 -5
- package/gsd-core/workflows/ui-review.md +1 -1
- package/gsd-core/workflows/ultraplan-phase.md +2 -0
- package/gsd-core/workflows/undo.md +1 -1
- package/gsd-core/workflows/update.md +48 -43
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
- package/gsd-core/workflows/verify-work.md +68 -182
- package/hooks/dist/gsd-agent-isolation-guard.js +42 -16
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-context-monitor.js +371 -27
- package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
- package/hooks/dist/gsd-node-runner.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +30 -5
- package/hooks/dist/gsd-read-guard.js +2 -0
- package/hooks/dist/gsd-read-injection-scanner.js +5 -5
- package/hooks/dist/gsd-secret-read-guard.js +1105 -0
- package/hooks/dist/gsd-statusline.js +18 -10
- package/hooks/dist/gsd-validate-commit.sh +474 -7
- package/hooks/dist/gsd-workflow-guard.js +2 -1
- package/hooks/dist/gsd-worktree-path-guard.js +25 -14
- package/hooks/dist/gsd-write-guard.js +46 -1
- package/hooks/dist/lib/dispatch-identity.js +187 -0
- package/hooks/dist/lib/filename-classification.js +64 -0
- package/hooks/dist/lib/git-cmd.js +210 -1
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/lib/isolation-deny-reason.js +53 -1
- package/hooks/dist/lib/isolation-sentinel.js +58 -19
- package/hooks/dist/managed-hooks-registry.cjs +1 -0
- package/hooks/gsd-agent-isolation-guard.js +42 -16
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-context-monitor.js +371 -27
- package/hooks/gsd-cursor-subagent-start.js +34 -14
- package/hooks/gsd-node-runner.sh +1 -0
- package/hooks/gsd-prompt-guard.js +30 -5
- package/hooks/gsd-read-guard.js +2 -0
- package/hooks/gsd-read-injection-scanner.js +5 -5
- package/hooks/gsd-secret-read-guard.js +1105 -0
- package/hooks/gsd-statusline.js +18 -10
- package/hooks/gsd-validate-commit.sh +474 -7
- package/hooks/gsd-workflow-guard.js +2 -1
- package/hooks/gsd-worktree-path-guard.js +25 -14
- package/hooks/gsd-write-guard.js +46 -1
- package/hooks/hooks.json +6 -0
- package/hooks/lib/dispatch-identity.js +187 -0
- package/hooks/lib/filename-classification.js +64 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/lib/isolation-deny-reason.js +53 -1
- package/hooks/lib/isolation-sentinel.js +58 -19
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +13 -9
- package/scripts/benchmark-compact-content-variants.cjs +298 -0
- package/scripts/benchmark-compact-content.cjs +368 -0
- package/scripts/build-hooks.js +11 -4
- package/scripts/check-contract-drift.cjs +4 -1
- package/scripts/check-env.cjs +36 -8
- package/scripts/check-glossary-refs.cjs +25 -21
- package/scripts/ci-next-health.cjs +271 -0
- package/scripts/ci-prepare-test-scope.cjs +7 -7
- package/scripts/ci-test-scope.cjs +133 -20
- package/scripts/ci-timeout-report.cjs +1 -1
- package/scripts/diff-touches-shipped-paths.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +17 -2
- package/scripts/gen-adr-index.cjs +8 -2
- package/scripts/gen-inventory-manifest.cjs +12 -0
- package/scripts/gen-loop-host-contract.cjs +67 -15
- package/scripts/gen-platform-conformance-tier.cjs +557 -0
- package/scripts/lib/drift-scan.cjs +1 -1
- package/scripts/lib/macos-conformance-tier.generated.cjs +210 -0
- package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +276 -0
- package/scripts/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lib/suite-detection.cjs +32 -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-allowed-tools-parity.cjs +221 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +24 -2
- package/scripts/lint-phase-enumeration-drift.cjs +24 -6
- package/scripts/lint-phase-id-drift.cjs +465 -15
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-response-language-coverage.cjs +530 -0
- package/scripts/lint-source-test-name-collision.cjs +1 -1
- package/scripts/lint-test-file-count.allowlist.json +4 -1
- package/scripts/lint-vendored-deps.cjs +128 -17
- package/scripts/lint-workflow-shellcheck-baseline.json +1112 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +22 -0
- package/scripts/require-issue-link-policy.cjs +16 -1
- package/scripts/workflow-size.cjs +139 -0
- package/skills/gsd-cleanup/SKILL.md +1 -0
- package/skills/gsd-code-review/SKILL.md +2 -1
- package/skills/gsd-complete-milestone/SKILL.md +1 -0
- package/skills/gsd-config/SKILL.md +1 -0
- package/skills/gsd-debug/SKILL.md +1 -0
- package/skills/gsd-execute-phase/SKILL.md +1 -1
- package/skills/gsd-graphify/SKILL.md +1 -0
- package/skills/gsd-health/SKILL.md +1 -0
- package/skills/gsd-mempalace-capture/SKILL.md +1 -0
- package/skills/gsd-mempalace-recall/SKILL.md +1 -0
- package/skills/gsd-new-milestone/SKILL.md +1 -0
- package/skills/gsd-new-project/SKILL.md +1 -0
- package/skills/gsd-next/SKILL.md +1 -0
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-pause-work/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +2 -1
- package/skills/gsd-pr-branch/SKILL.md +1 -0
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-resume-work/SKILL.md +1 -0
- package/skills/gsd-review-backlog/SKILL.md +1 -0
- package/skills/gsd-settings/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +1 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- package/skills/gsd-thread/SKILL.md +1 -0
- package/skills/gsd-workspace/SKILL.md +1 -0
- package/skills/gsd-workstreams/SKILL.md +1 -0
- package/vscode/package.json +1 -1
- package/gsd-core/templates/claude-md.md +0 -145
- package/gsd-core/templates/codebase/concerns.md +0 -310
- package/gsd-core/templates/codebase/conventions.md +0 -307
- package/gsd-core/templates/codebase/integrations.md +0 -280
- package/gsd-core/templates/codebase/structure.md +0 -285
- package/gsd-core/templates/codebase/testing.md +0 -480
- package/gsd-core/templates/debug-subagent-prompt.md +0 -91
- package/gsd-core/templates/discovery.md +0 -146
|
@@ -276,8 +276,22 @@ const kiloAgentPermissionOrder = [
|
|
|
276
276
|
'codesearch',
|
|
277
277
|
'lsp',
|
|
278
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
|
+
*/
|
|
279
289
|
function convertClaudeToKiloPermissionTool(claudeTool) {
|
|
280
|
-
|
|
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;
|
|
281
295
|
}
|
|
282
296
|
function buildKiloAgentPermissionBlock(claudeTools) {
|
|
283
297
|
const allowedPermissions = new Set();
|
|
@@ -291,6 +305,11 @@ function buildKiloAgentPermissionBlock(claudeTools) {
|
|
|
291
305
|
for (const permission of kiloAgentPermissionOrder) {
|
|
292
306
|
lines.push(` ${permission}: ${allowedPermissions.has(permission) ? 'allow' : 'deny'}`);
|
|
293
307
|
}
|
|
308
|
+
for (const permission of allowedPermissions) {
|
|
309
|
+
if (kiloAgentPermissionOrder.includes(permission))
|
|
310
|
+
continue;
|
|
311
|
+
lines.push(` ${permission}: allow`);
|
|
312
|
+
}
|
|
294
313
|
return lines;
|
|
295
314
|
}
|
|
296
315
|
function replaceRelativePathReference(content, fromPath, toPath) {
|
|
@@ -645,6 +664,137 @@ function convertClaudeCommandToKimiCodeSkill(content, skillName, _runtime = null
|
|
|
645
664
|
return convertClaudeCommandToKimiSkill(content, skillName, _runtime, cmdNames);
|
|
646
665
|
}
|
|
647
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
|
+
}
|
|
648
798
|
function parseKimiAgentSource(source) {
|
|
649
799
|
if (typeof source === 'string') {
|
|
650
800
|
return {
|
|
@@ -672,7 +822,9 @@ function parseFrontmatterTools(frontmatter) {
|
|
|
672
822
|
continue;
|
|
673
823
|
if (collecting) {
|
|
674
824
|
if (trimmed.startsWith('- ')) {
|
|
675
|
-
|
|
825
|
+
const tool = decodeToolScalar(trimmed.slice(2));
|
|
826
|
+
if (tool !== null)
|
|
827
|
+
tools.push(tool);
|
|
676
828
|
continue;
|
|
677
829
|
}
|
|
678
830
|
collecting = false;
|
|
@@ -683,10 +835,13 @@ function parseFrontmatterTools(frontmatter) {
|
|
|
683
835
|
}
|
|
684
836
|
if (trimmed.startsWith('tools:') || trimmed.startsWith('allowed-tools:')) {
|
|
685
837
|
const value = trimmed.slice(trimmed.indexOf(':') + 1).trim();
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
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)
|
|
690
845
|
tools.push(name);
|
|
691
846
|
}
|
|
692
847
|
}
|
|
@@ -856,7 +1011,7 @@ function buildKimiAgentArtifacts({ rootAgent = '', subagents = [], requestedSuba
|
|
|
856
1011
|
* @param {boolean} [isGlobal=false] - Whether this is a global install
|
|
857
1012
|
*/
|
|
858
1013
|
function convertClaudeToAntigravityContent(content, isGlobal = false) {
|
|
859
|
-
let c = content;
|
|
1014
|
+
let c = filterRuntimeNotesForTarget(content, 'antigravity');
|
|
860
1015
|
if (isGlobal) {
|
|
861
1016
|
// #3738: global skills install under ~/.gemini/config/skills (the dir AGY
|
|
862
1017
|
// scans for global discovery), so skills-path references must divert there
|
|
@@ -948,7 +1103,7 @@ function convertSlashCommandsToCursorSkillMentions(content) {
|
|
|
948
1103
|
return content.replace(/gsd:/gi, 'gsd-');
|
|
949
1104
|
}
|
|
950
1105
|
function convertClaudeToCursorMarkdown(content) {
|
|
951
|
-
let converted = convertSlashCommandsToCursorSkillMentions(content);
|
|
1106
|
+
let converted = convertSlashCommandsToCursorSkillMentions(filterRuntimeNotesForTarget(content, 'cursor'));
|
|
952
1107
|
// Replace tool name references in body text
|
|
953
1108
|
converted = converted.replace(/\bBash\(/g, 'Shell(');
|
|
954
1109
|
converted = converted.replace(/\bEdit\(/g, 'StrReplace(');
|
|
@@ -1048,7 +1203,7 @@ function convertSlashCommandsToWindsurfSkillMentions(content) {
|
|
|
1048
1203
|
return content.replace(/gsd:/gi, 'gsd-');
|
|
1049
1204
|
}
|
|
1050
1205
|
function convertClaudeToWindsurfMarkdown(content) {
|
|
1051
|
-
let converted = convertSlashCommandsToWindsurfSkillMentions(content);
|
|
1206
|
+
let converted = convertSlashCommandsToWindsurfSkillMentions(filterRuntimeNotesForTarget(content, 'windsurf'));
|
|
1052
1207
|
// Replace tool name references in body text
|
|
1053
1208
|
converted = converted.replace(/\bBash\(/g, 'Shell(');
|
|
1054
1209
|
converted = converted.replace(/\bEdit\(/g, 'StrReplace(');
|
|
@@ -1207,7 +1362,7 @@ function convertSlashCommandsToAugmentSkillMentions(content) {
|
|
|
1207
1362
|
return content.replace(/gsd:/gi, 'gsd-');
|
|
1208
1363
|
}
|
|
1209
1364
|
function convertClaudeToAugmentMarkdown(content) {
|
|
1210
|
-
let converted = convertSlashCommandsToAugmentSkillMentions(content);
|
|
1365
|
+
let converted = convertSlashCommandsToAugmentSkillMentions(filterRuntimeNotesForTarget(content, 'augment'));
|
|
1211
1366
|
converted = converted.replace(/\bBash\(/g, 'launch-process(');
|
|
1212
1367
|
converted = converted.replace(/\bEdit\(/g, 'str-replace-editor(');
|
|
1213
1368
|
converted = converted.replace(/\bRead\(/g, 'view(');
|
|
@@ -1285,7 +1440,7 @@ function convertSlashCommandsToTraeSkillMentions(content) {
|
|
|
1285
1440
|
});
|
|
1286
1441
|
}
|
|
1287
1442
|
function convertClaudeToTraeMarkdown(content) {
|
|
1288
|
-
let converted = convertSlashCommandsToTraeSkillMentions(content);
|
|
1443
|
+
let converted = convertSlashCommandsToTraeSkillMentions(filterRuntimeNotesForTarget(content, 'trae'));
|
|
1289
1444
|
converted = converted.replace(/\bBash\(/g, 'Shell(');
|
|
1290
1445
|
converted = converted.replace(/\bEdit\(/g, 'StrReplace(');
|
|
1291
1446
|
// Replace general-purpose subagent type with Trae's equivalent "general_purpose_task"
|
|
@@ -1393,7 +1548,7 @@ function convertSlashCommandsToCodebuddySkillMentions(content) {
|
|
|
1393
1548
|
});
|
|
1394
1549
|
}
|
|
1395
1550
|
function convertClaudeToCodebuddyMarkdown(content) {
|
|
1396
|
-
let converted = convertSlashCommandsToCodebuddySkillMentions(content);
|
|
1551
|
+
let converted = convertSlashCommandsToCodebuddySkillMentions(filterRuntimeNotesForTarget(content, 'codebuddy'));
|
|
1397
1552
|
// CodeBuddy uses the same tool names as Claude Code (Bash, Edit, Read, Write, etc.)
|
|
1398
1553
|
// No tool name conversion needed
|
|
1399
1554
|
converted = converted.replace(/\$ARGUMENTS\b/g, '{{GSD_ARGS}}');
|
|
@@ -1470,7 +1625,7 @@ function convertClaudeCommandToCodebuddyCommand(content, commandName) {
|
|
|
1470
1625
|
}
|
|
1471
1626
|
// ── Cline converters ────────────────────────────────────────────────────────
|
|
1472
1627
|
function convertClaudeToCliineMarkdown(content) {
|
|
1473
|
-
let converted = content;
|
|
1628
|
+
let converted = filterRuntimeNotesForTarget(content, 'cline');
|
|
1474
1629
|
// Cline uses the same tool names as Claude Code — no tool name conversion needed
|
|
1475
1630
|
converted = converted.replace(/`\.\/CLAUDE\.md`/g, '`.clinerules`');
|
|
1476
1631
|
converted = converted.replace(/\.\/CLAUDE\.md/g, '.clinerules');
|
|
@@ -1557,7 +1712,7 @@ function rewriteBareGsdToolsCommandsForCodex(content) {
|
|
|
1557
1712
|
.replace(/((?:&&|\|\||[;|])\s*)gsd-tools(?=\s)/g, `$1${CODEX_GSD_TOOLS_INVOCATION}`);
|
|
1558
1713
|
}
|
|
1559
1714
|
function convertClaudeToCodexMarkdown(content) {
|
|
1560
|
-
let converted = convertSlashCommandsToCodexSkillMentions(content);
|
|
1715
|
+
let converted = convertSlashCommandsToCodexSkillMentions(filterRuntimeNotesForTarget(content, 'codex'));
|
|
1561
1716
|
converted = converted.replace(/\$ARGUMENTS\b/g, '{{GSD_ARGS}}');
|
|
1562
1717
|
// Remove /clear references — Codex has no equivalent command
|
|
1563
1718
|
// Handle backtick-wrapped: `\/clear` then: → (removed)
|
|
@@ -1623,26 +1778,37 @@ Execute mode fallback:
|
|
|
1623
1778
|
## C. Task() → spawn_agent Mapping
|
|
1624
1779
|
GSD workflows use \`Task(...)\` (Claude Code syntax). Translate to Codex collaboration tools:
|
|
1625
1780
|
|
|
1626
|
-
**Schema detection (required first step):**
|
|
1627
|
-
|
|
1628
|
-
|
|
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.
|
|
1629
1787
|
|
|
1630
|
-
|
|
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.
|
|
1631
1790
|
|
|
1632
1791
|
Typed mapping (agent_type-capable schema only):
|
|
1633
1792
|
- \`Task(subagent_type="X", prompt="Y")\` → \`spawn_agent(agent_type="X", message="Y")\`
|
|
1634
1793
|
- \`Agent(subagent_type="X", prompt="Y")\` → \`spawn_agent(agent_type="X", message="Y")\`
|
|
1635
|
-
- \`Task(model="
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
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.
|
|
1643
1809
|
- \`fork_context: false\` by default — GSD agents load their own context via \`<required_reading>\` blocks
|
|
1644
|
-
- \`task_name\` —
|
|
1645
|
-
- \`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)
|
|
1646
1812
|
- \`Task(isolation="worktree")\` / \`Agent(isolation="worktree")\` → no direct \`spawn_agent\` mapping,
|
|
1647
1813
|
but Codex declares \`dispatch.isolation: orchestrator-worktree\` (#2584). Codex
|
|
1648
1814
|
\`spawn_agent\` still does not create or bind a git worktree; instead GSD itself
|
|
@@ -1735,9 +1901,24 @@ function frontmatterScalar(key, value) {
|
|
|
1735
1901
|
? `${key} "${frontmatterModule.escapeDoubleQuotedScalar(value)}"`
|
|
1736
1902
|
: `${key} ${value}`;
|
|
1737
1903
|
}
|
|
1904
|
+
const RUNTIME_NOTE_AUDIENCE_BY_HEADING = new Map([
|
|
1905
|
+
['copilot (vs code)', 'copilot'],
|
|
1906
|
+
]);
|
|
1907
|
+
function filterRuntimeNotesForTarget(content, targetRuntime) {
|
|
1908
|
+
return content.replace(/<runtime_note(?:\s+runtime=["']([^"']+)["'])?>([\s\S]*?)<\/runtime_note>/g, (whole, declaredAudience, inner) => {
|
|
1909
|
+
if (declaredAudience && declaredAudience.toLowerCase() !== targetRuntime)
|
|
1910
|
+
return '';
|
|
1911
|
+
const remaining = inner.replace(/(?:^|\n)[ \t]*\*\*([^*\n]+):\*\*[^\n]*(?:\n(?![ \t]*\n)[^\n]*)*/g, (section, heading) => {
|
|
1912
|
+
const audience = RUNTIME_NOTE_AUDIENCE_BY_HEADING.get(heading.trim().toLowerCase());
|
|
1913
|
+
return audience && audience !== targetRuntime ? '' : section;
|
|
1914
|
+
});
|
|
1915
|
+
const body = remaining.trim();
|
|
1916
|
+
return body ? `<runtime_note>\n${body}\n</runtime_note>` : '';
|
|
1917
|
+
});
|
|
1918
|
+
}
|
|
1738
1919
|
function convertClaudeToOpencodeFrontmatter(content, { isAgent = false, modelOverride = null, variant = null } = {}) {
|
|
1739
1920
|
// Replace tool name references in content (applies to all files)
|
|
1740
|
-
let convertedContent = content;
|
|
1921
|
+
let convertedContent = filterRuntimeNotesForTarget(content, 'opencode');
|
|
1741
1922
|
convertedContent = convertedContent.replace(/\bAskUserQuestion\b/g, 'question');
|
|
1742
1923
|
convertedContent = convertedContent.replace(/\bSlashCommand\b/g, 'skill');
|
|
1743
1924
|
convertedContent = convertedContent.replace(/\bTodoWrite\b/g, 'todowrite');
|
|
@@ -1898,7 +2079,7 @@ function convertClaudeToOpencodeFrontmatter(content, { isAgent = false, modelOve
|
|
|
1898
2079
|
// (#2093).
|
|
1899
2080
|
function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverride = null } = {}) {
|
|
1900
2081
|
// Replace tool name references in content (applies to all files)
|
|
1901
|
-
let convertedContent = content;
|
|
2082
|
+
let convertedContent = filterRuntimeNotesForTarget(content, 'kilo');
|
|
1902
2083
|
convertedContent = convertedContent.replace(/\bAskUserQuestion\b/g, 'question');
|
|
1903
2084
|
convertedContent = convertedContent.replace(/\bSlashCommand\b/g, 'skill');
|
|
1904
2085
|
convertedContent = convertedContent.replace(/\bTodoWrite\b/g, 'todowrite');
|
|
@@ -1948,7 +2129,9 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
1948
2129
|
}
|
|
1949
2130
|
if (isAgent && inAgentTools) {
|
|
1950
2131
|
if (trimmed.startsWith('- ')) {
|
|
1951
|
-
|
|
2132
|
+
const tool = decodeToolScalar(trimmed.substring(2));
|
|
2133
|
+
if (tool !== null)
|
|
2134
|
+
agentTools.push(tool);
|
|
1952
2135
|
continue;
|
|
1953
2136
|
}
|
|
1954
2137
|
if (trimmed && !trimmed.startsWith('-')) {
|
|
@@ -1959,8 +2142,11 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
1959
2142
|
if (trimmed.startsWith('tools:')) {
|
|
1960
2143
|
if (isAgent) {
|
|
1961
2144
|
const toolsValue = trimmed.substring(6).trim();
|
|
1962
|
-
|
|
1963
|
-
|
|
2145
|
+
// A comment-only value (`tools: # note`) is not real inline content —
|
|
2146
|
+
// fall through to the block-list scan (`inAgentTools`) instead of
|
|
2147
|
+
// decoding the comment as a bogus tool name and dropping the list.
|
|
2148
|
+
if (toolsValue && !toolsValue.startsWith('#')) {
|
|
2149
|
+
const tools = splitToolScalars(toolsValue).map(decodeToolScalar).filter((tool) => tool !== null);
|
|
1964
2150
|
agentTools.push(...tools);
|
|
1965
2151
|
}
|
|
1966
2152
|
else {
|
|
@@ -2022,7 +2208,9 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false, modelOverrid
|
|
|
2022
2208
|
if (trimmed.startsWith('- ')) {
|
|
2023
2209
|
const tool = trimmed.substring(2).trim();
|
|
2024
2210
|
if (isAgent) {
|
|
2025
|
-
|
|
2211
|
+
const decoded = decodeToolScalar(tool);
|
|
2212
|
+
if (decoded !== null)
|
|
2213
|
+
agentTools.push(decoded);
|
|
2026
2214
|
}
|
|
2027
2215
|
else {
|
|
2028
2216
|
allowedTools.push(tool);
|
|
@@ -2355,11 +2543,16 @@ function convertClaudeAgentToQwenAgent(content) {
|
|
|
2355
2543
|
* Byte-identical for an agent with no `mcp__*` grants (the common case) and
|
|
2356
2544
|
* for an agent with no frontmatter at all.
|
|
2357
2545
|
*/
|
|
2546
|
+
/** Fail-closed: an undecodable scalar is dropped, never kept (ZCode's contract is "never emit mcp__*"). */
|
|
2547
|
+
function zcodeKeepsGrant(rawTool) {
|
|
2548
|
+
const decoded = decodeToolScalar(rawTool);
|
|
2549
|
+
return decoded !== null && !decoded.startsWith('mcp__');
|
|
2550
|
+
}
|
|
2358
2551
|
function convertClaudeAgentToZcodeAgent(content) {
|
|
2359
|
-
//
|
|
2360
|
-
//
|
|
2361
|
-
//
|
|
2362
|
-
if (!content.includes('mcp__'))
|
|
2552
|
+
// A double-quoted YAML scalar may encode the leading "m" in mcp__ as an
|
|
2553
|
+
// escape, so only skip the shared scalar-decoder scan when neither form is
|
|
2554
|
+
// present. The unchanged scan below still preserves byte-identical content.
|
|
2555
|
+
if (!content.includes('mcp__') && !content.includes('\\'))
|
|
2363
2556
|
return content;
|
|
2364
2557
|
const lines = content.split('\n');
|
|
2365
2558
|
if (lines[0] !== '---')
|
|
@@ -2379,9 +2572,14 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2379
2572
|
while (i < fmEnd) {
|
|
2380
2573
|
const line = lines[i];
|
|
2381
2574
|
const inlineTools = /^tools:[ \t]*(.+)$/.exec(line);
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2575
|
+
// A header that is ONLY a comment (`tools: # note`) is not real inline
|
|
2576
|
+
// content — fall through to the block-list scan below instead of
|
|
2577
|
+
// matching here, or a following block list's mcp__* items never get
|
|
2578
|
+
// scanned and leak through unstripped.
|
|
2579
|
+
const commentOnlyHeader = inlineTools !== null && inlineTools[1].trim().startsWith('#');
|
|
2580
|
+
if (inlineTools && !commentOnlyHeader) {
|
|
2581
|
+
const grants = splitToolScalars(inlineTools[1]).map((tool) => tool.trim()).filter((tool) => tool !== '');
|
|
2582
|
+
const kept = grants.filter((tool) => zcodeKeepsGrant(tool));
|
|
2385
2583
|
if (kept.length === grants.length) {
|
|
2386
2584
|
out.push(line); // no mcp__* grants — keep the line byte-identical
|
|
2387
2585
|
}
|
|
@@ -2395,7 +2593,7 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2395
2593
|
i++;
|
|
2396
2594
|
continue;
|
|
2397
2595
|
}
|
|
2398
|
-
if (/^tools:[ \t]*$/.test(line)) {
|
|
2596
|
+
if (/^tools:[ \t]*$/.test(line) || commentOnlyHeader) {
|
|
2399
2597
|
// Block-list form: collect the following `- item` lines.
|
|
2400
2598
|
const items = [];
|
|
2401
2599
|
let j = i + 1;
|
|
@@ -2405,7 +2603,7 @@ function convertClaudeAgentToZcodeAgent(content) {
|
|
|
2405
2603
|
}
|
|
2406
2604
|
const kept = items.filter((item) => {
|
|
2407
2605
|
const name = /^([ \t]*)-[ \t]*(\S.*)$/.exec(item)[2].trim();
|
|
2408
|
-
return
|
|
2606
|
+
return zcodeKeepsGrant(name);
|
|
2409
2607
|
});
|
|
2410
2608
|
if (kept.length !== items.length) {
|
|
2411
2609
|
changed = true;
|
|
@@ -2762,6 +2960,7 @@ function restoreClaudeGlobalAtRefTilde(content, pathPrefix) {
|
|
|
2762
2960
|
function _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal = false, attribution = undefined) {
|
|
2763
2961
|
const dirName = getDirName(runtime);
|
|
2764
2962
|
const normalizedPathPrefix = pathPrefix.replace(/\/$/, '');
|
|
2963
|
+
content = filterRuntimeNotesForTarget(content, runtime);
|
|
2765
2964
|
// #1521: stamp runtime identity + use_worktrees=false for every non-Claude runtime
|
|
2766
2965
|
// before brand-specific path rewrites, so the replace operates on the pristine
|
|
2767
2966
|
// source line and is idempotent regardless of subsequent path substitutions.
|
|
@@ -2940,6 +3139,20 @@ function _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal = false, a
|
|
|
2940
3139
|
content = content.replace(/\.\/\.claude\b/g, `./${dirName}`);
|
|
2941
3140
|
content = processAttribution(content, attribution);
|
|
2942
3141
|
break;
|
|
3142
|
+
case 'zcode':
|
|
3143
|
+
// #4002: ZCode is a Claude-Code-shaped host (dot-home `.zcode`, `@~`-ref
|
|
3144
|
+
// expansion, `~/.zcode/...` documented paths) whose commands install with
|
|
3145
|
+
// `converter: null` — this pass is their only chance to receive
|
|
3146
|
+
// runtime-correct paths. Same shape as `claude`, including the tilde
|
|
3147
|
+
// restore: the tilde form is what ZCode expands and what its docs use.
|
|
3148
|
+
// `${_GSD_RUNTIME_ROOT}/.claude/…` matches none of these regexes and
|
|
3149
|
+
// survives as the project-local fallback, exactly as on every sibling.
|
|
3150
|
+
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
3151
|
+
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
|
3152
|
+
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
|
3153
|
+
content = restoreClaudeGlobalAtRefTilde(content, pathPrefix);
|
|
3154
|
+
content = processAttribution(content, attribution);
|
|
3155
|
+
break;
|
|
2943
3156
|
default:
|
|
2944
3157
|
// Unknown runtime — no rewrites (OpenCode/Kilo handled by their own install path).
|
|
2945
3158
|
break;
|
|
@@ -3364,6 +3577,7 @@ function processAttribution(content, attribution) {
|
|
|
3364
3577
|
}
|
|
3365
3578
|
module.exports = {
|
|
3366
3579
|
processAttribution,
|
|
3580
|
+
appendAgentTools,
|
|
3367
3581
|
// #2103: public accessor for hostBehaviors.agentFileExtension, exported so
|
|
3368
3582
|
// surface.cts's _syncGsdDir can derive the .agent.md rename from the SAME
|
|
3369
3583
|
// descriptor read as install-engine.cts (folds a duplicated hardcoded
|
|
@@ -3415,11 +3629,14 @@ module.exports = {
|
|
|
3415
3629
|
neutralizeAgentReferences,
|
|
3416
3630
|
convertClaudeCommandToOpencodeSkill,
|
|
3417
3631
|
convertClaudeCommandToKiloSkill,
|
|
3632
|
+
filterRuntimeNotesForTarget,
|
|
3418
3633
|
// #2087 — opencode/kilo command-frontmatter converters, exported so the
|
|
3419
3634
|
// layout-driven `convertedCommandsKind` can resolve them by name (routes the
|
|
3420
3635
|
// opencode/kilo command install through the engine instead of the bespoke path).
|
|
3421
3636
|
convertClaudeToOpencodeFrontmatter,
|
|
3422
3637
|
convertClaudeToKiloFrontmatter,
|
|
3638
|
+
_decodeToolScalar: decodeToolScalar,
|
|
3639
|
+
_splitToolScalars: splitToolScalars,
|
|
3423
3640
|
readGsdCommandNames,
|
|
3424
3641
|
transformContentToHyphen,
|
|
3425
3642
|
// #1383: version resolver (exported for regression test of the Codex
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// In .cts (CommonJS output) files, `require` is available as a global.
|
|
10
10
|
const _require = require;
|
|
11
11
|
const path = _require('node:path');
|
|
12
|
+
const { tryWithinRootLexical } = _require('./security.cjs');
|
|
12
13
|
// #2870: InstallScope is owned by install-scope.cts, not re-declared here.
|
|
13
14
|
// `isGlobalScope` centralizes the `scope === 'global'` boolean projection
|
|
14
15
|
// this module needs at `_computePathPrefix`'s `isGlobal: boolean` boundary
|
|
@@ -33,11 +34,19 @@ function assertDestWithinConfigHome(configDir, destSubpath) {
|
|
|
33
34
|
throw new Error(`destSubpath "${destSubpath}" contains a NUL byte and is not valid`);
|
|
34
35
|
}
|
|
35
36
|
const root = path.resolve(configDir);
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
// `resolved === root` is a DELIBERATE ADDITIONAL rejection, separate from
|
|
38
|
+
// the containment decision: `tryWithinRootLexical` treats target === root
|
|
39
|
+
// as CONTAINED, but a destSubpath of "" (or one that resolves to configDir
|
|
40
|
+
// itself) must never be accepted here — this is the strict-subpath
|
|
41
|
+
// requirement Phase B of ADR-1239 imposes on third-party descriptors, and
|
|
42
|
+
// it prevents a descriptor from writing at configHome itself. Kept as its
|
|
43
|
+
// own check per ADR-4650 decision 6 (a wrapper may add its own conditions
|
|
44
|
+
// on top of the canonical predicate, never invert it).
|
|
45
|
+
const contained = tryWithinRootLexical(destSubpath, configDir);
|
|
46
|
+
if (contained === null || contained === root) {
|
|
38
47
|
throw new Error(`destSubpath "${destSubpath}" must be a strict subpath of configHome "${configDir}" — not configHome itself or outside it (escapes configHome)`);
|
|
39
48
|
}
|
|
40
|
-
return
|
|
49
|
+
return contained;
|
|
41
50
|
}
|
|
42
51
|
function errorMessage(err) {
|
|
43
52
|
if (err instanceof Error)
|
|
@@ -51,7 +60,7 @@ function addCleanupDir(cleanupDirs, stagedDir, rewrittenDir) {
|
|
|
51
60
|
return sourceDir;
|
|
52
61
|
}
|
|
53
62
|
function createRuntimeArtifactInstallPlan(args) {
|
|
54
|
-
const { layout, resolvedProfile, homedir, platform, resolveAttribution, deps = {}, } = args;
|
|
63
|
+
const { layout, resolvedProfile, homedir, platform, resolveAttribution, projectDir, deps = {}, } = args;
|
|
55
64
|
const conversionExports = _require('./runtime-artifact-conversion.cjs');
|
|
56
65
|
const rewriteStagedSkillBodies = deps.rewriteStagedSkillBodies ?? conversionExports.rewriteStagedSkillBodies;
|
|
57
66
|
const rewriteStagedCommandBodies = deps.rewriteStagedCommandBodies ?? conversionExports.rewriteStagedCommandBodies;
|
|
@@ -66,11 +75,10 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
66
75
|
platform,
|
|
67
76
|
resolveAttribution,
|
|
68
77
|
};
|
|
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).
|
|
78
|
+
// ADR-1235 §1: build the staging context once per plan. Agent kinds apply
|
|
79
|
+
// the CORRECT pre-converter cross-cutting (path rewrites → attribution →
|
|
80
|
+
// converter → normalize). This
|
|
81
|
+
// mirrors the exact per-file order in the former inline agent loop.
|
|
74
82
|
// NO _stampNonClaudeRuntimeDefaults — agents are NOT stamped in the inline loop.
|
|
75
83
|
const os = _require('node:os');
|
|
76
84
|
const { posixNormalize } = _require('./shell-command-projection.cjs');
|
|
@@ -88,19 +96,19 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
88
96
|
const attribution = resolveAttribution ? resolveAttribution(layout.runtime) : undefined;
|
|
89
97
|
// #2875 Part 2 (row I1): layout.configDir IS the install root the inline
|
|
90
98
|
// agent loop called `targetDir` — same value, same resolution.
|
|
91
|
-
const agentCtx = {
|
|
99
|
+
const agentCtx = {
|
|
100
|
+
runtime: layout.runtime,
|
|
101
|
+
pathPrefix,
|
|
102
|
+
attribution,
|
|
103
|
+
targetDir: layout.configDir,
|
|
104
|
+
projectDir: projectDir ?? layout.configDir,
|
|
105
|
+
};
|
|
92
106
|
for (const kind of layout.kinds) {
|
|
93
107
|
let stagedDir;
|
|
94
108
|
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
|
-
}
|
|
109
|
+
// Agent kinds use the context for their pre-converter cross-cutting
|
|
110
|
+
// sequence; other kinds ignore it.
|
|
111
|
+
stagedDir = kind.stage(resolvedProfile, agentCtx);
|
|
104
112
|
}
|
|
105
113
|
catch (err) {
|
|
106
114
|
return { ok: false, kind: 'stage_failed', message: errorMessage(err), cleanupDirs, failedKind: kind.kind };
|
|
@@ -115,7 +123,7 @@ function createRuntimeArtifactInstallPlan(args) {
|
|
|
115
123
|
const rewrittenDir = rewriteStagedSkillBodies(stagedDir, rewriteOpts);
|
|
116
124
|
sourceDir = addCleanupDir(cleanupDirs, stagedDir, rewrittenDir);
|
|
117
125
|
}
|
|
118
|
-
//
|
|
126
|
+
// Agent kinds: cross-cutting already applied INSIDE kind.stage() via agentCtx.
|
|
119
127
|
// No POST-step needed. sourceDir stays as stagedDir.
|
|
120
128
|
}
|
|
121
129
|
catch (err) {
|