<p align="center">
  <img src="https://unerr.dev/icon-wordmark.svg" alt="unerr" width="320" />
</p>

<p align="center">
  <strong>Lands your AI agent at the right code in fewer turns, tokens, & breakages.</strong>
</p>

<p align="center">
  The intelligence layer between your AI agent and your codebase.<br/>
  It sees every dependency, remembers every session, and gets smarter the longer you use it.
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@unerr-ai/unerr"><img src="https://img.shields.io/badge/install-npm_i_@unerr--ai/unerr-8B5CF6?style=flat-square&logo=npm" alt="Install" /></a>
  <img src="https://img.shields.io/badge/runtime-Node.js_≥20-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js" />
  <img src="https://img.shields.io/badge/protocol-MCP-7C3AED?style=flat-square" alt="MCP" />
  <img src="https://img.shields.io/badge/license-ELv2-A1A1AA?style=flat-square" alt="License" />
</p>

<p align="center">
  <code>npm install -g @unerr-ai/unerr</code>
</p>

---

## Your agent loops because it's blind

You've seen it. You ask Claude or Cursor to refactor a function. It reads 30 files to find the call graph. It misses 14 downstream callers. It re-discovers conventions you told it yesterday. It tries a broken approach, fails, tries again — burning tokens while you watch.

**The agent isn't stupid. It's blind.**

- It can't see that `processPayment()` has 40 callers across 3 services
- It doesn't know your team uses `fetch` prefixes, not `get`
- It forgot everything from yesterday's session

unerr gives it an intelligence layer that compounds. Every caller, every convention, every session — accumulated, not re-derived. The agent stops searching and starts knowing.

---

## What happens when you run it

**5 seconds later**, your agent has:

| Before unerr | After unerr |
|:---|:---|
| Reads 30 files to understand a call graph | Queries the graph in 5ms |
| Misses downstream callers, breaks things | Sees full blast radius before editing |
| Re-derives conventions every session | Knows your patterns, enforces them |
| Session degrades at 70% context fill | Stays sharp — 93% shell compression, context lasts 3–5x longer |
| Starts from zero tomorrow | Resumes where it left off |

### See it in action

<p align="center">
  <table>
    <tr>
      <td align="center">
        <img src="https://unerr.dev/open-cli/screenshots/token-trace-main.png" alt="unerr token trace — main view" width="250" />
        <br/><sub>Token trace</sub>
      </td>
      <td align="center">
        <img src="https://unerr.dev/open-cli/screenshots/token-session.png" alt="unerr session token tracking" width="250" />
        <br/><sub>Session tracking</sub>
      </td>
      <td align="center">
        <img src="https://unerr.dev/open-cli/screenshots/token-turn.png" alt="unerr per-turn token breakdown" width="250" />
        <br/><sub>Per-turn breakdown</sub>
      </td>
    </tr>
  </table>
</p>

---

## Quick Start

### Install from npm

```bash
# 1. Install globally
npm install -g @unerr-ai/unerr

# 2. Add to your AI agent (in your project directory)
unerr install claude-code   # or: cursor, vscode, windsurf, codex, etc.

# 3. Run (indexes your codebase, starts MCP server)
unerr
```

<!--
### Install from source

```bash
# 1. Clone and build
git clone https://github.com/unerr-cli.git
cd unerr-cli
pnpm install
pnpm run build

# 2. Link globally (makes `unerr` command available)
pnpm link --global

# 3. Add to your AI agent (in your project directory)
cd /path/to/your/project
unerr install claude-code   # or: cursor, vscode, windsurf, codex, etc.

# 4. Run
unerr
```
-->

After install, your AI agent automatically connects to unerr via MCP. No config files to edit manually.

---

## Supported Agents

```bash
unerr install claude-code        # .mcp.json + CLAUDE.md + .claude/skills/ + hooks
unerr install cursor             # .cursor/mcp.json + .cursor/rules/
unerr install vscode             # .vscode/mcp.json + .github/copilot-instructions.md
unerr install windsurf           # .windsurf/mcp.json
unerr install zed                # .zed/mcp.json
unerr install cline              # .cline/mcp.json + .clinerules
unerr install kiro               # .kiro/mcp.json
unerr install gemini-cli         # .gemini/settings.json + GEMINI.md
unerr install codex              # .codex/mcp.json + AGENTS.md
unerr install aider              # .aider/mcp.json
unerr install opencode           # .opencode/mcp.json
unerr install trae               # .trae/mcp.json
unerr install augment            # .augment/mcp.json
unerr install github-copilot-cli # .github/mcp.json + .github/copilot-instructions.md
unerr install continue           # .continue/config.json
```

Works with any MCP-compatible agent. 15 supported out of the box.

<details>
<summary>Manual MCP config (any agent)</summary>

```json
{
  "mcpServers": {
    "unerr": {
      "command": "npx",
      "args": ["@unerr-ai/unerr", "--mcp"]
    }
  }
}
```

</details>

---

## What you get

### Instant (first session)

- **Graph navigation** — `get_entity` · `get_references` · `get_imports` · `search_code` in <5ms. The agent stops reading 30 files to find one function.
- **Blast radius** — before editing, the agent sees every downstream caller via `get_references`. No more confident wrong changes.
- **Smart file reads** — `file_read({entity: "functionName"})` returns just that function + context. Not 2000 lines.
- **Shell compression** — 11 strategies, 645+ command classifiers. Diffs, errors, logs, test results, YAML, key-value, tabular — each compressed differently. **93% average compression** across real-world benchmarks (2MB → 138KB).
- **Full output recovery** — when compression is significant, raw output is saved to disk with a recovery path. The agent can always access the original.
- **Convention awareness** — auto-detected naming, structure, and import patterns injected into agent context.
- **Semantic search** — `semantic_search` finds conceptually similar code even with different naming. `find_similar` discovers related entities by embedding distance.
- **Business context** — `get_business_context` explains why code exists — purpose, feature area, taxonomy.

### Compounding (session 2+)

- **Session persistence** — the agent tomorrow knows what the agent learned today. No more starting from zero.
- **Fact memory** — `record_fact` persists conventions, decisions, and anti-patterns across sessions. `recall_facts` retrieves them with decay-adjusted confidence.
- **Convention enforcement** — patterns detected in session 1 are enforced in session 5. No manual `.cursorrules` maintenance.
- **Anti-pattern rules** — when you revert bad code, unerr learns. That mistake never happens again.
- **Shadow ledger** — `unerr_mark_working` snapshots known-good state. `unerr_revert_to_working_state` rolls back when things break. `unerr_get_timeline` shows what changed across sessions.
- **Loop prevention** — circuit breaker fires after repeated failed attempts.

### Agent behaviors (long-lived mode)

When running `unerr` as a daemon, these automated behaviors activate:

- **Architecture guard** — flags structural violations before they ship
- **Cascade guard** — warns when a change has wide blast radius
- **Convention drift** — detects when new code diverges from established patterns
- **Auto-doc** — generates documentation for undocumented entities
- **Change narrative** — tracks the story behind multi-step refactors
- **Loop breaker** — intervenes when the agent is stuck in a retry loop
- **Session continuity** — preserves context across restarts

### Shell compression benchmarks

Every shell command the agent runs is classified (645+ command patterns + content heuristics) and compressed with the best-fit strategy:

| Strategy | What it compresses | Avg compression |
|----------|-------------------|:-:|
| **diff** | `git diff`, patch output | **99%** |
| **structured** | JSON APIs, `docker inspect` | **97%** |
| **progress** | `npm install`, `pip install` | **95%** |
| **log_text** | Build logs, server logs, `make`, `cargo build` | **89%** |
| **test_results** | `vitest`, `pytest`, `cargo test`, `playwright` | **80%** |
| **tabular** | `ps aux`, `docker ps`, `kubectl get` | **77%** |
| **error_diagnostic** | `tsc`, `eslint`, `rustc`, `shellcheck` | **72%** |
| **key_value** | `env`, `kubectl describe`, `systemctl status` | **48%** |
| **tree_paths** | `find`, `tree`, `ls -R` | **42%** |
| **yaml** | YAML configs, `kubectl get -o yaml`, Helm output | adaptive |
| **omni** | Fallback for unrecognized output | adaptive |

**Overall: 93% compression** (2MB → 138KB across 40 real-world test cases). Low-confidence classifications use smart fallback — tries both the best-guess strategy and generic compression, picks whichever saves more tokens.

### Language support

| Language | Tier | Entity Extraction | Edge Extraction | Tree-sitter AST | SCIP |
|----------|:---:|:-:|:-:|:-:|:-:|
| TypeScript | 1 | ✓ | ✓ | ✓ | ✓ |
| JavaScript | 1 | ✓ | ✓ | ✓ | ✓ |
| Python | 1 | ✓ | ✓ | ✓ | ✓ |
| Go | 1 | ✓ | ✓ | ✓ | ✓ |
| Java | 1 | ✓ | ✓ | ✓ | ✓ |
| Rust | 1 | ✓ | ✓ | ✓ | ✓ |
| Ruby | 1 | ✓ | ✓ | ✓ | — |
| C# | 1 | ✓ | ✓ | ✓ | — |
| C | 2 | ✓ | ✓ | ✓ | — |
| C++ | 2 | ✓ | ✓ | ✓ | — |
| PHP | 2 | ✓ | ✓ | ✓ | — |
| Swift | 2 | ✓ | ✓ | ✓ | — |
| Kotlin | 2 | ✓ | ✓ | ✓ | — |
| Scala | 2 | ✓ | ✓ | ✓ | — |
| Lua | 2 | ✓ | ✓ | ✓ | — |
| Dart | 2 | ✓ | ✓ | ✓ | — |
| Elixir | 2 | ✓ | ✓ | ✓ | — |
| Zig | 2 | ✓ | ✓ | ✓ | — |

**Tier 1** (8 languages): Full tree-sitter AST + dedicated extraction plugins + SCIP compiler-verified call graphs where available.
**Tier 2** (10 languages): Tree-sitter AST + generic extraction. Regex fallback for unsupported languages.

---

## How it works

```
AI Agent (Claude Code / Cursor / VS Code / Windsurf / any MCP client)
    │
    ├── MCP tools ──→ unerr ──→ CozoDB graph (in-process, <5ms)
    │                   │
    │                   ├── Convention engine (auto-detects patterns)
    │                   ├── Fact store (cross-session memory)
    │                   ├── Shadow ledger (mark-working / revert / timeline)
    │                   ├── Token budgeter (prevents context rot)
    │                   └── Compression engine (11 strategies, 645+ classifiers)
    │
    └── CLI hooks ──→ Output compression ──→ Graph-aware prioritization
```

One process. Fully local. No API keys. No network calls. No cloud.

---

## MCP Tools (20)

### Graph Intelligence (15)

| Tool | What the agent gets |
|------|-----|
| `get_entity` | Any code entity (function, class, type) — signature, body, callers, callees, risk level |
| `get_file` | All entities defined in a file with risk summary |
| `get_references` | All callers (blast radius) or callees (dependencies) of an entity |
| `get_imports` | Import/dependency graph for a file |
| `search_code` | Graph-ranked full-text search across all indexed entities |
| `get_rules` | Active rules for a path — optionally validates code against them |
| `get_conventions` | Detected naming, structure, import conventions with adherence rates |
| `get_business_context` | Why code exists — purpose, taxonomy, feature area |
| `get_critical_nodes` | High fan-in/fan-out chokepoints (structural bottlenecks) |
| `get_cross_boundary_links` | Unexpected cross-module dependencies scored by surprise |
| `semantic_search` | Vector-based conceptual search (finds similar code with different names) |
| `find_similar` | Entities similar to a given entity by embedding distance |
| `get_project_stats` | Project-wide entity counts, risk distribution, health grade |
| `file_connections` | Connected files — imports, co-change correlations, structure |
| `get_test_coverage` | Direct and transitive test coverage for any entity |

### File Protocol (2)

| Tool | What the agent gets |
|------|-----|
| `file_read` | Context-aware file reading — auto-injects conventions and facts |
| `file_outline` | File structure (functions, classes, exports) without reading content |

### Persistent Intelligence (2)

| Tool | What the agent gets |
|------|-----|
| `record_fact` | Persist a convention, decision, or anti-pattern to the fact store |
| `recall_facts` | Retrieve stored facts with decay-adjusted confidence scoring |

### Shadow Ledger (3)

| Tool | What the agent gets |
|------|-----|
| `unerr_mark_working` | Snapshot current known-good state before risky changes |
| `unerr_revert_to_working_state` | Roll back to last working snapshot |
| `unerr_get_timeline` | View modification timeline across sessions |

Every response includes `_meta` (latency, risk level, drift status) and contextual warnings.

---

<details>
<summary><strong>Commands</strong></summary>

```bash
unerr                 # Start MCP proxy (auto-started by IDE via MCP config)
unerr status          # Graph stats, health grade, active rules
unerr stats           # Session and weekly efficiency metrics
unerr install <agent> # Add unerr to a specific AI coding agent
unerr uninstall       # Remove unerr integration from agents
unerr init            # Initialize unerr in a new project
unerr timeline        # What happened across sessions
unerr rewind          # Restore to a previous working state
unerr learn           # Teach unerr a convention or correction
unerr debug           # Diagnostic dump
```

</details>

<details>
<summary><strong>Architecture</strong></summary>

```
src/
  entrypoints/        CLI entry + boot state machine
  intelligence/       CozoDB graph, AST extraction, conventions, rules, search, semantic
  proxy/              MCP server, shell compression, session stats, token tracking
  tracking/           Prompt ledger, drift detection, git attribution
  behaviors/          Agent behavior modules (cascade guard, loop breaker, auto-doc, etc.)
  commands/           CLI commands (install, status, stats, timeline, learn, debug, etc.)
  tools/              MCP tool implementations (intelligence + coding)
  hooks/              Claude Code hook system integration
  skills/             Bundled skill definitions for agent installation
  server/             HTTP dashboard API server
  ui/                 React (Vite) dashboard frontend
  config/             Agent registry, MCP config writer, settings
  schemas/            Zod schemas for entity/edge/rule types
  utils/              Logging, detection, git helpers
```

**Design principles:**
- Zero network calls — fully local, no API keys
- stdout is sacred — MCP JSON-RPC only, everything else to stderr
- <5ms query responses — CozoDB runs in-process (Rust via NAPI)
- 30s time-to-value — shallow index first, deep enrichment in background
- Enhancement, not dependency — agent falls back gracefully if unerr is unavailable

**Tech stack:** TypeScript (ESM) · CozoDB (Rust/NAPI) · web-tree-sitter (WASM) · MCP SDK · Ink (React CLI) · tsup · Vitest

</details>

<details>
<summary><strong>Development</strong></summary>

```bash
pnpm install
pnpm run build          # tsup → dist/ (ESM, node20)
pnpm run dev            # tsx watch
pnpm run test:run       # full suite
pnpm run lint           # biome check
pnpm run typecheck      # tsc --noEmit
```

```bash
pnpm link --global      # make `unerr` available globally
```

</details>

<details>
<summary><strong>Contributing</strong></summary>

Contributions welcome. Please open an issue first.

**Before submitting a PR:**
- Run `pnpm run typecheck && pnpm run lint && pnpm run test:run`
- All output goes to stderr — never stdout (MCP JSON-RPC channel)
- All CozoDB interactions are async — always `await`
- Use `.js` extensions in imports (NodeNext resolution)

See [CLAUDE.md](./CLAUDE.md) for detailed conventions.

</details>

---

## License

[Elastic License 2.0 (ELv2)](./LICENSE) — free to use, modify, and distribute. Cannot be offered as a hosted service.

---

<p align="center">
  <code>npm install -g @unerr-ai/unerr</code>
  <br /><br />
  <a href="https://www.npmjs.com/package/@unerr-ai/unerr"><sub>npm registry</sub></a> · <sub>No cloud. No account. Free.</sub>
</p>
