@skillsmith/mcp-server 0.4.13 → 0.5.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 +32 -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 +1 -1
- 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/compliance-tools.service.test.js +6 -4
- package/dist/src/tools/compliance-tools.service.test.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 +162 -7
- 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 +71 -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/search.d.ts +2 -2
- 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 +10 -1
- 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/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/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 +2 -2
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Edit-suggester core (SMI-4589 Wave 3 Steps 2-3).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/edit-suggester
|
|
4
|
+
*
|
|
5
|
+
* Takes the semantic-collision flags from Wave 1's `InventoryAuditResult`
|
|
6
|
+
* and produces `RecommendedEdit[]` — templated, deterministic prose-edit
|
|
7
|
+
* suggestions. No LLM calls. No fuzziness.
|
|
8
|
+
*
|
|
9
|
+
* Per-template gate (ratified 2026-05-01): v1 ships only
|
|
10
|
+
* `add_domain_qualifier` (4.10/5 from GPT-5.4 reviewer-#2 scoring). The
|
|
11
|
+
* other two templates (`narrow_scope` 1.70/5, `reword_trigger_verb`
|
|
12
|
+
* 2.35/5) FAILED the gate and are NOT shipped in any form — neither as
|
|
13
|
+
* auto-apply nor as `manual_review`. They route to SMI-4593 for
|
|
14
|
+
* reauthoring. Test cases 2-3 in `edit-suggester.test.ts` assert empty
|
|
15
|
+
* output for collisions that would have matched those failing templates,
|
|
16
|
+
* guarding against accidental re-registration before the gate clears.
|
|
17
|
+
*
|
|
18
|
+
* Dispatch pattern (plan §1):
|
|
19
|
+
* 1. Walk `result.semanticCollisions[]`, collect unique file paths
|
|
20
|
+
* across the surviving template's `applies()` checks.
|
|
21
|
+
* 2. `await Promise.all(uniqueFilePaths.map(fs.readFile))` — single
|
|
22
|
+
* parallel read phase. Latency budget is linear in unique-files,
|
|
23
|
+
* not templates × collisions.
|
|
24
|
+
* 3. Iterate flags; for each, walk templates pre-sorted by descending
|
|
25
|
+
* `priority`; first `applies()` true wins; `generate()` is
|
|
26
|
+
* synchronous over the cached `fileContent`.
|
|
27
|
+
* 4. Filter null results (template matched but generate() couldn't
|
|
28
|
+
* synthesize a valid edit — e.g. file content drifted).
|
|
29
|
+
*
|
|
30
|
+
* Plan: docs/internal/implementation/smi-4589-edit-suggester.md §1, §Steps 2-3.
|
|
31
|
+
*/
|
|
32
|
+
import * as fs from 'node:fs/promises';
|
|
33
|
+
/**
|
|
34
|
+
* `add_domain_qualifier` template. Fires for `description_overlap` flags
|
|
35
|
+
* where one entry has a `meta.tags[0]` value the other lacks. Inserts
|
|
36
|
+
* `for <tag> tasks` after the trigger verb in the description, narrowing
|
|
37
|
+
* the trigger surface enough to differentiate from the partner.
|
|
38
|
+
*
|
|
39
|
+
* Per-template gate verdict 2026-05-01: 4.10/5 (GPT-5.4 reviewer-#2).
|
|
40
|
+
* PASS — registered in `APPLY_TEMPLATE_REGISTRY`.
|
|
41
|
+
*/
|
|
42
|
+
const ADD_DOMAIN_QUALIFIER = {
|
|
43
|
+
category: 'description_overlap',
|
|
44
|
+
pattern: 'add_domain_qualifier',
|
|
45
|
+
priority: 100,
|
|
46
|
+
applies(flag) {
|
|
47
|
+
// Both entries must carry a description (the prose surface we mutate),
|
|
48
|
+
// and at least one entry must have a unique tag the other lacks (the
|
|
49
|
+
// qualifier text we insert). The tag-asymmetry check is the
|
|
50
|
+
// distinguishing feature of `add_domain_qualifier` versus a hypothetical
|
|
51
|
+
// `narrow_scope` template — same shape but different remediation.
|
|
52
|
+
const aTag = pickQualifierTag(flag.entryA, flag.entryB);
|
|
53
|
+
const bTag = pickQualifierTag(flag.entryB, flag.entryA);
|
|
54
|
+
if (aTag === null && bTag === null)
|
|
55
|
+
return false;
|
|
56
|
+
if (!flag.entryA.meta?.description && !flag.entryB.meta?.description) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
},
|
|
61
|
+
generate(flag, context) {
|
|
62
|
+
// Pick the entry on whose file we'll mutate. Prefer the one with a
|
|
63
|
+
// unique tag (the qualifier text comes from that tag). If both have
|
|
64
|
+
// unique tags, prefer entryA — deterministic by `applies()` ordering.
|
|
65
|
+
const aTag = pickQualifierTag(flag.entryA, flag.entryB);
|
|
66
|
+
const target = aTag !== null ? { entry: flag.entryA, tag: aTag, partner: flag.entryB } : null;
|
|
67
|
+
const fallback = target !== null
|
|
68
|
+
? target
|
|
69
|
+
: (() => {
|
|
70
|
+
const bTag = pickQualifierTag(flag.entryB, flag.entryA);
|
|
71
|
+
return bTag !== null ? { entry: flag.entryB, tag: bTag, partner: flag.entryA } : null;
|
|
72
|
+
})();
|
|
73
|
+
if (!fallback)
|
|
74
|
+
return null;
|
|
75
|
+
const description = fallback.entry.meta?.description;
|
|
76
|
+
if (!description)
|
|
77
|
+
return null;
|
|
78
|
+
// Locate the description block in the file. Skill SKILL.md uses YAML
|
|
79
|
+
// frontmatter with a `description:` key; we match the description text
|
|
80
|
+
// verbatim and identify the line range it spans. Multi-line block-scalar
|
|
81
|
+
// descriptions are handled by line-range expansion (start = first line,
|
|
82
|
+
// end = last line whose trimmed text appears in the description).
|
|
83
|
+
const located = locateDescription(context.fileContent, description);
|
|
84
|
+
if (!located)
|
|
85
|
+
return null;
|
|
86
|
+
// Compose the after-snippet by injecting `for <tag> tasks` after the
|
|
87
|
+
// first trigger verb in the description. The trigger verb is the first
|
|
88
|
+
// word matching /^(use|trigger|run|when|whenever|invoke)/i; if none
|
|
89
|
+
// matches, we prepend `for <tag> tasks: ` to the description body
|
|
90
|
+
// instead. Either way the edit is deterministic.
|
|
91
|
+
const after = injectQualifier(located.snippet, fallback.tag);
|
|
92
|
+
if (after === null || after === located.snippet) {
|
|
93
|
+
// Snippet didn't change — would emit a no-op edit. Skip.
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const cosine = flag.cosineScore.toFixed(2);
|
|
97
|
+
const rationale = `differentiates from \`${fallback.partner.identifier}\` (cosine ${cosine}) by inserting domain qualifier "for ${fallback.tag} tasks"`;
|
|
98
|
+
return {
|
|
99
|
+
collisionId: flag.collisionId,
|
|
100
|
+
category: 'description_overlap',
|
|
101
|
+
pattern: 'add_domain_qualifier',
|
|
102
|
+
filePath: fallback.entry.source_path,
|
|
103
|
+
lineRange: { start: located.startLine, end: located.endLine },
|
|
104
|
+
before: located.snippet,
|
|
105
|
+
after,
|
|
106
|
+
rationale,
|
|
107
|
+
applyAction: 'recommended_edit',
|
|
108
|
+
// Per-template gate cleared: ships at apply_with_confirmation.
|
|
109
|
+
applyMode: 'apply_with_confirmation',
|
|
110
|
+
otherEntry: {
|
|
111
|
+
identifier: fallback.partner.identifier,
|
|
112
|
+
sourcePath: fallback.partner.source_path,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Registry of templates that ship in v1. Pre-sorted by descending
|
|
119
|
+
* priority. The dispatcher walks this list per flag.
|
|
120
|
+
*
|
|
121
|
+
* Wave 3 ships a single template (`add_domain_qualifier`). SMI-4593
|
|
122
|
+
* reauthors `narrow_scope` and `reword_trigger_verb` and re-registers
|
|
123
|
+
* them upon clearing the per-template gate.
|
|
124
|
+
*/
|
|
125
|
+
const V1_TEMPLATES = [ADD_DOMAIN_QUALIFIER];
|
|
126
|
+
/**
|
|
127
|
+
* Run the edit-suggester over an `InventoryAuditResult`'s semantic
|
|
128
|
+
* collisions. Returns `RecommendedEdit[]` — one per flag that matches a
|
|
129
|
+
* registered template AND whose template successfully synthesized a
|
|
130
|
+
* non-empty edit.
|
|
131
|
+
*
|
|
132
|
+
* Order of returned edits: same as `result.semanticCollisions[]` input
|
|
133
|
+
* order. Tests assert this stability so PR diffs in the audit-report
|
|
134
|
+
* markdown are deterministic.
|
|
135
|
+
*
|
|
136
|
+
* I/O: reads each unique referenced file ONCE, in parallel, before
|
|
137
|
+
* iterating templates. Templates see only `fileContent` strings, not
|
|
138
|
+
* paths — keeps templates pure and unit-testable without fixtures on
|
|
139
|
+
* disk.
|
|
140
|
+
*
|
|
141
|
+
* Failure model: any per-flag template error (fileRead failure, snippet
|
|
142
|
+
* locate failure, `generate()` returning null) skips that flag silently.
|
|
143
|
+
* The other flags still produce edits. An empty
|
|
144
|
+
* `result.semanticCollisions[]` short-circuits with no I/O.
|
|
145
|
+
*/
|
|
146
|
+
export async function runEditSuggester(result, opts) {
|
|
147
|
+
if (result.semanticCollisions.length === 0)
|
|
148
|
+
return [];
|
|
149
|
+
const templates = sortByPriority(opts?.templateOverrides ?? V1_TEMPLATES);
|
|
150
|
+
if (templates.length === 0)
|
|
151
|
+
return [];
|
|
152
|
+
// Phase 1: collect unique file paths referenced by any flag whose
|
|
153
|
+
// partner-pair would feed into a template's `applies()`.
|
|
154
|
+
const uniquePaths = new Set();
|
|
155
|
+
for (const flag of result.semanticCollisions) {
|
|
156
|
+
uniquePaths.add(flag.entryA.source_path);
|
|
157
|
+
uniquePaths.add(flag.entryB.source_path);
|
|
158
|
+
}
|
|
159
|
+
// Phase 2: parallel reads. Failed reads degrade to `null` content; the
|
|
160
|
+
// template will return null when it can't locate the description.
|
|
161
|
+
const fileCache = new Map();
|
|
162
|
+
await Promise.all(Array.from(uniquePaths).map(async (filePath) => {
|
|
163
|
+
try {
|
|
164
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
165
|
+
fileCache.set(filePath, content);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
// Soft-warn; per plan §Tests case 9 a missing file emits no edit.
|
|
169
|
+
console.warn(`[edit-suggester] read failed for ${filePath} (${err.message}); skipping flags that target it`);
|
|
170
|
+
fileCache.set(filePath, null);
|
|
171
|
+
}
|
|
172
|
+
}));
|
|
173
|
+
// Phase 3: iterate flags, dispatch to templates synchronously over
|
|
174
|
+
// cached content.
|
|
175
|
+
const edits = [];
|
|
176
|
+
for (const flag of result.semanticCollisions) {
|
|
177
|
+
const template = templates.find((t) => t.applies(flag));
|
|
178
|
+
if (!template)
|
|
179
|
+
continue;
|
|
180
|
+
// Templates target one of the two entries' files. We let `generate()`
|
|
181
|
+
// pick which (it has the asymmetry logic). For now, hand it whichever
|
|
182
|
+
// entry's file content is available — `generate()` will return null
|
|
183
|
+
// if it needed the other side. We pick entryA's content first since
|
|
184
|
+
// `add_domain_qualifier`'s `generate` prefers entryA when both have
|
|
185
|
+
// unique tags.
|
|
186
|
+
const aContent = fileCache.get(flag.entryA.source_path);
|
|
187
|
+
const bContent = fileCache.get(flag.entryB.source_path);
|
|
188
|
+
const candidates = [aContent ?? null, bContent ?? null];
|
|
189
|
+
let edit = null;
|
|
190
|
+
for (const content of candidates) {
|
|
191
|
+
if (!content)
|
|
192
|
+
continue;
|
|
193
|
+
const generated = template.generate(flag, { fileContent: content });
|
|
194
|
+
if (generated) {
|
|
195
|
+
edit = generated;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (edit)
|
|
200
|
+
edits.push(edit);
|
|
201
|
+
}
|
|
202
|
+
return edits;
|
|
203
|
+
}
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// Template helpers (kept inline; ~150-LOC budget for this file)
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
/**
|
|
208
|
+
* Stable-sort templates by descending priority. Stable to preserve
|
|
209
|
+
* registration order on ties.
|
|
210
|
+
*/
|
|
211
|
+
function sortByPriority(templates) {
|
|
212
|
+
return [...templates].sort((a, b) => b.priority - a.priority);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Pick the first tag from `entry` that does NOT appear in `partner.meta.tags`.
|
|
216
|
+
* Returns `null` if `entry` has no tags or all tags overlap.
|
|
217
|
+
*/
|
|
218
|
+
function pickQualifierTag(entry, partner) {
|
|
219
|
+
const ours = entry.meta?.tags ?? [];
|
|
220
|
+
const theirs = new Set(partner.meta?.tags ?? []);
|
|
221
|
+
for (const tag of ours) {
|
|
222
|
+
if (typeof tag !== 'string')
|
|
223
|
+
continue;
|
|
224
|
+
const trimmed = tag.trim();
|
|
225
|
+
if (!trimmed)
|
|
226
|
+
continue;
|
|
227
|
+
if (!theirs.has(trimmed))
|
|
228
|
+
return trimmed;
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Locate the `description` text block within `fileContent`. Returns the
|
|
234
|
+
* matched snippet plus 1-indexed inclusive line range, or `null` if the
|
|
235
|
+
* description cannot be located (file content drifted since scan time).
|
|
236
|
+
*
|
|
237
|
+
* Strategy: split the description into lines (trimmed), then scan
|
|
238
|
+
* fileContent line-by-line for the first line that matches the first
|
|
239
|
+
* description line. Once anchored, walk forward to confirm subsequent
|
|
240
|
+
* description lines match in order. Returns the byte-exact snippet from
|
|
241
|
+
* the original file (preserves leading whitespace, comments, etc.).
|
|
242
|
+
*/
|
|
243
|
+
function locateDescription(fileContent, description) {
|
|
244
|
+
const fileLines = fileContent.split('\n');
|
|
245
|
+
const descLines = description
|
|
246
|
+
.split('\n')
|
|
247
|
+
.map((l) => l.trim())
|
|
248
|
+
.filter((l) => l.length > 0);
|
|
249
|
+
if (descLines.length === 0)
|
|
250
|
+
return null;
|
|
251
|
+
for (let i = 0; i < fileLines.length; i++) {
|
|
252
|
+
const fileLine = fileLines[i]?.trim() ?? '';
|
|
253
|
+
if (!fileLine.includes(descLines[0]))
|
|
254
|
+
continue;
|
|
255
|
+
// Try to match all description lines in order from this anchor.
|
|
256
|
+
let cursor = i;
|
|
257
|
+
let matched = true;
|
|
258
|
+
for (let j = 0; j < descLines.length; j++) {
|
|
259
|
+
// Walk forward; allow blank lines between description fragments.
|
|
260
|
+
while (cursor < fileLines.length) {
|
|
261
|
+
const candidate = fileLines[cursor]?.trim() ?? '';
|
|
262
|
+
if (candidate.includes(descLines[j]))
|
|
263
|
+
break;
|
|
264
|
+
if (candidate.length === 0 && j > 0) {
|
|
265
|
+
cursor++;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
matched = false;
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
if (!matched || cursor >= fileLines.length) {
|
|
272
|
+
matched = false;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
if (j < descLines.length - 1)
|
|
276
|
+
cursor++;
|
|
277
|
+
}
|
|
278
|
+
if (matched) {
|
|
279
|
+
const startLine = i + 1; // 1-indexed
|
|
280
|
+
const endLine = cursor + 1;
|
|
281
|
+
const snippet = fileLines.slice(i, cursor + 1).join('\n');
|
|
282
|
+
return { snippet, startLine, endLine };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Insert ` for <tag> tasks` after the first trigger verb match in
|
|
289
|
+
* `snippet`. If no trigger verb is found, prepend `for <tag> tasks: ` to
|
|
290
|
+
* the description body (after any leading frontmatter prefix like
|
|
291
|
+
* `description:`).
|
|
292
|
+
*
|
|
293
|
+
* Returns the modified snippet, or `null` if the qualifier text is
|
|
294
|
+
* already present (idempotent — no-op edits are filtered out by caller).
|
|
295
|
+
*/
|
|
296
|
+
function injectQualifier(snippet, tag) {
|
|
297
|
+
const qualifierPhrase = `for ${tag} tasks`;
|
|
298
|
+
if (snippet.toLowerCase().includes(qualifierPhrase.toLowerCase())) {
|
|
299
|
+
// Already qualified.
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
// Trigger-verb pattern: case-insensitive match for verb at start of a
|
|
303
|
+
// word boundary, optionally preceded by `description:` prefix.
|
|
304
|
+
const triggerVerbPattern = /\b(use|trigger|run|when|whenever|invoke)\b(\s+\w+)?/i;
|
|
305
|
+
const match = triggerVerbPattern.exec(snippet);
|
|
306
|
+
if (match && match.index >= 0) {
|
|
307
|
+
const insertAt = match.index + match[0].length;
|
|
308
|
+
return `${snippet.slice(0, insertAt)} ${qualifierPhrase}${snippet.slice(insertAt)}`;
|
|
309
|
+
}
|
|
310
|
+
// No trigger verb: inject after the description-key prefix if present,
|
|
311
|
+
// else prepend to the snippet body.
|
|
312
|
+
const descKeyMatch = /^(\s*description\s*:\s*)(.*)$/im.exec(snippet);
|
|
313
|
+
if (descKeyMatch && descKeyMatch.index >= 0) {
|
|
314
|
+
const prefix = descKeyMatch[1];
|
|
315
|
+
const rest = descKeyMatch[2];
|
|
316
|
+
return snippet.replace(descKeyMatch[0], `${prefix}${qualifierPhrase}: ${rest}`);
|
|
317
|
+
}
|
|
318
|
+
return `${qualifierPhrase}: ${snippet}`;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Public registry-key accessor. Re-exports the pattern strings so the
|
|
322
|
+
* apply-path registry (`edit-applier.ts`) can import a single source of
|
|
323
|
+
* truth instead of stringly-typed literals.
|
|
324
|
+
*/
|
|
325
|
+
export const V1_TEMPLATE_PATTERNS = V1_TEMPLATES.map((t) => t.pattern);
|
|
326
|
+
//# sourceMappingURL=edit-suggester.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-suggester.js","sourceRoot":"","sources":["../../../src/audit/edit-suggester.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type vocabulary for the edit-suggester (SMI-4589 Wave 3 Step 1).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/edit-suggester.types
|
|
4
|
+
*
|
|
5
|
+
* Defines `RecommendedEdit`, `EditCategory`, `EditTemplate` — the public
|
|
6
|
+
* surface consumed by Wave 3's audit-report writer extension, install
|
|
7
|
+
* pre-flight wiring, and Wave 4's MCP `apply_recommended_edit` tool surface.
|
|
8
|
+
*
|
|
9
|
+
* The shapes are deliberately additive: `RecommendedEdit` does not extend
|
|
10
|
+
* `RenameSuggestion` (Wave 2) because the `before`/`after` snippet pair has
|
|
11
|
+
* no analogue in the rename surface — coupling them would force the rename
|
|
12
|
+
* engine to carry prose-edit fields it never uses.
|
|
13
|
+
*
|
|
14
|
+
* Plan: docs/internal/implementation/smi-4589-edit-suggester.md §1.
|
|
15
|
+
*/
|
|
16
|
+
import type { CollisionId, SemanticCollisionFlag } from './collision-detector.types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Which class of prose collision a `RecommendedEdit` addresses.
|
|
19
|
+
*
|
|
20
|
+
* - `description_overlap` — two SKILL.md descriptions semantically overlap
|
|
21
|
+
* (cosine ≥0.75). Renaming doesn't help; the descriptions need to
|
|
22
|
+
* differentiate.
|
|
23
|
+
* - `claude_md_trigger_overlap` — two CLAUDE.md trigger phrases semantically
|
|
24
|
+
* overlap. Renaming the file doesn't help; the prose needs to change.
|
|
25
|
+
*
|
|
26
|
+
* v1 ships only `description_overlap` via the `add_domain_qualifier`
|
|
27
|
+
* template. `claude_md_trigger_overlap` (paired with the
|
|
28
|
+
* `reword_trigger_verb` template) FAILED the per-template gate at 2.35/5
|
|
29
|
+
* and is dropped from v1 — see plan §"Wave 3 ship gate". The category enum
|
|
30
|
+
* still ships so SMI-4593's reauthored template body has a stable value to
|
|
31
|
+
* register against without a follow-up type change.
|
|
32
|
+
*/
|
|
33
|
+
export type EditCategory = 'description_overlap' | 'claude_md_trigger_overlap';
|
|
34
|
+
/**
|
|
35
|
+
* The narrow set of template patterns the edit-suggester knows about. v1
|
|
36
|
+
* ships `add_domain_qualifier` only (4.10/5 from GPT-5.4 reviewer-#2
|
|
37
|
+
* scoring). The other two templates failed the per-template gate at
|
|
38
|
+
* 2.35/5 and 1.70/5 respectively; SMI-4593 reauthors them.
|
|
39
|
+
*
|
|
40
|
+
* The string union is the canonical allowlist key for
|
|
41
|
+
* `APPLY_TEMPLATE_REGISTRY` in `edit-applier.ts`. Adding a new pattern
|
|
42
|
+
* here without registering it in that allowlist is a TS error (the apply
|
|
43
|
+
* path narrows on the registry literal); adding it to the allowlist
|
|
44
|
+
* without re-scoring against the per-template gate is caught at
|
|
45
|
+
* plan-review time per the Wave 3 plan §6.
|
|
46
|
+
*/
|
|
47
|
+
export type EditTemplatePattern = 'add_domain_qualifier' | 'narrow_scope' | 'reword_trigger_verb';
|
|
48
|
+
/**
|
|
49
|
+
* One concrete prose-edit recommendation surfaced by `runEditSuggester`.
|
|
50
|
+
*
|
|
51
|
+
* Wave 3 emits these in two surfaces:
|
|
52
|
+
*
|
|
53
|
+
* 1. Audit-report writer's "Recommended Edits" section (rendered as a
|
|
54
|
+
* `diff` fenced markdown block per plan §2).
|
|
55
|
+
* 2. `NamespaceWarning.recommendedEdit` field for `description_overlap`
|
|
56
|
+
* collisions surfaced at install pre-flight time (plan §3).
|
|
57
|
+
*
|
|
58
|
+
* Wave 4's `apply_recommended_edit` MCP tool consumes this shape directly
|
|
59
|
+
* — `applyMode: 'apply_with_confirmation'` is the green-light for the
|
|
60
|
+
* tool to mutate the file, gated by `APPLY_TEMPLATE_REGISTRY`.
|
|
61
|
+
*/
|
|
62
|
+
export interface RecommendedEdit {
|
|
63
|
+
/** Matches the source `SemanticCollisionFlag.collisionId` from Wave 1. */
|
|
64
|
+
collisionId: CollisionId;
|
|
65
|
+
/** Which prose-collision class this edit addresses. */
|
|
66
|
+
category: EditCategory;
|
|
67
|
+
/** Template pattern that generated the edit (registry allowlist key). */
|
|
68
|
+
pattern: EditTemplatePattern;
|
|
69
|
+
/** Absolute path to the file to mutate (SKILL.md or CLAUDE.md). */
|
|
70
|
+
filePath: string;
|
|
71
|
+
/** 1-indexed inclusive line range covering the `before` snippet. */
|
|
72
|
+
lineRange: {
|
|
73
|
+
start: number;
|
|
74
|
+
end: number;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Exact current snippet at `filePath:lineRange`. The applier validates
|
|
78
|
+
* this matches byte-for-byte before mutating; mismatch returns
|
|
79
|
+
* `error: 'edit.stale_before'` and the file is untouched.
|
|
80
|
+
*/
|
|
81
|
+
before: string;
|
|
82
|
+
/**
|
|
83
|
+
* Templated proposed text. Deterministic — no LLM rewrite. v1 inserts
|
|
84
|
+
* `for <tag> tasks` after the trigger verb in the description.
|
|
85
|
+
*/
|
|
86
|
+
after: string;
|
|
87
|
+
/**
|
|
88
|
+
* Human-readable rationale, e.g.
|
|
89
|
+
* `"differentiates from skillsmith/release-tools (cosine 0.82)"`.
|
|
90
|
+
* Surfaced verbatim in the audit-report markdown and in the install
|
|
91
|
+
* pre-flight warning message.
|
|
92
|
+
*/
|
|
93
|
+
rationale: string;
|
|
94
|
+
/**
|
|
95
|
+
* Always `'recommended_edit'`. Distinguishes the prose-edit surface
|
|
96
|
+
* from Wave 2's rename surface (`'rename_command_file'` etc.) when
|
|
97
|
+
* agents introspect heterogeneous suggestion lists.
|
|
98
|
+
*/
|
|
99
|
+
applyAction: 'recommended_edit';
|
|
100
|
+
/**
|
|
101
|
+
* `'manual_review'` — render in the audit report only; no mutation
|
|
102
|
+
* path. `'apply_with_confirmation'` — agent may auto-apply via
|
|
103
|
+
* `apply_recommended_edit` after user confirmation.
|
|
104
|
+
*
|
|
105
|
+
* v1: `add_domain_qualifier` (the only registered template) ships at
|
|
106
|
+
* `'apply_with_confirmation'`. `runEditSuggester` does NOT emit any
|
|
107
|
+
* edit at `'manual_review'` mode in v1 — the failing templates are
|
|
108
|
+
* absent from output entirely per plan R-4/R-8.
|
|
109
|
+
*/
|
|
110
|
+
applyMode: 'manual_review' | 'apply_with_confirmation';
|
|
111
|
+
/**
|
|
112
|
+
* Cross-reference to the partner skill in the original collision flag.
|
|
113
|
+
* Lets the audit report say "differentiates from <other>" without
|
|
114
|
+
* forcing the writer to re-read inventory state.
|
|
115
|
+
*/
|
|
116
|
+
otherEntry: {
|
|
117
|
+
identifier: string;
|
|
118
|
+
sourcePath: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* One template implementation. `applies()` is a synchronous predicate over
|
|
123
|
+
* the flag; `generate()` is synchronous over `flag + fileContent` (the
|
|
124
|
+
* dispatcher pre-reads files in parallel before iterating templates per
|
|
125
|
+
* plan §1 async dispatch pattern).
|
|
126
|
+
*
|
|
127
|
+
* Templates return `null` from `generate()` when the flag matches but the
|
|
128
|
+
* synthesized edit can't be produced (e.g. line-range extraction fails
|
|
129
|
+
* because the file changed under us). The caller skips silently — the
|
|
130
|
+
* user still sees the warning + cosine score from Wave 1.
|
|
131
|
+
*/
|
|
132
|
+
export interface EditTemplate {
|
|
133
|
+
category: EditCategory;
|
|
134
|
+
pattern: EditTemplatePattern;
|
|
135
|
+
/**
|
|
136
|
+
* Higher fires first within a flag. Tiebreak by registration order —
|
|
137
|
+
* the dispatcher is stable. v1 ships a single template per category so
|
|
138
|
+
* priority is informational only, but the field is load-bearing for
|
|
139
|
+
* the SMI-4593 reauthoring path that may register additional templates
|
|
140
|
+
* against the same category.
|
|
141
|
+
*/
|
|
142
|
+
priority: number;
|
|
143
|
+
applies(flag: SemanticCollisionFlag): boolean;
|
|
144
|
+
generate(flag: SemanticCollisionFlag, context: {
|
|
145
|
+
fileContent: string;
|
|
146
|
+
}): RecommendedEdit | null;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=edit-suggester.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-suggester.types.d.ts","sourceRoot":"","sources":["../../../src/audit/edit-suggester.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAEvF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,YAAY,GAAG,qBAAqB,GAAG,2BAA2B,CAAA;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,GAAG,cAAc,GAAG,qBAAqB,CAAA;AAEjG;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,WAAW,EAAE,WAAW,CAAA;IACxB,uDAAuD;IACvD,QAAQ,EAAE,YAAY,CAAA;IACtB,yEAAyE;IACzE,OAAO,EAAE,mBAAmB,CAAA;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,WAAW,EAAE,kBAAkB,CAAA;IAC/B;;;;;;;;;OASG;IACH,SAAS,EAAE,eAAe,GAAG,yBAAyB,CAAA;IACtD;;;;OAIG;IACH,UAAU,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,mBAAmB,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAA;IAC7C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,GAAG,IAAI,CAAA;CAChG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type vocabulary for the edit-suggester (SMI-4589 Wave 3 Step 1).
|
|
3
|
+
* @module @skillsmith/mcp-server/audit/edit-suggester.types
|
|
4
|
+
*
|
|
5
|
+
* Defines `RecommendedEdit`, `EditCategory`, `EditTemplate` — the public
|
|
6
|
+
* surface consumed by Wave 3's audit-report writer extension, install
|
|
7
|
+
* pre-flight wiring, and Wave 4's MCP `apply_recommended_edit` tool surface.
|
|
8
|
+
*
|
|
9
|
+
* The shapes are deliberately additive: `RecommendedEdit` does not extend
|
|
10
|
+
* `RenameSuggestion` (Wave 2) because the `before`/`after` snippet pair has
|
|
11
|
+
* no analogue in the rename surface — coupling them would force the rename
|
|
12
|
+
* engine to carry prose-edit fields it never uses.
|
|
13
|
+
*
|
|
14
|
+
* Plan: docs/internal/implementation/smi-4589-edit-suggester.md §1.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=edit-suggester.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-suggester.types.js","sourceRoot":"","sources":["../../../src/audit/edit-suggester.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `claudeCodeAdapter` — v1 implementation of `FrameworkAdapter`.
|
|
3
|
+
* Wraps Wave 1's `scanLocalInventory`, Wave 2's `applyRename`,
|
|
4
|
+
* and Wave 3's `applyRecommendedEdit` behind a uniform seam.
|
|
5
|
+
* @module @skillsmith/mcp-server/audit/framework-adapter
|
|
6
|
+
*
|
|
7
|
+
* Plan: docs/internal/implementation/smi-4590-cli-mcp-framework-adapter.md §5.
|
|
8
|
+
*
|
|
9
|
+
* v1 contract (Claude-Code only):
|
|
10
|
+
* - `scanPaths` delegates to `scanLocalInventory` and returns `entries[]`.
|
|
11
|
+
* - `applyAction({kind:'rename'})` is REFUSED — a thin {from, to} pair
|
|
12
|
+
* cannot reconstruct the `InventoryEntry` Wave 2's `applyRename`
|
|
13
|
+
* needs (kind discriminator, identifier, source_path), and a raw
|
|
14
|
+
* `fs.rename` would bypass the backup + namespace ledger and leave
|
|
15
|
+
* the user without a revert path. Callers must use the
|
|
16
|
+
* `applyRename(entry, newName, { auditId })` convenience wrapper.
|
|
17
|
+
* The bare `{kind:'rename'}` shape stays in the union as a forward-
|
|
18
|
+
* compat surface for v2 adapters that own their own audit-history.
|
|
19
|
+
* - `applyAction({kind:'inline-edit', searchMode:'literal'})` translates
|
|
20
|
+
* the action into a Wave 3 `RecommendedEdit` and dispatches to
|
|
21
|
+
* `applyRecommendedEdit`. Requires `action.auditId` + `action.pattern`;
|
|
22
|
+
* missing context throws `namespace.adapter.missing_context`.
|
|
23
|
+
* - `applyAction({kind:'inline-edit', searchMode:'regex'})` throws the
|
|
24
|
+
* typed error `namespace.adapter.unsupported_search_mode`. Reserved
|
|
25
|
+
* for v2 cursorAdapter.
|
|
26
|
+
* - Convenience wrappers `applyRename` + `applyEdit` build the right
|
|
27
|
+
* `AdapterAction` shape from inventory/edit context and call
|
|
28
|
+
* `applyAction`. They do NOT re-implement Wave 2/3 — the rename
|
|
29
|
+
* wrapper goes through Wave 2's full path (backup + ledger), and the
|
|
30
|
+
* edit wrapper goes through Wave 3's `applyRecommendedEdit`.
|
|
31
|
+
*/
|
|
32
|
+
import { newAuditId } from './audit-history.js';
|
|
33
|
+
import type { FileRenameAction, FrameworkAdapter, InlineEditAction } from './framework-adapter.types.js';
|
|
34
|
+
/**
|
|
35
|
+
* Typed error class for adapter-layer failures. Callers `switch` on
|
|
36
|
+
* `kind` to branch on the failure mode without parsing strings.
|
|
37
|
+
*/
|
|
38
|
+
export declare class FrameworkAdapterError extends Error {
|
|
39
|
+
readonly kind: 'namespace.adapter.unsupported_search_mode' | 'namespace.adapter.missing_context' | 'namespace.adapter.unsupported_action' | 'namespace.adapter.template_not_in_apply_registry' | 'namespace.adapter.search_not_found' | 'namespace.adapter.search_not_unique' | 'namespace.adapter.subcall_failed';
|
|
40
|
+
/**
|
|
41
|
+
* For `'subcall_failed'`, carries the inner typed-error `kind` from
|
|
42
|
+
* Wave 2 (`RenameError`) or Wave 3 (`EditApplyError`) so callers can
|
|
43
|
+
* `switch` on it without parsing strings.
|
|
44
|
+
*/
|
|
45
|
+
readonly innerKind?: string;
|
|
46
|
+
constructor(kind: FrameworkAdapterError['kind'], message: string, innerKind?: string);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* v1 implementation of `FrameworkAdapter` for Claude-Code.
|
|
50
|
+
*/
|
|
51
|
+
export declare const claudeCodeAdapter: FrameworkAdapter;
|
|
52
|
+
export { newAuditId };
|
|
53
|
+
export type { FileRenameAction, InlineEditAction };
|
|
54
|
+
//# sourceMappingURL=framework-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-adapter.d.ts","sourceRoot":"","sources":["../../../src/audit/framework-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAAE,UAAU,EAAqB,MAAM,oBAAoB,CAAA;AAQlE,OAAO,KAAK,EAEV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,8BAA8B,CAAA;AAErC;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,IAAI,EAChB,2CAA2C,GAC3C,mCAAmC,GACnC,sCAAsC,GACtC,kDAAkD,GAClD,oCAAoC,GACpC,qCAAqC,GACrC,kCAAkC,CAAA;IAEtC;;;;OAIG;IACH,SAAgB,SAAS,CAAC,EAAE,MAAM,CAAA;gBAEtB,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAMrF;AA0ID;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,gBAwG/B,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}
|