code-kb-core 1.6.0

Core library for code-kb AST fact querying, slicing, and progressive disclosure
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
# code-kb

> **Interactive Showcase & Benchmarks:** [https://anortham.github.io/code-kb/](https://anortham.github.io/code-kb/)

`code-kb` is a fast, lightweight code-intelligence engine and Model Context Protocol (MCP) server designed specifically for AI coding agents. 

Backed by the rich AST fact tables produced by [`julie-extractors`](https://github.com/anortham/julie-extractors), `code-kb` provides progressive disclosure, semantic symbol navigation, and surgical context slicing—enabling agents to navigate, understand, and edit codebases with **80–90% fewer tokens** without burning context on full file reads or noisy text grep.

---

## Why code-kb?

Traditional AI coding agents burn massive amounts of context loading entire source files into their prompt windows just to inspect a single type signature or implementation detail. 

`code-kb` solves this with a **progressive disclosure** architecture:
1. **Repository Orientation (`codebase_outline`):** Understand directory structures and key exports in ~200 tokens.
2. **File Skeletons (`file_skeleton`):** Inspect function signatures, types, traits, and docstrings with implementation bodies stripped.
3. **Symbol Lookup & Discovery (`lookup_symbol` / `search_symbols`):** Instant exact/prefix identifier lookups and conceptual search over names, signatures, and docstrings; substrings inside identifiers are found (`sha256` finds `parseSha256Sidecar`).
4. **Surgical Symbol Context (`get_symbol_context`):** In a single turn, fetch a target function's body along with its callee signatures, parameter types, and associated unit tests.
5. **Single-Turn Edits (`edit_file` / `replace_symbol_body`):** Replace text in any file without reading it first, or replace a whole symbol body. Both validate the syntax with `julie-extract` for every language it parses, write atomically, and re-index immediately.

---

## Key Principles

- **Small Retained Memory:** Written in Rust, zero heavy runtimes (no web dashboard, no GPU models), retained process memory is about 25 MB. The plugin launcher is a small Node script that replaces itself with the native binary via `process.execve` on supported POSIX Node 22+ runtimes (or waits via `spawn` on Windows/older Node).
- **Sub-5ms Query Latency:** Direct SQLite queries in WAL mode with zero in-memory heap bloat.
- **Zero Workspace Parameters:** Pure semantic tool calling (`lookup_symbol(query="...")`). The agent is never burdened with `workspace_id`, `repo_path`, or path confusion.
- **CLI-First Parity:** Every MCP tool has an exact 1:1 CLI command for instantaneous terminal verification and dogfooding.
- **Continuous 3-Tier Sync:** Tool-driven updates, JIT staleness guards before reads, and a debounced background watcher with a Git storm circuit breaker.

---

## Install

Install the plugin for your agent. The plugin ships a small Node.js launcher. On the first
run it downloads the matching `code-kb` release archive for your platform, verifies its
SHA-256, and unpacks `code-kb` and `julie-extract` into `~/.code-kb/dist/<version>/`. Later
runs start instantly. Nothing else to download or put on `PATH`.

Requirements:
- Node.js 18 or newer on `PATH` (the launcher is a Node script; the server itself is a native binary).
- Windows 10 build 17063 or newer (the launcher unpacks with the built-in `tar.exe`).

### Claude Code

```text
/plugin marketplace add anortham/code-kb
```
```text
/plugin install code-kb@code-kb
```
*(Send as two separate prompts.)* The plugin registers the MCP server, the progressive
disclosure skill, a `/code-kb:telemetry` command for usage and token-savings reports, and
SessionStart and SubagentStart hooks that inject routing instructions.

### Codex

```bash
codex plugin marketplace add anortham/code-kb
codex plugin add code-kb@code-kb
```
Run `codex`, open `/hooks`, and trust the two code-kb hooks.

To update, refresh the marketplace snapshot first. `codex plugin remove` followed by
`codex plugin add` reinstalls the version already in the snapshot:

```bash
codex plugin marketplace upgrade
codex plugin remove code-kb@code-kb
codex plugin add code-kb@code-kb
```

### Antigravity CLI (AGY)

```bash
agy plugin install https://github.com/anortham/code-kb
```
The plugin registers the MCP server and a `PreInvocation` hook. Antigravity has no
`SessionStart` hook, so routing directives arrive per turn through `injectSteps`.

### Grok CLI

```bash
grok plugin install anortham/code-kb --trust
```

### First Run & Automatic Indexing

You do not need to run `code-kb scan` by hand. The first `code-kb` tool call or CLI command in
a repository creates `<workspace>/.code-kb/artifact.db` and runs the initial scan. A git
worktree copies its parent repository's index instead of scanning again. Files that changed
while no session ran, for example after a branch switch, are reconciled before the first
answer. Pre-index a large repository before a session with:

```bash
code-kb scan
```

Launcher environment variables:

| Variable | Effect |
|---|---|
| `CODE_KB_HOME` | Directory that holds `dist/` (default `~/.code-kb`). |
| `CODE_KB_VERSION` | Release version to fetch instead of the plugin's own version. |
| `CODE_KB_BIN` | Run this binary and skip the download entirely (local builds). |

Two overrides need no environment variable, which matters in harnesses that do not pass the
environment to MCP servers (Codex):

- A binary or symlink at `~/.code-kb/bin/code-kb` (`code-kb.exe` on Windows) runs instead of any
  download, in every harness. For development: `ln -s /path/to/code-kb/target/release/code-kb ~/.code-kb/bin/code-kb`.
- A plugin installed from a source checkout runs that checkout's `target/release/code-kb` when it
  exists.

With either in place, `cargo build --release` plus a session restart is the whole development loop.

### Uninstall

| Harness | Command / Action |
|---|---|
| Claude Code | `/plugin remove code-kb` |
| Codex | `codex plugin remove code-kb@code-kb` |
| Antigravity (AGY) | `agy plugin uninstall code-kb` |
| Grok CLI | `grok plugin uninstall code-kb` |

Delete `~/.code-kb/dist` to remove the downloaded binaries. Each workspace keeps its index
in `<workspace>/.code-kb/`; delete that directory to remove the index.

---

## Manual Configuration

Use this path for harnesses without a plugin manager, or when you would rather manage the
binary yourself.

### Step 1: Get the Binaries

- **GitHub Releases:** download the archive for your platform from
  [GitHub Releases](https://github.com/anortham/code-kb/releases):
  - Linux x86_64 and ARM64 (`.tar.gz`)
  - macOS Apple Silicon and Intel (`.tar.gz`)
  - Windows x86_64 and ARM64 (`.zip`)

  Unpack it and put both binaries on your `PATH` (for example `~/.local/bin`,
  `/usr/local/bin`, or `C:\tools`). `code-kb` and `julie-extract` are packaged side by side,
  and `code-kb` finds `julie-extract` next to its own executable.
- **Cargo:**
  ```bash
  cargo binstall code-kb-cli
  # or
  cargo install code-kb-cli
  ```
  Cargo installs `code-kb` only. Download the pinned `julie-extract` from the
  [julie-extractors releases](https://github.com/anortham/julie-extractors/releases) (version
  in `scripts/julie-pins.json`) and put it on your `PATH` or set `JULIE_EXTRACT_BIN`.
- **Verify:**
  ```bash
  code-kb --version
  ```

### Step 2: Register the MCP Server

Every harness runs the same command: `code-kb serve`. Hooks run `code-kb hook <Event>`.

#### How code-kb Finds Your Workspace

Tools never take a workspace parameter. The server binds a workspace in three steps, and each
later step replaces the earlier one:

1. At start: `--root <path>` on the `serve` command, or, without it, the directory the process
   starts in, searched upward for `.git` or a project marker.
2. At handshake: the roots the host sends in the MCP `initialize` request, if any.
3. At each tool call: an absolute path inside a repository in any `file_path` or `path` argument.

Terminal harnesses (Claude Code, Codex, AGY, Grok CLI, Copilot CLI, Pi, Swival, Zed) start the
server in the project directory, so `code-kb serve` alone is enough.

GUI apps (Cursor, Windsurf, the Antigravity IDE, Visual Studio, VS Code, Claude Desktop) start
the server from their own install directory, not from your project. For these apps, put the MCP
config inside the project and pass `--root` with the absolute path of the project:

```json
"args": ["serve", "--root", "/absolute/path/to/project"]
```

Without `--root`, the first tool call in a GUI app fails with
`Database artifact not found ... configure code-kb with '--root <repo-path>'`. That error is the
signal to add the flag. A tool call with an absolute path inside a repository also binds the
server, so a session can recover, but `--root` removes the guesswork.

#### Claude Code (without the plugin)

```bash
claude mcp add --scope user code-kb -- code-kb serve
```

#### Codex (without the plugin)

In `~/.codex/config.toml`:
```toml
[mcp_servers.code-kb]
command = "code-kb"
args = ["serve"]
```

#### Antigravity CLI (without the plugin)

```bash
agy mcp add code-kb code-kb serve
```

Global config (`~/.gemini/config/mcp_config.json`) with `"eager": true`. The AGY CLI starts the
server in the project directory. The Antigravity IDE starts it from its own install directory,
so add `--root` when you use the IDE:
```json
{
  "mcpServers": {
    "code-kb": {
      "command": "code-kb",
      "args": ["serve", "--root", "/absolute/path/to/project"],
      "disabled": false,
      "eager": true,
      "force_all_tools_eager": true
    }
  }
}
```

Lifecycle hook configuration (`~/.gemini/config/hooks.json`):
```json
{
  "code-kb": {
    "PreInvocation": [
      {
        "command": "code-kb hook PreInvocation",
        "timeout": 10,
        "type": "command"
      }
    ]
  }
}
```

Progressive disclosure skill linking:
```bash
ln -sf /path/to/code-kb/skills/code-kb ~/.gemini/config/skills/code-kb
```

#### Grok CLI (without the plugin)

Project-level `.mcp.json`:
```json
{
  "mcpServers": {
    "code-kb": {
      "command": "code-kb",
      "args": ["serve"]
    }
  }
}
```

#### Cursor

In `.cursor/mcp.json` at the repository root. Cursor is a GUI app, so pass `--root`:
```json
{
  "mcpServers": {
    "code-kb": {
      "command": "code-kb",
      "args": ["serve", "--root", "/absolute/path/to/project"]
    }
  }
}
```

#### OpenCode

Add to `opencode.json` in the project:
```json
{
  "mcpServers": {
    "code-kb": {
      "command": "code-kb",
      "args": ["serve", "--root", "/absolute/path/to/project"]
    }
  }
}
```

#### Claude Desktop

Claude Desktop has one global config and no project directory, so `--root` pins one project.
Add to `claude_desktop_config.json` (`%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
```json
{
  "mcpServers": {
    "code-kb": {
      "command": "code-kb",
      "args": ["serve", "--root", "/absolute/path/to/project"]
    }
  }
}
```

#### Other GUI Apps (Windsurf, Visual Studio, VS Code)

Use the app's project-level MCP config file and the same arguments:
`["serve", "--root", "/absolute/path/to/project"]`. On Windows write the path with forward
slashes, for example `C:/source/project`.

#### GitHub Copilot CLI & Terminal Agents

Terminal harnesses (Copilot CLI, Pi, Swival, Zed) start the server in the project directory:
configure the MCP server to run `code-kb serve` with no `--root`.

To remove a manual configuration, delete the `code-kb` entry from the harness config
(`claude mcp remove code-kb`, `agy mcp remove code-kb`, or edit the file) and delete the
binaries from your `PATH`.

---

## Qt and QML

For a Qt developer, `code-kb` answers the everyday questions about a QML code base.
`file_skeleton` prints the component as its object tree: declared properties, signals,
functions, inline components, and every nested object under its owner.
`find_references` crosses component files: it lists the components that extend a base
type as `extends` rows, the plain and qualified instantiations (`Kirigami.Page` as well
as `Page`), the files that read a singleton, and the signal handlers, each labelled
`handler` when the receiver names the owner and `handler (candidate)` when it does not.
`qmldir` module files and `.qmltypes` type descriptors are indexed. Qt JavaScript files
parse, including the `.pragma library` and `.import` directives, so `edit_file` works on
them. KDE test files under `autotests/` and files named `tst_*.qml` are hidden from
search by default; `--include-tests` shows them. This needs julie-extract 3.3.0.

A Qt C++ header indexes the same way. `file_skeleton` prints one `Q_PROPERTY(...)` row
per declared property under its class, keeping the `READ`, `WRITE`, `NOTIFY`, and
`MEMBER` accessors the macro names. A method declared in a `Q_SIGNALS:` section is an
`event` row, and the skeleton marks it `// event` before its line range because its C++
signature reads like a method. A method in a `Q_SLOTS:` section carries `qt_slot`, and a
`Q_INVOKABLE` method carries `qt_invokable`. A class records the QML element name it declares with
`QML_ELEMENT` or `QML_NAMED_ELEMENT`. A forward declaration such as `class ColumnView;`
emits no row, so `lookup_symbol` of a class name returns one row, at its definition.
`find_structural_facts` takes a `property` alias that covers the QML property
declarations and the Qt C++ `Q_PROPERTY` facts together, each fact naming its class.

First-class Qt support: QML, `qmldir`, `.qmltypes`, Qt JavaScript, and Qt C++ headers,
validated on pinned corpus revisions; static reference results have documented limits;
`.ui` and CMake files are not indexed.

### Validated on

| Corpus | Pinned commit | QML files | C++ files |
| :--- | :--- | ---: | ---: |
| Omarchy shell (Quickshell) | `49306774` | 106 | 0 |
| KDE Kirigami | `ca7d636` | 225 | 102 |
| KDE plasma-workspace | `a45871a` | 222 | 1051 |
| Quickshell examples | `c6d1236` | 14 | 0 |

Measured with the branch binaries on Omarchy and Kirigami:

```bash
# Omarchy
code-kb skeleton shell/Ui/Button.qml
# 71 lines for a 209-line file; the object tree nests, so ToolTip, Row, MouseArea,
# and HoverHandler hold their own children.

code-kb refs BarWidget --file shell/Ui/BarWidget.qml --limit 200
# 15 rows: 12 `extends` rows, one per component that extends BarWidget.
# The other 3 rows are signal handlers, grouped one row per file.

code-kb refs Color --file shell/Commons/Color.qml --limit 200
# 53 rows, one per file that reads the Color singleton.

code-kb refs clicked --file shell/Ui/Button.qml
# 20 rows: 4 emit sites, 1 `handler` row, and 15 `handler (candidate)` rows.

code-kb lookup SpeedDial
# 1 row: class SpeedDial [shell/Ui/SpeedTestOverlay.qml:206-411],
# signature `component SpeedDial: Item`, an inline component.

# Kirigami
code-kb refs Page --file src/controls/Page.qml --limit 200
# 60 rows, of which 7 are `extends` rows (four of them inline components).

# Kirigami, Qt C++
code-kb skeleton src/layouts/columnview.h
# 231 lines for a 785-line file, 38 `Q_PROPERTY(...)` rows, no parse-error banner.

code-kb lookup ColumnView
# 1 class row: `class ColumnView [src/layouts/columnview.h:276-783]`.
# The forward declaration in the same file adds no second row.

code-kb facts property --path src/layouts/columnview.h --limit 5
# 5 of the file's 38 `cpp.qt_property.v1` facts, each naming the class that owns it
# (`ScrollIntentionEvent`, `ColumnViewAttached`).
```

### Known limits

- A project macro that the extractor does not know is not blanked before the parse, so it
  can still cause a parse diagnostic. Diagnostics remain on both C++ corpora: 31 on
  Kirigami and 298 on plasma-workspace, down 97% and 94% from julie-extract 3.2.0. None
  of them is macro-shaped; a file-local `#define` used as a statement accounts for 12 of
  Kirigami's 31.
- `Q_DECLARE_FLAGS(Modes, Mode)` and a `Q_OBJECT_BINDABLE_PROPERTY(...)` member are
  blanked as whole statements, so the typedef and the member emit no row.
- A macro used inside a line, such as `Q_ARG(bool, true)` in a `QMetaObject::invokeMethod`
  call, is left alone by design, because rewriting it would delete real arguments.
- `.ui` designer files and CMake files are not indexed.
- A QML module imported through an alias resolves to a workspace file only when the alias
  is not a Qt module. `QtQuick.*` and `QtQml.*` aliases never name a workspace symbol.
- A reference list caps at 200 rows. For a heavily used singleton, `refs` groups the
  member accesses per file, one row per file with a count.

---

## MCP Tool Catalog

| Tool | Purpose | Key Parameters | Aliases |
| :--- | :--- | :--- | :--- |
| `codebase_outline` | High-level architectural orientation of directory layout & symbols. | `path` (opt), `depth` (opt, default 2) | `dir`, `subpath` |
| `file_skeleton` | File outline with function & method bodies stripped (80–90% token savings); a directory returns its outline. | `file_path` (req) | `file`, `path` |
| `lookup_symbol` | Fast identifier lookup (exact name or prefix) across repo or scoped path. Test functions, test containers, and rows from test files are hidden unless `is_test` is true, except a row whose name equals the query. | `query` (req), `path` (opt), `kind` (opt), `is_test` (opt), `limit` (opt) | `name`, `q` |
| `search_symbols` | Conceptual search over symbol names, signatures & docstrings; substrings inside identifiers are found (`sha256` finds `parseSha256Sidecar`). Results are reranked by crediting each query term once from its strongest field (name, signature, docstring), weighted by the term's rarity across the index, plus kind and path priors; `score` is that rerank score. Test functions, test containers, and rows from test files are hidden unless `is_test` is true. | `query` (req), `path` (opt), `kind` (opt), `is_test` (opt), `limit` (opt) | `name`, `q` |
| `get_symbol_body` | Slices the exact implementation body of a symbol from disk. | `symbol_name` (req), `file_path` (opt) | `symbol`, `name`, `path` |
| `get_symbol_context` | Surgical bundle: target body + callee signatures + parameter types + tests. | `symbol_name` (req), `file_path` (opt), `include_external` (opt, def: false) | `symbol`, `name`, `path` |
| `find_references` | Callers or callees of a symbol, matched by name from AST call sites and ranked by same file, same directory, then receiver type; callers also include type usages and member accesses (filters external stdlib noise; qualify overloaded names). | `symbol_name` (req), `file_path` (opt), `direction` ("callers" \| "callees", def: callers), `include_external` (opt, def: false) | `symbol`, `name`, `file`, `path` |
| `blast_radius` | Multi-hop reverse reachability (CTEs) & targeted test prediction. | `symbol` (opt), `file` (opt), `depth` (opt, def: 2), `limit` (opt) | `name`, `path`, `impact` |
| `find_structural_facts` | Queries framework facts (routes, SQL queries, config keys, tables). Lists all categories when omitted. | `category` (opt), `path` (opt), `limit` (opt) | `cat`, `kind`, `type`, `file`, `file_path` |
| `edit_file` | Replaces text in any file without reading it first. Finds `old_text` exactly, then ignoring indentation. Refuses a match that occurs more than once, overlapping matches included, unless `occurrence` is set, and names up to ten matching lines. | `file_path` (req), `old_text` (req), `new_text` (req), `occurrence` (opt, "only" \| "first" \| "last" \| "all", def: only) | `file`, `path`, `old`, `find`, `new`, `replace` |
| `replace_symbol_body` | Atomically replaces a symbol's implementation; `julie-extract check` validates the syntax for every language it parses (about 40), other paths report validation skipped. | `symbol_name` (req), `file_path` (req), `new_body` (req), `expected_body_hash` (opt) | `symbol`, `file`, `body`, `code` |
| `telemetry_summary` | Token savings with their coverage, call counts, and error rates from `~/.code-kb/telemetry.db`, across all workspaces or scoped to the current one. | `time_window` (opt, def: all), `workspace_only` (opt, def: false), `json` (opt) | `since`, `window` |

---

## CLI Commands (Direct Terminal Usage)

Every MCP capability can be executed directly from your terminal with 1:1 parity:

```bash
# Architectural outline of current repo (depth 2)
code-kb outline

# Skeleton of a specific file (implementation bodies stripped)
code-kb skeleton src/main.rs

# Lookup symbols by exact name or prefix (alias: code-kb symbol)
code-kb lookup Workspace --kind struct --path crates/code-kb-core

# Conceptual search over names, signatures, and docstrings (sha256 finds parseSha256Sidecar)
code-kb search "syntax validation concurrency"

# Same search with the rerank breakdown under each result (JSON: an `explain` object per result)
code-kb search "sha256 sidecar" --explain

# Retrieve exact implementation body of a symbol
code-kb body Workspace

# Get surgical context bundle: body + callees + types + tests (alias: code-kb slice)
code-kb context ensure_fresh_file

# Find callers or callees of a function (language-agnostically filters stdlib noise)
code-kb refs open_read_only --direction callers

# View callees including external standard library tokens
code-kb refs open_read_only --direction callees --include-external

# Predict blast radius and targeted tests to run for a symbol or file
code-kb blast-radius compute_blast_radius

# Zero-argument blast radius: auto-discovers uncommitted git working-tree changes
code-kb blast-radius
# (alias: code-kb impact)

# Query framework structural facts (or omit category to list all detected categories)
code-kb facts
code-kb facts config --path Cargo.toml
code-kb facts route --limit 10

# Atomically edit a symbol body with pre-flight syntax validation by julie-extract
code-kb edit my_func --file src/lib.rs --body "{\n    println!(\"hello\");\n}"

# Replace text in any file, without reading it first; --occurrence only|first|last|all
code-kb edit-file src/lib.rs --old "let timeout = 5;" --new "let timeout = 30;"
code-kb edit-file docs/guide.md --old "the old name" --new "the new name" --occurrence all

# View active log file and recent diagnostic messages
code-kb logs

# Token savings, call counts, and error rates (alias: code-kb telemetry)
code-kb stats --since month
code-kb stats --workspace

# Self-contained diagnostic bundle (versions, index facts, recent errors, log tail) with a
# pre-filled GitHub issue link; the /report-issue skill files it through `gh issue create`
code-kb bug-report --title "lookup returns nothing" --description "what went wrong"

# Output agent lifecycle hook payload (SessionStart / SubagentStart / PreInvocation)
code-kb hook SessionStart
code-kb hook SubagentStart
code-kb hook PreInvocation
```

---

## Telemetry and What "Saved" Means

`code-kb` records every tool call in `~/.code-kb/telemetry.db`. `telemetry_summary` and
`code-kb stats` report the calls, the latency, the error rate, the tokens served, and the
tokens saved.

Saved is the size, in estimated tokens, of the files the answer points into, minus the tokens
served. A skeleton, body, or context read is measured against its own file. A lookup, search,
references, blast-radius, or facts answer is measured against the distinct files its rows name,
at most 20 files. A call with no file to point at, such as an outline or a telemetry summary,
records no baseline and is not counted as saved.

The report states that coverage beside the number, so you can see how much of the window it
covers:

```text
Est. Tokens Saved: ~<saved> (baseline known for <K> of <M> calls)
```

Each tool row carries the same pair as `~N (K/M)`. Rows written before this measurement existed
carry no baseline and are never rewritten.

---

## Development

For contributors building `code-kb` from source:

### Prerequisites
- [Rust](https://www.rust-lang.org/) (1.95+ / Edition 2024)
- Extractor binary: Run `./scripts/restore-julie-extract.sh` to download the pinned [`julie-extract`](https://github.com/anortham/julie-extractors) binary

### Build and Install Locally
```bash
# Restore pinned julie-extract binary
./scripts/restore-julie-extract.sh

# Install code-kb binary from local checkout
cargo install --path crates/code-kb-cli --force
```

### Running Tests & Verification
```bash
# Run test suite
cargo test --workspace

# Run the plugin launcher and manifest tests
node --test tests/plugin/*.test.cjs

# Run release pre-flight verification
./scripts/release-preflight.sh
```

To run the Claude Code plugin from this checkout, build and load it. The launcher runs
`target/release/code-kb` when it exists, so no download happens:
```bash
cargo build --release
claude --plugin-dir .
```

---

## Architecture & Engineering Plans

`code-kb` was designed based on extensive benchmarking and retrospectives from earlier code intelligence engines:

- [**001: Architecture & Service Model**](docs/plans/001-architecture-and-service-model.md) — Multi-project workstation scope, Git worktree deduplication, and RAG vs. AST evaluation.
- [**002: Workspace Scoping & MCP**](docs/plans/002-workspace-scoping-and-mcp.md) — 1:1 session binding, eliminating workspace registries and `workspace_id` friction.
- [**003: Tool Catalog & Schema**](docs/plans/003-tool-catalog-and-schema.md) — The core read tools, token-minimized output formats, and `replace_symbol_body`.
- [**004: File Synchronization & Watchers**](docs/plans/004-file-synchronization-and-watchers.md) — 3-tier sync: tool-driven updates, JIT staleness guards, and debounced background watching.
- [**005: Cold-Start Reconciliation**](docs/plans/005-startup-reconciliation.md) — Detecting and reconciling offline edits in under 50ms on startup.
- [**006: Retrospective Lessons from Miller**](docs/plans/006-lessons-from-miller.md) — Analysis of calibration data, performance ledgers, and traps to avoid.
- [**010: Master Implementation Plan**](docs/plans/010-master-implementation-plan.md) — The phased engineering roadmap from workspace scaffolding to release.
- [**ADR 001: Zero Workspace Parameters**](docs/decisions/001-zero-workspace-parameters.md) — Decision record strictly forbidding workspace parameters in tool schemas.
- [**AGENTS.md Guidelines**](AGENTS.md) — Strict architectural invariants and rules for AI coding assistants working in this repository.

---

## License

Dual-licensed under MIT or Apache-2.0.