{"_id":"@broberg/secret-scan","_rev":"27-589268c9bb37c690df9944dcf90510eb","name":"@broberg/secret-scan","dist-tags":{"latest":"0.12.1"},"versions":{"0.1.0":{"name":"@broberg/secret-scan","version":"0.1.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"699fdd62697121d19ea91aeaa55f4257236e7d6a","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.0.tgz","fileCount":8,"integrity":"sha512-FTMb4KRA2OX+7HRcqk+7WZKshOKrPpSMzpsZ+Hg6nLB6SDhe96T+EIbQAuxW9FYfdtzSHHjdTg5RMdyvzoAxwg==","signatures":[{"sig":"MEYCIQC/xsJLQGq1IYOF8zBsrgXdh7xpHCvTFgm1djHFAJJiiwIhAPqQX8YhPoSOO4eqIBWwrzYigpkYrkfE2PWktfX7ln8Z","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51795},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"316e151e723b57153c22b9d965c4836e3b9bc590","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"cbroberg","email":"cb@webhouse.dk"},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.10.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"25.7.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.0_1781093655644_0.7412071437173744","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@broberg/secret-scan","version":"0.1.1","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.1","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"1a9de47a01d550802ad94297e9af2bffe3200df3","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.1.tgz","fileCount":8,"integrity":"sha512-4WW88X0fCk/WO+xmjD7shKJg1ILu2yvysHlgHdFprbuc4JUvH5ZYdbXXnqwg0wH2q4i/1Af9YIRYjd6OhdaV2g==","signatures":[{"sig":"MEUCIEkKpxhQNIt/nNsGe15DZYchNSntE12VJgkWQtli/O0CAiEAz4kg0TKU+MD7GeMpjHNNDR9p6r/n0EJVVbV8vqVLUKU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":56436},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"90840d7011f36c1411bd9a6f2971c7b48a92daae","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.16.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.1_1781095811031_0.28557611601191857","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@broberg/secret-scan","version":"0.1.2","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.2","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"e53427cdc15372b934f9f11dd1d5429c394e8abb","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.2.tgz","fileCount":8,"integrity":"sha512-ifcPeiB+Xyq2TWX6daloIyXqc+ffEhIhL/X3Xz2p9uZsxwrMaIdUmJehqAj1SMpjtbW6h94IfY40e7lRQNNEtg==","signatures":[{"sig":"MEQCIATTWBWlz6XiMhbIWq/vdqn0EiR9qkvEax9ogs5q4x7dAiB9EvRyLQxhrg1WLb5lQ+bjJElEbPtrvdKATlkVDXJ5MQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":60691},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"d5ca8ce8a7f914bdf9bd01b8fad26e8b3e7db19c","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.16.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.2_1781160635534_0.84092893556977","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@broberg/secret-scan","version":"0.1.3","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.3","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"c5adf1f7cf9f0f42991883540b56781e98787726","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.3.tgz","fileCount":8,"integrity":"sha512-82ndGWv4vz6jYehQkuhlMlCywqyM++OoKFYFiGwGX5hj2EZX7dyXt9og5OL/faPt9ozihF9ilx+IXCxdAbRPrQ==","signatures":[{"sig":"MEQCIC+bQYBqw3ADzfeCH0CF1p6vSojj5NCEeaPMRbGNhy8nAiBZFOQHOZoIwm2sBkqiSVNzfmRpdeIhpSlJIqikd+c5JA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62934},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"857f239c71d973250dbcb7371f020138a5e2c7d9","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.16.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.3_1781160943099_0.4147578518311401","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@broberg/secret-scan","version":"0.1.4","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.4","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"0ff2e8261bab1a95fd89f61c8f216eae830709c7","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.4.tgz","fileCount":8,"integrity":"sha512-r5LSPQBXwvaAZZ1s0Oo0wmGuwIkNrhTlWkMHJbYeT5LrIXaRhvaw4Pf4N8qPMp7HcGBprPeYJyQStnGU1G2PIQ==","signatures":[{"sig":"MEUCIQDB5GjhBSnhJr9XS9NxBpNEXBNLqCR4QOCs7/ku/jV+8AIgboTNDJC3g9fSFwbV869F8engktOBkopdcCMa9V+zmXo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":64622},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"14b7ad94e841b9f64001dc564b2a314c37ed05eb","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.17.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.4_1781622434500_0.17259330737196854","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@broberg/secret-scan","version":"0.1.5","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.5","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"34069f29fb30d46c8325d9787d8937ce62be2d07","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.5.tgz","fileCount":8,"integrity":"sha512-O04fe9so0a1r0VcD7msEQ2nnBx8xMJgOmFSDBjhOkH4u8OSgQrcOVF4a1cVRlwU74bw5GV6evEC3RhkauclLgQ==","signatures":[{"sig":"MEUCIAhuZv00/snm13fqWpYxfccNvAZRfXSIQNNTHik+37QAAiEAlRiEILvDCVjl2Il03Yw1EDYJH9MUUfg297r7BS57zDk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":66526},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"ff8de59d909517482721a709533b191070808106","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.17.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.5_1781701000730_0.6678512687079687","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@broberg/secret-scan","version":"0.1.6","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.6","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"04e29f82a0fbd4b10c29f1b3ac74c1095c513efa","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.6.tgz","fileCount":8,"integrity":"sha512-p4mXB+AOC3uz7dlJRg4yFdtSqlF54LezRzuMKNpfGf2/i7QaDoXtawzxkyz3WBCm75H0lq3/EyIaa2KSgi4BCg==","signatures":[{"sig":"MEUCIQCFEYgqGKw5+BMsMpfpdxr0nxU4voYsM6qBsptFcxDJ8gIgbfNOEmZgQLjKO9Wiv7AHqHrHvKu2PcGT5ABS7+nOlQQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72330},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"58676d5c20bbf2408013a0c6340ddacfdec3a87d","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.18.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.6_1782825464312_0.22248505071239189","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@broberg/secret-scan","version":"0.1.7","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.7","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"88f428751bcd013720933604780460ba88890be7","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.7.tgz","fileCount":8,"integrity":"sha512-1tPjf9i/Cir4YxDuETYQZnCQSv17bi+dPS5XKaCZEOVgYxT/hmA8mVbf54H5Nep3NaUY5Ftc4hI+3Cssy7qZjw==","signatures":[{"sig":"MEUCIQC+mnxPOHTvVLK5b2OH20eTzTi/xyo8KSudsVX9FFyJmgIgdtGLtMXAtd0hYlXEgtl4qFlHHJ8tIaZ6kXUkQ12Lp9Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":80908},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"03c7f349c3d1ac3493b320ba5977c9327ea80d47","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.18.0","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.7_1783089809807_0.4597451582823344","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@broberg/secret-scan","version":"0.1.8","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.1.8","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"26ee24b561c6233bca34a63d9484e673ab0d92cd","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.1.8.tgz","fileCount":8,"integrity":"sha512-tmtVyPvpDzQAkzpycOMhg0VOktsZY2gsOe6jpvazh97o1FyGAeyhUQOpRteKl5JlA7onLk1q/neqvM4qRT7U/w==","signatures":[{"sig":"MEUCIQD3Hnr1Lim12jZRqOMpeGfH9Oy7ulMC/hktip2dwRhDQAIgWL2t58M9NYZ6Ks3e+30SumbM3MqhX8N6zEb35EF0FQ0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.1.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":85358},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"eaecbbc98a576d74ab3ebfddafd6679a420ae16e","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.8_1786089886920_0.8569318653714901","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@broberg/secret-scan","version":"0.2.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.2.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"6f9a877c63074eae36ddb58e35d6d6f418051595","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.2.0.tgz","fileCount":8,"integrity":"sha512-tLwpwkVJLXKDedYWJ58NymayeJ9hwWNKVUOCLs+lyVgK/HX8xYC1YD+nKfk6xZNe3I2Z7l6o3ZdfPpyLe4IQVQ==","signatures":[{"sig":"MEUCIEmyYL/ERmXpyhwlMpa3RPcPoY7068Br7sGy5Lh5WJK1AiEA22J/FO4GpVjQ0l27lfIQfgc3fks+inohOXns8tkVtPY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":104907},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"e8878974ef20f1e5f78e39ef8e90c4da4d66c916","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.2.0_1786706544814_0.8210102313562309","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@broberg/secret-scan","version":"0.2.1","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.2.1","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"df68997bfb22ad1be482fdf95cfebe6f5b7ec9fc","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.2.1.tgz","fileCount":8,"integrity":"sha512-TTSvv2Bfmp6Ij+MZbu7YWTaSsmS1FQx/Nl6yW8/5hm9oPYu5QkbjiWaASkpcVqFLr0IKfzcdX1IW2NxQy3hO4Q==","signatures":[{"sig":"MEUCIFYU2q89zyMzU2Xk2LCyqhjYiEKeJyDzIhJcOPhWmYCEAiEA0dsS8WwEn6N19OW4flV5opxtiAqTDCdEuu+67H4L2Ro=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":105609},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"2e4a309a3d40e2d533986b6adf09fa47026e74a3","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.2.1_1786707077222_0.7190281238012655","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@broberg/secret-scan","version":"0.2.2","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.2.2","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"087358bf12571e054e62eab75e0d77c7854907b7","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.2.2.tgz","fileCount":8,"integrity":"sha512-sV/ES7UM+rtrN2OijmJroDQpkch4lDY7ibg/Zyp13kGdDVEiC8L6zwkaHwUeRxISi68TSPzgi5bmZ+USgec+dw==","signatures":[{"sig":"MEQCIBAYFLhrSJWxV208rPf5xO4pnxJX+rUok/qbhRjnUO4tAiAtQ+nZefc3TUsj4EZfce7N2LpkySRu3nQAzgY4pKnkjA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":109898},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"3b051e61bd2f9bd2274f74cbef72eb5a22b64e6a","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.2.2_1786708254256_0.1190939913941158","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@broberg/secret-scan","version":"0.3.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.3.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"b36e33fb494b680b51f41800862bf9e3793ababf","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.3.0.tgz","fileCount":8,"integrity":"sha512-GJGIngtvbvu2EfHaRvwWckB7rkpJ2NZT7cC7zN4QBf5MXEIQ3FNbG7GQgjXKBo+NEhS00MG4Fu+X3JXQ4qwrQQ==","signatures":[{"sig":"MEQCIFJJALLSyH1iSuxhMewHGIRo0gexOUhf8N6VHSSQ/WuRAiATbk6Ca7hoH/gym9LfEuEgnC0fUH+PwonLst5sGKA5Xg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":118037},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"eaf85cc4e706e23285f9926a5d9ead20945131df","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.3.0_1786708655438_0.4474011359019059","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@broberg/secret-scan","version":"0.4.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.4.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"56b58776da484496068028a51ce296e0fcf898b0","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.4.0.tgz","fileCount":8,"integrity":"sha512-oL4+NYXILV+//Lck1wEsW1F48KxoAEWyLXsrW7UELyE/BsO5FFy/jsltNO5UxMNoeXagQwDqBb4AzjAgxraCPA==","signatures":[{"sig":"MEYCIQDSVE38796Hzm75OiRouWtIadlY7NIrOm2wltYY8Yh31QIhALShbwnM5wpbKKjoz/z/qzoSU79W5q/Nq3WYWqcdFHmG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":124221},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"c80e96eeb17606e32201681bcdd59d5fb56381b6","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.4.0_1786709207574_0.16720152301434088","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@broberg/secret-scan","version":"0.5.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.5.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"3b78a134b63cc2f32351c3717277be6bc3b0ab03","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.5.0.tgz","fileCount":8,"integrity":"sha512-3GHD2kmJMysOXBigyeM/SRAxl1O6/nkkkZx8P2vQLMzh1nAr6jwM2nM+tFSusMKNpROfr9IJKL2YW5hvCKa6ZQ==","signatures":[{"sig":"MEUCIDpTmUfx1ptExMsEfvDq54ifmROhJ1Cc4fKHoxry8VSwAiEA3mFzGJVwU8GFmTAAsGcKS0i0XlUK0DdPnR0naKwLoyY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":127351},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"076319e152f211202f61e0ec063d7c0cb3539d33","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.5.0_1787480194917_0.05075883283583904","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@broberg/secret-scan","version":"0.5.1","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.5.1","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"d7c2933a26f1e7cec4e3850f4ece3be55c30ebf1","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.5.1.tgz","fileCount":8,"integrity":"sha512-REFa4lqFgdx5pn/37IPQUX0DLNq+K49xsqiy0ApbpWhCOZhZnO0FejioBxFNkyTduexpPAsLpoJZjpXIFvP09Q==","signatures":[{"sig":"MEUCIQCNjZxXWsVl69xCsXTy3bsMulodzy3oHcxPNas25uiJbwIgdQbGtN69vtIrESwhDnB6C3It7eRGSHk0NVj6oX966uM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":139142},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"1c489dbb51695a324947513f9980b8ef700c5483","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.5.1_1787845345186_0.7505299129844656","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@broberg/secret-scan","version":"0.6.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.6.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"73ea1557651949cad9dde9d9ff7f33c9b982be4e","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.6.0.tgz","fileCount":8,"integrity":"sha512-YLQ22Xd+f9wrKfA6Hrzl3hxf1xUYiaaz7M7IrgnU5yM3w2GCVkJivnrQx2sSOTPza5tjjTVbELEeZH7eFG0VGQ==","signatures":[{"sig":"MEQCIAjWx7YIlLTuExTZuYIIZDjdtAM+fcKiu/q0bP+q0mQZAiA4ak+qEiZ0hrPemlHts8FbJYpt7ohJX8xdVnxYzAQk6g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":150949},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"b5ede811e3cc51a286a4d20d3e52506b90fe7379","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.6.0_1788124694343_0.4795821978318613","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@broberg/secret-scan","version":"0.7.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.7.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"36c78cb90de3fada4d4ed66f11f8189b81f2ccc1","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.7.0.tgz","fileCount":8,"integrity":"sha512-6cxJxk3hWuXzWCN2mPFjxkcJcgQhkQJceMl0kpXQ9gdwrfr/475YByUHzWd5Pu9BGNFVhSuHAomy5KXC728mMQ==","signatures":[{"sig":"MEUCIQDOgwMM/J12eQE1yJLRMhjeWKzg/w61v9p+XMIVryNtuAIgXsxUb3ZPBv4IsGawjgSnOpH6/+w3nuKk/ptjEj1tEhU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":188429},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"78830c2ef25766cc6555087f8969f7873068ba59","scripts":{"test":"vitest run && node test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.7.0_1788204874874_0.7410889543365746","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@broberg/secret-scan","version":"0.7.2","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.7.2","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"5aa09416c4b4764b185b66c37bf5f1d20386567d","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.7.2.tgz","fileCount":8,"integrity":"sha512-jLxRv/bYHWBPaWqvmiouqyh+rq54xpumkLTfGJmEHGJI7nF4NFGcEi//tBjsLkLX7Xx+kHeMwVXLPAr2RtzseA==","signatures":[{"sig":"MEUCIQC61mEOBQuJwYoAqNN57CqYldz68ap7wdSm1TZUrW6abwIgDzDkLQND86SSc/TcPKt8ECeDG8axYbG1iQBWht6l+OY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.7.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":191198},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"531a980f9267aea1d70c131b3fe556eeb0cf13cc","scripts":{"test":"vitest run && node test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.7.2_1788205969455_0.064183722715484","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@broberg/secret-scan","version":"0.8.1","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.8.1","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"a5d111765e9ef65d0e90a70422ba6845e2cea72a","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.8.1.tgz","fileCount":8,"integrity":"sha512-SSAtPDPS/8qfBEXhpawUXtEU5C+OCUtBL5j1QIXCVHaIiloAKcCWh/NOYvqwHztDLgjjZUMDdBAEUDaD/ZujdA==","signatures":[{"sig":"MEQCIHWxc8TDUzYERGfBEGq3/hGGuLtImCINFXU6TlyRUd1CAiAkbJ1fYUr/WbxPkR4VFSjwvbQlPrZov6rLEE5YX6zeVg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDFAxjcvYGvsLCbSvtOnaTvFW4pbfSRDqf+bvayZXHk9QIhAJcdsZ/z4Nhu8ZePWBH0XmDqiklegtZnq5w9qvYPQcek","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.8.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":215006},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"0ac7fd36b8a364ad33fba9fcbdd012bf412234a5","scripts":{"test":"vitest run && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.8.1_1789043593950_0.24552571197904682","host":"s3://npm-registry-packages-npm-production"}},"0.8.4":{"name":"@broberg/secret-scan","version":"0.8.4","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.8.4","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"65ae5fde2426aeae520099bd9bac4e5b5d822937","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.8.4.tgz","fileCount":8,"integrity":"sha512-VjOkRp6fBGUt7keuAiuuRxXhjKCFMgW+rIu/rLTzLBXizQiB+Yo/uB4tMYGxHQ4D3kvTzr6HgeUEXU+cyoOizQ==","signatures":[{"sig":"MEYCIQCL0whOkj6ZxHjCjNVOSn0uDpfqVsBAM5XiXHNJAp7EawIhAIB8zm/9ViaEBmSb6b0MGl/o9+HsGSvdyaSA9+7vs5DU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIHgEE3ZBnvKk5KpFa+C3IMyp5DFAgry1hzAuCgQwvntGAiEA4jYgkvhw0MKa2pH3atQ3eCKuDaLE3hODwwNDoBb/9Ag=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.8.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":223899},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"a7752245273d39f035eddf756e6b415f2d8b5be1","scripts":{"test":"vitest run && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.8.4_1789044263738_0.6039489334165831","host":"s3://npm-registry-packages-npm-production"}},"0.9.3":{"name":"@broberg/secret-scan","version":"0.9.3","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.9.3","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"256872642153bc606396e546559d2b47e2b32601","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.9.3.tgz","fileCount":8,"integrity":"sha512-PGxMNy9tA12cbHF0Q9RVVHv8urQmyPti8+OzKvkFyfxjRhR4+Ip8zV58M2FXpZnqo64nky9BjrNT736nGo+DpA==","signatures":[{"sig":"MEUCIBbDGP8g8bg2zEhA+zogWrEVY7bvONI8kRktpWqQoyGkAiEArPFpULxguIDU50UCjgGKZzN4niYS9FG6wtDYl4trfcA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCo4+wn72AQNeQ3tHcQ/4pj0j0X1/f5vlFKFlfYF+fImAIgaLkNKFjk3rfgM8JsgW2SKOdUgUyzJCCAEGyQo90Ye10=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.9.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":234754},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"6ef9d71042a5222115d8961c15eb5ce39395791e","scripts":{"test":"vitest run && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@broberg/apikey":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.9.3_1789067630026_0.6899580426992027","host":"s3://npm-registry-packages-npm-production"}},"0.10.1":{"name":"@broberg/secret-scan","version":"0.10.1","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.10.1","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"5174d24086fe82c0036d34306d396ad08ca592e0","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.10.1.tgz","fileCount":8,"integrity":"sha512-plTTqcdLhuHq0dj/ISCNHxfjwbqGZ8CV/cBF7wgcy/2+d8I5T+jQHWFqsvfxGArHETpRLEvGZgTzQ1vXr75nog==","signatures":[{"sig":"MEQCIGWd/XPZN6ZzGjHKwIM7NHoAh2hKN7ZEd2sBEVwm+wUsAiBrFnX2zHwgTgD7gbpXz7tqYjDXtyECY7WLl1aOu6qnZg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIAHPWPHi9g7+kh3kT2P1E5hBWgiad33Wj+x9y9SJGZxhAiEAgYOCcpn94KV4WhCKJltks9A597C8kJYHc4/TI/W4ETI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.10.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":239615},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"1b6b1f5d52da46c4ad6f87dd46351dfdcb8aa2c9","scripts":{"test":"vitest run && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@broberg/apikey":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.10.1_1790727240301_0.6842177704617207","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@broberg/secret-scan","version":"0.11.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.11.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"21edd9c6ae91324ee2ddf96910c8c2efa7791ff7","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.11.0.tgz","fileCount":8,"integrity":"sha512-fQW3GD38uCld85OD6aWGVPjXFE9FHTkTsc/PPmbW5A1nTnVfiphEqJCkaVtS8hgWAtAEZyCYAtmsKl+hZreZQw==","signatures":[{"sig":"MEYCIQCo6BkuMidfxfzcsGkUFfonD24DJv8EYUv6/9aUDj3THgIhAJnWQt3uoRnIGjUnpKMKX6i02Ssw85I4VQ+MbJvNOZhG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIAyNtcg+wRI6dgy8CBHnbhu7rLdgXxLxe5ih9eNFxBRKAiEAjTbwNrqSVQOw9XMZJ8NC4IGTmaRpfBczfhjp0+O5eFs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":261100},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"d3666a2d28a4e25458ff9947415cb74c0a89fe5e","scripts":{"test":"vitest run && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@broberg/apikey":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.11.0_1790730400587_0.08551670168543457","host":"s3://npm-registry-packages-npm-production"}},"0.11.1":{"name":"@broberg/secret-scan","version":"0.11.1","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.11.1","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"833084d666ec3ef49290160605de6add05a95665","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.11.1.tgz","fileCount":8,"integrity":"sha512-m4URHU0HxwipgpMDTrNM4vQ5hVrtzNeVdIfosw2xSezCLEqTXywSc9zZWZBiu23HjDCfzEMeZVvw+i2ANZgQYQ==","signatures":[{"sig":"MEUCIB3jCkPMNFji2qWHfiLEdn7B7035Rel2VvK3frB/jDDIAiEAzHxzOTWZQ3zT0plHzRamzL9DOAvR85muHnuD0z0a0V8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIDLF5gtDO4Q+jRTcS9sM93xiRqImsmGH0fLdKiB7clo7AiEAiJm7H7JYtjLEaPaKAAvWwUus8NmccJooA28sFZiRan8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.11.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":264152},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"e6b0a971e2c9135471b86624b057b27545fba4b1","scripts":{"test":"vitest run && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@broberg/apikey":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.11.1_1790765824825_0.8667752090737202","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@broberg/secret-scan","version":"0.12.0","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"license":"MIT","_id":"@broberg/secret-scan@0.12.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/components#readme","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"c3bf796f79bfdaee5966dd7083bd441be3618857","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.12.0.tgz","fileCount":8,"integrity":"sha512-rei4xbxHWeBSaYYuObvxtshX0h+pqohVCtlg2yKix4gUEgPxTxE9qMxRAoerxo5W54+cTYblIoKtIfQXMxnzUQ==","signatures":[{"sig":"MEQCIGpL/gywqS9x66YS0/NspkyuJV16vRuCYU4e+k5ozR4GAiAHqiZSuV+4xBeZCoksHvHtvS6XMKQSHXyLCuseReh6SA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDEI0SjypnQr7tNTNqxMxw/rV4cp3dpJA2rFI1uTVYveQIhAJHOYbt0tIFdE865JUq0VEG8ZnL7vZzpMj2cWkvu72AF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.12.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":284081},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"7d370c5758f18608fe4b8fed4c9f771cc4997439","scripts":{"test":"vitest run --reporter=default --reporter=json --outputFile.json=.vitest-report/results.json && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@broberg/apikey":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.12.0_1790810849945_0.12556998271130326","host":"s3://npm-registry-packages-npm-production"}},"0.12.1":{"_id":"@broberg/secret-scan@0.12.1","bugs":{"url":"https://github.com/broberg-ai/components/issues"},"dist":{"shasum":"20e08a7a8e57419026fd9bf6d2a28b98f64f23cb","tarball":"https://registry.npmjs.org/@broberg/secret-scan/-/secret-scan-0.12.1.tgz","fileCount":8,"integrity":"sha512-MgVgDoKlFgM1Sq1EBmhycins1BWIAmEYgNgcg4B5s6xG3gRYp7kOL/IdgA8mpBwPwIQTfDR9j4MOOk6pvo/Nyw==","signatures":[{"sig":"MEQCIEmVaRIXVc72g/VO0Nr/Uc6HvMorEMx+qbh4aI/kqZkcAiBL8AvBFeyK5wnsenTcPMFaX5IVpOZu1zAErqD/2zhTXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDVgaNV8TPfLTIeefh+tuKTpEWZ/MTMZuODVeLLMqxvewIhAKmWO4/ojn2teiXCT6z4jeUSY5GztTHIxh+qPMlzr0dR"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@broberg%2fsecret-scan@0.12.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":284419},"main":"./dist/index.cjs","name":"@broberg/secret-scan","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"4e1be7dad2f628c805c161baed098e1eaa089b42","license":"MIT","scripts":{"test":"vitest run --reporter=default --reporter=json --outputFile.json=.vitest-report/results.json && node ../../scripts/mutations-if-changed.mjs test/mutations.mjs","build":"tsup","typecheck":"tsc --noEmit"},"version":"0.12.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"101fc779-c6e1-45d4-acf5-b438cf3b3ab6"}},"homepage":"https://github.com/broberg-ai/components#readme","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"_npmVersion":"11.5.1","description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","directories":{},"maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"sideEffects":false,"_nodeVersion":"22.23.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@broberg/apikey":"workspace:*"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/secret-scan_0.12.1_1790811683744_0.9612054390344109"}}},"time":{"created":"2026-06-10T12:14:15.423Z","modified":"2026-09-30T23:41:24.223Z","0.1.0":"2026-06-10T12:14:15.786Z","0.1.1":"2026-06-10T12:50:11.161Z","0.1.2":"2026-06-11T06:50:35.709Z","0.1.3":"2026-06-11T06:55:43.243Z","0.1.4":"2026-06-16T15:07:14.696Z","0.1.5":"2026-06-17T12:56:40.858Z","0.1.6":"2026-06-30T13:17:44.449Z","0.1.7":"2026-07-03T14:43:29.936Z","0.1.8":"2026-08-07T08:04:47.067Z","0.2.0":"2026-08-14T11:22:24.956Z","0.2.1":"2026-08-14T11:31:17.384Z","0.2.2":"2026-08-14T11:50:54.382Z","0.3.0":"2026-08-14T11:57:35.573Z","0.4.0":"2026-08-14T12:06:47.739Z","0.5.0":"2026-08-23T10:16:35.050Z","0.5.1":"2026-08-27T15:42:25.319Z","0.6.0":"2026-08-30T21:18:14.497Z","0.7.0":"2026-08-31T19:34:35.019Z","0.7.2":"2026-08-31T19:52:49.605Z","0.8.1":"2026-09-10T12:33:14.044Z","0.8.4":"2026-09-10T12:44:23.858Z","0.9.3":"2026-09-10T19:13:50.109Z","0.10.1":"2026-09-30T00:14:00.405Z","0.11.0":"2026-09-30T01:06:40.710Z","0.11.1":"2026-09-30T10:57:04.928Z","0.12.0":"2026-09-30T23:27:30.030Z","0.12.1":"2026-09-30T23:41:23.831Z"},"bugs":{"url":"https://github.com/broberg-ai/components/issues"},"license":"MIT","homepage":"https://github.com/broberg-ai/components#readme","keywords":["secret","redaction","credentials","security","api-key","token","secret-scanning","broberg"],"repository":{"url":"git+https://github.com/broberg-ai/components.git","type":"git","directory":"packages/secret-scan"},"description":"Pure, dependency-free secret/credential redaction for the broberg.ai fleet — redactSecrets / hasSecret over a curated, ordered SECRET_PATTERNS set. Redact at write + egress boundaries so keys never land in a DB, chat, or KB. Lifted from broberg/trail F197","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"readme":"# @broberg/secret-scan\n\nPure, dependency-free **secret/credential redaction** for the broberg.ai fleet.\nCatch leaked API keys and tokens at your write + egress boundaries so a key never\nlands in a database, a chat answer, a search result, or a shared knowledge base.\n\nLifted from [`broberg/trail` F197](https://github.com/broberg-ai/trail) — the\nsecond-brain safeguard that found 9 real leaked keys already sitting in a shared\nKB. `components` owns + publishes it; every repo consumes the same canonical\npattern set, so detection never drifts.\n\n**AWS, in one line, because a reader scans this far and no further:** an access\nkey id is caught on shape and labelled by kind (`AKIA…` long-term — rotate it;\n`ASIA…` temporary — it may already have expired); the **secret access key and\nsession token** are caught next to their field name, at any length from 20 and\nin **any alphabet**, so every S3-compatible provider is covered (Tigris, R2,\nMinIO — not only AWS's 40 base64); and a 40-char value **within 80 characters of\nan id** is caught as its pair. Deliberately **not** caught: a bare string with no\nfield name and no id nearby (the shape of every git hash), and a value that is a\n*reference* to a secret rather than one (`process.env.AWS_SECRET_ACCESS_KEY`).\n[Details](#aws-the-id-was-never-the-credential-v080).\n\n```bash\nnpm i @broberg/secret-scan\n```\n\n## Usage\n\n```ts\nimport { redactSecrets, hasSecret } from \"@broberg/secret-scan\";\n\nconst { redacted, findings } = redactSecrets(\"the key is sk-ant-api03-… use it\");\n// redacted → \"the key is [REDACTED:anthropic-api-key] use it\"\n// findings → [{ label: \"anthropic-api-key\", count: 1, confidence: \"format\" }]\n\nhasSecret(\"nothing here\"); // false\n```\n\n`redactSecrets` is **pure + deterministic**: clean input returns byte-identical\nwith `findings: []`. It replaces every detected secret with `[REDACTED:<label>]`\nand never blocks the write — the surrounding knowledge survives.\n\n> ### ⚠️ `redactSecrets(text)` does **not** catch an announced secret\n>\n> ```ts\n> redactSecrets(\"Adgangskode: hunter2\")\n> // → { redacted: \"Adgangskode: hunter2\", findings: [] }   ← password intact\n> ```\n>\n> There are **two detection axes** and only the format one is on by default.\n> `findings: []` here does not mean \"clean\" — it means the announced axis was\n> never examined.\n>\n> **Since 0.3.0 you can check that instead of remembering it.** Every result\n> carries `scanned` — which axes the call actually examined:\n>\n> ```ts\n> redactSecrets(\"Adgangskode: hunter2\").scanned              // [\"format\"]\n> redactSecrets(body, { announced: true }).scanned           // [\"format\", \"announced\"]\n>\n> const r = redactSecrets(body, { announced: true });\n> if (!r.scanned.includes(\"announced\")) throw new Error(\"announced axis not scanned\");\n> ```\n>\n> It is computed from the **options**, not from what was found, so a clean scan\n> and an unscanned one never look alike. **Honest limit:** this does not\n> *prevent* the mistake — someone who forgets the flag can equally forget to\n> check `scanned`. It makes the mistake **detectable** rather than merely\n> documented, which is the difference between a check and an agreement.\n>\n> Gating untrusted inbound text? Use **`hasAnnouncedSecret(text)`**, or pass\n> `{ announced: true }`. Do not treat an empty `findings` as safe.\n>\n> buddy came within one message of reporting this package as broken: their probe\n> used the defaults, so it could not see the axis they were testing. The\n> behaviour is correct — the **names** are the trap. Two functions that sound\n> interchangeable, one of which is only complete with a flag.\n\n## Announced secrets — when the label is the only evidence (v0.2.0, opt-in)\n\n`Adgangskode: hunter2` has **no format to match.** Everything above recognises a\nkey by its *shape* (`sk-ant-…`, `ghp_…`, `AKIA…`); here the value is arbitrary\nhuman text and the only signal is that someone wrote the word \"password\" next to\nit. cardmem found exactly this as the **first line of an ingested mail**, and\n`redactSecrets()` passed it through unchanged.\n\n```ts\nredactSecrets(\"Adgangskode: hunter2\");                      // ← UNCHANGED. Off by default.\nredactSecrets(\"Adgangskode: hunter2\", { announced: true });\n// redacted → \"Adgangskode: [REDACTED:announced-secret]\"   ← the label is kept on purpose\n// findings → [{ label: \"announced-secret\", count: 1, confidence: \"announced\" }]\n```\n\nFindings now carry `confidence`, so you can tell the two axes apart: `\"format\"`\n(the value identifies itself — safe anywhere) vs `\"announced\"` (a label claims\nthe next word is a credential).\n\n### Why it is opt-in — the measurement, not a hunch\n\n> Measured **2026-08-14** against this repo: **548 tracked files, 544 readable as\n> text**, containing essentially no real secrets. The shipped pattern matched\n> **97 times, all of them noise.** Per label: `secret` **61**, `api key` **33**,\n> `password` **4**, every Danish label **0**.\n\nSo 94 of the 97 come from the two words that are also ordinary **identifiers in\nsource code** — `secret: config.secret`, `apiKey: Record<…>`. That is the real\nfinding, and it is sharper than \"the pattern is noisy\": **its precision depends\nentirely on what you are scanning.** In an inbound mail body `Adgangskode:` is a\nstrong signal; in a TypeScript file it is a variable name. The package cannot\nknow which corpus it is looking at — **only you can** — so you make the call, and\nthe default cannot be on.\n\nThat is the opposite of this repo's usual defaults-ON stance (webpush F067.1,\nlens-engine F065). The numbers above are the reason, and they are why tuning is\nnot the answer either: a broader label+separator+value pattern measured **305**\non the same corpus, and refining it only reached **202**. A template/env-guard\n(`${FOO}`, `<your-key>`) was written and then dropped — it changed the count by\n**exactly 0**, because the noise here is identifiers, not templates.\n\n### Scanning source code? `{ announced: 'code' }` (v0.12.0)\n\nThe rule above reads **prose**, and in source code it is wrong both ways (filed\nby pitch, whose GitGuardian scan flagged a line this package passed):\n\n```ts\nconst line = \"JSON.stringify({ currentPassword: 'a', newPassword: 'abcdefgh' })\";\nredactSecrets(line, { announced: true }).findings;    // []  ← compound identifier, digit-free value\nredactSecrets(line, { announced: 'code' }).redacted;\n// \"JSON.stringify({ currentPassword: 'a', newPassword: '[REDACTED:announced-secret]' })\"\n\nredactSecrets(\"apiKey: nanoid(32)\", { announced: true }).findings.length;   // 1  ← an expression\nredactSecrets(\"apiKey: nanoid(32)\", { announced: 'code' }).findings;        // []\nhasAnnouncedSecret(line, 'code');                                           // true\n```\n\n`'code'` flags a **quoted string literal** (4+ chars, no whitespace, no `${`)\nassigned with `:` or `=` to an identifier that **contains** a credential word\n(`newPassword`, `DB_PASSWORD`, `clientSecret`, `apiKey`, `KODEORD`). Unquoted\nvalues are calls, variables or env references, so they are never flagged.\n\nMeasured 1/10 2026 over 2,848 TS/JS files in 13 fleet repos: most hits are test\nfixtures (`apiKey: \"re_x\"`), which is exactly GitGuardian's class. The noise\nshapes are refused by name: `password: \"Adgangskode\"` (an i18n label),\n`PASSWORD_TOO_SHORT: \"password_too_short\"`, `secretPath: \"…\"`, a ternary\nbranch, a `type X = '…' | '…'` union. **Not caught:** `.env` files (their values\nare unquoted; use `announced: true` there), comparisons (`password === 'x'`).\nIt costs about as much as the format pass: ~2 s per MB, linear.\n\n### `hasAnnouncedSecret` — for when the right answer is to refuse\n\n```ts\nimport { hasAnnouncedSecret } from \"@broberg/secret-scan\";\n\nif (hasAnnouncedSecret(mailBody)) return; // don't send this to a model at all\n```\n\nA boolean, with no redaction built. For **untrusted inbound text heading to an\nLLM**, refusing beats redacting: a false positive costs a slightly worse\nclassification, a false negative costs a leak. (buddy's reasoning, F035.8 — and\nit is the better half of this feature.)\n\nIt fires on `Password: hunter2` and **not** on `\"I forgot my password\"` — a\nlabel with no separator and value is prose, not a credential. Beware the\ntempting-but-wrong version: a bare \"3–32 alphanumerics on the first line\" regex\nmatches `Hej`, `Tak` and `FYI`. Harmless where a non-match costs nothing,\ndangerous in anything that redacts.\n\n### Bare `kode` is not in the list (v0.4.0)\n\n**In Danish, `kode` mostly means SOURCE CODE.** The credential words are\n`kodeord` and `adgangskode`, and both are still matched. Until 0.4.0 the bare\nform was included and fired on ordinary technical prose — measured by buddy over\n**82,662 lines of real Danish transcription**:\n\n```\n\"Det er min kode: se linje 40\"      \"Kode: const x = 1\"\n\"Merge-kode: konflikten er løst\"    \"QR-kode: scan den\"\n```\n\nAnd the old behaviour was **arbitrary**, which is what settled it: `\\b` meant\n`Landekode:` / `Postkode:` / `Fejlkode:` never matched (no word boundary inside\nthe word) while `QR-kode:` did (a hyphen *is* one). Whether a compound got\nflagged came down to whether someone happened to type a hyphen.\n\n**The cost, stated rather than hidden:** `Her er min kode: hunter2` is no longer\ndetected, and that is a real Danish way to announce a password. Deliberate — a\ntoken that means \"source code\" half the time is noise in every corpus, not just\nbuddy's. There is a test pinning the miss, so if it ever comes back it comes back\nas a decision. Need it? File it; don't re-add it locally.\n\n**A label needs something to follow it.** `Password:` on its own is `false`; the\nvalue must actually be there. buddy found this the sharp way after adopting\n0.2.0 — their own patch keyed on *label + separator* and flagged an ordinary\nmail that merely said \"I forgot my password\". That is the line between a guard\nand a noise source.\n\n**A value on the next line still counts.** `Adgangskode:\\nhunter2` fires, because\nmail wraps and a wrapped secret is still a secret.\n\n⚠️ **It CAN be a silent miss, and this sentence used to say otherwise.** Since\n0.6.0 the candidate must be plausible — any digit, or 16+ characters — so a\nwrapped line whose next word is ordinary prose is left untouched with no marker\nand no finding:\n\n```ts\nredactSecrets('Adgangskode:\\nJeg glemte den', { announced: true })\n// -> unchanged, findings: []\n```\n\nThat is the trade this axis makes: it stopped eating prose and gained a way to\nmiss. `Adgangskode: correcthorse` is not detected either. Both halves are tested,\nso neither is an accident of the regex — but do not read this axis as a\nguarantee.\n\n**Detection order is load-bearing.** The announced pass runs *last* and refuses a\nvalue that already contains a redaction marker, so `API key: sk-ant-…` still\nredacts as `anthropic-api-key` rather than flattening to a generic\n`announced-secret`.\n\nBefore 0.7.0 that guard tested only the FIRST character of the value, so a\n**quoted** key was flattened and the redacted text stopped saying what kind of\nkey it had been. It now tests for the marker anywhere in the value, which is why\nquotes, brackets and parentheses all behave the same.\n\n## Classify a single token — `classify`\n\nThe inverse of redaction: given a **single pasted token**, tell the caller what\nkind of secret it is. Backs a \"paste a key → detect its type\" UI so every\nconsumer shares one classification (not just one redaction).\n\n```ts\nimport { classify } from \"@broberg/secret-scan\";\n\nclassify(\"sk-ant-api03-…\"); // → { label: \"anthropic-api-key\", description: \"Anthropic API key (sk-ant-…)\" }\nclassify(\"npm_\" + \"…\");      // → { label: \"npm-token\", description: \"npm publish/automation token (npm_ + 36 base62)\" }\nclassify(\"just some text\");  // → null\n```\n\n**First-match-wins** over the same ordered `SECRET_PATTERNS`, so `sk-ant-…` is\n`anthropic-api-key`, never the generic `openai-api-key`. Input is trimmed;\nempty / whitespace-only / no-match → `null`. It honours `extraPatterns` too\n(`classify(value, { extraPatterns })`), with canonical attribution still winning.\n\nField-anchored patterns (`mistral` / `vimeo` / `cloudflare-api-token` /\n`labeled-hex-secret` / the `deepseek` fallback) only classify when the pasted\nvalue includes their `NAME=value` context — a bare provider token classifies via\nits prefix, and a prefix-less bare token (e.g. a raw Mistral key) is genuinely\nunidentifiable and returns `null`.\n\n### A `null` has two meanings — check the length floor first\n\nEvery token pattern carries a **minimum length** (typically `{20,}`). So a\n`null` from `classify()` means **either** of two things, and they are\nindistinguishable from the return value alone:\n\n1. no pattern matches this string; **or**\n2. a pattern exists, but your sample was **shorter than its floor**.\n\n```ts\nclassify(\"rk_live_51ABCdef\");                 // → null   (8 chars after the prefix — under the floor)\nclassify(\"rk_live_51\" + \"A\".repeat(90));      // → { label: \"stripe-secret-key\", … }\n```\n\n**Before you report a missing pattern, re-probe with a realistic-length value.**\nTwo gap reports in two days were both this, and both were withdrawn: a short\nsample measured the *floor* and was read as missing *coverage*.\n\nThe floor is deliberate and load-bearing. Without it the literal string\n`sk_live_` in prose, a doc or a code comment would be flagged — and a redactor\nthat fires on prose gets switched off within a week, after which it protects\nnothing. Do not lower it.\n\n**And measure the version you actually run.** Patterns are added over time\n(`whsec_` landed in **0.4.0**), and a caret on a `0.x` version locks the minor —\n`^0.1.7` can never resolve `0.4.0`, so a consumer never picks these up by\nitself. Check the **installed** version, not the source tree and not the roster,\nbefore concluding a pattern is absent.\n\n## Two recommended integration shapes\n\n1. **Write boundary (ingest gate)** — redact before you persist, so secrets never\n   enter storage:\n   ```ts\n   await db.insert({ content: redactSecrets(content).redacted });\n   ```\n2. **Egress guardrail** — scrub before a value leaves to a user or an LLM. The\n   highest-value guard is scrubbing retrieved context before it enters a prompt,\n   so the model can never see (and never echo) a secret that predates the gate.\n\n## Custom / per-tenant patterns\n\nAdd your own patterns on top of the canonical set — they run **after** the\ncanonical patterns, so canonical attribution always wins:\n\n```ts\nredactSecrets(text, {\n  extraPatterns: [{ label: \"acme-key\", description: \"ACME key\", regex: /\\bACME-[0-9]{6}\\b/g }],\n});\n```\n\n## What it detects\n\nA curated, **ordered** set (`SECRET_PATTERNS`) of named, low-false-positive\nregexes — most-specific first so attribution is correct:\n\n- **LLM:** Anthropic (`sk-ant-…`, incl. `oat01-`), OpenAI (`sk-`/`sk-proj-`),\n  OpenRouter (`sk-or-v1-`), ElevenLabs, fal.ai, Google/Gemini (`AIza…`),\n  Google OAuth (`GOCSPX-`), Mistral (field-anchored).\n- **Cloud / infra:** AWS (access key id `AKIA…`/`ASIA…`, **secret access key**,\n  **session token** — see below), GitHub, GitLab, Slack, Stripe live, Resend,\n  Fly.io, Cloudflare (global key · API token via field-context · Turnstile secret),\n  Supabase (`sbp_` / `sb_secret_`), npm (`npm_…`), UpCloud (`ucat_` + 26\n  Crockford base32, v0.10.1), Cloudflare user token (`cfut_`), Runpod (`rpa_`),\n  Hugging Face (`hf_`/`api_org_`), Tailscale (`tskey-`), Tigris (`tsec_`), Slack\n  app tokens (`xapp-`), Aiven/UpCloud managed-DB passwords (`AVNS_`) — v0.11.0.\n- **Connection strings (v0.11.0):** the PASSWORD inside a `postgres://`, `mysql://`,\n  `mongodb(+srv)://`, `redis(s)://` or `amqp(s)://` URL. Only the password is\n  redacted, so the URL still says which database it is. A password needs a digit\n  or 12+ characters, so README placeholders (`user:password@`) are left alone.\n- **Fleet:** upmetrics (`uk_`), cardmem (`pa_/pi_/pk_`, `piw_`), cms (`wh_`),\n  HelpDesk (`hd_live_` + 64 hex — the shorter `hd_live_f4b4cf` PREVIEW is\n  deliberately **not** matched, see below),\n  trail (`trail_`), cronjobs (`cj_` + 43 base64url), and — from the vault survey\n  of 30 Sep 2026 (v0.11.0) — BID app keys (`bidk_`), beacon (`bcn_`), mailworker\n  (`mw_`) and upmetrics remediation (`umrt_`) tokens.\n- **Generic:** JWT (`eyJ…` — also Turso + Supabase service_role tokens), PEM\n  private-key blocks, Discord bot/MFA tokens, and `labeled-hex-secret` (a 40+ hex\n  value assigned to a `secret`/`token`/`password`/`api-key`-named field).\n- **Field-anchored (context-only, to avoid FP on bare tokens):** Cloudflare API\n  token, Mistral, Vimeo — matched only next to their env-var name.\n\n### AWS: the id was never the credential (v0.8.0)\n\nUp to 0.7.2 this package shipped exactly one AWS pattern, `AKIA[0-9A-Z]{16}`.\nAn access key **id** alone is useless to an attacker; the **secret** access key\nis the credential. So the output masked the half that does not matter and left\nthe live one beside it — under a `[REDACTED:…]` marker, which tells the reader\nthe text was cleaned:\n\n```\naws_access_key_id=[REDACTED:aws-access-key-id]\naws_secret_access_key=<the live 40-character secret>     ← still there\n```\n\n> The value is written as a placeholder rather than quoted. Our own commit gate\n> refused this section twice while it was being written — first with AWS's full\n> published specimen, then with a shortened form that still matched. A README\n> about a secret-scanner is exactly the file that should not carry one.\n\nThree patterns now cover the pair, and **two of them are complements, not\nalternatives**:\n\n| label | fires on |\n|---|---|\n| `aws-secret-access-key` | a `(aws-)secret-access-key`-named field + 20 or more non-delimiter chars, any alphabet |\n| `aws-session-token` | a `(aws-)session-token`-named field + 100+ base64 |\n| `aws-secret-access-key-paired` | a 40-char base64 value **within 80 characters of an `AKIA`/`ASIA` id** |\n\nA bare 40-character base64 string **cannot** be matched on shape — it is every\ngit object hash and base64 body in every repo we own — so the field-anchored\nrule is the primary one. The paired rule exists because a real pair is often\nunder a name we did not anticipate: Terraform spells it `secret_key`, which the\nfield rule deliberately does **not** match (too broad on its own) and the pair\nrule catches because the id is 18 characters away.\n\n**The 80-character window is measured, and both sides of it are pinned by a\nfixture.** Gap between the end of the id and the start of the secret, in the six\nformats these actually arrive in:\n\n```\nconsole CSV row            1     terraform provider block   18\nsts assume-role JSON      21     aws CLI credentials file   25\nenv export pair           30     docker-compose env         30\n```\n\n80 is the largest real case plus room for one intervening line. A threshold\nnothing can move is a magic number wearing a measurement's clothes.\n\n**An `AWS_*` variable name does not mean an AWS key (v0.8.1).** cardmem measured\ntheir own production environment after 0.8.0 was tagged: all four `AWS_*`-named\nvariables on Fly are **Tigris** (Fly's S3-compatible store) — a 54-character\n`tid_` id and a 75-character secret. Every S3-compatible service (Tigris, R2,\nMinIO, Backblaze) reuses AWS's variable *names* with its own key format.\n\n0.8.0 required exactly 40 base64, so the field said `AWS_SECRET_ACCESS_KEY`, the\nvalue did not look like AWS, and a live credential stayed in the clear with no\nmarker anywhere near it — this card's own defect, in a new provider. **The length\nis now a floor (20+), not AWS's 40.** Pinning the exact shape put a second\nsignal on top of a name anchor, and the field name being the signal is the whole\ndesign of every context-only pattern here.\n\nThe paired rule keeps its exact 40, because it is shape-based by necessity and\nanchored to an AWS access key id.\n\n**False-positive cost, measured across this repo's own 907 tracked files: zero.**\nThe paired rule fires nowhere, because it requires the id to be present. The\nnegative fixtures are real shapes pulled from this repo — a commit sha, a pnpm\nintegrity digest, JWT segments, a base64 body — not invented ones, since an\ninvented negative is chosen by the same author who chose the pattern.\n\n> **Output changes for real text on this release.** A consumer who has been\n> storing or logging AWS pairs will see previously-visible values start coming\n> back redacted. That is the fix working, not the package becoming noisy.\n\n### HelpDesk: the preview must stay readable (v0.9.0)\n\n`hd_live_` followed by **exactly 64 lowercase hex**. HelpDesk mints through\n`@broberg/apikey`, which is ours — `generateKey(prefix, 32)` returns\n`${prefix}_${randomBytes(32).toString(\"hex\")}` — so the length is a fact about\nour own minter, not a guess. The test generates its fixture by calling the real\n`generateKey`, so it cannot drift from what HelpDesk actually issues.\n\n**The exact length is the load-bearing part.** HelpDesk shows a preview —\n`hd_live_f4b4cf`, prefix plus 6 hex — on purpose, in their UI and their logs, so\na human can see *which* key was revoked. It is not a secret. Redact it and a\nvalue designed to be read stops doing its job.\n\n> If you are reading this because you want to catch shortened keys too: that is\n> the one change this pattern must not take. A named test asserts\n> `classify('hd_live_f4b4cf') === null`, and loosening `{64}` reddens it.\n\nThis is the mirror of the AWS seal above:\n\n| | the risk | what the mutation proves |\n|---|---|---|\n| AWS | a pattern that can only be **too narrow** | widening it reddens a false-positive test |\n| HelpDesk | a pattern that can only be **too broad** | loosening `{64}` reddens the preview test |\n\n**No publishable variant, measured not assumed.** HelpDesk is headless and its\nconsole is a client of the same API using a session token; `grep -c \"hd_\"` in the\ndeployed bundle returns 0. No key reaches a browser, so Stripe's `pk_live_` trap\nhas no counterpart here — re-check if that ever changes.\n\n**What generalises:** every fleet key minted through `@broberg/apikey` has a\n64-hex tail, so the next prefix needs no measurement — only the prefix. What does\n**not** generalise is a single `<prefix>_[0-9a-f]{64}` rule: a 64-hex tail is also\na sha256, so `etag_<sha256>` and every content-addressed identifier would match.\nPer-prefix stays.\n\n### Deliberately NOT detected\n\n- **Stripe publishable keys (`pk_live_` / `pk_test_`).** These are *publishable*\n  by design — they ship in browser bundles and in setup instructions. They are\n  not a leak risk, and redacting one would corrupt copy-pasted setup docs for no\n  gain. This is a **decided scope boundary, not a gap**: a secret-scanner that\n  masks a public value trains people to ignore it. Requested and declined,\n  2026-08-25.\n\n- **A bare Hue application key sitting in free text** (40 mixed-case chars with\n  no field name near it). `hue-application-key` is **context-only**: it fires on\n  a `hue`/`bridge`-named field, not on the shape alone.\n\n  This is the same trade as above, and it was paid for. Until 0.5.1 the pattern\n  matched on shape, and the shape of a Hue key is also the shape of a\n  40-character window inside an npm integrity digest:\n\n  ```\n  resolution: {integrity: sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/…}\n                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matched\n  ```\n\n  33 hits in one real `pnpm-lock.yaml`. Any repo running this package as a\n  pre-commit gate could no longer commit a lockfile change — so no dependency\n  update at all. **A gate nobody can satisfy is a gate someone switches off**,\n  and then the other 38 patterns protect nothing either. Do not remove the\n  anchor to \"improve coverage\": that is the change that breaks everything.\n\n  **`classify()` is unaffected** and still names a bare key. It answers a\n  different question — its caller has already said \"this is a secret, what\n  kind?\", so there is no surrounding text to corrupt and no checksum to confuse\n  it with. Same value, two questions, two evidence bars.\n\n### Design notes\n\n- **Pattern-based, not entropy** — a redacted *real* fact corrupts knowledge, so\n  we accept missing an exotic token over false-positiving.\n- **Never a bare hex pattern** — it would hit git shas/hashes. Prefix-less service\n  secrets are caught only via the `labeled-hex-secret` name-context rule.\n- **Order is API** — specific patterns run before generic ones (`sk-ant-` before\n  `sk-`); a test asserts it.\n- **`hue-application-key` is the one unprefixed shape, and it runs LAST.** A Hue\n  v2 key is 40 chars of `[A-Za-z0-9-]` with nothing to anchor on, so the regex\n  carries a negative lookahead — `\\b(?![0-9a-f]{40}\\b)[A-Za-z0-9-]{40}\\b` — that\n  excludes **git commit SHAs**. This is not an optimisation: telemetry and error\n  output are full of SHAs, and a redactor that mangles commit hashes gets turned\n  off within a week, after which it protects nothing. Hue keys are mixed-case,\n  SHAs are lowercase hex. Do not \"simplify\" the lookahead away; `test/hue-key.test.ts`\n  asserts real SHAs stay untouched, standalone and in prose.\n\n## API\n\n```ts\ninterface SecretPattern { label: string; description: string; regex: RegExp; }\ntype SecretConfidence = \"format\" | \"announced\";\ninterface RedactionFinding { label: string; count: number; confidence: SecretConfidence; }\ninterface RedactionResult {\n  redacted: string;\n  findings: RedactionFinding[];\n  scanned: readonly SecretConfidence[];   // 0.3.0 — which axes were examined\n}\ninterface RedactOptions { extraPatterns?: SecretPattern[]; announced?: boolean; }\ninterface ClassifyResult { label: string; description: string; }\n\nconst SECRET_PATTERNS: SecretPattern[];\nconst ANNOUNCED_LABEL: string;                   // \"announced-secret\"\nfunction redactSecrets(text: string, opts?: RedactOptions): RedactionResult;\nfunction hasSecret(text: string, opts?: RedactOptions): boolean; // honours opts.announced\nfunction hasAnnouncedSecret(text: string): boolean;              // the refuse-path\nfunction classify(value: string, opts?: RedactOptions): ClassifyResult | null; // single-token type detection\nfunction redactionMarker(label: string): string; // `[REDACTED:${label}]`\n```\n\n## Upgrading to 0.7.0\n\n**One breaking change, and it is in `classify`.** The value-only axis — shapes\nnamed from the value alone, with no field name beside them — is now **opt-in**:\n\n```ts\nclassify(bareHueKey)                        // -> null      (was: hue-application-key)\nclassify(bareHueKey, { valueOnly: true })   // -> hue-application-key\n```\n\n*Why:* the decision to accept a weak signal belongs to whoever can **render** the\nuncertainty. A surface that shows a credential's type as a chip, with nowhere to\nsay \"low confidence\", must not be handed guesses — a guess it accepts silently\nbecomes an assertion. Callers who *can* carry that (a log redactor, where a false\npositive costs a masked word and a false negative costs the key) opt in and get\nit, including inside free text:\n\n```ts\nredactSecrets(text, { valueOnly: true })    // also masks bare 40-char Hue keys\n```\n\n`^0.6.0` will not resolve this release — a caret locks the minor on a 0.x\nversion — which is the intended outcome for a behaviour change.\n\n**Fixes, no action needed:**\n\n- A **quoted** announcement is now caught. `{\"password\": \"hunter2\"}` passed\n  through 0.6.0 untouched and `hasAnnouncedSecret` answered `false`. JSON is how\n  a machine writes a credential, and it was the one shape the pattern missed.\n- **Wrapping delimiters survive.** `config(password='hunter2')` used to lose its\n  closing quote and paren; a trailing comma or backtick went the same way. If you\n  re-redact a stored corpus, do it on 0.7.0 — 0.6.0 returns syntactically broken\n  text.\n- **Exported regexes are no longer global.** All 39 carried `/g`, so `lastIndex`\n  persisted between calls and `pattern.regex.test(x)` answered `true`, then\n  `false`, for the same input. `SECRET_PATTERNS` now holds stateless copies, and\n  `VALUE_ONLY_PATTERNS` is exported so the roster describes everything `classify`\n  can return.\n\n**Unchanged on purpose:** the digit branch still has no length floor, so\n`Kodeord: 2` is still redacted. Measured over 41,095 texts: an 11-character\nDanish password sits in the same length band as unambiguous prose, and no form\nrule separates them. The noise is kept because the alternative leaks a password.\n\n## Upgrading to 0.4.0\n\nTwo changes from buddy, measured against a real Danish corpus and their own DB:\n\n- **Added** `whsec_` (Stripe webhook signing secret) to the format axis. Clean\n  gap, no trade-off — they found real ones sitting in plaintext because their\n  scrub runs the format axis only, so a prefixed secret we miss is a secret\n  nobody catches.\n- **Removed** bare `kode` from the announced axis (see above). If you relied on\n  it, `kodeord` and `adgangskode` still work.\n\n## Upgrading to 0.3.0\n\n`RedactionResult` gained a required `scanned` field. Additive for anyone reading\n`redacted` / `findings` — **but a deep-equality assertion on the whole result\nobject will fail**, e.g. `expect(redactSecrets(\"\")).toEqual({ redacted: \"\", findings: [] })`.\nThat is exactly the one test in this package's own suite that broke, and it was\nkept as a whole-object compare rather than loosened, because it is the only\nthing that shows a consumer what they will feel.\n\nMIT · part of the [`@broberg/*`](https://github.com/broberg-ai/components) shared-library family.\n","readmeFilename":"README.md"}