scopecairn 0.6.0 → 0.8.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.
- package/README.md +204 -191
- package/dist/{chunk-ID4PMSFQ.js → chunk-DY2AAM62.js} +9 -2
- package/dist/cli.js +1233 -1087
- package/dist/grammars/tree-sitter-c.wasm +0 -0
- package/dist/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/dist/grammars/tree-sitter-cpp.wasm +0 -0
- package/dist/grammars/tree-sitter-go.wasm +0 -0
- package/dist/grammars/tree-sitter-html.wasm +0 -0
- package/dist/grammars/tree-sitter-java.wasm +0 -0
- package/dist/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/grammars/tree-sitter-php.wasm +0 -0
- package/dist/grammars/tree-sitter-python.wasm +0 -0
- package/dist/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/grammars/tree-sitter-rust.wasm +0 -0
- package/dist/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/grammars/tree-sitter-vue.wasm +0 -0
- package/dist/{metrics-ZWWLUYJW.js → metrics-BLUHSM64.js} +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,191 +1,204 @@
|
|
|
1
|
-
# ScopeCairn
|
|
2
|
-
|
|
3
|
-
Local-first codebase intelligence layer for AI coding agents.
|
|
4
|
-
Understand the codebase, then give the agent only what it needs:
|
|
5
|
-
a knowledge graph of the repository, the relevant context per task,
|
|
6
|
-
change impact analysis, and enforced minimal-work scope.
|
|
7
|
-
No MCP server, no embeddings, no network calls, no telemetry.
|
|
8
|
-
|
|
9
|
-
> Understand before exploring. Retrieve before reading.
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- **Knowledge graph** — files, symbols (functions, classes, methods,
|
|
14
|
-
interfaces, components, routes, models…), and typed relations
|
|
15
|
-
(`IMPORTS`, `CALLS`, `EXTENDS`, `TESTS`, `ROUTES_TO`, `QUERIES`…)
|
|
16
|
-
in local SQLite, fully deterministic.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- **
|
|
26
|
-
|
|
27
|
-
- **
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- **
|
|
33
|
-
|
|
34
|
-
- **
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
|
|
38
|
-
- **
|
|
39
|
-
|
|
40
|
-
- **Multi-
|
|
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
|
-
scopecairn
|
|
127
|
-
scopecairn
|
|
128
|
-
scopecairn
|
|
129
|
-
scopecairn
|
|
130
|
-
scopecairn
|
|
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
|
-
|
|
1
|
+
# ScopeCairn
|
|
2
|
+
|
|
3
|
+
Local-first codebase intelligence layer for AI coding agents.
|
|
4
|
+
Understand the codebase, then give the agent only what it needs:
|
|
5
|
+
a knowledge graph of the repository, the relevant context per task,
|
|
6
|
+
change impact analysis, and enforced minimal-work scope.
|
|
7
|
+
No MCP server, no embeddings, no network calls, no telemetry.
|
|
8
|
+
|
|
9
|
+
> Understand before exploring. Retrieve before reading.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Knowledge graph** — files, symbols (functions, classes, methods,
|
|
14
|
+
interfaces, components, routes, models…), and typed relations
|
|
15
|
+
(`IMPORTS`, `CALLS`, `EXTENDS`, `TESTS`, `ROUTES_TO`, `QUERIES`…)
|
|
16
|
+
in local SQLite, fully deterministic. Parsing uses Tree-sitter
|
|
17
|
+
grammars (bundled WASM); schema files without a grammar keep an
|
|
18
|
+
explicit fallback.
|
|
19
|
+
- **Graph retrieval, no embeddings** — token-matched seeds → weighted
|
|
20
|
+
expansion → 5-signal ranking (seed, proximity, centrality, git
|
|
21
|
+
recency, co-change). Weights configurable, calibrated by benchmark.
|
|
22
|
+
- **Task scope control** — every complex task returns Required /
|
|
23
|
+
Optional / Protected file lists plus Task Guard rules and a
|
|
24
|
+
Definition of Done, so the agent changes only what matters.
|
|
25
|
+
- **Change impact** — direct, indirect (2-hop), tests, and UI components
|
|
26
|
+
affected by a file or symbol.
|
|
27
|
+
- **Call path tracing** — `scopecairn path <A> <B>` shows the shortest
|
|
28
|
+
multi-hop call/dependency chain between two symbols.
|
|
29
|
+
- **Centrality ranking** — weighted PageRank + betweenness cached per
|
|
30
|
+
symbol; `context` surfaces critical hotspots, `doctor` flags
|
|
31
|
+
single points of failure.
|
|
32
|
+
- **Community detection** — Louvain clustering finds real modules by
|
|
33
|
+
link density (not just folders); `graph` shows each symbol's community.
|
|
34
|
+
- **Cycle detection** — Tarjan SCC finds circular dependencies;
|
|
35
|
+
reported by `doctor`, warned in `context`, listed in `GRAPH.md`.
|
|
36
|
+
- **Auto-refresh** — `context` and `impact` re-index changed files first;
|
|
37
|
+
run `scan` after editing to close the loop.
|
|
38
|
+
- **Framework adapters** — Next.js (App + Pages Router routes),
|
|
39
|
+
Prisma models, and Drizzle tables/queries detected automatically.
|
|
40
|
+
- **Multi-language** — TypeScript, JavaScript, Python, Java, Go, Rust,
|
|
41
|
+
PHP, C#, C/C++, Ruby, HTML, Vue SFC (plus config/schema files as
|
|
42
|
+
graph nodes).
|
|
43
|
+
- **Multi-agent setup** — skills for Claude Code (plugin + marketplace
|
|
44
|
+
ready), Antigravity, Cursor, Windsurf, Copilot, Kiro, and an OpenCode
|
|
45
|
+
slash command. ScopeCairn never touches your `AGENTS.md`/`CLAUDE.md` —
|
|
46
|
+
those hold your repo's details, not tool instructions.
|
|
47
|
+
- **`GRAPH.md` knowledge file** — `.scopecairn/GRAPH.md` is a budgeted
|
|
48
|
+
(±150 lines) frozen summary of the graph (modules, most-used symbols,
|
|
49
|
+
PageRank hotspots, circular dependencies, routes, models, protected).
|
|
50
|
+
Written on setup, rewritten only when the
|
|
51
|
+
graph changes — for cold-start orientation; per-task precision still
|
|
52
|
+
comes from `context`. `.scopecairn/ARCHAEOLOGY.md` (purely from local
|
|
53
|
+
`git log`: top author, bus factor, churn) is written once; delete it to
|
|
54
|
+
regenerate.
|
|
55
|
+
- **`GRAPH.html` visual explorer** — offline, dependency-free Canvas
|
|
56
|
+
explorer written next to `GRAPH.md` on every graph change.
|
|
57
|
+
Cluster ↔ File ↔ Symbol hierarchy toggle, live search, type filter,
|
|
58
|
+
click-for-details side panel (callers, callees, centrality scores).
|
|
59
|
+
Nodes sized by symbols/PageRank, colored by Louvain community.
|
|
60
|
+
Pan, zoom, hover inspect. Double-click to open, no server.
|
|
61
|
+
- **`export` for external tools** — `scopecairn export --format
|
|
62
|
+
mermaid|graphml|dot|json` writes `.scopecairn/graph.<ext>` for PR
|
|
63
|
+
diagrams (Mermaid), Gephi/Cytoscape (GraphML), Graphviz (DOT),
|
|
64
|
+
or custom scripts (JSON).
|
|
65
|
+
|
|
66
|
+
## Install
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install -g scopecairn
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Requires Node.js ≥ 20.
|
|
73
|
+
|
|
74
|
+
Upgrade later with:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
scopecairn update # or: npm install -g scopecairn@latest
|
|
78
|
+
scopecairn update --check # only check for a new version
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Agent-driven setup
|
|
82
|
+
|
|
83
|
+
Install once, then just type `scopecairn ./` to your AI agent —
|
|
84
|
+
it runs project setup itself.
|
|
85
|
+
|
|
86
|
+
1. Install the skill once (global):
|
|
87
|
+
```bash
|
|
88
|
+
npx skills add <github-user>/scopecairn -g
|
|
89
|
+
```
|
|
90
|
+
(fallback without a skill: add one line to your global agent
|
|
91
|
+
instructions — `~/.claude/CLAUDE.md` or equivalent: *When the user
|
|
92
|
+
writes "scopecairn \<path\>", run `scopecairn init \<path\>`.*)
|
|
93
|
+
2. In any project chat, type:
|
|
94
|
+
```
|
|
95
|
+
scopecairn ./
|
|
96
|
+
```
|
|
97
|
+
The agent runs `scopecairn init ./`, reports files indexed and
|
|
98
|
+
integration files written. Approve the terminal command once;
|
|
99
|
+
afterwards, add the printed allowlist so later calls need no approval.
|
|
100
|
+
|
|
101
|
+
## Quickstart (manual)
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd your-repo
|
|
105
|
+
scopecairn init # index + Antigravity Skill + Workflow
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Claude Code (project skill, committed with the repo):
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
scopecairn claude install
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Or as a plugin from the bundled marketplace (this repo):
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
/plugin marketplace add <github-user>/scopecairn
|
|
118
|
+
/plugin install scopecairn@scopecairn
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
After setup, your agent calls ScopeCairn automatically on every coding task.
|
|
122
|
+
To query manually:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
scopecairn context "add approval workflow"
|
|
126
|
+
scopecairn context ./ # repository orientation map
|
|
127
|
+
scopecairn impact src/request/RequestService.ts
|
|
128
|
+
scopecairn read symbol approveRequest
|
|
129
|
+
scopecairn graph RequestService
|
|
130
|
+
scopecairn path handleLogin dbQuery
|
|
131
|
+
scopecairn export --format mermaid
|
|
132
|
+
scopecairn doctor
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Per-agent installers (instead of `init --agents …`):
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
scopecairn antigravity install # Skill + Workflow + allowlist guide
|
|
139
|
+
scopecairn claude install # project skill .claude/skills (also: cursor, windsurf, copilot, kiro)
|
|
140
|
+
scopecairn opencode install # /scopecairn slash command + permission snippet
|
|
141
|
+
scopecairn claude uninstall # clean removal, user content preserved
|
|
142
|
+
scopecairn agents list
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Commands
|
|
146
|
+
|
|
147
|
+
| Command | Description |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `init [path]` | Initial indexing + Skill, Workflow, detected agent skills (`--agents …\|all`; never writes `AGENTS.md`) |
|
|
150
|
+
| `scan` / `rebuild` / `clean` | Manual index management (`scan` incremental; `rebuild` from scratch; `clean` removes `.scopecairn/`) |
|
|
151
|
+
| `status` / `doctor` | Index status (incl. adapters, invocations) and health checks |
|
|
152
|
+
| `context "<task>"` | Main entry point: context + scope (`--escalate`, `--no-refresh`, `--mode NORMAL|FAST|SAFE|AUDIT`, `--max-tokens N`); a path task returns an orientation map |
|
|
153
|
+
| `impact <path\|symbol>` | Change impact: direct, indirect, tests (via TESTS edges + static CALLS backward reachability), UI, queries, routes. Edge evidence tagged EXTRACTED/INFERRED/AMBIGUOUS |
|
|
154
|
+
| `graph <symbol>` | Symbol relations (+ PageRank, community, cycle status) |
|
|
155
|
+
| `path <from> <to>` | Shortest multi-hop call/dependency path between two symbols |
|
|
156
|
+
| `export --format <fmt>` | Graph export: `mermaid`, `graphml`, `dot`, or `json` (default `.scopecairn/graph.<ext>`, override with `--out`) |
|
|
157
|
+
| `read symbol <name>` | Symbol-level source excerpt (not whole files) |
|
|
158
|
+
| `<agent> install` | Per-agent setup: `antigravity`, `claude`, `gemini`, `cursor`, `windsurf`, `copilot`, `kiro` (each also `uninstall`; `agents list` to see all) |
|
|
159
|
+
| `dashboard` | Generate local HTML dashboard at `.scopecairn/dashboard.html` |
|
|
160
|
+
| `test-select <target>` | List test files affected by a file/symbol change target |
|
|
161
|
+
| `doctor --verbose` | Also surface adapter/graph errors from `.scopecairn/last-run.log` to stderr |
|
|
162
|
+
| `benchmark [--tune]` | Retrieval recall, irrelevant ratio, context reduction + weight calibration |
|
|
163
|
+
| `update [--check]` | Update ScopeCairn to the latest npm release (`--check` only checks) |
|
|
164
|
+
|
|
165
|
+
Agent commands (`context`, `impact`, `read`, `graph`, `status`, `doctor`)
|
|
166
|
+
are read-only toward source and only write to `.scopecairn/` — safe to
|
|
167
|
+
allowlist. `init`, `scan`, and `rebuild` are manual/user-side commands.
|
|
168
|
+
|
|
169
|
+
## Framework adapters
|
|
170
|
+
|
|
171
|
+
Detected automatically during `scan` (shown in output and `status`).
|
|
172
|
+
No configuration needed.
|
|
173
|
+
|
|
174
|
+
| Adapter | Detects | Produces |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| `nextjs` | `app/`, `pages/`, `next.config.*` | Route symbols (`GET /api/x`, `PAGE /y` incl. route groups, dynamic segments), `ROUTES_TO` handler edges, `QUERIES` handler→model edges |
|
|
177
|
+
| `prisma` | `schema.prisma` | `model` symbols for `QUERIES` resolution |
|
|
178
|
+
| `drizzle` | `drizzle*` paths/config, `db/` schemas | `model` symbols from `pgTable`/`sqliteTable`/`mysqlTable`; `QUERIES` from `db.query.*` relational and `db.select/insert/update/delete` builder calls |
|
|
179
|
+
| `express` | `package.json` deps | Route symbols from `app/router.METHOD(path)`, handler edges |
|
|
180
|
+
| `fastapi` | `.py` routes, requirements/pyproject | Route symbols from `@app.METHOD("/path")` decorators |
|
|
181
|
+
| `sqlalchemy` | requirements/pyproject | `model` symbols from `class X(Base)`/`__tablename__`; `QUERIES` from `session.query/select` |
|
|
182
|
+
| `vue` | `.vue` SFCs, `package.json` deps | `component` symbols per SFC; `IMPORTS` edges from used components in template |
|
|
183
|
+
|
|
184
|
+
Limits (honest): non-Prisma/Drizzle/SQLAlchemy ORMs, inter-table
|
|
185
|
+
references, raw SQL strings, and fully dynamic table names are not mapped
|
|
186
|
+
yet — those edges are skipped (and logged to `.scopecairn/last-run.log`),
|
|
187
|
+
never hallucinated. Server Actions (`detectServerActions`) and middleware
|
|
188
|
+
(`detectMiddleware`) are detected in `nextjs.ts`. QUERIES re-derive on
|
|
189
|
+
every scan so new models resolve without a rebuild.
|
|
190
|
+
Contributing a new adapter = one file + one registration line
|
|
191
|
+
in `src/adapters/index.ts` (see `FrameworkAdapter` in `src/adapters/types.ts`).
|
|
192
|
+
|
|
193
|
+
## Typical loop
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
prompt → scopecairn context (refresh at start) → agent edits code
|
|
197
|
+
→ scopecairn scan (refresh at end, incremental, ~instant)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Measure retrieval quality anytime: `scopecairn benchmark [--tune]`.
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -159,8 +159,15 @@ function ensureMetrics(db) {
|
|
|
159
159
|
try {
|
|
160
160
|
const syms = db.prepare(`SELECT COUNT(*) AS n FROM symbols`).get().n;
|
|
161
161
|
if (syms === 0) return 0;
|
|
162
|
-
const
|
|
163
|
-
|
|
162
|
+
const missing = db.prepare(
|
|
163
|
+
`SELECT COUNT(*) AS n FROM symbols s LEFT JOIN node_metrics m ON m.node_id = s.id WHERE m.node_id IS NULL`
|
|
164
|
+
).get().n;
|
|
165
|
+
const orphans = db.prepare(
|
|
166
|
+
`SELECT COUNT(*) AS n FROM node_metrics m LEFT JOIN symbols s ON s.id = m.node_id WHERE s.id IS NULL`
|
|
167
|
+
).get().n;
|
|
168
|
+
if (missing === 0 && orphans === 0) {
|
|
169
|
+
return db.prepare(`SELECT COUNT(*) AS n FROM node_metrics`).get().n;
|
|
170
|
+
}
|
|
164
171
|
return refreshMetrics(db);
|
|
165
172
|
} catch {
|
|
166
173
|
return 0;
|