@skillsmith/core 0.11.3 → 0.11.5
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 +34 -9
- package/README.md +10 -7
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +15 -5
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.private-registry.d.ts +80 -0
- package/dist/src/api/client.private-registry.d.ts.map +1 -0
- package/dist/src/api/client.private-registry.js +97 -0
- package/dist/src/api/client.private-registry.js.map +1 -0
- package/dist/src/api/client.private-registry.test.d.ts +9 -0
- package/dist/src/api/client.private-registry.test.d.ts.map +1 -0
- package/dist/src/api/client.private-registry.test.js +127 -0
- package/dist/src/api/client.private-registry.test.js.map +1 -0
- package/dist/src/api/client.toSkill.test.d.ts +25 -0
- package/dist/src/api/client.toSkill.test.d.ts.map +1 -0
- package/dist/src/api/client.toSkill.test.js +97 -0
- package/dist/src/api/client.toSkill.test.js.map +1 -0
- package/dist/src/api/client.token-refresh.d.ts +8 -0
- package/dist/src/api/client.token-refresh.d.ts.map +1 -1
- package/dist/src/api/client.token-refresh.js +26 -0
- package/dist/src/api/client.token-refresh.js.map +1 -1
- package/dist/src/api/client.token-refresh.test.js +82 -0
- package/dist/src/api/client.token-refresh.test.js.map +1 -1
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +9 -0
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/security-summary.d.ts +73 -0
- package/dist/src/api/security-summary.d.ts.map +1 -0
- package/dist/src/api/security-summary.js +88 -0
- package/dist/src/api/security-summary.js.map +1 -0
- package/dist/src/api/security-summary.test.d.ts +9 -0
- package/dist/src/api/security-summary.test.d.ts.map +1 -0
- package/dist/src/api/security-summary.test.js +94 -0
- package/dist/src/api/security-summary.test.js.map +1 -0
- package/dist/src/config/config-atomic-write.d.ts +30 -10
- package/dist/src/config/config-atomic-write.d.ts.map +1 -1
- package/dist/src/config/config-atomic-write.js +33 -80
- package/dist/src/config/config-atomic-write.js.map +1 -1
- package/dist/src/config/config-atomic-write.test.d.ts +8 -0
- package/dist/src/config/config-atomic-write.test.d.ts.map +1 -1
- package/dist/src/config/config-atomic-write.test.js +64 -12
- package/dist/src/config/config-atomic-write.test.js.map +1 -1
- package/dist/src/config/owned-lock.acquire.d.ts +53 -0
- package/dist/src/config/owned-lock.acquire.d.ts.map +1 -0
- package/dist/src/config/owned-lock.acquire.js +140 -0
- package/dist/src/config/owned-lock.acquire.js.map +1 -0
- package/dist/src/config/owned-lock.claim.d.ts +84 -0
- package/dist/src/config/owned-lock.claim.d.ts.map +1 -0
- package/dist/src/config/owned-lock.claim.js +310 -0
- package/dist/src/config/owned-lock.claim.js.map +1 -0
- package/dist/src/config/owned-lock.d.ts +113 -0
- package/dist/src/config/owned-lock.d.ts.map +1 -0
- package/dist/src/config/owned-lock.js +121 -0
- package/dist/src/config/owned-lock.js.map +1 -0
- package/dist/src/config/owned-lock.test.d.ts +12 -0
- package/dist/src/config/owned-lock.test.d.ts.map +1 -0
- package/dist/src/config/owned-lock.test.js +412 -0
- package/dist/src/config/owned-lock.test.js.map +1 -0
- package/dist/src/config/owned-lock.types.d.ts +78 -0
- package/dist/src/config/owned-lock.types.d.ts.map +1 -0
- package/dist/src/config/owned-lock.types.js +30 -0
- package/dist/src/config/owned-lock.types.js.map +1 -0
- package/dist/src/db/createDatabase.d.ts.map +1 -1
- package/dist/src/db/createDatabase.js +19 -7
- package/dist/src/db/createDatabase.js.map +1 -1
- package/dist/src/embeddings/hnsw-store.exports.d.ts +11 -0
- package/dist/src/embeddings/hnsw-store.exports.d.ts.map +1 -0
- package/dist/src/embeddings/hnsw-store.exports.js +10 -0
- package/dist/src/embeddings/hnsw-store.exports.js.map +1 -0
- package/dist/src/embeddings/index.d.ts +1 -2
- package/dist/src/embeddings/index.d.ts.map +1 -1
- package/dist/src/embeddings/index.js +17 -3
- package/dist/src/embeddings/index.js.map +1 -1
- package/dist/src/embeddings/probe.d.ts.map +1 -1
- package/dist/src/embeddings/probe.js +4 -8
- package/dist/src/embeddings/probe.js.map +1 -1
- package/dist/src/exports/services.d.ts +4 -1
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +22 -0
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +5 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +17 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/index.d.ts +1 -1
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +1 -1
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/paths.d.ts +10 -0
- package/dist/src/install/paths.d.ts.map +1 -1
- package/dist/src/install/paths.js +19 -0
- package/dist/src/install/paths.js.map +1 -1
- package/dist/src/logging/logger.test.js +57 -0
- package/dist/src/logging/logger.test.js.map +1 -1
- package/dist/src/logging/rotation.d.ts +27 -2
- package/dist/src/logging/rotation.d.ts.map +1 -1
- package/dist/src/logging/rotation.js +44 -3
- package/dist/src/logging/rotation.js.map +1 -1
- package/dist/src/logging/rotation.test.js +69 -0
- package/dist/src/logging/rotation.test.js.map +1 -1
- package/dist/src/logging/types.d.ts +8 -2
- package/dist/src/logging/types.d.ts.map +1 -1
- package/dist/src/security/index.d.ts +2 -1
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +3 -0
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.d.ts +2 -2
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.evidence.d.ts +76 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.js +176 -0
- package/dist/src/security/scanner/SecurityScanner.evidence.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.exec.d.ts +8 -1
- package/dist/src/security/scanner/SecurityScanner.exec.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.exec.js +58 -2
- package/dist/src/security/scanner/SecurityScanner.exec.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +35 -10
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.js +106 -59
- package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.js +41 -13
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.js +23 -1
- package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +15 -3
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts +11 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.ssrf.js +18 -7
- package/dist/src/security/scanner/SecurityScanner.ssrf.js.map +1 -1
- package/dist/src/security/scanner/index.d.ts +3 -3
- package/dist/src/security/scanner/index.d.ts.map +1 -1
- package/dist/src/security/scanner/index.js +5 -2
- package/dist/src/security/scanner/index.js.map +1 -1
- package/dist/src/security/scanner/multiline-category-closure.test.d.ts +80 -0
- package/dist/src/security/scanner/multiline-category-closure.test.d.ts.map +1 -0
- package/dist/src/security/scanner/multiline-category-closure.test.js +287 -0
- package/dist/src/security/scanner/multiline-category-closure.test.js.map +1 -0
- package/dist/src/security/scanner/patterns.d.ts +41 -14
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.jailbreak.d.ts +41 -0
- package/dist/src/security/scanner/patterns.jailbreak.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts +35 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.js +119 -0
- package/dist/src/security/scanner/patterns.jailbreak.evidence.js.map +1 -0
- package/dist/src/security/scanner/patterns.jailbreak.js +370 -0
- package/dist/src/security/scanner/patterns.jailbreak.js.map +1 -0
- package/dist/src/security/scanner/patterns.js +101 -82
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/patterns.scope.d.ts +62 -0
- package/dist/src/security/scanner/patterns.scope.d.ts.map +1 -0
- package/dist/src/security/scanner/patterns.scope.js +207 -0
- package/dist/src/security/scanner/patterns.scope.js.map +1 -0
- package/dist/src/security/scanner/regex-utils.d.ts +20 -0
- package/dist/src/security/scanner/regex-utils.d.ts.map +1 -1
- package/dist/src/security/scanner/regex-utils.js +20 -0
- package/dist/src/security/scanner/regex-utils.js.map +1 -1
- package/dist/src/security/scanner/types.d.ts +35 -0
- package/dist/src/security/scanner/types.d.ts.map +1 -1
- package/dist/src/services/recommend-guard.d.ts +28 -0
- package/dist/src/services/recommend-guard.d.ts.map +1 -0
- package/dist/src/services/recommend-guard.js +34 -0
- package/dist/src/services/recommend-guard.js.map +1 -0
- package/dist/src/services/recommend-guard.test.d.ts +2 -0
- package/dist/src/services/recommend-guard.test.d.ts.map +1 -0
- package/dist/src/services/recommend-guard.test.js +28 -0
- package/dist/src/services/recommend-guard.test.js.map +1 -0
- package/dist/src/services/skill-installation.content.d.ts +88 -0
- package/dist/src/services/skill-installation.content.d.ts.map +1 -0
- package/dist/src/services/skill-installation.content.js +319 -0
- package/dist/src/services/skill-installation.content.js.map +1 -0
- package/dist/src/services/skill-installation.helpers.d.ts +32 -1
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +39 -6
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.test.js +34 -2
- package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.js +86 -2
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.service.d.ts +20 -1
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +26 -4
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.types.d.ts +42 -1
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-resolution.d.ts +67 -0
- package/dist/src/services/skill-resolution.d.ts.map +1 -0
- package/dist/src/services/skill-resolution.js +67 -0
- package/dist/src/services/skill-resolution.js.map +1 -0
- package/dist/src/services/skill-resolution.test.d.ts +2 -0
- package/dist/src/services/skill-resolution.test.d.ts.map +1 -0
- package/dist/src/services/skill-resolution.test.js +143 -0
- package/dist/src/services/skill-resolution.test.js.map +1 -0
- package/dist/src/sync/inventory-collector.d.ts.map +1 -1
- package/dist/src/sync/inventory-collector.js +2 -2
- package/dist/src/sync/inventory-collector.js.map +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +4 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/quiet-mode.d.ts +21 -0
- package/dist/src/utils/quiet-mode.d.ts.map +1 -0
- package/dist/src/utils/quiet-mode.js +26 -0
- package/dist/src/utils/quiet-mode.js.map +1 -0
- package/dist/tests/EmbeddingService.test.js +58 -1
- package/dist/tests/EmbeddingService.test.js.map +1 -1
- package/dist/tests/SecurityScanner.ai-defence.test.js +32 -7
- package/dist/tests/SecurityScanner.ai-defence.test.js.map +1 -1
- package/dist/tests/SecurityScanner.exec.test.js +79 -0
- package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
- package/dist/tests/SecurityScanner.performance.test.js +5 -2
- package/dist/tests/SecurityScanner.performance.test.js.map +1 -1
- package/dist/tests/db/database-abstraction.test.js +45 -1
- package/dist/tests/db/database-abstraction.test.js.map +1 -1
- package/dist/tests/helpers/deterministic-dead-pid.d.ts +13 -0
- package/dist/tests/helpers/deterministic-dead-pid.d.ts.map +1 -0
- package/dist/tests/helpers/deterministic-dead-pid.js +31 -0
- package/dist/tests/helpers/deterministic-dead-pid.js.map +1 -0
- package/dist/tests/integration/owned-lock-lost-update.test.d.ts +12 -0
- package/dist/tests/integration/owned-lock-lost-update.test.d.ts.map +1 -0
- package/dist/tests/integration/owned-lock-lost-update.test.js +52 -0
- package/dist/tests/integration/owned-lock-lost-update.test.js.map +1 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts +19 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts.map +1 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.js +177 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js +6 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -1
- package/dist/tests/security/ContinuousSecurity.test.js +15 -0
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
- package/dist/tests/security/ad-crlf-injection.test.d.ts +18 -0
- package/dist/tests/security/ad-crlf-injection.test.d.ts.map +1 -0
- package/dist/tests/security/ad-crlf-injection.test.js +150 -0
- package/dist/tests/security/ad-crlf-injection.test.js.map +1 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts +25 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.d.ts.map +1 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.js +138 -0
- package/dist/tests/security/ai-defence-multiline-promotion.test.js.map +1 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.d.ts +15 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.d.ts.map +1 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.js +60 -0
- package/dist/tests/security/nested-instruction-long-attribute.test.js.map +1 -0
- package/dist/tests/security/pattern-scope.test.d.ts +17 -0
- package/dist/tests/security/pattern-scope.test.d.ts.map +1 -0
- package/dist/tests/security/pattern-scope.test.js +128 -0
- package/dist/tests/security/pattern-scope.test.js.map +1 -0
- package/dist/tests/security/pii-detection.test.js +39 -0
- package/dist/tests/security/pii-detection.test.js.map +1 -1
- package/dist/tests/security/scanner-evidence-tiers.test.d.ts +30 -0
- package/dist/tests/security/scanner-evidence-tiers.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-evidence-tiers.test.js +258 -0
- package/dist/tests/security/scanner-evidence-tiers.test.js.map +1 -0
- package/dist/tests/security/scanner-privesc-severity.test.d.ts +23 -0
- package/dist/tests/security/scanner-privesc-severity.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-privesc-severity.test.js +43 -0
- package/dist/tests/security/scanner-privesc-severity.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts +20 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.js +71 -0
- package/dist/tests/security/scanner-regression-guard.exec-locality.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts +24 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +59 -3
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts +19 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.js +65 -0
- package/dist/tests/security/scanner-ssrf-word-boundary.test.js.map +1 -0
- package/dist/tests/security.test.js +11 -2
- package/dist/tests/security.test.js.map +1 -1
- package/dist/tests/skill-scanner/allowlist.test.js +15 -7
- package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.content.test.d.ts +10 -0
- package/dist/tests/unit/services/skill-installation.content.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.content.test.js +290 -0
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts +8 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.js +72 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.test.js +54 -1
- package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts +15 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +190 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts +17 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.js +126 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.test.js +7 -112
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/utils/quiet-mode.test.d.ts +12 -0
- package/dist/tests/utils/quiet-mode.test.d.ts.map +1 -0
- package/dist/tests/utils/quiet-mode.test.js +42 -0
- package/dist/tests/utils/quiet-mode.test.js.map +1 -0
- package/package.json +17 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.token-refresh.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,gCAAgC,CAAA;AAEvC,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAEvB,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC9D,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAE3B,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAA;IACjC,OAAO,SAAS,CAAC,WAAW,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,WAAW,CAAA;AAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"client.token-refresh.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,gCAAgC,CAAA;AAEvC,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAEvB,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC9D,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAE3B,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAA;IACjC,OAAO,SAAS,CAAC,WAAW,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,WAAW,CAAA;AAC1B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,oBAAoB,GAAG,MAAM,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,oBAAoB;QAAE,OAAO,KAAK,CAAC,WAAW,CAAA;IACjF,OAAO,eAAe,EAAE,CAAA;AAC1B,CAAC"}
|
|
@@ -70,4 +70,86 @@ describe('client.token-refresh', () => {
|
|
|
70
70
|
expect(result).toBeNull();
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
+
// SMI-5905 Wave 1: resolveFreshAccessToken() — extracted from team-resolver.ts's
|
|
74
|
+
// resolveUserAccessToken() (TOKEN_EXPIRY_SKEW_MS=60s). team-resolver.ts now delegates to this
|
|
75
|
+
// function unchanged, so these cases are the authoritative coverage for the skew logic.
|
|
76
|
+
describe('resolveFreshAccessToken (SMI-5905)', () => {
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
vi.clearAllMocks();
|
|
79
|
+
});
|
|
80
|
+
it('RFT-1: returns accessToken directly when well within expiry (no refresh)', async () => {
|
|
81
|
+
const { loadCredentials, refreshAccessToken } = await import('../config/token-credentials.js');
|
|
82
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
83
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
84
|
+
accessToken: 'fresh_at',
|
|
85
|
+
refreshToken: 'fresh_rt',
|
|
86
|
+
expiresAt: Date.now() + 3_600_000, // 1h out — far outside the 60s skew window
|
|
87
|
+
version: 2,
|
|
88
|
+
});
|
|
89
|
+
const result = await resolveFreshAccessToken();
|
|
90
|
+
expect(result).toBe('fresh_at');
|
|
91
|
+
expect(refreshAccessToken).not.toHaveBeenCalled();
|
|
92
|
+
});
|
|
93
|
+
it('RFT-2: returns null when no credentials are stored (no refresh attempted)', async () => {
|
|
94
|
+
const { loadCredentials, refreshAccessToken } = await import('../config/token-credentials.js');
|
|
95
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
96
|
+
vi.mocked(loadCredentials).mockResolvedValue(null);
|
|
97
|
+
const result = await resolveFreshAccessToken();
|
|
98
|
+
expect(result).toBeNull();
|
|
99
|
+
expect(refreshAccessToken).not.toHaveBeenCalled();
|
|
100
|
+
});
|
|
101
|
+
it('RFT-3: expiry-skew boundary — refreshes within the 60s skew window', async () => {
|
|
102
|
+
const { loadCredentials, refreshAccessToken, storeCredentials } = await import('../config/token-credentials.js');
|
|
103
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
104
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
105
|
+
accessToken: 'about_to_expire_at',
|
|
106
|
+
refreshToken: 'still_valid_rt',
|
|
107
|
+
expiresAt: Date.now() + 30_000, // 30s out — inside the 60s skew window
|
|
108
|
+
version: 2,
|
|
109
|
+
});
|
|
110
|
+
vi.mocked(refreshAccessToken).mockResolvedValue({
|
|
111
|
+
accessToken: 'refreshed_at',
|
|
112
|
+
refreshToken: 'refreshed_rt',
|
|
113
|
+
expiresAt: Date.now() + 3_600_000,
|
|
114
|
+
version: 2,
|
|
115
|
+
});
|
|
116
|
+
vi.mocked(storeCredentials).mockResolvedValue(undefined);
|
|
117
|
+
const result = await resolveFreshAccessToken();
|
|
118
|
+
expect(result).toBe('refreshed_at');
|
|
119
|
+
expect(refreshAccessToken).toHaveBeenCalledWith('still_valid_rt');
|
|
120
|
+
expect(storeCredentials).toHaveBeenCalledWith(expect.objectContaining({ accessToken: 'refreshed_at' }));
|
|
121
|
+
});
|
|
122
|
+
it('RFT-4: an already-expired token also refreshes (not just the skew window)', async () => {
|
|
123
|
+
const { loadCredentials, refreshAccessToken, storeCredentials } = await import('../config/token-credentials.js');
|
|
124
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
125
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
126
|
+
accessToken: 'expired_at',
|
|
127
|
+
refreshToken: 'expired_rt',
|
|
128
|
+
expiresAt: Date.now() - 1_000,
|
|
129
|
+
version: 2,
|
|
130
|
+
});
|
|
131
|
+
vi.mocked(refreshAccessToken).mockResolvedValue({
|
|
132
|
+
accessToken: 'new_at',
|
|
133
|
+
refreshToken: 'new_rt',
|
|
134
|
+
expiresAt: Date.now() + 3_600_000,
|
|
135
|
+
version: 2,
|
|
136
|
+
});
|
|
137
|
+
vi.mocked(storeCredentials).mockResolvedValue(undefined);
|
|
138
|
+
const result = await resolveFreshAccessToken();
|
|
139
|
+
expect(result).toBe('new_at');
|
|
140
|
+
});
|
|
141
|
+
it('RFT-5: returns null when the refresh token itself is no longer valid', async () => {
|
|
142
|
+
const { loadCredentials, refreshAccessToken } = await import('../config/token-credentials.js');
|
|
143
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
144
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
145
|
+
accessToken: 'about_to_expire_at',
|
|
146
|
+
refreshToken: 'dead_rt',
|
|
147
|
+
expiresAt: Date.now() + 30_000,
|
|
148
|
+
version: 2,
|
|
149
|
+
});
|
|
150
|
+
vi.mocked(refreshAccessToken).mockResolvedValue(null);
|
|
151
|
+
const result = await resolveFreshAccessToken();
|
|
152
|
+
expect(result).toBeNull();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
73
155
|
//# sourceMappingURL=client.token-refresh.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.token-refresh.test.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.token-refresh.test.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.test.ts"],"names":[],"mappings":"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"}
|
package/dist/src/api/index.d.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* SMI-1300: API types matching OpenAPI spec
|
|
8
8
|
*/
|
|
9
9
|
export { SkillsmithApiClient, createApiClient, generateAnonymousId, ApiClientError, type ApiClientConfig, type ApiResponse, type ApiErrorResponse, type ApiSearchResult, type RecommendationRequest, type TelemetryEvent, } from './client.js';
|
|
10
|
+
export { getPrivateRegistrySkillContent, type PrivateRegistrySkillContent, type PrivateRegistryGetErrorCode, type PrivateRegistryGetResult, type GetPrivateRegistrySkillContentParams, } from './client.private-registry.js';
|
|
10
11
|
export { EventBatcher, createEventBatcher, type EventBatcherOptions, type BatchFlushFn, } from './event-batcher.js';
|
|
12
|
+
export { deriveSecuritySummaryFromApiSkill, deriveSecuritySummaryFromSkillRow, } from './security-summary.js';
|
|
11
13
|
export { ApiCache, createCache, getGlobalCache, DEFAULT_TTL, type CacheConfig, type CacheStats, } from './cache.js';
|
|
12
14
|
export { API_TRUST_TIERS, API_CATEGORIES } from './types.js';
|
|
13
15
|
export type { ApiTrustTier, ApiCategory, ApiProjectType, ApiSkill, ApiSearchResult as OpenApiSearchResult, RecommendedSkill, SearchParams, SearchResponse, SearchResponseMeta, RecommendParams, RecommendResponse, RecommendResponseMeta, SkillResponse, HealthStatus, TelemetryEventType, TelemetryMetadata, TelemetryEventPayload, TelemetryResponse, ApiErrorResponse as OpenApiErrorResponse, RateLimitInfo, ApiClientOptions, ApiResponse as OpenApiResponse, } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,GACpB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,GACpB,MAAM,aAAa,CAAA;AAIpB,OAAO,EACL,8BAA8B,EAC9B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,oCAAoC,GAC1C,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAA;AAO3B,OAAO,EACL,iCAAiC,EACjC,iCAAiC,GAClC,MAAM,uBAAuB,CAAA;AAM9B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAA;AAMnB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5D,YAAY,EAEV,YAAY,EACZ,WAAW,EACX,cAAc,EAEd,QAAQ,EACR,eAAe,IAAI,mBAAmB,EACtC,gBAAgB,EAEhB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAElB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EAErB,aAAa,EAEb,YAAY,EAEZ,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EAEjB,gBAAgB,IAAI,oBAAoB,EAExC,aAAa,EAEb,gBAAgB,EAEhB,WAAW,IAAI,eAAe,GAC/B,MAAM,YAAY,CAAA"}
|
package/dist/src/api/index.js
CHANGED
|
@@ -10,8 +10,17 @@
|
|
|
10
10
|
// API Client
|
|
11
11
|
// ============================================================================
|
|
12
12
|
export { SkillsmithApiClient, createApiClient, generateAnonymousId, ApiClientError, } from './client.js';
|
|
13
|
+
// SMI-5905 Wave 4: private-registry content fetch — the CLI's only transport
|
|
14
|
+
// to `private_registry_skills.content` (see client.private-registry.ts header).
|
|
15
|
+
export { getPrivateRegistrySkillContent, } from './client.private-registry.js';
|
|
13
16
|
// SMI-4119: Event batching
|
|
14
17
|
export { EventBatcher, createEventBatcher, } from './event-batcher.js';
|
|
18
|
+
// SMI-5897 (C-15): shared security-summary derivation — CLI (`toSkill()`)
|
|
19
|
+
// and MCP tool call sites both import this instead of independently
|
|
20
|
+
// reconstructing the passed/riskScore/findingsCount/scannedAt logic.
|
|
21
|
+
// SMI-5897 (Wave 4 fix): sibling `deriveSecuritySummaryFromSkillRow()` for
|
|
22
|
+
// the local-DB-shaped (pre-computed field) call sites.
|
|
23
|
+
export { deriveSecuritySummaryFromApiSkill, deriveSecuritySummaryFromSkillRow, } from './security-summary.js';
|
|
15
24
|
// ============================================================================
|
|
16
25
|
// API Cache
|
|
17
26
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,GAOf,MAAM,aAAa,CAAA;AAEpB,2BAA2B;AAC3B,OAAO,EACL,YAAY,EACZ,kBAAkB,GAGnB,MAAM,oBAAoB,CAAA;AAE3B,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,GAGZ,MAAM,YAAY,CAAA;AAEnB,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,GAOf,MAAM,aAAa,CAAA;AAEpB,6EAA6E;AAC7E,gFAAgF;AAChF,OAAO,EACL,8BAA8B,GAK/B,MAAM,8BAA8B,CAAA;AAErC,2BAA2B;AAC3B,OAAO,EACL,YAAY,EACZ,kBAAkB,GAGnB,MAAM,oBAAoB,CAAA;AAE3B,0EAA0E;AAC1E,oEAAoE;AACpE,qEAAqE;AACrE,2EAA2E;AAC3E,uDAAuD;AACvD,OAAO,EACL,iCAAiC,EACjC,iCAAiC,GAClC,MAAM,uBAAuB,CAAA;AAE9B,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,GAGZ,MAAM,YAAY,CAAA;AAEnB,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared derivation of a `SecuritySummary` from an API skill row,
|
|
3
|
+
* and from a pre-computed local-DB-shaped skill row.
|
|
4
|
+
* @module @skillsmith/core/api/security-summary
|
|
5
|
+
* @see SMI-4240: original inline derivation in mcp-server's get-skill.ts
|
|
6
|
+
* @see SMI-5562: extracted to mcp-server's utils/security-summary.ts so
|
|
7
|
+
* get-skill.ts, recommend.ts, and search.ts share a single implementation
|
|
8
|
+
* instead of triplicating the logic.
|
|
9
|
+
* @see SMI-5897 (C-15): moved here from mcp-server so `SkillsmithApiClient.toSkill()`
|
|
10
|
+
* (CLI path) can share the exact same derivation instead of hardcoding
|
|
11
|
+
* `riskScore: null, securityFindingsCount: 0, securityScannedAt: null,
|
|
12
|
+
* securityPassed: null` for every API-sourced skill — which caused CLI
|
|
13
|
+
* `info`/`search` to show "Not scanned" for skills MCP correctly reported
|
|
14
|
+
* as passed. Both `toSkill()` and mcp-server's tool call sites now import
|
|
15
|
+
* this one function, so the two surfaces cannot re-diverge.
|
|
16
|
+
* @see SMI-5897 (Wave 4 fix): `deriveSecuritySummaryFromSkillRow()` added
|
|
17
|
+
* alongside `deriveSecuritySummaryFromApiSkill()` — the local-DB-path
|
|
18
|
+
* sibling for the SAME undefined-when-never-scanned contract, but over the
|
|
19
|
+
* pre-computed `securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
20
|
+
* `securityScannedAt` field shape (as opposed to the raw API row's
|
|
21
|
+
* `last_scanned_at`/`quarantined`/`security_score`/`security_findings`
|
|
22
|
+
* columns). `recommend.helpers.ts`'s `buildDbFallbackRecommendation` had
|
|
23
|
+
* this exact ternary inline already; `search.helpers.ts`'s
|
|
24
|
+
* `mapLocalSkillToSearchResult` and `get-skill.ts`'s local-DB branch built
|
|
25
|
+
* the security object unconditionally, violating the contract for a
|
|
26
|
+
* never-scanned skill. All three now share this one function.
|
|
27
|
+
*/
|
|
28
|
+
import type { ApiSkill } from './types.js';
|
|
29
|
+
import type { SecuritySummary } from '../types.js';
|
|
30
|
+
/**
|
|
31
|
+
* Derive a `SecuritySummary` from an API skill row's flat security columns.
|
|
32
|
+
*
|
|
33
|
+
* Returns `undefined` when the skill has never been scanned
|
|
34
|
+
* (`last_scanned_at == null`) — never scanned is a distinct state from
|
|
35
|
+
* "scanned but no verdict" and callers must not conflate the two by
|
|
36
|
+
* shipping a placeholder `{ passed: null, ... }` object for skills that
|
|
37
|
+
* were never scanned at all.
|
|
38
|
+
*
|
|
39
|
+
* `security_findings_count` is not a stored column — `findingsCount` is
|
|
40
|
+
* always derived from the length of the `security_findings` jsonb array
|
|
41
|
+
* (defensively 0 when the value is missing or not an array).
|
|
42
|
+
*
|
|
43
|
+
* @param apiSkill - Object carrying the flat security columns from an
|
|
44
|
+
* `ApiSkill`/`ApiSearchResult` row (registry API response shape).
|
|
45
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
46
|
+
*/
|
|
47
|
+
export declare function deriveSecuritySummaryFromApiSkill(apiSkill: Pick<ApiSkill, 'last_scanned_at' | 'quarantined' | 'security_score' | 'security_findings'>): SecuritySummary | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Derive a `SecuritySummary` from a local-DB-shaped skill row's PRE-COMPUTED
|
|
50
|
+
* flat security fields (`securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
51
|
+
* `securityScannedAt` — a different shape from {@link deriveSecuritySummaryFromApiSkill}'s
|
|
52
|
+
* raw API-row columns).
|
|
53
|
+
*
|
|
54
|
+
* Same contract as {@link deriveSecuritySummaryFromApiSkill}: returns
|
|
55
|
+
* `undefined` when the skill has never been scanned (`securityScannedAt ==
|
|
56
|
+
* null`) — never scanned is a distinct state from "scanned but no verdict"
|
|
57
|
+
* and callers must not conflate the two by shipping a placeholder
|
|
58
|
+
* `{ passed: null, ... }` object for skills that were never scanned at all.
|
|
59
|
+
* `passed`/`riskScore` pass through RAW — never coerce/default to a
|
|
60
|
+
* fabricated value, which would misread as "confirmed clean/scanned."
|
|
61
|
+
*
|
|
62
|
+
* @param skill - Object carrying the pre-computed flat security fields
|
|
63
|
+
* present on both a local `Skill` repository row and `SkillData`
|
|
64
|
+
* (mcp-server's recommend matcher shape).
|
|
65
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
66
|
+
*/
|
|
67
|
+
export declare function deriveSecuritySummaryFromSkillRow(skill: {
|
|
68
|
+
securityPassed: boolean | null;
|
|
69
|
+
riskScore: number | null;
|
|
70
|
+
securityFindingsCount: number;
|
|
71
|
+
securityScannedAt: string | null;
|
|
72
|
+
}): SecuritySummary | undefined;
|
|
73
|
+
//# sourceMappingURL=security-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.d.ts","sourceRoot":"","sources":["../../../src/api/security-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,IAAI,CACZ,QAAQ,EACR,iBAAiB,GAAG,aAAa,GAAG,gBAAgB,GAAG,mBAAmB,CAC3E,GACA,eAAe,GAAG,SAAS,CAa7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iCAAiC,CAAC,KAAK,EAAE;IACvD,cAAc,EAAE,OAAO,GAAG,IAAI,CAAA;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC,GAAG,eAAe,GAAG,SAAS,CAW9B"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared derivation of a `SecuritySummary` from an API skill row,
|
|
3
|
+
* and from a pre-computed local-DB-shaped skill row.
|
|
4
|
+
* @module @skillsmith/core/api/security-summary
|
|
5
|
+
* @see SMI-4240: original inline derivation in mcp-server's get-skill.ts
|
|
6
|
+
* @see SMI-5562: extracted to mcp-server's utils/security-summary.ts so
|
|
7
|
+
* get-skill.ts, recommend.ts, and search.ts share a single implementation
|
|
8
|
+
* instead of triplicating the logic.
|
|
9
|
+
* @see SMI-5897 (C-15): moved here from mcp-server so `SkillsmithApiClient.toSkill()`
|
|
10
|
+
* (CLI path) can share the exact same derivation instead of hardcoding
|
|
11
|
+
* `riskScore: null, securityFindingsCount: 0, securityScannedAt: null,
|
|
12
|
+
* securityPassed: null` for every API-sourced skill — which caused CLI
|
|
13
|
+
* `info`/`search` to show "Not scanned" for skills MCP correctly reported
|
|
14
|
+
* as passed. Both `toSkill()` and mcp-server's tool call sites now import
|
|
15
|
+
* this one function, so the two surfaces cannot re-diverge.
|
|
16
|
+
* @see SMI-5897 (Wave 4 fix): `deriveSecuritySummaryFromSkillRow()` added
|
|
17
|
+
* alongside `deriveSecuritySummaryFromApiSkill()` — the local-DB-path
|
|
18
|
+
* sibling for the SAME undefined-when-never-scanned contract, but over the
|
|
19
|
+
* pre-computed `securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
20
|
+
* `securityScannedAt` field shape (as opposed to the raw API row's
|
|
21
|
+
* `last_scanned_at`/`quarantined`/`security_score`/`security_findings`
|
|
22
|
+
* columns). `recommend.helpers.ts`'s `buildDbFallbackRecommendation` had
|
|
23
|
+
* this exact ternary inline already; `search.helpers.ts`'s
|
|
24
|
+
* `mapLocalSkillToSearchResult` and `get-skill.ts`'s local-DB branch built
|
|
25
|
+
* the security object unconditionally, violating the contract for a
|
|
26
|
+
* never-scanned skill. All three now share this one function.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Derive a `SecuritySummary` from an API skill row's flat security columns.
|
|
30
|
+
*
|
|
31
|
+
* Returns `undefined` when the skill has never been scanned
|
|
32
|
+
* (`last_scanned_at == null`) — never scanned is a distinct state from
|
|
33
|
+
* "scanned but no verdict" and callers must not conflate the two by
|
|
34
|
+
* shipping a placeholder `{ passed: null, ... }` object for skills that
|
|
35
|
+
* were never scanned at all.
|
|
36
|
+
*
|
|
37
|
+
* `security_findings_count` is not a stored column — `findingsCount` is
|
|
38
|
+
* always derived from the length of the `security_findings` jsonb array
|
|
39
|
+
* (defensively 0 when the value is missing or not an array).
|
|
40
|
+
*
|
|
41
|
+
* @param apiSkill - Object carrying the flat security columns from an
|
|
42
|
+
* `ApiSkill`/`ApiSearchResult` row (registry API response shape).
|
|
43
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
44
|
+
*/
|
|
45
|
+
export function deriveSecuritySummaryFromApiSkill(apiSkill) {
|
|
46
|
+
if (apiSkill.last_scanned_at == null) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
passed: apiSkill.quarantined === true ? false : apiSkill.security_score == null ? null : true,
|
|
51
|
+
riskScore: apiSkill.security_score ?? null,
|
|
52
|
+
findingsCount: Array.isArray(apiSkill.security_findings)
|
|
53
|
+
? apiSkill.security_findings.length
|
|
54
|
+
: 0,
|
|
55
|
+
scannedAt: apiSkill.last_scanned_at,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Derive a `SecuritySummary` from a local-DB-shaped skill row's PRE-COMPUTED
|
|
60
|
+
* flat security fields (`securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
61
|
+
* `securityScannedAt` — a different shape from {@link deriveSecuritySummaryFromApiSkill}'s
|
|
62
|
+
* raw API-row columns).
|
|
63
|
+
*
|
|
64
|
+
* Same contract as {@link deriveSecuritySummaryFromApiSkill}: returns
|
|
65
|
+
* `undefined` when the skill has never been scanned (`securityScannedAt ==
|
|
66
|
+
* null`) — never scanned is a distinct state from "scanned but no verdict"
|
|
67
|
+
* and callers must not conflate the two by shipping a placeholder
|
|
68
|
+
* `{ passed: null, ... }` object for skills that were never scanned at all.
|
|
69
|
+
* `passed`/`riskScore` pass through RAW — never coerce/default to a
|
|
70
|
+
* fabricated value, which would misread as "confirmed clean/scanned."
|
|
71
|
+
*
|
|
72
|
+
* @param skill - Object carrying the pre-computed flat security fields
|
|
73
|
+
* present on both a local `Skill` repository row and `SkillData`
|
|
74
|
+
* (mcp-server's recommend matcher shape).
|
|
75
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
76
|
+
*/
|
|
77
|
+
export function deriveSecuritySummaryFromSkillRow(skill) {
|
|
78
|
+
if (skill.securityScannedAt == null) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
passed: skill.securityPassed,
|
|
83
|
+
riskScore: skill.riskScore,
|
|
84
|
+
findingsCount: skill.securityFindingsCount,
|
|
85
|
+
scannedAt: skill.securityScannedAt,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=security-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.js","sourceRoot":"","sources":["../../../src/api/security-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,iCAAiC,CAC/C,QAGC;IAED,IAAI,QAAQ,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;QACrC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QAC7F,SAAS,EAAE,QAAQ,CAAC,cAAc,IAAI,IAAI;QAC1C,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACtD,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,MAAM;YACnC,CAAC,CAAC,CAAC;QACL,SAAS,EAAE,QAAQ,CAAC,eAAe;KACpC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iCAAiC,CAAC,KAKjD;IACC,IAAI,KAAK,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC;QACpC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,cAAc;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa,EAAE,KAAK,CAAC,qBAAqB;QAC1C,SAAS,EAAE,KAAK,CAAC,iBAAiB;KACnC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5562: Unit coverage for the shared security-summary derivation helper,
|
|
3
|
+
* extracted from get-skill.ts's inline derivation (SMI-4240).
|
|
4
|
+
* SMI-5897 (C-15): moved from packages/mcp-server/src/utils/security-summary.test.ts
|
|
5
|
+
* to packages/core so the CLI (`SkillsmithApiClient.toSkill()`) and MCP tool
|
|
6
|
+
* call sites share and test one implementation.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=security-summary.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.test.d.ts","sourceRoot":"","sources":["../../../src/api/security-summary.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5562: Unit coverage for the shared security-summary derivation helper,
|
|
3
|
+
* extracted from get-skill.ts's inline derivation (SMI-4240).
|
|
4
|
+
* SMI-5897 (C-15): moved from packages/mcp-server/src/utils/security-summary.test.ts
|
|
5
|
+
* to packages/core so the CLI (`SkillsmithApiClient.toSkill()`) and MCP tool
|
|
6
|
+
* call sites share and test one implementation.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from 'vitest';
|
|
9
|
+
import { deriveSecuritySummaryFromApiSkill } from './security-summary.js';
|
|
10
|
+
describe('deriveSecuritySummaryFromApiSkill', () => {
|
|
11
|
+
it('returns undefined when the skill has never been scanned (last_scanned_at null)', () => {
|
|
12
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
13
|
+
last_scanned_at: null,
|
|
14
|
+
quarantined: false,
|
|
15
|
+
security_score: null,
|
|
16
|
+
security_findings: null,
|
|
17
|
+
});
|
|
18
|
+
expect(result).toBeUndefined();
|
|
19
|
+
});
|
|
20
|
+
it('returns undefined when last_scanned_at is undefined', () => {
|
|
21
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
22
|
+
last_scanned_at: undefined,
|
|
23
|
+
quarantined: undefined,
|
|
24
|
+
security_score: undefined,
|
|
25
|
+
security_findings: undefined,
|
|
26
|
+
});
|
|
27
|
+
expect(result).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
it('returns passed: false when quarantined, regardless of security_score', () => {
|
|
30
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
31
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
32
|
+
quarantined: true,
|
|
33
|
+
// A low score would otherwise read as "clean" — quarantined must win.
|
|
34
|
+
security_score: 0,
|
|
35
|
+
security_findings: [],
|
|
36
|
+
});
|
|
37
|
+
expect(result?.passed).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('returns passed: null when scanned but no security_score is recorded yet', () => {
|
|
40
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
41
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
42
|
+
quarantined: false,
|
|
43
|
+
security_score: null,
|
|
44
|
+
security_findings: null,
|
|
45
|
+
});
|
|
46
|
+
expect(result?.passed).toBeNull();
|
|
47
|
+
expect(result?.riskScore).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
it('returns passed: true for a clean scanned skill with a recorded score', () => {
|
|
50
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
51
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
52
|
+
quarantined: false,
|
|
53
|
+
security_score: 0,
|
|
54
|
+
security_findings: [],
|
|
55
|
+
});
|
|
56
|
+
expect(result).toEqual({
|
|
57
|
+
passed: true,
|
|
58
|
+
riskScore: 0,
|
|
59
|
+
findingsCount: 0,
|
|
60
|
+
scannedAt: '2026-06-01T00:00:00.000Z',
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
it('derives findingsCount from the security_findings array length', () => {
|
|
64
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
65
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
66
|
+
quarantined: false,
|
|
67
|
+
security_score: 42,
|
|
68
|
+
security_findings: [{ rule: 'a' }, { rule: 'b' }, { rule: 'c' }],
|
|
69
|
+
});
|
|
70
|
+
expect(result?.findingsCount).toBe(3);
|
|
71
|
+
});
|
|
72
|
+
it('defaults findingsCount to 0 when security_findings is not an array', () => {
|
|
73
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
74
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
75
|
+
quarantined: false,
|
|
76
|
+
security_score: 10,
|
|
77
|
+
// Defensive non-array case — should never happen at runtime (jsonb column),
|
|
78
|
+
// but the derivation must not throw or miscount.
|
|
79
|
+
security_findings: undefined,
|
|
80
|
+
});
|
|
81
|
+
expect(result?.findingsCount).toBe(0);
|
|
82
|
+
});
|
|
83
|
+
it('passes riskScore through as null (never a fabricated 0) when unscored', () => {
|
|
84
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
85
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
86
|
+
quarantined: false,
|
|
87
|
+
security_score: null,
|
|
88
|
+
security_findings: [{ rule: 'pending-review' }],
|
|
89
|
+
});
|
|
90
|
+
expect(result?.riskScore).toBeNull();
|
|
91
|
+
expect(result?.findingsCount).toBe(1);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=security-summary.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.test.js","sourceRoot":"","sources":["../../../src/api/security-summary.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AAEzE,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,IAAI;YACrB,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,IAAI;YACpB,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,SAAS;YAC1B,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,SAAS;YACzB,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,IAAI;YACjB,sEAAsE;YACtE,cAAc,EAAE,CAAC;YACjB,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,IAAI;YACpB,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QACjC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,CAAC;YACjB,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,CAAC;YAChB,SAAS,EAAE,0BAA0B;SACtC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,EAAE;YAClB,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;SACjE,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,EAAE;YAClB,4EAA4E;YAC5E,iDAAiD;YACjD,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,IAAI;YACpB,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;SAChD,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAA;QACpC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -17,9 +17,17 @@
|
|
|
17
17
|
* principle observe a partially-written file.
|
|
18
18
|
*
|
|
19
19
|
* This module fixes both:
|
|
20
|
-
* - {@link acquireConfigLock} serializes ALL writers (cross-process
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* - {@link acquireConfigLock} serializes ALL writers (cross-process) so a
|
|
21
|
+
* caller's full read-modify-write sequence is one atomic critical
|
|
22
|
+
* section. SMI-5883 Wave 2: this is now a thin wrapper over the shared
|
|
23
|
+
* two-level {@link acquireOwnedLock} primitive (`owned-lock.ts`) —
|
|
24
|
+
* staleness is determined by OWNER LIVENESS (not file age), and a stale
|
|
25
|
+
* lock is reclaimed only from inside a second, strict-no-auto-reclaim
|
|
26
|
+
* lock that serializes reclaim decisions. The prior age-based
|
|
27
|
+
* `STALE_LOCK_AGE_MS` force-clear is REMOVED, not tuned — a lock held
|
|
28
|
+
* legitimately longer than any timeout now correctly times out instead
|
|
29
|
+
* of being force-cleared out from under its live holder. See
|
|
30
|
+
* `owned-lock.ts`'s module docstring for the full soundness argument.
|
|
23
31
|
* - {@link atomicWriteFile} writes to a temp file in the same directory,
|
|
24
32
|
* then `renameSync`s it into place — POSIX guarantees `rename(2)` is
|
|
25
33
|
* atomic, so a concurrent reader (which never needs the lock — only
|
|
@@ -27,14 +35,26 @@
|
|
|
27
35
|
* never a torn write.
|
|
28
36
|
*/
|
|
29
37
|
/**
|
|
30
|
-
* Acquire an exclusive, cross-process lock guarding `configPath`.
|
|
38
|
+
* Acquire an exclusive, cross-process lock guarding `configPath`. Thin
|
|
39
|
+
* wrapper over {@link acquireOwnedLock} (SMI-5883 Wave 2) — preserves this
|
|
40
|
+
* function's signature and its `${configPath}.lock` path so no caller needs
|
|
41
|
+
* to change. Behaviour deltas vs the pre-SMI-5883 implementation (each
|
|
42
|
+
* covered by a test in `config-atomic-write.test.ts`):
|
|
31
43
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
44
|
+
* 1. A stale lock is cleared on OWNER DEATH, not on AGE. A lock held by a
|
|
45
|
+
* live process for longer than the old 10s threshold is no longer
|
|
46
|
+
* force-cleared — it now correctly waits, then times out.
|
|
47
|
+
* 2. A legacy bare-PID lock (this module's OWN pre-SMI-5883 on-disk format)
|
|
48
|
+
* is no longer cleared at all — `StuckLockError { reason:
|
|
49
|
+
* 'unreclaimable_legacy' }` (D-5: a legacy claim carries no `host`, so
|
|
50
|
+
* "dead on this host" cannot establish "dead").
|
|
51
|
+
* 3. The on-disk lock content changes from a bare PID to a v1 JSON record.
|
|
52
|
+
* No in-repo consumer parses it directly (only this module's own
|
|
53
|
+
* `acquireConfigLock`/release touch the file).
|
|
54
|
+
* 4. The timeout message keeps the stable prefix "Timed out waiting for
|
|
55
|
+
* config lock" (via `label: 'config lock'`) so existing assertions
|
|
56
|
+
* still match, with the failure reason and the manual unstick procedure
|
|
57
|
+
* appended.
|
|
38
58
|
*
|
|
39
59
|
* @param configPath - Path to the config file being guarded (NOT the lock
|
|
40
60
|
* file itself — the lock file is `${configPath}.lock`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-atomic-write.d.ts","sourceRoot":"","sources":["../../../src/config/config-atomic-write.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config-atomic-write.d.ts","sourceRoot":"","sources":["../../../src/config/config-atomic-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAeH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAgC,GAC1C,MAAM,IAAI,CAEZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAarF"}
|