{"_id":"@alimaandev/ripple","_rev":"8-017bfe4a78d00185b24ba85a364c2f1b","name":"@alimaandev/ripple","dist-tags":{"latest":"0.7.0"},"versions":{"0.1.0":{"name":"@alimaandev/ripple","version":"0.1.0","keywords":["cli","typescript","dependencies","impact-analysis","refactoring","risk"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.1.0","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"6b0ef83893b669872a229f872dda326a410b7414","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.1.0.tgz","fileCount":5,"integrity":"sha512-haHh0qz13/ZqnidrKZbI+ae40DghLDyl45Yr7exfuR1V2eb6lnbWS7WkVkHPiQL8aCvoKSLa0Q+MSlzi2lAWsg==","signatures":[{"sig":"MEUCIQClTPPE2yIQwazAPaqZSasNgBWXpmRhPi6vLL0N0pATzwIgZVsLi3Kstd4zDbrseP2rGzdoOABByjqOeE4F6XFK7/M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":259760},"type":"module","engines":{"node":">=22"},"gitHead":"b0507c7e8414bca07dd4c73abffe8fc5d1899f6b","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript projects. Answers the question: what will break if I change this file?","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","chalk":"^6.0.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.1.0_1786103996005_0.5575240775153032","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@alimaandev/ripple","version":"0.1.1","keywords":["cli","typescript","dependencies","impact-analysis","refactoring","risk"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.1.1","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"f967865690e1fb335601eee5dd34211cd51a46b9","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.1.1.tgz","fileCount":11,"integrity":"sha512-tcKFulXX9uQQzwQc6u/8VNgUD6DUSY9FZNwa18AAPim28nJiJqSvmkwdWLH844pO40WRM8+puu61N+VhwHdpGQ==","signatures":[{"sig":"MEUCIQD/Em2rULyyNqQj+gv1IlzSlSJHXGjm+ZFc7urccmlpTQIgd6U186zdPQJ7ON1h5eGATSzgYXYZwNXfWUYyFW5wMfU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":265287},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"25594bb2b5626b3a51434a133c7d64bc9922284d","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript projects. Answers the question: what will break if I change this file?","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","chalk":"^6.0.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.1.1_1786119171526_0.15383843150881393","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@alimaandev/ripple","version":"0.2.0","keywords":["cli","typescript","dependencies","impact-analysis","refactoring","risk"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.2.0","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"022c8f7a47fc419a692e6370b090d24538c93e65","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.2.0.tgz","fileCount":11,"integrity":"sha512-RKn8MTqDSEqOWJLpnMn0Id2W/i+aXfmIW0YqY2utLcKBbAOUiazP6ryfsF2hrQ4bKbOcOMH5SyJLcZjm+WtycQ==","signatures":[{"sig":"MEQCIHefN7UAUYXnzkchVwWSFSCa/Ka2Ky/56EzO1Sfasb9sAiBG5zqSIaImm3OlampBNmgGurkAwU4jv103cXplhezeHQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":284900},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"6c01396e0efd1f528e3105ce230b9720f1de28c5","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript projects. Answers the question: what will break if I change this file?","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","boxen":"^8.0.1","chalk":"^6.0.0","figures":"^6.1.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.2.0_1786121872282_0.5192491411706299","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alimaandev/ripple","version":"0.3.0","keywords":["cli","typescript","dependencies","impact-analysis","refactoring","risk"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.3.0","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"cf796e77754b35a8903b72e02626ca67384f13b3","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.3.0.tgz","fileCount":11,"integrity":"sha512-6T2CbU2j1NklN7WQhKW8OHrnKFC1fuRuDfHi/UsEPq5K98Rn5ZFxNvNUPEZOq40RRcUf/ZLvfeRjExxMDf4+Ig==","signatures":[{"sig":"MEQCIDr01RRiaY0BoWEPqYRtjLB0ej06L8SYWqF0eBz/pWsvAiAMw874HRcUjg9WbsyBS0R7kgN49h0mUgZsIAj0AYCPXg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":320819},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"a164448c6db9281265bf5a611d0a42f0516ac8fc","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript projects. Answers the question: what will break if I change this file?","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","boxen":"^8.0.1","chalk":"^6.0.0","figures":"^6.1.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.3.0_1786180580678_0.4509636031698234","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@alimaandev/ripple","version":"0.4.0","keywords":["cli","typescript","dependencies","impact-analysis","refactoring","risk"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.4.0","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"e20d984a3ca74227bc172ff69f04993be62c705f","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.4.0.tgz","fileCount":11,"integrity":"sha512-FjWdUEJUNvSQ9Fya9LKx5T7+wMr24kS/0roOCSXfXufGgKt/9h6YiSYoQjxj/+TkbzbKSliXNDk91qwLZaKXEw==","signatures":[{"sig":"MEYCIQCh3ZPM3i0SMMIQ8gGJx4ZFkLnwC5o8JTUxX2xAB3CWuwIhAIOe7OATX5ymBQxUjIyV+fse67H5pPJXDvEUB+44Z2OI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":323374},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"ae4b913b28748d6703f112d93480493823eb2014","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","test:unit":"vitest run tests/unit","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build","test:integration":"vitest run tests/integration"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript projects. Answers the question: what will break if I change this file?","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","boxen":"^8.0.1","chalk":"^6.0.0","figures":"^6.1.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","esbuild":"^0.28.1","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.4.0_1786188710569_0.2850447057178749","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@alimaandev/ripple","version":"0.5.0","keywords":["cli","typescript","dependencies","impact-analysis","refactoring","risk"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.5.0","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"ffab33f194ed3158ad49ea441dcd6bd46b210e4e","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.5.0.tgz","fileCount":11,"integrity":"sha512-I1Ca6Vx6UJvHNEpf+s5UGBs3SfqPPHhcVCDh3KDafwmn9vTtnpFfO2/tjRd40XcUZwWU0pRUQ+kPl/i6CnX/Gw==","signatures":[{"sig":"MEYCIQCsEjvzCNBm5nNTy6xQAZQ9Zw+apxbfFuTo9K+OpdrRdwIhAO+0FY1Mz11/fd/4EdKYc3v9RT1YAREILDQqBVKEn4w4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":335337},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"141c7df9fdd096d7eedbd8afa4ac6918f5ec0f80","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","test:unit":"vitest run tests/unit","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build","test:integration":"vitest run tests/integration"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript projects. Answers the question: what will break if I change this file?","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","boxen":"^8.0.1","chalk":"^6.0.0","figures":"^6.1.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","esbuild":"^0.28.1","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.5.0_1786204042194_0.3026076228432282","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@alimaandev/ripple","version":"0.6.0","keywords":["cli","typescript","javascript","dependency-graph","impact-analysis","static-analysis","refactoring","risk","cycle-detection","ci"],"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","_id":"@alimaandev/ripple@0.6.0","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"bin":{"ripple":"dist/bin.js"},"dist":{"shasum":"f1c0dad2322d8a44c338457057472616db41abb8","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.6.0.tgz","fileCount":12,"integrity":"sha512-EfgdHqCOjMr6VVytREmCgAYROAQvPdYugHEw2rKCZ4I16Lm6bJ8K39K9geTfQHNbGe5WV9NMQGliaWCM2zDjLg==","signatures":[{"sig":"MEYCIQDTwvPms+90SFAc6+r64wdDkEOW2eqPewFjLBwC5f5mLQIhAJyorbim9oiqKGFsQPWqpzjDj5/7Osavj2IHhim/hJMr","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":382974},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"f89e9635d98b2a83144afb48ab2753aaa7400a0d","scripts":{"dev":"tsup --watch","lint":"eslint .","test":"vitest run","build":"tsup","format":"prettier --write .","lint:fix":"eslint . --fix","test:unit":"vitest run tests/unit","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check .","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build","test:integration":"vitest run tests/integration"},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"repository":{"url":"git+https://github.com/alimaandev/ripple.git","type":"git"},"_npmVersion":"10.9.8","description":"Dependency impact analysis for TypeScript and JavaScript. Know the blast radius of any change — before you commit.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ora":"^9.4.1","zod":"^4.4.3","jiti":"^2.7.0","chalk":"^6.0.0","figures":"^6.1.0","treeify":"^1.1.0","ts-morph":"^28.0.0","commander":"^15.0.0","fast-glob":"^3.3.3","picomatch":"^4.0.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.20.0","devDependencies":{"ajv":"^8.20.0","tsup":"^8.5.1","eslint":"^10.8.0","vitest":"^4.1.10","esbuild":"^0.28.1","prettier":"^3.9.6","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^26.1.2","@types/treeify":"^1.0.3","@types/picomatch":"^4.0.3","typescript-eslint":"^8.66.0","@vitest/coverage-v8":"^4.1.10","eslint-config-prettier":"^10.1.8"},"_npmOperationalInternal":{"tmp":"tmp/ripple_0.6.0_1786627126489_0.9534836260849211","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@alimaandev/ripple","version":"0.7.0","description":"Dependency impact analysis for TypeScript and JavaScript. Know the blast radius of any change — before you commit.","keywords":["cli","typescript","javascript","dependency-graph","impact-analysis","static-analysis","refactoring","risk","cycle-detection","ci"],"license":"MIT","author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/alimaandev/ripple.git"},"homepage":"https://github.com/alimaandev/ripple#readme","bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"bin":{"ripple":"dist/bin.js"},"engines":{"node":">=22"},"packageManager":"pnpm@11.20.0","scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"vitest run","test:unit":"vitest run tests/unit","test:integration":"vitest run tests/integration","test:watch":"vitest","test:coverage":"vitest run --coverage","lint":"eslint .","lint:fix":"eslint . --fix","format":"prettier --write .","format:check":"prettier --check .","prepublishOnly":"pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build"},"dependencies":{"chalk":"^6.0.0","commander":"^15.0.0","fast-glob":"^3.3.3","figures":"^6.1.0","jiti":"^2.7.0","ora":"^9.4.1","picomatch":"^4.0.5","treeify":"^1.1.0","ts-morph":"^28.0.0","zod":"^4.4.3"},"devDependencies":{"@eslint/js":"^10.0.1","@types/node":"^26.1.2","@types/picomatch":"^4.0.3","@types/treeify":"^1.0.3","@vitest/coverage-v8":"^4.1.10","ajv":"^8.20.0","esbuild":"^0.28.1","eslint":"^10.8.0","eslint-config-prettier":"^10.1.8","prettier":"^3.9.6","tsup":"^8.5.1","typescript":"^5.9.3","typescript-eslint":"^8.66.0","vitest":"^4.1.10"},"_id":"@alimaandev/ripple@0.7.0","gitHead":"6122e0587a622ce28960393d888c53a1539c62ba","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-crKIbKrq4JGZXmLElKyDNKvrXBsryk3jkodxZiPuoEjjWSogPu42WUctWr1tiO9zewOPZ2Ww2btfRUEfOsyrBw==","shasum":"ed94f142c2f1d6ed345fbd4106c897072732dac6","tarball":"https://registry.npmjs.org/@alimaandev/ripple/-/ripple-0.7.0.tgz","fileCount":12,"unpackedSize":478133,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC/mBkOY5B+Nt1c4JAu9dEG21Yy/25FL9OTt6pOBD1FrgIhAI+dbqvgh72cLWezQkU2ebJwFoxRfj+UEFJnqhPZdKoc"}]},"_npmUser":{"name":"alimaandev","email":"alimaandev@gmail.com"},"directories":{},"maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ripple_0.7.0_1787044535171_0.5934471141085726"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-07T11:59:55.828Z","modified":"2026-08-18T09:15:35.525Z","0.1.0":"2026-08-07T11:59:56.159Z","0.1.1":"2026-08-07T16:12:51.706Z","0.2.0":"2026-08-07T16:57:52.428Z","0.3.0":"2026-08-08T09:16:20.807Z","0.4.0":"2026-08-08T11:31:50.856Z","0.5.0":"2026-08-08T15:47:22.380Z","0.6.0":"2026-08-13T13:18:46.635Z","0.7.0":"2026-08-18T09:15:35.294Z"},"bugs":{"url":"https://github.com/alimaandev/ripple/issues"},"author":{"name":"Ali Sher","email":"alishermaan0319@gmail.com"},"license":"MIT","homepage":"https://github.com/alimaandev/ripple#readme","keywords":["cli","typescript","javascript","dependency-graph","impact-analysis","static-analysis","refactoring","risk","cycle-detection","ci"],"repository":{"type":"git","url":"git+https://github.com/alimaandev/ripple.git"},"description":"Dependency impact analysis for TypeScript and JavaScript. Know the blast radius of any change — before you commit.","maintainers":[{"name":"alimaandev","email":"alimaandev@gmail.com"}],"readme":"<div align=\"center\">\n\n  <img src=\"https://raw.githubusercontent.com/alimaandev/ripple/main/assets/ripple-logo.png\" alt=\"Ripple\" width=\"120\" />\n\n# Ripple\n\n**Dependency impact analysis for TypeScript and JavaScript.**\n\nChange less. Break less. Know the blast radius of any file before you touch it.\n\n  <p align=\"center\">\n    &nbsp;<a href=\"https://www.npmjs.com/package/@alimaandev/ripple\"><img alt=\"npm version\" src=\"https://img.shields.io/npm/v/@alimaandev/ripple?logo=npm&logoColor=white&label=npm&style=for-the-badge\"/></a>&nbsp;\n    &nbsp;<a href=\"https://www.npmjs.com/package/@alimaandev/ripple\"><img alt=\"npm downloads\" src=\"https://img.shields.io/npm/dm/@alimaandev/ripple?label=downloads&style=for-the-badge\"/></a>&nbsp;\n    &nbsp;<a href=\"https://github.com/alimaandev/ripple/actions/workflows/ci.yml\"><img alt=\"CI build\" src=\"https://img.shields.io/github/actions/workflow/status/alimaandev/ripple/ci.yml?branch=main&logo=githubactions&logoColor=white&label=CI%20build&style=for-the-badge\"/></a>&nbsp;\n    &nbsp;<a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/github/license/alimaandev/ripple?label=License&style=for-the-badge\"/></a>&nbsp;\n    &nbsp;<a href=\"package.json\"><img alt=\"Node.js >= 22\" src=\"https://img.shields.io/badge/Node.js-%3E%3D22-339933?logo=nodedotjs&logoColor=white&style=for-the-badge\"/></a>&nbsp;\n  </p>\n\n  <pre><code>npm install -g @alimaandev/ripple\n\n# or try it without installing anything:\nnpx @alimaandev/ripple analyze src/your-file.ts</code></pre>\n\n  <img src=\"https://raw.githubusercontent.com/alimaandev/ripple/main/assets/hero-animated.svg\" alt=\"Animated terminal demo of `ripple analyze` — command types in, then the report builds up: risk score with gauge, affected files, routes, components, tests, and confidence\" title=\"ripple analyze\" width=\"100%\" />\n\n</div>\n\n## Why Ripple\n\n### The question your tooling doesn't answer\n\nIn any non-trivial codebase, there is a deceptively simple question:\n\n> **If I change this file, what else could break?**\n\nMost developer tooling stops short.\n\n`grep` finds text. Package managers track dependencies, not dependents. Traditional import graphs show what a file uses—not everything that relies on it.\n\nSo the blast radius of a change becomes a guess.\n\n**Ripple makes it explicit.**\n\nIt builds the project's import graph once, then walks it in reverse to show\nexactly how a change propagates through your codebase:\n\n```text\n$ ripple analyze src/authentication/login.ts\n\nFile        src/authentication/login.ts\nRisk        MEDIUM · 34.7/100 ███░░░░░░░\nImpact      4 routes · 2 components · 1 test\nAffected    7 files\nMax depth   2\nConfidence  100%\n```\n\nNo black box.\n\nNo cloud processing.\n\nNo telemetry.\n\nNo network calls.\n\nJust deterministic analysis against the code you actually have.\n\n**Know the ripple before you commit.**\n\n## Features\n\n| Feature                      | What it does                                                                                                            |\n| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- |\n| **Impact analysis**          | Reverse dependency traversal, transitively, with depth caps. Know who imports a target file.                            |\n| **Risk scoring**             | A transparent 0–100 score from seven weighted signals, with a per-factor breakdown in `--verbose`.                      |\n| **Cycle detection**          | Strongly-connected components with a concrete cycle path — `a → c → b → a`, not just a list of names.                   |\n| **Alias & path support**     | tsconfig `paths` and custom aliases like `{ \"@\": \"./src\" }`, including single-wildcard patterns.                        |\n| **Real-world resolution**    | Extension probing, index files, `.js` → `.ts` rewriting, dynamic `import()`, `require()`, `export … from`.              |\n| **Categorized results**      | Routes, layouts, components, utilities, and tests detected by path conventions — not a raw string of file names.        |\n| **Entry-point intelligence** | `package.json` `main`/`bin` plus conventional root and `src` entry files, flagged in the report.                        |\n| **Stable JSON contract**     | A machine-readable report for CI gates, dashboards, and tooling — additive-only compatibility.                          |\n| **Change-set gating**        | `ripple diff` analyzes every changed file since a base ref and blocks the merge on risky code.                          |\n| **Diff allowlist**           | `--allow <glob>` (or `diff.allow` in config) exempts legacy files from blocking the gate — analyze, report, don't fail. |\n| **Graph exports**            | `ripple graph --format mermaid                                                                                          | dot | html` renders the project graph as a Mermaid flowchart, Graphviz digraph, or a self-contained HTML report. |\n| **Config JSON Schema**       | Editors autocomplete and validate `ripple.config.json` against the shipped `ripple.schema.json` via `$schema`.          |\n| **Error-tolerant parsing**   | A broken file lowers confidence instead of aborting the run. No false precision.                                        |\n| **Deterministic & offline**  | Same input, same output, every time. No hidden network dependency.                                                      |\n\n## Quick start\n\nEverything below is real output against a shipped example project in `tests/fixtures/basic`.\n\n### Requirements\n\n- Node.js ≥ 22\n- pnpm 11+\n\n### Install & verify\n\n```bash\nnpm install -g @alimaandev/ripple\n\nripple version                  # → 0.7.0\n```\n\nOr install from source:\n\n```bash\ngit clone https://github.com/alimaandev/ripple.git\ncd ripple\npnpm install\npnpm build                      # bundles dist/bin.js via tsup\nnpm link                        # exposes the global `ripple` binary\n```\n\n### Run your first analysis\n\nNo install required — `npx` pulls the package from the registry on the fly:\n\n```bash\ncd tests/fixtures/basic\nnpx @alimaandev/ripple analyze src/authentication/login.ts\n```\n\nOnce you're sold, install it globally:\n\n```bash\nnpm install -g @alimaandev/ripple\nripple analyze src/authentication/login.ts\n```\n\nExpected output:\n\n```text\nripple · impact analysis · v0.7.0\n\nFile        src/authentication/login.ts\nRisk        MEDIUM · 34.7/100 ███░░░░░░░\nImpact      4 routes · 2 components · 1 test\nAffected    7 files\nMax depth   2\nConfidence  100%\n\n› Top impact\n● Dashboard (2)\n● Admin (1)\n● Index TS (1)\n\n› Circular dependencies\n◯ src/circular/a.ts → src/circular/c.ts → src/circular/b.ts → src/circular/a.ts\n\n› Affected files (7)\n├─ src/admin/page.tsx · depth 1\n├─ src/dashboard/page.tsx · depth 1\n└─ src/main.ts · depth 2\n```\n\n### See more of the project\n\n`ripple graph` gives a project-wide overview:\n\n```bash\ncd tests/fixtures/basic\nripple graph\n```\n\n```text\nripple · dependency graph · v0.7.0\n\nFiles            25\nEdges            28\nExternal         4\nUnresolved       0\nCircular groups  1\n\n› Circular dependencies\n◯ src/circular/a.ts → src/circular/c.ts → src/circular/b.ts → src/circular/a.ts\n```\n\nExport the graph for documentation or a team wiki — no extra tooling needed:\n\n```bash\nripple graph --format mermaid   # Mermaid flowchart (GitHub renders it natively)\nripple graph --format dot       # Graphviz digraph\nripple graph --format html      # self-contained dark-themed HTML report\nripple graph src/authentication/login.ts --format mermaid   # just a file's blast radius\n```\n\nPoint it at a file to see its dependency tree — forwards (what it imports)\nor, with `-r`, backwards (what imports it):\n\n```bash\nripple graph src/circular/b.ts -r\n```\n\n```text\nDependents (reverse)\n├─ src/circular/c.ts\n└─ src/circular/a.ts\n```\n\n## CLI reference\n\n```text\nripple <command> [options]\n```\n\n| Command          | Description                                       | Example                                      |\n| ---------------- | ------------------------------------------------- | -------------------------------------------- |\n| `analyze <file>` | Impact analysis for a target file                 | `ripple analyze src/authentication/login.ts` |\n| `graph [file]`   | Project stats, or a single file's dependency tree | `ripple graph src/circular/b.ts -r`          |\n| `diff`           | Gate all files changed since a git base ref       | `ripple diff --base main --gate critical`    |\n| `doctor`         | Project and environment health check              | `ripple doctor -v`                           |\n| `init`           | Scaffold a `ripple.config.json`                   | `ripple init`                                |\n| `version`        | Print the current version                         | `ripple version`                             |\n\n### Options\n\n| Command   | Flag                  | Description                                                                                    |\n| --------- | --------------------- | ---------------------------------------------------------------------------------------------- |\n| `analyze` | `-j, --json`          | Emit the JSON report instead of the terminal report                                            |\n| `analyze` | `--sarif`             | Emit a SARIF 2.1.0 report for code scanning                                                    |\n| `analyze` | `-v, --verbose`       | Include the risk-factor point breakdown                                                        |\n| `analyze` | `-d, --depth <n>`     | Cap the reverse traversal at `n` levels                                                        |\n| `analyze` | `-c, --config <path>` | Use a specific config file                                                                     |\n| `analyze` | `--no-color`          | Disable ANSI colors                                                                            |\n| `graph`   | `-j, --json`          | Emit the JSON report                                                                           |\n| `graph`   | `-r, --reverse`       | Show dependents (what imports this file) instead of dependencies                               |\n| `graph`   | `-d, --depth <n>`     | Cap tree depth                                                                                 |\n| `graph`   | `-c, --config <path>` | Use a specific config file                                                                     |\n| `graph`   | `--no-color`          | Disable ANSI colors                                                                            |\n| `doctor`  | `-c, --config <path>` | Use a specific config file                                                                     |\n| `doctor`  | `-v, --verbose`       | Verbose output                                                                                 |\n| `doctor`  | `--no-color`          | Disable ANSI colors                                                                            |\n| `init`    | `-f, --force`         | Overwrite an existing config                                                                   |\n| `diff`    | `-j, --json`          | Emit the JSON report instead of the terminal report                                            |\n| `diff`    | `-b, --base <ref>`    | Git ref to diff against (default: `origin/main`, `main`, `HEAD~1`, or `diff.base` from config) |\n| `diff`    | `-g, --gate <level>`  | Blocking level: `medium`, `high`, or `critical` (default: `high`, or `diff.gate` from config)  |\n| `diff`    | `-f, --format <fmt>`  | Output: `terminal`, `json`, `github` (workflow annotations), or `sarif`                        |\n| `diff`    | `-d, --depth <n>`     | Cap reverse traversal per file                                                                 |\n| `diff`    | `-c, --config <path>` | Use a specific config file                                                                     |\n| `diff`    | `--no-color`          | Disable ANSI colors                                                                            |\n\n### `ripple mcp`\n\nServe Ripple's analysis tools over the Model Context Protocol (see\n[the MCP section](#ripple-mcp-1) below).\n\n### `ripple doctor`\n\nIndependent health checks — config validity, tsconfig presence, source\ndiscovery, parse rate, import resolution, cycles. A failed check is reported\nbut doesn't abort the run; the command exits non-zero if anything fails.\n\n> [!TIP]\n> Run `ripple doctor` before your first analysis — it fails fast on config\n> and resolution problems and tells you exactly what to fix.\n\n```text\n$ ripple doctor\n✓ Node.js runtime v22.11.0\n✓ package.json package.json\n✓ ripple config ripple.config.json\n✓ tsconfig.json tsconfig.json\n✓ source files 25 discovered\n✓ path aliases 1 configured\n✓ parse all files parsed cleanly\n✓ import resolution all internal imports resolved\n⚠ circular dependencies 1 cycle group(s)\n⚠ Diagnoses passed with warnings.\n```\n\n### `ripple init`\n\nWrites `ripple.config.json` with the recommended defaults, ready to edit.\nThe minimal config references the shipped JSON Schema so editors\nautocomplete and validate as you type:\n\n```bash\nripple init                # minimal ripple.config.json + $schema\nripple init --full         # every built-in default, written out\nripple init --ts           # typed ripple.config.ts\nripple init --ts --full    # full defaults as TypeScript\n```\n\n### `ripple diff`\n\nAnalyzes every file that changed since a base git ref, scores each with the\nsame risk model as `analyze`, and gates the change set: any file reaching\nthe gate level (HIGH by default) makes the command exit `1`. Untracked\nfiles are included; deleted files and non-source changes are skipped.\n\n```bash\ncd my-project\nripple diff                       # vs origin/main (then main, then HEAD~1)\nripple diff --base HEAD~1 --json  # machine-readable gate report\nripple diff --gate critical       # only CRITICAL blocks the merge\nripple diff --allow \"src/legacy/**\"   # legacy files never block the gate\n```\n\nAdopting the gate on an existing codebase? Allowlist the files you haven't\nfixed yet — they are still analyzed and shown in the report, marked\n`(allowed)`, but they can't fail CI. The same list lives in config as\n`diff.allow`, so the whole team shares it.\n\n```text\nripple · diff vs origin/main\n\nChanged  2 files\nSource   2 files\nAllowed  1 file\nDuration 118ms\n\n✔ Gate passed — none (no HIGH or CRITICAL)\n\n› Risk analysis (2 files)\n✖ src/auth/token.ts     CRITICAL · 88.2/100 ████████░░\n✔ src/legacy/session.ts LOW · 12.4/100 █░░░░░░░░░ (allowed)\n… src/api/legacy.js     (not a source file)\n```\n\nRun `ripple diff` locally before opening a PR, and in CI as the same gate —\nidentical code, identical verdict.\n\n```bash\nripple diff --format github\n```\n\n`--format github` emits GitHub Actions workflow commands. Each risky change\nshows as a warning or error annotation right on the PR's Files tab —\n`::error` when a file blocks the gate, `::warning` otherwise — plus a\n`::notice` line with the gate verdict. The exit code still carries the\nverdict, so the job fails when the gate blocks:\n\n```yaml\n- run: npx @alimaandev/ripple diff --format github\n```\n\n(`--json` is shorthand for `--format json`; the format flag also accepts\n`terminal`, the default.)\n\n`--format sarif` emits SARIF 2.1.0, the format GitHub Code Scanning speaks:\n\n```bash\nripple diff --format sarif > ripple.sarif\n```\n\nEach analyzed change becomes a finding on the file — `error` when it is\nCRITICAL/HIGH, `warning` for MEDIUM, `note` for LOW — with a stable\n`primaryLocationLineHash` fingerprint so results deduplicate across runs.\nAllowlisted files are emitted as `note` with an in-source suppression, so\nthey show as exempted rather than failing. Upload the report straight into\nCode Scanning alerts:\n\n```yaml\n- uses: actions/upload-sarif@v3\n  with:\n    sarif_file: ripple.sarif\n```\n\nThe exit code still carries the gate verdict regardless of format.\n\n### `ripple mcp`\n\n`ripple mcp` exposes Ripple's analysis to AI coding agents as a Model\nContext Protocol server over stdio. Point any MCP client at the command and\nthe agent can check a file's blast radius before touching it:\n\n```json\n{\n  \"mcpServers\": {\n    \"ripple\": { \"command\": \"npx\", \"args\": [\"@alimaandev/ripple\", \"mcp\"] }\n  }\n}\n```\n\nFour tools are served:\n\n| Tool          | Inputs              | Returns                                                                 |\n| ------------- | ------------------- | ----------------------------------------------------------------------- |\n| `impact`      | `file`, `maxDepth?` | Blast radius: affected files, routes, tests, components, risk level     |\n| `dependents`  | `file`, `depth?`    | Who imports the file, up to a depth (default 1, direct)                 |\n| `risk`        | `file`              | Risk score with the factor breakdown behind it                          |\n| `gate_status` | `base?`, `gate?`    | Current change set vs the merge gate: files, levels, pass/block verdict |\n\nA typical agent loop: `impact src/auth/session.ts` before refactoring,\n`dependents` to see who breaks, then `gate_status` after editing to confirm\nthe gate still passes. Tool results are JSON text; failures return\n`isError` results instead of crashing the session.\n\n  <img src=\"https://raw.githubusercontent.com/alimaandev/ripple/main/assets/mcp-demo.svg\" alt=\"Flow diagram — an AI agent calls impact on src/auth/session.ts through ripple mcp and gets the blast radius back: 7 affected files, 4 routes, MEDIUM risk\" title=\"ripple mcp flow\" width=\"100%\" />\n\n## Configuration\n\nRipple discovers `ripple.config.ts`, `.js`, `.cjs`, `.mjs`, or `.json` in the\ncurrent directory, or from `--config <path>`. Your file is merged over the\ndefaults — every field is optional.\n\n```json\n{\n  \"$schema\": \"./node_modules/@alimaandev/ripple/ripple.schema.json\",\n  \"include\": [\"**/*.{ts,tsx,js,jsx}\"],\n  \"ignore\": [\"node_modules\", \"dist\", \"build\", \"coverage\", \".next\", \"out\"],\n  \"aliases\": { \"@\": \"./src\" },\n  \"tsconfigPath\": \"tsconfig.json\",\n  \"risk\": {\n    \"weights\": {\n      \"affectedFiles\": 0.3,\n      \"entryPoint\": 0.15,\n      \"sharedUtility\": 0.15,\n      \"publicExports\": 0.1,\n      \"tests\": 0.1,\n      \"routes\": 0.1,\n      \"cycleMembership\": 0.1\n    },\n    \"thresholds\": { \"medium\": 30, \"high\": 55, \"critical\": 80 }\n  },\n  \"diff\": {\n    \"base\": \"origin/main\",\n    \"gate\": \"high\",\n    \"allow\": [\"src/legacy/**\"]\n  }\n}\n```\n\n> [!TIP]\n> The `$schema` line powers editor autocomplete and validation for\n> `ripple.config.json` — the package ships `ripple.schema.json` for it.\n\n| Field             | Default                                                     | Purpose                                                |\n| ----------------- | ----------------------------------------------------------- | ------------------------------------------------------ |\n| `include`         | `**/*.{ts,tsx,js,jsx}`                                      | Source globs to analyze                                |\n| `ignore`          | `node_modules`, `dist`, `build`, `coverage`, `.next`, `out` | Exclusions                                             |\n| `aliases`         | `{}`                                                        | Path aliases, merged with tsconfig `paths` (user wins) |\n| `tsconfigPath`    | `tsconfig.json`                                             | tsconfig to read for `paths`                           |\n| `risk.weights`    | see example                                                 | Risk signal weights                                    |\n| `risk.thresholds` | 30 / 55 / 80                                                | Score thresholds for MEDIUM / HIGH / CRITICAL          |\n| `diff.base`       | `origin/main` → `main` → `HEAD~1`                           | Git ref to diff against when `--base` is not given     |\n| `diff.allow`      | `[]`                                                        | Globs of files that never block the gate               |\n| `diff.gate`       | `high`                                                      | Blocking level when `--gate` is not given              |\n\n`node_modules` is always excluded, regardless of config.\n\nThe `diff` block sets command defaults only — `--base`/`--gate` flags always\nwin over the config file, which wins over the built-in defaults.\n\n## Risk scoring\n\nThe score is a weighted sum of seven signals, normalized to 0–1. Affected\ncounts are log-scaled so a big graph can never drown out the signal:\n\n| Signal                          | Weight |\n| ------------------------------- | ------ |\n| Affected files                  | 0.30   |\n| Entry point impacted            | 0.15   |\n| Shared utilities impacted       | 0.15   |\n| Target public export surface    | 0.10   |\n| Tests impacted                  | 0.10   |\n| API routes impacted             | 0.10   |\n| Target in a circular dependency | 0.10   |\n\nThat yields a score from 0–100 and a level at thresholds 30, 55, 80 — the\nsame colors the CLI prints on your terminal:\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/alimaandev/ripple/main/assets/risk-levels.svg\" alt=\"Risk levels: LOW, MEDIUM, HIGH, CRITICAL\" title=\"Risk levels\" width=\"440\" />\n</p>\n\nConfidence (0–100) is separate — how trustworthy the analysis is. It drops\nwhen files fail to parse or imports stay unresolved, and takes a penalty if\nthe target sits inside a cycle. Use it to gate merges in CI, not just to look\nat pretty numbers.\n\n## How it works\n\nRipple is a small pipeline: discover source files, parse their imports in a\nreal TypeScript project, build the dependency graph, then answer questions\nagainst it. Risk and confidence are derived from that same graph — never from\nheuristics invented on the fly.\n\n```mermaid\nflowchart LR\n    A[Scanner] --> B[Parser]\n    B --> C[Graph]\n    C --> D[Reverse traversal]\n    D --> E[Risk + confidence]\n    E --> F[Terminal or JSON report]\n```\n\nThe pieces map to the source tree: `scanner/` discovers files from your\n`include`/`ignore` globs, `parser/` extracts imports and exports with\nerror-tolerant recovery, `graph/` resolves specifiers and detects cycles, and\n`risk/` turns graph signals into the score you see in the report.\n\n## JSON output (for CI)\n\n`ripple analyze --json` emits a stable, versioned contract:\n\n```json\n{\n  \"tool\": \"ripple\",\n  \"version\": \"0.5.0\",\n  \"command\": \"analyze\",\n  \"file\": \"src/authentication/login.ts\",\n  \"risk\": { \"score\": 34.4, \"level\": \"MEDIUM\", \"factors\": [] },\n  \"summary\": {\n    \"affectedFiles\": 7,\n    \"routes\": 4,\n    \"components\": 2,\n    \"entries\": 1,\n    \"tests\": 1,\n    \"utilities\": 0,\n    \"maxDepth\": 2,\n    \"confidence\": 100,\n    \"topImpact\": [\n      { \"label\": \"Dashboard\", \"count\": 2 },\n      { \"label\": \"Admin\", \"count\": 1 }\n    ]\n  },\n  \"affected\": [\n    {\n      \"path\": \"src/admin/page.tsx\",\n      \"depth\": 1,\n      \"direct\": true,\n      \"categories\": [\"route\"],\n      \"inCycle\": false\n    }\n  ],\n  \"cycles\": [\n    {\n      \"members\": [\"src/circular/a.ts\", \"src/circular/b.ts\", \"src/circular/c.ts\"],\n      \"path\": [\"src/circular/a.ts\", \"src/circular/c.ts\", \"src/circular/b.ts\", \"src/circular/a.ts\"]\n    }\n  ],\n  \"targetInCycle\": false,\n  \"durationMs\": 242\n}\n```\n\n> [!IMPORTANT]\n> The contract is additive-only — existing field names and shapes never\n> change without a major version bump. `graph --json` follows the same\n> convention.\n\n### `ripple diff --json`\n\nThe diff report wraps a per-file view of the same risk model, plus the gate\nverdict:\n\n```json\n{\n  \"tool\": \"ripple\",\n  \"version\": \"0.5.0\",\n  \"command\": \"diff\",\n  \"base\": \"origin/main\",\n  \"changedFiles\": 2,\n  \"files\": [\n    {\n      \"file\": \"src/auth/token.ts\",\n      \"analyzed\": true,\n      \"risk\": { \"score\": 88.2, \"level\": \"CRITICAL\", \"factors\": [] },\n      \"affectedFiles\": 14,\n      \"targetInCycle\": false\n    },\n    { \"file\": \"src/api/legacy.js\", \"analyzed\": false }\n  ],\n  \"gate\": {\n    \"level\": \"high\",\n    \"blocked\": true,\n    \"counts\": { \"low\": 0, \"medium\": 0, \"high\": 0, \"critical\": 1 }\n  },\n  \"durationMs\": 118\n}\n```\n\n`blocked` tells CI everything: exit code `1` if `true`, `0` otherwise.\n\n### Use it in CI\n\n```bash\nripple analyze src/authentication/login.ts --json | jq -r .risk.level\n# MEDIUM\n```\n\nGate every changed file in one call:\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\nripple diff --json --gate high\n# exits 1 when any changed file is HIGH or CRITICAL\n```\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\nlevel=\"$(ripple analyze \"$1\" --json | jq -r .risk.level)\"\nif [ \"$level\" = \"CRITICAL\" ]; then\n  echo \"CRITICAL impact — review before merging\" >&2\n  exit 1\nfi\n```\n\n## FAQ\n\n**Why is confidence below 100%?**\n\n> [!WARNING]\n> Confidence drops when files fail to parse or imports stay unresolved — the\n> two signals that make an analysis less trustworthy. Run `ripple doctor` to\n> see exactly which checks are failing.\n\n**Why do `.css` or package imports appear in the report?**\n\n> [!NOTE]\n> Non-source imports (styles, assets, npm packages) are classified as\n> external. They appear in the graph (see `External` in `ripple graph`) but\n> are never counted as affected files — you can't \"break\" a package by\n> changing local code.\n\n**Why are `node_modules` files never analyzed?**\n\n> [!NOTE]\n> `node_modules` is always excluded, even if your config adds it to\n> `include`. Analyzing installed packages would only add noise to your blast\n> radius.\n\n**Does Ripple work on Windows?**\n\n> [!TIP]\n> Yes — path handling is platform-aware. Integration tests run on Linux CI,\n> and development happens on Windows; both report the same results from the\n> same fixtures.\n\n## Exit codes\n\n| Code | Meaning                               |\n| ---- | ------------------------------------- |\n| `0`  | Success                               |\n| `1`  | General failure / gate blocked        |\n| `2`  | Target file or git base ref not found |\n| `3`  | Config missing or invalid             |\n\n## Development\n\n```bash\npnpm install\npnpm run dev            # watch-mode rebuild via tsup\npnpm run typecheck      # tsc --noEmit\npnpm run lint           # eslint\npnpm run lint:fix       # eslint --fix\npnpm run format         # prettier --write\npnpm run test           # vitest run\npnpm run test:watch     # vitest\npnpm run build          # tsup\n```\n\nArchitecture and design decisions live in [docs/architecture.md](docs/architecture.md).\nBefore contributing, read [CONTRIBUTING.md](CONTRIBUTING.md).\n\nQuality gates run on every pull request: lint, typecheck, build, unit tests\n(against a global coverage floor for `src/**`), integration tests on Linux\nand Windows, and a dogfood job — Ripple gates its own PRs with\n`ripple diff --format github`.\n\n## Get started\n\n```bash\nnpm install -g @alimaandev/ripple\nripple analyze src/your-file.ts --json | jq -r .risk.level   # MEDIUM, HIGH, ...\n```\n\nIf Ripple has ever kept you from an accidental breaking change, a\n[little star](https://github.com/alimaandev/ripple) goes a long way — it\nhelps other developers find it.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md"}