@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,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-883 / SMI-5615: Sensitive-data redaction, ported VERBATIM from the dead
|
|
3
|
+
* `packages/mcp-server/src/logger.ts` (lines 11-107) into the shared
|
|
4
|
+
* `@skillsmith/core` logging module. Same regex patterns, same behavior,
|
|
5
|
+
* same test coverage (see `redact.test.ts`) — this is tested, working code
|
|
6
|
+
* relocated, not rewritten.
|
|
7
|
+
*/
|
|
8
|
+
export declare function stripAnsi(text: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* SMI-883: Redact sensitive data from text before logging
|
|
11
|
+
* Exported for testing purposes
|
|
12
|
+
*/
|
|
13
|
+
export declare function redactSensitiveData(text: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* SMI-883: Recursively redact sensitive data from objects
|
|
16
|
+
* Exported for testing purposes
|
|
17
|
+
*
|
|
18
|
+
* SMI-5615 Mode-B diff-audit NEW-2: `seen` guards against circular
|
|
19
|
+
* references. The original (dead) `mcp-server/src/logger.ts` version this was
|
|
20
|
+
* ported from had no cycle guard — harmless there since it was never called
|
|
21
|
+
* in production, but this module IS the production write path now, so a
|
|
22
|
+
* circular `details`/`err` object (e.g. a thrown object with a `cause` cycle)
|
|
23
|
+
* must degrade to `'[Circular]'` rather than stack-overflowing, which would
|
|
24
|
+
* otherwise abort the whole record (including the redacted `msg` and
|
|
25
|
+
* `correlationId`) and fall through to the raw-message console fallback.
|
|
26
|
+
*
|
|
27
|
+
* `seen` tracks only the CURRENT recursion path (ancestors), not every object
|
|
28
|
+
* visited overall — each object is removed again once its own subtree
|
|
29
|
+
* finishes (the `finally` below). This is deliberate: the same object
|
|
30
|
+
* appearing twice at sibling positions (a shared, non-cyclic reference — a
|
|
31
|
+
* DAG, not a cycle) must redact normally both times, not get falsely flagged
|
|
32
|
+
* `'[Circular]'` just because it was visited once already elsewhere.
|
|
33
|
+
*/
|
|
34
|
+
export declare function redactSensitiveObject(obj: unknown, seen?: WeakSet<object>): unknown;
|
|
35
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/logging/redact.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9C;AAmED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASxD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,OAAO,CAAC,MAAM,CAAiB,GACpC,OAAO,CAgBT"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-883 / SMI-5615: Sensitive-data redaction, ported VERBATIM from the dead
|
|
3
|
+
* `packages/mcp-server/src/logger.ts` (lines 11-107) into the shared
|
|
4
|
+
* `@skillsmith/core` logging module. Same regex patterns, same behavior,
|
|
5
|
+
* same test coverage (see `redact.test.ts`) — this is tested, working code
|
|
6
|
+
* relocated, not rewritten.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Strips ANSI/SGR escape sequences (`\x1b[...m` — the `chalk`-style color
|
|
10
|
+
* codes CLI call sites wrap error text in). SMI-5615 Mode-B diff-audit
|
|
11
|
+
* (Wave 2 pass): the disk-persisted record must not embed raw escape codes
|
|
12
|
+
* as log noise, AND a secret sitting immediately after an escape code's
|
|
13
|
+
* trailing letter (e.g. `\x1b[31msk_live_...`) can defeat
|
|
14
|
+
* `redactSensitiveData`'s leading `\b` word-boundary check — the `m`→`s`
|
|
15
|
+
* transition is word-to-word, not a boundary. Stripping ANSI BEFORE redacting
|
|
16
|
+
* closes that gap. Only applied on the DISK-persisted path (`logger.ts`'s
|
|
17
|
+
* `buildRecord`/`normalizeError`) — deliberately NOT applied to the
|
|
18
|
+
* console-mirrored path, which must keep chalk's colors for CLI terminal UX.
|
|
19
|
+
* Covers chalk's actual output (SGR codes only); not a full ANSI/VT100 strip.
|
|
20
|
+
*/
|
|
21
|
+
// \x1b is the intentional ESC byte an SGR sequence always starts with; this
|
|
22
|
+
// is the same pattern the widely-used `strip-ansi` npm package uses (also
|
|
23
|
+
// eslint-disabled there).
|
|
24
|
+
// eslint-disable-next-line no-control-regex
|
|
25
|
+
const ANSI_SGR_PATTERN = /\x1b\[[0-9;]*m/g;
|
|
26
|
+
export function stripAnsi(text) {
|
|
27
|
+
if (!text)
|
|
28
|
+
return text;
|
|
29
|
+
return text.replace(ANSI_SGR_PATTERN, '');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* SMI-883: Sensitive data patterns to redact before logging
|
|
33
|
+
* Prevents API keys, tokens, passwords, and secrets from being written to disk
|
|
34
|
+
*/
|
|
35
|
+
const SENSITIVE_PATTERNS = [
|
|
36
|
+
// GitHub tokens
|
|
37
|
+
{ pattern: /\b(ghp_[a-zA-Z0-9]{36})\b/g, replacement: 'ghp_[REDACTED]' },
|
|
38
|
+
{ pattern: /\b(github_pat_[a-zA-Z0-9_]{22,})\b/g, replacement: 'github_pat_[REDACTED]' },
|
|
39
|
+
{ pattern: /\b(gho_[a-zA-Z0-9]{36})\b/g, replacement: 'gho_[REDACTED]' },
|
|
40
|
+
{ pattern: /\b(ghs_[a-zA-Z0-9]{36})\b/g, replacement: 'ghs_[REDACTED]' },
|
|
41
|
+
{ pattern: /\b(ghu_[a-zA-Z0-9]{36})\b/g, replacement: 'ghu_[REDACTED]' },
|
|
42
|
+
{ pattern: /\b(ghr_[a-zA-Z0-9]{36})\b/g, replacement: 'ghr_[REDACTED]' },
|
|
43
|
+
// Linear API keys
|
|
44
|
+
{ pattern: /\b(lin_api_[a-zA-Z0-9]{32,})\b/g, replacement: 'lin_api_[REDACTED]' },
|
|
45
|
+
// Stripe keys
|
|
46
|
+
{ pattern: /\b(sk_live_[a-zA-Z0-9]{24,})\b/g, replacement: 'sk_live_[REDACTED]' },
|
|
47
|
+
{ pattern: /\b(sk_test_[a-zA-Z0-9]{24,})\b/g, replacement: 'sk_test_[REDACTED]' },
|
|
48
|
+
{ pattern: /\b(pk_live_[a-zA-Z0-9]{24,})\b/g, replacement: 'pk_live_[REDACTED]' },
|
|
49
|
+
{ pattern: /\b(pk_test_[a-zA-Z0-9]{24,})\b/g, replacement: 'pk_test_[REDACTED]' },
|
|
50
|
+
// OpenAI API keys
|
|
51
|
+
{ pattern: /\b(sk-[a-zA-Z0-9]{48,})\b/g, replacement: 'sk-[REDACTED]' },
|
|
52
|
+
// Anthropic API keys
|
|
53
|
+
{ pattern: /\b(sk-ant-[a-zA-Z0-9-]{32,})\b/g, replacement: 'sk-ant-[REDACTED]' },
|
|
54
|
+
// AWS keys
|
|
55
|
+
{ pattern: /\b(AKIA[A-Z0-9]{16})\b/g, replacement: 'AKIA[REDACTED]' },
|
|
56
|
+
// Slack tokens
|
|
57
|
+
{ pattern: /\b(xox[boaprs]-[a-zA-Z0-9-]{10,})\b/g, replacement: 'xox*-[REDACTED]' },
|
|
58
|
+
// npm tokens
|
|
59
|
+
{ pattern: /\b(npm_[a-zA-Z0-9]{36})\b/g, replacement: 'npm_[REDACTED]' },
|
|
60
|
+
// Bearer tokens
|
|
61
|
+
{ pattern: /\bBearer\s+([a-zA-Z0-9_\-.]{20,})/gi, replacement: 'Bearer [REDACTED]' },
|
|
62
|
+
// Basic auth
|
|
63
|
+
{ pattern: /\bBasic\s+([a-zA-Z0-9+/=]{20,})/gi, replacement: 'Basic [REDACTED]' },
|
|
64
|
+
// JWT tokens
|
|
65
|
+
{
|
|
66
|
+
pattern: /\beyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]+\b/g,
|
|
67
|
+
replacement: '[JWT_REDACTED]',
|
|
68
|
+
},
|
|
69
|
+
// Generic API key patterns
|
|
70
|
+
{
|
|
71
|
+
pattern: /\b(api[_-]?key|apikey)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
|
|
72
|
+
replacement: 'api_key=[REDACTED]',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
pattern: /\b(token|auth[_-]?token)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
|
|
76
|
+
replacement: 'token=[REDACTED]',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
pattern: /\b(password|passwd|pwd)\s*[=:]\s*["']?([^"'\s]{4,})["']?/gi,
|
|
80
|
+
replacement: 'password=[REDACTED]',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
pattern: /\b(secret|client[_-]?secret)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
|
|
84
|
+
replacement: 'secret=[REDACTED]',
|
|
85
|
+
},
|
|
86
|
+
// Connection strings with passwords
|
|
87
|
+
{ pattern: /(:\/\/[^:]+:)([^@]+)(@)/gi, replacement: '$1[REDACTED]$3' },
|
|
88
|
+
// Private keys
|
|
89
|
+
{
|
|
90
|
+
pattern: /-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----/gi,
|
|
91
|
+
replacement: '-----[PRIVATE KEY REDACTED]-----',
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
/**
|
|
95
|
+
* SMI-883: Redact sensitive data from text before logging
|
|
96
|
+
* Exported for testing purposes
|
|
97
|
+
*/
|
|
98
|
+
export function redactSensitiveData(text) {
|
|
99
|
+
if (!text)
|
|
100
|
+
return text;
|
|
101
|
+
let redacted = text;
|
|
102
|
+
for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
|
|
103
|
+
// Reset lastIndex for global regex patterns to ensure all matches are found
|
|
104
|
+
pattern.lastIndex = 0;
|
|
105
|
+
redacted = redacted.replace(pattern, replacement);
|
|
106
|
+
}
|
|
107
|
+
return redacted;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* SMI-883: Recursively redact sensitive data from objects
|
|
111
|
+
* Exported for testing purposes
|
|
112
|
+
*
|
|
113
|
+
* SMI-5615 Mode-B diff-audit NEW-2: `seen` guards against circular
|
|
114
|
+
* references. The original (dead) `mcp-server/src/logger.ts` version this was
|
|
115
|
+
* ported from had no cycle guard — harmless there since it was never called
|
|
116
|
+
* in production, but this module IS the production write path now, so a
|
|
117
|
+
* circular `details`/`err` object (e.g. a thrown object with a `cause` cycle)
|
|
118
|
+
* must degrade to `'[Circular]'` rather than stack-overflowing, which would
|
|
119
|
+
* otherwise abort the whole record (including the redacted `msg` and
|
|
120
|
+
* `correlationId`) and fall through to the raw-message console fallback.
|
|
121
|
+
*
|
|
122
|
+
* `seen` tracks only the CURRENT recursion path (ancestors), not every object
|
|
123
|
+
* visited overall — each object is removed again once its own subtree
|
|
124
|
+
* finishes (the `finally` below). This is deliberate: the same object
|
|
125
|
+
* appearing twice at sibling positions (a shared, non-cyclic reference — a
|
|
126
|
+
* DAG, not a cycle) must redact normally both times, not get falsely flagged
|
|
127
|
+
* `'[Circular]'` just because it was visited once already elsewhere.
|
|
128
|
+
*/
|
|
129
|
+
export function redactSensitiveObject(obj, seen = new WeakSet()) {
|
|
130
|
+
if (obj === null || obj === undefined)
|
|
131
|
+
return obj;
|
|
132
|
+
if (typeof obj === 'string')
|
|
133
|
+
return redactSensitiveData(obj);
|
|
134
|
+
if (typeof obj !== 'object')
|
|
135
|
+
return obj;
|
|
136
|
+
if (seen.has(obj))
|
|
137
|
+
return '[Circular]';
|
|
138
|
+
seen.add(obj);
|
|
139
|
+
try {
|
|
140
|
+
if (Array.isArray(obj))
|
|
141
|
+
return obj.map((item) => redactSensitiveObject(item, seen));
|
|
142
|
+
const result = {};
|
|
143
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
144
|
+
result[key] = redactSensitiveObject(value, seen);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
seen.delete(obj);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/logging/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-883 / SMI-5615: Tests for logger sensitive data redaction, ported from
|
|
3
|
+
* `packages/mcp-server/tests/unit/logger.test.ts` — same coverage, new
|
|
4
|
+
* location (`@skillsmith/core`'s `logging/redact.ts`).
|
|
5
|
+
* Ensures API keys, tokens, passwords, and secrets are never written to disk.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=redact.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.test.d.ts","sourceRoot":"","sources":["../../../src/logging/redact.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-883 / SMI-5615: Tests for logger sensitive data redaction, ported from
|
|
3
|
+
* `packages/mcp-server/tests/unit/logger.test.ts` — same coverage, new
|
|
4
|
+
* location (`@skillsmith/core`'s `logging/redact.ts`).
|
|
5
|
+
* Ensures API keys, tokens, passwords, and secrets are never written to disk.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import { redactSensitiveData, redactSensitiveObject, stripAnsi } from './redact.js';
|
|
9
|
+
describe('SMI-883: Logger Sensitive Data Redaction', () => {
|
|
10
|
+
describe('redactSensitiveData', () => {
|
|
11
|
+
describe('GitHub tokens', () => {
|
|
12
|
+
it('should redact classic personal access tokens (ghp_)', () => {
|
|
13
|
+
const input = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyz';
|
|
14
|
+
const result = redactSensitiveData(input);
|
|
15
|
+
expect(result).toBe('Token: ghp_[REDACTED]');
|
|
16
|
+
expect(result).not.toContain('1234567890');
|
|
17
|
+
});
|
|
18
|
+
it('should redact fine-grained personal access tokens (github_pat_)', () => {
|
|
19
|
+
const input = 'Using github_pat_abcdefghijklmnopqrstuvwx12345';
|
|
20
|
+
const result = redactSensitiveData(input);
|
|
21
|
+
expect(result).toBe('Using github_pat_[REDACTED]');
|
|
22
|
+
});
|
|
23
|
+
it('should redact OAuth tokens (gho_)', () => {
|
|
24
|
+
const input = 'OAuth: gho_1234567890abcdefghijklmnopqrstuvwxyz';
|
|
25
|
+
const result = redactSensitiveData(input);
|
|
26
|
+
expect(result).toBe('OAuth: gho_[REDACTED]');
|
|
27
|
+
});
|
|
28
|
+
it('should redact server-to-server tokens (ghs_)', () => {
|
|
29
|
+
const input = 'Server: ghs_1234567890abcdefghijklmnopqrstuvwxyz';
|
|
30
|
+
const result = redactSensitiveData(input);
|
|
31
|
+
expect(result).toBe('Server: ghs_[REDACTED]');
|
|
32
|
+
});
|
|
33
|
+
it('should redact user-to-server tokens (ghu_)', () => {
|
|
34
|
+
const input = 'User: ghu_1234567890abcdefghijklmnopqrstuvwxyz';
|
|
35
|
+
const result = redactSensitiveData(input);
|
|
36
|
+
expect(result).toBe('User: ghu_[REDACTED]');
|
|
37
|
+
});
|
|
38
|
+
it('should redact refresh tokens (ghr_)', () => {
|
|
39
|
+
const input = 'Refresh: ghr_1234567890abcdefghijklmnopqrstuvwxyz';
|
|
40
|
+
const result = redactSensitiveData(input);
|
|
41
|
+
expect(result).toBe('Refresh: ghr_[REDACTED]');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('Linear API keys', () => {
|
|
45
|
+
it('should redact Linear API keys (lin_api_)', () => {
|
|
46
|
+
const input = 'LINEAR_API_KEY=lin_api_abcdefghijklmnopqrstuvwxyz123456';
|
|
47
|
+
const result = redactSensitiveData(input);
|
|
48
|
+
expect(result).toContain('lin_api_[REDACTED]');
|
|
49
|
+
expect(result).not.toContain('abcdefghij');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe('Stripe keys', () => {
|
|
53
|
+
it('should redact live secret keys (sk_live_)', () => {
|
|
54
|
+
const input = 'STRIPE_KEY=sk_live_abcdefghijklmnopqrstuvwx';
|
|
55
|
+
const result = redactSensitiveData(input);
|
|
56
|
+
expect(result).toContain('sk_live_[REDACTED]');
|
|
57
|
+
});
|
|
58
|
+
it('should redact test secret keys (sk_test_)', () => {
|
|
59
|
+
const input = 'STRIPE_KEY=sk_test_abcdefghijklmnopqrstuvwx';
|
|
60
|
+
const result = redactSensitiveData(input);
|
|
61
|
+
expect(result).toContain('sk_test_[REDACTED]');
|
|
62
|
+
});
|
|
63
|
+
it('should redact live publishable keys (pk_live_)', () => {
|
|
64
|
+
const input = 'STRIPE_PK=pk_live_abcdefghijklmnopqrstuvwx';
|
|
65
|
+
const result = redactSensitiveData(input);
|
|
66
|
+
expect(result).toContain('pk_live_[REDACTED]');
|
|
67
|
+
});
|
|
68
|
+
it('should redact test publishable keys (pk_test_)', () => {
|
|
69
|
+
const input = 'STRIPE_PK=pk_test_abcdefghijklmnopqrstuvwx';
|
|
70
|
+
const result = redactSensitiveData(input);
|
|
71
|
+
expect(result).toContain('pk_test_[REDACTED]');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('OpenAI API keys', () => {
|
|
75
|
+
it('should redact OpenAI API keys (sk-)', () => {
|
|
76
|
+
const input = 'OPENAI_API_KEY=sk-abcdefghijklmnopqrstuvwxyz1234567890abcdefghijkl';
|
|
77
|
+
const result = redactSensitiveData(input);
|
|
78
|
+
expect(result).toContain('sk-[REDACTED]');
|
|
79
|
+
expect(result).not.toContain('abcdefghij');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('Anthropic API keys', () => {
|
|
83
|
+
it('should redact Anthropic API keys (sk-ant-)', () => {
|
|
84
|
+
const input = 'ANTHROPIC_API_KEY=sk-ant-api03-abcdefghijklmnopqrstuvwxyz12';
|
|
85
|
+
const result = redactSensitiveData(input);
|
|
86
|
+
expect(result).toContain('sk-ant-[REDACTED]');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('AWS keys', () => {
|
|
90
|
+
it('should redact AWS access key IDs (AKIA)', () => {
|
|
91
|
+
const input = 'AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE';
|
|
92
|
+
const result = redactSensitiveData(input);
|
|
93
|
+
expect(result).toContain('AKIA[REDACTED]');
|
|
94
|
+
expect(result).not.toContain('IOSFODNN7EXAMPLE');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('Slack tokens', () => {
|
|
98
|
+
it('should redact bot tokens (xoxb-)', () => {
|
|
99
|
+
const input = 'SLACK_TOKEN=xoxb-123456789012-1234567890123-abcdefghijklmnop';
|
|
100
|
+
const result = redactSensitiveData(input);
|
|
101
|
+
expect(result).toContain('xox*-[REDACTED]');
|
|
102
|
+
});
|
|
103
|
+
it('should redact user tokens (xoxp-)', () => {
|
|
104
|
+
const input = 'SLACK_TOKEN=xoxp-123456789012-1234567890123-abcdefghijklmnop';
|
|
105
|
+
const result = redactSensitiveData(input);
|
|
106
|
+
expect(result).toContain('xox*-[REDACTED]');
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('npm tokens', () => {
|
|
110
|
+
it('should redact npm tokens (npm_)', () => {
|
|
111
|
+
const input = 'NPM_TOKEN=npm_abcdefghijklmnopqrstuvwxyz1234567890';
|
|
112
|
+
const result = redactSensitiveData(input);
|
|
113
|
+
expect(result).toContain('npm_[REDACTED]');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('Bearer and Basic auth', () => {
|
|
117
|
+
it('should redact Bearer tokens', () => {
|
|
118
|
+
const input = 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
|
|
119
|
+
const result = redactSensitiveData(input);
|
|
120
|
+
expect(result).toContain('Bearer [REDACTED]');
|
|
121
|
+
});
|
|
122
|
+
it('should redact Basic auth credentials', () => {
|
|
123
|
+
const input = 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQxMjM0NTY=';
|
|
124
|
+
const result = redactSensitiveData(input);
|
|
125
|
+
expect(result).toContain('Basic [REDACTED]');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
describe('JWT tokens', () => {
|
|
129
|
+
it('should redact JWT tokens', () => {
|
|
130
|
+
const input = 'Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
|
|
131
|
+
const result = redactSensitiveData(input);
|
|
132
|
+
expect(result).toContain('[JWT_REDACTED]');
|
|
133
|
+
expect(result).not.toContain('eyJzdWI');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('Generic patterns', () => {
|
|
137
|
+
it('should redact api_key assignments', () => {
|
|
138
|
+
const input = 'config.api_key = "my_secret_api_key_12345"';
|
|
139
|
+
const result = redactSensitiveData(input);
|
|
140
|
+
expect(result).toContain('api_key=[REDACTED]');
|
|
141
|
+
});
|
|
142
|
+
it('should redact password assignments', () => {
|
|
143
|
+
const input = 'password: "supersecret123"';
|
|
144
|
+
const result = redactSensitiveData(input);
|
|
145
|
+
expect(result).toContain('password=[REDACTED]');
|
|
146
|
+
});
|
|
147
|
+
it('should redact secret assignments', () => {
|
|
148
|
+
const input = 'client_secret = "abcdefghijklmnop"';
|
|
149
|
+
const result = redactSensitiveData(input);
|
|
150
|
+
expect(result).toContain('secret=[REDACTED]');
|
|
151
|
+
});
|
|
152
|
+
it('should redact token assignments', () => {
|
|
153
|
+
const input = 'auth_token: "my_auth_token_value"';
|
|
154
|
+
const result = redactSensitiveData(input);
|
|
155
|
+
expect(result).toContain('token=[REDACTED]');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
describe('Connection strings', () => {
|
|
159
|
+
it('should redact passwords in connection strings', () => {
|
|
160
|
+
const input = 'postgresql://user:mysecretpassword@localhost:5432/db';
|
|
161
|
+
const result = redactSensitiveData(input);
|
|
162
|
+
expect(result).toBe('postgresql://user:[REDACTED]@localhost:5432/db');
|
|
163
|
+
expect(result).not.toContain('mysecretpassword');
|
|
164
|
+
});
|
|
165
|
+
it('should redact passwords in MongoDB connection strings', () => {
|
|
166
|
+
const input = 'mongodb://admin:p4ssw0rd123@cluster.mongodb.net/mydb';
|
|
167
|
+
const result = redactSensitiveData(input);
|
|
168
|
+
expect(result).toContain('[REDACTED]@cluster');
|
|
169
|
+
expect(result).not.toContain('p4ssw0rd123');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('Private keys', () => {
|
|
173
|
+
it('should redact RSA private keys', () => {
|
|
174
|
+
const input = `-----BEGIN RSA PRIVATE KEY-----
|
|
175
|
+
MIIEpAIBAAKCAQEA0Z3VS5JJcds3xfn/ygWyF8PbnGy
|
|
176
|
+
-----END RSA PRIVATE KEY-----`;
|
|
177
|
+
const result = redactSensitiveData(input);
|
|
178
|
+
expect(result).toBe('-----[PRIVATE KEY REDACTED]-----');
|
|
179
|
+
expect(result).not.toContain('MIIEpAIBAAKCAQEA');
|
|
180
|
+
});
|
|
181
|
+
it('should redact generic private keys', () => {
|
|
182
|
+
const input = `-----BEGIN PRIVATE KEY-----
|
|
183
|
+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEA
|
|
184
|
+
-----END PRIVATE KEY-----`;
|
|
185
|
+
const result = redactSensitiveData(input);
|
|
186
|
+
expect(result).toBe('-----[PRIVATE KEY REDACTED]-----');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
describe('Edge cases', () => {
|
|
190
|
+
it('should handle empty strings', () => {
|
|
191
|
+
expect(redactSensitiveData('')).toBe('');
|
|
192
|
+
});
|
|
193
|
+
it('should handle null-ish values', () => {
|
|
194
|
+
expect(redactSensitiveData(null)).toBe(null);
|
|
195
|
+
expect(redactSensitiveData(undefined)).toBe(undefined);
|
|
196
|
+
});
|
|
197
|
+
it('should handle text with no sensitive data', () => {
|
|
198
|
+
const input = 'This is a normal log message with no secrets';
|
|
199
|
+
expect(redactSensitiveData(input)).toBe(input);
|
|
200
|
+
});
|
|
201
|
+
it('should handle multiple tokens in same string', () => {
|
|
202
|
+
const input = 'GitHub: ghp_1234567890abcdefghijklmnopqrstuvwxyz, Stripe: sk_live_abcdefghijklmnopqrstuvwx';
|
|
203
|
+
const result = redactSensitiveData(input);
|
|
204
|
+
expect(result).toContain('ghp_[REDACTED]');
|
|
205
|
+
expect(result).toContain('sk_live_[REDACTED]');
|
|
206
|
+
});
|
|
207
|
+
it('should handle repeated calls (regex lastIndex reset)', () => {
|
|
208
|
+
const input = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyz';
|
|
209
|
+
// Call multiple times to verify lastIndex is reset
|
|
210
|
+
const result1 = redactSensitiveData(input);
|
|
211
|
+
const result2 = redactSensitiveData(input);
|
|
212
|
+
const result3 = redactSensitiveData(input);
|
|
213
|
+
expect(result1).toBe('Token: ghp_[REDACTED]');
|
|
214
|
+
expect(result2).toBe('Token: ghp_[REDACTED]');
|
|
215
|
+
expect(result3).toBe('Token: ghp_[REDACTED]');
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
describe('redactSensitiveObject', () => {
|
|
220
|
+
it('should redact strings in simple objects', () => {
|
|
221
|
+
const input = {
|
|
222
|
+
token: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz',
|
|
223
|
+
name: 'test',
|
|
224
|
+
};
|
|
225
|
+
const result = redactSensitiveObject(input);
|
|
226
|
+
expect(result.token).toBe('ghp_[REDACTED]');
|
|
227
|
+
expect(result.name).toBe('test');
|
|
228
|
+
});
|
|
229
|
+
it('should redact strings in nested objects', () => {
|
|
230
|
+
const input = {
|
|
231
|
+
config: {
|
|
232
|
+
auth: {
|
|
233
|
+
apiKey: 'sk_live_abcdefghijklmnopqrstuvwx',
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
const result = redactSensitiveObject(input);
|
|
238
|
+
expect(result.config.auth).toEqual({
|
|
239
|
+
apiKey: 'sk_live_[REDACTED]',
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
it('should redact strings in arrays', () => {
|
|
243
|
+
const input = ['ghp_1234567890abcdefghijklmnopqrstuvwxyz', 'normal string'];
|
|
244
|
+
const result = redactSensitiveObject(input);
|
|
245
|
+
expect(result[0]).toBe('ghp_[REDACTED]');
|
|
246
|
+
expect(result[1]).toBe('normal string');
|
|
247
|
+
});
|
|
248
|
+
it('should handle mixed arrays and objects', () => {
|
|
249
|
+
const input = {
|
|
250
|
+
tokens: [
|
|
251
|
+
{ key: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' },
|
|
252
|
+
{ key: 'sk_live_abcdefghijklmnopqrstuvwx' },
|
|
253
|
+
],
|
|
254
|
+
};
|
|
255
|
+
const result = redactSensitiveObject(input);
|
|
256
|
+
const tokens = result.tokens;
|
|
257
|
+
expect(tokens[0].key).toBe('ghp_[REDACTED]');
|
|
258
|
+
expect(tokens[1].key).toBe('sk_live_[REDACTED]');
|
|
259
|
+
});
|
|
260
|
+
it('should handle null and undefined', () => {
|
|
261
|
+
expect(redactSensitiveObject(null)).toBe(null);
|
|
262
|
+
expect(redactSensitiveObject(undefined)).toBe(undefined);
|
|
263
|
+
});
|
|
264
|
+
it('should preserve non-string primitives', () => {
|
|
265
|
+
const input = {
|
|
266
|
+
count: 42,
|
|
267
|
+
enabled: true,
|
|
268
|
+
ratio: 3.14,
|
|
269
|
+
};
|
|
270
|
+
const result = redactSensitiveObject(input);
|
|
271
|
+
expect(result).toEqual(input);
|
|
272
|
+
});
|
|
273
|
+
it('should handle Error objects by converting to plain object', () => {
|
|
274
|
+
const input = {
|
|
275
|
+
error: new Error('Failed with token ghp_1234567890abcdefghijklmnopqrstuvwxyz'),
|
|
276
|
+
};
|
|
277
|
+
const result = redactSensitiveObject(input);
|
|
278
|
+
// Error.message won't be in entries, but if serialized it would be redacted
|
|
279
|
+
expect(result.error).toBeDefined();
|
|
280
|
+
});
|
|
281
|
+
it('should mark a directly circular reference as [Circular] instead of stack-overflowing (SMI-5615 NEW-2)', () => {
|
|
282
|
+
const circular = { name: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' };
|
|
283
|
+
circular.self = circular;
|
|
284
|
+
const result = redactSensitiveObject(circular);
|
|
285
|
+
expect(result.name).toBe('ghp_[REDACTED]');
|
|
286
|
+
expect(result.self).toBe('[Circular]');
|
|
287
|
+
});
|
|
288
|
+
it('should mark an indirect (two-hop) circular reference as [Circular]', () => {
|
|
289
|
+
const a = {};
|
|
290
|
+
const b = { a };
|
|
291
|
+
a.b = b;
|
|
292
|
+
const result = redactSensitiveObject(a);
|
|
293
|
+
const nestedB = result.b;
|
|
294
|
+
expect(nestedB.a).toBe('[Circular]');
|
|
295
|
+
});
|
|
296
|
+
it('should NOT treat the same object appearing twice at sibling (non-cyclic) positions as circular', () => {
|
|
297
|
+
const shared = { key: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' };
|
|
298
|
+
const input = { first: shared, second: shared };
|
|
299
|
+
const result = redactSensitiveObject(input);
|
|
300
|
+
expect(result.first.key).toBe('ghp_[REDACTED]');
|
|
301
|
+
expect(result.second.key).toBe('ghp_[REDACTED]');
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
describe('stripAnsi (SMI-5615 Mode-B Wave 2 pass)', () => {
|
|
305
|
+
it('should strip chalk-style SGR color codes', () => {
|
|
306
|
+
const chalkRed = '\x1b[31mError:\x1b[39m something failed';
|
|
307
|
+
expect(stripAnsi(chalkRed)).toBe('Error: something failed');
|
|
308
|
+
});
|
|
309
|
+
it('should leave plain text with no escape codes untouched', () => {
|
|
310
|
+
expect(stripAnsi('plain text, no colors')).toBe('plain text, no colors');
|
|
311
|
+
});
|
|
312
|
+
it('should handle empty and null-ish input like redactSensitiveData does', () => {
|
|
313
|
+
expect(stripAnsi('')).toBe('');
|
|
314
|
+
});
|
|
315
|
+
it('closes the leading word-boundary redaction gap: a secret immediately after an SGR code is still redacted once ANSI is stripped first', () => {
|
|
316
|
+
// \x1b[31m ends in 'm' (a word char) directly followed by the secret's
|
|
317
|
+
// 's' (also a word char) — no \b between them, so redactSensitiveData
|
|
318
|
+
// alone would miss this. stripAnsi-then-redact is the fix (see
|
|
319
|
+
// `redactForDisk` in logger.ts).
|
|
320
|
+
const secret = 'sk_live_' + 'c'.repeat(24);
|
|
321
|
+
const chalkWrapped = `\x1b[31m${secret}\x1b[39m`;
|
|
322
|
+
// Demonstrates the gap exists when redacting the raw (un-stripped) text:
|
|
323
|
+
expect(redactSensitiveData(chalkWrapped)).toContain(secret);
|
|
324
|
+
// ...and that stripping ANSI first closes it:
|
|
325
|
+
expect(redactSensitiveData(stripAnsi(chalkWrapped))).not.toContain(secret);
|
|
326
|
+
expect(redactSensitiveData(stripAnsi(chalkWrapped))).toContain('sk_live_[REDACTED]');
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
//# sourceMappingURL=redact.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.test.js","sourceRoot":"","sources":["../../../src/logging/redact.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5615: Per-surface serialized JSONL writer with daily/size rollover and
|
|
3
|
+
* retention sweep.
|
|
4
|
+
*
|
|
5
|
+
* Write-serialization invariant (F2, from
|
|
6
|
+
* docs/internal/implementation/production-error-logging.md — the plan's
|
|
7
|
+
* original P-5 draft omitted this; it was the Opus `concurrency-auditor`
|
|
8
|
+
* plan-audit's most likely real-world race):
|
|
9
|
+
*
|
|
10
|
+
* A redacted error record (stack ≤20 frames) can exceed `PIPE_BUF`
|
|
11
|
+
* (4096 bytes), so concurrent, independent `appendFile`/`appendFileSync`
|
|
12
|
+
* calls from parallel async tool invocations are NOT safe here — two
|
|
13
|
+
* large concurrent writes can interleave/tear into one invalid JSONL line.
|
|
14
|
+
*
|
|
15
|
+
* Fix: one long-lived `fs.createWriteStream(path, { flags: 'a' })` per
|
|
16
|
+
* surface, created lazily on first write and cached in a module-scoped
|
|
17
|
+
* map. ALL writes for a given surface go through THIS single stream.
|
|
18
|
+
*
|
|
19
|
+
* That alone (Node serializing writes queued on one stream) would already
|
|
20
|
+
* prevent tearing between two writes to the SAME stream object. This
|
|
21
|
+
* module goes one step further for simplicity and an even stronger
|
|
22
|
+
* guarantee: every write is wrapped in an async mutex (`runExclusive`) keyed
|
|
23
|
+
* by surface, so at most one write is ever in flight to a surface's
|
|
24
|
+
* underlying file descriptor at a time — including the write that decides
|
|
25
|
+
* whether a daily/size rollover is needed. That decision-and-possible-swap
|
|
26
|
+
* (open a new stream, `end()` the old one) happens INSIDE the same
|
|
27
|
+
* exclusive section as the write that triggered it, so a rotation can
|
|
28
|
+
* never race a write: no write can land on a stream that has already been
|
|
29
|
+
* told to `end()`, and no two writers can simultaneously decide "today's
|
|
30
|
+
* file doesn't exist yet" and both create a stream.
|
|
31
|
+
*
|
|
32
|
+
* Daily rollover: `skillsmith-<surface>-<YYYY-MM-DD>.jsonl`, keyed off the
|
|
33
|
+
* calendar date at write time (mocked by `vi.setSystemTime` in tests — no
|
|
34
|
+
* separate clock seam needed).
|
|
35
|
+
*
|
|
36
|
+
* Size cap: ~10MB per file. When the currently-open file for TODAY would
|
|
37
|
+
* exceed the cap, roll to a `.1`/`.2`/... suffixed continuation file for the
|
|
38
|
+
* same day (`skillsmith-<surface>-<YYYY-MM-DD>.jsonl.<n>`), through the same
|
|
39
|
+
* serialization point as everything else.
|
|
40
|
+
*
|
|
41
|
+
* Retention: on module init, asynchronously (NOT awaited — never blocks
|
|
42
|
+
* import) sweep `~/.skillsmith/logs/` and delete files whose mtime is older
|
|
43
|
+
* than 14 days. `pruneExpiredLogs` is also exported directly so tests can
|
|
44
|
+
* await a deterministic run against a temp directory instead of racing the
|
|
45
|
+
* fire-and-forget module-init sweep.
|
|
46
|
+
*/
|
|
47
|
+
import type { Surface } from './types.js';
|
|
48
|
+
/**
|
|
49
|
+
* Serializes `line` for `surface`: acquires that surface's exclusive queue,
|
|
50
|
+
* resolves (opening/rotating as needed) the current stream, and writes.
|
|
51
|
+
* Resolves once the OS-level write has completed; rejects (never throws
|
|
52
|
+
* synchronously) if the directory/file couldn't be created or the write
|
|
53
|
+
* failed — callers (see `logger.ts`) must handle rejection to honor the
|
|
54
|
+
* "logger never throws" invariant.
|
|
55
|
+
*/
|
|
56
|
+
export declare function writeLogLine(surface: Surface, line: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Deletes files under the log directory whose mtime is older than
|
|
59
|
+
* `RETENTION_DAYS`. Best-effort: a missing directory or a per-file stat/
|
|
60
|
+
* unlink failure (permissions, a concurrent process already deleted it,
|
|
61
|
+
* etc.) is swallowed rather than thrown — this must never be able to crash
|
|
62
|
+
* module init or take down a caller that awaits it in a test.
|
|
63
|
+
*
|
|
64
|
+
* Exported (not just fired at module init) so tests can await a
|
|
65
|
+
* deterministic run against a temp directory rather than racing the
|
|
66
|
+
* fire-and-forget call below.
|
|
67
|
+
*/
|
|
68
|
+
export declare function pruneExpiredLogs(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Closes any open streams and clears all in-memory state. Test-only — used
|
|
71
|
+
* by `rotation.test.ts` between cases so state from one temp-dir scenario
|
|
72
|
+
* never leaks into the next.
|
|
73
|
+
*/
|
|
74
|
+
export declare function __resetLoggingStateForTests(): Promise<void>;
|
|
75
|
+
//# sourceMappingURL=rotation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../../src/logging/rotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAqLzC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBtD;AAkBD;;;;GAIG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAQjE"}
|