@alimaandev/ripple 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +453 -0
- package/dist/bin.js +1829 -0
- package/dist/bin.js.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ripple contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="assets/ripple-logo.png" alt="Ripple" width="120" />
|
|
4
|
+
|
|
5
|
+
# Ripple
|
|
6
|
+
|
|
7
|
+
**Dependency impact analysis for TypeScript and JavaScript.**
|
|
8
|
+
|
|
9
|
+
Change less. Break less. Know the blast radius of any file before you touch it.
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<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>
|
|
13
|
+
<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>
|
|
14
|
+
<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>
|
|
15
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/github/license/alimaandev/ripple?label=License&style=for-the-badge"/></a>
|
|
16
|
+
<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>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<img src="assets/hero.svg" alt="Terminal output of `ripple analyze` — risk, affected files, routes, components, tests, and confidence score" title="ripple analyze" width="100%" />
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
## Why Ripple
|
|
24
|
+
|
|
25
|
+
### The question your tooling doesn't answer
|
|
26
|
+
|
|
27
|
+
In any non-trivial codebase, there is a deceptively simple question:
|
|
28
|
+
|
|
29
|
+
> **If I change this file, what else could break?**
|
|
30
|
+
|
|
31
|
+
Most developer tooling stops short.
|
|
32
|
+
|
|
33
|
+
`grep` finds text. Package managers track dependencies, not dependents. Traditional import graphs show what a file uses—not everything that relies on it.
|
|
34
|
+
|
|
35
|
+
So the blast radius of a change becomes a guess.
|
|
36
|
+
|
|
37
|
+
**Ripple makes it explicit.**
|
|
38
|
+
|
|
39
|
+
It builds the project's import graph once, then walks it in reverse to show
|
|
40
|
+
exactly how a change propagates through your codebase:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
$ ripple analyze src/authentication/login.ts
|
|
44
|
+
|
|
45
|
+
Risk MEDIUM
|
|
46
|
+
Affected Files 7 files
|
|
47
|
+
API Routes 4
|
|
48
|
+
Components 2
|
|
49
|
+
Tests 1
|
|
50
|
+
Max Depth 2
|
|
51
|
+
Confidence 100%
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
No black box.
|
|
55
|
+
|
|
56
|
+
No cloud processing.
|
|
57
|
+
|
|
58
|
+
No telemetry.
|
|
59
|
+
|
|
60
|
+
No network calls.
|
|
61
|
+
|
|
62
|
+
Just deterministic analysis against the code you actually have.
|
|
63
|
+
|
|
64
|
+
**Know the ripple before you commit.**
|
|
65
|
+
|
|
66
|
+
## Features
|
|
67
|
+
|
|
68
|
+
| Feature | What it does |
|
|
69
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| **Impact analysis** | Reverse dependency traversal, transitively, with depth caps. Know who imports a target file. |
|
|
71
|
+
| **Risk scoring** | A transparent 0–100 score from seven weighted signals, with a per-factor breakdown in `--verbose`. |
|
|
72
|
+
| **Cycle detection** | Strongly-connected components with a concrete cycle path — `a → c → b → a`, not just a list of names. |
|
|
73
|
+
| **Alias & path support** | tsconfig `paths` and custom aliases like `{ "@": "./src" }`, including single-wildcard patterns. |
|
|
74
|
+
| **Real-world resolution** | Extension probing, index files, `.js` → `.ts` rewriting, dynamic `import()`, `require()`, `export … from`. |
|
|
75
|
+
| **Categorized results** | Routes, layouts, components, utilities, and tests detected by path conventions — not a raw string of file names. |
|
|
76
|
+
| **Entry-point intelligence** | `package.json` `main`/`bin` plus conventional root and `src` entry files, flagged in the report. |
|
|
77
|
+
| **Stable JSON contract** | A machine-readable report for CI gates, dashboards, and tooling — additive-only compatibility. |
|
|
78
|
+
| **Error-tolerant parsing** | A broken file lowers confidence instead of aborting the run. No false precision. |
|
|
79
|
+
| **Deterministic & offline** | Same input, same output, every time. No hidden network dependency. |
|
|
80
|
+
|
|
81
|
+
## Quick start
|
|
82
|
+
|
|
83
|
+
Everything below is real output against a shipped example project in `tests/fixtures/basic`.
|
|
84
|
+
|
|
85
|
+
### Requirements
|
|
86
|
+
|
|
87
|
+
- Node.js ≥ 22
|
|
88
|
+
- pnpm 11+
|
|
89
|
+
|
|
90
|
+
### Install & verify
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install -g @alimaandev/ripple
|
|
94
|
+
|
|
95
|
+
ripple version # → 0.1.0
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Or install from source:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
git clone https://github.com/alimaandev/ripple.git
|
|
102
|
+
cd ripple
|
|
103
|
+
pnpm install
|
|
104
|
+
pnpm build # bundles dist/bin.js via tsup
|
|
105
|
+
npm link # exposes the global `ripple` binary
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Run your first analysis
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
cd tests/fixtures/basic
|
|
112
|
+
ripple analyze src/authentication/login.ts
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Expected output:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
🌊 Ripple Analysis
|
|
119
|
+
|
|
120
|
+
File src/authentication/login.ts
|
|
121
|
+
Risk MEDIUM
|
|
122
|
+
Affected Files 7 files
|
|
123
|
+
Components 2
|
|
124
|
+
API Routes 4
|
|
125
|
+
Tests 1
|
|
126
|
+
Utilities 0
|
|
127
|
+
Max Depth 2
|
|
128
|
+
Confidence 100%
|
|
129
|
+
|
|
130
|
+
Top Impact
|
|
131
|
+
• Dashboard (2)
|
|
132
|
+
• Admin (1)
|
|
133
|
+
• Index TS (1)
|
|
134
|
+
|
|
135
|
+
Circular Dependencies
|
|
136
|
+
⭕ src/circular/a.ts → src/circular/c.ts → src/circular/b.ts → src/circular/a.ts
|
|
137
|
+
|
|
138
|
+
Affected Files (7)
|
|
139
|
+
├─ src/admin/page.tsx (depth 1)
|
|
140
|
+
├─ src/dashboard/page.tsx (depth 1)
|
|
141
|
+
└─ src/main.ts (depth 2)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### See more of the project
|
|
145
|
+
|
|
146
|
+
`ripple graph` gives a project-wide overview:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
cd tests/fixtures/basic
|
|
150
|
+
ripple graph
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
🌊 Dependency Graph
|
|
155
|
+
|
|
156
|
+
Files 25
|
|
157
|
+
Edges 28
|
|
158
|
+
External 4
|
|
159
|
+
Unresolved 0
|
|
160
|
+
Circular groups 1
|
|
161
|
+
|
|
162
|
+
Circular Dependencies
|
|
163
|
+
⭕ src/circular/a.ts → src/circular/c.ts → src/circular/b.ts → src/circular/a.ts
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Point it at a file to see its dependency tree — forwards (what it imports)
|
|
167
|
+
or, with `-r`, backwards (what imports it):
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
ripple graph src/circular/b.ts -r
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
Dependents (reverse)
|
|
175
|
+
├─ src/circular/c.ts
|
|
176
|
+
└─ src/circular/a.ts
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## CLI reference
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
ripple <command> [options]
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
| Command | Description |
|
|
186
|
+
| ---------------- | ------------------------------------------------- |
|
|
187
|
+
| `analyze <file>` | Impact analysis for a target file |
|
|
188
|
+
| `graph [file]` | Project stats, or a single file's dependency tree |
|
|
189
|
+
| `doctor` | Project and environment health check |
|
|
190
|
+
| `init` | Scaffold a `ripple.config.json` |
|
|
191
|
+
| `version` | Print the current version |
|
|
192
|
+
|
|
193
|
+
### Options
|
|
194
|
+
|
|
195
|
+
| Command | Flag | Description |
|
|
196
|
+
| --------- | --------------------- | ---------------------------------------------------------------- |
|
|
197
|
+
| `analyze` | `-j, --json` | Emit the JSON report instead of the terminal report |
|
|
198
|
+
| `analyze` | `-v, --verbose` | Include the risk-factor point breakdown |
|
|
199
|
+
| `analyze` | `-d, --depth <n>` | Cap the reverse traversal at `n` levels |
|
|
200
|
+
| `analyze` | `-c, --config <path>` | Use a specific config file |
|
|
201
|
+
| `analyze` | `--no-color` | Disable ANSI colors |
|
|
202
|
+
| `graph` | `-j, --json` | Emit the JSON report |
|
|
203
|
+
| `graph` | `-r, --reverse` | Show dependents (what imports this file) instead of dependencies |
|
|
204
|
+
| `graph` | `-d, --depth <n>` | Cap tree depth |
|
|
205
|
+
| `graph` | `-c, --config <path>` | Use a specific config file |
|
|
206
|
+
| `graph` | `--no-color` | Disable ANSI colors |
|
|
207
|
+
| `doctor` | `-c, --config <path>` | Use a specific config file |
|
|
208
|
+
| `doctor` | `-v, --verbose` | Verbose output |
|
|
209
|
+
| `doctor` | `--no-color` | Disable ANSI colors |
|
|
210
|
+
| `init` | `-f, --force` | Overwrite an existing config |
|
|
211
|
+
|
|
212
|
+
### `ripple doctor`
|
|
213
|
+
|
|
214
|
+
Independent health checks — config validity, tsconfig presence, source
|
|
215
|
+
discovery, parse rate, import resolution, cycles. A failed check is reported
|
|
216
|
+
but doesn't abort the run; the command exits non-zero if anything fails.
|
|
217
|
+
|
|
218
|
+
> [!TIP]
|
|
219
|
+
> Run `ripple doctor` before your first analysis — it fails fast on config
|
|
220
|
+
> and resolution problems and tells you exactly what to fix.
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
$ ripple doctor
|
|
224
|
+
✓ Node.js runtime v22.11.0
|
|
225
|
+
✓ package.json package.json
|
|
226
|
+
✓ ripple config ripple.config.json
|
|
227
|
+
✓ tsconfig.json tsconfig.json
|
|
228
|
+
✓ source files 25 discovered
|
|
229
|
+
✓ path aliases 1 configured
|
|
230
|
+
✓ parse all files parsed cleanly
|
|
231
|
+
✓ import resolution all internal imports resolved
|
|
232
|
+
⚠ circular dependencies 1 cycle group(s)
|
|
233
|
+
⚠ Diagnoses passed with warnings.
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### `ripple init`
|
|
237
|
+
|
|
238
|
+
Writes `ripple.config.json` with the recommended defaults, ready to edit.
|
|
239
|
+
|
|
240
|
+
## Configuration
|
|
241
|
+
|
|
242
|
+
Ripple discovers `ripple.config.ts`, `.js`, `.cjs`, `.mjs`, or `.json` in the
|
|
243
|
+
current directory, or from `--config <path>`. Your file is merged over the
|
|
244
|
+
defaults — every field is optional.
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"include": ["**/*.{ts,tsx,js,jsx}"],
|
|
249
|
+
"ignore": ["node_modules", "dist", "build", "coverage", ".next", "out"],
|
|
250
|
+
"aliases": { "@": "./src" },
|
|
251
|
+
"tsconfigPath": "tsconfig.json",
|
|
252
|
+
"risk": {
|
|
253
|
+
"weights": {
|
|
254
|
+
"affectedFiles": 0.3,
|
|
255
|
+
"entryPoint": 0.15,
|
|
256
|
+
"sharedUtility": 0.15,
|
|
257
|
+
"publicExports": 0.1,
|
|
258
|
+
"tests": 0.1,
|
|
259
|
+
"routes": 0.1,
|
|
260
|
+
"cycleMembership": 0.1
|
|
261
|
+
},
|
|
262
|
+
"thresholds": { "medium": 30, "high": 55, "critical": 80 }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
| Field | Default | Purpose |
|
|
268
|
+
| ----------------- | ----------------------------------------------------------- | ------------------------------------------------------ |
|
|
269
|
+
| `include` | `**/*.{ts,tsx,js,jsx}` | Source globs to analyze |
|
|
270
|
+
| `ignore` | `node_modules`, `dist`, `build`, `coverage`, `.next`, `out` | Exclusions |
|
|
271
|
+
| `aliases` | `{}` | Path aliases, merged with tsconfig `paths` (user wins) |
|
|
272
|
+
| `tsconfigPath` | `tsconfig.json` | tsconfig to read for `paths` |
|
|
273
|
+
| `risk.weights` | see example | Risk signal weights |
|
|
274
|
+
| `risk.thresholds` | 30 / 55 / 80 | Score thresholds for MEDIUM / HIGH / CRITICAL |
|
|
275
|
+
|
|
276
|
+
`node_modules` is always excluded, regardless of config.
|
|
277
|
+
|
|
278
|
+
## Risk scoring
|
|
279
|
+
|
|
280
|
+
The score is a weighted sum of seven signals, normalized to 0–1. Affected
|
|
281
|
+
counts are log-scaled so a big graph can never drown out the signal:
|
|
282
|
+
|
|
283
|
+
| Signal | Weight |
|
|
284
|
+
| ------------------------------- | ------ |
|
|
285
|
+
| Affected files | 0.30 |
|
|
286
|
+
| Entry point impacted | 0.15 |
|
|
287
|
+
| Shared utilities impacted | 0.15 |
|
|
288
|
+
| Target public export surface | 0.10 |
|
|
289
|
+
| Tests impacted | 0.10 |
|
|
290
|
+
| API routes impacted | 0.10 |
|
|
291
|
+
| Target in a circular dependency | 0.10 |
|
|
292
|
+
|
|
293
|
+
That yields a score from 0–100 and a level at thresholds 30, 55, 80 — the
|
|
294
|
+
same colors the CLI prints on your terminal:
|
|
295
|
+
|
|
296
|
+
<p align="center">
|
|
297
|
+
<img src="assets/risk-levels.svg" alt="Risk levels: LOW, MEDIUM, HIGH, CRITICAL" title="Risk levels" width="440" />
|
|
298
|
+
</p>
|
|
299
|
+
|
|
300
|
+
Confidence (0–100) is separate — how trustworthy the analysis is. It drops
|
|
301
|
+
when files fail to parse or imports stay unresolved, and takes a penalty if
|
|
302
|
+
the target sits inside a cycle. Use it to gate merges in CI, not just to look
|
|
303
|
+
at pretty numbers.
|
|
304
|
+
|
|
305
|
+
## How it works
|
|
306
|
+
|
|
307
|
+
Ripple is a small pipeline: discover source files, parse their imports in a
|
|
308
|
+
real TypeScript project, build the dependency graph, then answer questions
|
|
309
|
+
against it. Risk and confidence are derived from that same graph — never from
|
|
310
|
+
heuristics invented on the fly.
|
|
311
|
+
|
|
312
|
+
```mermaid
|
|
313
|
+
flowchart LR
|
|
314
|
+
A[Scanner] --> B[Parser]
|
|
315
|
+
B --> C[Graph]
|
|
316
|
+
C --> D[Reverse traversal]
|
|
317
|
+
D --> E[Risk + confidence]
|
|
318
|
+
E --> F[Terminal or JSON report]
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
The pieces map to the source tree: `scanner/` discovers files from your
|
|
322
|
+
`include`/`ignore` globs, `parser/` extracts imports and exports with
|
|
323
|
+
error-tolerant recovery, `graph/` resolves specifiers and detects cycles, and
|
|
324
|
+
`risk/` turns graph signals into the score you see in the report.
|
|
325
|
+
|
|
326
|
+
## JSON output (for CI)
|
|
327
|
+
|
|
328
|
+
`ripple analyze --json` emits a stable, versioned contract:
|
|
329
|
+
|
|
330
|
+
```json
|
|
331
|
+
{
|
|
332
|
+
"tool": "ripple",
|
|
333
|
+
"version": "0.1.0",
|
|
334
|
+
"command": "analyze",
|
|
335
|
+
"file": "src/authentication/login.ts",
|
|
336
|
+
"risk": { "score": 34.4, "level": "MEDIUM", "factors": [] },
|
|
337
|
+
"summary": {
|
|
338
|
+
"affectedFiles": 7,
|
|
339
|
+
"routes": 4,
|
|
340
|
+
"components": 2,
|
|
341
|
+
"entries": 1,
|
|
342
|
+
"tests": 1,
|
|
343
|
+
"utilities": 0,
|
|
344
|
+
"maxDepth": 2,
|
|
345
|
+
"confidence": 100,
|
|
346
|
+
"topImpact": [
|
|
347
|
+
{ "label": "Dashboard", "count": 2 },
|
|
348
|
+
{ "label": "Admin", "count": 1 }
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
"affected": [
|
|
352
|
+
{
|
|
353
|
+
"path": "src/admin/page.tsx",
|
|
354
|
+
"depth": 1,
|
|
355
|
+
"direct": true,
|
|
356
|
+
"categories": ["route"],
|
|
357
|
+
"inCycle": false
|
|
358
|
+
}
|
|
359
|
+
],
|
|
360
|
+
"cycles": [
|
|
361
|
+
{
|
|
362
|
+
"members": ["src/circular/a.ts", "src/circular/b.ts", "src/circular/c.ts"],
|
|
363
|
+
"path": ["src/circular/a.ts", "src/circular/c.ts", "src/circular/b.ts", "src/circular/a.ts"]
|
|
364
|
+
}
|
|
365
|
+
],
|
|
366
|
+
"targetInCycle": false,
|
|
367
|
+
"durationMs": 242
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
> [!IMPORTANT]
|
|
372
|
+
> The contract is additive-only — existing field names and shapes never
|
|
373
|
+
> change without a major version bump. `graph --json` follows the same
|
|
374
|
+
> convention.
|
|
375
|
+
|
|
376
|
+
### Use it in CI
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
ripple analyze src/authentication/login.ts --json | jq -r .risk.level
|
|
380
|
+
# MEDIUM
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
#!/usr/bin/env bash
|
|
385
|
+
set -euo pipefail
|
|
386
|
+
|
|
387
|
+
level="$(ripple analyze "$1" --json | jq -r .risk.level)"
|
|
388
|
+
if [ "$level" = "CRITICAL" ]; then
|
|
389
|
+
echo "CRITICAL impact — review before merging" >&2
|
|
390
|
+
exit 1
|
|
391
|
+
fi
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## FAQ
|
|
395
|
+
|
|
396
|
+
**Why is confidence below 100%?**
|
|
397
|
+
|
|
398
|
+
> [!WARNING]
|
|
399
|
+
> Confidence drops when files fail to parse or imports stay unresolved — the
|
|
400
|
+
> two signals that make an analysis less trustworthy. Run `ripple doctor` to
|
|
401
|
+
> see exactly which checks are failing.
|
|
402
|
+
|
|
403
|
+
**Why do `.css` or package imports appear in the report?**
|
|
404
|
+
|
|
405
|
+
> [!NOTE]
|
|
406
|
+
> Non-source imports (styles, assets, npm packages) are classified as
|
|
407
|
+
> external. They appear in the graph (see `External` in `ripple graph`) but
|
|
408
|
+
> are never counted as affected files — you can't "break" a package by
|
|
409
|
+
> changing local code.
|
|
410
|
+
|
|
411
|
+
**Why are `node_modules` files never analyzed?**
|
|
412
|
+
|
|
413
|
+
> [!NOTE]
|
|
414
|
+
> `node_modules` is always excluded, even if your config adds it to
|
|
415
|
+
> `include`. Analyzing installed packages would only add noise to your blast
|
|
416
|
+
> radius.
|
|
417
|
+
|
|
418
|
+
**Does Ripple work on Windows?**
|
|
419
|
+
|
|
420
|
+
> [!TIP]
|
|
421
|
+
> Yes — path handling is platform-aware. Integration tests run on Linux CI,
|
|
422
|
+
> and development happens on Windows; both report the same results from the
|
|
423
|
+
> same fixtures.
|
|
424
|
+
|
|
425
|
+
## Exit codes
|
|
426
|
+
|
|
427
|
+
| Code | Meaning |
|
|
428
|
+
| ---- | ------------------------- |
|
|
429
|
+
| `0` | Success |
|
|
430
|
+
| `1` | General failure |
|
|
431
|
+
| `2` | Target file not found |
|
|
432
|
+
| `3` | Config missing or invalid |
|
|
433
|
+
|
|
434
|
+
## Development
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
pnpm install
|
|
438
|
+
pnpm run dev # watch-mode rebuild via tsup
|
|
439
|
+
pnpm run typecheck # tsc --noEmit
|
|
440
|
+
pnpm run lint # eslint
|
|
441
|
+
pnpm run lint:fix # eslint --fix
|
|
442
|
+
pnpm run format # prettier --write
|
|
443
|
+
pnpm run test # vitest run
|
|
444
|
+
pnpm run test:watch # vitest
|
|
445
|
+
pnpm run build # tsup
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Architecture and design decisions live in [docs/architecture.md](docs/architecture.md).
|
|
449
|
+
Before contributing, read [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
MIT — see [LICENSE](LICENSE).
|