@skillsmith/core 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/analysis/tree-sitter/pythonIncremental.d.ts +23 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.d.ts.map +1 -1
- package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.js +137 -0
- package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.js.map +1 -1
- package/dist/src/analysis/tree-sitter/pythonIncremental.js +83 -10
- package/dist/src/analysis/tree-sitter/pythonIncremental.js.map +1 -1
- package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.js +6 -1
- package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.js.map +1 -1
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +6 -0
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.test.d.ts +9 -0
- package/dist/src/api/client.test.d.ts.map +1 -0
- package/dist/src/api/client.test.js +81 -0
- package/dist/src/api/client.test.js.map +1 -0
- package/dist/src/config/audit-notify-state.d.ts +46 -0
- package/dist/src/config/audit-notify-state.d.ts.map +1 -0
- package/dist/src/config/audit-notify-state.js +55 -0
- package/dist/src/config/audit-notify-state.js.map +1 -0
- package/dist/src/config/audit-notify-state.test.d.ts +9 -0
- package/dist/src/config/audit-notify-state.test.d.ts.map +1 -0
- package/dist/src/config/audit-notify-state.test.js +63 -0
- package/dist/src/config/audit-notify-state.test.js.map +1 -0
- package/dist/src/config/index.d.ts +10 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/exports/services.d.ts +3 -1
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +9 -1
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +6 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/agent-config-merge.json-array.d.ts +29 -0
- package/dist/src/install/agent-config-merge.json-array.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.json-array.js +100 -0
- package/dist/src/install/agent-config-merge.json-array.js.map +1 -0
- package/dist/src/install/agent-config-merge.json.d.ts +37 -0
- package/dist/src/install/agent-config-merge.json.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.json.js +134 -0
- package/dist/src/install/agent-config-merge.json.js.map +1 -0
- package/dist/src/install/agent-config-merge.toml-block.d.ts +48 -0
- package/dist/src/install/agent-config-merge.toml-block.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.toml-block.js +107 -0
- package/dist/src/install/agent-config-merge.toml-block.js.map +1 -0
- package/dist/src/install/agent-config-merge.types.d.ts +87 -0
- package/dist/src/install/agent-config-merge.types.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.types.js +83 -0
- package/dist/src/install/agent-config-merge.types.js.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.d.ts +46 -0
- package/dist/src/install/agent-config-merge.yaml.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.js +133 -0
- package/dist/src/install/agent-config-merge.yaml.js.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.test.d.ts +2 -0
- package/dist/src/install/agent-config-merge.yaml.test.d.ts.map +1 -0
- package/dist/src/install/agent-config-merge.yaml.test.js +210 -0
- package/dist/src/install/agent-config-merge.yaml.test.js.map +1 -0
- package/dist/src/install/agent-harness-targets.d.ts +98 -0
- package/dist/src/install/agent-harness-targets.d.ts.map +1 -0
- package/dist/src/install/agent-harness-targets.js +154 -0
- package/dist/src/install/agent-harness-targets.js.map +1 -0
- package/dist/src/install/agent-home-relocate.d.ts +29 -0
- package/dist/src/install/agent-home-relocate.d.ts.map +1 -0
- package/dist/src/install/agent-home-relocate.js +38 -0
- package/dist/src/install/agent-home-relocate.js.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.d.ts +55 -0
- package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.js +109 -0
- package/dist/src/install/agent-manifest-path-guard.js.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.test.d.ts +2 -0
- package/dist/src/install/agent-manifest-path-guard.test.d.ts.map +1 -0
- package/dist/src/install/agent-manifest-path-guard.test.js +72 -0
- package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -0
- package/dist/src/install/agent-manifest.d.ts +58 -0
- package/dist/src/install/agent-manifest.d.ts.map +1 -0
- package/dist/src/install/agent-manifest.js +103 -0
- package/dist/src/install/agent-manifest.js.map +1 -0
- package/dist/src/install/agent-pack-installer.d.ts +39 -0
- package/dist/src/install/agent-pack-installer.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.entry.d.ts +55 -0
- package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.entry.js +90 -0
- package/dist/src/install/agent-pack-installer.entry.js.map +1 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.d.ts +33 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.js +59 -0
- package/dist/src/install/agent-pack-installer.fs-helpers.js.map +1 -0
- package/dist/src/install/agent-pack-installer.harness.d.ts +66 -0
- package/dist/src/install/agent-pack-installer.harness.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.harness.js +310 -0
- package/dist/src/install/agent-pack-installer.harness.js.map +1 -0
- package/dist/src/install/agent-pack-installer.js +221 -0
- package/dist/src/install/agent-pack-installer.js.map +1 -0
- package/dist/src/install/agent-pack-installer.preserve.test.d.ts +11 -0
- package/dist/src/install/agent-pack-installer.preserve.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.preserve.test.js +72 -0
- package/dist/src/install/agent-pack-installer.preserve.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.test.js +350 -0
- package/dist/src/install/agent-pack-installer.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.types.d.ts +51 -0
- package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.types.js +16 -0
- package/dist/src/install/agent-pack-installer.types.js.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.d.ts +43 -0
- package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.js +113 -0
- package/dist/src/install/agent-pack-uninstaller.js.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.test.d.ts +2 -0
- package/dist/src/install/agent-pack-uninstaller.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.test.js +212 -0
- package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -0
- package/dist/src/install/index.d.ts +7 -0
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +7 -0
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/paths.d.ts +1 -1
- package/dist/src/install/paths.d.ts.map +1 -1
- package/dist/src/install/paths.js +4 -0
- package/dist/src/install/paths.js.map +1 -1
- package/dist/src/install/paths.test.js +15 -0
- package/dist/src/install/paths.test.js.map +1 -1
- package/dist/src/journal/hash.d.ts +13 -0
- package/dist/src/journal/hash.d.ts.map +1 -0
- package/dist/src/journal/hash.js +16 -0
- package/dist/src/journal/hash.js.map +1 -0
- package/dist/src/journal/index.d.ts +15 -0
- package/dist/src/journal/index.d.ts.map +1 -0
- package/dist/src/journal/index.js +15 -0
- package/dist/src/journal/index.js.map +1 -0
- package/dist/src/journal/journal.test.d.ts +16 -0
- package/dist/src/journal/journal.test.d.ts.map +1 -0
- package/dist/src/journal/journal.test.js +171 -0
- package/dist/src/journal/journal.test.js.map +1 -0
- package/dist/src/journal/path.d.ts +44 -0
- package/dist/src/journal/path.d.ts.map +1 -0
- package/dist/src/journal/path.js +61 -0
- package/dist/src/journal/path.js.map +1 -0
- package/dist/src/journal/reader.d.ts +38 -0
- package/dist/src/journal/reader.d.ts.map +1 -0
- package/dist/src/journal/reader.js +93 -0
- package/dist/src/journal/reader.js.map +1 -0
- package/dist/src/journal/types.d.ts +87 -0
- package/dist/src/journal/types.d.ts.map +1 -0
- package/dist/src/journal/types.js +21 -0
- package/dist/src/journal/types.js.map +1 -0
- package/dist/src/journal/writer.d.ts +52 -0
- package/dist/src/journal/writer.d.ts.map +1 -0
- package/dist/src/journal/writer.js +125 -0
- package/dist/src/journal/writer.js.map +1 -0
- package/dist/src/logging/context.d.ts +58 -0
- package/dist/src/logging/context.d.ts.map +1 -0
- package/dist/src/logging/context.js +62 -0
- package/dist/src/logging/context.js.map +1 -0
- package/dist/src/logging/context.test.d.ts +14 -0
- package/dist/src/logging/context.test.d.ts.map +1 -0
- package/dist/src/logging/context.test.js +88 -0
- package/dist/src/logging/context.test.js.map +1 -0
- package/dist/src/logging/index.d.ts +13 -0
- package/dist/src/logging/index.d.ts.map +1 -0
- package/dist/src/logging/index.js +12 -0
- package/dist/src/logging/index.js.map +1 -0
- package/dist/src/logging/logger.d.ts +71 -0
- package/dist/src/logging/logger.d.ts.map +1 -0
- package/dist/src/logging/logger.js +264 -0
- package/dist/src/logging/logger.js.map +1 -0
- package/dist/src/logging/logger.test.d.ts +9 -0
- package/dist/src/logging/logger.test.d.ts.map +1 -0
- package/dist/src/logging/logger.test.js +320 -0
- package/dist/src/logging/logger.test.js.map +1 -0
- package/dist/src/logging/redact.d.ts +35 -0
- package/dist/src/logging/redact.d.ts.map +1 -0
- package/dist/src/logging/redact.js +152 -0
- package/dist/src/logging/redact.js.map +1 -0
- package/dist/src/logging/redact.test.d.ts +8 -0
- package/dist/src/logging/redact.test.d.ts.map +1 -0
- package/dist/src/logging/redact.test.js +330 -0
- package/dist/src/logging/redact.test.js.map +1 -0
- package/dist/src/logging/rotation.d.ts +75 -0
- package/dist/src/logging/rotation.d.ts.map +1 -0
- package/dist/src/logging/rotation.js +284 -0
- package/dist/src/logging/rotation.js.map +1 -0
- package/dist/src/logging/rotation.test.d.ts +11 -0
- package/dist/src/logging/rotation.test.d.ts.map +1 -0
- package/dist/src/logging/rotation.test.js +132 -0
- package/dist/src/logging/rotation.test.js.map +1 -0
- package/dist/src/logging/types.d.ts +69 -0
- package/dist/src/logging/types.d.ts.map +1 -0
- package/dist/src/logging/types.js +9 -0
- package/dist/src/logging/types.js.map +1 -0
- package/dist/src/paywall-triggers/index.d.ts +13 -0
- package/dist/src/paywall-triggers/index.d.ts.map +1 -0
- package/dist/src/paywall-triggers/index.js +13 -0
- package/dist/src/paywall-triggers/index.js.map +1 -0
- package/dist/src/paywall-triggers/path.d.ts +47 -0
- package/dist/src/paywall-triggers/path.d.ts.map +1 -0
- package/dist/src/paywall-triggers/path.js +73 -0
- package/dist/src/paywall-triggers/path.js.map +1 -0
- package/dist/src/paywall-triggers/store.d.ts +75 -0
- package/dist/src/paywall-triggers/store.d.ts.map +1 -0
- package/dist/src/paywall-triggers/store.js +122 -0
- package/dist/src/paywall-triggers/store.js.map +1 -0
- package/dist/src/paywall-triggers/store.test.d.ts +2 -0
- package/dist/src/paywall-triggers/store.test.d.ts.map +1 -0
- package/dist/src/paywall-triggers/store.test.js +121 -0
- package/dist/src/paywall-triggers/store.test.js.map +1 -0
- package/dist/src/paywall-triggers/types.d.ts +24 -0
- package/dist/src/paywall-triggers/types.d.ts.map +1 -0
- package/dist/src/paywall-triggers/types.js +13 -0
- package/dist/src/paywall-triggers/types.js.map +1 -0
- package/dist/src/security/index.d.ts +2 -0
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +4 -0
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.compound.d.ts +13 -0
- package/dist/src/security/scanner/SecurityScanner.compound.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.compound.js +127 -0
- package/dist/src/security/scanner/SecurityScanner.compound.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.hostile-update.d.ts +46 -0
- package/dist/src/security/scanner/SecurityScanner.hostile-update.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.hostile-update.js +209 -0
- package/dist/src/security/scanner/SecurityScanner.hostile-update.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.js +10 -1
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts +23 -0
- package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.pii.js +152 -0
- package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts +5 -12
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +63 -137
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/index.d.ts +2 -1
- package/dist/src/security/scanner/index.d.ts.map +1 -1
- package/dist/src/security/scanner/index.js +2 -0
- package/dist/src/security/scanner/index.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts +2 -0
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.js +79 -11
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/types.d.ts +23 -0
- package/dist/src/security/scanner/types.d.ts.map +1 -1
- package/dist/src/services/agent-pack/agent-pack.test.d.ts +18 -0
- package/dist/src/services/agent-pack/agent-pack.test.d.ts.map +1 -0
- package/dist/src/services/agent-pack/agent-pack.test.js +344 -0
- package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -0
- package/dist/src/services/agent-pack/hooks.d.ts +29 -0
- package/dist/src/services/agent-pack/hooks.d.ts.map +1 -0
- package/dist/src/services/agent-pack/hooks.js +139 -0
- package/dist/src/services/agent-pack/hooks.js.map +1 -0
- package/dist/src/services/agent-pack/index.d.ts +26 -0
- package/dist/src/services/agent-pack/index.d.ts.map +1 -0
- package/dist/src/services/agent-pack/index.js +109 -0
- package/dist/src/services/agent-pack/index.js.map +1 -0
- package/dist/src/services/agent-pack/prompt-source.d.ts +47 -0
- package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -0
- package/dist/src/services/agent-pack/prompt-source.js +182 -0
- package/dist/src/services/agent-pack/prompt-source.js.map +1 -0
- package/dist/src/services/agent-pack/shims.d.ts +40 -0
- package/dist/src/services/agent-pack/shims.d.ts.map +1 -0
- package/dist/src/services/agent-pack/shims.js +96 -0
- package/dist/src/services/agent-pack/shims.js.map +1 -0
- package/dist/src/services/agent-pack/skill-md.d.ts +35 -0
- package/dist/src/services/agent-pack/skill-md.d.ts.map +1 -0
- package/dist/src/services/agent-pack/skill-md.js +89 -0
- package/dist/src/services/agent-pack/skill-md.js.map +1 -0
- package/dist/src/services/agent-pack/types.d.ts +118 -0
- package/dist/src/services/agent-pack/types.d.ts.map +1 -0
- package/dist/src/services/agent-pack/types.js +61 -0
- package/dist/src/services/agent-pack/types.js.map +1 -0
- package/dist/src/services/agent-tool-profile.d.ts +59 -0
- package/dist/src/services/agent-tool-profile.d.ts.map +1 -0
- package/dist/src/services/agent-tool-profile.js +76 -0
- package/dist/src/services/agent-tool-profile.js.map +1 -0
- package/dist/src/services/agent-tool-profile.test.d.ts +2 -0
- package/dist/src/services/agent-tool-profile.test.d.ts.map +1 -0
- package/dist/src/services/agent-tool-profile.test.js +28 -0
- package/dist/src/services/agent-tool-profile.test.js.map +1 -0
- package/dist/src/services/bundled-sibling-scan.d.ts +111 -0
- package/dist/src/services/bundled-sibling-scan.d.ts.map +1 -0
- package/dist/src/services/bundled-sibling-scan.js +170 -0
- package/dist/src/services/bundled-sibling-scan.js.map +1 -0
- package/dist/src/services/skill-installation.io.d.ts +16 -5
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.js +63 -22
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.policy.d.ts +96 -0
- package/dist/src/services/skill-installation.policy.d.ts.map +1 -0
- package/dist/src/services/skill-installation.policy.js +144 -0
- package/dist/src/services/skill-installation.policy.js.map +1 -0
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +9 -3
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/sources/index.d.ts +1 -0
- package/dist/src/sources/index.d.ts.map +1 -1
- package/dist/src/sources/index.js +4 -0
- package/dist/src/sources/index.js.map +1 -1
- package/dist/src/sync/access-token.d.ts +27 -0
- package/dist/src/sync/access-token.d.ts.map +1 -0
- package/dist/src/sync/access-token.js +40 -0
- package/dist/src/sync/access-token.js.map +1 -0
- package/dist/src/sync/audit-notify-client.d.ts +83 -0
- package/dist/src/sync/audit-notify-client.d.ts.map +1 -0
- package/dist/src/sync/audit-notify-client.js +126 -0
- package/dist/src/sync/audit-notify-client.js.map +1 -0
- package/dist/src/sync/audit-notify-client.test.d.ts +14 -0
- package/dist/src/sync/audit-notify-client.test.d.ts.map +1 -0
- package/dist/src/sync/audit-notify-client.test.js +133 -0
- package/dist/src/sync/audit-notify-client.test.js.map +1 -0
- package/dist/src/sync/index.d.ts +2 -1
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/index.js +3 -1
- package/dist/src/sync/index.js.map +1 -1
- package/dist/src/sync/inventory-client.d.ts +16 -0
- package/dist/src/sync/inventory-client.d.ts.map +1 -1
- package/dist/src/sync/inventory-client.js +59 -16
- package/dist/src/sync/inventory-client.js.map +1 -1
- package/dist/src/sync/inventory-client.test.js +67 -1
- package/dist/src/sync/inventory-client.test.js.map +1 -1
- package/dist/src/sync/inventory-collector.d.ts.map +1 -1
- package/dist/src/sync/inventory-collector.js +32 -5
- package/dist/src/sync/inventory-collector.js.map +1 -1
- package/dist/src/sync/inventory-collector.test.js +50 -1
- package/dist/src/sync/inventory-collector.test.js.map +1 -1
- package/dist/src/sync/inventory-types.d.ts +9 -0
- package/dist/src/sync/inventory-types.d.ts.map +1 -1
- package/dist/src/sync/inventory-types.js +3 -0
- package/dist/src/sync/inventory-types.js.map +1 -1
- package/dist/src/telemetry/agent-marker.d.ts +137 -0
- package/dist/src/telemetry/agent-marker.d.ts.map +1 -0
- package/dist/src/telemetry/agent-marker.js +242 -0
- package/dist/src/telemetry/agent-marker.js.map +1 -0
- package/dist/src/telemetry/agent-marker.test.d.ts +13 -0
- package/dist/src/telemetry/agent-marker.test.d.ts.map +1 -0
- package/dist/src/telemetry/agent-marker.test.js +202 -0
- package/dist/src/telemetry/agent-marker.test.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +2 -1
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +6 -1
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/posthog.d.ts +25 -0
- package/dist/src/telemetry/posthog.d.ts.map +1 -1
- package/dist/src/telemetry/posthog.js +10 -1
- package/dist/src/telemetry/posthog.js.map +1 -1
- package/dist/src/telemetry/wrap.bench.js +5 -0
- package/dist/src/telemetry/wrap.bench.js.map +1 -1
- package/dist/src/telemetry/wrap.correlation.test.d.ts +20 -0
- package/dist/src/telemetry/wrap.correlation.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.correlation.test.js +174 -0
- package/dist/src/telemetry/wrap.correlation.test.js.map +1 -0
- package/dist/src/telemetry/wrap.d.ts +28 -7
- package/dist/src/telemetry/wrap.d.ts.map +1 -1
- package/dist/src/telemetry/wrap.gate.test.d.ts +22 -0
- package/dist/src/telemetry/wrap.gate.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.gate.test.js +202 -0
- package/dist/src/telemetry/wrap.gate.test.js.map +1 -0
- package/dist/src/telemetry/wrap.js +196 -52
- package/dist/src/telemetry/wrap.js.map +1 -1
- package/dist/src/telemetry/wrap.marker.test.d.ts +16 -0
- package/dist/src/telemetry/wrap.marker.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.marker.test.js +190 -0
- package/dist/src/telemetry/wrap.marker.test.js.map +1 -0
- package/dist/src/telemetry/wrap.test.js +14 -0
- package/dist/src/telemetry/wrap.test.js.map +1 -1
- package/dist/src/types.d.ts +6 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tests/SecurityScanner.exec.test.js +60 -0
- package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
- package/dist/tests/security/ContinuousSecurity.test.js +10 -4
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts +2 -0
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts.map +1 -0
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.js +126 -0
- package/dist/tests/security/SecurityScanner.chmod-evasion.test.js.map +1 -0
- package/dist/tests/security/chmod-compound.test.d.ts +2 -0
- package/dist/tests/security/chmod-compound.test.d.ts.map +1 -0
- package/dist/tests/security/chmod-compound.test.js +188 -0
- package/dist/tests/security/chmod-compound.test.js.map +1 -0
- package/dist/tests/security/pii-detection.test.js +24 -0
- package/dist/tests/security/pii-detection.test.js.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.d.ts +23 -7
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +206 -12
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-fp.test.d.ts +2 -0
- package/dist/tests/security/sensitive-path-fp.test.d.ts.map +1 -0
- package/dist/tests/security/sensitive-path-fp.test.js +142 -0
- package/dist/tests/security/sensitive-path-fp.test.js.map +1 -0
- package/dist/tests/services/bundled-sibling-scan.test.d.ts +2 -0
- package/dist/tests/services/bundled-sibling-scan.test.d.ts.map +1 -0
- package/dist/tests/services/bundled-sibling-scan.test.js +139 -0
- package/dist/tests/services/bundled-sibling-scan.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.test.js +166 -0
- package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.policy.test.d.ts +8 -0
- package/dist/tests/unit/services/skill-installation.policy.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.policy.test.js +151 -0
- package/dist/tests/unit/services/skill-installation.policy.test.js.map +1 -0
- package/package.json +28 -3
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5615: Shared structured JSON-line logger.
|
|
3
|
+
*
|
|
4
|
+
* Generalized from the dead `packages/mcp-server/src/logger.ts` (SMI-883
|
|
5
|
+
* redaction) into a surface-agnostic module usable by the MCP server, CLI,
|
|
6
|
+
* and VS Code extension independently — `createLogger(surface)` is a
|
|
7
|
+
* factory, not a singleton, so each host process can mint its own logger
|
|
8
|
+
* (optionally stamped with its own package version) while still writing to
|
|
9
|
+
* per-surface files that are safe to share across processes for the same
|
|
10
|
+
* surface (see `rotation.ts`).
|
|
11
|
+
*
|
|
12
|
+
* Call-site invariants (see
|
|
13
|
+
* docs/internal/implementation/production-error-logging.md §1 and the
|
|
14
|
+
* Shared-State / Coordination Audit table, F2/F3):
|
|
15
|
+
*
|
|
16
|
+
* - `getCorrelationId()` is read SYNCHRONOUSLY at the call site, inside
|
|
17
|
+
* `buildRecord`, never inside an async flush/rotation callback (F3) — a
|
|
18
|
+
* deferred read could observe a different call's (or no) correlation ID
|
|
19
|
+
* once the originating call's `AsyncLocalStorage` scope has unwound.
|
|
20
|
+
* - The full JSON-line record (including the synchronously-read
|
|
21
|
+
* correlation ID and synchronously-applied redaction) is built and
|
|
22
|
+
* `JSON.stringify`'d BEFORE handing the string off to `rotation.ts`'s
|
|
23
|
+
* serialized per-surface writer (F2) — only the actual disk write may
|
|
24
|
+
* complete asynchronously; by the time it starts, the record content is
|
|
25
|
+
* already frozen.
|
|
26
|
+
* - Logger calls never throw. Any failure while assembling or persisting a
|
|
27
|
+
* record falls back to `console.error`/`console.warn` (matching level,
|
|
28
|
+
* with `info`/`debug` also routed to `console.error`) rather than being
|
|
29
|
+
* fully silent — stderr remains the safety net of last resort. This
|
|
30
|
+
* differs from the old logger's "silently fail" comment intent, which is
|
|
31
|
+
* no longer acceptable once this is the only durable failure signal.
|
|
32
|
+
* - `warn`/`error` ALWAYS mirror to `console.warn`/`console.error`,
|
|
33
|
+
* synchronously, regardless of whether the disk write succeeds — this is
|
|
34
|
+
* NOT a failure-only fallback for those two levels (only `info`/`debug`
|
|
35
|
+
* use console purely as a write-failure fallback). This is what makes
|
|
36
|
+
* `logger.error`/`logger.warn` a safe drop-in replacement for existing
|
|
37
|
+
* `console.error`/`console.warn` call sites in the MCP server and CLI —
|
|
38
|
+
* the caller-visible terminal/stderr output stays identical to today,
|
|
39
|
+
* with redacted disk persistence added on top rather than instead of it.
|
|
40
|
+
*/
|
|
41
|
+
import { getCorrelationId } from './context.js';
|
|
42
|
+
import { redactSensitiveData, redactSensitiveObject, stripAnsi } from './redact.js';
|
|
43
|
+
import { writeLogLine } from './rotation.js';
|
|
44
|
+
const LEVEL_ORDER = {
|
|
45
|
+
debug: 0,
|
|
46
|
+
info: 1,
|
|
47
|
+
warn: 2,
|
|
48
|
+
error: 3,
|
|
49
|
+
};
|
|
50
|
+
const MAX_STACK_FRAMES = 20;
|
|
51
|
+
/**
|
|
52
|
+
* Accepts `'1'`/`'true'` (case-insensitive) — matches the existing
|
|
53
|
+
* `SKILLSMITH_<FEATURE>_DISABLE` convention, e.g.
|
|
54
|
+
* `isInventorySyncDisabledLocally()` at
|
|
55
|
+
* `packages/core/src/config/device-identity.ts:124`
|
|
56
|
+
* (`SKILLSMITH_INVENTORY_DISABLE`).
|
|
57
|
+
*/
|
|
58
|
+
function isLoggingDisabled() {
|
|
59
|
+
const val = process.env.SKILLSMITH_ERROR_LOG_DISABLE;
|
|
60
|
+
if (!val)
|
|
61
|
+
return false;
|
|
62
|
+
return val === '1' || val.toLowerCase() === 'true';
|
|
63
|
+
}
|
|
64
|
+
function configuredLevel() {
|
|
65
|
+
const raw = process.env.SKILLSMITH_LOG_LEVEL?.toLowerCase();
|
|
66
|
+
if (raw === 'debug' || raw === 'info' || raw === 'warn' || raw === 'error') {
|
|
67
|
+
return raw;
|
|
68
|
+
}
|
|
69
|
+
return 'warn';
|
|
70
|
+
}
|
|
71
|
+
function isLevelEnabled(level) {
|
|
72
|
+
return LEVEL_ORDER[level] >= LEVEL_ORDER[configuredLevel()];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fallback console channel for a level. `warn` mirrors to `console.warn`
|
|
76
|
+
* (stderr); everything else — including `info`/`debug`, which have no
|
|
77
|
+
* dedicated stderr-only console method — falls back to `console.error`
|
|
78
|
+
* (stderr) so a failure never lands on stdout. MCP servers must keep stdout
|
|
79
|
+
* clean for the stdio JSON-RPC transport; `console.log`/`console.info` write
|
|
80
|
+
* to stdout and would corrupt it.
|
|
81
|
+
*
|
|
82
|
+
* Always redacts `message` before printing (Mode-B diff-audit NEW-1): this is
|
|
83
|
+
* the last-resort channel when the redacted disk record couldn't be built or
|
|
84
|
+
* written, so it must independently uphold the same SMI-883 guarantee — never
|
|
85
|
+
* pass the raw, un-redacted message straight to `console.*`.
|
|
86
|
+
*/
|
|
87
|
+
function consoleFallback(level, message) {
|
|
88
|
+
const redacted = redactSensitiveData(message);
|
|
89
|
+
if (level === 'warn') {
|
|
90
|
+
console.warn(redacted);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.error(redacted);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// SMI-5615 Mode-B (Wave 2 pass): ANSI stripped BEFORE redaction on every
|
|
97
|
+
// disk-bound field — see `stripAnsi`'s doc comment in `redact.ts` for why
|
|
98
|
+
// (embedded chalk escape codes are log noise AND can defeat the redaction
|
|
99
|
+
// regex's leading word-boundary check).
|
|
100
|
+
function redactForDisk(text) {
|
|
101
|
+
return redactSensitiveData(stripAnsi(text));
|
|
102
|
+
}
|
|
103
|
+
function normalizeError(err) {
|
|
104
|
+
if (err instanceof Error) {
|
|
105
|
+
const frames = err.stack
|
|
106
|
+
? err.stack.split('\n').slice(0, MAX_STACK_FRAMES).join('\n')
|
|
107
|
+
: undefined;
|
|
108
|
+
return {
|
|
109
|
+
name: err.name,
|
|
110
|
+
message: redactForDisk(err.message),
|
|
111
|
+
stack: frames ? redactForDisk(frames) : undefined,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (typeof err === 'string') {
|
|
115
|
+
return { name: 'Error', message: redactForDisk(err) };
|
|
116
|
+
}
|
|
117
|
+
if (err && typeof err === 'object') {
|
|
118
|
+
const asRecord = err;
|
|
119
|
+
const name = typeof asRecord.name === 'string' ? asRecord.name : 'Error';
|
|
120
|
+
const message = typeof asRecord.message === 'string'
|
|
121
|
+
? asRecord.message
|
|
122
|
+
: safeStringify(redactSensitiveObject(asRecord));
|
|
123
|
+
return { name, message: redactForDisk(message) };
|
|
124
|
+
}
|
|
125
|
+
return { name: 'Error', message: redactForDisk(String(err)) };
|
|
126
|
+
}
|
|
127
|
+
function safeStringify(value) {
|
|
128
|
+
try {
|
|
129
|
+
return JSON.stringify(value) ?? String(value);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return '[unserializable value]';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Builds the complete, already-redacted `LogRecord` synchronously — this is
|
|
137
|
+
* the F2/F3 boundary: everything below runs on the calling stack, before any
|
|
138
|
+
* async write is even scheduled.
|
|
139
|
+
*/
|
|
140
|
+
function buildRecord(surface, level, version, message, details) {
|
|
141
|
+
// F3: correlation ID read synchronously, at the call site — never deferred.
|
|
142
|
+
const correlationId = getCorrelationId();
|
|
143
|
+
const { event, err, toolOrCommand, skillId, ...rest } = details ?? {};
|
|
144
|
+
const record = {
|
|
145
|
+
ts: new Date().toISOString(),
|
|
146
|
+
level,
|
|
147
|
+
surface,
|
|
148
|
+
event: typeof event === 'string' && event.length > 0 ? event : level,
|
|
149
|
+
msg: redactForDisk(message),
|
|
150
|
+
version,
|
|
151
|
+
pid: process.pid,
|
|
152
|
+
};
|
|
153
|
+
if (correlationId)
|
|
154
|
+
record.correlationId = correlationId;
|
|
155
|
+
if (typeof toolOrCommand === 'string')
|
|
156
|
+
record.toolOrCommand = toolOrCommand;
|
|
157
|
+
if (typeof skillId === 'string')
|
|
158
|
+
record.skillId = skillId;
|
|
159
|
+
if (err !== undefined)
|
|
160
|
+
record.err = normalizeError(err);
|
|
161
|
+
if (Object.keys(rest).length > 0) {
|
|
162
|
+
record.details = redactSensitiveObject(rest);
|
|
163
|
+
}
|
|
164
|
+
return record;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Hands the fully-built record off to `rotation.ts`, AND mirrors `warn`/
|
|
168
|
+
* `error` to console UNCONDITIONALLY (not only on a write failure) — per
|
|
169
|
+
* plan §1: "the logger writes to disk AND still emits to stderr for warn/
|
|
170
|
+
* error". This is the mechanism that lets `packages/mcp-server/src/index.ts`
|
|
171
|
+
* and `packages/cli/src` replace their scattered `console.error`/`warn`
|
|
172
|
+
* calls with `logger.error`/`warn` as a drop-in swap: the caller-visible
|
|
173
|
+
* terminal/stderr output must be identical to today, with disk persistence
|
|
174
|
+
* added on top — not replaced by it. `info`/`debug` are disk-only by design
|
|
175
|
+
* (routine/diagnostic detail, not something every caller needs to see live);
|
|
176
|
+
* they still reach console as a write-failure fallback like before, via the
|
|
177
|
+
* `catch` paths below, so a failure is never fully silent at any level.
|
|
178
|
+
*/
|
|
179
|
+
function persistRecord(surface, level, message, record) {
|
|
180
|
+
if (level === 'warn' || level === 'error') {
|
|
181
|
+
consoleFallback(level, message);
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
const line = safeStringifyRecord(record, message);
|
|
185
|
+
writeLogLine(surface, line).catch(() => {
|
|
186
|
+
if (level !== 'warn' && level !== 'error')
|
|
187
|
+
consoleFallback(level, message);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Synchronous failure calling into rotation.ts (should be effectively
|
|
192
|
+
// unreachable — `writeLogLine` itself only throws via its returned
|
|
193
|
+
// Promise — but the invariant is "never throws", full stop).
|
|
194
|
+
if (level !== 'warn' && level !== 'error')
|
|
195
|
+
consoleFallback(level, message);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function safeStringifyRecord(record, fallbackMessage) {
|
|
199
|
+
try {
|
|
200
|
+
return JSON.stringify(record);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Circular reference or similar inside `details`/`err` — degrade to a
|
|
204
|
+
// minimal, definitely-serializable record rather than losing the
|
|
205
|
+
// message and metadata entirely.
|
|
206
|
+
const { details: _details, err: _err, ...safe } = record;
|
|
207
|
+
return JSON.stringify({
|
|
208
|
+
...safe,
|
|
209
|
+
msg: `${redactForDisk(fallbackMessage)} [unserializable details/err omitted]`,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Creates a logger bound to `surface`. Independent instances for different
|
|
215
|
+
* surfaces (or the same surface with different `version` stamps) are safe to
|
|
216
|
+
* create concurrently — they only share state at the `rotation.ts` layer,
|
|
217
|
+
* which is itself safe for concurrent writers to the same surface (F2).
|
|
218
|
+
*/
|
|
219
|
+
export function createLogger(surface, options = {}) {
|
|
220
|
+
const version = options.version ?? 'unknown';
|
|
221
|
+
function log(level, message, details) {
|
|
222
|
+
try {
|
|
223
|
+
if (isLoggingDisabled())
|
|
224
|
+
return;
|
|
225
|
+
if (!isLevelEnabled(level))
|
|
226
|
+
return;
|
|
227
|
+
const record = buildRecord(surface, level, version, message, details);
|
|
228
|
+
persistRecord(surface, level, message, record);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// Absolute last resort — never let a logging call throw into the
|
|
232
|
+
// caller, regardless of what went wrong above.
|
|
233
|
+
try {
|
|
234
|
+
consoleFallback(level, message);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// Truly nothing left to do.
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
info: (message, details) => log('info', message, details),
|
|
243
|
+
warn: (message, details) => log('warn', message, details),
|
|
244
|
+
error: (message, details) => log('error', message, details),
|
|
245
|
+
debug: (message, details) => log('debug', message, details),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
const memoizedLoggers = new Map();
|
|
249
|
+
/**
|
|
250
|
+
* Memoized per-surface logger created with default options
|
|
251
|
+
* (`version: 'unknown'`). Prefer calling `createLogger(surface, { version })`
|
|
252
|
+
* once at each package's entrypoint so records carry that package's real
|
|
253
|
+
* version; `getLogger` is a convenience for call sites that don't need a
|
|
254
|
+
* custom version stamp and want a single shared instance per surface.
|
|
255
|
+
*/
|
|
256
|
+
export function getLogger(surface) {
|
|
257
|
+
let logger = memoizedLoggers.get(surface);
|
|
258
|
+
if (!logger) {
|
|
259
|
+
logger = createLogger(surface);
|
|
260
|
+
memoizedLoggers.set(surface, logger);
|
|
261
|
+
}
|
|
262
|
+
return logger;
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/logging/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5615: Tests for the shared `logger.ts` factory — crash-proofing,
|
|
3
|
+
* `SKILLSMITH_ERROR_LOG_DISABLE`, `SKILLSMITH_LOG_LEVEL` filtering,
|
|
4
|
+
* redaction-on-disk, and the correlation-ID call-site invariant (F3). All
|
|
5
|
+
* tests point `SKILLSMITH_LOG_DIR` at a temp directory — never the real
|
|
6
|
+
* `~/.skillsmith/logs/`.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=logger.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../../../src/logging/logger.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5615: Tests for the shared `logger.ts` factory — crash-proofing,
|
|
3
|
+
* `SKILLSMITH_ERROR_LOG_DISABLE`, `SKILLSMITH_LOG_LEVEL` filtering,
|
|
4
|
+
* redaction-on-disk, and the correlation-ID call-site invariant (F3). All
|
|
5
|
+
* tests point `SKILLSMITH_LOG_DIR` at a temp directory — never the real
|
|
6
|
+
* `~/.skillsmith/logs/`.
|
|
7
|
+
*/
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
9
|
+
import { mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { runWithCorrelationId } from './context.js';
|
|
13
|
+
import { createLogger } from './logger.js';
|
|
14
|
+
import { __resetLoggingStateForTests } from './rotation.js';
|
|
15
|
+
let tempDir;
|
|
16
|
+
let originalLogDir;
|
|
17
|
+
let originalDisable;
|
|
18
|
+
let originalLevel;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
tempDir = mkdtempSync(join(tmpdir(), 'skillsmith-logger-'));
|
|
21
|
+
originalLogDir = process.env.SKILLSMITH_LOG_DIR;
|
|
22
|
+
originalDisable = process.env.SKILLSMITH_ERROR_LOG_DISABLE;
|
|
23
|
+
originalLevel = process.env.SKILLSMITH_LOG_LEVEL;
|
|
24
|
+
process.env.SKILLSMITH_LOG_DIR = tempDir;
|
|
25
|
+
delete process.env.SKILLSMITH_ERROR_LOG_DISABLE;
|
|
26
|
+
delete process.env.SKILLSMITH_LOG_LEVEL;
|
|
27
|
+
});
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
await __resetLoggingStateForTests();
|
|
30
|
+
vi.restoreAllMocks();
|
|
31
|
+
const restore = (key, value) => {
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
delete process.env[key];
|
|
34
|
+
else
|
|
35
|
+
process.env[key] = value;
|
|
36
|
+
};
|
|
37
|
+
restore('SKILLSMITH_LOG_DIR', originalLogDir);
|
|
38
|
+
restore('SKILLSMITH_ERROR_LOG_DISABLE', originalDisable);
|
|
39
|
+
restore('SKILLSMITH_LOG_LEVEL', originalLevel);
|
|
40
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
41
|
+
});
|
|
42
|
+
function findLogFile(surfacePrefix) {
|
|
43
|
+
const files = readdirSync(tempDir).filter((f) => f.startsWith(surfacePrefix));
|
|
44
|
+
expect(files.length).toBeGreaterThan(0);
|
|
45
|
+
return join(tempDir, files[0]);
|
|
46
|
+
}
|
|
47
|
+
async function waitForLogFile(surfacePrefix) {
|
|
48
|
+
return vi.waitFor(() => {
|
|
49
|
+
const files = readdirSync(tempDir).filter((f) => f.startsWith(surfacePrefix));
|
|
50
|
+
expect(files.length).toBeGreaterThan(0);
|
|
51
|
+
return files;
|
|
52
|
+
}, { timeout: 2000, interval: 20 });
|
|
53
|
+
}
|
|
54
|
+
describe('logger.ts — redaction on disk', () => {
|
|
55
|
+
it('writes a redacted message and never persists the raw secret', async () => {
|
|
56
|
+
const logger = createLogger('mcp');
|
|
57
|
+
logger.error('Failed with token sk_live_abcdefghijklmnopqrstuvwx');
|
|
58
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
59
|
+
const content = await vi.waitFor(() => {
|
|
60
|
+
const text = readFileSync(findLogFile('skillsmith-mcp-'), 'utf8');
|
|
61
|
+
expect(text.length).toBeGreaterThan(0);
|
|
62
|
+
return text;
|
|
63
|
+
}, { timeout: 2000, interval: 20 });
|
|
64
|
+
expect(content).toContain('sk_live_[REDACTED]');
|
|
65
|
+
expect(content).not.toContain('abcdefghijklmnopqrstuvwx');
|
|
66
|
+
const record = JSON.parse(content.trim().split('\n')[0]);
|
|
67
|
+
expect(record.level).toBe('error');
|
|
68
|
+
expect(record.surface).toBe('mcp');
|
|
69
|
+
expect(record.msg).toContain('sk_live_[REDACTED]');
|
|
70
|
+
});
|
|
71
|
+
it('redacts secrets inside the `err` detail as well as the message', async () => {
|
|
72
|
+
const logger = createLogger('cli');
|
|
73
|
+
const err = new Error('token=ghp_1234567890abcdefghijklmnopqrstuvwxyz');
|
|
74
|
+
logger.error('tool call failed', { err });
|
|
75
|
+
await waitForLogFile('skillsmith-cli-');
|
|
76
|
+
const content = await vi.waitFor(() => {
|
|
77
|
+
const text = readFileSync(findLogFile('skillsmith-cli-'), 'utf8');
|
|
78
|
+
expect(text.length).toBeGreaterThan(0);
|
|
79
|
+
return text;
|
|
80
|
+
}, { timeout: 2000, interval: 20 });
|
|
81
|
+
const record = JSON.parse(content.trim().split('\n')[0]);
|
|
82
|
+
expect(record.err.message).toContain('ghp_[REDACTED]');
|
|
83
|
+
expect(record.err.message).not.toContain('1234567890abcdefghijklmnopqrstuvwxyz');
|
|
84
|
+
});
|
|
85
|
+
it('strips chalk/ANSI codes from the disk record and redacts a secret that immediately follows one (Mode-B Wave 2 finding)', async () => {
|
|
86
|
+
const logger = createLogger('cli');
|
|
87
|
+
const secret = 'sk_live_' + 'd'.repeat(24);
|
|
88
|
+
// Realistic CLI shape: chalk.red('Error:') directly adjacent to a secret,
|
|
89
|
+
// no space — the exact pattern the diff-audit flagged as a latent gap.
|
|
90
|
+
logger.error(`\x1b[31mError:\x1b[39m${secret} leaked`);
|
|
91
|
+
await waitForLogFile('skillsmith-cli-');
|
|
92
|
+
const content = readFileSync(findLogFile('skillsmith-cli-'), 'utf8');
|
|
93
|
+
const record = JSON.parse(content.trim().split('\n')[0]);
|
|
94
|
+
expect(record.msg).not.toContain('\x1b[');
|
|
95
|
+
expect(record.msg).not.toContain(secret);
|
|
96
|
+
expect(record.msg).toContain('sk_live_[REDACTED]');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('logger.ts — warn/error always mirror to console (plan §1, not just on write failure)', () => {
|
|
100
|
+
// Regression coverage for a Mode-B-adjacent finding caught during Wave 2
|
|
101
|
+
// wire-in: an earlier version of `persistRecord` only called
|
|
102
|
+
// `consoleFallback` when the disk write FAILED. That silently broke the
|
|
103
|
+
// whole point of swapping `console.error`/`warn` call sites in the MCP
|
|
104
|
+
// server and CLI for `logger.error`/`warn` — on the (normal) successful
|
|
105
|
+
// write path, callers would see NOTHING on screen, a regression from
|
|
106
|
+
// today's always-visible `console.error`. The plan is explicit: "the
|
|
107
|
+
// logger writes to disk AND still emits to stderr for warn/error" —
|
|
108
|
+
// unconditionally, not as a failure fallback.
|
|
109
|
+
it('mirrors error to console.error even when the disk write succeeds (writable dir)', async () => {
|
|
110
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
111
|
+
const logger = createLogger('mcp');
|
|
112
|
+
logger.error('boom');
|
|
113
|
+
// console mirror must be synchronous/immediate — a CLI user reading a
|
|
114
|
+
// terminal cannot wait for an async disk write to decide whether to print.
|
|
115
|
+
expect(errorSpy).toHaveBeenCalledWith('boom');
|
|
116
|
+
// ...and the disk record still lands too (both, not either/or).
|
|
117
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
118
|
+
});
|
|
119
|
+
it('mirrors warn to console.warn (not console.error) even when the disk write succeeds', async () => {
|
|
120
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
121
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
122
|
+
const logger = createLogger('cli');
|
|
123
|
+
logger.warn('careful');
|
|
124
|
+
expect(warnSpy).toHaveBeenCalledWith('careful');
|
|
125
|
+
expect(errorSpy).not.toHaveBeenCalled();
|
|
126
|
+
await waitForLogFile('skillsmith-cli-');
|
|
127
|
+
});
|
|
128
|
+
it('redacts the console-mirrored message too, not just the disk record', () => {
|
|
129
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
130
|
+
const logger = createLogger('mcp');
|
|
131
|
+
const secret = 'sk_live_' + 'b'.repeat(24);
|
|
132
|
+
logger.error(`auth failed with ${secret}`);
|
|
133
|
+
const calledWith = errorSpy.mock.calls.map((call) => call[0]).join('\n');
|
|
134
|
+
expect(calledWith).not.toContain(secret);
|
|
135
|
+
expect(calledWith).toContain('sk_live_[REDACTED]');
|
|
136
|
+
});
|
|
137
|
+
it('does NOT mirror info/debug to console on the successful-write path (disk-only by design)', async () => {
|
|
138
|
+
process.env.SKILLSMITH_LOG_LEVEL = 'debug';
|
|
139
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
140
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
141
|
+
const logger = createLogger('mcp');
|
|
142
|
+
logger.info('routine status');
|
|
143
|
+
logger.debug('verbose detail');
|
|
144
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
145
|
+
expect(errorSpy).not.toHaveBeenCalled();
|
|
146
|
+
expect(warnSpy).not.toHaveBeenCalled();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
describe('logger.ts — SKILLSMITH_ERROR_LOG_DISABLE', () => {
|
|
150
|
+
it('accepts "1" and skips writing entirely', async () => {
|
|
151
|
+
process.env.SKILLSMITH_ERROR_LOG_DISABLE = '1';
|
|
152
|
+
const logger = createLogger('mcp');
|
|
153
|
+
logger.error('should not be written');
|
|
154
|
+
// Give any accidental async write a chance to land before asserting absence.
|
|
155
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
156
|
+
expect(readdirSync(tempDir)).toHaveLength(0);
|
|
157
|
+
});
|
|
158
|
+
it('accepts "true" (case-insensitive)', async () => {
|
|
159
|
+
process.env.SKILLSMITH_ERROR_LOG_DISABLE = 'TRUE';
|
|
160
|
+
const logger = createLogger('mcp');
|
|
161
|
+
logger.error('should not be written');
|
|
162
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
163
|
+
expect(readdirSync(tempDir)).toHaveLength(0);
|
|
164
|
+
});
|
|
165
|
+
it('logs normally when unset', async () => {
|
|
166
|
+
const logger = createLogger('mcp');
|
|
167
|
+
logger.error('should be written');
|
|
168
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
describe('logger.ts — SKILLSMITH_LOG_LEVEL filtering', () => {
|
|
172
|
+
it('defaults to warn — info/debug are suppressed, warn/error are not', async () => {
|
|
173
|
+
const logger = createLogger('mcp');
|
|
174
|
+
logger.debug('debug message');
|
|
175
|
+
logger.info('info message');
|
|
176
|
+
logger.warn('warn message');
|
|
177
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
178
|
+
const content = readFileSync(findLogFile('skillsmith-mcp-'), 'utf8');
|
|
179
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
180
|
+
expect(lines).toHaveLength(1);
|
|
181
|
+
expect(JSON.parse(lines[0]).msg).toBe('warn message');
|
|
182
|
+
});
|
|
183
|
+
it('SKILLSMITH_LOG_LEVEL=debug allows every level through', async () => {
|
|
184
|
+
process.env.SKILLSMITH_LOG_LEVEL = 'debug';
|
|
185
|
+
const logger = createLogger('mcp');
|
|
186
|
+
logger.debug('debug message');
|
|
187
|
+
logger.info('info message');
|
|
188
|
+
logger.warn('warn message');
|
|
189
|
+
logger.error('error message');
|
|
190
|
+
await vi.waitFor(() => {
|
|
191
|
+
const files = readdirSync(tempDir).filter((f) => f.startsWith('skillsmith-mcp-'));
|
|
192
|
+
expect(files.length).toBeGreaterThan(0);
|
|
193
|
+
const content = readFileSync(join(tempDir, files[0]), 'utf8');
|
|
194
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
195
|
+
expect(lines).toHaveLength(4);
|
|
196
|
+
return lines;
|
|
197
|
+
}, { timeout: 2000, interval: 20 });
|
|
198
|
+
});
|
|
199
|
+
it('SKILLSMITH_LOG_LEVEL=error suppresses everything but error', async () => {
|
|
200
|
+
process.env.SKILLSMITH_LOG_LEVEL = 'error';
|
|
201
|
+
const logger = createLogger('mcp');
|
|
202
|
+
logger.warn('warn message');
|
|
203
|
+
logger.error('error message');
|
|
204
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
205
|
+
const content = await vi.waitFor(() => {
|
|
206
|
+
const text = readFileSync(findLogFile('skillsmith-mcp-'), 'utf8');
|
|
207
|
+
const lines = text.trim().split('\n').filter(Boolean);
|
|
208
|
+
expect(lines).toHaveLength(1);
|
|
209
|
+
return text;
|
|
210
|
+
}, { timeout: 2000, interval: 20 });
|
|
211
|
+
expect(JSON.parse(content.trim())).toMatchObject({ level: 'error', msg: 'error message' });
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe('logger.ts — crash-proofing', () => {
|
|
215
|
+
it('never throws and falls back to console when the log directory is unwritable', async () => {
|
|
216
|
+
// A regular FILE at the path where a directory is expected makes
|
|
217
|
+
// `mkdir(..., { recursive: true })` fail with ENOTDIR — portable and
|
|
218
|
+
// permission-independent (unlike relying on running as non-root).
|
|
219
|
+
const blockerFile = join(tempDir, 'blocker');
|
|
220
|
+
writeFileSync(blockerFile, '');
|
|
221
|
+
process.env.SKILLSMITH_LOG_DIR = join(blockerFile, 'logs');
|
|
222
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
223
|
+
const logger = createLogger('mcp');
|
|
224
|
+
expect(() => logger.error('this must not throw')).not.toThrow();
|
|
225
|
+
await vi.waitFor(() => {
|
|
226
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
227
|
+
}, { timeout: 2000, interval: 20 });
|
|
228
|
+
expect(errorSpy.mock.calls.some((call) => call[0] === 'this must not throw')).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
it('routes the warn-level fallback through console.warn, not console.error', async () => {
|
|
231
|
+
const blockerFile = join(tempDir, 'blocker');
|
|
232
|
+
writeFileSync(blockerFile, '');
|
|
233
|
+
process.env.SKILLSMITH_LOG_DIR = join(blockerFile, 'logs');
|
|
234
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
235
|
+
const logger = createLogger('cli');
|
|
236
|
+
expect(() => logger.warn('warn fallback')).not.toThrow();
|
|
237
|
+
await vi.waitFor(() => {
|
|
238
|
+
expect(warnSpy).toHaveBeenCalledWith('warn fallback');
|
|
239
|
+
}, { timeout: 2000, interval: 20 });
|
|
240
|
+
});
|
|
241
|
+
it('never throws even when `details` contains a circular reference, and still persists the record (NEW-2)', async () => {
|
|
242
|
+
const logger = createLogger('mcp');
|
|
243
|
+
const circular = {};
|
|
244
|
+
circular.self = circular;
|
|
245
|
+
expect(() => logger.error('circular details', { blob: circular })).not.toThrow();
|
|
246
|
+
// Before the cycle guard, `redactSensitiveObject` stack-overflowed on
|
|
247
|
+
// `circular`, which aborted the whole record and silently dropped it to
|
|
248
|
+
// the console-only fallback. With the guard, the record — including the
|
|
249
|
+
// correlationId/msg that have nothing to do with the cycle — must still
|
|
250
|
+
// reach disk, with only the offending branch marked `'[Circular]'`.
|
|
251
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
252
|
+
const content = readFileSync(findLogFile('skillsmith-mcp-'), 'utf8');
|
|
253
|
+
const record = JSON.parse(content.trim().split('\n')[0]);
|
|
254
|
+
expect(record.msg).toBe('circular details');
|
|
255
|
+
expect(record.details.blob.self).toBe('[Circular]');
|
|
256
|
+
});
|
|
257
|
+
it('redacts the message before the console fallback, not just the disk record (NEW-1)', async () => {
|
|
258
|
+
const blockerFile = join(tempDir, 'blocker');
|
|
259
|
+
writeFileSync(blockerFile, '');
|
|
260
|
+
process.env.SKILLSMITH_LOG_DIR = join(blockerFile, 'logs');
|
|
261
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
262
|
+
const logger = createLogger('mcp');
|
|
263
|
+
const secret = 'sk_live_' + 'a'.repeat(24);
|
|
264
|
+
expect(() => logger.error(`auth failed with ${secret}`)).not.toThrow();
|
|
265
|
+
await vi.waitFor(() => {
|
|
266
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
267
|
+
}, { timeout: 2000, interval: 20 });
|
|
268
|
+
const calledWith = errorSpy.mock.calls.map((call) => call[0]).join('\n');
|
|
269
|
+
expect(calledWith).not.toContain(secret);
|
|
270
|
+
expect(calledWith).toContain('sk_live_[REDACTED]');
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
describe('logger.ts — correlation ID (F3)', () => {
|
|
274
|
+
it('stamps the correlation ID installed for the calling async continuation', async () => {
|
|
275
|
+
const logger = createLogger('mcp');
|
|
276
|
+
await runWithCorrelationId('corr-abc-123', async () => {
|
|
277
|
+
logger.error('inside scope');
|
|
278
|
+
});
|
|
279
|
+
await waitForLogFile('skillsmith-mcp-');
|
|
280
|
+
const content = readFileSync(findLogFile('skillsmith-mcp-'), 'utf8');
|
|
281
|
+
const record = JSON.parse(content.trim().split('\n')[0]);
|
|
282
|
+
expect(record.correlationId).toBe('corr-abc-123');
|
|
283
|
+
});
|
|
284
|
+
it('omits correlationId when called outside any runWithCorrelationId scope', async () => {
|
|
285
|
+
const logger = createLogger('cli');
|
|
286
|
+
logger.error('outside scope');
|
|
287
|
+
await waitForLogFile('skillsmith-cli-');
|
|
288
|
+
const content = readFileSync(findLogFile('skillsmith-cli-'), 'utf8');
|
|
289
|
+
const record = JSON.parse(content.trim().split('\n')[0]);
|
|
290
|
+
expect(record.correlationId).toBeUndefined();
|
|
291
|
+
});
|
|
292
|
+
it('keeps two concurrent, overlapping scopes from observing each others correlation ID', async () => {
|
|
293
|
+
const logger = createLogger('vscode');
|
|
294
|
+
const seen = {};
|
|
295
|
+
await Promise.all([
|
|
296
|
+
runWithCorrelationId('corr-A', async () => {
|
|
297
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
298
|
+
logger.error('call A');
|
|
299
|
+
}),
|
|
300
|
+
runWithCorrelationId('corr-B', async () => {
|
|
301
|
+
logger.error('call B');
|
|
302
|
+
}),
|
|
303
|
+
]);
|
|
304
|
+
await vi.waitFor(() => {
|
|
305
|
+
const files = readdirSync(tempDir).filter((f) => f.startsWith('skillsmith-vscode-'));
|
|
306
|
+
expect(files.length).toBeGreaterThan(0);
|
|
307
|
+
const content = readFileSync(join(tempDir, files[0]), 'utf8');
|
|
308
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
309
|
+
expect(lines).toHaveLength(2);
|
|
310
|
+
for (const line of lines) {
|
|
311
|
+
const record = JSON.parse(line);
|
|
312
|
+
seen[record.msg] = record.correlationId;
|
|
313
|
+
}
|
|
314
|
+
return lines;
|
|
315
|
+
}, { timeout: 2000, interval: 20 });
|
|
316
|
+
expect(seen['call A']).toBe('corr-A');
|
|
317
|
+
expect(seen['call B']).toBe('corr-B');
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
//# sourceMappingURL=logger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.test.js","sourceRoot":"","sources":["../../../src/logging/logger.test.ts"],"names":[],"mappings":"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"}
|