@skillsmith/core 0.8.2 → 0.10.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/CHANGELOG.md +17 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +6 -0
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.test.d.ts +9 -0
- package/dist/src/api/client.test.d.ts.map +1 -0
- package/dist/src/api/client.test.js +81 -0
- package/dist/src/api/client.test.js.map +1 -0
- package/dist/src/config/device-identity.d.ts +113 -0
- package/dist/src/config/device-identity.d.ts.map +1 -0
- package/dist/src/config/device-identity.js +171 -0
- package/dist/src/config/device-identity.js.map +1 -0
- package/dist/src/config/device-identity.test.d.ts +10 -0
- package/dist/src/config/device-identity.test.d.ts.map +1 -0
- package/dist/src/config/device-identity.test.js +213 -0
- package/dist/src/config/device-identity.test.js.map +1 -0
- package/dist/src/config/index.d.ts +9 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/exports/services.d.ts +3 -1
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +11 -1
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/agent-config-merge.json-array.d.ts +29 -0
- package/dist/src/install/agent-config-merge.json-array.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.json-array.js +100 -0
- package/dist/src/install/agent-config-merge.json-array.js.map +1 -0
- package/dist/src/install/agent-config-merge.json.d.ts +37 -0
- package/dist/src/install/agent-config-merge.json.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.json.js +134 -0
- package/dist/src/install/agent-config-merge.json.js.map +1 -0
- package/dist/src/install/agent-config-merge.toml-block.d.ts +48 -0
- package/dist/src/install/agent-config-merge.toml-block.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.toml-block.js +107 -0
- package/dist/src/install/agent-config-merge.toml-block.js.map +1 -0
- package/dist/src/install/agent-config-merge.types.d.ts +87 -0
- package/dist/src/install/agent-config-merge.types.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.types.js +83 -0
- package/dist/src/install/agent-config-merge.types.js.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.d.ts +46 -0
- package/dist/src/install/agent-config-merge.yaml.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.js +133 -0
- package/dist/src/install/agent-config-merge.yaml.js.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.test.d.ts +2 -0
- package/dist/src/install/agent-config-merge.yaml.test.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.test.js +210 -0
- package/dist/src/install/agent-config-merge.yaml.test.js.map +1 -0
- package/dist/src/install/agent-harness-targets.d.ts +98 -0
- package/dist/src/install/agent-harness-targets.d.ts.map +1 -0
- package/dist/src/install/agent-harness-targets.js +154 -0
- package/dist/src/install/agent-harness-targets.js.map +1 -0
- package/dist/src/install/agent-home-relocate.d.ts +29 -0
- package/dist/src/install/agent-home-relocate.d.ts.map +1 -0
- package/dist/src/install/agent-home-relocate.js +38 -0
- package/dist/src/install/agent-home-relocate.js.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.d.ts +55 -0
- package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.js +109 -0
- package/dist/src/install/agent-manifest-path-guard.js.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.test.d.ts +2 -0
- package/dist/src/install/agent-manifest-path-guard.test.d.ts.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.test.js +72 -0
- package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -0
- package/dist/src/install/agent-manifest.d.ts +58 -0
- package/dist/src/install/agent-manifest.d.ts.map +1 -0
- package/dist/src/install/agent-manifest.js +103 -0
- package/dist/src/install/agent-manifest.js.map +1 -0
- package/dist/src/install/agent-pack-installer.d.ts +39 -0
- package/dist/src/install/agent-pack-installer.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.entry.d.ts +55 -0
- package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.entry.js +90 -0
- package/dist/src/install/agent-pack-installer.entry.js.map +1 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.d.ts +33 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.js +59 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.js.map +1 -0
- package/dist/src/install/agent-pack-installer.harness.d.ts +66 -0
- package/dist/src/install/agent-pack-installer.harness.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.harness.js +310 -0
- package/dist/src/install/agent-pack-installer.harness.js.map +1 -0
- package/dist/src/install/agent-pack-installer.js +221 -0
- package/dist/src/install/agent-pack-installer.js.map +1 -0
- package/dist/src/install/agent-pack-installer.preserve.test.d.ts +11 -0
- package/dist/src/install/agent-pack-installer.preserve.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.preserve.test.js +72 -0
- package/dist/src/install/agent-pack-installer.preserve.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.test.js +350 -0
- package/dist/src/install/agent-pack-installer.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.types.d.ts +51 -0
- package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.types.js +16 -0
- package/dist/src/install/agent-pack-installer.types.js.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.d.ts +43 -0
- package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.js +113 -0
- package/dist/src/install/agent-pack-uninstaller.js.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.test.d.ts +2 -0
- package/dist/src/install/agent-pack-uninstaller.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.test.js +212 -0
- package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -0
- package/dist/src/install/index.d.ts +8 -1
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +8 -1
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/paths.d.ts +17 -1
- package/dist/src/install/paths.d.ts.map +1 -1
- package/dist/src/install/paths.js +26 -0
- package/dist/src/install/paths.js.map +1 -1
- package/dist/src/install/paths.test.d.ts +2 -0
- package/dist/src/install/paths.test.d.ts.map +1 -0
- package/dist/src/install/paths.test.js +76 -0
- package/dist/src/install/paths.test.js.map +1 -0
- package/dist/src/journal/hash.d.ts +13 -0
- package/dist/src/journal/hash.d.ts.map +1 -0
- package/dist/src/journal/hash.js +16 -0
- package/dist/src/journal/hash.js.map +1 -0
- package/dist/src/journal/index.d.ts +15 -0
- package/dist/src/journal/index.d.ts.map +1 -0
- package/dist/src/journal/index.js +15 -0
- package/dist/src/journal/index.js.map +1 -0
- package/dist/src/journal/journal.test.d.ts +16 -0
- package/dist/src/journal/journal.test.d.ts.map +1 -0
- package/dist/src/journal/journal.test.js +171 -0
- package/dist/src/journal/journal.test.js.map +1 -0
- package/dist/src/journal/path.d.ts +44 -0
- package/dist/src/journal/path.d.ts.map +1 -0
- package/dist/src/journal/path.js +61 -0
- package/dist/src/journal/path.js.map +1 -0
- package/dist/src/journal/reader.d.ts +38 -0
- package/dist/src/journal/reader.d.ts.map +1 -0
- package/dist/src/journal/reader.js +93 -0
- package/dist/src/journal/reader.js.map +1 -0
- package/dist/src/journal/types.d.ts +87 -0
- package/dist/src/journal/types.d.ts.map +1 -0
- package/dist/src/journal/types.js +21 -0
- package/dist/src/journal/types.js.map +1 -0
- package/dist/src/journal/writer.d.ts +52 -0
- package/dist/src/journal/writer.d.ts.map +1 -0
- package/dist/src/journal/writer.js +125 -0
- package/dist/src/journal/writer.js.map +1 -0
- package/dist/src/paywall-triggers/index.d.ts +13 -0
- package/dist/src/paywall-triggers/index.d.ts.map +1 -0
- package/dist/src/paywall-triggers/index.js +13 -0
- package/dist/src/paywall-triggers/index.js.map +1 -0
- package/dist/src/paywall-triggers/path.d.ts +47 -0
- package/dist/src/paywall-triggers/path.d.ts.map +1 -0
- package/dist/src/paywall-triggers/path.js +73 -0
- package/dist/src/paywall-triggers/path.js.map +1 -0
- package/dist/src/paywall-triggers/store.d.ts +75 -0
- package/dist/src/paywall-triggers/store.d.ts.map +1 -0
- package/dist/src/paywall-triggers/store.js +122 -0
- package/dist/src/paywall-triggers/store.js.map +1 -0
- package/dist/src/paywall-triggers/store.test.d.ts +2 -0
- package/dist/src/paywall-triggers/store.test.d.ts.map +1 -0
- package/dist/src/paywall-triggers/store.test.js +121 -0
- package/dist/src/paywall-triggers/store.test.js.map +1 -0
- package/dist/src/paywall-triggers/types.d.ts +24 -0
- package/dist/src/paywall-triggers/types.d.ts.map +1 -0
- package/dist/src/paywall-triggers/types.js +13 -0
- package/dist/src/paywall-triggers/types.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.compound.d.ts +13 -0
- package/dist/src/security/scanner/SecurityScanner.compound.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.compound.js +127 -0
- package/dist/src/security/scanner/SecurityScanner.compound.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.js +10 -1
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts +23 -0
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.pii.js +152 -0
- package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts +5 -2
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +63 -70
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts +2 -0
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.js +79 -11
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/types.d.ts +2 -0
- package/dist/src/security/scanner/types.d.ts.map +1 -1
- package/dist/src/services/agent-pack/agent-pack.test.d.ts +18 -0
- package/dist/src/services/agent-pack/agent-pack.test.d.ts.map +1 -0
- package/dist/src/services/agent-pack/agent-pack.test.js +344 -0
- package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -0
- package/dist/src/services/agent-pack/hooks.d.ts +29 -0
- package/dist/src/services/agent-pack/hooks.d.ts.map +1 -0
- package/dist/src/services/agent-pack/hooks.js +139 -0
- package/dist/src/services/agent-pack/hooks.js.map +1 -0
- package/dist/src/services/agent-pack/index.d.ts +26 -0
- package/dist/src/services/agent-pack/index.d.ts.map +1 -0
- package/dist/src/services/agent-pack/index.js +109 -0
- package/dist/src/services/agent-pack/index.js.map +1 -0
- package/dist/src/services/agent-pack/prompt-source.d.ts +47 -0
- package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -0
- package/dist/src/services/agent-pack/prompt-source.js +182 -0
- package/dist/src/services/agent-pack/prompt-source.js.map +1 -0
- package/dist/src/services/agent-pack/shims.d.ts +40 -0
- package/dist/src/services/agent-pack/shims.d.ts.map +1 -0
- package/dist/src/services/agent-pack/shims.js +96 -0
- package/dist/src/services/agent-pack/shims.js.map +1 -0
- package/dist/src/services/agent-pack/skill-md.d.ts +35 -0
- package/dist/src/services/agent-pack/skill-md.d.ts.map +1 -0
- package/dist/src/services/agent-pack/skill-md.js +89 -0
- package/dist/src/services/agent-pack/skill-md.js.map +1 -0
- package/dist/src/services/agent-pack/types.d.ts +118 -0
- package/dist/src/services/agent-pack/types.d.ts.map +1 -0
- package/dist/src/services/agent-pack/types.js +61 -0
- package/dist/src/services/agent-pack/types.js.map +1 -0
- package/dist/src/services/agent-tool-profile.d.ts +59 -0
- package/dist/src/services/agent-tool-profile.d.ts.map +1 -0
- package/dist/src/services/agent-tool-profile.js +76 -0
- package/dist/src/services/agent-tool-profile.js.map +1 -0
- package/dist/src/services/agent-tool-profile.test.d.ts +2 -0
- package/dist/src/services/agent-tool-profile.test.d.ts.map +1 -0
- package/dist/src/services/agent-tool-profile.test.js +28 -0
- package/dist/src/services/agent-tool-profile.test.js.map +1 -0
- package/dist/src/services/bundled-sibling-scan.d.ts +111 -0
- package/dist/src/services/bundled-sibling-scan.d.ts.map +1 -0
- package/dist/src/services/bundled-sibling-scan.js +170 -0
- package/dist/src/services/bundled-sibling-scan.js.map +1 -0
- package/dist/src/services/skill-installation.io.d.ts +16 -5
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.js +44 -20
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.policy.d.ts +96 -0
- package/dist/src/services/skill-installation.policy.d.ts.map +1 -0
- package/dist/src/services/skill-installation.policy.js +144 -0
- package/dist/src/services/skill-installation.policy.js.map +1 -0
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +9 -3
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/sources/index.d.ts +1 -0
- package/dist/src/sources/index.d.ts.map +1 -1
- package/dist/src/sources/index.js +4 -0
- package/dist/src/sources/index.js.map +1 -1
- package/dist/src/sync/index.d.ts +6 -0
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/index.js +8 -0
- package/dist/src/sync/index.js.map +1 -1
- package/dist/src/sync/inventory-builder.d.ts +21 -0
- package/dist/src/sync/inventory-builder.d.ts.map +1 -0
- package/dist/src/sync/inventory-builder.js +26 -0
- package/dist/src/sync/inventory-builder.js.map +1 -0
- package/dist/src/sync/inventory-client.d.ts +80 -0
- package/dist/src/sync/inventory-client.d.ts.map +1 -0
- package/dist/src/sync/inventory-client.js +204 -0
- package/dist/src/sync/inventory-client.js.map +1 -0
- package/dist/src/sync/inventory-client.test.d.ts +14 -0
- package/dist/src/sync/inventory-client.test.d.ts.map +1 -0
- package/dist/src/sync/inventory-client.test.js +212 -0
- package/dist/src/sync/inventory-client.test.js.map +1 -0
- package/dist/src/sync/inventory-collector.d.ts +35 -0
- package/dist/src/sync/inventory-collector.d.ts.map +1 -0
- package/dist/src/sync/inventory-collector.js +176 -0
- package/dist/src/sync/inventory-collector.js.map +1 -0
- package/dist/src/sync/inventory-collector.test.d.ts +14 -0
- package/dist/src/sync/inventory-collector.test.d.ts.map +1 -0
- package/dist/src/sync/inventory-collector.test.js +156 -0
- package/dist/src/sync/inventory-collector.test.js.map +1 -0
- package/dist/src/sync/inventory-device.d.ts +36 -0
- package/dist/src/sync/inventory-device.d.ts.map +1 -0
- package/dist/src/sync/inventory-device.js +58 -0
- package/dist/src/sync/inventory-device.js.map +1 -0
- package/dist/src/sync/inventory-push.d.ts +45 -0
- package/dist/src/sync/inventory-push.d.ts.map +1 -0
- package/dist/src/sync/inventory-push.js +62 -0
- package/dist/src/sync/inventory-push.js.map +1 -0
- package/dist/src/sync/inventory-push.test.d.ts +16 -0
- package/dist/src/sync/inventory-push.test.d.ts.map +1 -0
- package/dist/src/sync/inventory-push.test.js +104 -0
- package/dist/src/sync/inventory-push.test.js.map +1 -0
- package/dist/src/sync/inventory-types.d.ts +110 -0
- package/dist/src/sync/inventory-types.d.ts.map +1 -0
- package/dist/src/sync/inventory-types.js +45 -0
- package/dist/src/sync/inventory-types.js.map +1 -0
- package/dist/src/telemetry/agent-marker.d.ts +137 -0
- package/dist/src/telemetry/agent-marker.d.ts.map +1 -0
- package/dist/src/telemetry/agent-marker.js +242 -0
- package/dist/src/telemetry/agent-marker.js.map +1 -0
- package/dist/src/telemetry/agent-marker.test.d.ts +13 -0
- package/dist/src/telemetry/agent-marker.test.d.ts.map +1 -0
- package/dist/src/telemetry/agent-marker.test.js +202 -0
- package/dist/src/telemetry/agent-marker.test.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +2 -1
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +6 -1
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/posthog.d.ts +10 -0
- package/dist/src/telemetry/posthog.d.ts.map +1 -1
- package/dist/src/telemetry/posthog.js +5 -1
- package/dist/src/telemetry/posthog.js.map +1 -1
- package/dist/src/telemetry/wrap.d.ts +28 -7
- package/dist/src/telemetry/wrap.d.ts.map +1 -1
- package/dist/src/telemetry/wrap.gate.test.d.ts +22 -0
- package/dist/src/telemetry/wrap.gate.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.gate.test.js +197 -0
- package/dist/src/telemetry/wrap.gate.test.js.map +1 -0
- package/dist/src/telemetry/wrap.js +111 -26
- package/dist/src/telemetry/wrap.js.map +1 -1
- package/dist/src/telemetry/wrap.marker.test.d.ts +16 -0
- package/dist/src/telemetry/wrap.marker.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.marker.test.js +185 -0
- package/dist/src/telemetry/wrap.marker.test.js.map +1 -0
- package/dist/src/telemetry/wrap.test.js +4 -0
- package/dist/src/telemetry/wrap.test.js.map +1 -1
- package/dist/tests/SecurityScanner.exec.test.js +60 -0
- package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
- package/dist/tests/security/ContinuousSecurity.test.js +10 -4
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts +2 -0
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts.map +1 -0
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.js +126 -0
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.js.map +1 -0
- package/dist/tests/security/chmod-compound.test.d.ts +2 -0
- package/dist/tests/security/chmod-compound.test.d.ts.map +1 -0
- package/dist/tests/security/chmod-compound.test.js +188 -0
- package/dist/tests/security/chmod-compound.test.js.map +1 -0
- package/dist/tests/security/pii-detection.test.js +131 -0
- package/dist/tests/security/pii-detection.test.js.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.d.ts +23 -7
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +27 -11
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-fp.test.d.ts +2 -0
- package/dist/tests/security/sensitive-path-fp.test.d.ts.map +1 -0
- package/dist/tests/security/sensitive-path-fp.test.js +142 -0
- package/dist/tests/security/sensitive-path-fp.test.js.map +1 -0
- package/dist/tests/services/bundled-sibling-scan.test.d.ts +2 -0
- package/dist/tests/services/bundled-sibling-scan.test.d.ts.map +1 -0
- package/dist/tests/services/bundled-sibling-scan.test.js +139 -0
- package/dist/tests/services/bundled-sibling-scan.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.test.js +166 -0
- package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.policy.test.d.ts +8 -0
- package/dist/tests/unit/services/skill-installation.policy.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.policy.test.js +151 -0
- package/dist/tests/unit/services/skill-installation.policy.test.js.map +1 -0
- package/package.json +23 -3
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for `installAgentPack` (SMI-5456 Wave 1 Step 5).
|
|
3
|
+
* @module @skillsmith/core/install/agent-pack-installer.test
|
|
4
|
+
*
|
|
5
|
+
* Covers the P-5 "Harness MCP config files" + "Dual-path pack copies"
|
|
6
|
+
* invariants named in
|
|
7
|
+
* docs/internal/implementation/smi-5456-skillsmith-agent-wave1.md:
|
|
8
|
+
* - install to a temp HOME: dual-path byte-identical
|
|
9
|
+
* - shims only for detected harnesses
|
|
10
|
+
* - hooks +x (incl. Codex SessionStart TOML wiring, Step-6 corrected)
|
|
11
|
+
* - MCP config JSON/YAML/TOML merge results correct
|
|
12
|
+
* - double-install idempotency (no duplicate backups/manifest entries)
|
|
13
|
+
* - preserve-existing (non-interactive refusal path)
|
|
14
|
+
* The uninstall exact-reversal + manifest-path-guard suites live in
|
|
15
|
+
* `agent-pack-uninstaller.test.ts` (split at the 500-line gate).
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
18
|
+
import { tmpdir } from 'node:os';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
21
|
+
import { installAgentPack } from './agent-pack-installer.js';
|
|
22
|
+
import { AGENT_INSTALL_DIR_ENV_VAR, getAgentInstallBackupsDir, getAgentManifestPath, } from './agent-manifest.js';
|
|
23
|
+
import { CLIENT_NATIVE_PATHS } from './paths.js';
|
|
24
|
+
import { relocateUnderHome } from './agent-home-relocate.js';
|
|
25
|
+
let homeDir;
|
|
26
|
+
let manifestDir;
|
|
27
|
+
let prevInstallDirEnv;
|
|
28
|
+
function skillPath(client) {
|
|
29
|
+
return join(relocateUnderHome(CLIENT_NATIVE_PATHS[client], homeDir), 'skillsmith-agent', 'SKILL.md');
|
|
30
|
+
}
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
homeDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-home-'));
|
|
33
|
+
manifestDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-manifest-'));
|
|
34
|
+
prevInstallDirEnv = process.env[AGENT_INSTALL_DIR_ENV_VAR];
|
|
35
|
+
process.env[AGENT_INSTALL_DIR_ENV_VAR] = manifestDir;
|
|
36
|
+
});
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
39
|
+
rmSync(manifestDir, { recursive: true, force: true });
|
|
40
|
+
if (prevInstallDirEnv !== undefined)
|
|
41
|
+
process.env[AGENT_INSTALL_DIR_ENV_VAR] = prevInstallDirEnv;
|
|
42
|
+
else
|
|
43
|
+
delete process.env[AGENT_INSTALL_DIR_ENV_VAR];
|
|
44
|
+
});
|
|
45
|
+
describe('installAgentPack — dual-path + shim + hook + MCP', () => {
|
|
46
|
+
it('writes byte-identical SKILL.md to both claude-code and agents skill paths', () => {
|
|
47
|
+
installAgentPack({ homeDir });
|
|
48
|
+
const claudePath = skillPath('claude-code');
|
|
49
|
+
const agentsPath = skillPath('agents');
|
|
50
|
+
expect(existsSync(claudePath)).toBe(true);
|
|
51
|
+
expect(existsSync(agentsPath)).toBe(true);
|
|
52
|
+
expect(readFileSync(claudePath, 'utf-8')).toBe(readFileSync(agentsPath, 'utf-8'));
|
|
53
|
+
});
|
|
54
|
+
it('writes the claude-code shim unconditionally; copilot/opencode shims only when detected', () => {
|
|
55
|
+
const result = installAgentPack({ homeDir });
|
|
56
|
+
const claudeShim = join(homeDir, '.claude', 'agents', 'skillsmith-agent.md');
|
|
57
|
+
const copilotShim = join(homeDir, '.copilot', 'agents', 'skillsmith-agent.agent.md');
|
|
58
|
+
expect(existsSync(claudeShim)).toBe(true);
|
|
59
|
+
expect(existsSync(copilotShim)).toBe(false);
|
|
60
|
+
const claudeReport = result.harnessReports.find((r) => r.harness === 'claude-code');
|
|
61
|
+
const copilotReport = result.harnessReports.find((r) => r.harness === 'copilot');
|
|
62
|
+
expect(claudeReport?.shimWritten).toBe(true);
|
|
63
|
+
expect(copilotReport?.detected).toBe(false);
|
|
64
|
+
expect(copilotReport?.shimWritten).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
it('detects copilot and writes its shim + skill pack when ~/.copilot/skills is present', () => {
|
|
67
|
+
mkdirSync(join(homeDir, '.copilot', 'skills'), { recursive: true });
|
|
68
|
+
const result = installAgentPack({ homeDir });
|
|
69
|
+
const copilotShim = join(homeDir, '.copilot', 'agents', 'skillsmith-agent.agent.md');
|
|
70
|
+
expect(existsSync(copilotShim)).toBe(true);
|
|
71
|
+
const copilotReport = result.harnessReports.find((r) => r.harness === 'copilot');
|
|
72
|
+
expect(copilotReport?.detected).toBe(true);
|
|
73
|
+
expect(copilotReport?.shimWritten).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
it('installs claude-code + cursor hook scripts with the executable bit set', () => {
|
|
76
|
+
mkdirSync(join(homeDir, '.cursor', 'skills'), { recursive: true });
|
|
77
|
+
installAgentPack({ homeDir });
|
|
78
|
+
for (const dir of ['.claude', '.cursor']) {
|
|
79
|
+
const startPath = join(homeDir, dir, 'hooks', 'session-start.sh');
|
|
80
|
+
const endPath = join(homeDir, dir, 'hooks', 'session-end.sh');
|
|
81
|
+
expect(existsSync(startPath)).toBe(true);
|
|
82
|
+
expect((statSync(startPath).mode & 0o111) !== 0).toBe(true);
|
|
83
|
+
expect((statSync(endPath).mode & 0o111) !== 0).toBe(true);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
it('does not install cursor hooks when cursor is not detected', () => {
|
|
87
|
+
installAgentPack({ homeDir });
|
|
88
|
+
expect(existsSync(join(homeDir, '.cursor', 'hooks', 'session-start.sh'))).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
it('merges the skillsmith MCP entry into claude-code settings.json with SKILLSMITH_TOOL_PROFILE=agent', () => {
|
|
91
|
+
const result = installAgentPack({ homeDir });
|
|
92
|
+
const settingsPath = join(homeDir, '.claude', 'settings.json');
|
|
93
|
+
const doc = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
94
|
+
expect(doc.mcpServers.skillsmith.env.SKILLSMITH_TOOL_PROFILE).toBe('agent');
|
|
95
|
+
const report = result.harnessReports.find((r) => r.harness === 'claude-code');
|
|
96
|
+
expect(report?.mcpConfig?.status).toBe('created');
|
|
97
|
+
});
|
|
98
|
+
it('merges the codex MCP + agents entries as marker-delimited TOML blocks when codex is detected', () => {
|
|
99
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
100
|
+
const result = installAgentPack({ homeDir });
|
|
101
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
102
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
103
|
+
expect(content).toContain('# >>> skillsmith:mcp_servers.skillsmith >>>');
|
|
104
|
+
expect(content).toContain('# >>> skillsmith:agents.skillsmith-agent >>>');
|
|
105
|
+
const report = result.harnessReports.find((r) => r.harness === 'codex');
|
|
106
|
+
expect(report?.detected).toBe(true);
|
|
107
|
+
expect(report?.shimWritten).toBe(true);
|
|
108
|
+
expect(report?.mcpConfig?.status).toBe('created');
|
|
109
|
+
});
|
|
110
|
+
// Step-6 correction (2026-07-01): Codex hook wiring is now implemented —
|
|
111
|
+
// the inline `[[hooks.SessionStart]]` array-of-tables shape was verified
|
|
112
|
+
// against developers.openai.com/codex/hooks.
|
|
113
|
+
it('wires the codex SessionStart hook as a marker-delimited [[hooks.SessionStart]] TOML block', () => {
|
|
114
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
115
|
+
const result = installAgentPack({ homeDir });
|
|
116
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
117
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
118
|
+
const startScript = join(homeDir, '.codex', 'hooks', 'session-start.sh');
|
|
119
|
+
expect(content).toContain('# >>> skillsmith:hooks.SessionStart >>>');
|
|
120
|
+
expect(content).toContain('[[hooks.SessionStart]]');
|
|
121
|
+
expect(content).toContain('[[hooks.SessionStart.hooks]]');
|
|
122
|
+
expect(content).toContain('type = "command"');
|
|
123
|
+
expect(content).toContain(JSON.stringify(startScript));
|
|
124
|
+
const report = result.harnessReports.find((r) => r.harness === 'codex');
|
|
125
|
+
expect(report?.hooksInstalled).toBe(true);
|
|
126
|
+
expect(report?.hookConfig.some((w) => w.status === 'created')).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
it('does NOT wire any codex SessionEnd/Stop cleanup (no SessionEnd event; Stop is per-turn)', () => {
|
|
129
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
130
|
+
const result = installAgentPack({ homeDir });
|
|
131
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
132
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
133
|
+
expect(content).not.toContain('SessionEnd');
|
|
134
|
+
expect(content).not.toContain('hooks.Stop');
|
|
135
|
+
expect(content).not.toContain('session-end.sh');
|
|
136
|
+
// session-end.sh is still INSTALLED (inert, manifest-tracked) so the
|
|
137
|
+
// script tree stays uniform across hook-capable harnesses.
|
|
138
|
+
const endScript = join(homeDir, '.codex', 'hooks', 'session-end.sh');
|
|
139
|
+
expect(existsSync(endScript)).toBe(true);
|
|
140
|
+
expect((statSync(endScript).mode & 0o111) !== 0).toBe(true);
|
|
141
|
+
const report = result.harnessReports.find((r) => r.harness === 'codex');
|
|
142
|
+
expect(report?.notes.some((n) => n.includes('no SessionEnd event'))).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
it('refuses codex hook wiring (conflict) when the user defined [hooks.SessionStart] as a plain table', () => {
|
|
145
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
146
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
147
|
+
// Single-bracket TABLE — appending our [[...]] array entry would make
|
|
148
|
+
// the file invalid TOML, so this must be a non-destructive refusal.
|
|
149
|
+
const preExisting = '[hooks.SessionStart]\nsomething = "user-defined"\n';
|
|
150
|
+
writeFileSync(configPath, preExisting);
|
|
151
|
+
const result = installAgentPack({ homeDir });
|
|
152
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
153
|
+
expect(content).toContain('something = "user-defined"');
|
|
154
|
+
expect(content).not.toContain('# >>> skillsmith:hooks.SessionStart >>>');
|
|
155
|
+
const report = result.harnessReports.find((r) => r.harness === 'codex');
|
|
156
|
+
expect(report?.hookConfig.some((w) => w.status === 'conflict')).toBe(true);
|
|
157
|
+
expect(report?.notes.some((n) => n.includes('plain TOML table'))).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
// Governance follow-up (2026-07-01): `mergeTomlBlock` ignores `force` for a
|
|
160
|
+
// bare foreign table header (see `void force` in
|
|
161
|
+
// `agent-config-merge.toml-block.ts`) — must hold with force: true too.
|
|
162
|
+
it('refuses codex hook wiring (conflict) even with force: true, since appending would be invalid TOML', () => {
|
|
163
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
164
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
165
|
+
const preExisting = '[hooks.SessionStart]\nsomething = "user-defined"\n';
|
|
166
|
+
writeFileSync(configPath, preExisting);
|
|
167
|
+
const result = installAgentPack({ homeDir, force: true });
|
|
168
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
169
|
+
// Unrelated blocks (agents shim, mcp_servers) still merge under
|
|
170
|
+
// force: true — only the hooks.SessionStart table conflict is refused.
|
|
171
|
+
expect(content).toContain('something = "user-defined"');
|
|
172
|
+
expect(content).not.toContain('# >>> skillsmith:hooks.SessionStart >>>');
|
|
173
|
+
const report = result.harnessReports.find((r) => r.harness === 'codex');
|
|
174
|
+
expect(report?.hookConfig.some((w) => w.status === 'conflict')).toBe(true);
|
|
175
|
+
expect(report?.notes.some((n) => n.includes('plain TOML table'))).toBe(true);
|
|
176
|
+
});
|
|
177
|
+
it("appends alongside a user's own [[hooks.SessionStart]] array entry (valid TOML coexistence)", () => {
|
|
178
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
179
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
180
|
+
const userHook = [
|
|
181
|
+
'[[hooks.SessionStart]]',
|
|
182
|
+
'',
|
|
183
|
+
'[[hooks.SessionStart.hooks]]',
|
|
184
|
+
'type = "command"',
|
|
185
|
+
'command = "/usr/local/bin/my-own-hook.sh"',
|
|
186
|
+
'',
|
|
187
|
+
].join('\n');
|
|
188
|
+
writeFileSync(configPath, userHook);
|
|
189
|
+
installAgentPack({ homeDir });
|
|
190
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
191
|
+
// Both hooks present: the user's untouched, ours marker-delimited.
|
|
192
|
+
expect(content).toContain('/usr/local/bin/my-own-hook.sh');
|
|
193
|
+
expect(content).toContain('# >>> skillsmith:hooks.SessionStart >>>');
|
|
194
|
+
expect(content.split('[[hooks.SessionStart]]').length - 1).toBe(2);
|
|
195
|
+
});
|
|
196
|
+
// Step-6 corrections (2026-07-01): opencode agent dir is `agents/`
|
|
197
|
+
// (plural, opencode.ai/docs/agents/) and its MCP entry uses OpenCode's own
|
|
198
|
+
// schema (type local|remote, command ARRAY, `environment` not `env`).
|
|
199
|
+
it('writes the opencode shim to agents/ (plural) and an OpenCode-schema MCP entry when detected', () => {
|
|
200
|
+
mkdirSync(join(homeDir, '.config', 'opencode', 'skills'), { recursive: true });
|
|
201
|
+
const result = installAgentPack({ homeDir });
|
|
202
|
+
const shimPath = join(homeDir, '.config', 'opencode', 'agents', 'skillsmith-agent.md');
|
|
203
|
+
expect(existsSync(shimPath)).toBe(true);
|
|
204
|
+
expect(existsSync(join(homeDir, '.config', 'opencode', 'agent', 'skillsmith-agent.md'))).toBe(false);
|
|
205
|
+
const configPath = join(homeDir, '.config', 'opencode', 'opencode.json');
|
|
206
|
+
const doc = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
207
|
+
expect(doc.mcp.skillsmith.type).toBe('local');
|
|
208
|
+
expect(Array.isArray(doc.mcp.skillsmith.command)).toBe(true);
|
|
209
|
+
expect(doc.mcp.skillsmith.command).toContain('@skillsmith/mcp-server');
|
|
210
|
+
expect(doc.mcp.skillsmith.environment.SKILLSMITH_TOOL_PROFILE).toBe('agent');
|
|
211
|
+
expect(doc.mcp.skillsmith.env).toBeUndefined();
|
|
212
|
+
expect(doc.mcp.skillsmith.args).toBeUndefined();
|
|
213
|
+
const report = result.harnessReports.find((r) => r.harness === 'opencode');
|
|
214
|
+
expect(report?.detected).toBe(true);
|
|
215
|
+
expect(report?.shimWritten).toBe(true);
|
|
216
|
+
expect(report?.mcpConfig?.status).toBe('created');
|
|
217
|
+
});
|
|
218
|
+
it('recognizes a prior-install OpenCode-schema entry as OURS and updates it without --force', () => {
|
|
219
|
+
mkdirSync(join(homeDir, '.config', 'opencode', 'skills'), { recursive: true });
|
|
220
|
+
const configPath = join(homeDir, '.config', 'opencode', 'opencode.json');
|
|
221
|
+
// Simulates an entry a PREVIOUS sklx version wrote: same OpenCode schema,
|
|
222
|
+
// same package, but stale field content. Without the command-array /
|
|
223
|
+
// `environment` checks in looksLikeOurMcpEntry, this would be
|
|
224
|
+
// misclassified as foreign and refuse to update.
|
|
225
|
+
writeFileSync(configPath, JSON.stringify({
|
|
226
|
+
mcp: {
|
|
227
|
+
skillsmith: {
|
|
228
|
+
type: 'local',
|
|
229
|
+
command: ['npx', '-y', '@skillsmith/mcp-server@0.0.1'],
|
|
230
|
+
environment: { SKILLSMITH_TOOL_PROFILE: 'agent', STALE_VAR: 'x' },
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
}, null, 2));
|
|
234
|
+
const result = installAgentPack({ homeDir });
|
|
235
|
+
const report = result.harnessReports.find((r) => r.harness === 'opencode');
|
|
236
|
+
expect(report?.mcpConfig?.status).toBe('updated');
|
|
237
|
+
const doc = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
238
|
+
expect(doc.mcp.skillsmith.command).toContain('@skillsmith/mcp-server');
|
|
239
|
+
expect(doc.mcp.skillsmith.environment.STALE_VAR).toBeUndefined();
|
|
240
|
+
});
|
|
241
|
+
it('writes the copilot MCP entry to mcp-config.json (Step-6 corrected filename)', () => {
|
|
242
|
+
mkdirSync(join(homeDir, '.copilot', 'skills'), { recursive: true });
|
|
243
|
+
const result = installAgentPack({ homeDir });
|
|
244
|
+
const configPath = join(homeDir, '.copilot', 'mcp-config.json');
|
|
245
|
+
expect(existsSync(configPath)).toBe(true);
|
|
246
|
+
expect(existsSync(join(homeDir, '.copilot', 'mcp.json'))).toBe(false);
|
|
247
|
+
const doc = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
248
|
+
expect(doc.mcpServers.skillsmith.env.SKILLSMITH_TOOL_PROFILE).toBe('agent');
|
|
249
|
+
const report = result.harnessReports.find((r) => r.harness === 'copilot');
|
|
250
|
+
expect(report?.mcpConfig?.status).toBe('created');
|
|
251
|
+
});
|
|
252
|
+
// Governance follow-up (2026-07-01): hermes is the ONLY detected harness
|
|
253
|
+
// whose MCP config is YAML (`agent-config-merge.yaml.ts`) — before this
|
|
254
|
+
// test, nothing in the installer suite ever created `~/.hermes`, so the
|
|
255
|
+
// YAML merge path had zero coverage end-to-end through `installAgentPack`.
|
|
256
|
+
it('merges the skillsmith MCP entry into hermes config.yaml (YAML format) when hermes is detected', () => {
|
|
257
|
+
mkdirSync(join(homeDir, '.hermes', 'skills'), { recursive: true });
|
|
258
|
+
const result = installAgentPack({ homeDir });
|
|
259
|
+
const configPath = join(homeDir, '.hermes', 'config.yaml');
|
|
260
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
261
|
+
expect(content).toContain('mcp_servers:');
|
|
262
|
+
expect(content).toContain('skillsmith:');
|
|
263
|
+
expect(content).toContain('SKILLSMITH_TOOL_PROFILE');
|
|
264
|
+
const report = result.harnessReports.find((r) => r.harness === 'hermes');
|
|
265
|
+
expect(report?.detected).toBe(true);
|
|
266
|
+
expect(report?.skillPackWritten).toBe(true);
|
|
267
|
+
expect(report?.mcpConfig?.status).toBe('created');
|
|
268
|
+
});
|
|
269
|
+
it('hermes YAML merge preserves pre-existing comments and unrelated keys', () => {
|
|
270
|
+
mkdirSync(join(homeDir, '.hermes', 'skills'), { recursive: true });
|
|
271
|
+
const configPath = join(homeDir, '.hermes', 'config.yaml');
|
|
272
|
+
writeFileSync(configPath, ['# my hermes config', 'some_setting: true # inline note', ''].join('\n'));
|
|
273
|
+
installAgentPack({ homeDir });
|
|
274
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
275
|
+
expect(content).toContain('# my hermes config');
|
|
276
|
+
expect(content).toContain('some_setting: true');
|
|
277
|
+
expect(content).toContain('# inline note');
|
|
278
|
+
expect(content).toContain('mcp_servers:');
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
describe('installAgentPack — double-install idempotency', () => {
|
|
282
|
+
it('produces identical manifest entry count and zero additional backups on a second install', () => {
|
|
283
|
+
mkdirSync(join(homeDir, '.cursor', 'skills'), { recursive: true });
|
|
284
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
285
|
+
installAgentPack({ homeDir });
|
|
286
|
+
const manifestAfterFirst = JSON.parse(readFileSync(getAgentManifestPath(), 'utf-8'));
|
|
287
|
+
const backupsDir = getAgentInstallBackupsDir();
|
|
288
|
+
const backupCountAfterFirst = existsSync(backupsDir) ? readdirSync(backupsDir).length : 0;
|
|
289
|
+
installAgentPack({ homeDir });
|
|
290
|
+
const manifestAfterSecond = JSON.parse(readFileSync(getAgentManifestPath(), 'utf-8'));
|
|
291
|
+
const backupCountAfterSecond = existsSync(backupsDir) ? readdirSync(backupsDir).length : 0;
|
|
292
|
+
expect(manifestAfterSecond.entries.length).toBe(manifestAfterFirst.entries.length);
|
|
293
|
+
expect(backupCountAfterSecond).toBe(backupCountAfterFirst);
|
|
294
|
+
});
|
|
295
|
+
// Governance regression test (2026-07-01): the marker-delimited Codex TOML
|
|
296
|
+
// block must be updated in place on re-install, never appended as a SECOND
|
|
297
|
+
// block — a naive "no match found → append" fallback would duplicate the
|
|
298
|
+
// `[mcp_servers.skillsmith]` / `[agents.skillsmith-agent]` tables on every
|
|
299
|
+
// subsequent install.
|
|
300
|
+
it('does not duplicate the codex TOML marker blocks on a second install', () => {
|
|
301
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
302
|
+
installAgentPack({ homeDir });
|
|
303
|
+
installAgentPack({ homeDir });
|
|
304
|
+
const configPath = join(homeDir, '.codex', 'config.toml');
|
|
305
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
306
|
+
const countOccurrences = (needle) => content.split(needle).length - 1;
|
|
307
|
+
expect(countOccurrences('# >>> skillsmith:mcp_servers.skillsmith >>>')).toBe(1);
|
|
308
|
+
expect(countOccurrences('# >>> skillsmith:agents.skillsmith-agent >>>')).toBe(1);
|
|
309
|
+
expect(countOccurrences('# >>> skillsmith:hooks.SessionStart >>>')).toBe(1);
|
|
310
|
+
expect(countOccurrences('[mcp_servers.skillsmith]')).toBe(1);
|
|
311
|
+
expect(countOccurrences('[[hooks.SessionStart]]')).toBe(1);
|
|
312
|
+
});
|
|
313
|
+
it('reports the codex hook wiring as "unchanged" on the second install', () => {
|
|
314
|
+
mkdirSync(join(homeDir, '.codex'), { recursive: true });
|
|
315
|
+
installAgentPack({ homeDir });
|
|
316
|
+
const second = installAgentPack({ homeDir });
|
|
317
|
+
const report = second.harnessReports.find((r) => r.harness === 'codex');
|
|
318
|
+
expect(report?.hookConfig.some((w) => w.status === 'unchanged')).toBe(true);
|
|
319
|
+
});
|
|
320
|
+
it('reports mcpConfig status "unchanged" on the second install', () => {
|
|
321
|
+
installAgentPack({ homeDir });
|
|
322
|
+
const second = installAgentPack({ homeDir });
|
|
323
|
+
const report = second.harnessReports.find((r) => r.harness === 'claude-code');
|
|
324
|
+
expect(report?.mcpConfig?.status).toBe('unchanged');
|
|
325
|
+
});
|
|
326
|
+
// Governance regression test (2026-07-01) for the commit-message-claimed
|
|
327
|
+
// fix: "duplicate backups when hooks+MCP share a config file". Within a
|
|
328
|
+
// SINGLE install run, claude-code's settings.json is merged into THREE
|
|
329
|
+
// times (SessionStart hook, SessionEnd hook, MCP registration) — without
|
|
330
|
+
// `alreadyBackedUpPaths` sharing across those calls, the second and third
|
|
331
|
+
// merges would each independently "back up" content THIS SAME RUN already
|
|
332
|
+
// wrote, producing 3 backup files for one genuine pre-install state instead
|
|
333
|
+
// of 1, and (per `agent-manifest.ts`'s `dedupeEntriesByPath` last-non-null-
|
|
334
|
+
// wins rule) the manifest would end up pointing `uninstall` at the WRONG,
|
|
335
|
+
// polluted backup rather than the true pre-install content.
|
|
336
|
+
it('writes exactly ONE backup file for settings.json even though 3 separate merges touch it in one run', () => {
|
|
337
|
+
mkdirSync(join(homeDir, '.claude'), { recursive: true });
|
|
338
|
+
const settingsPath = join(homeDir, '.claude', 'settings.json');
|
|
339
|
+
writeFileSync(settingsPath, JSON.stringify({ preExisting: true }, null, 2));
|
|
340
|
+
installAgentPack({ homeDir });
|
|
341
|
+
const backupsDir = getAgentInstallBackupsDir();
|
|
342
|
+
const backupFiles = readdirSync(backupsDir).filter((f) => f.includes('settings.json'));
|
|
343
|
+
expect(backupFiles).toHaveLength(1);
|
|
344
|
+
const backupContent = JSON.parse(readFileSync(join(backupsDir, backupFiles[0]), 'utf-8'));
|
|
345
|
+
// The ONE backup that exists must be the GENUINE pre-install content —
|
|
346
|
+
// not an intermediate state polluted by an earlier merge THIS run.
|
|
347
|
+
expect(backupContent).toEqual({ preExisting: true });
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
//# sourceMappingURL=agent-pack-installer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.test.js","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report + options types for `installAgentPack` / `uninstallAgentPack`
|
|
3
|
+
* (SMI-5456 Wave 1 Step 5).
|
|
4
|
+
*
|
|
5
|
+
* @module @skillsmith/core/install/agent-pack-installer.types
|
|
6
|
+
*/
|
|
7
|
+
import type { MergeResult } from './agent-config-merge.types.js';
|
|
8
|
+
/** Support tier from PRD §3.1 / Decision 5. */
|
|
9
|
+
export type SupportTier = 1 | 2 | 3;
|
|
10
|
+
export declare const HARNESS_SUPPORT_TIER: Readonly<Record<string, SupportTier>>;
|
|
11
|
+
export interface HarnessInstallReport {
|
|
12
|
+
harness: string;
|
|
13
|
+
tier: SupportTier;
|
|
14
|
+
detected: boolean;
|
|
15
|
+
skillPackWritten: boolean;
|
|
16
|
+
shimWritten: boolean;
|
|
17
|
+
hooksInstalled: boolean;
|
|
18
|
+
mcpConfig: MergeResult | null;
|
|
19
|
+
hookConfig: MergeResult[];
|
|
20
|
+
notes: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface AgentInstallOptions {
|
|
23
|
+
/** Override HOME for tests. Defaults to `os.homedir()`. */
|
|
24
|
+
homeDir?: string;
|
|
25
|
+
/** Overwrite a foreign (non-Skillsmith) MCP/hook config entry instead of refusing. Default false. */
|
|
26
|
+
force?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface AgentInstallResult {
|
|
29
|
+
installedAt: string;
|
|
30
|
+
manifestPath: string;
|
|
31
|
+
harnessReports: HarnessInstallReport[];
|
|
32
|
+
}
|
|
33
|
+
export interface AgentUninstallOptions {
|
|
34
|
+
homeDir?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface AgentUninstallResult {
|
|
37
|
+
/** Paths that were deleted (installer-created files) or restored from backup (installer-modified files). */
|
|
38
|
+
removed: string[];
|
|
39
|
+
restored: string[];
|
|
40
|
+
/** Manifest entries that referenced a path already missing on disk (no-op, not an error). */
|
|
41
|
+
alreadyGone: string[];
|
|
42
|
+
/**
|
|
43
|
+
* Manifest entries whose `path` or `backupPath` did not match a known
|
|
44
|
+
* installer target (see `agent-manifest-path-guard.ts`) — skipped
|
|
45
|
+
* entirely, neither deleted nor restored. Non-empty only for a corrupted
|
|
46
|
+
* or hand-tampered manifest; empty on every normal install/uninstall
|
|
47
|
+
* cycle.
|
|
48
|
+
*/
|
|
49
|
+
rejected: string[];
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=agent-pack-installer.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.types.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAEhE,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAEnC,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAQtE,CAAA;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE,OAAO,CAAA;IACpB,cAAc,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IAC7B,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qGAAqG;IACrG,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,oBAAoB,EAAE,CAAA;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,4GAA4G;IAC5G,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,6FAA6F;IAC7F,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report + options types for `installAgentPack` / `uninstallAgentPack`
|
|
3
|
+
* (SMI-5456 Wave 1 Step 5).
|
|
4
|
+
*
|
|
5
|
+
* @module @skillsmith/core/install/agent-pack-installer.types
|
|
6
|
+
*/
|
|
7
|
+
export const HARNESS_SUPPORT_TIER = {
|
|
8
|
+
'claude-code': 1,
|
|
9
|
+
cursor: 1,
|
|
10
|
+
codex: 1,
|
|
11
|
+
copilot: 1,
|
|
12
|
+
opencode: 2,
|
|
13
|
+
hermes: 2,
|
|
14
|
+
windsurf: 3,
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=agent-pack-installer.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.types.js","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,CAAC,MAAM,oBAAoB,GAA0C;IACzE,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;CACZ,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sklx agent uninstall` core orchestration (SMI-5456 Wave 1 Step 5).
|
|
3
|
+
*
|
|
4
|
+
* Reverses EXACTLY what `installAgentPack` wrote by replaying the manifest
|
|
5
|
+
* it saved — never by re-deriving "what the generator would currently
|
|
6
|
+
* produce" (which could have drifted across a version bump between install
|
|
7
|
+
* and uninstall). Per manifest entry:
|
|
8
|
+
* - `backupPath !== null` (a shared config file we merged a key into):
|
|
9
|
+
* restore the file to the FULL pre-merge content captured in the
|
|
10
|
+
* backup — this removes exactly our `skillsmith` key/hook entry while
|
|
11
|
+
* leaving every other key in the file untouched, because the backup was
|
|
12
|
+
* taken of the whole file immediately before the merge.
|
|
13
|
+
* - `backupPath === null` (a file we created outright — skill pack copy,
|
|
14
|
+
* shim, hook script): delete it. There is nothing to restore to.
|
|
15
|
+
* - A path already missing on disk (user deleted it manually) is a no-op,
|
|
16
|
+
* not an error.
|
|
17
|
+
*
|
|
18
|
+
* SECURITY (governance follow-up, 2026-07-01): before touching the
|
|
19
|
+
* filesystem, every entry's `path` is checked against
|
|
20
|
+
* {@link isAllowedManifestEntryPath} (must structurally match one of the
|
|
21
|
+
* installer's known per-harness target locations) and, when `backupPath` is
|
|
22
|
+
* set, {@link isAllowedManifestBackupPath} (must resolve under this run's
|
|
23
|
+
* manifest backups directory). The manifest is an ordinary user-writable
|
|
24
|
+
* JSON file, not a signed record — a corrupted or tampered manifest must
|
|
25
|
+
* never become an arbitrary-file-delete/overwrite primitive. An entry
|
|
26
|
+
* failing either check is skipped entirely (added to `result.rejected`,
|
|
27
|
+
* counted toward neither `removed` nor `restored`) rather than acted on.
|
|
28
|
+
*
|
|
29
|
+
* After removing all installer-created files, now-empty directories we
|
|
30
|
+
* likely created (the parents of removed paths) are cleaned up bottom-up —
|
|
31
|
+
* a non-empty directory is left alone (`rmdirSync` only removes empty ones).
|
|
32
|
+
*
|
|
33
|
+
* Known limitation: a hook script's original executable bit is not
|
|
34
|
+
* separately tracked, so restoring a backup writes default file
|
|
35
|
+
* permissions. This only matters for the vanishingly rare case of a
|
|
36
|
+
* pre-existing FOREIGN executable file that happened to already occupy our
|
|
37
|
+
* namespaced hook-script path — documented, not defended against.
|
|
38
|
+
*
|
|
39
|
+
* @module @skillsmith/core/install/agent-pack-uninstaller
|
|
40
|
+
*/
|
|
41
|
+
import type { AgentUninstallOptions, AgentUninstallResult } from './agent-pack-installer.types.js';
|
|
42
|
+
export declare function uninstallAgentPack(_opts?: AgentUninstallOptions): AgentUninstallResult;
|
|
43
|
+
//# sourceMappingURL=agent-pack-uninstaller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-uninstaller.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-uninstaller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAUH,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AAElG,wBAAgB,kBAAkB,CAAC,KAAK,GAAE,qBAA0B,GAAG,oBAAoB,CAkD1F"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sklx agent uninstall` core orchestration (SMI-5456 Wave 1 Step 5).
|
|
3
|
+
*
|
|
4
|
+
* Reverses EXACTLY what `installAgentPack` wrote by replaying the manifest
|
|
5
|
+
* it saved — never by re-deriving "what the generator would currently
|
|
6
|
+
* produce" (which could have drifted across a version bump between install
|
|
7
|
+
* and uninstall). Per manifest entry:
|
|
8
|
+
* - `backupPath !== null` (a shared config file we merged a key into):
|
|
9
|
+
* restore the file to the FULL pre-merge content captured in the
|
|
10
|
+
* backup — this removes exactly our `skillsmith` key/hook entry while
|
|
11
|
+
* leaving every other key in the file untouched, because the backup was
|
|
12
|
+
* taken of the whole file immediately before the merge.
|
|
13
|
+
* - `backupPath === null` (a file we created outright — skill pack copy,
|
|
14
|
+
* shim, hook script): delete it. There is nothing to restore to.
|
|
15
|
+
* - A path already missing on disk (user deleted it manually) is a no-op,
|
|
16
|
+
* not an error.
|
|
17
|
+
*
|
|
18
|
+
* SECURITY (governance follow-up, 2026-07-01): before touching the
|
|
19
|
+
* filesystem, every entry's `path` is checked against
|
|
20
|
+
* {@link isAllowedManifestEntryPath} (must structurally match one of the
|
|
21
|
+
* installer's known per-harness target locations) and, when `backupPath` is
|
|
22
|
+
* set, {@link isAllowedManifestBackupPath} (must resolve under this run's
|
|
23
|
+
* manifest backups directory). The manifest is an ordinary user-writable
|
|
24
|
+
* JSON file, not a signed record — a corrupted or tampered manifest must
|
|
25
|
+
* never become an arbitrary-file-delete/overwrite primitive. An entry
|
|
26
|
+
* failing either check is skipped entirely (added to `result.rejected`,
|
|
27
|
+
* counted toward neither `removed` nor `restored`) rather than acted on.
|
|
28
|
+
*
|
|
29
|
+
* After removing all installer-created files, now-empty directories we
|
|
30
|
+
* likely created (the parents of removed paths) are cleaned up bottom-up —
|
|
31
|
+
* a non-empty directory is left alone (`rmdirSync` only removes empty ones).
|
|
32
|
+
*
|
|
33
|
+
* Known limitation: a hook script's original executable bit is not
|
|
34
|
+
* separately tracked, so restoring a backup writes default file
|
|
35
|
+
* permissions. This only matters for the vanishingly rare case of a
|
|
36
|
+
* pre-existing FOREIGN executable file that happened to already occupy our
|
|
37
|
+
* namespaced hook-script path — documented, not defended against.
|
|
38
|
+
*
|
|
39
|
+
* @module @skillsmith/core/install/agent-pack-uninstaller
|
|
40
|
+
*/
|
|
41
|
+
import { dirname } from 'node:path';
|
|
42
|
+
import { existsSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
43
|
+
import { loadAgentManifest, saveAgentManifest } from './agent-manifest.js';
|
|
44
|
+
import { isAllowedManifestBackupPath, isAllowedManifestEntryPath, } from './agent-manifest-path-guard.js';
|
|
45
|
+
export function uninstallAgentPack(_opts = {}) {
|
|
46
|
+
const manifest = loadAgentManifest();
|
|
47
|
+
const removed = [];
|
|
48
|
+
const restored = [];
|
|
49
|
+
const alreadyGone = [];
|
|
50
|
+
const rejected = [];
|
|
51
|
+
const touchedDirs = new Set();
|
|
52
|
+
for (const entry of manifest.entries) {
|
|
53
|
+
if (!isAllowedManifestEntryPath(entry.path)) {
|
|
54
|
+
rejected.push(entry.path);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (entry.backupPath && !isAllowedManifestBackupPath(entry.backupPath)) {
|
|
58
|
+
// A validated destination path but an untrusted backup SOURCE — never
|
|
59
|
+
// restore from it (that would be an attacker-controlled read into a
|
|
60
|
+
// safe write target) and never fall through to delete either (the
|
|
61
|
+
// entry's true install-time shape can't be determined). Skip it whole.
|
|
62
|
+
rejected.push(entry.path);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!existsSync(entry.path)) {
|
|
66
|
+
alreadyGone.push(entry.path);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
touchedDirs.add(dirname(entry.path));
|
|
70
|
+
if (entry.backupPath && existsSync(entry.backupPath)) {
|
|
71
|
+
const content = readFileSync(entry.backupPath, 'utf-8');
|
|
72
|
+
writeFileSync(entry.path, content, 'utf-8');
|
|
73
|
+
restored.push(entry.path);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
unlinkSync(entry.path);
|
|
77
|
+
removed.push(entry.path);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
cleanupEmptyDirs(touchedDirs);
|
|
81
|
+
// Uninstall clears the manifest — a subsequent install starts fresh
|
|
82
|
+
// (P-5 idempotency: install → uninstall → install produces the same
|
|
83
|
+
// filesystem state as a first-ever install, not accumulated entries).
|
|
84
|
+
saveAgentManifest({
|
|
85
|
+
schemaVersion: 1,
|
|
86
|
+
installedAt: new Date(0).toISOString(),
|
|
87
|
+
packSchemaVersion: 0,
|
|
88
|
+
entries: [],
|
|
89
|
+
});
|
|
90
|
+
return { removed, restored, alreadyGone, rejected };
|
|
91
|
+
}
|
|
92
|
+
/** Remove now-empty directories, deepest first, stopping at the first non-empty one per branch. */
|
|
93
|
+
function cleanupEmptyDirs(dirs) {
|
|
94
|
+
const sorted = [...dirs].sort((a, b) => b.length - a.length);
|
|
95
|
+
for (const dir of sorted) {
|
|
96
|
+
let current = dir;
|
|
97
|
+
// Walk upward while each level is empty; stop at the first non-empty
|
|
98
|
+
// (or missing/root) directory. Bounded by path length, never infinite.
|
|
99
|
+
for (let i = 0; i < 32; i++) {
|
|
100
|
+
try {
|
|
101
|
+
rmdirSync(current);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
break; // non-empty, missing, or permission-denied — stop this branch.
|
|
105
|
+
}
|
|
106
|
+
const parent = dirname(current);
|
|
107
|
+
if (parent === current)
|
|
108
|
+
break;
|
|
109
|
+
current = parent;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=agent-pack-uninstaller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-uninstaller.js","sourceRoot":"","sources":["../../../src/install/agent-pack-uninstaller.ts"],"names":[],"mappings":"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"}
|