{"_id":"@aldegad/safedeps","_rev":"22-1e308f82ad96e4ffde9c9c5e44e0d567","name":"@aldegad/safedeps","dist-tags":{"latest":"2.17.2"},"versions":{"2.1.0":{"name":"@aldegad/safedeps","version":"2.1.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.1.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"5b0edeb2729de8a00507af35a9b7bec993a5f1a5","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.1.0.tgz","fileCount":19,"integrity":"sha512-Fz6UkkpPT718CYbDEoJ0KYlr5U6yAGK2aZ2DnB8lBve2/zhiCXjs15LDwOMdmMsqLGHYsTY3YFzEWvllKxHpKg==","signatures":[{"sig":"MEUCIQDYUxHBgbsYX0ic3L1rHsaTWXbkMpYfdrFiCWG740iWuQIgaREOj6kTPlnl9EF5/3RZXS+ulAF7QsN2lJNg+kPpoic=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":202436},"main":"bin/safedeps","gitHead":"af6fcd84d39ae3aefac9ee4ae80e3e480899e7a2","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.1.0_1779095256324_0.6690816271097819","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"@aldegad/safedeps","version":"2.1.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.1.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"2c66bcbc574b7c8e1cb7d61af6ca56c588236e0d","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.1.1.tgz","fileCount":20,"integrity":"sha512-PlO+9f8khhxdfQUVEHU7XsGJsJ5qLWL1QskpdwoUfCQmp2l/ckmQJxiZ3ZugmkNq0yCiru+ZtPejtIu3iffK8g==","signatures":[{"sig":"MEYCIQCizrbFfXp/TXhyRBs9iEv4ASmcr6vsxgWJeTfX38sJ3wIhALaVcJP7V8rAgaBHup3eOJGpVyyI6SoNIkQMTTWLo7xF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":212102},"main":"bin/safedeps","gitHead":"4ce92989f8b70f32652b4defc000c4e5717fd404","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.1.1_1779098216864_0.4889979415483592","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@aldegad/safedeps","version":"2.2.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.2.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"050e1a579c9bd05d93dc0c957cd519e76c6814ce","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.2.0.tgz","fileCount":26,"integrity":"sha512-aTnSDSHmULDOj//xnves4iOkOE8h7GT5eJ3f8scGP4ZVSl6D9GQwppqAdpKc+nXvcQpEzWDFY6JeiGdrclHO1Q==","signatures":[{"sig":"MEUCIQCujiyhNVUIZlC4DSL8LDHOSmzb/Gdt5ER8zng6xNhfOQIgZoPmCdLYx3WdfGuwCM6f5oipioTRSvttcbwzTLKXZFo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":282501},"main":"bin/safedeps","gitHead":"6bb557c64c25d76c411cd1821766f2e3b60aed1d","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.2.0_1780678761558_0.267985293822387","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"name":"@aldegad/safedeps","version":"2.4.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.4.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"efbbddda8026d2f2a0675433f88c65a75ff5ccd1","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.4.0.tgz","fileCount":31,"integrity":"sha512-w3kIiS/FmAmd7ea3qevGHfDaPm6zVmDN+MrVU4tWGkxHAXF/35UGyreHra7wYMUl+5fOC7LC8GFv2wypWxeDkA==","signatures":[{"sig":"MEUCICwnuaUw+HJyjqaKdnleGXkbKp8NA7+gZczUHLsyQlaCAiEAmZ3kO0X6vwuTKOlVSqJGSLFjBullioALbsM4lbZ1+sM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":318607},"main":"bin/safedeps","gitHead":"b25ee4810a8705e8f28f8a8c95fec32bd7fa5e69","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.4.0_1780729636894_0.6008248084756485","host":"s3://npm-registry-packages-npm-production"}},"2.4.1":{"name":"@aldegad/safedeps","version":"2.4.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.4.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"43ade4771dd1cd0f5903594124daf11a37294dba","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.4.1.tgz","fileCount":31,"integrity":"sha512-X8qbaN+dgs9wca7bxNfBQEZB7o/YRPEw14WRX/eJyd2vdzBvBjQVu+LmUYLM8gBtO8od4Zg2Tp0lMar1LJdo1g==","signatures":[{"sig":"MEQCIFhl55sAAtSttyLNROKrVPEvbKPN5h+iiU/cZqItsWDfAiBsufrp7Wbo0FXlezXEQKq4DnaW0LXq+VWcJt3oFaalNg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":326180},"main":"bin/safedeps","gitHead":"239a25b3608ec6a997519791cfb375509202dc86","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.4.1_1780731622314_0.41706067993375173","host":"s3://npm-registry-packages-npm-production"}},"2.5.0":{"name":"@aldegad/safedeps","version":"2.5.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.5.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"af36ba986d3ea3f2f575239dc2faabfb823d4044","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.5.0.tgz","fileCount":31,"integrity":"sha512-yr2m07ul5BKaoQ3U7A2PimPJqltDnF08tTbBBpH3+DvhlL/EzpjCi/atLvRhABYxEaAfHgXwX6ZfYcWAgaQ5BA==","signatures":[{"sig":"MEUCIQCb/M1e2B32Bel0MeEq5EQYnExPZSnJiuFhQZTWwlMawgIgAhIgroHwv5yxLDQwqXhm7YjmmGcWPY8UwMNXBYpG494=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":341819},"main":"bin/safedeps","gitHead":"c97a4594c4bd6a05c6abcbc34cb7104d30d524be","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.5.0_1780744331693_0.30616777817430996","host":"s3://npm-registry-packages-npm-production"}},"2.5.1":{"name":"@aldegad/safedeps","version":"2.5.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.5.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"ee2c400888a26a550ef169baea1e44a651cd7166","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.5.1.tgz","fileCount":31,"integrity":"sha512-t+UT0ZJRvBCXuNRaLZGvTyzXZdbXVR2BAvjgxCmAJePUe6IgLxnvjVX/bB0nXedomw8RirLFky87DWypr62SHw==","signatures":[{"sig":"MEUCIQCfytKekhIRYeTAzhvd4zX93RbN3R+K4OzXXh4NGhgNKQIgOLmP7IqZ9KXL23lv0SYolfCKrljRyOW/FLttzV9BshI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":348257},"main":"bin/safedeps","gitHead":"6890740b3615d7b8e23bb9c6214490c925bf296c","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.5.1_1780750815424_0.33966084497267657","host":"s3://npm-registry-packages-npm-production"}},"2.6.0":{"name":"@aldegad/safedeps","version":"2.6.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.6.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"5454918ed544715be11f83d96ac5d0df40494bdd","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.6.0.tgz","fileCount":31,"integrity":"sha512-Al/rHAPPHFHko64M9STZVNbPeX/NeL89XCJ3IlowBH1P765BTgJGU/Ysr8AAaEGg+JWVZ5v2zbPYait3elaWtQ==","signatures":[{"sig":"MEUCIQCPJwZ/EOsmcazZafcQpi8c3Zsyk8TjNiw/quaO+CqWRQIgNd9TUH8H8TZSUO1bnO9Loq+d4mxo941FuMujWAoarW8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":348175},"main":"bin/safedeps","gitHead":"912ef349bcecfed1a0eedeac309a6c6a93ba030b","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.6.0_1780753694487_0.3693822080043545","host":"s3://npm-registry-packages-npm-production"}},"2.6.1":{"name":"@aldegad/safedeps","version":"2.6.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.6.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"12cfe60e1066b232c1989245c70e4771f789b5cb","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.6.1.tgz","fileCount":31,"integrity":"sha512-1rSgp+2npcbfsORGJkrcPDdVtIrpCgFOX4soMU3lSXbTHjU/2eyA1Vw6ixDJMOzg6ASuT/U+cre9OR2C0u6ChA==","signatures":[{"sig":"MEQCIAEgPq2xnbqjFNXtrU2uBxEm6KPjr6xLLpYHNtx4Y+W2AiBDuVJMxrL9QOOhOyreeEZkuInyEuGpQaJN8MU6i0L1Ig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":359167},"main":"bin/safedeps","gitHead":"b524f27e74ca52e00173c35e2e5eeb9bcf68cc7d","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.6.1_1780762253748_0.46026878901674295","host":"s3://npm-registry-packages-npm-production"}},"2.8.1":{"name":"@aldegad/safedeps","version":"2.8.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.8.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"1449b6d3c128292550ed0b9a4810cf182b7ea9e2","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.8.1.tgz","fileCount":31,"integrity":"sha512-yVoi1zLBBozvJB97uz5gxTVt3E1zJMqld/bfe0Bof84y8Hl1+9QiBSUpoaG0w3c5/XfxaB8AoffZQ3mpJY4ZYw==","signatures":[{"sig":"MEUCIFISBJsUZAKMYNGgNZK4sVqeGEcqjUDkjanUGSqGZ3SvAiEA6F1K45p0NyU6zZ4R5ykTHFaKqPhJmUimbmCSYVtmX4M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":402429},"main":"bin/safedeps","gitHead":"7a8bc31f223d436ecd7c522fe5baf0120f98f814","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.8.1_1781871739395_0.8068610246473669","host":"s3://npm-registry-packages-npm-production"}},"2.9.0":{"name":"@aldegad/safedeps","version":"2.9.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.9.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"a431190c02b7fea6aa5c50d0adb18a9afd4c4bdc","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.9.0.tgz","fileCount":31,"integrity":"sha512-+P/AnqWMp3aH01uDs/ePCRGQY8eh1t8CvJIzwAwSlqk408Lr+iy3w1wTKFjW9Iq/qMlT9op2IFMWTh6BzxALEA==","signatures":[{"sig":"MEUCIEtpjRXSc5UoPNEx41UZtajqHigz84q/45Olh5SMzPrbAiEAiwIOg1aFlxoKgHqHivP5cvREuMqtS1q+f1WJkFNEJYo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":424224},"main":"bin/safedeps","gitHead":"0d956b578ee663919d9040fc0704f18162fe7a03","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.9.0_1781878509882_0.11484409340067292","host":"s3://npm-registry-packages-npm-production"}},"2.9.1":{"name":"@aldegad/safedeps","version":"2.9.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.9.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"febe6c056c59e1288b076dadc4939f400791a548","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.9.1.tgz","fileCount":31,"integrity":"sha512-wGJX2jmTXui/LpgPQW0Aydk8Uj+FQOHIJ0uv1dAmS9xfsAWikvrJ0I1Cmx8lM5Q6A0SvVDXsK+5B/Zo17cS0mA==","signatures":[{"sig":"MEQCIGEXz78uJQ8tZ/yEvR4I4iUZ5qcJYr2NLVi4NQgKv0joAiB05z8dEyqXgA43eE2qhfrRbEd1o7ljQ41v/F/xvBMhAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":428100},"main":"bin/safedeps","gitHead":"e306a8733e117b6808fd4b8504857fcdadf03c3d","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.9.1_1781922713469_0.04086108762467622","host":"s3://npm-registry-packages-npm-production"}},"2.14.5":{"name":"@aldegad/safedeps","version":"2.14.5","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.14.5","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"56409f1ee0f987c5e96ad5e7017666c90087d05c","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.14.5.tgz","fileCount":35,"integrity":"sha512-lfGOolsKEHRRwwYfLeYwPmLJ8B925x00YZk0zaSHz0mCbZm8iYPXtEbVVasbZnjE52IYQ+AzVj1Lj5IewYPBzw==","signatures":[{"sig":"MEYCIQDYqxHawse2eHa1Fm38zdf/+xCr2WMje3QURa7kYUEV3gIhAJDOgkwjDKfxPXnC5+ior2+zSX1BDebgfoGDHtqsQ1Py","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":618179},"main":"bin/safedeps","gitHead":"6d861d327524046677f24f60f404fed7d2ca1827","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.14.5_1785829875716_0.4498551439236962","host":"s3://npm-registry-packages-npm-production"}},"2.15.0":{"name":"@aldegad/safedeps","version":"2.15.0","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.0","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"de4f319a1e7ba111bbdcefcb30ebe9978b85f031","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.0.tgz","fileCount":36,"integrity":"sha512-zjrGCrN9ZUvQBQM1I0enfbFK30oY7t4LRnF3too6lbJEMlf+dHw/c4gPXuajbCWXo/YPDgHFUTMyu/YoaKBMYw==","signatures":[{"sig":"MEUCIAk+3m7zi8MshcjFkzXLlmFXYgQQhbtNLAq9Nmdoo4oxAiEA44918P84GfXJqnysCgnqdXh7CPWcDbKNluLI54dvoII=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":650570},"main":"bin/safedeps","gitHead":"623cb451d982d9de8718cbf14013c73b158a5352","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.0_1785835080070_0.0228313236760036","host":"s3://npm-registry-packages-npm-production"}},"2.15.1":{"name":"@aldegad/safedeps","version":"2.15.1","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.1","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"b10f4ab45ae9c621c3c5fe6ba3f91f201191f5ef","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.1.tgz","fileCount":36,"integrity":"sha512-tMlHzRbPfAfo4zg9Ra6+D3JYGwsNEom1uGkzpFwK74wWIAtA/srrfI3g+jvFIpQFvpXh8MiOThWum71aF29DTQ==","signatures":[{"sig":"MEUCIQDMdC8RfYWBkLsodQgtoYHtsoCT4r4t1t2rnvYWXYBzqgIgeaNab9dCUJIC+xkO+1UTkEw/3k1IrYmTEYcMw9Bq+BQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":677960},"main":"bin/safedeps","gitHead":"785e6c0cf8680f451c713408f9272b23031d3276","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.1_1785842072006_0.0569254823849068","host":"s3://npm-registry-packages-npm-production"}},"2.15.2":{"name":"@aldegad/safedeps","version":"2.15.2","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.2","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"b84b68e791fc87024030ace2ffe7cd1a336de62b","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.2.tgz","fileCount":36,"integrity":"sha512-zx09ISfcHA1yIzi5BbO7NGl0p+DVZ4OrbEDCSHFOV9C0T36mMOmqxCArH4PKFIA5LtxsCxKnzZ9ZDIxLsWRHiw==","signatures":[{"sig":"MEUCIDbmqJQ+M16w7k4LOibBD8zo76efZF/BX4wHb64erfVMAiEA7AHd01PrDgSYpow6hoxFr+2jISmgMmgSZNwisY1xb4M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":695256},"main":"bin/safedeps","gitHead":"f7bf91e844ea0db08f9b5bcd8d053a5e2094bd1e","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.2_1785848247095_0.359991531679839","host":"s3://npm-registry-packages-npm-production"}},"2.15.3":{"name":"@aldegad/safedeps","version":"2.15.3","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.3","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"49edb276d4f4df65d01f07dca1199db10daa1690","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.3.tgz","fileCount":36,"integrity":"sha512-ajnpW61GkNYPgA+5ZUMEXxLn1W/Bzt/Enc3SHE7p1aOsNf75E6FMBzZiyLIuoSDEJbL2bMe1Mx/1feitDCa8QA==","signatures":[{"sig":"MEYCIQCpJARXW3JVhRc4n4LkRKImSNexYMLRb4cOZ8eSCDaWjgIhAMzzoKKTvVqHjdbkBp2KJi0Wttw0K5UwBH7I7G+4JDT7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":701710},"main":"bin/safedeps","gitHead":"6861ac8eeeca844fb9ff8188adccd0205360cd2d","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.3_1785850305480_0.7803410784171478","host":"s3://npm-registry-packages-npm-production"}},"2.15.4":{"name":"@aldegad/safedeps","version":"2.15.4","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.4","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"9bdb1ae731a816ff2efce3fd2b5d9d33092bffec","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.4.tgz","fileCount":36,"integrity":"sha512-RAN+zBn4uc0KPkLnMMb5VFItb2ZLq7xgVBCzj2Z6HNWhwwZgUwAuukkjtCNlSzV2X3FFuOX5k3PktwN7tp20rQ==","signatures":[{"sig":"MEQCIA2cZYJbI2rYn1n2BFsgjiU6wvgxFB1BBhyegq6CkNlrAiBE0kmdtASr5kiC9+/IU+mZUP6VCgExKGcaWde/1tFkvA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":706603},"main":"bin/safedeps","gitHead":"db732a42ba564f44c40dff97a839952760af727a","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.4_1785854578648_0.6848920789259034","host":"s3://npm-registry-packages-npm-production"}},"2.15.6":{"name":"@aldegad/safedeps","version":"2.15.6","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.6","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"0476c0f3657f67ccb33f484195dac5b6f399db24","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.6.tgz","fileCount":36,"integrity":"sha512-4QwxbliApMS+zWrc9dRuRD5/4nSYR692DRo3oF1Ee5Stst7j+UGOQrcMlP2ymCDnXZaRxms5sj3uW0LFhK+gqQ==","signatures":[{"sig":"MEUCIQD3rrFHz5xIU9zkrYvW1KlpVQuK/8Ap0PsOHTGyHH5jQAIgWFJLwLkPSKMjXTDfjOKxVuwbmXyF5tXAHSevLDTx2Ik=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":716139},"main":"bin/safedeps","gitHead":"cb6f5c71f5bf66c1810bb06cf31da37bb0cdf6d6","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.6_1785857979197_0.13062707314689814","host":"s3://npm-registry-packages-npm-production"}},"2.15.7":{"name":"@aldegad/safedeps","version":"2.15.7","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.7","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"682b00c1c1f2d333515a59ce2809839a26a8f92b","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.7.tgz","fileCount":36,"integrity":"sha512-7J+4b+gpH8Si9YbHqq/DfDbwBTvPx54g+DMtdd4Z7G3+SCxjLRDkZLQT8wXUVZJLwObFI1Pxy+mcuBw4Lnx8iQ==","signatures":[{"sig":"MEQCIGtH/MqsE9HF/RDrW003SftisMD25oVwUqffeykii6PyAiAMUq5ABcXGiozpYL0ESjV/WQ5xW17SPNMppbqN0dPjZQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":725922},"main":"bin/safedeps","gitHead":"cbb200bc1ca21e56f8ced668775b2bffde583fc1","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.7_1785860188539_0.8785258256087833","host":"s3://npm-registry-packages-npm-production"}},"2.15.8":{"name":"@aldegad/safedeps","version":"2.15.8","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","_id":"@aldegad/safedeps@2.15.8","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"homepage":"https://github.com/aldegad/safedeps#readme","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"bin":{"safedeps":"bin/safedeps"},"dist":{"shasum":"4d456d60ee438c9d137ca1eab44dc68928c6130a","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.15.8.tgz","fileCount":37,"integrity":"sha512-ewxt5wHN5QuhFHit34xCPsdess9BxoLEMQn9cr1du2HRsEoouQGSI3dVtzEc7SP692SBLg/gWj+2/GI+/5A0bQ==","signatures":[{"sig":"MEQCIH6ZNc/KymcaqRFTDYA/EcuzOUeIO8mWVCtjQhkJdlKxAiAqxyRcYlbzGMGPWQSUlF9PS1jNRp1yNKnv7P9hvZJrbg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":739210},"main":"bin/safedeps","gitHead":"2d6910bdd447648149e17504403b8befbf07f48f","scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"repository":{"url":"git+https://github.com/aldegad/safedeps.git","type":"git"},"_npmVersion":"10.9.4","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","directories":{},"_nodeVersion":"22.22.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/safedeps_2.15.8_1785862334325_0.4729417587791356","host":"s3://npm-registry-packages-npm-production"}},"2.17.2":{"name":"@aldegad/safedeps","version":"2.17.2","description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","main":"bin/safedeps","bin":{"safedeps":"bin/safedeps"},"scripts":{"test":"bash scripts/test/smoke.sh && bash scripts/test/consumer-forms.sh && bash scripts/test/self-budget.sh && bash scripts/test/hook-entry.sh && bash scripts/test/e2e.sh"},"keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"author":{"name":"soohongkim"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/aldegad/safedeps.git"},"_id":"@aldegad/safedeps@2.17.2","gitHead":"bb0787da65eed2ab9462f4782ff990069b5e5aa7","bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"homepage":"https://github.com/aldegad/safedeps#readme","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-wCtvPD/F3iUeE5w46v1kikkNEExrXb9v7YonRBnF8YddL4zEAM+f+4Bg+7TvWXR9iCE9rWU/vrrjwGni1yT5hA==","shasum":"0d04e2ea85bc986ac2529a7effdd8ece82eb220f","tarball":"https://registry.npmjs.org/@aldegad/safedeps/-/safedeps-2.17.2.tgz","fileCount":42,"unpackedSize":837315,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCVjV/S99TU/RSQ8mzp8YwrWAI+fauTJAWIiFHX24FsgwIgPzykzPQx2FWm6Jhj1H04Ao9o1zI0QFsxM/8kXc2OIz0="}]},"_npmUser":{"name":"aldegad","email":"aldegad@gmail.com"},"directories":{},"maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/safedeps_2.17.2_1787221179162_0.597357721698087"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-18T09:07:36.254Z","modified":"2026-08-20T10:19:39.515Z","2.1.0":"2026-05-18T09:07:36.486Z","2.1.1":"2026-05-18T09:56:57.008Z","2.2.0":"2026-06-05T16:59:21.737Z","2.4.0":"2026-06-06T07:07:17.039Z","2.4.1":"2026-06-06T07:40:22.464Z","2.5.0":"2026-06-06T11:12:11.830Z","2.5.1":"2026-06-06T13:00:15.569Z","2.6.0":"2026-06-06T13:48:14.632Z","2.6.1":"2026-06-06T16:10:53.886Z","2.8.1":"2026-06-19T12:22:19.546Z","2.9.0":"2026-06-19T14:15:10.068Z","2.9.1":"2026-06-20T02:31:53.679Z","2.14.5":"2026-08-04T07:51:15.890Z","2.15.0":"2026-08-04T09:18:00.212Z","2.15.1":"2026-08-04T11:14:32.164Z","2.15.2":"2026-08-04T12:57:27.270Z","2.15.3":"2026-08-04T13:31:45.639Z","2.15.4":"2026-08-04T14:42:58.828Z","2.15.6":"2026-08-04T15:39:39.346Z","2.15.7":"2026-08-04T16:16:28.734Z","2.15.8":"2026-08-04T16:52:14.495Z","2.17.2":"2026-08-20T10:19:39.354Z"},"bugs":{"url":"https://github.com/aldegad/safedeps/issues"},"author":{"name":"soohongkim"},"license":"Apache-2.0","homepage":"https://github.com/aldegad/safedeps#readme","keywords":["safedeps","security","supply-chain","advisory","osv","reorg","claude-code","hooks","package-lock","rollback"],"repository":{"type":"git","url":"git+https://github.com/aldegad/safedeps.git"},"description":"Dependency install safety gate with OSV-backed advisory checks, approved-spec ledger enforcement, and reorg rollback hooks","maintainers":[{"name":"aldegad","email":"aldegad@gmail.com"}],"readme":"# safedeps\n\n> **Stop your AI coding agent from installing vulnerable or unapproved dependencies — and roll back the ones that slip through.**\n>\n> `safedeps` gates every dependency install your Claude Code or Codex CLI agent runs. It pre-approves packages against OSV / CISA KEV / GitHub Advisory, re-verifies the closure that actually lands in your lockfile, and auto-rolls-back anything that diverges. Local-only, with zero runtime dependencies. *(한국어 README → [README.ko.md](./README.ko.md))*\n\n- **Pre-approve** — every `pkg@version`, plus its full transitive closure for npm, is cleared against OSV (canonical), CISA KEV, and GitHub Advisory *before* it installs.\n- **Enforce the real effect** — after the install, the actual `package-lock.json` closure is re-checked, so a wrapped or obfuscated command can't sneak a package past the gate.\n- **Roll back** — anything unapproved or newly-vulnerable is reverted to the last confirmed safe snapshot. On Claude Code the install runs inert (`--ignore-scripts`), so a rejected package's lifecycle scripts never run.\n\n> **A real catch.** The pre-commit audit flagged a vulnerable transitive `hono` advisory that Dependabot missed — by re-querying the advisory DB at commit time. A CVE disclosed *after* you installed a package (\"looked safe then, flagged now\") surfaces at your next commit, not weeks later.\n\n## Quickstart\n\n```bash\n# 1. Install the CLI — the npm package is scoped, note the @aldegad/ prefix\nnpm install -g @aldegad/safedeps\n\n# 2. Wire the hooks into Claude Code / Codex (idempotent)\ncd \"$(npm root -g)/@aldegad/safedeps\" && node scripts/install/install-safedeps-hooks.mjs\n\n# 3. Done — every dependency install your agent runs is now gated.\n```\n\n> `safedeps` is the CLI command; the npm package is **`@aldegad/safedeps`** — the unscoped `safedeps` on npm is an unrelated package. Prefer the full skill source tree? See [Installation](#installation).\n\n![safedeps withholds a vulnerable install, then clears the patched version](assets/demo.gif)\n\n## Distribution Model\n\nSafedeps has two distribution surfaces:\n\n1. **Agent skill + hooks (canonical)** -- the repo itself is the skill folder. `SKILL.md`, hook scripts, provider/ledger libraries, and install helpers stay together in one directory.\n2. **npm package (CLI convenience)** -- `@aldegad/safedeps` installs the `safedeps` command. npm does **not** make Claude Code or Codex automatically discover the skill; after npm installation, users still need to run the hook/skill installer or manually register the skill folder.\n\nUse the GitHub release when you want the full skill/hook source tree as the canonical artifact. Use npm when you mainly want a versioned global CLI.\n\nTerminology: safedeps is an agent security skill backed by Claude/Codex hooks and a local CLI. It is not a Codex plugin bundle unless it is later wrapped with a plugin manifest.\n\n## Two Lanes\n\n`safedeps` owns two security lanes (full design in [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1):\n\n- **Install-time** (the focus of this README) — advisory check + approved-spec ledger + fast PreToolUse guard + PostToolUse effect enforcement + post-install reorg. Per-package, around the install command and its actual lockfile effect.\n- **Release-time** — `safedeps gates run`, `safedeps scan secrets [--repo|--worktree|--staged]`, `safedeps audit [npm|pnpm|yarn|bun]`, `safedeps hooks install|check`. Repo-tree secret scan, dependency audit, repo-local git hook install/check before push/release, plus opt-in remote repository posture checks. Repo-specific policy (gitleaks config, privacy paths) stays in the target repo; safedeps owns local execution. *(Absorbed the former `security-release-gates`.)*\n\nThe secret-leak side of the release-time lane is **per-repo and opt-in**. `safedeps doctor` is its repo-entry check: it diagnoses the repo's `.gitleaks` policy, `.githooks/pre-commit`, the active `core.hooksPath`, and scanner availability (and reports the global install-time gate too), then `safedeps doctor --fix` scaffolds a starter policy (`safedeps hooks init`) and activates it (`safedeps hooks install`). That local pre-commit setup is automatic once you choose `--fix`; it does not spend remote CI minutes. The scaffold is non-destructive — an existing repo-owned `.gitleaks.toml` is never overwritten — and the pre-commit hook runs a secret scan (`safedeps scan secrets --staged`) plus, on every commit in a repo with a supported lockfile, a dependency audit (`safedeps audit`, auto-detecting npm/pnpm/yarn/bun): a real finding blocks (fail-closed), while an unreachable advisory DB only warns and lets the commit through (observable offline failover). Remote enforcement is split: blocking direct pushes to `main` with a branch rule is recommended no-runner posture, while GitHub Actions workflows and required status checks remain explicit cost-bearing opt-in because hosted runners can cost money. See [Secret-Leak Lane (per-repo)](#secret-leak-lane-per-repo).\n\n## How It Works\n\n[![safedeps architecture — two lanes, a three-phase install gate, and OSV as the one canonical truth](assets/architecture.png)](./ARCHITECTURE.md)\n\n`safedeps` works in two moves around every install:\n\n- **Before** — `safedeps check` clears a package against OSV (canonical), CISA KEV, and GitHub Advisory, then records the approval in a local ledger. For npm it resolves the package's full dependency closure and checks every transitive package too.\n- **After** — the PostToolUse hook re-reads what actually landed in `package-lock.json` and reorgs (rolls back) anything that isn't in the ledger or that the advisory databases now flag.\n\nThe registered command for both hook events is a small entry shim (`safedeps-hook-entry.sh`). The hooks run live from the repo checkout through a symlink, so a checkout that is temporarily broken (a merge in progress, a half-saved edit) used to either block every Bash call with a bare syntax error or silently disable the gate, depending on the exit code. The shim turns both into an explained fail-closed deny: it names what broke, whether a merge is in progress, and how to recover. Details: [ARCHITECTURE — Phase 0](./ARCHITECTURE.md).\n\n**Running out of time is an answer, not a gap.** The agent runtime gives each hook a fixed budget and kills it when that expires — and the tool call then proceeds, so a gate that runs long simply disappears. Since the command scan gets more expensive with command length, padding a command was enough to cross that line. The pre-install guard now keeps a smaller budget of its own and, if it cannot finish judging in time, blocks and says so: the message leads with `UNDECIDED, not unsafe` so nobody reads a timeout as a finding. Commands short enough to be nowhere near the budget are unaffected.\n\nThe pre-install command hook (PreToolUse) is a fast advisory nudge — it blocks obvious unapproved installs and risky command forms so the agent gets immediate feedback. But for npm the real authority is the post-install effect gate: it judges what was *actually installed*, not what the command looked like, so a wrapped or obfuscated install command can't slip a package past it.\n\n**Script safety (inert install).** On Claude Code, the PreToolUse hook rewrites an npm install to add `--ignore-scripts`, so the install runs **inert** — packages land on disk but no lifecycle script runs yet. The effect gate then verifies the closure; only if it passes does the PostToolUse hook run `npm rebuild` to execute the now-verified scripts. A package the gate rejects is reorged before any of its scripts run. (This uses the Claude Code hook `updatedInput` capability. Codex CLI does not expose it, so on Codex the install runs normally and the effect gate is detect-and-rollback — a malicious install script can run once before the rollback.)\n\nThis effect-primary model is npm-only for now. `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` stay on the v2.1 command-gate + reorg model until their closure resolvers land.\n\n```\n                         PreToolUse                          PostToolUse\n                  (safedeps-pre-guard.sh)          (safedeps-post-verify.sh)\n                            |                                    |\n  install cmd ──> [ Advisory/ledger UX ] ──> [ Execute ] ──> [ npm effect gate ]\n                     |            |                           |       |\n                  Block obvious Snapshot                  Clean?  Suspicious?\n                  misses/risk   lock/manifest files,        |       |\n                                package listings          Confirm  REORG\n                                                              |       |\n                                    |                       v       v\n                                    +--- parent_snapshot_id ──> confirmed\n                                                                    |\n                                                              Rollback to last\n                                                              confirmed snapshot\n```\n\n### Phase 1: Advisory Check (`safedeps check`)\n\nBefore an agent installs a dependency, it should run:\n\n```bash\nsafedeps check <ecosystem> <pkg>@<version|range> --json\n```\n\nThat command queries OSV (canonical), CISA KEV (hard-risk overlay), and GitHub Advisory (enrichment). For npm, it first creates a script-free temp lockfile with `npm install --package-lock-only --ignore-scripts`, extracts the full dependency closure, and queries OSV `/v1/querybatch`. Clean or safely narrowed specs are written to `~/.safedeps/approved-specs/`; npm entries also record `transitive_specs`.\n\n**Yarn project-scoped closure.** When the target directory is a Yarn Berry project with a root `resolutions` entry, `check` resolves the closure from that project's actual `yarn.lock` via `yarn info`, instead of a fresh published-package probe. This lets a project that pins a vulnerable transitive dependency to a patched version through `resolutions` get approved on its real, resolved dependency tree -- the published package closure alone would still show the vulnerable version and deny the install. The approval only covers that exact project: the ledger key folds in a hash of the project directory, `resolutions`, and `yarn.lock` content, so it cannot satisfy the check for a different project or after `resolutions`/`yarn.lock` changes. If `resolutions` is declared but the requested package can't be verified in the project's resolved graph, or the lockfile isn't a supported Yarn Berry lockfile, the check stays fail-closed.\n\n**Yarn candidate materialization (v2.11.0).** The closure above needs the package to already be in `yarn.lock`, which is not true for the case that matters most: checking a dependency you are about to add. For that candidate, `check` builds the closure in a private mirror instead of denying. safedeps copies a temporary mirror of the project's canonical resolution inputs -- the root and workspace `package.json` files, `yarn.lock`, `.yarnrc.yml`, and the `.yarn/releases`, `.yarn/plugins`, and `.yarn/patches` files. Nothing else is copied; `node_modules`, caches, unplugged packages, install state, and VCS data stay out. The candidate is added to the mirror's manifest only, then Yarn resolves it there with `yarn install --mode=update-lockfile --no-immutable`. That mode updates lock resolution without the link step, so no lifecycle script from the candidate ever runs, and your own project tree is never written to.\n\nThe approval records what produced it: a hash of the exact input set, the list of input files, the hash of the generated lockfile, the candidate locator, the exact Yarn command, and the `private-project-mirror` isolation mode. The ledger rejects an entry missing any of them. safedeps re-hashes the project inputs before and after Yarn runs; if a manifest, `resolutions`, config, or lockfile changed in between, the candidate is invalidated rather than approved against a mixed project state. Any failure to copy the inputs, run Yarn, or resolve the candidate in the generated lockfile denies with `project-candidate-materialization-unavailable`. There is no fallback to the published-package closure -- a materialization that cannot be verified is a denial, not a downgrade.\n\n**npm `overrides` awareness (v2.12.0).** The same problem exists for plain npm. `overrides` is the standard way to pin a vulnerable transitive to a patched version, but the closure probe used an empty manifest, so it resolved the *published* tree and denied installs that the repo had already fixed. `check` now discovers the consuming repo's `overrides` and applies them to the probe, so it resolves transitives the way the real install will. Discovery reads `SAFEDEPS_NPM_OVERRIDES_JSON` if set, otherwise the nearest `package.json` with a non-empty `overrides`, walking up from the working directory and stopping at the repository root -- including a worktree root, whose `.git` is a file rather than a directory. Only concrete version pins are honored; `$`-references like `\"$react\"` are dropped, because they have no meaning in a standalone probe.\n\nHonoring `overrides` cannot hide a vulnerability. The probe still resolves each override to a concrete version and OSV is queried for that exact version, so an override pointing at a still-vulnerable release is flagged like any other. If the overrides cannot be applied to the probe manifest, safedeps says so and continues without them, which only makes the check stricter.\n\nBecause the closure now depends on the consuming project, the approval is scoped to it. A published-package approval is global precisely because it is project-independent; one derived from `overrides` is not. The ledger entry therefore carries the project root, the override set, and a hash of both, and the key folds that hash in. An approval earned in a repo that patched a transitive does not satisfy the check in a repo that did not, whose real install would resolve the vulnerable version. Changing the override set changes the key. Repos with no `overrides` are unaffected and keep the ordinary global approval.\n\n### Phase 2: Fast Command Guard + Snapshots (PreToolUse)\n\nWhen Claude Code or Codex CLI is about to run `npm install`, `pip install`, `cargo add`, `go get`, `gem install`, or similar commands, the guard hook provides a fast advisory/UX layer:\n\n1. **Snapshots** the current `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, and `package.json` into `~/.safedeps/snapshots/`.\n2. **Records metadata** including a `parent_snapshot_id` linking to the previous confirmed snapshot (forming a chain, just like blocks).\n3. **Captures pre-install state** of `node_modules` (package listings and binary listings) for diff-based detection later.\n4. **Fast-checks the approved-spec ledger** for explicit `pkg@version` install commands.\n5. **Runs pre-flight checks** and **blocks** the command entirely if it detects:\n   - Typosquatting package names (`lod_sh`, `reacct`, `axois`, etc.)\n   - Non-standard `--registry` URLs (anything outside `registry.npmjs.org` and `registry.yarnpkg.com`)\n   - Piped remote execution patterns (`curl ... | bash`)\n   - Explicit disabling of install script safety (`npm config set ignore-scripts false`)\n\nIf the ledger gate or a pre-flight check fails, the command is **blocked before execution** -- nothing is installed. This command guard is intentionally best-effort; it improves the agent loop and catches direct misses, while npm authority lives in the post-install effect gate.\n\n**What the command guard does not see, and what that costs per ecosystem.** The guard recognizes an install by the syntactic form that hands text to a shell -- `sh -c`, `eval`, command substitution, a pipe into a shell. Forms outside that list get through: a herestring, a command line built by `xargs`, a script written to a file and then run. For npm this is *delayed* detection, not a miss, because the effect gate reads the live lockfile and catches the result regardless of how the command was written -- while the gate finishes inside its 30s hook budget, which is a measured range and not a given (see below). For `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` there is no closure resolver behind the guard, so the same form is a **complete miss** -- it is recorded as `UNVERIFIED` in `~/.safedeps/advisory.log` and nothing else happens. Do not read \"the guard does not parse this form\" as npm-shaped. The boundary is measured and pinned in `scripts/test/consumer-forms.sh`, and `ARCHITECTURE.md` explains why widening it is not the fix.\n\n**How far \"delayed detection\" actually reaches.** The effect gate is registered at 30s and the runtime kills it there, so npm's delayed detection is real only while the gate finishes. Its cost rides on the size of the project's lockfile closure. It used to ride on the size of your approved-spec ledger too -- the gate asked the ledger about every closure package separately, and each question read the whole ledger directory -- which on a 738-entry ledger put it past 30s at a closure of **four packages**. v2.16.0 reads the ledger once per closure; the ledger axis is now flat, and on the same machine with a cold advisory cache the gate crosses 30s at a closure near **390 packages**. Below that the backstop is there; above it -- a large application's lockfile -- the gate is killed and does not judge the install. The crossing point moves with the machine, the network, and the cache, so measure yours: `scripts/measure/effect-gate-cost.sh <package-lock.json> --ledger ~/.safedeps/approved-specs`.\n\n**If a rollback is cut off, safedeps says so.** When the gate rejects a closure it rolls the project back: restore the lock and manifest files, then rebuild `node_modules`. Until v2.16.0 the log entry and the report came last, so a hook killed mid-rollback left no record at all -- in some cases with the project already reverted, which looks like an install that silently undid itself. The gate now writes what it is about to do before it does it, and clears that note once the rollback has reported itself. A note that outlives its run is an unfinished rollback: the next command reports it once, records it in `~/.safedeps/rollback-incidents/`, appends `REORG INTERRUPTED` to `~/.safedeps/reorg.log`, and tells you which stage it reached and how to repair the tree. \"Outlives its run\" means the process that wrote it is gone, not merely that the note is there -- a rollback still working has its note on disk on purpose, so an unrelated command during one stays quiet (v2.16.1).\n\n**An install with no version pin is not gated either, and it says so.** The ledger check runs on a parseable `pkg@version` operand. `pip install evil`, `cargo add evil`, `go get example.com/evil`, and `gem install evil` name a package without pinning one, so no spec is produced and the ledger gate never runs. No wrapper is needed for this -- omitting the version is enough. For npm the effect gate still enforces on the resulting lockfile; for the other ecosystems the install proceeds unverified. That case is now recorded as `UNGATED` in `~/.safedeps/advisory.log`, naming the ecosystem and the command. The record does **not** block: refusing every unpinned install is a policy change that would break ordinary `cargo add x` workflows, so it stays a decision for the repo owner -- one the record makes answerable from evidence. Routine installs stay out of the log on purpose, and the line is drawn at whether a package is named rather than at which flags appear -- which flags carry a value is a property of the tool, so pip's `-t`/`-f` take one while go's and gem's do not. `pip install -r requirements.txt` and `npm install` name none, and neither does `pip install .`, which builds from the working tree instead of fetching. A source flag consumes only its own argument, so `pip install -r requirements.txt evil` still installs `evil` and is still recorded. A record that fires on every install is noise rather than signal, but one that goes quiet whenever a flag appears is worse -- it reads as coverage it does not have.\n\n### Phase 3: Post-install Effect Enforcement (`safedeps-post-verify.sh` -- PostToolUse)\n\nAfter the install command completes, the verify hook analyzes what changed. For npm, this is the primary enforcement surface: it reads the actual `package-lock.json` closure, verifies every package against approved direct entries and their `transitive_specs`, and re-checks the closure with OSV batch.\n\n1. **npm effect gate** -- Reorgs if any lockfile package is unapproved, KEV-blocked, vulnerable, or cannot be verified fail-closed.\n\n2. **Install script analysis** -- Scans newly added packages for `preinstall`, `install`, and `postinstall` scripts containing:\n   - Network access (`curl`, `wget`, `fetch`, `http`, `socket`, `dns`)\n   - Dynamic code execution (`eval`, `exec`, `spawn`, `child_process`, `Function()`)\n   - Sensitive path access (`~/.ssh`, `.env`, `.aws`, `credentials`)\n   - Obfuscated content (`base64`, `atob`, `Buffer.from`, hex/unicode escapes)\n\n3. **Lock file diff analysis** -- Compares the snapshotted lock file content against the post-install version:\n   - Resolved URLs pointing to non-standard registries\n   - Insecure protocols (`http://`, `git://`) in resolved URLs\n   - Unusually large dependency additions (>50 new resolved entries, indicating potential dependency confusion)\n\n4. **Binary inspection** -- Checks `node_modules/.bin/` for newly added native binaries (ELF, Mach-O, shared objects) that should not appear in a JavaScript project.\n\n### Confirm or Reorg\n\n- **All checks pass** -- The snapshot is marked as **confirmed** in `~/.safedeps/confirmed`. This becomes the new safe baseline.\n- **Any check fails** -- A **reorg** is triggered:\n  1. Lock files are restored from the last confirmed snapshot.\n  2. `package.json` is restored if it was modified.\n  3. `node_modules` is rebuilt via `npm ci` (or `npm install` as fallback) to purge any malicious artifacts.\n  4. The event is logged to `~/.safedeps/reorg.log`.\n  5. Claude Code receives a system message detailing the detected threats and rollback actions.\n\n## Why \"reorg\"?\n\nThe name borrows from blockchain, where a **reorganization (reorg)** invalidates a sequence of unconfirmed blocks and reverts the chain to its last confirmed safe state. `safedeps` treats every install the same way: an unconfirmed block candidate until it passes a battery of supply-chain checks. If the installed effect diverges, the tool performs a **reorg** -- rolling the lock file, `package.json`, and `node_modules` back to the last confirmed safe snapshot.\n\nBut the reorg is the **backstop, not the front line.** Most bad installs never reach it: the pre-approval gate *denies* an unapproved or flagged package before it runs, and on Claude Code the install runs **inert** (`--ignore-scripts`) so lifecycle scripts do not execute until the closure verifies clean. The reorg fires for the residual case -- an approved direct package that pulls in an unapproved or vulnerable transitive, or a wrapped command that slips past the advisory layer -- and even then it rolls back files that never got to run.\n\nFast advisory feedback, observable rollback, and no hidden fallback. The command guard is best-effort UX; the installed effect is the backstop.\n\n## The Blockchain Analogy\n\n| Blockchain Concept | Safedeps Equivalent |\n|---|---|\n| **Block candidate** | Snapshot taken before `npm install` |\n| **Block validation** | Post-install effect checks (npm closure, scripts, lock diff, binaries) |\n| **Finality / confirmation** | Snapshot ID written to `~/.safedeps/confirmed` |\n| **Chain reorganization** | Rollback to last confirmed snapshot + `node_modules` rebuild |\n| **Parent hash linking** | `parent_snapshot_id` in each snapshot's `_meta.json` |\n| **Chain pruning** | Old unconfirmed snapshots cleaned up, confirmed chain preserved |\n\n## Detection Rules\n\n| Category | What it catches | Phase | Action |\n|---|---|---|---|\n| Typosquatting | Known misspelling patterns of popular packages | PreToolUse advisory guard | **Block** |\n| Pipe execution | `curl \\| bash`, `wget \\| sh` | PreToolUse advisory guard | **Block** |\n| Registry hijack | `--registry` pointing to unofficial sources | PreToolUse advisory guard | **Block** |\n| Script safety bypass | `npm config set ignore-scripts false` | PreToolUse advisory guard | **Block** |\n| Command indirection | `eval \"npm install ...\"`, subshell expansion, variable indirection | PreToolUse advisory guard | **Guard** |\n| npx/dlx execution | `npx`, `pnpm dlx`, `yarn dlx` package execution | PreToolUse advisory guard | **Guard** |\n| Unapproved transitive dependency | npm `package-lock.json` package missing from direct ledger or `transitive_specs` | PostToolUse npm primary effect gate | **Reorg** |\n| Vulnerable closure package | npm direct/transitive package with OSV/KEV hit | PostToolUse npm primary effect gate | **Reorg** |\n| Malicious install scripts | Network calls, `eval`/`exec`, sensitive path access in hooks | PostToolUse effect verify | **Reorg** |\n| Obfuscated code | Base64, hex encoding, `Buffer.from` in install scripts | PostToolUse effect verify | **Reorg** |\n| Lock file tampering | Resolved URLs from non-standard registries | PostToolUse effect verify | **Reorg** |\n| Insecure protocols | `http://` or `git://` resolved URLs | PostToolUse effect verify | **Reorg** |\n| Dependency confusion | >50 new dependencies in a single install | PostToolUse effect verify | **Reorg** |\n| Native binaries | Compiled executables in `node_modules/.bin/` | PostToolUse effect verify | **Reorg** |\n\n## Secret-Leak Lane (per-repo)\n\nThe install-time gate is global, but stopping a secret or a real `.env` from being committed is **per-repo** and stays opt-in — its detection policy lives in each repo, not in safedeps. `safedeps doctor` is the entry point that closes that gap.\n\n```bash\n# Diagnose this repo's posture (read-only). Exits non-zero if the secret lane has gaps.\n$ safedeps doctor\nsafedeps doctor — repo security posture\nrepo:    /path/to/repo\nprofile: public\n\nSecret-leak lane (per-repo)\n  ✓ git worktree\n  ✗ gitleaks config (.gitleaks.toml)             → safedeps hooks init --root \"/path/to/repo\"\n  ✗ .githooks/pre-commit (present)               → safedeps hooks init --root \"/path/to/repo\"\n  ✗ git hooks active (core.hooksPath=<unset>)    → safedeps hooks install --root \"/path/to/repo\"\n  ✓ secret scanner available (gitleaks)\n\nDependency-install gate (global, all repos)\n  ✓ dependency-install gate installed (~/.claude/skills/safedeps)\n\nRemote repository governance (opt-in; no-runner vs CI-cost)\n  ! remote PR security workflow (opt-in; may spend CI minutes)              → safedeps gates run --root \"/path/to/repo\" --strict\n  – main direct-push protection for main (no runner minutes; opt-in)        → no-runner opt-in: require pull requests before updating main; do not require status checks unless CI cost is accepted\n  – required PR status checks for main (CI-cost opt-in)                     → cost-bearing opt-in: add a safedeps workflow, then require it before merging main\n\n3 gap(s) in the secret-leak lane.\nFix all at once:  safedeps doctor --fix --root \"/path/to/repo\"\n\n# Scaffold the starter policy + activate the hooks (non-destructive).\n$ safedeps doctor --fix\n```\n\nWhat the lane is made of:\n\n- **`safedeps hooks init`** scaffolds a starter `.gitleaks.toml` (or `.gitleaks.private.toml` for a private repo) and a `.githooks/pre-commit`. Existing files are kept, never overwritten — the repo owns the policy.\n- **`safedeps hooks install`** activates the repo-local hooks (`core.hooksPath = .githooks`).\n- The **pre-commit hook runs two checks**:\n  - **Secret scan** (`safedeps scan secrets --staged`) on every commit, **fail-closed**. If the scanner (local `gitleaks` or Docker) cannot run, it blocks the commit instead of skipping silently.\n  - **Dependency audit** (`safedeps audit`) on **every commit** in a repo that has a supported lockfile. It auto-detects the ecosystem from the lockfile(s) present — npm (`package-lock.json`), pnpm (`pnpm-lock.yaml`), yarn (`yarn.lock`), or bun (`bun.lock`) — and delegates to that tool's native audit. This catches a vulnerable direct *or transitive* dependency — including a CVE that was published *after* you installed the package (\"looked safe then, flagged now\"), the kind of thing a human never reviews by hand. Running it every commit (not only when the lockfile changes) is the point: it re-queries the advisory DB so a newly-disclosed CVE on an already-installed dependency surfaces at the very next commit. The verdict and an availability failure are kept apart: a real finding **blocks** (fail-closed), but if the advisory DB is **unreachable** (offline / registry error) the hook **warns and lets the commit through** — an observable availability failover, never a silent skip. (CI and the daily re-check then re-cover what the offline commit could not verify.)\n\n  The only intentional bypass is `git commit --no-verify`, which the human owns.\n\nThe scaffolded `.gitleaks.toml` is a **starter you tune**: it extends gitleaks' default ruleset, adds a rule for a committed `.env` with an assigned secret (the `.env.example`/`.sample`/`.template` variants are allowlisted), and leaves a repo-owned `[allowlist]` block for your fixtures. safedeps owns *execution* — running gitleaks via `safedeps scan secrets` — not the policy content.\n\n`safedeps doctor --json` returns `{ command, repo, profile, gaps, ok, checks[] }`; `gaps`/`ok` reflect the per-repo secret-leak lane only. Remote posture appears as `lane: \"remote\"` checks, but missing remote workflows, branch rules, or required status checks do not change `ok`. `doctor --fix` is local-only: it scaffolds repo hooks and never creates `.github/workflows`, enables GitHub Actions, or mutates branch protection. A no-runner branch rule that blocks direct pushes to `main` is recommended when the user asks for \"install everything that does not cost money\"; Actions-backed required checks are not included in that no-cost bundle.\n\n## Installation\n\n### Prerequisites\n\n- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) with hook support\n- `jq` -- JSON parsing (hooks exit gracefully if missing)\n- `shasum` or `sha256sum` -- hash computation\n- `file` (optional) -- binary detection\n\n```bash\n# macOS\nbrew install jq\n\n# Ubuntu / Debian\nsudo apt-get install jq\n```\n\n### Setup From GitHub (Skill + Hooks)\n\n**1. Clone the repository:**\n\n```bash\ngit clone https://github.com/aldegad/safedeps.git\ncd safedeps\n```\n\n**2. Install the skill + hooks:**\n\n```bash\nnode scripts/install/install-safedeps-hooks.mjs\n```\n\nThe installer is idempotent. It symlinks the skill into `~/.claude/skills/safedeps` and `~/.codex/skills/safedeps` when those roots exist, patches the matching hook config, and — with `--link-bin` — can also place `safedeps` on PATH through `~/.local/bin`. That PATH link is optional: the hooks name an absolute fallback path in their block messages, so the gate is self-contained and works with zero PATH setup.\n\n**3. Manual hook registration, if needed:**\n\nThe registered command is the entry shim with `pre` or `post`, not the hook script itself — that is what the installer writes, and it is what turns a broken checkout into an explained fail-closed deny instead of a silently disabled gate. Registering the hook scripts directly still gates installs, but without that protection.\n\nEdit `.claude/settings.json` (project-level) or `~/.claude/settings.json` (global):\n\n```json\n{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"~/.claude/skills/safedeps/scripts/safedeps-hook-entry.sh pre\",\n            \"timeout\": 30\n          }\n        ]\n      }\n    ],\n    \"PostToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"~/.claude/skills/safedeps/scripts/safedeps-hook-entry.sh post\",\n            \"timeout\": 30\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n**4. Verify permissions:**\n\n```bash\nchmod +x ~/.claude/skills/safedeps/scripts/safedeps-hook-entry.sh\nchmod +x ~/.claude/skills/safedeps/scripts/safedeps-pre-guard.sh\nchmod +x ~/.claude/skills/safedeps/scripts/safedeps-post-verify.sh\n```\n\nThat's it. The guard activates automatically whenever Claude Code or Codex CLI runs a package install command.\n\n### Setup From npm (CLI First)\n\n```bash\nnpm install -g @aldegad/safedeps\nsafedeps version\n```\n\nnpm puts `safedeps` on PATH through its standard `bin` entry. It does **not** register the agent skill or hooks for Claude Code / Codex. To enable the hooks from the npm-installed copy, run the installer from the installed package root:\n\n```bash\ncd \"$(npm root -g)/@aldegad/safedeps\"\nnode scripts/install/install-safedeps-hooks.mjs\n```\n\nThe installer is idempotent and only adds symlinks/hook entries. The `--link-bin` flag is **only useful when you installed via GitHub clone instead of npm** — npm already places the CLI on PATH, so the flag is redundant in this path.\n\nIf you want the skill folder itself to be the canonical local source, prefer the GitHub setup above.\n\n### Daily Re-check With macOS Alerts\n\nInstall a per-user LaunchAgent to re-check the approved-spec ledger once per day:\n\n```bash\nnode scripts/install/install-safedeps-recheck-agent.mjs install --hour 9 --minute 0\n```\n\nThis runs `safedeps re-check --json` against `~/.safedeps/approved-specs/`. It does not use LLM tokens; it only calls the advisory providers used by safedeps. If a new CVE/KEV is found, a spec is revoked, a provider check is skipped, or a ledger entry has no matching `advisory.log` approval record (a suspected forgery), the wrapper writes `~/.safedeps/recheck-alerts.jsonl` and raises a macOS notification.\n\nUseful commands:\n\n```bash\nnode scripts/install/install-safedeps-recheck-agent.mjs status\nnode scripts/install/install-safedeps-recheck-agent.mjs uninstall\ntail -f ~/.safedeps/recheck.log\n```\n\n## Real-World Attack Coverage\n\n`safedeps` is designed to catch the patterns behind real supply-chain incidents:\n\n- **`event-stream` (2018)** -- Malicious `postinstall` script with obfuscated code that exfiltrated cryptocurrency wallet keys. Caught by: install script analysis (obfuscation + network access detection).\n- **`ua-parser-js` hijack (2021)** -- Compromised package added a `preinstall` script that downloaded and executed cryptominers. Caught by: install script analysis (network access + code execution).\n- **`colors` / `faker` sabotage (2022)** -- While these were author-initiated, the abnormal dependency behavior would trigger the dependency explosion check.\n- **Typosquatting campaigns** -- Ongoing campaigns publishing packages like `crossenv` (instead of `cross-env`) or `babelcli` (instead of `babel-cli`). Caught by: pre-flight typosquatting pattern matching.\n- **Dependency confusion attacks** -- Internal package names published to the public registry with higher version numbers. Caught by: non-standard registry detection + large dependency count changes.\n\n## Logs and Snapshots\n\n| Path | Description |\n|---|---|\n| `~/.safedeps/reorg.log` | Full reorg event history with timestamps, reasons, and rolled-back files |\n| `~/.safedeps/confirmed` | Current confirmed (safe) snapshot ID |\n| `~/.safedeps/snapshots/` | All snapshot files (lock files, package.json copies, metadata) |\n\n```bash\n# View reorg history\ncat ~/.safedeps/reorg.log\n\n# Check current confirmed snapshot\ncat ~/.safedeps/confirmed\n\n# List all snapshots\nls -la ~/.safedeps/snapshots/\n```\n\nOld unconfirmed snapshots are automatically pruned (keeping the 10 most recent), while the confirmed snapshot chain is always preserved.\n\n## Security Hardening\n\n`safedeps` includes multiple layers of defense against attacks targeting the guard itself:\n\n| Measure | What it prevents |\n|---|---|\n| **JSON-safe metadata** | `project_dir` is escaped via `jq -Rs` to prevent JSON injection in snapshot metadata |\n| **Path canonicalization** | `realpath`/`readlink -f` resolves symlinks and `..` traversal in `cwd` before use |\n| **Atomic state files** | Snapshot ID and project directory are written as a single JSON file, preventing TOCTOU races |\n| **Stale lock recovery** | Locks older than 60 seconds are automatically removed, preventing permanent DoS from `SIGKILL`/OOM |\n| **Project-scoped state** | Each project gets its own confirmed snapshot chain (`confirmed_${dir_hash}`), preventing cross-project interference |\n| **Restrictive permissions** | `umask 077` ensures `~/.safedeps/` is readable only by the owner |\n| **Indirection detection** | Commands using `eval`, `$()`, or backticks with package manager keywords are treated as install candidates |\n\n## Project Structure\n\n```\nsafedeps/\n  bin/\n    safedeps      # CLI -- advisory gate, ledger, revoke, re-check\n  lib/\n    providers/    # OSV / CISA KEV / GHSA adapters\n    ledger/       # approved-spec ledger\n    npm/          # lockfile closure resolver\n    gates/        # repo-tree lane: scan / audit / hooks / doctor + templates/\n  scripts/\n    safedeps-pre-guard.sh       # PreToolUse hook -- advisory ledger UX + snapshots\n    safedeps-post-verify.sh     # PostToolUse hook -- npm primary effect verification + reorg\n    install/install-safedeps-hooks.mjs\n    install/install-safedeps-recheck-agent.mjs\n    install/migrate-safedeps-state.mjs\n    safedeps-recheck-alert.sh\n    test/\n  package.json\n  SKILL.md        # Claude Code / Codex skill manifest\n  LICENSE         # Apache-2.0\n```\n\n## What's Different\n\n`safedeps` intercepts package installs at **the moment an AI coding agent writes the install command** — not at CI scan time, PR review time, or runtime sandbox time. That timing is the core differentiator.\n\nTypical flow:\n\n1. The agent writes `npm install foo@1.2.3` (or any of the other supported install verbs).\n2. The PreToolUse hook does a fast advisory ledger check. If the direct spec is missing, expired, or obviously risky, it **blocks** the install and returns the exact `safedeps check npm foo@1.2.3` command the agent should run next, in the block reason.\n3. The agent runs `safedeps check`. The CLI queries OSV / CISA KEV / GitHub Advisory and, if safe, **adds the spec to the ledger**. KEV matches are hard-block (no override). CVEs with an available patch are auto-narrowed to the fixed version.\n4. The agent retries the install. The ledger entry now matches, so the install **proceeds**.\n5. After the install, the PostToolUse hook is the npm primary authority: it verifies the actual lockfile closure against direct ledger entries, `transitive_specs`, and OSV batch, then checks install scripts and native binaries and **auto-reorgs** to the last confirmed snapshot if anything diverged.\n\nEvery install command gets fast advisory feedback before it runs; every npm install gets closure-level enforcement after it runs. The suspicious package a human would catch at PR review is already caught at install time — and there is no SaaS dependency, only the local CLI plus public databases (OSV / KEV / GHSA).\n\nTwo honest boundaries:\n\n- **The command hook is a heuristic, not a sandbox.** Unusual wrappers, shell interpreters, or same-user tampering with local `~/.safedeps` state sit outside its trust boundary. The npm effect gate is the backstop — it catches what the command hook misses, because it inspects the installed result rather than the command text. It is **command-independent**: when an install-looking command leaves no pending state (the PreToolUse parser did not recognize it), the PostToolUse hook still runs the npm closure check against the live `package-lock.json`, so a parser blind spot does not also blind the backstop. Detection is always command-independent; *automatic rollback* of such a parser-missed install needs a prior confirmed-safe snapshot for that project — the first-ever install with no baseline is flagged loudly (systemMessage + advisory log) but not auto-reverted.\n- **Effect-primary enforcement is npm-only today.** `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` stay on the v2.1 command-gate + reorg model until their closure resolvers land.\n\n## Legacy / Migration: v1 `npm-reorg-guard`\n\nThe v1 product was named `npm-reorg-guard` and used `~/.npm-reorg-guard/` as the state directory. v2 moves state to `~/.safedeps/`. A one-shot migration is provided:\n\n```bash\nsafedeps migrate\n```\n\n- If `~/.npm-reorg-guard/` exists, it copies the snapshot chain, confirmed pointers, and logs into `~/.safedeps/` and archives the legacy directory so there is no second active state root.\n- If it does not exist, the command is a no-op (fresh v2 users do not need it).\n\n## License\n\n[Apache License 2.0](LICENSE)\n","readmeFilename":"README.md"}