{"_id":"@elberacasa/umbra","_rev":"15-16555649d501c5cb11fafb9d29c594a4","name":"@elberacasa/umbra","dist-tags":{"latest":"1.8.1"},"versions":{"0.2.0":{"name":"@elberacasa/umbra","version":"0.2.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@0.2.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js"},"dist":{"shasum":"c5527e84495bbdabec4ffaaa98be1642155ab081","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-0.2.0.tgz","fileCount":40,"integrity":"sha512-/fNX1YAxzSA/+khM4PTGOrZ4gNIk6h4O5K+1rzEqp950H7BJtRd4PS5SwQkcy9Xb/UbDBp2HswDAjZa3HtjJUg==","signatures":[{"sig":"MEUCIQCjMeH0g2kioTpsESUVeftNhMwLBs6Zr1EqV7LHyojWcwIgLlNqyPxobAzcrgRzy4OhNWfRqlo+932QkZ0r3JqQPTI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54704},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"6cb0f82353b76bf8209bf0eaf0215a26f4ff8f4d","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"commander":"^12.1.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_0.2.0_1785794054260_0.4546685448042236","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@elberacasa/umbra","version":"0.2.1","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@0.2.1","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js"},"dist":{"shasum":"817fb1807cd9a69b1c21d814e75d10415501d7cd","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-0.2.1.tgz","fileCount":40,"integrity":"sha512-/3Av04SEl87JgOz4o4er3Rz07sw69jdvGkZtid9KNURcdUKPFKlsmn5dsUZSGxMMxc3Z2sCqMrTR11aUv636hg==","signatures":[{"sig":"MEUCIH9WeqiOXNoAdm0b8gs8zd66hobq7nluB/bLmTxYTu4GAiEA3v7/wfLhifbL8ST5YtLxmSCS2qMojsphpwWZ+BrvUNE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54762},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"6cb0f82353b76bf8209bf0eaf0215a26f4ff8f4d","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"commander":"^12.1.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_0.2.1_1785794179336_0.6566684185490561","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@elberacasa/umbra","version":"0.2.2","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@0.2.2","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js"},"dist":{"shasum":"e02dc0a562ed9dfa83116d9d71f4b6666d4d48fc","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-0.2.2.tgz","fileCount":40,"integrity":"sha512-LwOLVHO9/Tz1CJl+yf36iExSDb8DNlo1/AlqleSzKktespVxtp/jLNpp3Ef0bPzioWs3iowTvmEzTTj3Zattuw==","signatures":[{"sig":"MEUCIQCyXGV/z1sR57b2eUZXZA1eQ98fDhT4yp8vvXhbDMpAQgIgG+iCT+/AzFQsa+lzgUVGxCklRoLoCqzJrvdFFt+u4Zg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54817},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"6cb0f82353b76bf8209bf0eaf0215a26f4ff8f4d","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"commander":"^12.1.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_0.2.2_1785794262911_0.49132439683872375","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@elberacasa/umbra","version":"0.3.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@0.3.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js"},"dist":{"shasum":"88729c8e7d8d374c282f04f3d2c1f6f1519b4e7a","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-0.3.0.tgz","fileCount":76,"integrity":"sha512-Lh4igSegzAkd+0PnKt5x90Q9Q5GW9VUyn0vTwoETbZotjFhlBx3UvXRq0kboOyEZYvjwjhXMim+Sa2HRqqBY3Q==","signatures":[{"sig":"MEUCIB9+xHEBjDxgbEdCsFC/vkN2bwItncvZ3EMphwFgbSrMAiEArSCUHmmVFfMfCrtJtlpa1fP8TeUI9TS0/s9Z8KyfFvw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":145404},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"2e7f322fc03a7a7fdf93a8d8022739f9d127a997","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"commander":"^12.1.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_0.3.0_1785796854476_0.14938681702165257","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@elberacasa/umbra","version":"0.3.1","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@0.3.1","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js"},"dist":{"shasum":"6876d6f594d3832eacc8ff33d4377c5b3f0b6960","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-0.3.1.tgz","fileCount":76,"integrity":"sha512-oO67jzTCFMnDOeONkI2E1TycoMdN4JiYgF3xM0bZ6R07KXVlB129nEDaaW3HZZqlx+0mr0FxdfgvSV0MAK74jQ==","signatures":[{"sig":"MEYCIQDT/5xHMDKk1S99axmaKBB+0UjLxB9msrN3R9XFKHA9dAIhAM1j4dDJAmDUuwoUSRRF8RrPM8hfrLzLeCIuVoNMrtvt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151482},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"80ccb534bafae709c28637dba7f87786117e45e3","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"commander":"^12.1.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_0.3.1_1785798912095_0.8973093148511198","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@elberacasa/umbra","version":"1.0.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.0.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"4203941d7e6e85254715361e7380de56d9e16ab4","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.0.0.tgz","fileCount":90,"integrity":"sha512-6+8ngofs8qY6YEc7fWKhsGvJ5/0MoCw3id7Nh8wh0ogx08uF07xO4bd56Oecq76aOaqaXY1fipXNGTZbb6bHWA==","signatures":[{"sig":"MEUCIQCADjvVAR89Uqs7AKPFWD87mlGhuq+4kG8GxKnKoOy6jwIgZBQZYZQOx2xQ1GGLY0/ym3CXs34U19FkMc2zQE/FW3M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":198985},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"cb56992c911b166e1efa09c3890620e425172334","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.0.0_1785801099284_0.412122884929933","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@elberacasa/umbra","version":"1.1.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.1.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"6849138aa7bda79abeb03179fc9dca22b5961753","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.1.0.tgz","fileCount":90,"integrity":"sha512-DCfDy/CYdKMkgApImldiVHDWwNGzQco+AvW4RCsdyRD3gwN63n4rZV8Zm0Rgf1N2Y7cLw+Hp7wVhM1N9HjrQZg==","signatures":[{"sig":"MEUCICYsEzo7h4M44/37Fw3W0kvELL/PEdhuDP2YO8fAuhT+AiEA67ysyAlJR3gRJ9dXkzbOAVSiFSvuiRfDRljPvy7K/0M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208955},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"f55d601389686be0439cfc2f52aac9936716c55c","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.1.0_1785849642839_0.49183242500472457","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@elberacasa/umbra","version":"1.2.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.2.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"670dd912889fbe47c476de346fd71ebe59e3f609","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.2.0.tgz","fileCount":90,"integrity":"sha512-h6bVo+1AiCrSC5k+prS0nRpaAJwgB4FrhUaFNE+2+zCMGOagPlfKNZkoiiv12Uj5Afc8Etg5fLQMDSvzGOuMxQ==","signatures":[{"sig":"MEYCIQCLU+X8Ifr7UAW8WemPUiLea0Gde5dUUEJrskBtuPYY8gIhAOVLLek4loHRA0IEZTrAIWcxnW++Y3uwrqHr3eTGhFPm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":209659},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"23e45867bbd89748c3e069b8da5e49c999d90a67","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.2.0_1785851714982_0.5602298209488785","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@elberacasa/umbra","version":"1.3.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.3.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"4a8576cf5887da9ae6117ca633539e6eee670865","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.3.0.tgz","fileCount":92,"integrity":"sha512-8iE2+5se2Y3MDYyRf9DYHDOej3hMo+ASBcmiphYP1AFtGJbVGsQ9853Kdz13k2Wjcp8mw4QD8uGxDl0aHAKidg==","signatures":[{"sig":"MEQCIH87vhc1reUIzNRBa+lWeJ8MFXJh59e2c2x2RzjBcCXgAiAb+x5fdd9sTEi2xY/5v8R16g5NowhaWLXVC50e50T9KA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":223748},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"87e05ced51bece212a7b10c840b93cde2fe1f918","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.3.0_1785861397488_0.6750499915684649","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@elberacasa/umbra","version":"1.4.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.4.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"e9a13ab18c40a6c4c603c7b0b7c33db6fe962fc7","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.4.0.tgz","fileCount":96,"integrity":"sha512-VwkPyiSOlEyN0kwBz3IJL7KSTxn//THAKn0BmAk4SEU+sVC53mXGgf6JFTD8WfVJCw8dTPPYwycEb245lSTGkw==","signatures":[{"sig":"MEYCIQCpkOaCWoKUgDfrWa0k/HKtwRwhFKB+6rdEc9V1bpha4wIhAJU/gGyEubWRKie/hrqQVNATduyrLbVsES6eK/UcVdvr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":231131},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"2a8caaeee1e86719022d4e749dcd0ebd39b492ff","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.4.0_1785871083856_0.14081429057381012","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@elberacasa/umbra","version":"1.5.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.5.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"7b0554281dbd75e33d88249cd53b20f151a20dc8","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.5.0.tgz","fileCount":104,"integrity":"sha512-RjzG5ClQsAOJoXdTBs1V5EFBRYVvoy8ATQ5mXj1nicoaGsGGWdscjbwg58ucjnhcxTaUvewH/kfhNIjnq6W18w==","signatures":[{"sig":"MEYCIQDiULAAt22VZt3GYYfH1SINvOmglEM9Wtn/r0xdpI9cmwIhAN85PHl73ytvBwW+BmYXwqwZDXa5637sgdIQshMO9nqk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":248702},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"e08eea3205a4fa5fa2976cd8a87cde5b19e06e3b","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.5.0_1785873144218_0.0900518532624448","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@elberacasa/umbra","version":"1.6.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.6.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"36accf313e8951ad7270592215be6ad9c314b60c","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.6.0.tgz","fileCount":110,"integrity":"sha512-i6BkUP3qzTX6265y+komDrayQ64or7U+WzI916M+1Eb4kv8dPWz74Uvkrt8jXZdz9hJ2JXPDlmyqiqPuqrflPA==","signatures":[{"sig":"MEQCIG5ezz848cWkVgkISEzwjZC3TG0wEf7QLHAjnRcxlEzwAiA6HsvmQWRfDNw/2oHBrjczUkapaEYpMiQqRuctVAuilA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":279365},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"43c827e13524af177baddffefc84a2392ebfc93d","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.6.0_1785876767247_0.32147990902757395","host":"s3://npm-registry-packages-npm-production"}},"1.7.0":{"name":"@elberacasa/umbra","version":"1.7.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.7.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"a0d3c5809909a2bc129bb8eee06df4d46286a587","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.7.0.tgz","fileCount":112,"integrity":"sha512-HbbgOJgI6+eBn61v55rmXJjwjPMPq+mENaJ8Ya+sy2ccVDp/v8YScM9vZhE2MIVBFDhdQgP9j7NCz4KUR3ZfyA==","signatures":[{"sig":"MEUCIFw5u4KqXWxbDvfU4NgPZRMsy9WTXtPdVPaew37sm38PAiEAlX+wMsuJbGXhGN1+WsMp4AhwWfEauWXEGQ1fuIiHNn4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":291753},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"0b428a8f0a5e1db6ab5a8ffa5f68bdd6f3d863d1","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.7.0_1785891632781_0.4539030616321609","host":"s3://npm-registry-packages-npm-production"}},"1.8.0":{"name":"@elberacasa/umbra","version":"1.8.0","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"url":"https://github.com/elberacasa","name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com"},"license":"MIT","_id":"@elberacasa/umbra@1.8.0","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"homepage":"https://github.com/elberacasa/umbra#readme","bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"dist":{"shasum":"d804ab9f1d40de483e98cf4a46a545a015038e37","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.8.0.tgz","fileCount":114,"integrity":"sha512-AMrkaTVe4WCapf9S0z23wmJhvqMz0LGj3AmOIqNEU/prJbQ/QBV43VfaBbfiLZx31NoxxXeUqwKHDvC/VCxpXg==","signatures":[{"sig":"MEUCIE/70EKBBoM0LX+GiU7GrR2lR/qiOBKwsbeNYq+1X2IMAiEAxQxUHQwXPx7SFxKBlJ9y62K3MDoUGM36mwgA71Bi954=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298624},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"170a974a7eb6178703f9fa8b5595af483a7f0441","mcpName":"io.github.elberacasa/umbra","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"repository":{"url":"git+https://github.com/elberacasa/umbra.git","type":"git"},"_npmVersion":"11.8.0","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","directories":{},"_nodeVersion":"25.6.0","dependencies":{"zod":"^4.4.3","commander":"^12.1.0","picocolors":"^1.1.1","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.9","typescript":"^5.5.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/umbra_1.8.0_1785898216210_0.05499469678698232","host":"s3://npm-registry-packages-npm-production"}},"1.8.1":{"name":"@elberacasa/umbra","version":"1.8.1","description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","mcpName":"io.github.elberacasa/umbra","type":"module","bin":{"umbra":"dist/cli.js","umbra-mcp":"dist/mcp/server.js"},"main":"dist/index.js","engines":{"node":">=20"},"scripts":{"build":"tsc -p tsconfig.json","dev":"tsc -p tsconfig.json --watch","test":"vitest run","prepublishOnly":"npm run build && npm test"},"keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"author":{"name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com","url":"https://github.com/elberacasa"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/elberacasa/umbra.git"},"bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"homepage":"https://github.com/elberacasa/umbra#readme","publishConfig":{"access":"public"},"dependencies":{"@modelcontextprotocol/sdk":"^1.30.0","commander":"^12.1.0","picocolors":"^1.1.1","zod":"^4.4.3"},"devDependencies":{"@types/node":"^20.14.0","typescript":"^5.5.0","vitest":"^2.1.9"},"gitHead":"2ee5d306a22d50eb2eefe9114dda7fc344bfa607","types":"./dist/index.d.ts","_id":"@elberacasa/umbra@1.8.1","_nodeVersion":"25.6.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-AmDPaiaVZscKTBgfpw7v07DluJ5iR6kUBUZEKxnK7wVPMHfJsSKsveOLRV1Wf1fDChQxqq7DvmQNJQdwHS8BzA==","shasum":"1aaf5ae7d8daa26e25db62383301d89d51a2cf14","tarball":"https://registry.npmjs.org/@elberacasa/umbra/-/umbra-1.8.1.tgz","fileCount":114,"unpackedSize":298862,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDZcjk+Zabb0/+G+pbsNBbPfF/v7gQWslKB/TvEQttO+gIhAK7VYk5wOp0PFBRov6as0I/oGxHPkRzKJocvFGXdNbeb"}]},"_npmUser":{"name":"elberacasa","email":"alejoberacasa@gmail.com"},"directories":{},"maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/umbra_1.8.1_1785899142813_0.2317811015893012"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-03T21:54:14.087Z","modified":"2026-08-05T03:05:43.116Z","0.2.0":"2026-08-03T21:54:14.417Z","0.2.1":"2026-08-03T21:56:19.543Z","0.2.2":"2026-08-03T21:57:43.055Z","0.3.0":"2026-08-03T22:40:54.606Z","0.3.1":"2026-08-03T23:15:12.248Z","1.0.0":"2026-08-03T23:51:39.438Z","1.1.0":"2026-08-04T13:20:42.982Z","1.2.0":"2026-08-04T13:55:15.120Z","1.3.0":"2026-08-04T16:36:37.626Z","1.4.0":"2026-08-04T19:18:04.017Z","1.5.0":"2026-08-04T19:52:24.365Z","1.6.0":"2026-08-04T20:52:47.390Z","1.7.0":"2026-08-05T01:00:32.933Z","1.8.0":"2026-08-05T02:50:16.359Z","1.8.1":"2026-08-05T03:05:42.948Z"},"bugs":{"url":"https://github.com/elberacasa/umbra/issues"},"author":{"name":"Alejandro Beracasa","email":"elberacasa@users.noreply.github.com","url":"https://github.com/elberacasa"},"license":"MIT","homepage":"https://github.com/elberacasa/umbra#readme","keywords":["security","scanner","vibe-coding","ai","trust","sast","static-analysis","cli","code-quality","llm"],"repository":{"type":"git","url":"git+https://github.com/elberacasa/umbra.git"},"description":"Trust Score for AI-built software. npx @elberacasa/umbra <path> → one score, one badge.","maintainers":[{"name":"elberacasa","email":"alejoberacasa@gmail.com"}],"readme":"<div align=\"center\">\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"assets/logo.svg\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"assets/logo-light.svg\">\n  <img alt=\"Umbra: the trust score for AI-generated code\" src=\"assets/logo-light.svg\" width=\"340\">\n</picture>\n\n**Everyone is vibecoding. Nobody is verifying. Umbra scores it.**\n\nUmbra is a deterministic Trust Score (0–100) for AI-generated code: the vibe\ncoding security scanner that verifies what your agent shipped, not what it\nclaimed. One command, fully local, evidence for every finding.\n\n[![npm version](https://img.shields.io/npm/v/@elberacasa/umbra)](https://www.npmjs.com/package/@elberacasa/umbra)\n[![npm downloads](https://img.shields.io/npm/dm/@elberacasa/umbra)](https://www.npmjs.com/package/@elberacasa/umbra)\n[![GitHub stars](https://img.shields.io/github/stars/elberacasa/umbra)](https://github.com/elberacasa/umbra/stargazers)\n[![Glama MCP score](https://glama.ai/mcp/servers/elberacasa/umbra/badges/score.svg)](https://glama.ai/mcp/servers/elberacasa/umbra)\n[![MCP registry: listed](https://img.shields.io/badge/MCP_registry-listed-00f0ff)](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.elberacasa/umbra)\n[![license: MIT](https://img.shields.io/npm/l/@elberacasa/umbra)](./LICENSE)\n[![CI](https://github.com/elberacasa/umbra/actions/workflows/ci.yml/badge.svg)](https://github.com/elberacasa/umbra/actions/workflows/ci.yml)\n[![rubric v4](https://img.shields.io/badge/rubric-v4-b829f7)](./RUBRIC.md)\n[![node >=20](https://img.shields.io/node/v/@elberacasa/umbra)](https://www.npmjs.com/package/@elberacasa/umbra)\n\n[Quickstart](#quickstart) · [Demo](#demo) · [The Audit](#the-audit-61-vibe-coded-repos-scanned) · [How it works](#how-it-works) · [The Four Axes](#the-four-axes) · [FAQ](#faq) · [Roadmap](#roadmap) · [Contributing](#contributing)\n\n</div>\n\n<a id=\"demo\"></a>\n\n![Umbra scanning a vibe-coded app: Trust Score 30/100](demo/demo.gif)\n\n<!--\n  DEMO GIF: recorded from demo/demo.tape via charmbracelet/vhs.\n  Specs:\n    - Terminal recording, 1200x600, dark theme\n    - < 25 seconds total runtime\n    - Beats per docs/demo-script.md: fresh shell → cd into vibe-coded app →\n      `npx @elberacasa/umbra .` → verdict streams in → hold 3s on the final score\n    - Render: `cd demo && vhs demo.tape`\n  Re-record whenever the verdict format changes; stale demo output is a\n  credibility bug (see docs/demo-script.md).\n-->\n\n## Why Umbra exists\n\nStudies put exploitable vulnerabilities in 40 to 60 percent of AI-generated\ncode, and coding agents routinely claim \"all tests pass\" when three do. The\ntooling for *writing* code with AI is a year ahead of the tooling for\n*trusting* it. Umbra closes that gap: SAST rebuilt for how software gets\nwritten now, plus sandboxed verification that catches what static rules\ncannot.\n\nOne command scans any repo an agent produced (Claude Code, Cursor, Copilot,\nWindsurf, Lovable) and returns a score with file:line evidence for every\nfinding. With `--deep` it goes further: Umbra builds and boots the repo in a\nlocked-down Docker sandbox, then replays the agent's own claims against\nreality. If the agent is lying about tests, the score is capped below\npassing, with receipts.\n\n## The audit: 61 vibe-coded repos, scanned\n\nWe ran Umbra over 61 public, actively-maintained AI-built repos and\npublished everything. [The Vibe-Coding Security Audit](./docs/vibe-coding-audit-2026-08.md):\n\n| Finding | Repos hit |\n|---|---:|\n| Hardcoded-secret findings (committed `.env`, service keys in source) | **25%** |\n| API routes with no auth check | **26%** |\n| Injection sinks (SQL interpolation, unsafe HTML injection) | **49%** |\n| Entire databases / SQL dumps committed to git | **13%** |\n| At least one critical finding | **10%** |\n| Zero scored findings (genuinely clean) | 7 of 61 |\n\nMean trust score: **74/100**. One in five repos fails outright. The full\nreport has per-class deep dives with representative snippets and fixes, the\ncomplete per-repo table, and an honest methodology section — including the\nfalse positives we found in our own rules while running it, and fixed\n(rubric v4).\n\n## Quickstart\n\n```bash\nnpx umbra-scan            # check — scans the directory you're standing in\nnpx umbra-scan --fix      # heal — applies provably-safe fixes, shows the score climbing\nnpx umbra-scan --setup    # protect — pre-commit gate, PR checks, agent guardrails\n```\n\nThat's the whole interface. Three verbs: check, heal, protect.\n\n**Using an AI coding agent?** Umbra is built to be driven by agents, not\njust run by humans:\n\n- **Any agent** — it reads this repo's [AGENTS.md](./AGENTS.md) / [llms.txt](./llms.txt) and knows what to do. Or tell yours: \"check this repo with umbra.\"\n- **Claude Code / Kimi Code** — `--setup` installs PreToolUse hooks so every file the agent writes is guarded before it lands.\n- **Claude Code, Cursor, Copilot, Windsurf** — the [trust-review skill](./skills/README.md) makes the agent scan its own work before declaring done.\n- **MCP-native agents** — add `umbra-mcp` (`npx --yes -p @elberacasa/umbra umbra-mcp`) and the agent gets `scan_repo`, `guard_content`, and `get_score` as tools.\n\nReal output, scanning a typical vibe-coded Next.js app\n([fixtures/bad-app](./fixtures/bad-app) in this repo, Trust Score **30/100**):\n\n```\n$ npx umbra-scan ./fixtures/bad-app\n\nUMBRA TRUST SCORE: 30/100  🔴\n\nSAFE   🔴 5/100 — 14 findings\nCLEAN  ✅ 87/100 — 10 findings\nRUNS   — not measured — run with --deep\nHONEST — not measured — run with --deep\n\nScore computed over measured axes only (full rubric: SAFE 35%, RUNS 25%, HONEST 25%, CLEAN 15%). Rubric v4.\n…plus 7 further findings beyond the per-rule cap (see report)\n\nTop findings:\n  [safe/hardcoded-secrets] Hardcoded Supabase service_role JWT — bypasses all row level security — .env:2\n  [safe/hardcoded-secrets] Hardcoded Supabase service_role JWT — bypasses all row level security — lib/supabase.ts:5\n  [safe/supabase-antipatterns] Supabase service_role key reachable from client-side code — full database bypass for anyone who opens the bundle — .env:2\n  [safe/supabase-antipatterns] Supabase service_role key reachable from client-side code — full database bypass for anyone who opens the bundle — app/components/UserList.tsx:10\n  [safe/hardcoded-secrets] Committed environment file with secret values: .env — .env:1\n\nNotes (low confidence — not scored):\n  [safe/missing-rate-limit] Auth endpoint with no rate-limiting signal in the repo — brute-force / credential-stuffing exposure (heuristic) — app/api/login/route.ts:3\n\nBadge: [![Umbra Trust Score](https://img.shields.io/badge/Umbra_Trust_Score-30-red)](https://github.com/elberacasa/umbra)\n```\n\nThe exit code is **1** when the score is below 50, so CI can gate on it.\n\n<details>\n<summary><strong>All commands and flags</strong> (the expert layer — most users never need these)</summary>\n\n```bash\numbra [path]               # path defaults to the current directory\numbra [path] --json        # machine-readable output\numbra [path] --offline     # skip npm registry checks, fully local\numbra [path] --deep        # verify RUNS and HONEST in a Docker sandbox\numbra [path] --report      # write UMBRA.md: an agent-actionable task list\numbra [path] --fix         # apply provably-safe fixes and re-scan (score before → after)\numbra [path] --dry-run     # preview --fix without writing anything\numbra [path] --baseline-write  # write .umbra-baseline.json: grandfather current findings, gate only on new ones\numbra [path] --baseline <path> # use an explicit baseline file (\"write\" is shorthand for --baseline-write)\numbra [path] --publish     # self-report the score to the hosted badge service (live README badge)\numbra setup                # install everything (hooks + Action + agent guards)\numbra init                 # only the pre-commit hook + GitHub Action\numbra protect              # only the agent PreToolUse hooks (--remove uninstalls)\numbra guard --stdin        # hook entrypoint (agents call this, not humans)\numbra mcp                  # run the MCP server (bin: umbra-mcp)\n```\n\nThe canonical package is `@elberacasa/umbra`; `umbra-scan` is the short\nalias. Same engine either way.\n\n</details>\n\n## How it works\n\n```\nrepo in\n   │\n   ▼  Layer 0 · static rules (17 SAFE + CLEAN rules, 0 tokens, <1s)\n   ▼  Layer 1 · evidence gating (confidence-scored, low never moves the score)\n   ▼  Layer 2 · --deep sandbox (Docker: build, boot, HTTP probe, claim replay)\n   │\n   ▼  deterministic Trust Score + verdict + badge\n```\n\nEvery finding carries a confidence level and file:line evidence. Only high\nand medium confidence findings move the score; hunches go to a notes section.\nThe rubric is versioned (currently v3), so the same repo always gets the same\nscore. Full math in [RUBRIC.md](./RUBRIC.md).\n\n## The immune layer: guard the write, not just the repo\n\nScanning finds problems after they land. The immune layer checks every file\nyour agent writes **before** it lands. `umbra protect` installs PreToolUse\nhooks into Claude Code and Kimi Code (auto-detected, one command); the same\nengine backs the `umbra-mcp` server for MCP-native agents.\n\n![Umbra blocking an agent's attempt to write a live key into .env](demo/guard.gif)\n\n```mermaid\nflowchart LR\n    CC[Claude Code hook] --> E\n    KC[Kimi Code hook] --> E\n    MCP[\"umbra-mcp: guard_content\"] --> E\n    E{\"guardContent(file, content)<br/>file rules + path guard\"} -->|allow / warn| W[write lands]\n    E -->|\"block (exit 2)\"| B[\"reason fed back:<br/>agent fixes the root cause\"]\n```\n\n```bash\nnpx umbra-scan protect   # install the hooks; --remove uninstalls cleanly\n```\n\nA leaked Stripe key or an `alg: none` JWT never reaches the file. The path\nguard hard-blocks agent writes into `.git/hooks` and `.git/config`\n([CVE-2026-26268](https://anomity.ai/blog/cursor-git-hooks-sandbox-escape-rce-cve-2026-26268/),\nthe agent-planted git hook escape), and live credentials going into `.env`.\nBlocking is reserved for high-confidence critical/high findings; everything\nelse warns, and every failure fails open. Verdicts land in ~0.2 ms, so the\nguard never slows the agent down. Full story:\n[docs/immune-layer.md](./docs/immune-layer.md).\n\n## `--deep`: verify AI code, don't trust it\n\nThe fast scan is static. `--deep` is LLM code verification with evidence.\nUmbra copies the repo into a throwaway Docker container (no network at\nruntime, 512 MB / 1 CPU hard limits, 120-second kill switch), builds it,\nboots it, HTTP-probes its endpoints, and replays every claim found in\nREADMEs and agent artifacts against what actually happens. Slower (minutes,\nnot seconds) and needs a running Docker daemon. Without Docker the sandboxed\naxes are skipped and left out of the score; unverifiable is never punished.\n\nReal output, deep-scanning a repo whose README lies\n([fixtures/claims-app](./fixtures/claims-app), capped at **49/100** by the\nliar cap):\n\n```\n$ npx @elberacasa/umbra ./fixtures/claims-app --deep\n\nUMBRA TRUST SCORE: 49/100  🔴\n\nSAFE   ✅ 100/100 — 0 findings\nCLEAN  ✅ 100/100 — 2 findings\nRUNS   — not measured — No detectable run path (no Dockerfile, no package.json start script or main entry)\nHONEST ⚠️ 50/100 — 2 claims failed, 2 verified, 1 unverifiable\n\nScore computed over measured axes only (full rubric: SAFE 35%, RUNS 25%, HONEST 25%, CLEAN 15%). Rubric v4.\nScore capped below passing: a documented claim was verified false. Trust is the product.\n\nClaim receipts:\n  CLAIM FAILED: \"14 tests pass\" — README.md:7 — actually 3 tests pass, 0 fail\n  CLAIM FAILED: \"build passes\" — README.md:9 — actually build exits 1\n  CLAIM VERIFIED: \"All tests pass\" — CLAUDE.md:3 — 3 tests pass\n  CLAIM VERIFIED: \"All tests are passing\" — README.md:8 — 3 tests pass\n```\n\nAny claim verified false caps the total at 49: a repo caught lying does not\nget a passing trust score. For contrast, a genuinely working app\n([fixtures/runnable-app](./fixtures/runnable-app)) scores **100/100** under\n`--deep`.\n\n## The Four Axes\n\n| Axis | Question | How it's measured |\n|------|----------|-------------------|\n| **SAFE** (35%) | Is it vulnerable? | 13 deterministic static rules, every scan, fully offline. |\n| **RUNS** (25%) | Does it actually build and boot? | Docker sandbox: install, build, start, HTTP probe. *(`--deep`)* |\n| **HONEST** (25%) | Is the agent lying about tests or the build? | Claims extracted from READMEs and agent files, replayed against sandbox reality, receipts emitted. *(`--deep`)* |\n| **CLEAN** (15%) | How much is slop? | Static rules: dead exports, unused deps, mega-files, duplication. |\n\nThe SAFE rules cover the failures AI-generated code security actually ships:\nhardcoded secrets (Stripe keys, JWTs, connection strings), Supabase\nservice-role keys exposed client-side and missing **Supabase RLS**, missing\nauth on API routes, injection sinks, rate-limit hints, hallucinated and\ntyposquatted dependencies, CORS wildcard with credentials, JWT misconfig\n(`alg: none`, no expiry, decode-as-authorization), debug flags and\nstack-trace leaks, committed sensitive files (`.pem`, `id_rsa`, SQL dumps),\nand default credentials.\n\nIt also lints the agent's own setup — the surface nobody else covers:\nprompt-injection payloads in instruction files (`CLAUDE.md`, `.cursor/rules`,\nskills: zero-width Unicode, override phrases in HTML comments) and dangerous\nMCP configs (literal API keys in `.mcp.json`, unpinned `npx -y` servers,\n`curl | sh` installers). These run in the guard too, so an agent editing its\nown config gets checked mid-write.\n\n## Umbra vs. existing tools\n\n| | Umbra | Traditional SAST (Semgrep, Snyk Code) | Secret scanners (trufflehog, Gitleaks) | Agent review bots |\n|---|---|---|---|---|\n| Built for AI-generated code | ✅ | generic rulesets | secrets only | ✅ |\n| Verifies the app builds, boots, and answers HTTP | ✅ (sandbox) | — | — | — |\n| Replays agent claims, caps liars below passing | ✅ | — | — | — |\n| Deterministic score, versioned rubric | ✅ | findings list | findings list | prose review |\n| Agent-native surfaces (skill, Action, MCP) | ✅ | — | — | partial |\n\nExisting tools answer \"is this code pattern dangerous?\" Umbra answers the\nquestion vibe coding actually raises: \"the AI wrote this, can I trust it?\"\n\n## The badge\n\nEvery scan prints badge markdown. Paste it in your README and your repo\nadvertises its own trust score:\n\n```markdown\n[![Umbra Trust Score](https://img.shields.io/badge/Umbra_Trust_Score-30-red)](https://github.com/elberacasa/umbra)\n```\n\n[![Umbra Trust Score](https://img.shields.io/badge/Umbra_Trust_Score-30-red)](https://github.com/elberacasa/umbra)\n\n**Live badges** are one flag away: run with `--publish` (or the Action's\n`publish: true`) and your score reports to the hosted badge service, so your\nREADME always shows the current number with a full report page behind the\nclick — self-reported by your CI, labeled as such:\n\n```markdown\n[![Umbra Trust Score](https://umbra-badge.umbrabadge.workers.dev/badge/OWNER/REPO.svg)](https://umbra-badge.umbrabadge.workers.dev/OWNER/REPO)\n```\n\n## One engine, every surface\n\n- **CLI** (`npx @elberacasa/umbra`): the core, available today. Short alias:\n  `npx umbra-scan`.\n- **Agent skill**: a [trust-review skill](./skills/README.md) installable\n  into Claude Code, Cursor, Copilot, and Windsurf, so the agent checks its\n  own work before you do. Claude Code / Cursor / Copilot security, from\n  inside the agent.\n- **GitHub Action**: [`uses: elberacasa/umbra@v1`](./action.yml) comments the\n  Trust Score on every PR. Trust gating in CI, zero local setup.\n- **`umbra setup`**: the one-word installer — pre-commit gate, PR score\n  comments, and PreToolUse guard hooks for detected agents, all idempotent\n  and clobber-free. (`init` and `protect` remain for piecemeal installs.)\n- **`umbra protect`**: installs PreToolUse hooks into Claude Code and Kimi\n  Code (auto-detected, idempotent, `--remove` to uninstall) so Umbra reviews\n  every agent write mid-stream and blocks dangerous ones before they land.\n- **MCP server** (`umbra-mcp`): agents call Umbra mid-stream and catch their\n  own mistakes before the code lands. Add it with\n  `npx --yes -p @elberacasa/umbra umbra-mcp`.\n\nDay-to-day recipes (CI gating, JSON parsing, hooks): [docs/daily-use.md](./docs/daily-use.md).\n\n## Roadmap\n\n- **v0.1** *(shipped)*: CLI, SAFE + CLEAN static axes, deterministic score, verdict output, badge markdown.\n- **v0.2** *(shipped)*: the surfaces. Agent skill, GitHub Action, `umbra init`.\n- **v0.3** *(shipped, current)*: RUNS axis (sandbox build, boot, HTTP probe) and HONEST axis (claim receipts plus the liar cap).\n- **v1.0** *(shipped)*: the immune layer. Umbra sits between the agent and your codebase, intercepting writes mid-stream and scoring them before they land. Full story in [docs/immune-layer.md](./docs/immune-layer.md).\n- **Beyond**: attack graphs across your dependency tree, a security twin of your app that gets probed so production doesn't, hosted report permalinks behind every badge.\n\nThe wedge is a score. The destination is the verification layer every\nAI-built repo runs through.\n\n## FAQ\n\n**How do I adopt Umbra in a repo that already has findings?**\nRun `npx umbra-scan --baseline-write` once. Umbra writes `.umbra-baseline.json`\ninto the repo root, and from then on the gate only blocks **new** issues —\nexisting findings are grandfathered (the verdict shows\n`baseline: N existing findings grandfathered (M new)`), so you fix forward\ninstead of boiling the ocean. Commit the baseline file so the whole team and\nCI share it.\n\n**How is Umbra different from Semgrep, Snyk, or trufflehog?**\nThey scan code patterns; Umbra verifies outcomes. Static rules are one input\nto the SAFE axis. Umbra additionally boots the app in a sandbox to prove it\nruns, and replays the agent's documented claims to prove it isn't lying.\n\"README says 14 tests pass, actually 3 do\" costs the repo a passing grade.\n\n**Does Umbra send my code anywhere?**\nNo. Scanning is fully local; `--offline` skips even the npm registry checks.\n`--deep` runs your repo in a local Docker container with no network at\nruntime. Nothing leaves your machine.\n\n**Does it need Docker?**\nOnly for `--deep` (RUNS and HONEST). The default fast scan is pure static\nanalysis. Without Docker the sandboxed axes are skipped and excluded from the\nscore, never punished.\n\n**What languages does it support?**\nJavaScript and TypeScript (including Next.js and Supabase apps) have the\ndeepest coverage today, which is where most vibe-coded repos live. The rule\nengine is extensible; new rules need a fixture and a test.\n\n**Is the score reproducible?**\nYes. Same repo, same rubric version, same score, every time. The rubric is\nversioned (v2) and printed in every report, and low-confidence findings never\naffect it. Skipped axes are excluded and renormalized over, never punished.\n\n**What does it catch that my AI agent won't mention?**\nThe classics of AI-generated code: a Supabase `service_role` JWT shipped to\nthe browser (bypasses all row level security), live Stripe keys in `.env`,\nAPI routes with no auth check, `alg: none` JWTs, CORS `*` with credentials,\nhallucinated dependencies that don't exist on npm, and whether its own claims\nabout tests and builds are true.\n\n**Can Umbra stop my agent mid-write?**\nYes, via hooks. Run `npx @elberacasa/umbra protect` and Umbra installs a\nPreToolUse hook into Claude Code and/or Kimi Code that reviews every\n`Write`/`Edit`/`MultiEdit` before it lands. Only high-confidence critical and\nhigh severity findings block (a wrong block gets tools uninstalled, so when\nin doubt Umbra warns), the `.git/hooks` path guard blocks git-hook planting\n(CVE-2026-26268) outright, and the guard fails open on its own errors so it\nnever breaks your flow. Hooks are a guardrail, not a sandbox; details in\n[docs/immune-layer.md](./docs/immune-layer.md).\n\n**Can my AI coding agent use Umbra directly?**\nYes, that is the design. The repo ships an [AGENTS.md](./AGENTS.md) and\n[llms.txt](./llms.txt) so assistants know exactly when and how to run it, and\nthe [agent skill](./skills/README.md) makes Claude Code, Cursor, Copilot, and\nWindsurf scan their own work before declaring a task done.\n\n## Contributing\n\nIssues and PRs welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md). The\nhighest-value contributions right now: new SAFE/CLEAN rules with fixtures and\ntests, false-positive reports (severity-one bugs here), renders against real\nAI-generated repos, and new harness adapters for `umbra protect`.\n\nBuild and test before submitting:\n\n```bash\nnpm install\nnpm run build\nnpm test\n```\n\n## Ethical use\n\nUmbra is a defensive tool. Scan repos you own, repos you are about to depend\non, or repos you have permission to audit. Findings point at weaknesses; they\nare not exploits, and publishing someone else's low score to shame them is\nnot the point. The point is that \"the AI wrote it\" stops being the end of the\nverification conversation.\n\n## License\n\n[MIT](./LICENSE)\n","readmeFilename":"README.md"}