Branch Narrator is a local-first, deterministic CLI that analyzes git diff and provides structured context for AI coding agents and human code review. No LLMs, no network calls — just evidence-based analysis you can trust.

Quick Start

The quickest way to get started is using bunx (or npx). This approach ensures you're always running the latest version without worrying about global installations.

# Install as dev dependency (recommended)
bun add -D @better-vibe/branch-narrator

# Or run without installing
bunx @better-vibe/branch-narrator facts --pretty

Common Commands

Here are the most useful commands to get you started:

# Generate a PR description for current changes
branch-narrator pr-body

# Colorized summary for humans
branch-narrator pretty

# Structured JSON facts for automation
branch-narrator facts --pretty

# Risk report for review
branch-narrator risk-report --format md

# Prompt-ready diff with smart filtering
branch-narrator dump-diff --out .ai/diff.txt

# Zoom into a specific finding
branch-narrator zoom --finding finding.env-var#abc123

# Save workspace snapshot for agent iteration
branch-narrator snap save "before-refactor"

# Compare changes since last run (delta mode)
branch-narrator facts --since .ai/baseline.json

Why Branch Narrator?

Traditional git diffs are noisy and lack context. Branch Narrator bridges this gap by providing:

  • Deterministic and offline: No LLMs, no network calls — your code never leaves your machine
  • Evidence-based output: Summaries and risk flags are tied to actual diff evidence
  • Profile-aware analysis: Framework-specific insights for SvelteKit, Next.js, React, Vue, Astro, Angular, and Python
  • Multiple output formats: Markdown for humans, JSON/SARIF for automation

Key Capabilities

Output Formats

  • Markdown PR descriptions (pr-body) with consistent sections
  • JSON facts (facts) for pipelines and automation
  • Prompt-ready diffs (dump-diff) with smart filtering for AI context windows
  • SARIF output (--format sarif) for GitHub Code Scanning integration
  • Risk scoring (risk-report) with evidence-backed flags and categories
  • Workspace snapshots (snap) for saving and comparing workspace state

Analysis Features

  • Route and API change detection for modern frameworks (SvelteKit, Next.js App Router, React Router, Vue/Nuxt, Astro, Angular)
  • Python support (FastAPI, Django, Flask)
  • Dependency and package surface analysis (semver impact, exports, lockfile mismatches)
  • Environment variables, security-sensitive files, CI workflows, and infrastructure changes
  • Migration safety checks (Supabase and Python migrations, SQL risk patterns)

Agent Workflows

  • Delta mode (--since) for comparing runs and tracking changes over time
  • Stable IDs for deterministic finding/flag references across runs
  • Snapshot workflows (snap) for saving and restoring workspace state
  • Drill-down (zoom) for detailed context on specific findings or flags
  • AI assistant integration (integrate) to generate provider rules for Cursor, Claude, Jules, and OpenCode

CLI Reference

Global Flags

Available for all commands:

--quiet              # Suppress non-fatal diagnostics (warnings, info)
--debug              # Print debug diagnostics to stderr
--no-cache           # Disable caching entirely
--clear-cache        # Clear cache before running

Diff Modes

Control what changes are analyzed:

  • unstaged - Working tree vs index + untracked files (default)
  • branch - Compare base ref to head ref
  • staged - Index vs HEAD (staged changes)
  • all - All changes vs HEAD (staged + unstaged + untracked)

Available Profiles

Use --profile <name> to override auto-detection:

  • auto - Default profile selection (framework detection fallback)
  • sveltekit - SvelteKit fullstack apps
  • next - Next.js App Router apps
  • react - React apps using React Router
  • vue - Vue/Nuxt apps
  • astro - Astro projects
  • angular - Angular apps
  • python - Python apps
  • library - npm packages/libraries

Command: pretty

Display a colorized summary of changes in the terminal.

# Review unstaged changes (default)
branch-narrator pretty

# Compare branches
branch-narrator pretty --mode branch --base develop --head feature/auth

# Review all local changes
branch-narrator pretty --mode all

Command: pr-body

Generate a raw Markdown PR description.

# Analyze unstaged changes (default)
branch-narrator pr-body

# Compare branches for PR
branch-narrator pr-body --mode branch --base develop --head feature/auth

# Interactive mode (prompts for context)
branch-narrator pr-body --interactive

Command: facts

Output JSON findings for programmatic use.

# Pretty-printed JSON
branch-narrator facts --pretty

# SARIF output for code scanning
branch-narrator facts --format sarif --out branch-narrator.sarif

# Delta mode - save baseline then compare
branch-narrator facts --out .ai/baseline.json
branch-narrator facts --since .ai/baseline.json --pretty

Command: dump-diff

Output a prompt-ready git diff with smart exclusions.

# Output unstaged changes to stdout (default)
branch-narrator dump-diff

# Compare branches for PR
branch-narrator dump-diff --mode branch --base main --head feature/auth --out .ai/diff.txt

# Chunk large diffs
branch-narrator dump-diff --max-chars 25000 --chunk-dir .ai/diff-chunks

Command: risk-report

Analyze diffs and emit a risk score with evidence-backed flags.

# Analyze unstaged changes (default)
branch-narrator risk-report

# Markdown format for human review
branch-narrator risk-report --format md

# Fail CI if risk score >= threshold
branch-narrator risk-report --fail-on-score 60

Risk levels:

  • Low: 0-20
  • Moderate: 21-40
  • Elevated: 41-60
  • High: 61-80
  • Critical: 81-100

Command: zoom

Zoom into a specific finding or risk flag for detailed context.

# Zoom into a finding
branch-narrator zoom --finding finding.env-var#abc123

# Zoom into a risk flag
branch-narrator zoom --flag flag.db.destructive_sql#def456 --format md

# Zoom without patch context
branch-narrator zoom --finding finding.dependency-change#c0ffee --no-patch

Command: integrate

Generate provider-specific rules for AI coding assistants.

# Generate Cursor rules
branch-narrator integrate cursor

# Generate Jules rules
branch-narrator integrate jules

# Preview without writing files
branch-narrator integrate --dry-run

# Overwrite existing files
branch-narrator integrate opencode --force

Command: snap

Manage local workspace snapshots.

# Save a snapshot
branch-narrator snap save "before-refactor"

# List snapshots
branch-narrator snap list --pretty

# Compare two snapshots
branch-narrator snap diff abc123def456 def456abc789 --pretty

Snapshots are stored under .branch-narrator/. Add it to .gitignore to keep snapshots local.

CI/CD Integration

GitHub Actions with SARIF

Upload findings to GitHub Code Scanning:

name: Code Analysis

on:
  pull_request:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Bun
        uses: oven-sh/setup-bun@v1

      - name: Generate SARIF report
        run: bunx @better-vibe/branch-narrator facts --mode branch --base origin/main --format sarif --out results.sarif

      - name: Upload SARIF to GitHub
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Risk Gate

Fail CI if risk score exceeds threshold:

- name: Check risk score
  run: branch-narrator risk-report --mode branch --base origin/main --fail-on-score 60

Programmatic API

Use Branch Narrator as a library for custom integrations:

import {
  collectChangeSet,
  getProfile,
  resolveProfileName,
  runAnalyzersInParallel,
  computeRiskScore,
} from "@better-vibe/branch-narrator";

// Collect git changes
const changeSet = await collectChangeSet({
  mode: "branch",
  base: "main",
  head: "HEAD",
});

// Resolve and run profile analyzers
const profileName = resolveProfileName("auto", changeSet, process.cwd());
const profile = getProfile(profileName);
const findings = await runAnalyzersInParallel(profile.analyzers, changeSet);

// Compute risk
const riskScore = computeRiskScore(findings);

console.log(`Risk: ${riskScore.level} (${riskScore.score}/100)`);
console.log(`Findings: ${findings.length}`);

Example Output

Sample facts output (JSON structure):

{
  "schemaVersion": "2.1",
  "git": {
    "base": "main",
    "head": "HEAD",
    "range": "main..HEAD",
    "mode": "branch"
  },
  "profile": {
    "requested": "auto",
    "detected": "sveltekit",
    "confidence": "high",
    "reasons": ["Found src/routes/ directory"]
  },
  "stats": {
    "filesChanged": 12,
    "insertions": 245,
    "deletions": 89
  },
  "risk": {
    "score": 35,
    "level": "medium"
  },
  "findings": [
    {
      "type": "route-change",
      "findingId": "finding.route-change#a1b2c3d4",
      "routeId": "/api/users",
      "change": "added"
    }
  ]
}

Exit Codes

  • 0 - Success
  • 1 - Expected failures (not a git repo, invalid refs)
  • 2 - Risk score threshold exceeded (risk-report --fail-on-score)

Best Practices

  1. Run before AI sessions: Always generate context before starting work with AI agents
  2. Share the report: Include the generated markdown or JSON in your AI prompts
  3. Watch risk scores: Pay attention to scores above 40 - they indicate elevated risk
  4. Use snapshots: Save snapshots at key milestones to track progress
  5. Leverage delta mode: Compare runs to see what changed between iterations
  6. Customize profiles: Create profiles matching your specific framework and patterns
  7. Integrate with CI: Use SARIF output for automated code scanning

Conclusion

Branch Narrator bridges the gap between raw git diffs and structured context that AI agents can effectively use. By providing evidence-based analysis with clear risk assessments, it helps both human reviewers and AI assistants understand the scope and impact of changes.

Start with the basic pretty or pr-body commands, then gradually explore advanced features like delta mode, risk reporting, and CI integration to optimize your workflow.

For more detailed documentation, visit the GitHub repository or check out the npm package page.