@fodx/codelens 2.0.1 → 2.1.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 +18 -10
- package/adapters/pi/extension.json +1 -1
- package/build/src/cli.js +5 -2
- package/build/src/cli.js.map +1 -1
- package/build/src/installer/agents.js +37 -19
- package/build/src/installer/agents.js.map +1 -1
- package/build/src/obs/usage.js +33 -5
- package/build/src/obs/usage.js.map +1 -1
- package/build/src/runtime/root.js +31 -0
- package/build/src/runtime/root.js.map +1 -0
- package/build/src/server.js +76 -15
- package/build/src/server.js.map +1 -1
- package/build/src/tools/explore.js +40 -3
- package/build/src/tools/explore.js.map +1 -1
- package/build/src/tools/impact.js +22 -5
- package/build/src/tools/impact.js.map +1 -1
- package/build/src/tools/registry.js +7 -1
- package/build/src/tools/registry.js.map +1 -1
- package/docs/how-it-works.md +154 -0
- package/docs/routing.md +9 -1
- package/docs/tools.md +4 -4
- package/docs/usage-metrics.md +89 -0
- package/package.json +5 -2
package/docs/routing.md
CHANGED
|
@@ -25,6 +25,12 @@ reads from disk — never stale), and `cl_save`/`cl_load` to persist working
|
|
|
25
25
|
context across compaction. If a query result has `stale:true`, read that file
|
|
26
26
|
from disk before relying on indexed snippets/edges.
|
|
27
27
|
|
|
28
|
+
If `cl_current.inGitRepo` is false or `repo` points outside the current
|
|
29
|
+
workspace, CodeLens is not attached to this workspace. Report the setup issue and
|
|
30
|
+
ask the user to run `codelens install --target cursor --location local --yes`
|
|
31
|
+
from the workspace root (or restart the MCP server after roots attach). Do not
|
|
32
|
+
silently fall back to raw `find`/`grep` for discovery.
|
|
33
|
+
|
|
28
34
|
## When raw grep/find/read is fine (or better)
|
|
29
35
|
|
|
30
36
|
- you already know an exact string/symbol/path
|
|
@@ -42,7 +48,9 @@ you're looking for.
|
|
|
42
48
|
Results are scoped to the **current branch/worktree index only** by default.
|
|
43
49
|
After `git checkout`, results will not leak from the old branch. If you switch
|
|
44
50
|
branches mid-task, call `cl_current` again; the tool activates/creates the new
|
|
45
|
-
branch's index automatically.
|
|
51
|
+
branch's index automatically. MCP clients that provide Roots let CodeLens attach
|
|
52
|
+
to the active workspace even from a global MCP config; otherwise use `--cwd` or
|
|
53
|
+
project-local MCP config.
|
|
46
54
|
|
|
47
55
|
## Freshness
|
|
48
56
|
|
package/docs/tools.md
CHANGED
|
@@ -24,8 +24,8 @@ JSON-serialized text content.
|
|
|
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
26
|
## cl_explore
|
|
27
|
-
- **Input**: `{ query: string, limit?: number=8, cursor?: string, contentType?: "code"|"prose", snippet?: "none"|"headline"|"compact"|"full", relatedDepth?: number=1 }`
|
|
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? }`
|
|
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
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
30
|
|
|
31
31
|
## cl_related
|
|
@@ -35,8 +35,8 @@ JSON-serialized text content.
|
|
|
35
35
|
|
|
36
36
|
## cl_impact
|
|
37
37
|
- **Input**: `{ symbol?: string, path?: string, depth?: number=2, includeTests?: boolean=true }`
|
|
38
|
-
- **Returns**: `{ indexId, target?, candidates?, callers, callees, affectedFiles, affectedTests, depth, 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; use `cl_expand` to inspect exact current code before editing.
|
|
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
40
|
|
|
41
41
|
## cl_map
|
|
42
42
|
- **Input**: `{ path?: string, limit?: number=50, all?: boolean }`
|
|
@@ -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.
|
|
3
|
+
"version": "2.1.1",
|
|
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",
|