@opengsd/gsd-core 1.10.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/agents/gsd-debug-session-manager.md +11 -0
- package/agents/gsd-doc-synthesizer.md +2 -4
- package/agents/gsd-executor.md +5 -5
- package/agents/gsd-mempalace-curator.md +5 -2
- package/agents/gsd-phase-researcher.md +20 -1
- package/agents/gsd-plan-checker.md +37 -0
- package/agents/gsd-planner.md +44 -46
- package/agents/gsd-user-profiler.md +3 -0
- package/agents/gsd-verifier.md +12 -3
- package/bin/install.js +841 -971
- package/bin/lib/ui-safety-gate.cjs +2 -0
- package/commands/gsd/code-review.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/map-codebase.md +1 -1
- package/commands/gsd/mempalace-capture.md +1 -1
- package/commands/gsd/mempalace-recall.md +1 -1
- package/commands/gsd/new-milestone.md +1 -1
- package/commands/gsd/quick.md +1 -1
- package/commands/gsd/review-backlog.md +2 -1
- package/commands/gsd/verify-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +469 -88
- package/gsd-core/bin/lib/active-workstream-store.cjs +138 -22
- package/gsd-core/bin/lib/agent-install-check.cjs +230 -32
- package/gsd-core/bin/lib/api-coverage.cjs +3 -5
- package/gsd-core/bin/lib/artifacts.cjs +3 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
- package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
- package/gsd-core/bin/lib/audit.cjs +876 -240
- package/gsd-core/bin/lib/broken-windows.cjs +1 -1
- package/gsd-core/bin/lib/capability-consent.cjs +149 -15
- package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
- package/gsd-core/bin/lib/capability-registry.cjs +575 -101
- package/gsd-core/bin/lib/capability-source.cjs +92 -0
- package/gsd-core/bin/lib/capability-trust.cjs +444 -25
- package/gsd-core/bin/lib/capability-validator.cjs +495 -22
- package/gsd-core/bin/lib/capability-writer.cjs +3 -2
- package/gsd-core/bin/lib/check-command-router.cjs +71 -37
- package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
- package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
- package/gsd-core/bin/lib/command-aliases.cjs +22 -0
- package/gsd-core/bin/lib/command-roster.cjs +44 -1
- package/gsd-core/bin/lib/commands.cjs +651 -86
- package/gsd-core/bin/lib/commonjs-marker.cjs +12 -6
- package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
- package/gsd-core/bin/lib/config-loader.cjs +75 -0
- package/gsd-core/bin/lib/config.cjs +10 -1
- package/gsd-core/bin/lib/core-utils.cjs +127 -29
- package/gsd-core/bin/lib/decisions.cjs +23 -0
- package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
- package/gsd-core/bin/lib/frontmatter.cjs +155 -20
- package/gsd-core/bin/lib/gap-checker.cjs +68 -7
- package/gsd-core/bin/lib/git-base-branch.cjs +102 -0
- package/gsd-core/bin/lib/gsd2-import.cjs +10 -1
- package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
- package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
- package/gsd-core/bin/lib/init.cjs +321 -129
- package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
- package/gsd-core/bin/lib/install-engine.cjs +745 -258
- package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
- package/gsd-core/bin/lib/install-profiles.cjs +134 -57
- package/gsd-core/bin/lib/install-scope.cjs +270 -0
- package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
- package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +138 -31
- package/gsd-core/bin/lib/io.cjs +10 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +2 -1
- package/gsd-core/bin/lib/markdown-table.cjs +133 -20
- package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
- package/gsd-core/bin/lib/milestone.cjs +754 -70
- package/gsd-core/bin/lib/model-catalog.cjs +59 -1
- package/gsd-core/bin/lib/model-resolver.cjs +183 -40
- package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
- package/gsd-core/bin/lib/pattern.cjs +122 -0
- package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
- package/gsd-core/bin/lib/phase-id.cjs +444 -36
- package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
- package/gsd-core/bin/lib/phase-locator.cjs +125 -18
- package/gsd-core/bin/lib/phase.cjs +646 -143
- package/gsd-core/bin/lib/plan-dependency-graph.cjs +72 -1
- package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
- package/gsd-core/bin/lib/plan-scan.cjs +86 -2
- package/gsd-core/bin/lib/planning-scope.cjs +31 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +56 -6
- package/gsd-core/bin/lib/probe-core.cjs +1 -1
- package/gsd-core/bin/lib/profile-output.cjs +1 -1
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
- package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +11 -6
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +13 -4
- package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +421 -66
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
- package/gsd-core/bin/lib/roadmap-command-router.cjs +34 -0
- package/gsd-core/bin/lib/roadmap-parser.cjs +943 -184
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
- package/gsd-core/bin/lib/roadmap.cjs +385 -94
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +608 -46
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +426 -55
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +69 -3
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +115 -3
- package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
- package/gsd-core/bin/lib/security.cjs +104 -5
- package/gsd-core/bin/lib/shell-command-projection.cjs +275 -3
- package/gsd-core/bin/lib/smart-entry.cjs +142 -22
- package/gsd-core/bin/lib/state-command-router.cjs +5 -1
- package/gsd-core/bin/lib/state-document.cjs +152 -8
- package/gsd-core/bin/lib/state-transition.cjs +371 -117
- package/gsd-core/bin/lib/state.cjs +1794 -357
- package/gsd-core/bin/lib/surface.cjs +23 -9
- package/gsd-core/bin/lib/text-lines.cjs +80 -0
- package/gsd-core/bin/lib/token-scanner.cjs +76 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +9 -3
- package/gsd-core/bin/lib/uat.cjs +399 -56
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
- package/gsd-core/bin/lib/unusable-input.cjs +24 -0
- package/gsd-core/bin/lib/update-context.cjs +8 -2
- package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
- package/gsd-core/bin/lib/validate.cjs +20 -6
- package/gsd-core/bin/lib/vendor/README.md +37 -0
- package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
- package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +258 -8
- package/gsd-core/bin/lib/verify.cjs +368 -888
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +53 -32
- package/gsd-core/bin/lib/workstream-inventory.cjs +63 -10
- package/gsd-core/bin/lib/workstream.cjs +2 -2
- package/gsd-core/bin/lib/worktree-safety.cjs +176 -9
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +7 -1
- package/gsd-core/references/agent-contracts.md +43 -26
- package/gsd-core/references/checkpoints.md +2 -2
- package/gsd-core/references/context-budget.md +1 -1
- package/gsd-core/references/dispatch-isolation-gate.md +138 -0
- package/gsd-core/references/doc-conflict-engine.md +1 -1
- package/gsd-core/references/execute-mvp-tdd.md +3 -3
- package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
- package/gsd-core/references/execute-phase-context-guard.md +1 -1
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +6 -2
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-planning-commit.md +2 -1
- package/gsd-core/references/loop-hook-dispatch.md +39 -2
- package/gsd-core/references/model-profiles.md +12 -4
- package/gsd-core/references/mvp-concepts.md +9 -9
- package/gsd-core/references/planner-guidance.md +3 -9
- package/gsd-core/references/planner-preconditions.md +1 -1
- package/gsd-core/references/planner-reviews.md +1 -1
- package/gsd-core/references/planning-config.md +8 -6
- package/gsd-core/references/revision-loop.md +1 -1
- package/gsd-core/references/specless-probe-fallback.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +3 -3
- package/gsd-core/references/verifier-phase-gates.md +192 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +22 -6
- package/gsd-core/templates/discussion-log.md +1 -1
- package/gsd-core/templates/phase-prompt.md +2 -4
- package/gsd-core/templates/state.md +4 -4
- package/gsd-core/templates/verification-report.md +9 -1
- package/gsd-core/workflows/ai-integration-phase.md +9 -11
- package/gsd-core/workflows/autonomous.md +1 -1
- package/gsd-core/workflows/cleanup.md +62 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +13 -3
- package/gsd-core/workflows/code-review-fix.md +37 -10
- package/gsd-core/workflows/code-review.md +38 -12
- package/gsd-core/workflows/complete-milestone.md +141 -18
- package/gsd-core/workflows/debug.md +7 -5
- package/gsd-core/workflows/diagnose-issues.md +35 -9
- package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
- package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +2 -1
- package/gsd-core/workflows/edit-phase.md +26 -1
- package/gsd-core/workflows/eval-review.md +3 -5
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +31 -6
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +2 -0
- package/gsd-core/workflows/execute-phase.md +38 -50
- package/gsd-core/workflows/execute-plan.md +36 -4
- package/gsd-core/workflows/explore.md +131 -4
- package/gsd-core/workflows/fast.md +10 -2
- package/gsd-core/workflows/health.md +73 -4
- package/gsd-core/workflows/import.md +4 -4
- package/gsd-core/workflows/ingest-docs.md +5 -5
- package/gsd-core/workflows/mvp-phase.md +6 -3
- package/gsd-core/workflows/new-milestone.md +14 -9
- package/gsd-core/workflows/new-project.md +14 -14
- package/gsd-core/workflows/next.md +12 -0
- package/gsd-core/workflows/plan-phase.md +41 -17
- package/gsd-core/workflows/plan-review-convergence.md +50 -2
- package/gsd-core/workflows/progress.md +34 -6
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -4
- package/gsd-core/workflows/quick/steps/quick-verification.md +27 -6
- package/gsd-core/workflows/quick/steps/research-phase.md +2 -2
- package/gsd-core/workflows/quick.md +35 -15
- package/gsd-core/workflows/review.md +26 -5
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/session-report.md +2 -1
- package/gsd-core/workflows/settings.md +66 -2
- package/gsd-core/workflows/ship.md +104 -44
- package/gsd-core/workflows/spec-phase.md +30 -12
- package/gsd-core/workflows/sync-skills.md +63 -8
- package/gsd-core/workflows/transition.md +46 -11
- package/gsd-core/workflows/ui-phase.md +5 -5
- package/gsd-core/workflows/ui-review.md +2 -2
- package/gsd-core/workflows/update.md +1 -1
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-work.md +9 -7
- package/hooks/dist/gsd-agent-isolation-guard.js +103 -14
- package/hooks/dist/gsd-check-update-worker.js +56 -13
- package/hooks/dist/gsd-check-update.js +19 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
- package/hooks/dist/gsd-cursor-subagent-start.js +77 -2
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/dist/gsd-prompt-guard.js +21 -20
- package/hooks/dist/gsd-read-injection-scanner.js +38 -24
- package/hooks/dist/gsd-statusline.js +18 -0
- package/hooks/dist/gsd-update-banner.js +22 -1
- package/hooks/dist/gsd-workflow-guard.js +134 -36
- package/hooks/dist/lib/git-cmd.js +92 -59
- package/hooks/dist/lib/injection-patterns.js +45 -0
- package/hooks/dist/lib/isolation-deny-reason.js +39 -0
- package/hooks/dist/lib/isolation-sentinel.js +9 -0
- package/hooks/gsd-agent-isolation-guard.js +103 -14
- package/hooks/gsd-check-update-worker.js +56 -13
- package/hooks/gsd-check-update.js +19 -1
- package/hooks/gsd-cursor-pre-tool.js +0 -3
- package/hooks/gsd-cursor-subagent-start.js +77 -2
- package/hooks/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/gsd-prompt-guard.js +21 -20
- package/hooks/gsd-read-injection-scanner.js +38 -24
- package/hooks/gsd-statusline.js +18 -0
- package/hooks/gsd-update-banner.js +22 -1
- package/hooks/gsd-workflow-guard.js +134 -36
- package/hooks/lib/git-cmd.js +92 -59
- package/hooks/lib/injection-patterns.js +45 -0
- package/hooks/lib/isolation-deny-reason.js +39 -0
- package/hooks/lib/isolation-sentinel.js +9 -0
- package/package.json +21 -9
- package/pi/gsd.cjs +19 -5
- package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
- package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
- package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
- package/scripts/changeset/lint.cjs +60 -5
- package/scripts/check-alias-drift.cjs +7 -43
- package/scripts/check-contract-drift.cjs +297 -0
- package/scripts/ci-test-scope.cjs +19 -2
- package/scripts/command-contract-helpers.cjs +903 -1
- package/scripts/gen-adr-index.cjs +728 -38
- package/scripts/gen-capability-registry.cjs +3 -15
- package/scripts/gen-context-index.cjs +2 -11
- package/scripts/gen-health-docs.cjs +390 -0
- package/scripts/gen-inventory-manifest.cjs +50 -4
- package/scripts/gen-loop-host-contract.cjs +4 -24
- package/scripts/gen-registry.cjs +3 -14
- package/scripts/lib/alias-drift-families.cjs +46 -0
- package/scripts/lib/drift-scan.cjs +278 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -26
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
- package/scripts/lint-canary-version-leak.cjs +73 -0
- package/scripts/lint-command-contract.cjs +96 -13
- package/scripts/lint-completion-predicate-drift.cjs +933 -0
- package/scripts/lint-completion-ratio-drift.cjs +214 -0
- package/scripts/lint-default-flip-documentation.cjs +193 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
- package/scripts/lint-eslint-glob-coverage.cjs +340 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
- package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
- package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
- package/scripts/lint-milestone-window-drift.cjs +468 -0
- package/scripts/lint-phase-enumeration-drift.cjs +479 -0
- package/scripts/lint-plan-count-drift.cjs +318 -0
- package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
- package/scripts/lint-planning-prompt-drift.cjs +434 -0
- package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
- package/scripts/lint-regression-test-names.cjs +15 -13
- package/scripts/lint-removed-but-needed.cjs +320 -0
- package/scripts/lint-state-field-drift.cjs +805 -0
- package/scripts/lint-state-write-path-drift.cjs +1045 -0
- package/scripts/lint-test-file-count.allowlist.json +21 -10
- package/scripts/lint-unreachable-guard-drift.cjs +843 -0
- package/scripts/lint-vendored-deps.cjs +124 -0
- package/scripts/pr-changed-files.cjs +63 -0
- package/scripts/pr-template-policy.cjs +14 -4
- package/scripts/prompt-injection-scan.sh +25 -0
- package/scripts/require-issue-link-policy.cjs +192 -0
- package/scripts/state-write-path-drift-baseline.json +19 -0
- package/scripts/sync-runtime-launcher.cjs +2 -4
- package/skills/gsd-autonomous/SKILL.md +0 -1
- package/skills/gsd-code-review/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -2
- package/skills/gsd-map-codebase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +1 -1
- package/skills/gsd-mempalace-recall/SKILL.md +1 -1
- package/skills/gsd-new-milestone/SKILL.md +1 -1
- package/skills/gsd-next/SKILL.md +0 -1
- package/skills/gsd-plan-phase/SKILL.md +0 -1
- package/skills/gsd-progress/SKILL.md +0 -1
- package/skills/gsd-quick/SKILL.md +1 -1
- package/skills/gsd-review-backlog/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +0 -1
- package/skills/gsd-verify-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/discovery-phase.md +0 -298
- package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
- package/gsd-core/workflows/verify-phase.md +0 -574
- package/scripts/affected-tests-lib.cjs +0 -554
- package/scripts/lint-allow-test-rule-refs.cjs +0 -162
- package/scripts/run-affected-tests.cjs +0 -7
- package/scripts/run-tests.cjs +0 -1051
|
@@ -13,13 +13,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
15
15
|
const node_os_1 = __importDefault(require("node:os"));
|
|
16
|
+
// #2874 (ADR-58 cleanup phase): route the staging functions' fs calls
|
|
17
|
+
// through the installRuntimeArtifacts call tree's injectable seam — see
|
|
18
|
+
// install-fs-adapter.cts's module doc. Resolves to real `node:fs` unless the
|
|
19
|
+
// top-level installRuntimeArtifacts call injected a `deps.fs`. Only the
|
|
20
|
+
// staging functions reachable FROM that call tree are routed
|
|
21
|
+
// (stageSkillsForProfile / stageAgentsForProfile /
|
|
22
|
+
// stageAgentsForRuntimeWithConverter / stageSkillsForRuntimeAsSkills /
|
|
23
|
+
// stageCommandsForRuntimeFlat / buildNamespaceBundleMap) — the profile-marker
|
|
24
|
+
// and manifest-loading helpers below are not on that call tree and keep
|
|
25
|
+
// using real `fs` directly.
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
27
|
+
const installFsAdapter = require("./install-fs-adapter.cjs");
|
|
28
|
+
const { installFs, mkInstallTempDir } = installFsAdapter;
|
|
16
29
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
17
30
|
// #2322: reuse the existing pure path-containment seam (ADR-1239 Phase C-2)
|
|
18
31
|
// instead of hand-rolling a new traversal check for capability skill stems.
|
|
19
32
|
const external_descriptor_trust_cjs_1 = require("./external-descriptor-trust.cjs");
|
|
20
33
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
34
|
const conversionModule = require("./runtime-artifact-conversion.cjs");
|
|
22
|
-
const { applyAgentPathRewrites: _applyAgentPathRewrites, processAttribution: _processAttribution, normalizeAgentBodyForRuntime: _normalizeAgentBodyForRuntime, readGsdCommandNames: _readGsdCommandNames, } = conversionModule;
|
|
35
|
+
const { applyAgentPathRewrites: _applyAgentPathRewrites, processAttribution: _processAttribution, normalizeAgentBodyForRuntime: _normalizeAgentBodyForRuntime, readGsdCommandNames: _readGsdCommandNames, deriveAgentName: _deriveAgentName, applyAgentFrontmatterExtensions: _applyAgentFrontmatterExtensions, } = conversionModule;
|
|
23
36
|
// #2995 (epic #1671 Phase 6.4): agent bodies join the fragment model. Markers are
|
|
24
37
|
// stripped at emit BEFORE any path rewrite or converter runs, so a `.claude/` ->
|
|
25
38
|
// `.windsurf/` regex can never reach inside a marker attribute and corrupt it —
|
|
@@ -264,10 +277,41 @@ function resolveProfile({ modes, manifest, _profilesOverride, registry } = {}) {
|
|
|
264
277
|
// site to track its own cleanup handle.
|
|
265
278
|
const STAGED_DIRS = new Set();
|
|
266
279
|
let exitHandlerRegistered = false;
|
|
280
|
+
// #2874 leak-fix: `cleanupStagedSkills` runs at process exit — AFTER
|
|
281
|
+
// `withInstallFs` has already restored `current` back to the real adapter
|
|
282
|
+
// (install-fs-adapter.cts's module doc, "SYNCHRONOUS-ONLY / RE-ENTRANCY
|
|
283
|
+
// ASSUMPTION" — extended there to reference this map). A dir staged during a
|
|
284
|
+
// fake-adapter call must be cleaned up with THAT SAME fake adapter, not with
|
|
285
|
+
// whatever is ambiently active later, or an exit handler would perform real
|
|
286
|
+
// filesystem IO on a path that only ever existed in the fake's in-memory
|
|
287
|
+
// store. Capturing the adapter OBJECT `installFs()` returns at registration
|
|
288
|
+
// time (not the ambient `current` variable, which changes) means cleanup
|
|
289
|
+
// always replays the exact adapter that created the path. Dirs added to
|
|
290
|
+
// STAGED_DIRS without going through `registerStagedDir` (the deprecated
|
|
291
|
+
// `stageSkillsForMode`, which creates its stage dir via raw `fs.mkdtempSync`
|
|
292
|
+
// and was never on the injectable seam) have no entry here and fall back to
|
|
293
|
+
// real `fs.rmSync` below — the same real fs it always used to create them.
|
|
294
|
+
const STAGED_DIR_ADAPTERS = new Map();
|
|
295
|
+
/**
|
|
296
|
+
* Register a dir just staged through the injectable seam (`installFs()`) for
|
|
297
|
+
* exit-time cleanup, capturing the adapter that staged it alongside the path.
|
|
298
|
+
* See `STAGED_DIR_ADAPTERS`'s comment for why the capture matters.
|
|
299
|
+
*/
|
|
300
|
+
function registerStagedDir(dir) {
|
|
301
|
+
STAGED_DIRS.add(dir);
|
|
302
|
+
STAGED_DIR_ADAPTERS.set(dir, installFs());
|
|
303
|
+
ensureExitCleanup();
|
|
304
|
+
}
|
|
267
305
|
function cleanupStagedSkills() {
|
|
268
306
|
for (const dir of STAGED_DIRS) {
|
|
307
|
+
const adapter = STAGED_DIR_ADAPTERS.get(dir);
|
|
269
308
|
try {
|
|
270
|
-
|
|
309
|
+
if (adapter) {
|
|
310
|
+
adapter.rmSync(dir, { recursive: true, force: true });
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
node_fs_1.default.rmSync(dir, { recursive: true, force: true });
|
|
314
|
+
}
|
|
271
315
|
}
|
|
272
316
|
catch {
|
|
273
317
|
// Best-effort: missing dir or permission error shouldn't crash a
|
|
@@ -275,6 +319,7 @@ function cleanupStagedSkills() {
|
|
|
275
319
|
}
|
|
276
320
|
}
|
|
277
321
|
STAGED_DIRS.clear();
|
|
322
|
+
STAGED_DIR_ADAPTERS.clear();
|
|
278
323
|
}
|
|
279
324
|
// Signals we register a cleanup handler for in addition to the natural
|
|
280
325
|
// 'exit' event. `process.on('exit')` does NOT fire on these — an installer
|
|
@@ -303,11 +348,11 @@ function ensureExitCleanup() {
|
|
|
303
348
|
function stageSkillsForProfile(srcDir, resolvedProfile) {
|
|
304
349
|
if (resolvedProfile.skills === '*')
|
|
305
350
|
return srcDir;
|
|
306
|
-
if (!
|
|
351
|
+
if (!installFs().existsSync(srcDir))
|
|
307
352
|
return srcDir;
|
|
308
|
-
const stageDir =
|
|
353
|
+
const stageDir = mkInstallTempDir('gsd-profile-skills-');
|
|
309
354
|
try {
|
|
310
|
-
const entries =
|
|
355
|
+
const entries = installFs().readdirSync(srcDir, { withFileTypes: true });
|
|
311
356
|
for (const entry of entries) {
|
|
312
357
|
if (!entry.isFile())
|
|
313
358
|
continue;
|
|
@@ -316,18 +361,17 @@ function stageSkillsForProfile(srcDir, resolvedProfile) {
|
|
|
316
361
|
const stem = entry.name.slice(0, -3);
|
|
317
362
|
if (!(resolvedProfile.skills).has(stem))
|
|
318
363
|
continue;
|
|
319
|
-
|
|
364
|
+
installFs().copyFileSync(node_path_1.default.join(srcDir, entry.name), node_path_1.default.join(stageDir, entry.name));
|
|
320
365
|
}
|
|
321
366
|
}
|
|
322
367
|
catch (err) {
|
|
323
368
|
try {
|
|
324
|
-
|
|
369
|
+
installFs().rmSync(stageDir, { recursive: true, force: true });
|
|
325
370
|
}
|
|
326
371
|
catch { /* best-effort */ }
|
|
327
372
|
throw err;
|
|
328
373
|
}
|
|
329
|
-
|
|
330
|
-
ensureExitCleanup();
|
|
374
|
+
registerStagedDir(stageDir);
|
|
331
375
|
return stageDir;
|
|
332
376
|
}
|
|
333
377
|
/**
|
|
@@ -353,12 +397,12 @@ function stageSkillsForProfile(srcDir, resolvedProfile) {
|
|
|
353
397
|
function stageAgentsForProfile(srcAgentsDir, resolvedProfile) {
|
|
354
398
|
if (resolvedProfile.skills === '*')
|
|
355
399
|
return srcAgentsDir;
|
|
356
|
-
if (!
|
|
400
|
+
if (!installFs().existsSync(srcAgentsDir))
|
|
357
401
|
return srcAgentsDir;
|
|
358
|
-
const stageDir =
|
|
402
|
+
const stageDir = mkInstallTempDir('gsd-profile-agents-');
|
|
359
403
|
try {
|
|
360
404
|
if (resolvedProfile.agents instanceof Set && resolvedProfile.agents.size > 0) {
|
|
361
|
-
const entries =
|
|
405
|
+
const entries = installFs().readdirSync(srcAgentsDir, { withFileTypes: true });
|
|
362
406
|
for (const entry of entries) {
|
|
363
407
|
if (!entry.isFile())
|
|
364
408
|
continue;
|
|
@@ -368,20 +412,19 @@ function stageAgentsForProfile(srcAgentsDir, resolvedProfile) {
|
|
|
368
412
|
const stem = entry.name.slice(0, -3);
|
|
369
413
|
if (!resolvedProfile.agents.has(stem))
|
|
370
414
|
continue;
|
|
371
|
-
|
|
415
|
+
installFs().copyFileSync(node_path_1.default.join(srcAgentsDir, entry.name), node_path_1.default.join(stageDir, entry.name));
|
|
372
416
|
}
|
|
373
417
|
}
|
|
374
418
|
// If agents is empty Set, we produce an empty stageDir (no agents for this profile)
|
|
375
419
|
}
|
|
376
420
|
catch (err) {
|
|
377
421
|
try {
|
|
378
|
-
|
|
422
|
+
installFs().rmSync(stageDir, { recursive: true, force: true });
|
|
379
423
|
}
|
|
380
424
|
catch { /* best-effort */ }
|
|
381
425
|
throw err;
|
|
382
426
|
}
|
|
383
|
-
|
|
384
|
-
ensureExitCleanup();
|
|
427
|
+
registerStagedDir(stageDir);
|
|
385
428
|
return stageDir;
|
|
386
429
|
}
|
|
387
430
|
/**
|
|
@@ -395,10 +438,10 @@ function buildNamespaceBundleMap(srcCommandsDir) {
|
|
|
395
438
|
const routerStems = new Set();
|
|
396
439
|
const routerChildren = new Map();
|
|
397
440
|
const childToRouters = new Map();
|
|
398
|
-
if (!
|
|
441
|
+
if (!installFs().existsSync(srcCommandsDir)) {
|
|
399
442
|
return { routerStems, routerChildren, childToRouters };
|
|
400
443
|
}
|
|
401
|
-
for (const entry of
|
|
444
|
+
for (const entry of installFs().readdirSync(srcCommandsDir, { withFileTypes: true })) {
|
|
402
445
|
if (!entry.isFile() || !entry.name.endsWith('.md'))
|
|
403
446
|
continue;
|
|
404
447
|
if (!entry.name.startsWith('ns-'))
|
|
@@ -406,7 +449,7 @@ function buildNamespaceBundleMap(srcCommandsDir) {
|
|
|
406
449
|
const stem = entry.name.slice(0, -3);
|
|
407
450
|
let children = [];
|
|
408
451
|
try {
|
|
409
|
-
children = parseRequires(
|
|
452
|
+
children = parseRequires(installFs().readFileSync(node_path_1.default.join(srcCommandsDir, entry.name), 'utf8'));
|
|
410
453
|
}
|
|
411
454
|
catch {
|
|
412
455
|
children = [];
|
|
@@ -637,7 +680,7 @@ function readInstalledCapabilitySkill(stem, registry) {
|
|
|
637
680
|
* When absent, NOTHING third-party is staged (fail closed).
|
|
638
681
|
*/
|
|
639
682
|
function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converter, prefix, nested = false, registry) {
|
|
640
|
-
if (!
|
|
683
|
+
if (!installFs().existsSync(srcCommandsDir))
|
|
641
684
|
return srcCommandsDir;
|
|
642
685
|
// Nesting applies to the `full` install AND to any surface whose skill set
|
|
643
686
|
// still contains every namespace router (a full/reset surface). It must NOT
|
|
@@ -660,9 +703,9 @@ function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converte
|
|
|
660
703
|
// this call, so the third-party fill-in pass below can enforce "first-party
|
|
661
704
|
// ALWAYS wins on collision" without re-deriving membership.
|
|
662
705
|
const firstPartyStems = new Set();
|
|
663
|
-
const stageDir =
|
|
706
|
+
const stageDir = mkInstallTempDir('gsd-profile-runtime-skills-');
|
|
664
707
|
try {
|
|
665
|
-
const entries =
|
|
708
|
+
const entries = installFs().readdirSync(srcCommandsDir, { withFileTypes: true });
|
|
666
709
|
for (const entry of entries) {
|
|
667
710
|
if (!entry.isFile())
|
|
668
711
|
continue;
|
|
@@ -672,15 +715,15 @@ function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converte
|
|
|
672
715
|
if (resolvedProfile.skills !== '*' && !(resolvedProfile.skills).has(stem))
|
|
673
716
|
continue;
|
|
674
717
|
firstPartyStems.add(stem);
|
|
675
|
-
const content =
|
|
718
|
+
const content = installFs().readFileSync(node_path_1.default.join(srcCommandsDir, entry.name), 'utf8');
|
|
676
719
|
const skillName = `${prefix}${stem}`;
|
|
677
720
|
const converted = converter(content, skillName);
|
|
678
721
|
if (doNest && bundles.routerStems.has(stem)) {
|
|
679
722
|
// Router skill: rewrite its routing table to the nested Read pattern and
|
|
680
723
|
// emit it as the single top-level bundle entry.
|
|
681
724
|
const destDir = node_path_1.default.join(stageDir, skillName);
|
|
682
|
-
|
|
683
|
-
|
|
725
|
+
installFs().mkdirSync(destDir, { recursive: true });
|
|
726
|
+
installFs().writeFileSync(node_path_1.default.join(destDir, 'SKILL.md'), transformRouterBodyToNested(converted));
|
|
684
727
|
continue;
|
|
685
728
|
}
|
|
686
729
|
if (doNest && bundles.childToRouters.has(stem)) {
|
|
@@ -689,16 +732,16 @@ function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converte
|
|
|
689
732
|
// top-level eager listing while staying readable by file path (#69).
|
|
690
733
|
for (const routerStem of bundles.childToRouters.get(stem)) {
|
|
691
734
|
const destDir = node_path_1.default.join(stageDir, `${prefix}${routerStem}`, 'skills', stem);
|
|
692
|
-
|
|
693
|
-
|
|
735
|
+
installFs().mkdirSync(destDir, { recursive: true });
|
|
736
|
+
installFs().writeFileSync(node_path_1.default.join(destDir, 'SKILL.md'), converted);
|
|
694
737
|
}
|
|
695
738
|
continue;
|
|
696
739
|
}
|
|
697
740
|
// Flat top-level skill (default behaviour; also the unrouted fallback when
|
|
698
741
|
// nesting is active).
|
|
699
742
|
const destDir = node_path_1.default.join(stageDir, skillName);
|
|
700
|
-
|
|
701
|
-
|
|
743
|
+
installFs().mkdirSync(destDir, { recursive: true });
|
|
744
|
+
installFs().writeFileSync(node_path_1.default.join(destDir, 'SKILL.md'), converted);
|
|
702
745
|
}
|
|
703
746
|
// #2322: materialize installed THIRD-PARTY capability skills, bound to
|
|
704
747
|
// their DECLARING capability via the registry's capabilityClusters view
|
|
@@ -740,25 +783,24 @@ function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converte
|
|
|
740
783
|
if (!(0, external_descriptor_trust_cjs_1.isPathConfined)(skillName, stageDir))
|
|
741
784
|
continue; // defense-in-depth
|
|
742
785
|
const destDir = node_path_1.default.join(stageDir, skillName);
|
|
743
|
-
|
|
744
|
-
|
|
786
|
+
installFs().mkdirSync(destDir, { recursive: true });
|
|
787
|
+
installFs().writeFileSync(node_path_1.default.join(destDir, 'SKILL.md'), found.content);
|
|
745
788
|
// #2322 HIGH-3: persist the capability-owned marker so a later prune
|
|
746
789
|
// pass (surface.cts pruneSkillDirs) can identify — and remove — this
|
|
747
790
|
// directory even once the owning capability is uninstalled/unsurfaced
|
|
748
791
|
// and no longer appears in any registry view.
|
|
749
|
-
|
|
792
|
+
installFs().writeFileSync(node_path_1.default.join(destDir, CAPABILITY_SKILL_MARKER), found.capId + '\n', 'utf8');
|
|
750
793
|
}
|
|
751
794
|
}
|
|
752
795
|
}
|
|
753
796
|
catch (err) {
|
|
754
797
|
try {
|
|
755
|
-
|
|
798
|
+
installFs().rmSync(stageDir, { recursive: true, force: true });
|
|
756
799
|
}
|
|
757
800
|
catch { /* best-effort */ }
|
|
758
801
|
throw err;
|
|
759
802
|
}
|
|
760
|
-
|
|
761
|
-
ensureExitCleanup();
|
|
803
|
+
registerStagedDir(stageDir);
|
|
762
804
|
return stageDir;
|
|
763
805
|
}
|
|
764
806
|
/**
|
|
@@ -782,26 +824,57 @@ function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converte
|
|
|
782
824
|
* 1. applyAgentPathRewrites (4 base ~/.claude/ regexes; skipped for copilot/antigravity)
|
|
783
825
|
* 2. processAttribution (Co-Authored-By policy)
|
|
784
826
|
* 3. converter (runtime-specific frontmatter/body transform)
|
|
785
|
-
* 4.
|
|
827
|
+
* 4. applyAgentFrontmatterExtensions (#2875 Part 2: effort/disallowedTools,
|
|
828
|
+
* gated by hostBehaviors.agentFrontmatterExtensions — no-op for a runtime
|
|
829
|
+
* that declares nothing, e.g. every non-Claude runtime today)
|
|
830
|
+
* 5. normalizeAgentBodyForRuntime (colon→hyphen refs; no-op for trivial group)
|
|
786
831
|
* When `agentCtx` is absent, only the converter is applied (backward-compat for
|
|
787
832
|
* the feat-1173 synthetic-descriptor tests and the copilot/antigravity paths
|
|
788
833
|
* that handle cross-cutting inside their converters).
|
|
789
834
|
*
|
|
790
835
|
* @param srcAgentsDir source agents directory (e.g. agents/)
|
|
791
836
|
* @param resolvedProfile profile filter from resolveProfile()
|
|
792
|
-
* @param converter (content: string, isGlobal?: boolean) → string
|
|
793
|
-
* converter; scope-aware converters (copilot/antigravity)
|
|
794
|
-
* read isGlobal, single-arg converters ignore
|
|
837
|
+
* @param converter (content: string, isGlobal?: boolean, meta?: {agentName: string}) → string
|
|
838
|
+
* per-file converter; scope-aware converters (copilot/antigravity)
|
|
839
|
+
* read isGlobal, single-arg converters ignore both extra args (#1173).
|
|
840
|
+
* `meta.agentName` (#2875 Part 2) is passed ONLY when `agentCtx` is
|
|
841
|
+
* present, letting a converter close over per-agent config
|
|
842
|
+
* (e.g. kilo/opencode model-override resolution in
|
|
843
|
+
* runtime-artifact-layout.cts's convertedAgentsKind) without widening
|
|
844
|
+
* every OTHER converter's contract — converters that don't declare a
|
|
845
|
+
* 3rd parameter simply never read it.
|
|
795
846
|
* @param isGlobal install scope passed through to the converter
|
|
796
847
|
* @param agentCtx optional cross-cutting context (ADR-1235 §1); when absent,
|
|
797
848
|
* only the converter is applied (backward compat)
|
|
798
849
|
*/
|
|
799
850
|
function stageAgentsForRuntimeWithConverter(srcAgentsDir, resolvedProfile, converter, isGlobal = false, agentCtx) {
|
|
800
|
-
if (!
|
|
851
|
+
if (!installFs().existsSync(srcAgentsDir))
|
|
801
852
|
return srcAgentsDir;
|
|
802
|
-
const stageDir =
|
|
853
|
+
const stageDir = mkInstallTempDir('gsd-profile-runtime-agents-');
|
|
854
|
+
let entries;
|
|
855
|
+
try {
|
|
856
|
+
// #2284/#2875: readdirSync-ing the shipped agents/ source is isolated in
|
|
857
|
+
// its own try/catch so an unreadable source directory (permissions, a
|
|
858
|
+
// corrupted install, or — as the #2284 test suite demonstrates — the
|
|
859
|
+
// fail-closed injection harness) produces the SAME "refusing to install"
|
|
860
|
+
// fail-closed wording every other agents-dir-unreadable path in this
|
|
861
|
+
// codebase uses (bin/install.js's `_resolveAvailableGsdRoles` /
|
|
862
|
+
// `_assertRoleResolvable`), instead of an unrelated raw fs error message
|
|
863
|
+
// escaping uncaught. Hermes's role-dispatch validation depends on the
|
|
864
|
+
// SAME shipped agents/ directory being readable; before this runtime also
|
|
865
|
+
// declared an `agents` kind, this function was never reached on a Hermes
|
|
866
|
+
// install, so an unreadable source here silently surfaced as a raw error
|
|
867
|
+
// rather than the deliberate fail-closed contract #2284 established.
|
|
868
|
+
entries = installFs().readdirSync(srcAgentsDir, { withFileTypes: true });
|
|
869
|
+
}
|
|
870
|
+
catch (err) {
|
|
871
|
+
try {
|
|
872
|
+
installFs().rmSync(stageDir, { recursive: true, force: true });
|
|
873
|
+
}
|
|
874
|
+
catch { /* best-effort */ }
|
|
875
|
+
throw new Error(`stageAgentsForRuntimeWithConverter: could not resolve the shipped agents/ directory "${srcAgentsDir}" to stage — refusing to install (fail-closed, #2284/#2875): ${err.message}`);
|
|
876
|
+
}
|
|
803
877
|
try {
|
|
804
|
-
const entries = node_fs_1.default.readdirSync(srcAgentsDir, { withFileTypes: true });
|
|
805
878
|
// Resolve cmdNames once per staging call (not per file) for performance.
|
|
806
879
|
const cmdNames = agentCtx ? _readGsdCommandNames() : [];
|
|
807
880
|
for (const entry of entries) {
|
|
@@ -817,39 +890,44 @@ function stageAgentsForRuntimeWithConverter(srcAgentsDir, resolvedProfile, conve
|
|
|
817
890
|
}
|
|
818
891
|
}
|
|
819
892
|
const agentSourcePath = node_path_1.default.join(srcAgentsDir, entry.name);
|
|
820
|
-
let content =
|
|
893
|
+
let content = installFs().readFileSync(agentSourcePath, 'utf8');
|
|
821
894
|
// #2995: strip gsd:section markers FIRST — before path rewrites, attribution,
|
|
822
895
|
// and the per-runtime converter. Byte-identical (no-op) for an unmarked agent;
|
|
823
896
|
// throws loudly naming the file for a malformed marker, never emitting a
|
|
824
897
|
// half-composed agent.
|
|
825
898
|
content = _composeWorkflow(content, { sourcePath: agentSourcePath });
|
|
826
899
|
if (agentCtx) {
|
|
900
|
+
// #2875 Part 2 / row I3: derived exactly as the inline loop does —
|
|
901
|
+
// single-sourced via deriveAgentName (runtime-artifact-conversion.cts).
|
|
902
|
+
const agentName = _deriveAgentName(entry.name);
|
|
827
903
|
// ADR-1235 §1: pre-converter cross-cutting (matches inline loop order exactly)
|
|
828
904
|
// Step 1: path rewrites (4 base ~/.claude/ regexes; skipped for copilot/antigravity)
|
|
829
905
|
content = _applyAgentPathRewrites(content, agentCtx.runtime, agentCtx.pathPrefix);
|
|
830
906
|
// Step 2: attribution
|
|
831
907
|
content = _processAttribution(content, agentCtx.attribution);
|
|
832
908
|
// Step 3: converter (runtime-specific frontmatter/body transform)
|
|
833
|
-
content = converter(content, isGlobal);
|
|
834
|
-
// Step 4:
|
|
909
|
+
content = converter(content, isGlobal, { agentName });
|
|
910
|
+
// Step 4: frontmatter extensions (effort/disallowedTools; no-op unless
|
|
911
|
+
// the runtime declares hostBehaviors.agentFrontmatterExtensions)
|
|
912
|
+
content = _applyAgentFrontmatterExtensions(content, { runtime: agentCtx.runtime, agentName, targetDir: agentCtx.targetDir });
|
|
913
|
+
// Step 5: normalize colon→hyphen refs (no-op for trivial group)
|
|
835
914
|
content = _normalizeAgentBodyForRuntime(content, agentCtx.runtime, cmdNames);
|
|
836
915
|
}
|
|
837
916
|
else {
|
|
838
917
|
// Backward-compat: only apply the converter (no cross-cutting)
|
|
839
918
|
content = converter(content, isGlobal);
|
|
840
919
|
}
|
|
841
|
-
|
|
920
|
+
installFs().writeFileSync(node_path_1.default.join(stageDir, entry.name), content, 'utf8');
|
|
842
921
|
}
|
|
843
922
|
}
|
|
844
923
|
catch (err) {
|
|
845
924
|
try {
|
|
846
|
-
|
|
925
|
+
installFs().rmSync(stageDir, { recursive: true, force: true });
|
|
847
926
|
}
|
|
848
927
|
catch { /* best-effort */ }
|
|
849
928
|
throw err;
|
|
850
929
|
}
|
|
851
|
-
|
|
852
|
-
ensureExitCleanup();
|
|
930
|
+
registerStagedDir(stageDir);
|
|
853
931
|
return stageDir;
|
|
854
932
|
}
|
|
855
933
|
/**
|
|
@@ -876,11 +954,11 @@ function stageAgentsForRuntimeWithConverter(srcAgentsDir, resolvedProfile, conve
|
|
|
876
954
|
* @param prefix command name prefix (for converter arg), e.g. 'gsd-'
|
|
877
955
|
*/
|
|
878
956
|
function stageCommandsForRuntimeFlat(srcCommandsDir, resolvedProfile, converter, prefix) {
|
|
879
|
-
if (!
|
|
957
|
+
if (!installFs().existsSync(srcCommandsDir))
|
|
880
958
|
return srcCommandsDir;
|
|
881
|
-
const stageDir =
|
|
959
|
+
const stageDir = mkInstallTempDir('gsd-profile-runtime-commands-');
|
|
882
960
|
try {
|
|
883
|
-
const entries =
|
|
961
|
+
const entries = installFs().readdirSync(srcCommandsDir, { withFileTypes: true });
|
|
884
962
|
for (const entry of entries) {
|
|
885
963
|
if (!entry.isFile())
|
|
886
964
|
continue;
|
|
@@ -889,24 +967,23 @@ function stageCommandsForRuntimeFlat(srcCommandsDir, resolvedProfile, converter,
|
|
|
889
967
|
const stem = entry.name.slice(0, -3);
|
|
890
968
|
if (resolvedProfile.skills !== '*' && !(resolvedProfile.skills).has(stem))
|
|
891
969
|
continue;
|
|
892
|
-
const content =
|
|
970
|
+
const content = installFs().readFileSync(node_path_1.default.join(srcCommandsDir, entry.name), 'utf8');
|
|
893
971
|
// Pass the full command name (with prefix) to the converter so it can
|
|
894
972
|
// reference the installed command name in the body (e.g. for descriptions).
|
|
895
973
|
// The staged file itself is named without the prefix; _copyStaged adds it.
|
|
896
974
|
const commandName = `${prefix}${stem}`;
|
|
897
975
|
const converted = converter(content, commandName);
|
|
898
|
-
|
|
976
|
+
installFs().writeFileSync(node_path_1.default.join(stageDir, `${stem}.md`), converted);
|
|
899
977
|
}
|
|
900
978
|
}
|
|
901
979
|
catch (err) {
|
|
902
980
|
try {
|
|
903
|
-
|
|
981
|
+
installFs().rmSync(stageDir, { recursive: true, force: true });
|
|
904
982
|
}
|
|
905
983
|
catch { /* best-effort */ }
|
|
906
984
|
throw err;
|
|
907
985
|
}
|
|
908
|
-
|
|
909
|
-
ensureExitCleanup();
|
|
986
|
+
registerStagedDir(stageDir);
|
|
910
987
|
return stageDir;
|
|
911
988
|
}
|
|
912
989
|
// ---------------------------------------------------------------------------
|