@fodx/codelens 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,13 @@ End-to-end workflow for a coding agent using codelens.
11
11
  2. cl_refresh
12
12
  → { indexedFiles: 812, totalChunks: 2400, status: "ready" }
13
13
 
14
- 3. cl_search(query: "session validation")
14
+ 3. cl_explore(query: "session validation flow")
15
+ → { query: "session validation flow", count: 3,
16
+ files: [{ path: "src/auth/session.ts", results: [{ handle: "chk_…", lines: "12-58", preview: "export function validateSession…" }] }],
17
+ related: [{ sourcePath: "src/auth/session.ts", path: "src/routes/login.ts", edgeType: "imported_by", hops: 1 }] }
18
+
19
+ # If you only need to locate a handle, use the leaner search tool:
20
+ cl_search(query: "session validation")
15
21
  → { query: "session validation", count: 1, results: [
16
22
  { handle: "chk_…", path: "src/auth/session.ts", lines: "12-58",
17
23
  score: 0.92, why: "fts,symbol,graph", preview: "export function validateSession(token: string): boolean" }
@@ -24,6 +30,10 @@ End-to-end workflow for a coding agent using codelens.
24
30
  ]
25
31
  # TS/JS also populate `calls`/`references` and resolve dynamic import().
26
32
 
33
+ # Before changing shared code, ask for the blast radius.
34
+ cl_impact(symbol: "validateSession", path: "src/auth/session.ts")
35
+ → { callers: [...], callees: [...], affectedFiles: [...], affectedTests: [...], confidenceNote: "…" }
36
+
27
37
  # Orientation (optional): outline a file or directory without reading it.
28
38
  cl_map(path: "src/auth")
29
39
  → files: [{ path: "src/auth/session.ts", symbols: [{ name: "validateSession", kind: "function", signature: "export function validateSession(token: string): boolean" }] }]
@@ -37,6 +47,14 @@ End-to-end workflow for a coding agent using codelens.
37
47
  8. cl_load(name: "auth-investigation") # after compaction
38
48
  ```
39
49
 
50
+ ## Tool choice
51
+
52
+ - Use `cl_explore` for broad questions: "how does X work?", "show the flow around Y", or surveying an unfamiliar area. It combines search, compact source previews, and relationships in one call.
53
+ - Use `cl_search` when you only need ranked handles/locations.
54
+ - Use `cl_related` to expand from a known file.
55
+ - Use `cl_impact` before editing shared code to see callers/callees/affected tests.
56
+ - Use `cl_expand` (or raw read) for exact current file content before editing.
57
+
40
58
  ## Branch switch
41
59
 
42
60
  ```
@@ -46,6 +64,10 @@ cl_refresh → builds feature-b index; main's results no longer leak in
46
64
  ```
47
65
 
48
66
 
67
+ ## Freshness and stale results
68
+
69
+ Query tools reconcile changed files before answering. If a response includes `freshness: "partial"`, `pendingFiles`, or per-result `stale:true`, read those stale files directly (`cl_expand` or raw read) before relying on indexed previews/edges.
70
+
49
71
  ## Saving context across compaction
50
72
 
51
73
  `cl_save` / `cl_load` persist named handle sets in a **separate** DB that
@@ -0,0 +1,154 @@
1
+ # How CodeLens works
2
+
3
+ CodeLens is a **branch-aware local code knowledge retrieval engine**. It indexes
4
+ the current repo/branch into SQLite and lets coding agents ask "what code is
5
+ relevant to X?" via compact ranked handles — instead of grep/find/read flooding
6
+ their context window. No chat LLM is used anywhere in the core path.
7
+
8
+ ## Architecture
9
+
10
+ ```
11
+ Agent (Pi / Claude Code / Cursor / Gemini / opencode / Codex)
12
+ │ MCP stdio
13
+
14
+ CodeLens MCP server ──▶ CLI (codelens <subcommand>)
15
+
16
+ ├── Git scope detector (repo / worktree / branch / HEAD / dirty)
17
+ ├── Index manager (per-branch index identity)
18
+ ├── File scanner (.gitignore-aware, binary/size filters)
19
+ ├── FTS5 indexer (structure-aware chunks + content hash)
20
+ ├── Tree-sitter symbol extractor (11 grammars, text fallback)
21
+ ├── Source graph builder (imports / defines / tests / belongs_to)
22
+ ├── Graph query (recursive CTE + bounded BFS)
23
+ ├── Freshness checker (mtime/size fast → hash on suspicion)
24
+ ├── TTL pruner (never-delete guards)
25
+ ├── Saved-context store (separate DB, survives rebuilds)
26
+ └── Usage tracker (global, actual-file-size savings)
27
+
28
+
29
+ SQLite
30
+ ├── per-branch index DB (~/.codelens/indexes/index-<repoId>.db)
31
+ ├── saved-contexts DB (~/.codelens/contexts/contexts-<repoId>.db)
32
+ └── global usage DB (~/.codelens/usage.db)
33
+ ```
34
+
35
+ ## The index layers
36
+
37
+ 1. **Files**: path, language, size, mtime, content hash.
38
+ 2. **FTS5 lexical**: structure-aware code chunks with line-based fallback and
39
+ Porter-stemming/BM25 ranking. Code files with extractable symbols are chunked
40
+ around outermost functions/classes/methods/types; oversized symbols and non-structural
41
+ gaps (imports, top-level statements, inter-symbol regions) are line-chunked.
42
+ Leading comment/decorator blocks are attached to the following symbol chunk.
43
+ Line fallback uses small overlap to reduce boundary loss. Chunks carry
44
+ `code` vs `prose`, `chunker`, `chunker_version`, and `symbol_id` when aligned
45
+ to a symbol. The match-only FTS text preserves the original chunk and appends
46
+ bounded, deduplicated identifier subtokens (for example `validateSession` →
47
+ `validate session`) so code-identifier queries can match without changing
48
+ snippets or `cl_expand` content.
49
+ 3. **Symbols** (tree-sitter): functions/classes/methods/types/exports/imports
50
+ with line ranges + signatures + exported flag. Parser-eligible files are
51
+ parsed once and the same tree-sitter tree is reused for symbols and edges;
52
+ structure-aware chunking consumes those extracted symbol ranges. 11 grammars
53
+ shipped; unknown languages fall back to text-only FTS.
54
+ 4. **Source graph**: edges `imports`, `defines`, `belongs_to`, `exports`,
55
+ `tests` (filename heuristics). Resolution handles TS ESM `.js`→`.ts`
56
+ substitution. Unresolved imports emit no edge (no wrong edges).
57
+ 5. *(No vector/semantic layer — removed; ranking is FTS + symbol + graph.)*
58
+
59
+ ## Branch isolation (the core idea)
60
+
61
+ Every index is scoped to `repoRoot + worktreePath + branch + HEAD`:
62
+
63
+ ```
64
+ index_id = sha256(repoRoot | worktreePath | branch | headSha)
65
+ ```
66
+
67
+ Every table row carries `index_id`; every query filters by it. So `git checkout`
68
+ activates/creates a different index automatically — results from `main` never
69
+ leak into `feature-b`. `cl_current` reports which index is active.
70
+
71
+ ## Freshness (local files are source of truth)
72
+
73
+ Before query tools answer (`cl_search`, `cl_explore`, `cl_related`, `cl_impact`, `cl_map`), `ensureFreshIndex` runs:
74
+ 1. Detect current git scope → activate/create the branch index.
75
+ 2. Scan files, diff `mtime`+`size` vs indexed rows (fast); hash only
76
+ changed/suspicious files.
77
+ 3. Reindex changed/new files in per-file transactions; drop deleted. Files with
78
+ chunks from an older/unknown `chunker_version` are also treated as changed, so
79
+ chunker improvements roll forward on the next refresh.
80
+ 4. Budget-bounded (default 500ms); if incomplete, surface
81
+ `freshness:"partial"` + `pendingFiles`. A chunker-version bump can require a
82
+ full budget-bounded re-chunk over several refresh cycles.
83
+
84
+ `cl_expand` **always reads current disk** (never stale stored text). A file
85
+ watcher (server mode) short-circuits the scan when nothing changed, with a 5s
86
+ periodic full-scan backstop.
87
+
88
+ **Edit behavior:** when the agent edits a file, the *next query tool call*
89
+ auto-refreshes and reindexes it (lazy, not eager at edit time). If the refresh
90
+ budget is exhausted, known-stale paths are surfaced with `stale:true` and
91
+ `freshness:"partial"` so the agent can read those files directly.
92
+
93
+ ## Ranking (hybrid)
94
+
95
+ `cl_search` fuses lexical, structural, graph, path, and code/prose signals with
96
+ weights from `src/search/rank.ts`:
97
+
98
+ ```
99
+ score = fts×0.34 + symbol×0.18 + graph×0.22 + code×0.08 + path×0.08 + exact×0.10
100
+ ```
101
+
102
+ - `fts`: BM25 normalized. Queries are expanded with the same bounded identifier
103
+ splitter used at index time, then quoted through the FTS path; expansion is
104
+ capped to avoid broadening queries or hurting latency.
105
+ - `symbol`: full signal when the chunk's `symbol_id` name partially matches a
106
+ query term; lower-strength file-level symbol match is kept as fallback.
107
+ - `exact`: full signal when the chunk's `symbol_id` name exactly matches a query
108
+ term; lower-strength file-level exact match is kept as fallback.
109
+ - `graph`: 1 if the file is graph-proximate to top lexical results.
110
+ - `path`: query term appears in the file path/name.
111
+ - `code`: modest boost for `code` chunks over `prose` (docs), so code discovery
112
+ isn't drowned out by markdown. Pass `contentType:"code"` to filter to source
113
+ only.
114
+
115
+ `cl_related` runs a recursive-CTE BFS over the `edges` table (direction-aware,
116
+ cycle-guarded, depth-capped at 3).
117
+
118
+ ## Concurrency & recovery
119
+
120
+ - **WAL mode** + a single-writer queue + a cross-process advisory lease
121
+ (`index_locks`) so two agent processes on the same repo never corrupt rows;
122
+ readers see the prior committed snapshot.
123
+ - **Corruption recovery:** `PRAGMA quick_check` on startup + on query error →
124
+ rebuild the core index. Saved contexts live in a **separate DB** and survive.
125
+ - **Schema versioning:** version guard refuses a newer-than-code DB; migrations
126
+ are transactional with a pre-migration backup.
127
+
128
+ ## TTL
129
+
130
+ Inactive indexes are pruned automatically (startup + periodic): inactive branch
131
+ 14d, detached 3d, worktree 48h. **Never** deletes the active index, pinned
132
+ indexes, locked indexes, or recently-accessed ones. `cl_prune` (manual),
133
+ `cl_drop` (explicit, refuses active/pinned).
134
+
135
+ ## Saved contexts
136
+
137
+ `cl_save`/`cl_load` persist named handle sets + notes in a **separate**
138
+ contexts DB (`~/.codelens/contexts/`), keyed by repo. They survive core-index
139
+ rebuilds. Items reference path+symbol (stable across reindex), not chunk ids.
140
+ Pin to prevent TTL deletion.
141
+
142
+ ## Usage tracking
143
+
144
+ Global (`~/.codelens/usage.db`): per-tool calls, bytes served, and an estimated
145
+ context saving computed from **actual indexed file sizes** of the result files.
146
+ Discovery tools (`cl_search`, `cl_explore`, `cl_related`, `cl_impact`) accrue savings. See
147
+ [`docs/usage-metrics.md`](usage-metrics.md).
148
+
149
+ ## Distribution
150
+
151
+ Currently builds from source (Node ≥ 22.5) via `install.sh`/`install.ps1`,
152
+ which also wires agent configs + slash commands. A self-contained bundle
153
+ (vendored Node) like some other tools is future work once published. The `cl_*`
154
+ MCP tools are the same surface across every host.
package/docs/routing.md CHANGED
@@ -14,14 +14,16 @@ right tool for the job.
14
14
 
15
15
  Prefer codelens when:
16
16
  - you don't know the exact name/string (semantic or conceptual search via `cl_search`)
17
- - you need relationships importers, tests, callers (`cl_related`) — or a
18
- per-file outline / repo map (`cl_map`)
17
+ - you need broad orientation in one call (`cl_explore`) — "how does X work?", flows, or unfamiliar areas
18
+ - you need relationships importers, tests, callers (`cl_related`) — or blast radius before edits (`cl_impact`)
19
+ - you need a per-file outline / repo map (`cl_map`)
19
20
  - the repo is large or unfamiliar, or you'd otherwise grep + read many files
20
21
  - branch-scoped correctness matters (results won't leak across branches)
21
22
 
22
23
  Then use `cl_expand` to read the exact current content of a chosen target (it
23
24
  reads from disk — never stale), and `cl_save`/`cl_load` to persist working
24
- context across compaction.
25
+ context across compaction. If a query result has `stale:true`, read that file
26
+ from disk before relying on indexed snippets/edges.
25
27
 
26
28
  ## When raw grep/find/read is fine (or better)
27
29
 
@@ -44,9 +46,11 @@ branch's index automatically.
44
46
 
45
47
  ## Freshness
46
48
 
47
- `cl_search` auto-refreshes changed files before returning (budget-bounded). If
48
- the response carries `freshness: "partial"` and `pendingFiles > 0`, some very
49
- recent edits may not yet be reflected call `cl_refresh` or re-query.
49
+ Query tools auto-refresh changed files before returning (budget-bounded). If
50
+ the response carries `freshness: "partial"`, `pendingFiles > 0`, or per-result
51
+ `stale:true`, some recent edits were not reindexed within the budget. Read those
52
+ files directly with `cl_expand`/raw read, then call `cl_refresh` or re-query when
53
+ you need indexed relationships to catch up.
50
54
 
51
55
  ## Tool quick reference
52
56
 
@@ -55,7 +59,9 @@ recent edits may not yet be reflected — call `cl_refresh` or re-query.
55
59
  | `cl_current` | repo/branch/index status + freshness |
56
60
  | `cl_refresh` | build/update the current branch index |
57
61
  | `cl_search` | hybrid ranked search → compact handles |
62
+ | `cl_explore` | one-call grouped search + previews + relationship map |
58
63
  | `cl_related` | graph neighbors (imports/tests/callers) |
64
+ | `cl_impact` | callers/callees/affected files/tests before edits |
59
65
  | `cl_map` | per-file symbol outline (repo map) |
60
66
  | `cl_expand` | exact current file content by path/range |
61
67
  | `cl_save` / `cl_load` | persist + reload working context |
package/docs/tools.md CHANGED
@@ -15,24 +15,37 @@ JSON-serialized text content.
15
15
 
16
16
  ## cl_search
17
17
  - **Input**: `{ query: string, limit?: number=5, cursor?: string, contentType?: "code"|"prose", related?: boolean, snippet?: "none"|"headline"|"compact"|"full" }`
18
- - **Returns**: `{ indexId, query, count, results:[{handle,path,lines,score,why,preview}], freshness, nextCursor?, pendingFiles?, related? }`
19
- - `lines` is `"start-end"`; `why` is a comma-joined signal string; `preview` is a short highlighted snippet (empty when `snippet:"none"`). Use `handle` with `cl_expand`/`cl_save`. Pagination uses the top-level `nextCursor` (no per-result cursor).
18
+ - **Returns**: `{ indexId, query, count, results:[{handle,path,lines,score,why,preview,stale?}], freshness, nextCursor?, pendingFiles?, related? }`
19
+ - `lines` is `"start-end"`; `why` is a comma-joined signal string; `preview` is a short highlighted snippet (empty when `snippet:"none"`). Use `handle` with `cl_expand`/`cl_save`. Pagination uses the top-level `nextCursor` (no per-result cursor). If `stale:true`, read that file from disk (`cl_expand`/raw read) before relying on indexed content.
20
20
  - **Use**: intent-level code discovery.
21
21
  - **Identifier matching**: code identifiers are indexed with bounded subtokens (`validateSession` also matches `session`) in the match-only FTS text. Query expansion uses the same bounded splitter and preserves snippets/handles from stored chunk content.
22
22
  - **`snippet` (preview verbosity)**: default is signature-first `headline` (richer `compact` for the top ~3 results), which keeps payloads small. `none` returns path+lines only (fetch with `cl_expand`); `compact`/`full` return larger code windows. Explicitly setting `snippet` applies that mode to all results.
23
23
  - **`why` signals**: `fts|symbol|exact|graph|path|code` (exact = exact symbol-name match; path = query term in the file path). Ranking is deterministic with a stable tie-break.
24
24
  - **Line-range format**: `cl_search` reports `lines` as a `"start-end"` string for compact display; `cl_map` and `cl_expand` use numeric `startLine`/`endLine` for programmatic use. This difference is intentional.
25
25
 
26
+ ## cl_explore
27
+ - **Input**: `{ query: string, limit?: number=8, cursor?: string, contentType?: "code"|"prose", snippet?: "none"|"headline"|"compact"|"full", relatedDepth?: number=1, maxFiles?: number=6, maxResultsPerFile?: number=3, maxRelated?: number=20 }`
28
+ - **Returns**: `{ indexId, query, count, files:[{path, stale?, results:[{handle,lines,score,why,preview,signature?,collapsed?,stale?}]}], related:[{sourcePath,path,edgeType,hops,confidence,stale?}], freshness, pendingFiles?, nextCursor?, truncated? }`
29
+ - **Use**: broad orientation in one call — "how does X work?", "show the flow around Y", or surveying an unfamiliar area. It fuses `cl_search` + grouped previews + graph relationships; use `cl_search` when you only need to locate handles.
30
+
26
31
  ## cl_related
27
32
  - **Input**: `{ path: string, types?: string[], depth?: number=2, direction?: "out"|"in"|"both" }`
28
- - **Returns**: `{ indexId, results:[{handle,path,edgeType,hops,confidence}] }`
33
+ - **Returns**: `{ indexId, results:[{handle,path,edgeType,hops,confidence,stale?}], freshness?, pendingFiles? }`
29
34
  - **Edge types**: `imports|imported_by|tests|calls|references|defines|exports|belongs_to` (TS/JS populate `calls`/`references` and resolve dynamic `import()`).
30
35
 
36
+ ## cl_impact
37
+ - **Input**: `{ symbol?: string, path?: string, depth?: number=2, includeTests?: boolean=true }`
38
+ - **Returns**: `{ indexId, target?, candidates?, callers, callees, affectedFiles, affectedTests, depth, summary?, confidenceNote, freshness?, pendingFiles? }`
39
+ - **Use**: before changing shared code. Pass `symbol` plus `path` when possible; if a symbol is ambiguous, CodeLens returns `candidates` instead of guessing. Impact is edge-derived and includes confidence/hop counts plus provenance labels (`graph` or conservative `path-heuristic`); use `cl_expand` to inspect exact current code before editing.
40
+
31
41
  ## cl_map
32
42
  - **Input**: `{ path?: string, limit?: number=50, all?: boolean }`
33
- - **Returns**: `{ indexId, files:[{path, symbols:[{name,kind,signature,startLine,endLine,exported}]}], fileCount, truncated }`
43
+ - **Returns**: `{ indexId, files:[{path, stale?, symbols:[{name,kind,signature,startLine,endLine,exported}]}], fileCount, truncated, freshness?, pendingFiles? }`
34
44
  - **Use**: outline / repo-map for orientation — per-file symbol signatures from the index (no file re-read). Defaults to exported symbols; pass `all:true` for everything. File-capped (default 50, max 200) with a `truncated` flag.
35
45
 
46
+ ## Freshness and stale flags
47
+ Query tools perform a budget-bounded reconciliation before answering. If the response has `freshness:"partial"` and `pendingFiles > 0`, some changed files were not reindexed within the budget. Results/files with `stale:true` point at those known-stale paths; read them directly with `cl_expand` or a raw read before depending on indexed previews/edges.
48
+
36
49
  ## cl_expand
37
50
  - **Input**: `{ path?: string, handle?: string, startLine?: number, endLine?: number, budget?: number=4000 }`
38
51
  - **Returns**: `{ path, startLine, endLine, content, truncated, chars }`
@@ -0,0 +1,89 @@
1
+ # Usage metrics — how "saved" is calculated
2
+
3
+ `cl_usage` reports per-tool call counts, bytes served, and an **estimated**
4
+ context-window saving. The saving is an *estimate*, not a measurement — this
5
+ page explains exactly how it's computed and its limits.
6
+
7
+ ## Which tools are tracked
8
+
9
+ Only the agent's **retrieval + context-management** tools are tracked as
10
+ "usage" — the ones that represent the agent actually using CodeLens to
11
+ find/read/save code:
12
+
13
+ | Tool | tracked | calls | bytes_served | bytes_saved |
14
+ |------|---------|-------|--------------|-------------|
15
+ | `cl_search` | ✅ | ✅ | ✅ | ✅ (discovery) |
16
+ | `cl_explore` | ✅ | ✅ | ✅ | ✅ (discovery) |
17
+ | `cl_related` | ✅ | ✅ | ✅ | ✅ (discovery) |
18
+ | `cl_impact` | ✅ | ✅ | ✅ | ✅ (discovery) |
19
+ | `cl_expand` | ✅ | ✅ | ✅ | 0 (it *is* the scoped read step) |
20
+ | `cl_save` / `cl_load` | ✅ | ✅ | ✅ | 0 (context management) |
21
+
22
+ **Operational tools are NOT tracked** (they're maintenance, not usage):
23
+ `cl_refresh`, `cl_doctor`, `cl_stats`, `cl_prune`, `cl_drop`, `cl_current`,
24
+ `cl_usage`. So `cl_refresh` (building the index) does not appear in the usage
25
+ report, and checking `cl_usage` never inflates the numbers.
26
+
27
+ Only the **discovery** tools (`cl_search`, `cl_explore`, `cl_related`, `cl_impact`) accrue `bytes_saved` —
28
+ the ones that replace "grep + read a bunch of files" with compact indexed context.
29
+
30
+ ## The formula (refined — actual file sizes)
31
+
32
+ For a discovery call, CodeLens computes savings from the **real sizes of the
33
+ files in the results**, which it already indexes (`files.size`):
34
+
35
+ ```
36
+ saved = max(0, Σ(distinct result files' indexed sizes) − bytesServed)
37
+ ```
38
+
39
+ - `distinct result files` = the unique paths among the returned handles/files
40
+ (`cl_search`/`cl_related` carry `results[].path`; `cl_explore` carries
41
+ `files[].path`; `cl_impact` carries paths in target/candidates/callers/callees/affected lists).
42
+ - `indexed sizes` = `files.size` for those paths in the current branch index.
43
+ - `bytesServed` = bytes of the JSON actually sent to the model.
44
+ - **Capped at 50 distinct files** so a `cl_related` result returning 100
45
+ importers doesn't inflate the total (the agent wouldn't read all 100
46
+ without the tool).
47
+
48
+ **Counterfactual being modeled:** without the index, the agent would `grep` +
49
+ `read` the relevant files (whole-file reads at their real sizes); with the tool
50
+ it got compact handles. The difference is the saved context.
51
+
52
+ ### Fallback (flat proxy)
53
+
54
+ If the size lookup fails (e.g. index not ready, paths not yet indexed), CodeLens
55
+ falls back to a flat proxy:
56
+
57
+ ```
58
+ saved = max(0, handles × 4096 − bytesServed)
59
+ ```
60
+
61
+ where `4096` is a rough average file size and `handles` = number of result
62
+ entries. This is the older, less-accurate estimate, kept only as a graceful
63
+ fallback.
64
+
65
+ ## Honest limits
66
+
67
+ 1. **It's a counterfactual estimate, not a measurement.** We don't know exactly
68
+ which files the agent *would have* read without the tool — we assume the
69
+ result files, whole.
70
+ 2. **Whole-file assumption.** We credit the full file size, but a raw `read`
71
+ might be partial, or the agent might read only the relevant part — so the
72
+ estimate can overstate for large files with small relevant regions.
73
+ 3. **No grep-output cost.** It ignores the bytes `grep` itself would have dumped
74
+ into context, which would make the real saving *larger*.
75
+ 4. **No multi-round exploration.** It counts one call, not the exploration
76
+ rounds the agent avoids.
77
+ 5. The 50-file cap is a judgment call to curb broad relationship/impact results.
78
+
79
+ Net: treat `saved(est)` as an order-of-magnitude indicator of how much context
80
+ the index tools are sparing, not an audited figure.
81
+
82
+ ## Storage
83
+
84
+ Usage is **global** (`~/.codelens/usage.db`), aggregated across all repos, with
85
+ a `(tool, repo_id)` key so `cl_usage` can break it down per repo. It survives
86
+ restarts and core-index rebuilds (it's separate from the per-branch index DBs).
87
+
88
+ Reset with `cl_usage` is not exposed as a tool; from code, `UsageTracker.reset()`
89
+ clears it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fodx/codelens",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Local, branch-aware code search & relation graph. SQLite FTS5 + tree-sitter symbols + source-graph edges, exposed as an MCP server and CLI. No chat LLM required.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,8 +39,10 @@
39
39
  "adapters/pi",
40
40
  "README.md",
41
41
  "docs/agent-guide.md",
42
+ "docs/how-it-works.md",
42
43
  "docs/routing.md",
43
44
  "docs/tools.md",
45
+ "docs/usage-metrics.md",
44
46
  "docs/codelens-preview.png"
45
47
  ],
46
48
  "pi": {
@@ -58,7 +60,8 @@
58
60
  "mcp:smoke": "node build/src/server.js --smoke",
59
61
  "start": "node build/src/server.js",
60
62
  "benchmark": "npx tsx bench/run.ts",
61
- "quality": "npx tsx bench/quality.ts"
63
+ "quality": "npx tsx bench/quality.ts",
64
+ "eval:agent": "npx tsx bench/agent-eval.ts"
62
65
  },
63
66
  "dependencies": {
64
67
  "@modelcontextprotocol/sdk": "^1.26.0",