@better-vibe/branch-narrator 1.0.0 → 1.2.1

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/README.md CHANGED
@@ -1,95 +1,250 @@
1
1
  # branch-narrator
2
2
 
3
- A local-first CLI that reads `git diff` and generates structured **PR descriptions** (Markdown) and **machine-readable facts** (JSON).
3
+ [![npm version](https://img.shields.io/npm/v/@better-vibe/branch-narrator)](https://www.npmjs.com/package/@better-vibe/branch-narrator)
4
+ [![CI](https://github.com/@better-vibe/branch-narrator/actions/workflows/ci.yml/badge.svg)](https://github.com/@better-vibe/branch-narrator/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4
6
 
5
- ## Features
7
+ A local-first, deterministic CLI that analyzes `git diff` and provides
8
+ structured context for AI coding agents and human code review.
6
9
 
7
- - **Heuristics-only**: No LLM calls, no network calls. Fully deterministic and grounded in git diff.
8
- - **Agent-grade reliability**: JSON outputs are deterministic, parseable, and pipe-safe (e.g., `branch-narrator facts | jq .`). Global `--quiet` and `--debug` flags control diagnostics.
9
- - **Risk Analysis**: Framework-agnostic security and quality risk scoring (0-100) with evidence-backed flags.
10
- - **SvelteKit-aware**: Detects routes, layouts, endpoints, and HTTP methods.
11
- - **React Router support**: Detects route changes in React apps (JSX `<Route>` and data routers like `createBrowserRouter`).
12
- - **Supabase integration**: Scans migrations for destructive SQL patterns.
13
- - **Environment variable detection**: Finds `process.env`, SvelteKit `$env` imports, Vite `import.meta.env`, React App `REACT_APP_*`, and Next.js `NEXT_PUBLIC_*`.
14
- - **Cloudflare detection**: Detects wrangler config and CI changes.
15
- - **Dependency analysis**: Tracks package.json changes with semver impact.
16
- - **CI/CD security**: Detects workflow permission changes, pull_request_target, remote script execution.
17
- - **Infrastructure changes**: Tracks Dockerfile, Terraform, and Kubernetes manifest changes.
18
-
19
- ## Installation
10
+ ## Quick Start
20
11
 
21
12
  ```bash
22
- bun add -D branch-narrator
13
+ # Install as dev dependency (recommended)
14
+ bun add -D @better-vibe/branch-narrator
23
15
  # or
24
- npm install -D branch-narrator
16
+ npm install -D @better-vibe/branch-narrator
17
+
18
+ # Or install globally
19
+ npm install -g @better-vibe/branch-narrator
20
+
21
+ # Or run without installing
22
+ npx @better-vibe/branch-narrator facts --pretty
25
23
  ```
26
24
 
27
- ## Common Use Cases
25
+ ### Common Commands
28
26
 
29
- ### For AI Agents
30
- Agents need grounded, hallucination-free context to work effectively. `branch-narrator` provides the "ground truth" of what actually changed in the codebase.
31
- - **Context Gathering**: Use `facts` to get a structured JSON summary of changes (routes, dependencies, risks) to understand the "what" before generating code.
32
- - **Diff Understanding**: Use `dump-diff` to get a clean, token-optimized git diff that handles exclusions smartly (ignoring lockfiles, minified files, etc.).
33
- - **Self-Verification**: Use `zoom` to verify specific findings or check if a requested change (e.g., "add a route") was actually implemented correctly.
27
+ ```bash
28
+ # Generate a PR description for current changes
29
+ branch-narrator pr-body
34
30
 
35
- ### For Developers
36
- Streamline your daily workflow without context switching.
37
- - **Fast Code Review**: Run `branch-narrator pretty` to see a high-level summary of your uncommitted changes in the terminal.
38
- - **PR Descriptions**: Generate a consistent, comprehensive PR description with `branch-narrator pr-body` and pipe it directly to `gh pr create` or your clipboard.
31
+ # Structured JSON facts for automation
32
+ branch-narrator facts --pretty
39
33
 
40
- ### For CI/CD Pipelines
41
- Automate quality and security checks.
42
- - **Risk Gating**: Use `branch-narrator risk-report --fail-on-score 60` in your CI pipeline to automatically block merges that introduce high-risk changes (like destructive migrations or dangerous permissions) until they are reviewed.
34
+ # Risk report for review
35
+ branch-narrator risk-report --format md
43
36
 
44
- ## Usage
37
+ # Prompt-ready diff with smart filtering
38
+ branch-narrator dump-diff --out .ai/diff.txt
45
39
 
46
- ### Global Flags
40
+ # Save workspace snapshot for agent iteration
41
+ branch-narrator snap save "before-refactor"
47
42
 
48
- All commands support the following global flags:
43
+ # SARIF output for GitHub Code Scanning
44
+ branch-narrator facts --format sarif --out results.sarif
49
45
 
50
- ```bash
51
- # Suppress non-fatal diagnostic output (warnings, info messages)
52
- branch-narrator --quiet facts
46
+ # Compare changes since last run (delta mode)
47
+ branch-narrator facts --since .ai/baseline.json
48
+ ```
49
+
50
+ ## Table of Contents
51
+
52
+ - [Quick Start](#quick-start)
53
+ - [Why branch-narrator](#why-branch-narrator)
54
+ - [Key Capabilities](#key-capabilities)
55
+ - [Documentation](#documentation)
56
+ - [CLI Reference](#cli-reference)
57
+ - [CI/CD Integration](#cicd-integration)
58
+ - [Programmatic API](#programmatic-api)
59
+ - [Example Output](#example-output)
60
+ - [Development](#development)
61
+ - [Contributing](#contributing)
62
+ - [Requirements](#requirements)
63
+ - [License](#license)
64
+
65
+ ## Why branch-narrator
66
+
67
+ - Deterministic and offline: no LLMs, no network calls.
68
+ - Evidence-based output: summaries and risk flags are tied to diff evidence.
69
+ - Profile-aware analysis across frameworks and libraries.
70
+ - Output for humans (Markdown) and automation (JSON/SARIF).
71
+
72
+ ## Key Capabilities
73
+
74
+ ### Output Formats
75
+ - **Markdown PR descriptions** (`pr-body`) with consistent sections.
76
+ - **JSON facts** (`facts`) for pipelines and automation.
77
+ - **Prompt-ready diffs** (`dump-diff`) with smart filtering for AI context windows.
78
+ - **SARIF output** (`--format sarif`) for GitHub Code Scanning integration.
79
+ - **Risk scoring** (`risk-report`) with evidence-backed flags and categories.
80
+ - **Workspace snapshots** (`snap`) for saving and comparing workspace state.
81
+
82
+ ### Analysis Features
83
+ - Route and API change detection for SvelteKit, Next.js App Router, React Router,
84
+ Vue/Nuxt, and Astro.
85
+ - Dependency and package surface analysis (semver impact, exports, lockfile
86
+ mismatches).
87
+ - Environment variables, security-sensitive files, CI workflows, and
88
+ infrastructure changes.
89
+ - Migration safety checks (Supabase migrations and SQL risk patterns).
90
+
91
+ ### Agent Workflows
92
+ - **Delta mode** (`--since`) for comparing runs and tracking changes over time.
93
+ - **Stable IDs** for deterministic finding/flag references across runs.
94
+ - **Snapshot workflows** (`snap`) for saving and restoring workspace state.
95
+ - **Drill-down** (`zoom`) for detailed context on specific findings or flags.
96
+ - **AI assistant integration** (`integrate`) to generate provider rules for
97
+ Cursor, Claude, Jules, and OpenCode.
98
+
99
+ ## Documentation
100
+
101
+ Start with the docs index: [`docs/README.md`](docs/README.md). The `docs/`
102
+ folder is the source of truth for detailed technical documentation.
103
+
104
+ Key sections:
105
+
106
+ - Product overview and roadmap: [`docs/01-product/`](docs/01-product/)
107
+ - CLI commands and options: [`docs/05-cli/`](docs/05-cli/)
108
+ - Analyzer catalog: [`docs/03-analyzers/`](docs/03-analyzers/)
109
+ - Profiles and detection: [`docs/07-profiles/`](docs/07-profiles/)
110
+ - Rendering formats and risk scoring: [`docs/08-rendering/`](docs/08-rendering/)
111
+ - Stable IDs and traceability: [`docs/09-stable-ids/`](docs/09-stable-ids/)
112
+ - Snapshots: [`docs/10-snapshots/`](docs/10-snapshots/)
113
+ - Delta mode: [`docs/11-delta-mode/`](docs/11-delta-mode/)
114
+ - Development guides: [`docs/06-development/`](docs/06-development/)
115
+
116
+ See [`CHANGELOG.md`](CHANGELOG.md) for version history and release notes.
117
+
118
+ ## CLI Reference
119
+
120
+ ### Global behavior
121
+
122
+ - JSON outputs (`facts`, `risk-report --format json`, `dump-diff --format json`)
123
+ write diagnostics to stderr so stdout is parse-safe.
124
+ - `--quiet` suppresses non-fatal diagnostics; `--debug` enables timing and
125
+ detector logs.
126
+ - `DEBUG=1` prints stack traces for debugging.
127
+
128
+ ### Global flags
129
+
130
+ | Flag | Description |
131
+ |------|-------------|
132
+ | `--quiet` | Suppress non-fatal diagnostics (warnings, info) |
133
+ | `--debug` | Print debug diagnostics to stderr |
134
+
135
+ ### Diff modes
136
+
137
+ | Mode | Description | Git Command |
138
+ |------|-------------|-------------|
139
+ | `unstaged` | Working tree vs index + untracked files (default) | `git diff` + `git ls-files --others` |
140
+ | `branch` | Compare base ref to head ref | `git diff base..head` |
141
+ | `staged` | Index vs HEAD (staged changes) | `git diff --staged` |
142
+ | `all` | All changes vs HEAD (staged + unstaged + untracked) | `git diff HEAD` + `git ls-files --others` |
143
+
144
+ ### Profiles
145
+
146
+ Use `--profile <name>` to override auto-detection.
147
+
148
+ | Profile | Description | Auto-detect signals |
149
+ |---------|-------------|--------------------|
150
+ | `auto` | Default profile selection | Framework detection fallback |
151
+ | `sveltekit` | SvelteKit fullstack apps | `src/routes/` or `@sveltejs/kit` |
152
+ | `next` | Next.js App Router apps | `next` dependency + `app/` or `src/app/` |
153
+ | `react` | React apps using React Router | `react` + `react-router` |
154
+ | `vue` | Vue/Nuxt apps | `nuxt` or `vue` + `pages/` |
155
+ | `astro` | Astro projects | `astro` dependency or `astro.config.*` |
156
+ | `stencil` | StencilJS projects | `@stencil/core` or `stencil.config.*` |
157
+ | `library` | npm packages/libraries | `exports`, `publishConfig`, `bin`, `private: false` |
53
158
 
54
- # Show debug diagnostics on stderr (timings, detector counts, etc.)
55
- branch-narrator --debug risk-report
159
+ ### Commands
56
160
 
57
- # Combine flags (--quiet overrides --debug)
58
- branch-narrator --quiet --debug facts
161
+ #### pretty
162
+
163
+ Display a colorized summary of changes in the terminal.
164
+
165
+ ```bash
166
+ branch-narrator pretty [options]
59
167
  ```
60
168
 
61
- **Note:** In JSON mode (`facts`, `risk-report --format json`, `dump-diff --format json`), all diagnostic output goes to stderr to ensure stdout contains only valid JSON. This makes the output safe for piping to `jq` or other JSON parsers.
169
+ | Option | Default | Description |
170
+ |--------|---------|-------------|
171
+ | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
172
+ | `--base <ref>` | auto-detected | Base git reference (branch mode only) |
173
+ | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
174
+ | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `next`, `react`, `vue`, `astro`, `stencil`, `library` |
62
175
 
63
- ### Preview Changes (for Humans)
176
+ Examples:
64
177
 
65
178
  ```bash
66
- # Colorized summary of unstaged changes (default)
179
+ # Review unstaged changes (default)
67
180
  branch-narrator pretty
68
181
 
69
- # Compare specific branches
182
+ # Compare branches
70
183
  branch-narrator pretty --mode branch --base develop --head feature/auth
71
184
 
72
- # Review all uncommitted changes (staged + unstaged + untracked)
185
+ # Review all uncommitted changes
73
186
  branch-narrator pretty --mode all
74
187
  ```
75
188
 
76
- ### Generate PR Description
189
+ #### pr-body
190
+
191
+ Generate a raw Markdown PR description.
192
+
193
+ ```bash
194
+ branch-narrator pr-body [options]
195
+ ```
196
+
197
+ | Option | Default | Description |
198
+ |--------|---------|-------------|
199
+ | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
200
+ | `--base <ref>` | auto-detected | Base git reference (branch mode only) |
201
+ | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
202
+ | `-u, --uncommitted` | `false` | Deprecated: use `--mode unstaged` |
203
+ | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `next`, `react`, `vue`, `astro`, `stencil`, `library` |
204
+ | `--interactive` | `false` | Prompt for context and test notes |
205
+
206
+ Examples:
77
207
 
78
208
  ```bash
79
209
  # Analyze unstaged changes (default)
80
210
  branch-narrator pr-body
81
211
 
82
212
  # Compare branches for PR
83
- branch-narrator pr-body --mode branch --base develop --head feature/my-feature
213
+ branch-narrator pr-body --mode branch --base develop --head feature/auth
84
214
 
85
215
  # Interactive mode (prompts for context)
86
216
  branch-narrator pr-body --interactive
217
+ ```
87
218
 
88
- # Pipe to clipboard (macOS)
89
- branch-narrator pr-body | pbcopy
219
+ #### facts
220
+
221
+ Output JSON findings for programmatic use.
222
+
223
+ ```bash
224
+ branch-narrator facts [options]
90
225
  ```
91
226
 
92
- ### Generate JSON Facts (Agent-Grade)
227
+ | Option | Default | Description |
228
+ |--------|---------|-------------|
229
+ | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
230
+ | `--base <ref>` | auto-detected | Base git reference (branch mode only) |
231
+ | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
232
+ | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `next`, `react`, `vue`, `astro`, `stencil`, `library` |
233
+ | `--format <type>` | `json` | Output format: `json`, `sarif` |
234
+ | `--pretty` | `false` | Pretty-print JSON with 2-space indentation |
235
+ | `--redact` | `false` | Redact obvious secrets in evidence |
236
+ | `--exclude <glob>` | (none) | Exclude files matching glob (repeatable) |
237
+ | `--include <glob>` | (none) | Include only files matching glob (repeatable) |
238
+ | `--max-file-bytes <n>` | `1048576` | Max file size to analyze |
239
+ | `--max-diff-bytes <n>` | `5242880` | Max diff size to analyze |
240
+ | `--max-findings <n>` | (none) | Max findings to include |
241
+ | `--out <path>` | (stdout) | Write output to file |
242
+ | `--no-timestamp` | `false` | Omit `generatedAt` for deterministic output |
243
+ | `--since <path>` | (none) | Compare current output to a previous JSON file |
244
+ | `--since-strict` | `false` | Exit with code 1 on scope mismatch |
245
+ | `--test-parity` | `false` | Enable test parity checks |
246
+
247
+ Examples:
93
248
 
94
249
  ```bash
95
250
  # Analyze unstaged changes (default)
@@ -101,620 +256,390 @@ branch-narrator facts --mode branch --base develop --head feature/auth
101
256
  # Pretty-printed JSON
102
257
  branch-narrator facts --pretty
103
258
 
104
- # Redact secrets in evidence excerpts
105
- branch-narrator facts --redact
106
-
107
- # Limit output
108
- branch-narrator facts --max-findings 50
109
-
110
- # Filter files
111
- branch-narrator facts --exclude "**/test/**" --include "src/**"
112
-
113
- # Parse with jq
114
- branch-narrator facts | jq '.risk.level'
115
- branch-narrator facts | jq '.categories[] | select(.id == "database")'
116
- branch-narrator facts | jq '.actions[] | select(.blocking == true)'
259
+ # SARIF output for code scanning
260
+ branch-narrator facts --format sarif --out branch-narrator.sarif
117
261
 
118
- # Delta mode: compare to previous run
262
+ # Delta mode
119
263
  branch-narrator facts --out .ai/baseline.json
120
- # ... make changes ...
121
264
  branch-narrator facts --since .ai/baseline.json --pretty
122
265
  ```
123
266
 
124
- ### Generate SARIF Output (for CI/Code Scanning)
267
+ SARIF output details (rule mappings, schema, limitations) are documented in
268
+ [`docs/08-rendering/sarif.md`](docs/08-rendering/sarif.md).
269
+ Delta mode details are documented in
270
+ [`docs/11-delta-mode/11-delta-mode.md`](docs/11-delta-mode/11-delta-mode.md).
125
271
 
126
- [SARIF (Static Analysis Results Interchange Format)](https://sarifweb.azurewebsites.net/) is a standardized JSON format for static analysis tools. Use `--format sarif` to output findings in a format compatible with GitHub Code Scanning and other SARIF consumers.
272
+ #### dump-diff
127
273
 
128
- ```bash
129
- # Generate SARIF output for GitHub Code Scanning
130
- branch-narrator facts --mode branch --base main --head HEAD --format sarif
131
-
132
- # Save to file for upload
133
- branch-narrator facts --format sarif --out branch-narrator.sarif
274
+ Output a prompt-ready git diff with smart exclusions.
134
275
 
135
- # Pretty-printed SARIF
136
- branch-narrator facts --format sarif --pretty
276
+ ```bash
277
+ branch-narrator dump-diff [options]
137
278
  ```
138
279
 
139
- For detailed technical documentation on the SARIF renderer—including the output schema, rule mappings (BNR001–BNR006), how line number tracking works, and known limitations—see [`docs/08-rendering/sarif.md`](docs/08-rendering/sarif.md).
140
-
141
- **SARIF Rule Mapping:**
280
+ | Option | Default | Description |
281
+ |--------|---------|-------------|
282
+ | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
283
+ | `--base <ref>` | auto-detected | Base git reference (branch mode only) |
284
+ | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
285
+ | `--no-untracked` | (off) | Exclude untracked files (non-branch modes) |
286
+ | `--out <path>` | stdout | Write output to file |
287
+ | `--format <type>` | `text` | Output format: `text`, `md`, `json` |
288
+ | `--unified <n>` | `0` | Lines of unified context |
289
+ | `--include <glob>` | (none) | Include only matching files (repeatable) |
290
+ | `--exclude <glob>` | (none) | Additional exclusion globs |
291
+ | `--max-chars <n>` | (none) | Chunk output if it exceeds this size |
292
+ | `--chunk-dir <path>` | `.ai/diff-chunks` | Directory for chunk files |
293
+ | `--name <prefix>` | `diff` | Chunk file name prefix |
294
+ | `--dry-run` | `false` | Preview what would be included/excluded |
295
+ | `--name-only` | `false` | Output only file list (no diff content) |
296
+ | `--stat` | `false` | Output file statistics |
297
+ | `--patch-for <path>` | (none) | Output diff for a specific file only |
298
+ | `--pretty` | `false` | Pretty-print JSON with 2-space indentation |
299
+ | `--no-timestamp` | `false` | Omit `generatedAt` for deterministic output |
142
300
 
143
- The following findings are mapped to stable SARIF rules:
301
+ Notes:
144
302
 
145
- - **BNR001**: Dangerous SQL in migration (DROP, TRUNCATE, ALTER TYPE, etc.) - `error`
146
- - **BNR002**: Non-destructive migration changed - `warning`
147
- - **BNR003**: Major version bump in critical dependencies (@sveltejs/kit, svelte, vite, react, next) - `warning`
148
- - **BNR004**: New environment variable reference detected - `warning`
149
- - **BNR005**: Cloudflare configuration changed - `note`
150
- - **BNR006**: API endpoint changed (added/modified/deleted) - `note`
303
+ - `--name-only`, `--stat`, and `--patch-for` are mutually exclusive.
304
+ - Default exclusions include lockfiles, build artifacts, sourcemaps, and
305
+ minified files (see docs for the full list).
151
306
 
152
- **GitHub Actions Example:**
307
+ Examples:
153
308
 
154
- ```yaml
155
- name: Code Scanning
309
+ ```bash
310
+ # Output unstaged changes to stdout (default)
311
+ branch-narrator dump-diff
156
312
 
157
- on:
158
- pull_request:
159
- branches: [main]
313
+ # Compare branches for PR
314
+ branch-narrator dump-diff --mode branch --base main --head feature/auth --out .ai/diff.txt
160
315
 
161
- jobs:
162
- analyze:
163
- runs-on: ubuntu-latest
164
- permissions:
165
- security-events: write
166
- contents: read
316
+ # Chunk large diffs
317
+ branch-narrator dump-diff --max-chars 25000 --chunk-dir .ai/diff-chunks
167
318
 
168
- steps:
169
- - uses: actions/checkout@v4
170
- with:
171
- fetch-depth: 0 # Fetch full history for diff analysis
319
+ # JSON output with metadata
320
+ branch-narrator dump-diff --format json --pretty --out .ai/diff.json
321
+ ```
172
322
 
173
- - name: Install branch-narrator
174
- run: npm install -g @better-vibe/branch-narrator
323
+ #### risk-report
175
324
 
176
- - name: Generate SARIF
177
- run: |
178
- branch-narrator facts \
179
- --mode branch \
180
- --base ${{ github.event.pull_request.base.sha }} \
181
- --head ${{ github.event.pull_request.head.sha }} \
182
- --format sarif \
183
- --out branch-narrator.sarif
325
+ Analyze diffs and emit a risk score with evidence-backed flags.
184
326
 
185
- - name: Upload SARIF to GitHub
186
- uses: github/codeql-action/upload-sarif@v3
187
- with:
188
- sarif_file: branch-narrator.sarif
189
- category: branch-narrator
327
+ ```bash
328
+ branch-narrator risk-report [options]
190
329
  ```
191
330
 
192
- **Limitations:**
193
- - SARIF output is deterministic and based on heuristics only (no LLM calls)
194
- - Line numbers are included when evidence is based on added diff lines
195
- - Not all finding types are mapped to SARIF rules (see mapping above for covered types)
196
- - No autofix suggestions in MVP (SARIF `fixes` field not populated)
331
+ | Option | Default | Description |
332
+ |--------|---------|-------------|
333
+ | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
334
+ | `--base <ref>` | auto-detected | Base git reference (branch mode only) |
335
+ | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
336
+ | `--format <type>` | `json` | Output format: `json`, `md`, `text` |
337
+ | `--out <path>` | (stdout) | Write output to file |
338
+ | `--fail-on-score <n>` | (none) | Exit with code 2 if risk score >= threshold |
339
+ | `--only <categories>` | (all) | Only include these categories (comma-separated) |
340
+ | `--exclude <categories>` | (none) | Exclude these categories (comma-separated) |
341
+ | `--max-evidence-lines <n>` | `5` | Max evidence lines per flag |
342
+ | `--redact` | `false` | Redact secret values in evidence |
343
+ | `--explain-score` | `false` | Include score breakdown |
344
+ | `--pretty` | `false` | Pretty-print JSON with 2-space indentation |
345
+ | `--no-timestamp` | `false` | Omit `generatedAt` for deterministic output |
346
+ | `--since <path>` | (none) | Compare current output to a previous JSON file |
347
+ | `--since-strict` | `false` | Exit with code 1 on scope mismatch |
348
+ | `--test-parity` | `false` | Enable test parity checks |
349
+
350
+ Risk levels:
351
+
352
+ - `low` (0-20)
353
+ - `moderate` (21-40)
354
+ - `elevated` (41-60)
355
+ - `high` (61-80)
356
+ - `critical` (81-100)
197
357
 
198
- ### Risk Report (General-Purpose Security & Quality Analysis)
358
+ Examples:
199
359
 
200
360
  ```bash
201
361
  # Analyze unstaged changes (default)
202
362
  branch-narrator risk-report
203
363
 
204
- # Compare branches for PR
205
- branch-narrator risk-report --mode branch --base develop --head feature/auth
206
-
207
364
  # Markdown format for human review
208
365
  branch-narrator risk-report --format md
209
366
 
210
- # Text format for terminal
211
- branch-narrator risk-report --format text
212
-
213
367
  # Fail CI if risk score >= threshold
214
368
  branch-narrator risk-report --fail-on-score 50
215
369
 
216
- # Focus on specific categories
217
- branch-narrator risk-report --only security,deps,db
218
-
219
- # Exclude certain categories
220
- branch-narrator risk-report --exclude tests,churn
221
-
222
- # Show score breakdown
223
- branch-narrator risk-report --explain-score
224
-
225
- # Redact secrets in evidence
226
- branch-narrator risk-report --redact
227
-
228
- # Limit evidence lines per flag
229
- branch-narrator risk-report --max-evidence-lines 3
230
-
231
- # Write to file
232
- branch-narrator risk-report --format md --out .ai/risk-report.md
233
-
234
- # Parse with jq
235
- branch-narrator risk-report | jq '.riskScore'
236
- branch-narrator risk-report | jq '.flags[] | select(.category == "security")'
237
- branch-narrator risk-report | jq '.categoryScores.db'
238
-
239
- # Delta mode: track risk improvement
370
+ # Delta mode
240
371
  branch-narrator risk-report --out .ai/baseline-risk.json
241
- # ... make changes ...
242
372
  branch-narrator risk-report --since .ai/baseline-risk.json --pretty
243
- # Shows: risk score change, added/removed/changed flags
244
- ```
245
-
246
- **Risk Categories:**
247
- - `security`: Workflow permissions, pull_request_target, remote script execution
248
- - `ci`: CI/CD pipeline configuration changes
249
- - `deps`: New dependencies, major version bumps, lockfile inconsistencies
250
- - `db`: Database migrations, destructive SQL, schema changes
251
- - `infra`: Dockerfile, Terraform, Kubernetes manifests
252
- - `api`: OpenAPI, GraphQL, Protocol Buffer schema changes
253
- - `tests`: Test coverage gaps, test file changes
254
- - `churn`: Large changesets (>50 files or >1500 lines)
255
-
256
- **Risk Levels:** (based on 0-100 score)
257
- - `low` (0-20): Minimal risk, safe to merge
258
- - `moderate` (21-40): Some risk, review recommended
259
- - `elevated` (41-60): Moderate risk, careful review needed
260
- - `high` (61-80): High risk, thorough review required
261
- - `critical` (81-100): Critical risk, requires security review
262
-
263
- **Output Schema (v1.0):**
264
- - `schemaVersion`: Schema version identifier
265
- - `generatedAt`: ISO timestamp
266
- - `git`: Git metadata (base, head, range, isDirty)
267
- - `profile`: Detected project profile with confidence
268
- - `stats`: File change statistics
269
- - `filters`: Applied filtering configuration
270
- - `summary`: High-level summary with highlights
271
- - `categories`: Findings aggregated by category with risk weights
272
- - `risk`: Structured risk score with factors and evidence
273
- - `findings`: Detailed findings array (typed discriminated union)
274
- - `actions`: Actionable recommendations (blocking/non-blocking)
275
- - `skippedFiles`: Files excluded from analysis with reasons
276
- - `warnings`: Any warnings encountered during analysis
277
-
278
- **Example categories output:**
279
- ```json
280
- {
281
- "categories": [
282
- {
283
- "id": "database",
284
- "count": 2,
285
- "riskWeight": 45,
286
- "topEvidence": [
287
- {
288
- "file": "supabase/migrations/002_users.sql",
289
- "excerpt": "DROP TABLE IF EXISTS old_users;"
290
- }
291
- ]
292
- }
293
- ]
294
- }
295
373
  ```
296
374
 
297
- ### Dump Diff for AI Agents
298
-
299
- ```bash
300
- # Output unstaged changes (default)
301
- branch-narrator dump-diff
302
-
303
- # Write to file
304
- branch-narrator dump-diff --out .ai/diff.txt
305
-
306
- # Compare branches for PR
307
- branch-narrator dump-diff --mode branch --base main --head feature/auth --out .ai/diff.txt
308
-
309
- # Staged changes only (index vs HEAD)
310
- branch-narrator dump-diff --mode staged --format md --out .ai/staged.md
311
-
312
- # All changes since HEAD (staged + unstaged + untracked)
313
- branch-narrator dump-diff --mode all --out .ai/all-changes.txt
375
+ Risk scoring details are documented in
376
+ [`docs/08-rendering/risk-scoring.md`](docs/08-rendering/risk-scoring.md).
314
377
 
315
- # Exclude untracked files
316
- branch-narrator dump-diff --mode all --no-untracked --out .ai/diff.txt
378
+ #### zoom
317
379
 
318
- # Chunk large diffs for context windows
319
- branch-narrator dump-diff --max-chars 25000 --chunk-dir .ai/diff-chunks
320
-
321
- # JSON format with metadata
322
- branch-narrator dump-diff --format json --out .ai/diff.json
380
+ Zoom into a specific finding or risk flag for detailed context.
323
381
 
324
- # Include only specific files
325
- branch-narrator dump-diff --include "src/**" --include "tests/**"
382
+ ```bash
383
+ branch-narrator zoom [options]
326
384
  ```
327
385
 
328
- ### Zoom Command
386
+ | Option | Default | Description |
387
+ |--------|---------|-------------|
388
+ | `--finding <id>` | (none) | Finding ID to zoom into |
389
+ | `--flag <id>` | (none) | Flag ID to zoom into |
390
+ | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
391
+ | `--base <ref>` | auto-detected | Base git reference (branch mode only) |
392
+ | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
393
+ | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `next`, `react`, `vue`, `astro`, `stencil`, `library` |
394
+ | `--format <type>` | `json` | Output format: `json`, `md`, `text` |
395
+ | `--unified <n>` | `3` | Lines of unified context |
396
+ | `--no-patch` | `false` | Exclude patch context (evidence only) |
397
+ | `--max-evidence-lines <n>` | `8` | Max evidence excerpt lines |
398
+ | `--redact` | `false` | Redact obvious secret values |
399
+ | `--out <path>` | stdout | Write output to file |
400
+ | `--pretty` | `false` | Pretty-print JSON with 2-space indentation |
401
+ | `--no-timestamp` | `false` | Omit `generatedAt` for deterministic output |
329
402
 
330
- Drill down into a specific finding or risk flag to get detailed, isolated context. Useful for AI agents to verify specific issues or changes without processing the entire diff.
403
+ Examples:
331
404
 
332
405
  ```bash
333
- # Zoom into a specific finding by ID (from 'facts' output)
334
- branch-narrator zoom --finding finding-123
335
-
336
- # Zoom into a risk flag by ID (from 'risk-report' output)
337
- branch-narrator zoom --flag flag-456
338
-
339
- # Output as Markdown (default is markdown, can be json or text)
340
- branch-narrator zoom --finding finding-123 --format md
406
+ # Zoom into a finding
407
+ branch-narrator zoom --finding finding.env-var#abc123
341
408
 
342
- # Get JSON output for machine parsing
343
- branch-narrator zoom --flag flag-456 --format json --pretty
409
+ # Zoom into a risk flag
410
+ branch-narrator zoom --flag flag.db.destructive_sql#def456 --format md
344
411
 
345
- # Exclude patch context (show only evidence metadata)
346
- branch-narrator zoom --finding finding-123 --no-patch
347
-
348
- # Adjust context lines
349
- branch-narrator zoom --finding finding-123 --unified 5
412
+ # Zoom without patch context
413
+ branch-narrator zoom --finding finding.dependency-change#c0ffee --no-patch
350
414
  ```
351
415
 
352
- ### AI Agent Integration
416
+ #### integrate
353
417
 
354
- Generate provider-specific rules for AI coding assistants (Cursor, Jules, etc.).
418
+ Generate provider-specific rules for AI coding assistants.
355
419
 
356
420
  ```bash
357
- # Generate Cursor rules
358
- branch-narrator integrate cursor
359
-
360
- # Generate Jules rules
361
- branch-narrator integrate jules
362
-
363
- # Preview what would be created without writing files
364
- branch-narrator integrate cursor --dry-run
365
-
366
- # Overwrite existing rule files
367
- branch-narrator integrate cursor --force
421
+ branch-narrator integrate [target] [options]
368
422
  ```
369
423
 
370
- **What it does:**
371
- - Creates provider-specific rule files (e.g., `.cursor/rules/branch-narrator.md`)
372
- - Instructs the AI on when and how to use `branch-narrator` commands
373
- - Provides consistent workflows for PR descriptions and analysis
374
-
375
- **Why use this:**
376
- - AI assistants will automatically read these rules when working in your repository
377
- - Ensures the AI uses branch-narrator to ground PR descriptions in actual git diffs instead of guessing
378
- - Provides consistent PR description templates across your team
379
-
380
- **Exit codes:**
381
- - `0`: Success
382
- - `1`: Expected failure (unknown target, files exist without --force, etc.)
383
-
384
- ## CLI Commands
385
-
386
- ### `pretty` Command
387
-
388
- Display a colorized summary of changes in the terminal.
424
+ Options:
389
425
 
390
426
  | Option | Default | Description |
391
427
  |--------|---------|-------------|
392
- | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
393
- | `--base <ref>` | auto-detected | Base git reference (branch mode only; auto-detected from remote HEAD, falls back to `main`) |
394
- | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
395
- | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `stencil`, `next`, or `react` |
396
-
397
- ### `pr-body` Command
398
-
399
- Generate a raw Markdown PR description.
400
-
401
- | Option | Default | Description |
402
- |--------|---------|-------------|
403
- | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
404
- | `--base <ref>` | auto-detected | Base git reference (branch mode only; auto-detected from remote HEAD, falls back to `main`) |
405
- | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
406
- | `-u, --uncommitted` | `false` | **[DEPRECATED]** Use `--mode unstaged` instead |
407
- | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `stencil`, `next`, or `react` |
408
- | `--interactive` | `false` | Prompt for additional context |
428
+ | `--dry-run` | `false` | Preview without writing files |
429
+ | `--force` | `false` | Overwrite existing files |
409
430
 
410
- ### `facts` Command
431
+ Targets:
411
432
 
412
- Output JSON findings for programmatic use.
433
+ - `cursor` -> `.cursor/rules/branch-narrator.md` and `.cursor/rules/pr-description.md`
434
+ - `jules` -> `AGENTS.md`
435
+ - `claude` -> `CLAUDE.md`
436
+ - `jules-rules` -> `.jules/rules/branch-narrator.md`
437
+ - `opencode` -> `OPENCODE.md` / `.opencode/branch-narrator.md`
413
438
 
414
- | Option | Default | Description |
415
- |--------|---------|-------------|
416
- | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
417
- | `--base <ref>` | auto-detected | Base git reference (branch mode only; auto-detected from remote HEAD, falls back to `main`) |
418
- | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
419
- | `--profile <name>` | `auto` | Profile: `auto`, `sveltekit`, `stencil`, `next`, or `react` |
439
+ When `target` is omitted, `integrate` auto-detects existing guide locations and
440
+ applies matching integrations.
420
441
 
421
- ### `dump-diff` Command
442
+ Examples:
422
443
 
423
- Output prompt-ready git diff with smart exclusions. Designed for AI agents.
444
+ ```bash
445
+ branch-narrator integrate cursor
446
+ branch-narrator integrate --dry-run
447
+ branch-narrator integrate opencode --force
448
+ ```
424
449
 
425
- | Option | Default | Description |
426
- |--------|---------|-------------|
427
- | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
428
- | `--base <ref>` | auto-detected | Base git reference (branch mode only; auto-detected from remote HEAD, falls back to `main`) |
429
- | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
430
- | `--no-untracked` | (off) | Exclude untracked files (non-branch modes) |
431
- | `--out <path>` | stdout | Write output to file |
432
- | `--format <type>` | `text` | Format: `text`, `md`, or `json` |
433
- | `--unified <n>` | `0` | Lines of unified context |
434
- | `--include <glob>` | (none) | Include only matching files |
435
- | `--exclude <glob>` | (none) | Additional exclusion globs |
436
- | `--max-chars <n>` | (none) | Chunk if output exceeds size |
437
- | `--chunk-dir <path>` | `.ai/diff-chunks` | Directory for chunks |
438
- | `--name <prefix>` | `diff` | Chunk file prefix |
439
- | `--dry-run` | `false` | Preview without writing |
450
+ #### snap
440
451
 
441
- **Modes:**
442
- - `unstaged` (default): Working tree vs index (uncommitted changes)
443
- - `branch`: Compare `--base` to `--head` refs
444
- - `staged`: Index vs HEAD (staged changes)
445
- - `all`: Working tree vs HEAD (all uncommitted changes)
452
+ Manage local workspace snapshots.
446
453
 
447
- **Default exclusions:** lockfiles, `.d.ts`, logs, `dist/`, `build/`, `.svelte-kit/`, `.next/`, minified files, sourcemaps, binaries.
454
+ ```bash
455
+ branch-narrator snap <subcommand> [options]
456
+ ```
448
457
 
449
- ### `integrate` Command
458
+ Subcommands:
450
459
 
451
- Generate provider-specific rules for AI coding assistants.
460
+ - `snap save [label]` -- Save a snapshot.
461
+ - Options: `--out <path>`
462
+ - `snap list` -- List snapshots.
463
+ - Options: `--pretty`
464
+ - `snap show <snapshotId>` -- Show snapshot details.
465
+ - Options: `--pretty`
466
+ - `snap diff <idA> <idB>` -- Compare two snapshots.
467
+ - Options: `--pretty`
468
+ - `snap restore <snapshotId>` -- Restore workspace to a snapshot.
452
469
 
453
- | Option | Default | Description |
454
- |--------|---------|-------------|
455
- | `<target>` | (required) | Integration target: `cursor`, `jules` |
456
- | `--dry-run` | `false` | Preview what would be written without creating files |
457
- | `--force` | `false` | Overwrite existing files |
470
+ Snapshots are stored under `.branch-narrator/`. Add it to `.gitignore` to keep
471
+ snapshots local.
458
472
 
459
- **Supported targets:**
460
- - `cursor`: Generates `.cursor/rules/branch-narrator.md` and `.cursor/rules/pr-description.md`
461
- - `jules`: Generates `AGENTS.md` in the repository root with Branch Narrator rules for Jules
473
+ Examples:
462
474
 
463
- **Behavior:**
464
- - Creates rules directory if it doesn't exist
465
- - Fails with exit code 1 if files already exist (use `--force` to overwrite)
466
- - Outputs exact file paths and contents in `--dry-run` mode
475
+ ```bash
476
+ # Save a snapshot
477
+ branch-narrator snap save "before-refactor"
467
478
 
468
- ### `risk-report` Command
479
+ # Compare two snapshots
480
+ branch-narrator snap diff abc123def456 def456abc789 --pretty
481
+ ```
469
482
 
470
- Analyze git diff and emit a risk score (0-100) with evidence-backed flags. Framework-agnostic security and quality analysis.
483
+ ### Exit Codes
471
484
 
472
- | Option | Default | Description |
473
- |--------|---------|-------------|
474
- | `--mode <type>` | `unstaged` | Diff mode: `branch`, `unstaged`, `staged`, `all` |
475
- | `--base <ref>` | auto-detected | Base git reference (branch mode only; auto-detected from remote HEAD, falls back to `main`) |
476
- | `--head <ref>` | `HEAD` | Head git reference (branch mode only) |
477
- | `--format <type>` | `json` | Output format: `json`, `md`, or `text` |
478
- | `--out <path>` | stdout | Write output to file |
479
- | `--fail-on-score <n>` | (none) | Exit with code 2 if risk score >= threshold |
480
- | `--only <categories>` | (none) | Only include these categories (comma-separated) |
481
- | `--exclude <categories>` | (none) | Exclude these categories (comma-separated) |
482
- | `--max-evidence-lines <n>` | `5` | Max evidence lines per flag |
483
- | `--redact` | `false` | Redact secret values in evidence |
484
- | `--explain-score` | `false` | Include score breakdown in output |
485
-
486
- **Output Schema (v1.0):**
487
- - `schemaVersion`: "1.0"
488
- - `range`: { base, head }
489
- - `riskScore`: 0-100 computed score
490
- - `riskLevel`: "low" | "moderate" | "elevated" | "high" | "critical"
491
- - `categoryScores`: Scores per category (0-100)
492
- - `flags`: Array of risk flags with evidence
493
- - `skippedFiles`: Files excluded from analysis
494
- - `scoreBreakdown`: (optional) Score computation details
495
-
496
- **Exit Codes:**
497
485
  | Code | Description |
498
486
  |------|-------------|
499
487
  | `0` | Success |
500
- | `1` | Expected errors (not a git repo, invalid refs, etc.) |
501
- | `2` | Risk score >= `--fail-on-score` threshold |
502
-
503
- ### `zoom` Command
504
-
505
- Zoom into a specific finding or flag for detailed context.
488
+ | `1` | Expected failures (not a git repo, invalid refs) |
489
+ | `2` | Risk score threshold exceeded (`risk-report --fail-on-score`) |
506
490
 
507
- | Option | Default | Description |
508
- |--------|---------|-------------|
509
- | `--finding <id>` | (optional) | Finding ID to zoom into (mutually exclusive with `--flag`) |
510
- | `--flag <id>` | (optional) | Flag ID to zoom into (mutually exclusive with `--finding`) |
511
- | `--format <type>` | `md` | Output format: `json`, `md`, `text` |
512
- | `--no-patch` | `false` | Exclude patch context, only show evidence |
513
- | `--unified <n>` | `3` | Lines of unified context for patch hunks |
514
- | `--max-evidence-lines <n>` | `8` | Max evidence excerpt lines to show |
515
- | `--redact` | `false` | Redact obvious secret values |
516
- | `--out <path>` | stdout | Write output to file |
491
+ ## CI/CD Integration
517
492
 
518
- ## Sample Output
493
+ ### GitHub Actions with SARIF
519
494
 
520
- ### Markdown PR Body
495
+ Upload findings to GitHub Code Scanning:
521
496
 
522
- ```markdown
523
- ## Summary
497
+ ```yaml
498
+ name: Code Analysis
524
499
 
525
- - 5 file(s) changed
526
- - 2 file(s) added
527
- - 1 new route(s)
528
- - Database migrations detected
500
+ on:
501
+ pull_request:
502
+ branches: [main]
529
503
 
530
- ## Routes / API
504
+ jobs:
505
+ analyze:
506
+ runs-on: ubuntu-latest
507
+ steps:
508
+ - uses: actions/checkout@v4
509
+ with:
510
+ fetch-depth: 0
531
511
 
532
- | Route | Type | Change | Methods |
533
- |-------|------|--------|---------|
534
- | `/dashboard` | page | added | - |
535
- | `/api/users` | endpoint | added | GET, POST |
512
+ - name: Setup Node
513
+ uses: actions/setup-node@v4
514
+ with:
515
+ node-version: "20"
536
516
 
537
- ## Database (Supabase)
517
+ - name: Install branch-narrator
518
+ run: npm install -g @better-vibe/branch-narrator
538
519
 
539
- **Risk Level:** 🟡 MEDIUM
520
+ - name: Generate SARIF report
521
+ run: branch-narrator facts --mode branch --base origin/main --format sarif --out results.sarif
540
522
 
541
- **Files:**
542
- - `supabase/migrations/20240101_add_users.sql`
523
+ - name: Upload SARIF to GitHub
524
+ uses: github/codeql-action/upload-sarif@v3
525
+ with:
526
+ sarif_file: results.sarif
527
+ ```
543
528
 
544
- ## Config / Env
529
+ ### Risk Gate
545
530
 
546
- | Variable | Status | Evidence |
547
- |----------|--------|----------|
548
- | `PUBLIC_API_URL` | added | src/lib/config.ts |
549
- | `DATABASE_URL` | added | src/hooks.server.ts |
531
+ Fail CI if risk score exceeds threshold:
550
532
 
551
- ## Dependencies
533
+ ```yaml
534
+ - name: Check risk score
535
+ run: branch-narrator risk-report --mode branch --base origin/main --fail-on-score 60
536
+ ```
552
537
 
553
- ### Production
538
+ ## Programmatic API
554
539
 
555
- | Package | From | To | Impact |
556
- |---------|------|-----|--------|
557
- | `@sveltejs/kit` | ^1.0.0 | ^2.0.0 | major |
540
+ Use branch-narrator as a library for custom integrations:
558
541
 
559
- ## Suggested Test Plan
542
+ ```typescript
543
+ import {
544
+ collectChangeSet,
545
+ getProfile,
546
+ resolveProfileName,
547
+ runAnalyzersInParallel,
548
+ computeRiskScore,
549
+ } from "@better-vibe/branch-narrator";
560
550
 
561
- - [ ] `bun run test` - Run test suite
562
- - [ ] `bun run check` - Run SvelteKit type check
563
- - [ ] Test `GET/POST /api/users` endpoint
564
- - [ ] Verify `/dashboard` page renders correctly
551
+ // Collect git changes
552
+ const changeSet = await collectChangeSet({
553
+ mode: "branch",
554
+ base: "main",
555
+ head: "HEAD",
556
+ });
565
557
 
566
- ## Risks / Notes
558
+ // Resolve and run profile analyzers
559
+ const profileName = resolveProfileName("auto", changeSet, process.cwd());
560
+ const profile = getProfile(profileName);
561
+ const findings = await runAnalyzersInParallel(profile.analyzers, changeSet);
567
562
 
568
- **Overall Risk:** 🟡 MEDIUM (score: 35/100)
563
+ // Compute risk
564
+ const riskScore = computeRiskScore(findings);
569
565
 
570
- - ⚠️ Major version bump: @sveltejs/kit ^1.0.0 → ^2.0.0
571
- - ℹ️ New env var: PUBLIC_API_URL
566
+ console.log(`Risk: ${riskScore.level} (${riskScore.score}/100)`);
567
+ console.log(`Findings: ${findings.length}`);
572
568
  ```
573
569
 
574
- ### JSON Facts
570
+ ## Example Output
571
+
572
+ Sample `facts` output (truncated):
575
573
 
576
574
  ```json
577
575
  {
578
- "profile": "sveltekit",
579
- "riskScore": {
576
+ "schemaVersion": "2.1",
577
+ "git": {
578
+ "base": "main",
579
+ "head": "HEAD",
580
+ "range": "main..HEAD",
581
+ "mode": "branch"
582
+ },
583
+ "profile": {
584
+ "requested": "auto",
585
+ "detected": "sveltekit",
586
+ "confidence": "high"
587
+ },
588
+ "stats": {
589
+ "filesChanged": 12,
590
+ "insertions": 245,
591
+ "deletions": 89
592
+ },
593
+ "risk": {
580
594
  "score": 35,
581
- "level": "medium",
582
- "evidenceBullets": [
583
- "⚠️ Major version bump: @sveltejs/kit ^1.0.0 → ^2.0.0"
595
+ "level": "moderate",
596
+ "factors": [
597
+ { "category": "routes", "weight": 15 },
598
+ { "category": "dependencies", "weight": 10 },
599
+ { "category": "config", "weight": 10 }
584
600
  ]
585
601
  },
586
602
  "findings": [
587
- {
588
- "type": "file-summary",
589
- "added": ["src/routes/dashboard/+page.svelte"],
590
- "modified": ["package.json"],
591
- "deleted": [],
592
- "renamed": []
593
- },
594
603
  {
595
604
  "type": "route-change",
596
- "routeId": "/dashboard",
597
- "file": "src/routes/dashboard/+page.svelte",
605
+ "findingId": "finding.route-change#a1b2c3d4",
606
+ "route": "/api/users",
598
607
  "change": "added",
599
- "routeType": "page"
600
- },
601
- {
602
- "type": "dependency-change",
603
- "name": "@sveltejs/kit",
604
- "section": "dependencies",
605
- "from": "^1.0.0",
606
- "to": "^2.0.0",
607
- "impact": "major"
608
+ "methods": ["GET", "POST"],
609
+ "evidence": [...]
608
610
  }
609
611
  ]
610
612
  }
611
613
  ```
612
614
 
613
- ## Analyzers
614
-
615
- ### Route Detector
616
-
617
- Detects changes under `src/routes/**`:
618
-
619
- - Maps filesystem paths to SvelteKit route IDs
620
- - Identifies page, layout, endpoint, and error types
621
- - Extracts HTTP methods from endpoint exports
622
- - Preserves param notation (`[slug]`, `[[id]]`, `[...rest]`)
623
-
624
- ### Supabase Migration Detector
625
-
626
- Scans `supabase/migrations/*.sql` for:
627
-
628
- - **High risk**: `DROP TABLE`, `DROP COLUMN`, `TRUNCATE`, `ALTER TYPE`, `DELETE` without `WHERE`
629
- - **Medium risk**: Migrations without destructive patterns
630
- - **Low risk**: Only seed/config files changed
631
-
632
- ### Environment Variable Detector
633
-
634
- Extracts env vars from:
615
+ See [`docs/04-types/findings.md`](docs/04-types/findings.md) for the complete
616
+ schema and all finding types.
635
617
 
636
- - `process.env.VAR_NAME`
637
- - `PUBLIC_*` patterns
638
- - SvelteKit `$env/static/public` imports
639
- - SvelteKit `$env/static/private` imports
640
-
641
- ### Cloudflare Detector
642
-
643
- Detects:
644
-
645
- - `wrangler.toml` / `wrangler.json` changes
646
- - GitHub workflow changes mentioning Cloudflare/wrangler
647
-
648
- ### Vitest Detector
649
-
650
- Detects:
651
-
652
- - `*.test.ts`, `*.spec.ts` files
653
- - `tests/` directory changes
654
- - `vitest.config.*` changes
655
-
656
- ### Dependency Analyzer
657
-
658
- Compares `package.json`:
659
-
660
- - Additions, removals, and version bumps
661
- - Semver impact classification (major/minor/patch)
662
- - Risk flags for critical package major bumps
663
-
664
- ## Profiles
665
-
666
- ### Auto Detection
667
-
668
- When `--profile auto` (default), the profile is detected by:
669
-
670
- 1. **SvelteKit**: Checking for `src/routes` directory or `@sveltejs/kit` in package.json
671
- 2. **React**: Checking for `react`, `react-dom`, and `react-router-dom` in package.json (only when Next.js is not detected)
672
- 3. **Default**: Generic profile for all other projects
673
-
674
- ### SvelteKit Profile
675
-
676
- Runs all analyzers optimized for SvelteKit projects, including:
677
- - SvelteKit route detection (`src/routes/`)
678
- - SvelteKit env var patterns (`$env/static/public`, `$env/static/private`)
679
-
680
- ### React Profile
681
-
682
- Runs all analyzers optimized for React projects, including:
683
- - React Router route detection (JSX `<Route>` components and data routers)
684
- - Vite env var patterns (`import.meta.env.VITE_*`)
685
- - React App env var patterns (`process.env.REACT_APP_*`)
686
-
687
- **Note**: React Router detection requires `react-router` or `react-router-dom` in package.json.
688
-
689
- ## Exit Codes
618
+ ## Development
690
619
 
691
- | Code | Description |
692
- |------|-------------|
693
- | `0` | Success |
694
- | `1` | Expected failures (not a git repo, invalid refs, etc.) |
695
- | `2` | Risk score threshold exceeded (when using `risk-report --fail-on-score`) |
620
+ See [`docs/06-development/getting-started.md`](docs/06-development/getting-started.md)
621
+ and [`docs/06-development/testing.md`](docs/06-development/testing.md).
696
622
 
697
- ## Development
623
+ Quick commands:
698
624
 
699
625
  ```bash
700
- # Install dependencies
701
626
  bun install
702
-
703
- # Run tests
704
627
  bun run test
705
-
706
- # Build
707
628
  bun run build
708
-
709
- # Type check
710
629
  bun run typecheck
711
-
712
- # Run locally
713
- bun src/cli.ts pretty -u
714
- bun src/cli.ts pr-body --base main --head HEAD
715
- bun src/cli.ts facts -u | jq '.riskScore'
716
630
  ```
717
631
 
632
+ ## Contributing
633
+
634
+ Contributions are welcome! Please read the development guides before submitting
635
+ a pull request:
636
+
637
+ - [Getting Started](docs/06-development/getting-started.md) - Setup and workflow
638
+ - [Coding Standards](docs/06-development/coding-standards.md) - Code style and conventions
639
+ - [Testing](docs/06-development/testing.md) - Test requirements
640
+
641
+ For bug reports and feature requests, please open an issue.
642
+
718
643
  ## Requirements
719
644
 
720
645
  - Node.js >= 18