@skillsmith/mcp-server 0.4.13 → 0.5.1
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 +37 -4
- package/README.md +89 -13
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/__tests__/compare.test.js +5 -5
- package/dist/src/__tests__/compare.test.js.map +1 -1
- package/dist/src/__tests__/context-listeners.test.d.ts +12 -0
- package/dist/src/__tests__/context-listeners.test.d.ts.map +1 -0
- package/dist/src/__tests__/context-listeners.test.js +87 -0
- package/dist/src/__tests__/context-listeners.test.js.map +1 -0
- package/dist/src/__tests__/context.test.js +84 -82
- package/dist/src/__tests__/context.test.js.map +1 -1
- package/dist/src/__tests__/get-skill.api-path.test.js +21 -14
- package/dist/src/__tests__/get-skill.api-path.test.js.map +1 -1
- package/dist/src/__tests__/get-skill.test.js +5 -5
- package/dist/src/__tests__/get-skill.test.js.map +1 -1
- package/dist/src/__tests__/index-local.test.js +5 -5
- package/dist/src/__tests__/index-local.test.js.map +1 -1
- package/dist/src/__tests__/recommend-online-path.test.js +5 -5
- package/dist/src/__tests__/recommend-online-path.test.js.map +1 -1
- package/dist/src/__tests__/recommend.test.js +9 -9
- package/dist/src/__tests__/recommend.test.js.map +1 -1
- package/dist/src/__tests__/search-compatible-with.test.d.ts +10 -0
- package/dist/src/__tests__/search-compatible-with.test.d.ts.map +1 -0
- package/dist/src/__tests__/search-compatible-with.test.js +96 -0
- package/dist/src/__tests__/search-compatible-with.test.js.map +1 -0
- package/dist/src/__tests__/search-online-path.test.js +5 -5
- package/dist/src/__tests__/search-online-path.test.js.map +1 -1
- package/dist/src/__tests__/search.test.js +16 -101
- package/dist/src/__tests__/search.test.js.map +1 -1
- package/dist/src/__tests__/test-utils.d.ts +18 -3
- package/dist/src/__tests__/test-utils.d.ts.map +1 -1
- package/dist/src/__tests__/test-utils.js +24 -7
- package/dist/src/__tests__/test-utils.js.map +1 -1
- package/dist/src/audit/audit-history.d.ts +77 -0
- package/dist/src/audit/audit-history.d.ts.map +1 -0
- package/dist/src/audit/audit-history.js +98 -0
- package/dist/src/audit/audit-history.js.map +1 -0
- package/dist/src/audit/audit-report-writer.d.ts +82 -0
- package/dist/src/audit/audit-report-writer.d.ts.map +1 -0
- package/dist/src/audit/audit-report-writer.js +241 -0
- package/dist/src/audit/audit-report-writer.js.map +1 -0
- package/dist/src/audit/audit-suggestions.d.ts +52 -0
- package/dist/src/audit/audit-suggestions.d.ts.map +1 -0
- package/dist/src/audit/audit-suggestions.js +90 -0
- package/dist/src/audit/audit-suggestions.js.map +1 -0
- package/dist/src/audit/bootstrap-unmanaged.d.ts +66 -0
- package/dist/src/audit/bootstrap-unmanaged.d.ts.map +1 -0
- package/dist/src/audit/bootstrap-unmanaged.js +91 -0
- package/dist/src/audit/bootstrap-unmanaged.js.map +1 -0
- package/dist/src/audit/collision-detector.d.ts +72 -0
- package/dist/src/audit/collision-detector.d.ts.map +1 -0
- package/dist/src/audit/collision-detector.helpers.d.ts +63 -0
- package/dist/src/audit/collision-detector.helpers.d.ts.map +1 -0
- package/dist/src/audit/collision-detector.helpers.js +141 -0
- package/dist/src/audit/collision-detector.helpers.js.map +1 -0
- package/dist/src/audit/collision-detector.js +172 -0
- package/dist/src/audit/collision-detector.js.map +1 -0
- package/dist/src/audit/collision-detector.semantic.helpers.d.ts +49 -0
- package/dist/src/audit/collision-detector.semantic.helpers.d.ts.map +1 -0
- package/dist/src/audit/collision-detector.semantic.helpers.js +121 -0
- package/dist/src/audit/collision-detector.semantic.helpers.js.map +1 -0
- package/dist/src/audit/collision-detector.types.d.ts +70 -0
- package/dist/src/audit/collision-detector.types.d.ts.map +1 -0
- package/dist/src/audit/collision-detector.types.js +9 -0
- package/dist/src/audit/collision-detector.types.js.map +1 -0
- package/dist/src/audit/edit-applier.d.ts +64 -0
- package/dist/src/audit/edit-applier.d.ts.map +1 -0
- package/dist/src/audit/edit-applier.js +233 -0
- package/dist/src/audit/edit-applier.js.map +1 -0
- package/dist/src/audit/edit-applier.types.d.ts +72 -0
- package/dist/src/audit/edit-applier.types.d.ts.map +1 -0
- package/dist/src/audit/edit-applier.types.js +13 -0
- package/dist/src/audit/edit-applier.types.js.map +1 -0
- package/dist/src/audit/edit-suggester.d.ts +63 -0
- package/dist/src/audit/edit-suggester.d.ts.map +1 -0
- package/dist/src/audit/edit-suggester.js +326 -0
- package/dist/src/audit/edit-suggester.js.map +1 -0
- package/dist/src/audit/edit-suggester.types.d.ts +148 -0
- package/dist/src/audit/edit-suggester.types.d.ts.map +1 -0
- package/dist/src/audit/edit-suggester.types.js +17 -0
- package/dist/src/audit/edit-suggester.types.js.map +1 -0
- package/dist/src/audit/framework-adapter.d.ts +54 -0
- package/dist/src/audit/framework-adapter.d.ts.map +1 -0
- package/dist/src/audit/framework-adapter.js +251 -0
- package/dist/src/audit/framework-adapter.js.map +1 -0
- package/dist/src/audit/framework-adapter.types.d.ts +162 -0
- package/dist/src/audit/framework-adapter.types.d.ts.map +1 -0
- package/dist/src/audit/framework-adapter.types.js +31 -0
- package/dist/src/audit/framework-adapter.types.js.map +1 -0
- package/dist/src/audit/index.d.ts +46 -0
- package/dist/src/audit/index.d.ts.map +1 -0
- package/dist/src/audit/index.js +44 -0
- package/dist/src/audit/index.js.map +1 -0
- package/dist/src/audit/install-preflight.d.ts +99 -0
- package/dist/src/audit/install-preflight.d.ts.map +1 -0
- package/dist/src/audit/install-preflight.js +320 -0
- package/dist/src/audit/install-preflight.js.map +1 -0
- package/dist/src/audit/namespace-audit.types.d.ts +100 -0
- package/dist/src/audit/namespace-audit.types.d.ts.map +1 -0
- package/dist/src/audit/namespace-audit.types.js +20 -0
- package/dist/src/audit/namespace-audit.types.js.map +1 -0
- package/dist/src/audit/namespace-overrides.d.ts +79 -0
- package/dist/src/audit/namespace-overrides.d.ts.map +1 -0
- package/dist/src/audit/namespace-overrides.js +228 -0
- package/dist/src/audit/namespace-overrides.js.map +1 -0
- package/dist/src/audit/namespace-overrides.types.d.ts +115 -0
- package/dist/src/audit/namespace-overrides.types.d.ts.map +1 -0
- package/dist/src/audit/namespace-overrides.types.js +26 -0
- package/dist/src/audit/namespace-overrides.types.js.map +1 -0
- package/dist/src/audit/rename-engine.apply-paths.d.ts +54 -0
- package/dist/src/audit/rename-engine.apply-paths.d.ts.map +1 -0
- package/dist/src/audit/rename-engine.apply-paths.js +126 -0
- package/dist/src/audit/rename-engine.apply-paths.js.map +1 -0
- package/dist/src/audit/rename-engine.d.ts +59 -0
- package/dist/src/audit/rename-engine.d.ts.map +1 -0
- package/dist/src/audit/rename-engine.helpers.d.ts +63 -0
- package/dist/src/audit/rename-engine.helpers.d.ts.map +1 -0
- package/dist/src/audit/rename-engine.helpers.js +224 -0
- package/dist/src/audit/rename-engine.helpers.js.map +1 -0
- package/dist/src/audit/rename-engine.js +393 -0
- package/dist/src/audit/rename-engine.js.map +1 -0
- package/dist/src/audit/rename-engine.types.d.ts +157 -0
- package/dist/src/audit/rename-engine.types.d.ts.map +1 -0
- package/dist/src/audit/rename-engine.types.js +15 -0
- package/dist/src/audit/rename-engine.types.js.map +1 -0
- package/dist/src/audit/run-inventory-audit.d.ts +95 -0
- package/dist/src/audit/run-inventory-audit.d.ts.map +1 -0
- package/dist/src/audit/run-inventory-audit.js +245 -0
- package/dist/src/audit/run-inventory-audit.js.map +1 -0
- package/dist/src/audit/suggestion-chain.d.ts +89 -0
- package/dist/src/audit/suggestion-chain.d.ts.map +1 -0
- package/dist/src/audit/suggestion-chain.js +121 -0
- package/dist/src/audit/suggestion-chain.js.map +1 -0
- package/dist/src/audit-tool-dispatch.d.ts +61 -0
- package/dist/src/audit-tool-dispatch.d.ts.map +1 -0
- package/dist/src/audit-tool-dispatch.js +114 -0
- package/dist/src/audit-tool-dispatch.js.map +1 -0
- package/dist/src/index.js +34 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexer/LocalIndexer.d.ts +8 -1
- package/dist/src/indexer/LocalIndexer.d.ts.map +1 -1
- package/dist/src/indexer/LocalIndexer.js +42 -38
- package/dist/src/indexer/LocalIndexer.js.map +1 -1
- package/dist/src/middleware/__tests__/license.gate.test.js +21 -2
- package/dist/src/middleware/__tests__/license.gate.test.js.map +1 -1
- package/dist/src/middleware/license.gate.d.ts +14 -0
- package/dist/src/middleware/license.gate.d.ts.map +1 -1
- package/dist/src/middleware/license.gate.js +52 -1
- package/dist/src/middleware/license.gate.js.map +1 -1
- package/dist/src/onboarding/install-assets.d.ts.map +1 -1
- package/dist/src/onboarding/install-assets.js +11 -5
- package/dist/src/onboarding/install-assets.js.map +1 -1
- package/dist/src/tool-dispatch.d.ts.map +1 -1
- package/dist/src/tool-dispatch.js +6 -4
- package/dist/src/tool-dispatch.js.map +1 -1
- package/dist/src/tools/analytics.service.test.js +6 -4
- package/dist/src/tools/analytics.service.test.js.map +1 -1
- package/dist/src/tools/apply-namespace-rename.d.ts +71 -0
- package/dist/src/tools/apply-namespace-rename.d.ts.map +1 -0
- package/dist/src/tools/apply-namespace-rename.js +137 -0
- package/dist/src/tools/apply-namespace-rename.js.map +1 -0
- package/dist/src/tools/apply-namespace-rename.types.d.ts +46 -0
- package/dist/src/tools/apply-namespace-rename.types.d.ts.map +1 -0
- package/dist/src/tools/apply-namespace-rename.types.js +9 -0
- package/dist/src/tools/apply-namespace-rename.types.js.map +1 -0
- package/dist/src/tools/apply-recommended-edit.d.ts +50 -0
- package/dist/src/tools/apply-recommended-edit.d.ts.map +1 -0
- package/dist/src/tools/apply-recommended-edit.js +112 -0
- package/dist/src/tools/apply-recommended-edit.js.map +1 -0
- package/dist/src/tools/apply-recommended-edit.types.d.ts +49 -0
- package/dist/src/tools/apply-recommended-edit.types.d.ts.map +1 -0
- package/dist/src/tools/apply-recommended-edit.types.js +14 -0
- package/dist/src/tools/apply-recommended-edit.types.js.map +1 -0
- package/dist/src/tools/audit-tools.d.ts +4 -4
- package/dist/src/tools/compare.types.js +1 -1
- package/dist/src/tools/compare.types.js.map +1 -1
- package/dist/src/tools/compliance-tools.service.test.js +6 -4
- package/dist/src/tools/compliance-tools.service.test.js.map +1 -1
- package/dist/src/tools/get-skill.d.ts.map +1 -1
- package/dist/src/tools/get-skill.js +1 -1
- package/dist/src/tools/get-skill.js.map +1 -1
- package/dist/src/tools/install.backup-gc.d.ts +61 -0
- package/dist/src/tools/install.backup-gc.d.ts.map +1 -0
- package/dist/src/tools/install.backup-gc.js +166 -0
- package/dist/src/tools/install.backup-gc.js.map +1 -0
- package/dist/src/tools/install.conflict-helpers.d.ts +29 -2
- package/dist/src/tools/install.conflict-helpers.d.ts.map +1 -1
- package/dist/src/tools/install.conflict-helpers.js +37 -4
- package/dist/src/tools/install.conflict-helpers.js.map +1 -1
- package/dist/src/tools/install.d.ts +15 -1
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.js +168 -8
- package/dist/src/tools/install.js.map +1 -1
- package/dist/src/tools/install.ledger-replay.d.ts +52 -0
- package/dist/src/tools/install.ledger-replay.d.ts.map +1 -0
- package/dist/src/tools/install.ledger-replay.js +88 -0
- package/dist/src/tools/install.ledger-replay.js.map +1 -0
- package/dist/src/tools/install.namespace-gate.d.ts +68 -0
- package/dist/src/tools/install.namespace-gate.d.ts.map +1 -0
- package/dist/src/tools/install.namespace-gate.js +129 -0
- package/dist/src/tools/install.namespace-gate.js.map +1 -0
- package/dist/src/tools/install.test.js +136 -1
- package/dist/src/tools/install.test.js.map +1 -1
- package/dist/src/tools/install.tool.d.ts +17 -0
- package/dist/src/tools/install.tool.d.ts.map +1 -1
- package/dist/src/tools/install.tool.js +19 -1
- package/dist/src/tools/install.tool.js.map +1 -1
- package/dist/src/tools/install.types.d.ts +35 -1
- package/dist/src/tools/install.types.d.ts.map +1 -1
- package/dist/src/tools/install.types.js +24 -2
- package/dist/src/tools/install.types.js.map +1 -1
- package/dist/src/tools/namespace-audit/telemetry.d.ts +80 -0
- package/dist/src/tools/namespace-audit/telemetry.d.ts.map +1 -0
- package/dist/src/tools/namespace-audit/telemetry.js +129 -0
- package/dist/src/tools/namespace-audit/telemetry.js.map +1 -0
- package/dist/src/tools/outdated.test.js +2 -2
- package/dist/src/tools/outdated.test.js.map +1 -1
- package/dist/src/tools/publish-private.test.js +2 -2
- package/dist/src/tools/publish-private.test.js.map +1 -1
- package/dist/src/tools/recommend.types.d.ts +2 -2
- package/dist/src/tools/recommend.types.js +1 -1
- package/dist/src/tools/recommend.types.js.map +1 -1
- package/dist/src/tools/search.d.ts +2 -2
- package/dist/src/tools/search.d.ts.map +1 -1
- package/dist/src/tools/search.js +3 -3
- package/dist/src/tools/search.js.map +1 -1
- package/dist/src/tools/skill-audit.test.js +2 -2
- package/dist/src/tools/skill-audit.test.js.map +1 -1
- package/dist/src/tools/skill-diff.d.ts +1 -1
- package/dist/src/tools/skill-inventory-audit.d.ts +67 -0
- package/dist/src/tools/skill-inventory-audit.d.ts.map +1 -0
- package/dist/src/tools/skill-inventory-audit.js +112 -0
- package/dist/src/tools/skill-inventory-audit.js.map +1 -0
- package/dist/src/tools/skill-inventory-audit.types.d.ts +67 -0
- package/dist/src/tools/skill-inventory-audit.types.d.ts.map +1 -0
- package/dist/src/tools/skill-inventory-audit.types.js +14 -0
- package/dist/src/tools/skill-inventory-audit.types.js.map +1 -0
- package/dist/src/tools/skill-pack-audit.d.ts.map +1 -1
- package/dist/src/tools/skill-pack-audit.helpers.d.ts.map +1 -1
- package/dist/src/tools/skill-pack-audit.helpers.js +15 -2
- package/dist/src/tools/skill-pack-audit.helpers.js.map +1 -1
- package/dist/src/tools/skill-pack-audit.js +15 -1
- package/dist/src/tools/skill-pack-audit.js.map +1 -1
- package/dist/src/tools/skill-rescan.d.ts.map +1 -1
- package/dist/src/tools/skill-rescan.js +4 -2
- package/dist/src/tools/skill-rescan.js.map +1 -1
- package/dist/src/tools/suggest.d.ts +2 -2
- package/dist/src/tools/uninstall.d.ts +1 -1
- package/dist/src/tools/uninstall.d.ts.map +1 -1
- package/dist/src/tools/uninstall.js +17 -3
- package/dist/src/tools/uninstall.js.map +1 -1
- package/dist/src/tools/validate.types.d.ts +10 -1
- package/dist/src/tools/validate.types.d.ts.map +1 -1
- package/dist/src/tools/validate.types.js +11 -2
- package/dist/src/tools/validate.types.js.map +1 -1
- package/dist/src/utils/installed-skills.d.ts.map +1 -1
- package/dist/src/utils/installed-skills.js +8 -6
- package/dist/src/utils/installed-skills.js.map +1 -1
- package/dist/src/utils/local-inventory.d.ts +29 -0
- package/dist/src/utils/local-inventory.d.ts.map +1 -0
- package/dist/src/utils/local-inventory.helpers.d.ts +96 -0
- package/dist/src/utils/local-inventory.helpers.d.ts.map +1 -0
- package/dist/src/utils/local-inventory.helpers.js +279 -0
- package/dist/src/utils/local-inventory.helpers.js.map +1 -0
- package/dist/src/utils/local-inventory.js +202 -0
- package/dist/src/utils/local-inventory.js.map +1 -0
- package/dist/src/utils/local-inventory.types.d.ts +100 -0
- package/dist/src/utils/local-inventory.types.d.ts.map +1 -0
- package/dist/src/utils/local-inventory.types.js +9 -0
- package/dist/src/utils/local-inventory.types.js.map +1 -0
- package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +12 -0
- package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -1
- package/dist/src/webhooks/stripe-webhook-endpoint.js +30 -9
- package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -1
- package/dist/src/webhooks/webhook-endpoint.d.ts +13 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -1
- package/dist/src/webhooks/webhook-endpoint.js +31 -9
- package/dist/src/webhooks/webhook-endpoint.js.map +1 -1
- package/dist/tests/compare.test.js +5 -5
- package/dist/tests/compare.test.js.map +1 -1
- package/dist/tests/context-async-listeners.test.d.ts +12 -0
- package/dist/tests/context-async-listeners.test.d.ts.map +1 -0
- package/dist/tests/context-async-listeners.test.js +62 -0
- package/dist/tests/context-async-listeners.test.js.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.js +9 -3
- package/dist/tests/e2e/compare.e2e.test.js.map +1 -1
- package/dist/tests/e2e/install-flow.e2e.test.js +9 -3
- package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -1
- package/dist/tests/e2e/recommend.e2e.test.js +9 -3
- package/dist/tests/e2e/recommend.e2e.test.js.map +1 -1
- package/dist/tests/e2e/skill-flow.e2e.test.js +17 -5
- package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -1
- package/dist/tests/e2e/suggest.e2e.test.js +11 -3
- package/dist/tests/e2e/suggest.e2e.test.js.map +1 -1
- package/dist/tests/install-assets.test.d.ts +16 -0
- package/dist/tests/install-assets.test.d.ts.map +1 -0
- package/dist/tests/install-assets.test.js +72 -0
- package/dist/tests/install-assets.test.js.map +1 -0
- package/dist/tests/integration/audit-roundtrip.test.d.ts +29 -0
- package/dist/tests/integration/audit-roundtrip.test.d.ts.map +1 -0
- package/dist/tests/integration/audit-roundtrip.test.js +214 -0
- package/dist/tests/integration/audit-roundtrip.test.js.map +1 -0
- package/dist/tests/integration/install-namespace.integration.test.d.ts +14 -0
- package/dist/tests/integration/install-namespace.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/install-namespace.integration.test.js +414 -0
- package/dist/tests/integration/install-namespace.integration.test.js.map +1 -0
- package/dist/tests/performance/search-performance.test.js +9 -3
- package/dist/tests/performance/search-performance.test.js.map +1 -1
- package/dist/tests/tool-descriptions.test.d.ts +16 -0
- package/dist/tests/tool-descriptions.test.d.ts.map +1 -0
- package/dist/tests/tool-descriptions.test.js +63 -0
- package/dist/tests/tool-descriptions.test.js.map +1 -0
- package/dist/tests/tools.test.js +5 -5
- package/dist/tests/tools.test.js.map +1 -1
- package/dist/tests/unit/apply-namespace-rename.test.d.ts +24 -0
- package/dist/tests/unit/apply-namespace-rename.test.d.ts.map +1 -0
- package/dist/tests/unit/apply-namespace-rename.test.js +205 -0
- package/dist/tests/unit/apply-namespace-rename.test.js.map +1 -0
- package/dist/tests/unit/apply-recommended-edit.test.d.ts +28 -0
- package/dist/tests/unit/apply-recommended-edit.test.d.ts.map +1 -0
- package/dist/tests/unit/apply-recommended-edit.test.js +229 -0
- package/dist/tests/unit/apply-recommended-edit.test.js.map +1 -0
- package/dist/tests/unit/audit-history.test.d.ts +11 -0
- package/dist/tests/unit/audit-history.test.d.ts.map +1 -0
- package/dist/tests/unit/audit-history.test.js +183 -0
- package/dist/tests/unit/audit-history.test.js.map +1 -0
- package/dist/tests/unit/audit-report-writer.test.d.ts +7 -0
- package/dist/tests/unit/audit-report-writer.test.d.ts.map +1 -0
- package/dist/tests/unit/audit-report-writer.test.js +249 -0
- package/dist/tests/unit/audit-report-writer.test.js.map +1 -0
- package/dist/tests/unit/audit-tool-dispatch.test.d.ts +17 -0
- package/dist/tests/unit/audit-tool-dispatch.test.d.ts.map +1 -0
- package/dist/tests/unit/audit-tool-dispatch.test.js +133 -0
- package/dist/tests/unit/audit-tool-dispatch.test.js.map +1 -0
- package/dist/tests/unit/collision-detector.semantic.test.d.ts +12 -0
- package/dist/tests/unit/collision-detector.semantic.test.d.ts.map +1 -0
- package/dist/tests/unit/collision-detector.semantic.test.js +281 -0
- package/dist/tests/unit/collision-detector.semantic.test.js.map +1 -0
- package/dist/tests/unit/collision-detector.test.d.ts +8 -0
- package/dist/tests/unit/collision-detector.test.d.ts.map +1 -0
- package/dist/tests/unit/collision-detector.test.js +266 -0
- package/dist/tests/unit/collision-detector.test.js.map +1 -0
- package/dist/tests/unit/edit-applier.test.d.ts +17 -0
- package/dist/tests/unit/edit-applier.test.d.ts.map +1 -0
- package/dist/tests/unit/edit-applier.test.js +165 -0
- package/dist/tests/unit/edit-applier.test.js.map +1 -0
- package/dist/tests/unit/edit-suggester.fixtures.d.ts +38 -0
- package/dist/tests/unit/edit-suggester.fixtures.d.ts.map +1 -0
- package/dist/tests/unit/edit-suggester.fixtures.js +84 -0
- package/dist/tests/unit/edit-suggester.fixtures.js.map +1 -0
- package/dist/tests/unit/edit-suggester.test.d.ts +17 -0
- package/dist/tests/unit/edit-suggester.test.d.ts.map +1 -0
- package/dist/tests/unit/edit-suggester.test.js +356 -0
- package/dist/tests/unit/edit-suggester.test.js.map +1 -0
- package/dist/tests/unit/framework-adapter.test.d.ts +30 -0
- package/dist/tests/unit/framework-adapter.test.d.ts.map +1 -0
- package/dist/tests/unit/framework-adapter.test.js +221 -0
- package/dist/tests/unit/framework-adapter.test.js.map +1 -0
- package/dist/tests/unit/install-preflight.test.d.ts +17 -0
- package/dist/tests/unit/install-preflight.test.d.ts.map +1 -0
- package/dist/tests/unit/install-preflight.test.js +270 -0
- package/dist/tests/unit/install-preflight.test.js.map +1 -0
- package/dist/tests/unit/install.backup-gc.test.d.ts +18 -0
- package/dist/tests/unit/install.backup-gc.test.d.ts.map +1 -0
- package/dist/tests/unit/install.backup-gc.test.js +177 -0
- package/dist/tests/unit/install.backup-gc.test.js.map +1 -0
- package/dist/tests/unit/install.ledger-replay.test.d.ts +12 -0
- package/dist/tests/unit/install.ledger-replay.test.d.ts.map +1 -0
- package/dist/tests/unit/install.ledger-replay.test.js +98 -0
- package/dist/tests/unit/install.ledger-replay.test.js.map +1 -0
- package/dist/tests/unit/local-inventory.test.d.ts +8 -0
- package/dist/tests/unit/local-inventory.test.d.ts.map +1 -0
- package/dist/tests/unit/local-inventory.test.js +165 -0
- package/dist/tests/unit/local-inventory.test.js.map +1 -0
- package/dist/tests/unit/namespace-audit-telemetry.test.d.ts +10 -0
- package/dist/tests/unit/namespace-audit-telemetry.test.d.ts.map +1 -0
- package/dist/tests/unit/namespace-audit-telemetry.test.js +215 -0
- package/dist/tests/unit/namespace-audit-telemetry.test.js.map +1 -0
- package/dist/tests/unit/namespace-overrides.test.d.ts +18 -0
- package/dist/tests/unit/namespace-overrides.test.d.ts.map +1 -0
- package/dist/tests/unit/namespace-overrides.test.js +210 -0
- package/dist/tests/unit/namespace-overrides.test.js.map +1 -0
- package/dist/tests/unit/rename-engine.test.d.ts +26 -0
- package/dist/tests/unit/rename-engine.test.d.ts.map +1 -0
- package/dist/tests/unit/rename-engine.test.js +367 -0
- package/dist/tests/unit/rename-engine.test.js.map +1 -0
- package/dist/tests/unit/skill-inventory-audit.test.d.ts +20 -0
- package/dist/tests/unit/skill-inventory-audit.test.d.ts.map +1 -0
- package/dist/tests/unit/skill-inventory-audit.test.js +299 -0
- package/dist/tests/unit/skill-inventory-audit.test.js.map +1 -0
- package/dist/tests/unit/skill-pack-audit.helpers.test.d.ts +11 -0
- package/dist/tests/unit/skill-pack-audit.helpers.test.d.ts.map +1 -0
- package/dist/tests/unit/skill-pack-audit.helpers.test.js +61 -0
- package/dist/tests/unit/skill-pack-audit.helpers.test.js.map +1 -0
- package/dist/tests/unit/skill-pack-audit.test.js +1 -1
- package/dist/tests/unit/skill-pack-audit.test.js.map +1 -1
- package/dist/tests/unit/suggestion-chain.test.d.ts +17 -0
- package/dist/tests/unit/suggestion-chain.test.d.ts.map +1 -0
- package/dist/tests/unit/suggestion-chain.test.js +191 -0
- package/dist/tests/unit/suggestion-chain.test.js.map +1 -0
- package/dist/tests/webhooks/standalone-shutdown.test.d.ts +12 -0
- package/dist/tests/webhooks/standalone-shutdown.test.d.ts.map +1 -0
- package/dist/tests/webhooks/standalone-shutdown.test.js +91 -0
- package/dist/tests/webhooks/standalone-shutdown.test.js.map +1 -0
- package/package.json +17 -4
- package/server.json +3 -3
- package/src/assets/skills/skillsmith/SKILL.md +109 -80
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Install pre-flight namespace check (SMI-4588 Wave 2 Step 5, PR #3).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/install-preflight
|
|
4
|
+
*
|
|
5
|
+
* Detects namespace collisions between an in-flight install candidate and
|
|
6
|
+
* the user's existing local inventory BEFORE any side effects. Returns both
|
|
7
|
+
* a non-blocking `warnings[]` shape (for `power_user` / `governance` modes)
|
|
8
|
+
* AND a blocking `pendingCollision` envelope (for `preventative` mode). The
|
|
9
|
+
* mode gate lives in the install.ts caller — this module is pure detection
|
|
10
|
+
* + suggestion generation + audit-history persistence.
|
|
11
|
+
*
|
|
12
|
+
* Plan §3 + §Step 5 + Edits 2/3/6/7.
|
|
13
|
+
*
|
|
14
|
+
* Inventory contract (Edit 7):
|
|
15
|
+
* - `existingInventory` — pre-candidate snapshot, passed to
|
|
16
|
+
* `generateSuggestionChain` (chain self-collides at tier 1 otherwise).
|
|
17
|
+
* - `augmentedInventory` — existing + the synthesized candidate, passed to
|
|
18
|
+
* `detectCollisions`. Filtering to flags involving the candidate keeps
|
|
19
|
+
* pre-existing collisions from re-surfacing on every install.
|
|
20
|
+
*
|
|
21
|
+
* Failure model (Edit 2):
|
|
22
|
+
* - Pre-flight scanner failure (ledger malformed unrecoverably, fs error,
|
|
23
|
+
* unexpected throw) is ALWAYS non-blocking. The caller treats `warnings:
|
|
24
|
+
* [], pendingCollision: null` as a degraded-but-clean pass and proceeds
|
|
25
|
+
* with the install.
|
|
26
|
+
*
|
|
27
|
+
* Edit 6 — `readLedger()` may throw `namespace.ledger.version_unsupported`.
|
|
28
|
+
* The pre-flight catches it and degrades to non-blocking; bubbling would
|
|
29
|
+
* brick installs after a ledger downgrade.
|
|
30
|
+
*/
|
|
31
|
+
import type { AuditId, InventoryEntry } from './collision-detector.types.js';
|
|
32
|
+
import type { NamespaceWarning, PendingCollision } from './namespace-audit.types.js';
|
|
33
|
+
import type { AuditMode, Tier } from '@skillsmith/core/config/audit-mode';
|
|
34
|
+
/**
|
|
35
|
+
* One synthesized candidate skill being considered for install. The
|
|
36
|
+
* pre-flight builds an `InventoryEntry` for it so the existing
|
|
37
|
+
* `detectCollisions` pipeline can compare it against the user's inventory.
|
|
38
|
+
*/
|
|
39
|
+
export interface CandidateSkill {
|
|
40
|
+
/** Skill identifier post-install (e.g. `"code-helper"`). */
|
|
41
|
+
identifier: string;
|
|
42
|
+
/**
|
|
43
|
+
* Path the skill WILL occupy post-install. The pre-flight runs before
|
|
44
|
+
* the install touches disk, so this is a projected path used for
|
|
45
|
+
* suggestion-chain `authorPath` derivation. Real on-disk state is not
|
|
46
|
+
* inspected here.
|
|
47
|
+
*/
|
|
48
|
+
projectedSourcePath: string;
|
|
49
|
+
/** Optional Skillsmith manifest skillId (`<author>/<name>`). */
|
|
50
|
+
skillId?: string | null;
|
|
51
|
+
/** Optional `meta.author` slug (`anthropic`) — flows to suggestion chain. */
|
|
52
|
+
author?: string | null;
|
|
53
|
+
/** Optional `meta.tags` for the suggestion-chain tag fallback. */
|
|
54
|
+
tags?: string[];
|
|
55
|
+
/** Optional `meta.description` (round-tripped for audit-history). */
|
|
56
|
+
description?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Pack-domain hint (e.g. `codehelper`) used at chain tier 2/3. The install
|
|
59
|
+
* caller derives this from the registry response or manifest; pre-flight
|
|
60
|
+
* passes it through unchanged.
|
|
61
|
+
*/
|
|
62
|
+
packDomain?: string | null;
|
|
63
|
+
}
|
|
64
|
+
export interface RunInstallPreflightInput {
|
|
65
|
+
/** Pre-candidate snapshot of `~/.claude/{skills,commands,agents}` + CLAUDE.md. */
|
|
66
|
+
existingInventory: ReadonlyArray<InventoryEntry>;
|
|
67
|
+
/** Synthesized candidate skill being considered for install. */
|
|
68
|
+
candidate: CandidateSkill;
|
|
69
|
+
/** Resolved audit mode (`'preventative'` blocks install in caller). */
|
|
70
|
+
mode: AuditMode;
|
|
71
|
+
/** Subscription tier (drives default mode for the inner detector run). */
|
|
72
|
+
tier: Tier;
|
|
73
|
+
}
|
|
74
|
+
export interface RunInstallPreflightResult {
|
|
75
|
+
/** Non-blocking warnings (`power_user` / `governance` mode shape). */
|
|
76
|
+
warnings: NamespaceWarning[];
|
|
77
|
+
/**
|
|
78
|
+
* Blocking envelope for `preventative` mode. Populated only when at
|
|
79
|
+
* least one candidate-related collision is detected. Caller decides
|
|
80
|
+
* whether to surface it based on `mode`.
|
|
81
|
+
*/
|
|
82
|
+
pendingCollision: PendingCollision | null;
|
|
83
|
+
/**
|
|
84
|
+
* ULID written to audit history. Bubbled explicitly per Edit 7 so the
|
|
85
|
+
* install caller does not re-derive it for telemetry / ledger linkage.
|
|
86
|
+
*/
|
|
87
|
+
auditId: AuditId;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Run the install pre-flight. Pure function over `existingInventory` +
|
|
91
|
+
* `candidate`; emits an audit-history entry as a side effect so the agent's
|
|
92
|
+
* later `apply_namespace_rename` call can re-derive context via `auditId`.
|
|
93
|
+
*
|
|
94
|
+
* Failure model: any unexpected throw inside this function returns the
|
|
95
|
+
* degraded shape (`warnings: []`, `pendingCollision: null`, fresh
|
|
96
|
+
* `auditId`) — the install MUST proceed when the detector breaks (Edit 2).
|
|
97
|
+
*/
|
|
98
|
+
export declare function runInstallPreflight(input: RunInstallPreflightInput): Promise<RunInstallPreflightResult>;
|
|
99
|
+
//# sourceMappingURL=install-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-preflight.d.ts","sourceRoot":"","sources":["../../../src/audit/install-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EACV,OAAO,EAKP,cAAc,EAEf,MAAM,+BAA+B,CAAA;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAEpF,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAA;AAOzE;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,mBAAmB,EAAE,MAAM,CAAA;IAC3B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,kFAAkF;IAClF,iBAAiB,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IAChD,gEAAgE;IAChE,SAAS,EAAE,cAAc,CAAA;IACzB,uEAAuE;IACvE,IAAI,EAAE,SAAS,CAAA;IACf,0EAA0E;IAC1E,IAAI,EAAE,IAAI,CAAA;CACX;AAED,MAAM,WAAW,yBAAyB;IACxC,sEAAsE;IACtE,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B;;;;OAIG;IACH,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACzC;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAA;CACjB;AA4KD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CAgHpC"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Install pre-flight namespace check (SMI-4588 Wave 2 Step 5, PR #3).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/install-preflight
|
|
4
|
+
*
|
|
5
|
+
* Detects namespace collisions between an in-flight install candidate and
|
|
6
|
+
* the user's existing local inventory BEFORE any side effects. Returns both
|
|
7
|
+
* a non-blocking `warnings[]` shape (for `power_user` / `governance` modes)
|
|
8
|
+
* AND a blocking `pendingCollision` envelope (for `preventative` mode). The
|
|
9
|
+
* mode gate lives in the install.ts caller — this module is pure detection
|
|
10
|
+
* + suggestion generation + audit-history persistence.
|
|
11
|
+
*
|
|
12
|
+
* Plan §3 + §Step 5 + Edits 2/3/6/7.
|
|
13
|
+
*
|
|
14
|
+
* Inventory contract (Edit 7):
|
|
15
|
+
* - `existingInventory` — pre-candidate snapshot, passed to
|
|
16
|
+
* `generateSuggestionChain` (chain self-collides at tier 1 otherwise).
|
|
17
|
+
* - `augmentedInventory` — existing + the synthesized candidate, passed to
|
|
18
|
+
* `detectCollisions`. Filtering to flags involving the candidate keeps
|
|
19
|
+
* pre-existing collisions from re-surfacing on every install.
|
|
20
|
+
*
|
|
21
|
+
* Failure model (Edit 2):
|
|
22
|
+
* - Pre-flight scanner failure (ledger malformed unrecoverably, fs error,
|
|
23
|
+
* unexpected throw) is ALWAYS non-blocking. The caller treats `warnings:
|
|
24
|
+
* [], pendingCollision: null` as a degraded-but-clean pass and proceeds
|
|
25
|
+
* with the install.
|
|
26
|
+
*
|
|
27
|
+
* Edit 6 — `readLedger()` may throw `namespace.ledger.version_unsupported`.
|
|
28
|
+
* The pre-flight catches it and degrades to non-blocking; bubbling would
|
|
29
|
+
* brick installs after a ledger downgrade.
|
|
30
|
+
*/
|
|
31
|
+
import { detectCollisions } from './collision-detector.js';
|
|
32
|
+
import { newAuditId, writeAuditHistory } from './audit-history.js';
|
|
33
|
+
import { generateSuggestionChain } from './suggestion-chain.js';
|
|
34
|
+
import { runEditSuggester } from './edit-suggester.js';
|
|
35
|
+
/**
|
|
36
|
+
* Synthesize an `InventoryEntry` for the candidate skill. Mirrors the
|
|
37
|
+
* shape `scanLocalInventory` produces for `~/.claude/skills/*`.
|
|
38
|
+
*/
|
|
39
|
+
function synthesizeCandidateEntry(candidate) {
|
|
40
|
+
return {
|
|
41
|
+
kind: 'skill',
|
|
42
|
+
source_path: candidate.projectedSourcePath,
|
|
43
|
+
identifier: candidate.identifier,
|
|
44
|
+
triggerSurface: [candidate.identifier],
|
|
45
|
+
meta: {
|
|
46
|
+
author: candidate.author ?? undefined,
|
|
47
|
+
tags: candidate.tags,
|
|
48
|
+
description: candidate.description,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Filter detector flags to those that involve the candidate skill. The
|
|
54
|
+
* user has already accepted any pre-existing collisions; only newly
|
|
55
|
+
* introduced ones surface at install time.
|
|
56
|
+
*/
|
|
57
|
+
function flagInvolvesCandidate(flag, candidatePath) {
|
|
58
|
+
if (flag.kind === 'exact') {
|
|
59
|
+
return flag.entries.some((e) => e.source_path === candidatePath);
|
|
60
|
+
}
|
|
61
|
+
if (flag.kind === 'generic') {
|
|
62
|
+
return flag.entry.source_path === candidatePath;
|
|
63
|
+
}
|
|
64
|
+
// semantic
|
|
65
|
+
return flag.entryA.source_path === candidatePath || flag.entryB.source_path === candidatePath;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Find the inventory entry on the OTHER side of a flag — the entry the
|
|
69
|
+
* candidate collides with. Used when constructing `RenameSuggestion`
|
|
70
|
+
* shapes whose `entry` field points at the candidate (so the apply path
|
|
71
|
+
* mutates the candidate, not the existing entry).
|
|
72
|
+
*/
|
|
73
|
+
function candidateEntryFromFlag(flag, candidatePath) {
|
|
74
|
+
if (flag.kind === 'exact') {
|
|
75
|
+
return flag.entries.find((e) => e.source_path === candidatePath) ?? null;
|
|
76
|
+
}
|
|
77
|
+
if (flag.kind === 'generic') {
|
|
78
|
+
return flag.entry;
|
|
79
|
+
}
|
|
80
|
+
return flag.entryA.source_path === candidatePath ? flag.entryA : flag.entryB;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Pick the apply-action for the candidate based on its kind. The candidate
|
|
84
|
+
* is always synthesized as `kind: 'skill'`; this stays a switch so future
|
|
85
|
+
* candidate kinds (commands, agents added at install time) are supported.
|
|
86
|
+
*/
|
|
87
|
+
function actionForEntry(entry) {
|
|
88
|
+
switch (entry.kind) {
|
|
89
|
+
case 'command':
|
|
90
|
+
return 'rename_command_file';
|
|
91
|
+
case 'agent':
|
|
92
|
+
return 'rename_agent_file';
|
|
93
|
+
case 'skill':
|
|
94
|
+
case 'claude_md_rule':
|
|
95
|
+
default:
|
|
96
|
+
return 'rename_skill_dir_and_frontmatter';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Build a `RenameSuggestion` for the candidate, picking the first
|
|
101
|
+
* non-colliding chain candidate as `suggested`. Falls back to chain
|
|
102
|
+
* candidate[0] when all collide (the agent surfaces the chain via
|
|
103
|
+
* `pendingCollision.suggestionChain`).
|
|
104
|
+
*/
|
|
105
|
+
function buildCandidateSuggestion(args) {
|
|
106
|
+
const chain = generateSuggestionChain({
|
|
107
|
+
token: args.candidate.identifier,
|
|
108
|
+
author: args.candidate.author ?? null,
|
|
109
|
+
packDomain: args.candidate.packDomain ?? null,
|
|
110
|
+
tagFallback: args.candidate.tags?.[0] ?? null,
|
|
111
|
+
authorPath: args.candidate.projectedSourcePath,
|
|
112
|
+
existingInventory: args.existingInventory,
|
|
113
|
+
});
|
|
114
|
+
// First non-colliding candidate, or fall back to first slot when all
|
|
115
|
+
// collide (caller surfaces `chainExhausted` separately).
|
|
116
|
+
const lowercaseInventory = new Set(args.existingInventory.map((e) => e.identifier.toLowerCase()));
|
|
117
|
+
const firstFree = chain.candidates.find((c) => !lowercaseInventory.has(c.toLowerCase()));
|
|
118
|
+
const suggested = firstFree ?? chain.candidates[0] ?? args.candidate.identifier;
|
|
119
|
+
const reason = buildReason(args.flag, args.candidate.projectedSourcePath);
|
|
120
|
+
return {
|
|
121
|
+
suggestion: {
|
|
122
|
+
collisionId: args.flag.collisionId,
|
|
123
|
+
entry: args.candidateEntry,
|
|
124
|
+
currentName: args.candidate.identifier,
|
|
125
|
+
suggested,
|
|
126
|
+
applyAction: actionForEntry(args.candidateEntry),
|
|
127
|
+
reason,
|
|
128
|
+
},
|
|
129
|
+
chain: chain.candidates,
|
|
130
|
+
exhausted: chain.exhausted,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function buildReason(flag, candidatePath) {
|
|
134
|
+
if (flag.kind === 'exact') {
|
|
135
|
+
// Exclude the candidate from the rendered list so the message reads
|
|
136
|
+
// as "X collides with the existing entries", not "X collides with X
|
|
137
|
+
// and the existing entries".
|
|
138
|
+
const others = flag.entries
|
|
139
|
+
.filter((e) => e.source_path !== candidatePath)
|
|
140
|
+
.map((e) => `${e.kind}:${e.identifier}`)
|
|
141
|
+
.join(', ');
|
|
142
|
+
return `exact collision with ${others}`;
|
|
143
|
+
}
|
|
144
|
+
if (flag.kind === 'generic') {
|
|
145
|
+
return `generic-token flag (${flag.matchedTokens.join(', ')})`;
|
|
146
|
+
}
|
|
147
|
+
return `semantic overlap (cosine ${flag.cosineScore.toFixed(2)}) with ${flag.entryB.identifier}`;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Filter out the candidate skill's own prior on-disk presence from the
|
|
151
|
+
* inventory snapshot.
|
|
152
|
+
*
|
|
153
|
+
* On reinstall (`force: true`), `scanLocalInventory` returns an entry for
|
|
154
|
+
* the already-installed skill at `<projectedSourcePath>/SKILL.md`. If we
|
|
155
|
+
* left it in `existingInventory`, the augmented inventory would contain
|
|
156
|
+
* both the prior entry AND the synthesized candidate with the same
|
|
157
|
+
* `identifier`, and `detectExactCollisions` would surface a false-positive
|
|
158
|
+
* "namespace collision" that blocks reinstall in `preventative` mode.
|
|
159
|
+
*
|
|
160
|
+
* The reinstall flow is owned by `install.conflict.ts` (three-way merge,
|
|
161
|
+
* backup, force semantics). Pre-flight is for *new* namespace conflicts
|
|
162
|
+
* with *other* skills, not for the candidate's own prior copy.
|
|
163
|
+
*/
|
|
164
|
+
function excludeSelfReinstall(existing, candidate) {
|
|
165
|
+
const candidateDir = candidate.projectedSourcePath;
|
|
166
|
+
const candidateIdentifier = candidate.identifier.toLowerCase();
|
|
167
|
+
return existing.filter((entry) => {
|
|
168
|
+
if (entry.kind !== 'skill')
|
|
169
|
+
return true;
|
|
170
|
+
if (entry.identifier.toLowerCase() !== candidateIdentifier)
|
|
171
|
+
return true;
|
|
172
|
+
// Skill entries' source_path is `<dir>/SKILL.md`; match by parent dir.
|
|
173
|
+
// Also accept exact-equality for forward-compat with future synthesis
|
|
174
|
+
// shapes that may use the directory path directly.
|
|
175
|
+
if (entry.source_path === candidateDir)
|
|
176
|
+
return false;
|
|
177
|
+
if (entry.source_path.startsWith(`${candidateDir}/`))
|
|
178
|
+
return false;
|
|
179
|
+
return true;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Run the install pre-flight. Pure function over `existingInventory` +
|
|
184
|
+
* `candidate`; emits an audit-history entry as a side effect so the agent's
|
|
185
|
+
* later `apply_namespace_rename` call can re-derive context via `auditId`.
|
|
186
|
+
*
|
|
187
|
+
* Failure model: any unexpected throw inside this function returns the
|
|
188
|
+
* degraded shape (`warnings: []`, `pendingCollision: null`, fresh
|
|
189
|
+
* `auditId`) — the install MUST proceed when the detector breaks (Edit 2).
|
|
190
|
+
*/
|
|
191
|
+
export async function runInstallPreflight(input) {
|
|
192
|
+
const { existingInventory, candidate, mode, tier } = input;
|
|
193
|
+
// Allocate the audit id up front so the degraded path returns a valid
|
|
194
|
+
// ULID even when the inner detector throws before producing a result.
|
|
195
|
+
const auditId = newAuditId();
|
|
196
|
+
let inventoryWithoutSelf;
|
|
197
|
+
let augmentedInventory;
|
|
198
|
+
let result;
|
|
199
|
+
try {
|
|
200
|
+
// Exclude the candidate's own prior on-disk copy (reinstall) so the
|
|
201
|
+
// detector doesn't surface it as a namespace collision against itself.
|
|
202
|
+
inventoryWithoutSelf = excludeSelfReinstall(existingInventory, candidate);
|
|
203
|
+
const candidateEntry = synthesizeCandidateEntry(candidate);
|
|
204
|
+
augmentedInventory = [...inventoryWithoutSelf, candidateEntry];
|
|
205
|
+
result = await detectCollisions(augmentedInventory, {
|
|
206
|
+
auditId,
|
|
207
|
+
tier,
|
|
208
|
+
auditModeOverride: mode,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
// Edit 2: pre-flight failure is always non-blocking. Log + degrade.
|
|
213
|
+
// The catch covers `excludeSelfReinstall` (rejects non-iterable
|
|
214
|
+
// inputs), `synthesizeCandidateEntry`, the spread, AND
|
|
215
|
+
// `detectCollisions`. Any pre-flight failure → install proceeds.
|
|
216
|
+
console.warn(`[install-preflight] detector failed (${err.message}); degrading to non-blocking pass`);
|
|
217
|
+
return { warnings: [], pendingCollision: null, auditId };
|
|
218
|
+
}
|
|
219
|
+
// Filter to flags involving the candidate. Pre-existing collisions are
|
|
220
|
+
// out of scope at install time.
|
|
221
|
+
const allFlags = [
|
|
222
|
+
...result.exactCollisions,
|
|
223
|
+
...result.genericFlags,
|
|
224
|
+
...result.semanticCollisions,
|
|
225
|
+
];
|
|
226
|
+
const candidateFlags = allFlags.filter((f) => flagInvolvesCandidate(f, candidate.projectedSourcePath));
|
|
227
|
+
if (candidateFlags.length === 0) {
|
|
228
|
+
// Clean candidate. Persist the audit history (zero-flag run) so the
|
|
229
|
+
// agent's later inspection by auditId still resolves; absence of an
|
|
230
|
+
// audit file would be ambiguous.
|
|
231
|
+
await tryWriteAuditHistory(result);
|
|
232
|
+
return { warnings: [], pendingCollision: null, auditId };
|
|
233
|
+
}
|
|
234
|
+
// SMI-4589 Wave 3: run the edit-suggester over the audit result (which
|
|
235
|
+
// already contains the candidate-augmented inventory). We attach the
|
|
236
|
+
// matching edit to each semantic NamespaceWarning by collisionId. Edge
|
|
237
|
+
// cases:
|
|
238
|
+
// - Edit-suggester throws → log + degrade to no edits (preserves the
|
|
239
|
+
// non-blocking install contract per Wave 2 Edit 2). Failure of the
|
|
240
|
+
// edit surface MUST NOT brick the install pre-flight.
|
|
241
|
+
// - Non-semantic warnings (`exact`, `generic`) never carry a
|
|
242
|
+
// recommendedEdit — the suggester only runs over semanticCollisions.
|
|
243
|
+
const editsByCollisionId = await collectRecommendedEdits(result);
|
|
244
|
+
// Build a NamespaceWarning + suggestion-chain for each candidate-related
|
|
245
|
+
// flag. We surface the first flag's chain in `pendingCollision` (the
|
|
246
|
+
// dominant collision); all flags surface in `warnings[]`.
|
|
247
|
+
const warnings = [];
|
|
248
|
+
let pendingCollision = null;
|
|
249
|
+
for (let i = 0; i < candidateFlags.length; i++) {
|
|
250
|
+
const flag = candidateFlags[i];
|
|
251
|
+
const candidateEntry = candidateEntryFromFlag(flag, candidate.projectedSourcePath);
|
|
252
|
+
if (!candidateEntry)
|
|
253
|
+
continue;
|
|
254
|
+
const built = buildCandidateSuggestion({
|
|
255
|
+
flag,
|
|
256
|
+
candidate,
|
|
257
|
+
candidateEntry,
|
|
258
|
+
// Pass the self-excluded snapshot so the chain doesn't treat the
|
|
259
|
+
// candidate's own prior install (during a force-reinstall) as a
|
|
260
|
+
// colliding entry — that would force `chainExhausted: true` on
|
|
261
|
+
// every reinstall.
|
|
262
|
+
existingInventory: inventoryWithoutSelf,
|
|
263
|
+
});
|
|
264
|
+
const recommendedEdit = editsByCollisionId.get(flag.collisionId);
|
|
265
|
+
warnings.push({
|
|
266
|
+
collisionId: flag.collisionId,
|
|
267
|
+
kind: flag.kind,
|
|
268
|
+
severity: 'warning',
|
|
269
|
+
message: buildWarningMessage(flag, candidate, built.suggestion.suggested),
|
|
270
|
+
suggestion: built.suggestion,
|
|
271
|
+
auditId,
|
|
272
|
+
recommendedEdit,
|
|
273
|
+
});
|
|
274
|
+
// First candidate-flag becomes the pendingCollision envelope.
|
|
275
|
+
if (i === 0) {
|
|
276
|
+
pendingCollision = {
|
|
277
|
+
auditId,
|
|
278
|
+
suggestedRename: built.suggestion,
|
|
279
|
+
suggestionChain: built.chain,
|
|
280
|
+
chainExhausted: built.exhausted,
|
|
281
|
+
remediationHint: "call apply_namespace_rename({ auditId, action: 'apply' }) then re-invoke install_skill",
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
await tryWriteAuditHistory(result);
|
|
286
|
+
return { warnings, pendingCollision, auditId };
|
|
287
|
+
}
|
|
288
|
+
function buildWarningMessage(flag, candidate, suggested) {
|
|
289
|
+
const reason = buildReason(flag, candidate.projectedSourcePath);
|
|
290
|
+
return `Namespace ${flag.kind} collision installing "${candidate.identifier}": ${reason}. Suggested rename: "${suggested}".`;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* SMI-4589 Wave 3: collect recommended edits indexed by collisionId.
|
|
294
|
+
* Edit-suggester failure degrades silently to an empty map — the
|
|
295
|
+
* non-blocking install contract from Wave 2 Edit 2 extends here.
|
|
296
|
+
*/
|
|
297
|
+
async function collectRecommendedEdits(result) {
|
|
298
|
+
try {
|
|
299
|
+
const recommendedEdits = await runEditSuggester(result);
|
|
300
|
+
return new Map(recommendedEdits.map((e) => [e.collisionId, e]));
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
console.warn(`[install-preflight] edit-suggester failed (${err.message}); proceeding without prose edits`);
|
|
304
|
+
return new Map();
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Persist the audit history. Errors here are logged + swallowed — pre-flight
|
|
309
|
+
* is non-blocking (Edit 2), and a missing audit file degrades the agent's
|
|
310
|
+
* later `apply_namespace_rename` lookup but does not break install.
|
|
311
|
+
*/
|
|
312
|
+
async function tryWriteAuditHistory(result) {
|
|
313
|
+
try {
|
|
314
|
+
await writeAuditHistory(result);
|
|
315
|
+
}
|
|
316
|
+
catch (err) {
|
|
317
|
+
console.warn(`[install-preflight] writeAuditHistory failed (${err.message}); auditId will be unrecoverable but install proceeds`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=install-preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-preflight.js","sourceRoot":"","sources":["../../../src/audit/install-preflight.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared namespace-audit type vocabulary (SMI-4588 Wave 2 Step 1, PR #1).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/namespace-audit.types
|
|
4
|
+
*
|
|
5
|
+
* `NamespaceWarning` and `PendingCollision` live here — not in
|
|
6
|
+
* `tools/install.types.ts` and not in `audit/install-preflight.ts` — to break
|
|
7
|
+
* the `tools → audit → tools` cycle that would otherwise form between
|
|
8
|
+
* `install-preflight.ts` (which constructs them) and `install.types.ts`
|
|
9
|
+
* (which embeds them in `InstallResult`). The shared file is depended on by
|
|
10
|
+
* both sides; neither side depends on the other.
|
|
11
|
+
*
|
|
12
|
+
* Wave 2 plan §4 + Edit 3 — placed in Step 1 so PRs #3/#4 import without
|
|
13
|
+
* rework.
|
|
14
|
+
*
|
|
15
|
+
* `RenameSuggestion` is imported from `./rename-engine.types.js` (PR #2). The
|
|
16
|
+
* PR #1 forward-declaration shim has been retired now that the canonical
|
|
17
|
+
* type ships alongside the rename engine.
|
|
18
|
+
*/
|
|
19
|
+
import type { CollisionId } from './collision-detector.types.js';
|
|
20
|
+
import type { RenameSuggestion } from './rename-engine.types.js';
|
|
21
|
+
import type { RecommendedEdit } from './edit-suggester.types.js';
|
|
22
|
+
/**
|
|
23
|
+
* A non-blocking namespace collision surfaced by the install pre-flight
|
|
24
|
+
* (Wave 2 PR #3). `power_user` and `governance` modes return one of these
|
|
25
|
+
* per detected collision in `InstallResult.warnings[]`; the agent surfaces
|
|
26
|
+
* the suggestion to the user but the install still proceeds.
|
|
27
|
+
*/
|
|
28
|
+
export interface NamespaceWarning {
|
|
29
|
+
/** Stable across audit runs — derived via `deriveCollisionId`. */
|
|
30
|
+
collisionId: CollisionId;
|
|
31
|
+
/** Matches the source collision flag's `kind`. */
|
|
32
|
+
kind: 'exact' | 'generic' | 'semantic';
|
|
33
|
+
/** Always `'warning'` — `NamespaceWarning` never blocks install. */
|
|
34
|
+
severity: 'warning';
|
|
35
|
+
/** User-facing message (rendered verbatim to the agent). */
|
|
36
|
+
message: string;
|
|
37
|
+
/**
|
|
38
|
+
* Suggested rename for the agent to surface. Constructed by
|
|
39
|
+
* `generateRenameSuggestions` (Wave 2 PR #2). Walking the suggestion
|
|
40
|
+
* chain is the agent's job — `suggestion` is the first non-colliding
|
|
41
|
+
* candidate.
|
|
42
|
+
*/
|
|
43
|
+
suggestion: RenameSuggestion;
|
|
44
|
+
/**
|
|
45
|
+
* FK to the audit history written by `runInstallPreflight` (PR #3). Lets
|
|
46
|
+
* a later `apply_namespace_rename` call (Wave 4) re-read the original
|
|
47
|
+
* suggestion without re-running detection.
|
|
48
|
+
*/
|
|
49
|
+
auditId: string;
|
|
50
|
+
/**
|
|
51
|
+
* SMI-4589 Wave 3: optional prose-edit recommendation surfaced for
|
|
52
|
+
* `description_overlap` semantic collisions. The agent surfaces the
|
|
53
|
+
* `RecommendedEdit` alongside the rename suggestion; rename may not
|
|
54
|
+
* be the right remediation when descriptions semantically overlap.
|
|
55
|
+
*
|
|
56
|
+
* Per the per-template gate ratified 2026-05-01, only
|
|
57
|
+
* `add_domain_qualifier`-pattern edits populate this field in v1.
|
|
58
|
+
* `kind: 'exact'` and `kind: 'generic'` warnings never carry a
|
|
59
|
+
* recommended edit (they're text-identifier collisions, not prose).
|
|
60
|
+
*/
|
|
61
|
+
recommendedEdit?: RecommendedEdit;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Blocking-mode envelope for `audit_mode: 'preventative'` installs (Wave 2
|
|
65
|
+
* PR #3, decision #2). When pre-flight detects a collision, `install_skill`
|
|
66
|
+
* returns `installComplete: false` plus this envelope. The agent calls
|
|
67
|
+
* `apply_namespace_rename({ auditId, action: 'apply' })` (Wave 4) and then
|
|
68
|
+
* re-invokes `install_skill`.
|
|
69
|
+
*
|
|
70
|
+
* The `suggestionChain[]` carries up to 3 ordered candidates per
|
|
71
|
+
* decision #11; the agent walks the chain and picks the first non-colliding
|
|
72
|
+
* one. `chainExhausted` is `true` when all 3 collide and the agent must
|
|
73
|
+
* escalate to the human via `customName`.
|
|
74
|
+
*/
|
|
75
|
+
export interface PendingCollision {
|
|
76
|
+
/** ULID — passed back to `apply_namespace_rename`. */
|
|
77
|
+
auditId: string;
|
|
78
|
+
/**
|
|
79
|
+
* First non-colliding candidate from `generateSuggestionChain`. The agent
|
|
80
|
+
* surfaces this to the user as the recommended rename.
|
|
81
|
+
*/
|
|
82
|
+
suggestedRename: RenameSuggestion;
|
|
83
|
+
/**
|
|
84
|
+
* Up to 3 candidates from `generateSuggestionChain` (decision #11). The
|
|
85
|
+
* agent has the full chain so it can present alternatives without
|
|
86
|
+
* re-querying.
|
|
87
|
+
*/
|
|
88
|
+
suggestionChain: string[];
|
|
89
|
+
/**
|
|
90
|
+
* `true` when all 3 chain candidates collide. The agent must escalate to
|
|
91
|
+
* the human and call `apply_namespace_rename({ customName: '…' })`.
|
|
92
|
+
*/
|
|
93
|
+
chainExhausted: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Human-readable remediation hint, e.g.
|
|
96
|
+
* `"call apply_namespace_rename({ auditId, action: 'apply' }) then re-invoke install_skill"`.
|
|
97
|
+
*/
|
|
98
|
+
remediationHint: string;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=namespace-audit.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-audit.types.d.ts","sourceRoot":"","sources":["../../../src/audit/namespace-audit.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAMhE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,WAAW,EAAE,WAAW,CAAA;IACxB,kDAAkD;IAClD,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;IACtC,oEAAoE;IACpE,QAAQ,EAAE,SAAS,CAAA;IACnB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAA;IACf;;;;;OAKG;IACH,UAAU,EAAE,gBAAgB,CAAA;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,eAAe,EAAE,gBAAgB,CAAA;IACjC;;;;OAIG;IACH,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAA;IACvB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAA;CACxB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared namespace-audit type vocabulary (SMI-4588 Wave 2 Step 1, PR #1).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/namespace-audit.types
|
|
4
|
+
*
|
|
5
|
+
* `NamespaceWarning` and `PendingCollision` live here — not in
|
|
6
|
+
* `tools/install.types.ts` and not in `audit/install-preflight.ts` — to break
|
|
7
|
+
* the `tools → audit → tools` cycle that would otherwise form between
|
|
8
|
+
* `install-preflight.ts` (which constructs them) and `install.types.ts`
|
|
9
|
+
* (which embeds them in `InstallResult`). The shared file is depended on by
|
|
10
|
+
* both sides; neither side depends on the other.
|
|
11
|
+
*
|
|
12
|
+
* Wave 2 plan §4 + Edit 3 — placed in Step 1 so PRs #3/#4 import without
|
|
13
|
+
* rework.
|
|
14
|
+
*
|
|
15
|
+
* `RenameSuggestion` is imported from `./rename-engine.types.js` (PR #2). The
|
|
16
|
+
* PR #1 forward-declaration shim has been retired now that the canonical
|
|
17
|
+
* type ships alongside the rename engine.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=namespace-audit.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-audit.types.js","sourceRoot":"","sources":["../../../src/audit/namespace-audit.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Atomic reader/writer for the namespace-overrides ledger
|
|
3
|
+
* (SMI-4588 Wave 2 Step 1, PR #1).
|
|
4
|
+
* @module @skillsmith/mcp-server/audit/namespace-overrides
|
|
5
|
+
*
|
|
6
|
+
* Persists `~/.skillsmith/namespace-overrides.json` — the load-bearing
|
|
7
|
+
* artifact that makes consumer-side namespace renames durable across pack
|
|
8
|
+
* version bumps. Conceptually equivalent to git's `rerere` but for
|
|
9
|
+
* namespace identifiers.
|
|
10
|
+
*
|
|
11
|
+
* Atomicity: every write goes through `<path>.tmp` + `fs.rename`. On read,
|
|
12
|
+
* a missing file degrades gracefully to an empty ledger; malformed JSON
|
|
13
|
+
* surfaces as a typed `namespace.ledger.malformed` discriminator (the
|
|
14
|
+
* caller decides whether to log + reset, never silently). A
|
|
15
|
+
* higher-than-supported `version` returns
|
|
16
|
+
* `namespace.ledger.version_unsupported` rather than a silent empty
|
|
17
|
+
* ledger — see plan §2 Edit 6.
|
|
18
|
+
*
|
|
19
|
+
* Concurrent-write boundary: last-write-wins on a single Node event loop
|
|
20
|
+
* via `<path>.tmp` + `fs.rename`. Multi-process scenarios (two MCP
|
|
21
|
+
* instances on the same machine) can lose one write under a tight race;
|
|
22
|
+
* documented as a known limitation in the plan. If multi-process safety
|
|
23
|
+
* becomes load-bearing, a future revision adds advisory locking via
|
|
24
|
+
* `proper-lockfile`.
|
|
25
|
+
*/
|
|
26
|
+
import { type OverrideRecord, type OverridesLedger, type ReadLedgerResult } from './namespace-overrides.types.js';
|
|
27
|
+
export interface LedgerPathOptions {
|
|
28
|
+
/** Override the ledger path (default `~/.skillsmith/namespace-overrides.json`). */
|
|
29
|
+
ledgerPath?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Read the ledger from disk and return a tagged union. Missing file →
|
|
33
|
+
* `{ kind: 'ok', ledger: <empty> }`. Malformed JSON →
|
|
34
|
+
* `{ kind: 'namespace.ledger.malformed', reason }`. `version > CURRENT_VERSION`
|
|
35
|
+
* → `{ kind: 'namespace.ledger.version_unsupported', found, expected }`.
|
|
36
|
+
*
|
|
37
|
+
* Callers that want the simpler "read or empty" semantics should use
|
|
38
|
+
* `readLedger()` (below) which collapses the discriminator.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readLedgerResult(opts?: LedgerPathOptions): Promise<ReadLedgerResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Convenience wrapper: returns the ledger directly, collapsing the
|
|
43
|
+
* `malformed` branch to an empty ledger plus a `console.warn`. Higher-
|
|
44
|
+
* version files still bubble a thrown error — silently empty-ing a
|
|
45
|
+
* higher-version ledger would corrupt forward-compat (plan §2 Edit 6).
|
|
46
|
+
*
|
|
47
|
+
* For callers that need the typed discriminator, use `readLedgerResult`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function readLedger(opts?: LedgerPathOptions): Promise<OverridesLedger>;
|
|
50
|
+
/**
|
|
51
|
+
* Write the ledger atomically: `<path>.tmp` + `fs.rename`. Creates the
|
|
52
|
+
* parent directory on first run with `recursive: true` (mirrors
|
|
53
|
+
* audit-history.ts E-MISS-2 fix).
|
|
54
|
+
*/
|
|
55
|
+
export declare function writeLedger(ledger: OverridesLedger, opts?: LedgerPathOptions): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Pure helper: append a new override to a ledger and return a new copy.
|
|
58
|
+
* Original ledger is not mutated. The caller is responsible for
|
|
59
|
+
* persisting the result via `writeLedger` (separation of concerns —
|
|
60
|
+
* tests can build ledgers without touching disk).
|
|
61
|
+
*
|
|
62
|
+
* Idempotency: if an override with the same
|
|
63
|
+
* `(skillId, kind, originalIdentifier, renamedTo)` quadruple already
|
|
64
|
+
* exists, the input is returned unchanged. The caller can detect the
|
|
65
|
+
* no-op by reference equality (`appended === ledger`).
|
|
66
|
+
*/
|
|
67
|
+
export declare function appendOverride(ledger: OverridesLedger, override: Omit<OverrideRecord, 'id' | 'appliedAt'>): OverridesLedger;
|
|
68
|
+
/**
|
|
69
|
+
* Pure lookup: find an override by `(skillId, kind, originalIdentifier)`.
|
|
70
|
+
* `skillId` may be omitted for local/unregistered artifacts; in that case
|
|
71
|
+
* only `kind` + `originalIdentifier` are matched. Returns the first match
|
|
72
|
+
* or `null`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function findOverride(ledger: OverridesLedger, query: {
|
|
75
|
+
skillId?: string | null;
|
|
76
|
+
kind?: OverrideRecord['kind'];
|
|
77
|
+
originalIdentifier: string;
|
|
78
|
+
}): OverrideRecord | null;
|
|
79
|
+
//# sourceMappingURL=namespace-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace-overrides.d.ts","sourceRoot":"","sources":["../../../src/audit/namespace-overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AASH,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,gCAAgC,CAAA;AAgBvC,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAUD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6D9F;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CA0BvF;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,eAAe,EACvB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,WAAW,CAAC,GACjD,eAAe,CAkBjB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,GAC5F,cAAc,GAAG,IAAI,CAQvB"}
|