sverklo 0.27.0 → 0.28.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 +84 -74
- package/dist/bin/sverklo.js +38 -10
- package/dist/bin/sverklo.js.map +1 -1
- package/dist/src/audit-prompt.js +10 -10
- package/dist/src/doctor.js +23 -15
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/init.d.ts +1 -1
- package/dist/src/init.js +39 -29
- package/dist/src/init.js.map +1 -1
- package/dist/src/prove.d.ts +34 -0
- package/dist/src/prove.js +199 -0
- package/dist/src/prove.js.map +1 -0
- package/dist/src/server/assets/dashboard.js +2 -2
- package/dist/src/server/hints.js +40 -41
- package/dist/src/server/hints.js.map +1 -1
- package/dist/src/server/mcp-server.d.ts +10 -0
- package/dist/src/server/mcp-server.js +218 -119
- package/dist/src/server/mcp-server.js.map +1 -1
- package/dist/src/server/prompts.js +37 -37
- package/dist/src/server/prompts.js.map +1 -1
- package/dist/src/server/tool-overrides.js +71 -59
- package/dist/src/server/tool-overrides.js.map +1 -1
- package/dist/src/server/tools/ask.js +7 -7
- package/dist/src/server/tools/ask.js.map +1 -1
- package/dist/src/server/tools/ast-grep.js +2 -2
- package/dist/src/server/tools/ast-grep.js.map +1 -1
- package/dist/src/server/tools/audit.js +5 -5
- package/dist/src/server/tools/audit.js.map +1 -1
- package/dist/src/server/tools/clusters.js +3 -3
- package/dist/src/server/tools/clusters.js.map +1 -1
- package/dist/src/server/tools/concepts.js +6 -6
- package/dist/src/server/tools/concepts.js.map +1 -1
- package/dist/src/server/tools/context.js +7 -7
- package/dist/src/server/tools/context.js.map +1 -1
- package/dist/src/server/tools/critique.js +4 -4
- package/dist/src/server/tools/critique.js.map +1 -1
- package/dist/src/server/tools/ctx-handles.js +3 -3
- package/dist/src/server/tools/ctx-handles.js.map +1 -1
- package/dist/src/server/tools/dependencies.js +3 -3
- package/dist/src/server/tools/dependencies.js.map +1 -1
- package/dist/src/server/tools/diff-search.js +2 -2
- package/dist/src/server/tools/diff-search.js.map +1 -1
- package/dist/src/server/tools/find-references.js +3 -3
- package/dist/src/server/tools/find-references.js.map +1 -1
- package/dist/src/server/tools/forget.js +3 -3
- package/dist/src/server/tools/forget.js.map +1 -1
- package/dist/src/server/tools/impact.js +1 -1
- package/dist/src/server/tools/impact.js.map +1 -1
- package/dist/src/server/tools/index-status.js +21 -21
- package/dist/src/server/tools/index-status.js.map +1 -1
- package/dist/src/server/tools/investigate.js +5 -5
- package/dist/src/server/tools/investigate.js.map +1 -1
- package/dist/src/server/tools/list-repos.js +1 -1
- package/dist/src/server/tools/list-repos.js.map +1 -1
- package/dist/src/server/tools/lookup.js +4 -4
- package/dist/src/server/tools/lookup.js.map +1 -1
- package/dist/src/server/tools/memories.js +3 -3
- package/dist/src/server/tools/memories.js.map +1 -1
- package/dist/src/server/tools/overview.js +3 -3
- package/dist/src/server/tools/overview.js.map +1 -1
- package/dist/src/server/tools/patterns.js +1 -1
- package/dist/src/server/tools/patterns.js.map +1 -1
- package/dist/src/server/tools/pin.js +2 -2
- package/dist/src/server/tools/pin.js.map +1 -1
- package/dist/src/server/tools/post-filter.js +3 -3
- package/dist/src/server/tools/post-filter.js.map +1 -1
- package/dist/src/server/tools/recall.js +4 -4
- package/dist/src/server/tools/recall.js.map +1 -1
- package/dist/src/server/tools/remember.js +2 -2
- package/dist/src/server/tools/remember.js.map +1 -1
- package/dist/src/server/tools/review-diff.js +5 -5
- package/dist/src/server/tools/review-diff.js.map +1 -1
- package/dist/src/server/tools/search-iterative.js +10 -10
- package/dist/src/server/tools/search-iterative.js.map +1 -1
- package/dist/src/server/tools/search.js +5 -5
- package/dist/src/server/tools/search.js.map +1 -1
- package/dist/src/server/tools/test-map.js +3 -3
- package/dist/src/server/tools/test-map.js.map +1 -1
- package/dist/src/server/tools/tier.js +4 -4
- package/dist/src/server/tools/tier.js.map +1 -1
- package/dist/src/server/tools/verify.js +4 -4
- package/dist/src/server/tools/verify.js.map +1 -1
- package/dist/src/server/tools/wakeup.js +3 -3
- package/dist/src/server/tools/wakeup.js.map +1 -1
- package/dist/src/server/trajectory.js +20 -8
- package/dist/src/server/trajectory.js.map +1 -1
- package/dist/src/utils/ollama.js +1 -1
- package/dist/src/utils/ollama.js.map +1 -1
- package/package.json +2 -2
- package/src/skills/sverklo-onboard.md +4 -4
- package/src/skills/sverklo-refactor.md +5 -5
- package/src/skills/sverklo-review.md +3 -3
package/README.md
CHANGED
|
@@ -6,19 +6,27 @@
|
|
|
6
6
|
🇬🇧 <b>English</b> · 🇨🇳 <a href="./README-zh-CN.md">中文</a>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
>
|
|
11
|
-
> Training data is the map. Your codebase is the territory. **Sverklo gives the agent the territory.**
|
|
9
|
+
# Give your coding agent repo memory.
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
Sverklo gives coding agents repo memory: symbols, callers, diffs, blast radius, and git-pinned decisions before they edit. It is an open-source local-first MCP server for Claude Code, Cursor, Windsurf, Codex CLI, and any MCP-speaking coding agent.
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
**Local-first** ◦ MIT ◦ no API keys ◦ no code upload ◦ first run downloads a local ONNX model
|
|
14
|
+
|
|
15
|
+
Use grep when you know the exact string. Use Sverklo when the agent needs relationships: who calls this, what depends on it, what changed, and which project decisions still apply. The public bench covers 180 hand-verified tasks across 6 OSS codebases; the methodology and ground truth live in [sverklo/sverklo-bench](https://github.com/sverklo/sverklo-bench). [Bench](https://sverklo.com/bench/) · [paper](https://doi.org/10.5281/zenodo.19802051) · [90-second demo](https://www.youtube.com/watch?v=OX7aEgdlqhQ)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g sverklo
|
|
19
|
+
cd your-project && sverklo init
|
|
20
|
+
sverklo prove
|
|
21
|
+
```
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
`sverklo init` writes the MCP config for your agent, appends local instructions to `AGENTS.md` or `CLAUDE.md`, and runs `sverklo doctor` to verify the handshake. `sverklo prove` then shows central files, a real symbol with callers, and the exact prompt to paste into your agent. Your code stays on your machine.
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
> *"The map is not the territory."* — Alfred Korzybski
|
|
26
|
+
>
|
|
27
|
+
> Training data is the map. Your codebase is the territory. **Sverklo gives the agent the territory.**
|
|
20
28
|
|
|
21
|
-
###
|
|
29
|
+
### Editor shortcuts
|
|
22
30
|
|
|
23
31
|
[](#claude-code) [](cursor://anysphere.cursor-deeplink/mcp/install?name=sverklo&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInN2ZXJrbG8iXX0=) [](https://insiders.vscode.dev/redirect/mcp/install?name=sverklo&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22sverklo%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=sverklo&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22sverklo%22%5D%7D&quality=insiders) [](#windsurf--zed--vs-code--jetbrains)
|
|
24
32
|
|
|
@@ -29,9 +37,9 @@
|
|
|
29
37
|
[](https://doi.org/10.5281/zenodo.19802051)
|
|
30
38
|
[](https://github.com/sverklo/sverklo/stargazers)
|
|
31
39
|
|
|
32
|
-
>
|
|
40
|
+
> If `sverklo prove` surfaces useful repo context, please star the repo. It is the fastest way to help other agent-heavy teams find it.
|
|
33
41
|
|
|
34
|
-

|
|
35
43
|
|
|
36
44
|
[](https://www.youtube.com/watch?v=OX7aEgdlqhQ)
|
|
37
45
|
|
|
@@ -67,9 +75,10 @@ Sverklo drills into your repo before the agent does — symbol graph, blast radi
|
|
|
67
75
|
```bash
|
|
68
76
|
npm install -g sverklo
|
|
69
77
|
cd your-project && sverklo init
|
|
78
|
+
sverklo prove
|
|
70
79
|
```
|
|
71
80
|
|
|
72
|
-
That's it. `sverklo init` auto-detects your installed AI coding agent (Claude Code, Cursor, Windsurf, Zed), writes the right MCP config, appends instructions to `AGENTS.md` if present (otherwise `CLAUDE.md`), and runs `sverklo doctor` to verify the setup. Works on macOS, Linux, and Windows. **No API keys. No cloud. Telemetry off by default.**
|
|
81
|
+
That's it. `sverklo init` auto-detects your installed AI coding agent (Claude Code, Cursor, Windsurf, Zed), writes the right MCP config, appends instructions to `AGENTS.md` if present (otherwise `CLAUDE.md`), and runs `sverklo doctor` to verify the setup. `sverklo prove` shows the first useful repo-memory proof from your own codebase. Works on macOS, Linux, and Windows. **No API keys. No cloud. Telemetry off by default.**
|
|
73
82
|
|
|
74
83
|
> The embedding model (`all-MiniLM-L6-v2` ONNX, ~86 MB) is downloaded from HuggingFace on first use into `~/.sverklo/models/` and cached forever — every subsequent run is fully offline.
|
|
75
84
|
|
|
@@ -81,7 +90,7 @@ That's it. `sverklo init` auto-detects your installed AI coding agent (Claude Co
|
|
|
81
90
|
|
|
82
91
|
Likely you've seen tools that look adjacent. The honest one-paragraph answers, with detailed comparisons linked.
|
|
83
92
|
|
|
84
|
-
**…just grep with extra steps?** No, but tuned grep is genuinely competitive
|
|
93
|
+
**…just grep with extra steps?** No, but tuned grep is genuinely competitive when you know the exact string. On the [180-task bench](https://sverklo.com/bench/), sverklo leads overall F1 (0.58 vs smart-grep's 0.34) while using about 35× fewer input tokens than naive grep and one tool call per task. For an AI agent inside a 200K context window, that's the load-bearing axis. For a human at a terminal, grep is still fine.
|
|
85
94
|
|
|
86
95
|
**…just Sourcegraph Cody?** Same retrieval surface (hybrid BM25 + vector + graph), different deployment model and license. Cody is source-available with enterprise per-developer pricing ($9-19/dev/mo); sverklo is MIT and runs on a laptop with no signup. [Full comparison →](https://sverklo.com/vs/sourcegraph-cody/)
|
|
87
96
|
|
|
@@ -103,7 +112,7 @@ If something is missing here that you'd ask about, [open an issue](https://githu
|
|
|
103
112
|
|
|
104
113
|
## What's new in 0.20
|
|
105
114
|
|
|
106
|
-
- **Contradiction detection on the bi-temporal memory layer.** `
|
|
115
|
+
- **Contradiction detection on the bi-temporal memory layer.** `memories mode:"conflicts"` surfaces pairs of active memories that share a pin (file path or symbol name) and may contradict — e.g., "JWT in middleware" vs "JWT in route handler" both pinned to `src/auth.ts`. Restricted to decision/preference/pattern categories (procedural/context are additive, not contradicting). Same-SHA pairs are skipped. Sorted by shared-pin count and age. Conservative by design: surfaces *candidates* for the agent or human to review, not auto-resolution. The bi-temporal model already preserved both sides of the contradiction; this just makes them findable.
|
|
107
116
|
|
|
108
117
|
## What's new in 0.19
|
|
109
118
|
|
|
@@ -116,7 +125,7 @@ If something is missing here that you'd ask about, [open an issue](https://githu
|
|
|
116
125
|
- **Windows pathing fixed.** `sverklo init` and `sverklo doctor` now work on Windows — absolute paths go through `path.basename()` and stored `relativePath` is normalized to forward slashes so every downstream consumer is cross-platform.
|
|
117
126
|
- **`npm run bench:swe`** — third-party-reproducible cross-repo eval. Clones 5 OSS repos (express, nestjs, vite, prisma, fastapi), runs 65 grounded questions, prints aggregated recall. PRs that add questions are welcome.
|
|
118
127
|
- **Tree-sitter parser opt-in.** `sverklo grammars install` (~3.5 MB across 6 languages) + `SVERKLO_PARSER=tree-sitter` routes the indexer through real ASTs for TypeScript/TSX/JavaScript/Python/Go/Rust. Silent regex fallback when grammars aren't installed. Plan to flip the default lives in [docs/parser-parity.md](./docs/parser-parity.md).
|
|
119
|
-
- **Workspace shared memory.** `sverklo workspace memory <name> add/list/search` plus `
|
|
128
|
+
- **Workspace shared memory.** `sverklo workspace memory <name> add/list/search` plus `remember scope:"workspace"` from the agent — write a decision once, query it from every other repo in the workspace. `recall` blends workspace results under project ones with a `[ws]` badge.
|
|
120
129
|
- **`sverklo memory export`** — markdown / Notion / JSON. Migrate your team's decision log to wherever it actually lives.
|
|
121
130
|
- **PR-bot inline review.** `sverklo review --format github-review-json` + the action's new `inline-comments: true` default posts per-line review comments via `pulls.createReview`, alongside the existing sticky summary.
|
|
122
131
|
- **VS Code extension scaffold** at [`extensions/vscode/`](./extensions/vscode/) with a pre-built `sverklo-vscode-0.1.0.vsix`. Inline caller-count decorations on every function header (`⟵ 47 callers`). Marketplace publish workflow ships dormant; install with `code --install-extension extensions/vscode/sverklo-vscode-0.1.0.vsix` today.
|
|
@@ -130,11 +139,11 @@ Every one of these is a query a real engineer asked a real AI assistant last wee
|
|
|
130
139
|
|
|
131
140
|
| The question | With Grep | With Sverklo |
|
|
132
141
|
|---|---|---|
|
|
133
|
-
| "Where is auth handled in this repo?" | `grep -r 'auth' .` -- 847 matches across tests, comments, unrelated vars, and one 2021 TODO | `
|
|
134
|
-
| "Can I safely rename `BillingAccount.charge`?" | `grep '\.charge('` -- 312 matches polluted by `recharge`, `discharge`, `Battery.charge` fixtures | `
|
|
135
|
-
| "Is this helper actually used anywhere?" | `grep -r 'parseFoo' .` -- 4 matches in 3 files. Are any real, or just string mentions? Read each one. | `
|
|
136
|
-
| "What's load-bearing in this codebase?" | `find . -name '*.ts' \| xargs wc -l \| sort` -- the biggest files. Not the most important ones. | `
|
|
137
|
-
| "Review this 40-file PR — what should I read first?" | Read them in the order git diff printed them | `
|
|
142
|
+
| "Where is auth handled in this repo?" | `grep -r 'auth' .` -- 847 matches across tests, comments, unrelated vars, and one 2021 TODO | `search "authentication flow"` -- top 5 files ranked by PageRank: middleware, JWT verifier, session store, login route, logout route |
|
|
143
|
+
| "Can I safely rename `BillingAccount.charge`?" | `grep '\.charge('` -- 312 matches polluted by `recharge`, `discharge`, `Battery.charge` fixtures | `impact BillingAccount.charge` -- 14 real callers, depth-ranked, with file paths and line numbers |
|
|
144
|
+
| "Is this helper actually used anywhere?" | `grep -r 'parseFoo' .` -- 4 matches in 3 files. Are any real, or just string mentions? Read each one. | `refs parseFoo` -- 0 real callers. Zero. Walk the symbol graph, not the text. Delete the function. |
|
|
145
|
+
| "What's load-bearing in this codebase?" | `find . -name '*.ts' \| xargs wc -l \| sort` -- the biggest files. Not the most important ones. | `overview` -- PageRank over the dep graph. The files the rest of the repo depends on, not the ones someone wrote too much code in. |
|
|
146
|
+
| "Review this 40-file PR — what should I read first?" | Read them in the order git diff printed them | `review_diff` -- risk-scored per file (touched-symbol importance x coverage x churn), prioritized order, flagged production files with no test changes |
|
|
138
147
|
|
|
139
148
|
If the answer to your question is "exact string X exists somewhere," grep wins. Use grep. If the answer is "which 5 files actually matter here, ranked by the graph," you need sverklo.
|
|
140
149
|
|
|
@@ -161,10 +170,10 @@ If the answer to your question is "exact string X exists somewhere," grep wins.
|
|
|
161
170
|
|
|
162
171
|
| Tool | What it does |
|
|
163
172
|
|------|-------------|
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
173
|
+
| `search` | Hybrid BM25 + vector + PageRank search. Find code without knowing the literal string. |
|
|
174
|
+
| `refs` | All references to a symbol, with caller context. Proves dead code with certainty. |
|
|
175
|
+
| `impact` | Walk the symbol graph, return ranked transitive callers — the real blast radius. |
|
|
176
|
+
| `review_diff` | Risk-scored review of `git diff`: touched-symbol importance x coverage x churn. |
|
|
168
177
|
|
|
169
178
|
[See all 37 tools below.](#full-tool-reference)
|
|
170
179
|
|
|
@@ -206,60 +215,60 @@ Pre-existing cycles and fan-in spikes don't trip the gate — only violations *i
|
|
|
206
215
|
### Search — find code without knowing the literal string
|
|
207
216
|
| Tool | What |
|
|
208
217
|
|------|------|
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
218
|
+
| `search` | Hybrid BM25 + ONNX vector + PageRank, fused with Reciprocal Rank Fusion |
|
|
219
|
+
| `search_iterative` | Wider candidate pool with refinement hints between rounds |
|
|
220
|
+
| `investigate` | Parallel multi-channel fan-out (FTS / vector / path / symbol) with per-channel RRF |
|
|
221
|
+
| `ask` | Natural-language router — concepts + investigate + refs in one call |
|
|
222
|
+
| `overview` | Structural codebase map ranked by PageRank importance |
|
|
223
|
+
| `lookup` | Find any function, class, or type by name (typo-tolerant) |
|
|
224
|
+
| `context` | One-call onboarding — combines overview, code, and saved memories |
|
|
225
|
+
| `ast_grep` | Structural pattern matching across the AST, not just text |
|
|
226
|
+
| `concepts` | Browse the LLM-derived concept index (themes across the codebase) |
|
|
227
|
+
| `clusters` | Semantic clusters of related symbols, computed offline |
|
|
228
|
+
| `patterns` | Query symbols tagged with a design pattern (observer, repository, validator, ...) |
|
|
220
229
|
|
|
221
230
|
### Impact — refactor without the regression
|
|
222
231
|
| Tool | What |
|
|
223
232
|
|------|------|
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
233
|
+
| `impact` | Walk the symbol graph, return ranked transitive callers (the real blast radius) |
|
|
234
|
+
| `refs` | Find all references to a symbol, with caller context |
|
|
235
|
+
| `deps` | File dependency graph — both directions, importers and imports |
|
|
236
|
+
| `audit` | **Lint your codebase for AI-readiness.** God nodes, hub files, dead code, circular deps, security smells, A-F health grade — all in one call |
|
|
228
237
|
|
|
229
238
|
### Review — diff-aware MR review with risk scoring
|
|
230
239
|
| Tool | What |
|
|
231
240
|
|------|------|
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `
|
|
235
|
-
| `
|
|
236
|
-
| `
|
|
241
|
+
| `review_diff` | Risk-scored review of `git diff` — touched-symbol importance x coverage x churn |
|
|
242
|
+
| `critique` | Second-pass critique of a review — what did the first read miss |
|
|
243
|
+
| `test_map` | Which tests cover which changed symbols; flag untested production changes |
|
|
244
|
+
| `diff_search` | Semantic search restricted to the changed surface of a diff |
|
|
245
|
+
| `verify` | Verify a quoted code span is still present at the cited SHA — citation gate |
|
|
237
246
|
|
|
238
247
|
### Memory — bi-temporal, git-aware, never stale
|
|
239
248
|
| Tool | What |
|
|
240
249
|
|------|------|
|
|
241
|
-
| `
|
|
242
|
-
| `
|
|
243
|
-
| `
|
|
244
|
-
| `
|
|
245
|
-
| `
|
|
246
|
-
| `
|
|
250
|
+
| `remember` | Save decisions, patterns, invariants — pinned to the current git SHA |
|
|
251
|
+
| `recall` | Semantic search over saved memories with staleness detection |
|
|
252
|
+
| `memories` | List all memories with health metrics (still valid / stale / orphaned) |
|
|
253
|
+
| `forget` | Delete a memory |
|
|
254
|
+
| `promote` / `demote` | Move memories between tiers (core / archive) |
|
|
255
|
+
| `pin` / `unpin` | Pin a memory to a file path or symbol so recall surfaces it without semantic search |
|
|
247
256
|
|
|
248
257
|
### Post-filter primitives — refine the last response without re-querying
|
|
249
258
|
| Tool | What |
|
|
250
259
|
|------|------|
|
|
251
|
-
| `
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
260
|
+
| `grep_results` | Grep inside the previous result block instead of re-running the search |
|
|
261
|
+
| `head_results` | Take the first N hits from the previous response |
|
|
262
|
+
| `ctx_peek` | Peek at a referenced span by its handle without expanding it fully |
|
|
263
|
+
| `ctx_slice` | Slice a stored response by line range |
|
|
264
|
+
| `ctx_grep` | Grep within a stored context window |
|
|
265
|
+
| `ctx_stats` | Token-budget stats for stored response handles |
|
|
257
266
|
|
|
258
267
|
### Index health
|
|
259
268
|
| Tool | What |
|
|
260
269
|
|------|------|
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
270
|
+
| `status` | Index health check, file counts, last update |
|
|
271
|
+
| `wakeup` | 500-token codebase summary for system prompts on agents that can't run MCP |
|
|
263
272
|
|
|
264
273
|
</details>
|
|
265
274
|
|
|
@@ -289,11 +298,11 @@ If a launch post tells you a tool is great for everything, close the tab.
|
|
|
289
298
|
|
|
290
299
|
### How do I stop Claude Code from hallucinating about my codebase?
|
|
291
300
|
|
|
292
|
-
Claude generates code from training-data patterns, not your repo. Without a symbol graph, it invents `getUserByEmail()` when your code uses `findByEmail()`. Sverklo grounds the agent in your actual symbol graph — `
|
|
301
|
+
Claude generates code from training-data patterns, not your repo. Without a symbol graph, it invents `getUserByEmail()` when your code uses `findByEmail()`. Sverklo grounds the agent in your actual symbol graph — `lookup` and `refs` resolve names to `file:line` and prove existence before the agent writes the call. Verifiable retrieval (`verify`) lets the agent re-check that a quoted span is still present at the cited SHA, so a stale citation gets caught instead of confabulated.
|
|
293
302
|
|
|
294
303
|
### Is there a local-first MCP server for codebase memory?
|
|
295
304
|
|
|
296
|
-
Yes — sverklo. `
|
|
305
|
+
Yes — sverklo. `remember` and `recall` ship a bi-temporal memory layer: every memory is pinned to the git SHA it was authored on, and `valid_until_sha` + `superseded_by` preserve a timeline of supersessions instead of overwriting. Recall is hybrid (FTS5 + cosine over an ONNX embedding) and runs entirely in embedded SQLite. No cloud, no API keys, no external vector database — unlike most "memory MCP" projects which require Zilliz, Milvus, or a managed Postgres+pgvector.
|
|
297
306
|
|
|
298
307
|
### Is there an open-source alternative to Sourcegraph Cody I can run locally?
|
|
299
308
|
|
|
@@ -395,23 +404,23 @@ Real measurements on real codebases. Reproducible via `npm run bench` ([methodol
|
|
|
395
404
|
|
|
396
405
|
- **Search p95 stays under 26 ms** even on a 4k-file monorepo
|
|
397
406
|
- **Impact analysis is sub-millisecond** — indexed SQL join, not a string scan
|
|
398
|
-
- **
|
|
407
|
+
- **24 languages:** 10 first-class structural parsers plus 14 regex-fallback languages
|
|
399
408
|
|
|
400
409
|
### Retrieval benchmark — bench:primitives
|
|
401
410
|
|
|
402
|
-
Hybrid retrieval F1 vs grep baselines on a
|
|
411
|
+
Hybrid retrieval F1 vs grep baselines on a 180-task hand-verified evaluation across six OSS codebases (express, lodash, sverklo, requests, flask, fastapi). Public report at **[sverklo.com/bench/](https://sverklo.com/bench/)** — including every slice where sverklo *loses*. Methodology repo: **[github.com/sverklo/sverklo-bench](https://github.com/sverklo/sverklo-bench)**.
|
|
403
412
|
|
|
404
|
-
Latest run (sverklo v0.20.
|
|
413
|
+
Latest published 180-task run (sverklo v0.20.21, May 2026):
|
|
405
414
|
|
|
406
|
-
| baseline | F1 |
|
|
407
|
-
|
|
408
|
-
| naive-grep | 0.
|
|
409
|
-
| smart-grep (tuned) | 0.
|
|
410
|
-
|
|
|
411
|
-
|
|
|
412
|
-
|
|
|
415
|
+
| baseline | F1 | avg input tokens | tool calls |
|
|
416
|
+
|---|---:|---:|---:|
|
|
417
|
+
| naive-grep | 0.25 | 22,704 | 6.3 |
|
|
418
|
+
| smart-grep (tuned) | 0.34 | 714 | 3.2 |
|
|
419
|
+
| jcodemunch-mcp | 0.29 | 1,907 | 1.2 |
|
|
420
|
+
| GitNexus | 0.30 | 630 | 1.2 |
|
|
421
|
+
| **sverklo** | **0.58** | **652** | **1.0** |
|
|
413
422
|
|
|
414
|
-
Sverklo leads overall F1
|
|
423
|
+
Sverklo leads overall F1, dominates P4 file-dependency questions, and keeps the honest loss slice visible: dead-code detection is where grep-style baselines remain strongest. Token economy: about 35× fewer input tokens than naive grep, with a single tool call per task.
|
|
415
424
|
|
|
416
425
|
Reproduce: `npm run bench:quick`. Filter with `BASELINES=sverklo,jcodemunch DATASETS=express npm run bench:quick`.
|
|
417
426
|
|
|
@@ -440,9 +449,10 @@ Click the badge for your editor. Cursor / VS Code prompt to confirm, then sverkl
|
|
|
440
449
|
```bash
|
|
441
450
|
npm install -g sverklo
|
|
442
451
|
cd your-project && sverklo init
|
|
452
|
+
sverklo prove
|
|
443
453
|
```
|
|
444
454
|
|
|
445
|
-
`sverklo init` auto-detects which AI coding agents you have (Claude Code, Cursor, Windsurf, Zed, Antigravity) and writes the right MCP config files. Idempotent — safe to re-run. If sverklo doesn't appear in your agent after restart, run `sverklo doctor`.
|
|
455
|
+
`sverklo init` auto-detects which AI coding agents you have (Claude Code, Cursor, Windsurf, Zed, Antigravity) and writes the right MCP config files. `sverklo prove` prints central files, a real caller graph, and a prompt to paste into your agent. Idempotent — safe to re-run. If sverklo doesn't appear in your agent after restart, run `sverklo doctor`.
|
|
446
456
|
|
|
447
457
|
**Per-agent config locations** (`sverklo init` writes these for you):
|
|
448
458
|
- Claude Code: `.mcp.json` at project root + appends to `CLAUDE.md` (or `AGENTS.md` if present)
|
|
@@ -486,7 +496,7 @@ Use this if you're contributing, debugging the indexer, or want to run a not-yet
|
|
|
486
496
|
|
|
487
497
|
To run the bench:
|
|
488
498
|
```bash
|
|
489
|
-
npm run bench:
|
|
499
|
+
npm run bench:quick
|
|
490
500
|
```
|
|
491
501
|
|
|
492
502
|
Output lands in `benchmark/results/<timestamp>/`.
|
|
@@ -522,7 +532,7 @@ Inside Claude Code:
|
|
|
522
532
|
/plugin install sverklo-skill@sverklo-marketplace
|
|
523
533
|
```
|
|
524
534
|
|
|
525
|
-
Installs the bundled Skill (procedural instructions teaching Claude when to reach for `
|
|
535
|
+
Installs the bundled Skill (procedural instructions teaching Claude when to reach for `search`, `impact`, `review_diff`, `remember`, etc.) without touching your global skills directory.
|
|
526
536
|
|
|
527
537
|
> **First run note:** The ONNX embedding model (~90 MB) downloads automatically on first launch. Takes ~30 seconds, then every subsequent run is offline-capable.
|
|
528
538
|
|
|
@@ -554,7 +564,7 @@ sverklo audit --format sarif # GitHub code-scanning alerts
|
|
|
554
564
|
sverklo audit --format json # machine-readable for CI gates
|
|
555
565
|
```
|
|
556
566
|
|
|
557
|
-
Six formats: `markdown`, `html`, `json`, `sarif`, `csv`, `badges`. Pair with `
|
|
567
|
+
Six formats: `markdown`, `html`, `json`, `sarif`, `csv`, `badges`. Pair with `impact` (the MCP tool) when you want to see the per-symbol blast radius before refactoring.
|
|
558
568
|
|
|
559
569
|
---
|
|
560
570
|
|
package/dist/bin/sverklo.js
CHANGED
|
@@ -52,6 +52,7 @@ if (command && command !== "--help" && command !== "-h") {
|
|
|
52
52
|
const HELP_BLURBS = {
|
|
53
53
|
init: "Set up sverklo in your project (.mcp.json + CLAUDE.md, auto-detects Claude Code/Cursor/Windsurf/Antigravity). With --global: one-time-per-machine setup — write SVERKLO_SNIPPET to ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md, register the project, gitignore .sverklo/, import memories. Skips per-project boilerplate.",
|
|
54
54
|
doctor: "Diagnose MCP setup issues. Run after `init` to verify the agent can reach sverklo.",
|
|
55
|
+
prove: "Show a first-run repo-memory proof: central files, a real symbol with callers, and a paste-ready agent prompt.",
|
|
55
56
|
audit: "Run codebase audit and emit a graded report. Flags: --format markdown|html|json|graph|arch|obsidian, --output PATH, --open, --badge, --publish.",
|
|
56
57
|
"audit-diff": "Incremental architectural quality gate. Audits `git diff` for new cycles + fan-in spikes. Flags: --against REF, --fan-in-threshold N, --format human|json, --show-existing, --verbose. Exits 1 on regression.",
|
|
57
58
|
review: "Risk-scored diff review (CI-friendly). Flags: --ref REF, --ci, --format markdown|json, --max-files N, --fail-on low|medium|high.",
|
|
@@ -161,6 +162,14 @@ if (command === "register") {
|
|
|
161
162
|
console.log(`Registry: ${getRegistryPath()}`);
|
|
162
163
|
process.exit(0);
|
|
163
164
|
}
|
|
165
|
+
if (command === "prove") {
|
|
166
|
+
const flags = args.slice(1);
|
|
167
|
+
const projectPath = await resolveProjectPath(flags);
|
|
168
|
+
const { runProve } = await import("../src/prove.js");
|
|
169
|
+
const report = await runProve(projectPath);
|
|
170
|
+
process.stdout.write(report);
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
164
173
|
if (command === "unregister") {
|
|
165
174
|
// Issue #73 (HaleTom, 2026-05-25): agents tearing down git worktrees
|
|
166
175
|
// know the absolute path but not the internal repo name. Looking up
|
|
@@ -869,7 +878,7 @@ if (command === "telemetry") {
|
|
|
869
878
|
console.log(" os darwin / linux / win32");
|
|
870
879
|
console.log(" node_major the Node major version sverklo is running on");
|
|
871
880
|
console.log(" event one of 17 fixed event types");
|
|
872
|
-
console.log(" tool
|
|
881
|
+
console.log(" tool sverklo tool name (when applicable)");
|
|
873
882
|
console.log(" outcome ok / error / timeout");
|
|
874
883
|
console.log(" duration_ms tool execution time");
|
|
875
884
|
console.log("");
|
|
@@ -1084,7 +1093,7 @@ if (command === "profile") {
|
|
|
1084
1093
|
console.log(` ${tools.map((t) => t.replace(/^sverklo_/, "")).join(", ")}`);
|
|
1085
1094
|
console.log();
|
|
1086
1095
|
}
|
|
1087
|
-
console.log(" full
|
|
1096
|
+
console.log(" full 37 tools (every first-party sverklo tool — default)");
|
|
1088
1097
|
console.log("\n Set with: SVERKLO_PROFILE=core sverklo init");
|
|
1089
1098
|
console.log(" Or in .sverklo.yaml: profile: core");
|
|
1090
1099
|
console.log(" See: https://sverklo.com/blog/we-already-shipped-mcp-code-mode/\n");
|
|
@@ -1112,8 +1121,14 @@ if (command === "profile") {
|
|
|
1112
1121
|
// Structured doc — use it directly. The --days window doesn't apply
|
|
1113
1122
|
// to cumulative stats; we use the full lifetime instead, and tell
|
|
1114
1123
|
// the user when the doc started accumulating.
|
|
1124
|
+
//
|
|
1125
|
+
// v0.28.0: canonicalize legacy `sverklo_*` names in historical stats
|
|
1126
|
+
// files so they collapse onto the new short names (`sverklo_search`
|
|
1127
|
+
// + `search` → `search`). Without this, a long-running user's stats
|
|
1128
|
+
// would show duplicate rows after the rename.
|
|
1115
1129
|
for (const [tool, stat] of Object.entries(structuredStats.tools)) {
|
|
1116
|
-
|
|
1130
|
+
const canon = tool.startsWith("sverklo_") ? tool.slice("sverklo_".length) : tool;
|
|
1131
|
+
counts[canon] = (counts[canon] || 0) + stat.calls;
|
|
1117
1132
|
}
|
|
1118
1133
|
total = structuredStats.totalCalls;
|
|
1119
1134
|
const sinceStr = new Date(structuredStats.startedAt).toISOString().slice(0, 10);
|
|
@@ -1134,7 +1149,10 @@ if (command === "profile") {
|
|
|
1134
1149
|
process.exit(0);
|
|
1135
1150
|
}
|
|
1136
1151
|
for (const c of calls) {
|
|
1137
|
-
const
|
|
1152
|
+
const raw = String(c.detail.tool);
|
|
1153
|
+
// v0.28.0: collapse legacy `sverklo_*` rows onto canonical names so
|
|
1154
|
+
// upgraded users don't see split-personality stats.
|
|
1155
|
+
const tool = raw.startsWith("sverklo_") ? raw.slice("sverklo_".length) : raw;
|
|
1138
1156
|
counts[tool] = (counts[tool] || 0) + 1;
|
|
1139
1157
|
}
|
|
1140
1158
|
total = calls.length;
|
|
@@ -1147,8 +1165,7 @@ if (command === "profile") {
|
|
|
1147
1165
|
console.log(" " + "-".repeat(70));
|
|
1148
1166
|
for (const [tool, n] of ranked) {
|
|
1149
1167
|
const pct = ((n / total) * 100).toFixed(1) + "%";
|
|
1150
|
-
|
|
1151
|
-
console.log(" " + display.padEnd(38) + String(n).padStart(10) + pct.padStart(10));
|
|
1168
|
+
console.log(" " + tool.padEnd(38) + String(n).padStart(10) + pct.padStart(10));
|
|
1152
1169
|
}
|
|
1153
1170
|
console.log(" " + "-".repeat(70));
|
|
1154
1171
|
// Compute coverage for every named profile so the user can see the
|
|
@@ -1157,6 +1174,15 @@ if (command === "profile") {
|
|
|
1157
1174
|
// of real usage calls fall outside the profile.
|
|
1158
1175
|
const profileOrder = ["core", "nav", "review", "lean", "research"];
|
|
1159
1176
|
const fits = [];
|
|
1177
|
+
// v0.28.0: first-party tools no longer carry a `sverklo_` prefix, so
|
|
1178
|
+
// "missing from profile" is anyone-not-in-profile minus the Zilliz
|
|
1179
|
+
// compat aliases (recorded but not first-party).
|
|
1180
|
+
const COMPAT_ALIASES = new Set([
|
|
1181
|
+
"index_codebase",
|
|
1182
|
+
"search_code",
|
|
1183
|
+
"clear_index",
|
|
1184
|
+
"get_indexing_status",
|
|
1185
|
+
]);
|
|
1160
1186
|
for (const name of profileOrder) {
|
|
1161
1187
|
const profileTools = PROFILES[name];
|
|
1162
1188
|
if (!profileTools)
|
|
@@ -1167,7 +1193,7 @@ if (command === "profile") {
|
|
|
1167
1193
|
for (const [tool, n] of ranked) {
|
|
1168
1194
|
if (profileSet.has(tool))
|
|
1169
1195
|
covered += n;
|
|
1170
|
-
else if (
|
|
1196
|
+
else if (!COMPAT_ALIASES.has(tool))
|
|
1171
1197
|
missing.push(tool);
|
|
1172
1198
|
}
|
|
1173
1199
|
fits.push({ name, size: profileTools.length, coveragePct: covered / total, missing });
|
|
@@ -2195,10 +2221,10 @@ if (command === "memory") {
|
|
|
2195
2221
|
` --editor PATH editor to invoke (default: $EDITOR or vi)\n\n` +
|
|
2196
2222
|
`Safety:\n` +
|
|
2197
2223
|
` - Removing a memory's heading from the file does NOT delete it.\n` +
|
|
2198
|
-
` Use \`sverklo memory demote <id>\` (planned) or \`
|
|
2224
|
+
` Use \`sverklo memory demote <id>\` (planned) or \`demote\`\n` +
|
|
2199
2225
|
` from MCP for explicit deletion.\n` +
|
|
2200
2226
|
` - Adding a new memory by hand is not supported here. Use\n` +
|
|
2201
|
-
` \`
|
|
2227
|
+
` \`remember\` from MCP or call the API directly.\n` +
|
|
2202
2228
|
` - If the parser can't make sense of your edits, the change\n` +
|
|
2203
2229
|
` is rejected and your SQLite store is left untouched.\n`);
|
|
2204
2230
|
process.exit(0);
|
|
@@ -2555,13 +2581,14 @@ sverklo — code intelligence for AI agents
|
|
|
2555
2581
|
|
|
2556
2582
|
Just installed? Run these two:
|
|
2557
2583
|
sverklo init Set up sverklo in your project (.mcp.json + CLAUDE.md)
|
|
2558
|
-
sverklo
|
|
2584
|
+
sverklo prove Show a real repo-memory proof from your codebase
|
|
2559
2585
|
|
|
2560
2586
|
Then restart your AI agent (Claude Code, Cursor, Windsurf, etc.) — sverklo tools become available automatically.
|
|
2561
2587
|
|
|
2562
2588
|
Usage:
|
|
2563
2589
|
sverklo init Set up sverklo in your project (.mcp.json + CLAUDE.md)
|
|
2564
2590
|
sverklo doctor Diagnose MCP setup issues
|
|
2591
|
+
sverklo prove [path] Show central files, a real caller graph, and an agent prompt
|
|
2565
2592
|
sverklo reindex [path] Incremental rebuild of the index (changed files only)
|
|
2566
2593
|
Use --force to clear and rebuild from scratch.
|
|
2567
2594
|
Use --timing to see per-phase elapsed ms.
|
|
@@ -2604,6 +2631,7 @@ Setup / runtime:
|
|
|
2604
2631
|
Quick start (single project):
|
|
2605
2632
|
npm install -g sverklo
|
|
2606
2633
|
cd your-project && sverklo init
|
|
2634
|
+
sverklo prove
|
|
2607
2635
|
claude # start coding — sverklo tools are preferred automatically
|
|
2608
2636
|
|
|
2609
2637
|
Quick start (multi-repo, global):
|