@maxgfr/codeindex 2.7.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 +115 -0
- package/docs/MIGRATION.md +100 -0
- package/package.json +89 -0
- package/scripts/cli.mjs +10 -0
- package/scripts/engine.d.mts +618 -0
- package/scripts/engine.mjs +10655 -0
- package/scripts/grammars/bash.wasm +0 -0
- package/scripts/grammars/c.wasm +0 -0
- package/scripts/grammars/c_sharp.wasm +0 -0
- package/scripts/grammars/cpp.wasm +0 -0
- package/scripts/grammars/go.wasm +0 -0
- package/scripts/grammars/java.wasm +0 -0
- package/scripts/grammars/javascript.wasm +0 -0
- package/scripts/grammars/lua.wasm +0 -0
- package/scripts/grammars/php.wasm +0 -0
- package/scripts/grammars/python.wasm +0 -0
- package/scripts/grammars/ruby.wasm +0 -0
- package/scripts/grammars/rust.wasm +0 -0
- package/scripts/grammars/scala.wasm +0 -0
- package/scripts/grammars/tsx.wasm +0 -0
- package/scripts/grammars/typescript.wasm +0 -0
- package/scripts/grammars/web-tree-sitter.wasm +0 -0
- package/src/ast/extract.ts +713 -0
- package/src/ast/loader.ts +104 -0
- package/src/bm25.ts +156 -0
- package/src/callers.ts +0 -0
- package/src/calls.ts +131 -0
- package/src/categorize.ts +80 -0
- package/src/centrality.ts +148 -0
- package/src/classify.ts +53 -0
- package/src/cli-entry.ts +16 -0
- package/src/community.ts +345 -0
- package/src/complexity.ts +69 -0
- package/src/coupling.ts +0 -0
- package/src/deadcode.ts +46 -0
- package/src/edit.ts +93 -0
- package/src/engine-cli.ts +278 -0
- package/src/engine.ts +148 -0
- package/src/extract/code.ts +376 -0
- package/src/extract/markdown.ts +135 -0
- package/src/git.ts +205 -0
- package/src/glob.ts +56 -0
- package/src/graph.ts +0 -0
- package/src/grep.ts +115 -0
- package/src/hash.ts +13 -0
- package/src/ignore.ts +134 -0
- package/src/lang/c.ts +26 -0
- package/src/lang/common.ts +68 -0
- package/src/lang/csharp.ts +22 -0
- package/src/lang/elixir.ts +18 -0
- package/src/lang/go.ts +22 -0
- package/src/lang/java.ts +19 -0
- package/src/lang/js-ts.ts +112 -0
- package/src/lang/kotlin.ts +20 -0
- package/src/lang/lua.ts +18 -0
- package/src/lang/php.ts +24 -0
- package/src/lang/python.ts +22 -0
- package/src/lang/registry.ts +54 -0
- package/src/lang/ruby.ts +17 -0
- package/src/lang/rust.ts +22 -0
- package/src/lang/scala.ts +19 -0
- package/src/lang/shell.ts +17 -0
- package/src/lang/swift.ts +23 -0
- package/src/mcp.ts +512 -0
- package/src/memory.ts +75 -0
- package/src/modules.ts +128 -0
- package/src/pipeline.ts +59 -0
- package/src/query.ts +118 -0
- package/src/render/graph-json.ts +16 -0
- package/src/render/symbols-json.ts +79 -0
- package/src/repomap.ts +52 -0
- package/src/resolve.ts +950 -0
- package/src/rules.ts +249 -0
- package/src/scan.ts +172 -0
- package/src/sort.ts +12 -0
- package/src/surprise.ts +58 -0
- package/src/tests-map.ts +105 -0
- package/src/types.ts +201 -0
- package/src/util.ts +169 -0
- package/src/viz.ts +44 -0
- package/src/walk.ts +216 -0
- package/src/workspaces.ts +748 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# codeindex
|
|
2
|
+
|
|
3
|
+
Self-contained, deterministic **repo-indexing engine**: file walking, language
|
|
4
|
+
detection, symbol/import extraction (tree-sitter AST with a regex fallback),
|
|
5
|
+
import resolution, a typed cross-file link-graph, and graph analytics — shipped
|
|
6
|
+
as a single zero-dependency `engine.mjs` that consumer tools **vendor** (copy
|
|
7
|
+
into their repo) instead of installing.
|
|
8
|
+
|
|
9
|
+
Extracted from [ultraindex](https://github.com/maxgfr/ultraindex) 5.1.0's core,
|
|
10
|
+
and consumed by the ultra* skill family (ultraindex, ultradoc, ultrasec,
|
|
11
|
+
ultraeval, reconstruct, construct, ultra11y).
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
- **Walk** a repo deterministically: ignore lists, binary/lockfile skips, size
|
|
16
|
+
and count caps (`capped` flag, never silent truncation), symlink-cycle guard.
|
|
17
|
+
- **Scan** every file into a `FileRecord`: classification, language, symbols,
|
|
18
|
+
imports, headings, hashes — with an incremental cache fastpath.
|
|
19
|
+
- **Extract symbols** via tree-sitter (10 languages, when the wasm sidecar is
|
|
20
|
+
present) or per-language regex rules (15 languages, always available).
|
|
21
|
+
- **Resolve imports** across languages: tsconfig paths, package `exports`,
|
|
22
|
+
go.mod, Cargo, Java packages, PSR-4, C# namespaces.
|
|
23
|
+
- **Build a typed link-graph**: `import` / `call` / `use` / `doc-link` /
|
|
24
|
+
`mention` edges at file and module level, plus Louvain communities, PageRank/
|
|
25
|
+
betweenness centrality, a tests→code map, and surprise-edge detection.
|
|
26
|
+
- **Render** byte-stable `graph.json` / `symbols.json` (two builds of an
|
|
27
|
+
unchanged repo are byte-identical).
|
|
28
|
+
|
|
29
|
+
## Use as a library (the vendoring model)
|
|
30
|
+
|
|
31
|
+
Consumers commit `scripts/engine.mjs` + `scripts/engine.d.mts` (fetched at a
|
|
32
|
+
pinned release tag) into `src/vendor/` and import from it; their bundler inlines
|
|
33
|
+
the engine so they still ship a single file:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { buildIndexArtifacts, renderGraphJson } from "./vendor/engine.mjs";
|
|
37
|
+
|
|
38
|
+
const { scan, graph, symbols } = buildIndexArtifacts("/path/to/repo");
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The AST tier is optional: without a `grammars/` directory next to the bundle
|
|
42
|
+
the engine silently uses its regex tier. Only tools that want AST precision
|
|
43
|
+
(e.g. ultraindex) also vendor `scripts/grammars/` (~17 MiB of wasm).
|
|
44
|
+
|
|
45
|
+
## Use from npm
|
|
46
|
+
|
|
47
|
+
For consumers who don't want to vendor the bundle, `@maxgfr/codeindex` also
|
|
48
|
+
resolves as a regular package:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm i @maxgfr/codeindex
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { scanRepo, ENGINE_VERSION } from "@maxgfr/codeindex";
|
|
56
|
+
|
|
57
|
+
const scan = scanRepo("/path/to/repo");
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The CLI ships in the same package (`npm i -g @maxgfr/codeindex`, see below).
|
|
61
|
+
Skills should still prefer vendoring: it keeps their own bundle single-file and
|
|
62
|
+
pinned to an exact commit without an npm dependency.
|
|
63
|
+
|
|
64
|
+
## Use as a CLI
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
brew install maxgfr/tap/codeindex # or: npm i -g @maxgfr/codeindex
|
|
68
|
+
|
|
69
|
+
codeindex index --repo . --out .codeindex # graph + symbols + incremental cache
|
|
70
|
+
codeindex graph --repo . > graph.json
|
|
71
|
+
codeindex callers --repo . # per-symbol caller index
|
|
72
|
+
codeindex grep 'pattern' --repo .
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Use as an MCP server
|
|
76
|
+
|
|
77
|
+
`codeindex mcp` (or `node scripts/cli.mjs mcp`) serves the engine over stdio —
|
|
78
|
+
tools: `scan_summary`, `graph`, `symbols`, `callers`, `workspaces`, `churn`,
|
|
79
|
+
`grep`. Register it in Claude Code with:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
claude mcp add codeindex -- codeindex mcp
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`engine.mjs` is a pure side-effect-free library (safe for consumers to inline
|
|
86
|
+
into their own CLIs); `cli.mjs` is the thin standalone CLI/MCP wrapper.
|
|
87
|
+
|
|
88
|
+
## Versioning
|
|
89
|
+
|
|
90
|
+
- `ENGINE_VERSION` — the release tag, embedded greppably in the bundle.
|
|
91
|
+
- `SCHEMA_VERSION` — the `graph.json`/`symbols.json` shape (continues
|
|
92
|
+
ultraindex's lineage; currently 4). Consumers reject mismatched artifacts.
|
|
93
|
+
- `EXTRACTOR_VERSION` — the extraction output shape; incremental caches keyed
|
|
94
|
+
on it are discarded wholesale when it bumps.
|
|
95
|
+
|
|
96
|
+
`buildGraph`/`buildIndexArtifacts` accept `meta: { version, schemaVersion }` so
|
|
97
|
+
a consumer can stamp its own identity into artifacts it persists.
|
|
98
|
+
|
|
99
|
+
## Development
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
pnpm install
|
|
103
|
+
pnpm test # unit + fixtures + compat + no-wasm gates
|
|
104
|
+
pnpm typecheck
|
|
105
|
+
pnpm build # tsup → scripts/engine.mjs + scripts/engine.d.mts
|
|
106
|
+
pnpm check:build # proves the committed bundle is byte-reproducible
|
|
107
|
+
pnpm test:e2e # opt-in: pinned real-repo builds with ratchets
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The compat suite pins the exact bytes ultraindex 5.1.0 produced for the
|
|
111
|
+
`mini-repo` fixture — the proof that extraction was lossless.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Migrating a skill onto the codeindex engine
|
|
2
|
+
|
|
3
|
+
The engine ships as two files, released together at every tag:
|
|
4
|
+
|
|
5
|
+
- `scripts/engine.mjs` — self-contained zero-dependency ESM bundle (library + CLI + MCP server)
|
|
6
|
+
- `scripts/engine.d.mts` — TypeScript declarations for the bundle
|
|
7
|
+
|
|
8
|
+
Consumers **vendor** them (commit a copy) — never an npm dependency — so every
|
|
9
|
+
skill stays standalone-installable.
|
|
10
|
+
|
|
11
|
+
## Vendoring steps
|
|
12
|
+
|
|
13
|
+
1. Copy `scripts/sync-engine.mjs` (reference implementation lives in the
|
|
14
|
+
ultraeval repo) into your repo and run:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
node scripts/sync-engine.mjs --ref v1.0.0
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
It fetches `engine.mjs` + `engine.d.mts` from
|
|
21
|
+
`https://raw.githubusercontent.com/maxgfr/codeindex/<ref>/scripts/…` into
|
|
22
|
+
`src/vendor/`, greps the bundle's `ENGINE_VERSION` to assert it matches the
|
|
23
|
+
tag, and writes `src/vendor/engine.meta.json` (`{ tag, sha256, syncedAt }`).
|
|
24
|
+
|
|
25
|
+
2. Import what you need from the vendored file:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { scanRepo, buildGraph, gitChurn } from "../vendor/engine.mjs";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
With `moduleResolution: "Bundler"` the sibling `.d.mts` types the import
|
|
32
|
+
with zero config. Your tsup/esbuild build inlines the engine into your own
|
|
33
|
+
single-file bundle — the user installs nothing extra.
|
|
34
|
+
|
|
35
|
+
3. Exclude `src/vendor/` from your linter, and add
|
|
36
|
+
`node scripts/sync-engine.mjs --check` (offline sha256 check against
|
|
37
|
+
`engine.meta.json`) to your CI so local edits to the vendored file fail
|
|
38
|
+
loudly. Upgrades are a deliberate re-pin: run the sync with a newer tag and
|
|
39
|
+
commit the diff.
|
|
40
|
+
|
|
41
|
+
The AST tier is optional: without a `grammars/` directory next to the vendored
|
|
42
|
+
bundle the engine uses its regex tier (15 languages). Only vendor
|
|
43
|
+
`scripts/grammars/` (~17 MiB wasm) if you need AST-exact symbols (ultraindex
|
|
44
|
+
does; nobody else should).
|
|
45
|
+
|
|
46
|
+
## Version constants
|
|
47
|
+
|
|
48
|
+
| Constant | Meaning | On mismatch |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `ENGINE_VERSION` | the release tag, greppable in the bundle | sync script refuses the fetch |
|
|
51
|
+
| `SCHEMA_VERSION` | `graph.json` / `symbols.json` shape | reject the artifact, rebuild |
|
|
52
|
+
| `EXTRACTOR_VERSION` | extraction output shape | discard incremental caches wholesale |
|
|
53
|
+
|
|
54
|
+
`buildGraph(...)` / `buildIndexArtifacts(...)` accept
|
|
55
|
+
`meta: { version, schemaVersion }` so a consumer stamps its own identity into
|
|
56
|
+
artifacts it persists (ultraindex does this to keep its graph.json lineage).
|
|
57
|
+
|
|
58
|
+
## Per-skill mapping (what to replace with what)
|
|
59
|
+
|
|
60
|
+
| Skill | Replace | With (engine export) |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| **ultraeval** | `walkFiles`, `SKIP_DIRS` | `scanRepo` (gitignore on by default) |
|
|
63
|
+
| | `importsOf` + `resolveImport` (JS/TS+py regex) | `FileRecord.refs` (kind `import`) + `buildResolveContext`/`resolveImport` |
|
|
64
|
+
| | `gitChurn`, `changedFiles` | `gitChurn`, `changedSince` |
|
|
65
|
+
| | keeps | cycle DFS, hotspot scoring, todos/maxIndent, ANALYSIS.md rendering |
|
|
66
|
+
| **construct** | walker clone + language histogram + test count | `scanRepo` (`.languages`) + `isTestPath` |
|
|
67
|
+
| **ultraindex** | the whole core (walk/scan/extract/resolve/modules/graph/calls/analytics/renderers) | vendored engine + shim `src/engine.ts` re-exporting it; pass `meta: { version: VERSION, schemaVersion: SCHEMA_VERSION }` to keep graph.json byte-lineage |
|
|
68
|
+
| | keeps | store/manifest, encyclopedia, merge/entries, find/ask, check/verify, embeddings, orchestrate |
|
|
69
|
+
| **ultradoc** | walker, `EXT_LANG` map, symbol `RULES` + `applyExportLists` | `scanRepo`, `extToLang`/`languageOf`, `extractSymbols`/`buildSymbolIndex` |
|
|
70
|
+
| | `PKG_MANIFESTS` workspace probing | `detectWorkspaces` |
|
|
71
|
+
| | `rgSearch` + JS fallback | `grepRepo` |
|
|
72
|
+
| | keeps | issues/PRs/SO/web retrieval, citations, DOC.md |
|
|
73
|
+
| **ultra11y** | walker + glob scoping | `walk`/`scanRepo` with `include`/`exclude` |
|
|
74
|
+
| | tsconfig path-alias resolution | `buildResolveContext` + `resolveImport` |
|
|
75
|
+
| | keeps | its JSX component graph and every WCAG check |
|
|
76
|
+
| **reconstruct** | walker + gitignore parser + `categorize` | `scanRepo`, `categorize` |
|
|
77
|
+
| | `EXT_LANGUAGE` | `extToLang` |
|
|
78
|
+
| | workspace detection + dep graph + cycle + topo | `detectWorkspaces` (packages/dependsOn/cycle/topoOrder) |
|
|
79
|
+
| | `resolveModule` | `resolveImport` |
|
|
80
|
+
| | keeps | framework adapters (routes), data-model inference, PRD rendering |
|
|
81
|
+
| **ultrasec** | walker + gitignore + scope + symlink guard | `scanRepo` (`scope`, `gitignore` — its own semantics, ported here) |
|
|
82
|
+
| | per-language defs/imports/calls extraction | `extractCode` (`symbols`/`refs`/`calls`) |
|
|
83
|
+
| | `resolveImport` | `resolveImport` |
|
|
84
|
+
| | `buildGraph` (import+call edges, symbolDefs, callersBySymbol, enclosingSymbol) | `buildGraph` + `resolveCallEdges` + `buildCallerIndex` + `enclosingSymbol` |
|
|
85
|
+
| | keeps | taint source→sink enumeration, external scanners, EPSS/KEV/CVSS, SARIF |
|
|
86
|
+
|
|
87
|
+
## Golden-diff adjudication (every migration)
|
|
88
|
+
|
|
89
|
+
Capture the skill's load-bearing artifact **before** touching code (a committed
|
|
90
|
+
snapshot test), migrate, then adjudicate every diff:
|
|
91
|
+
|
|
92
|
+
- **Accept + document**: file-set changes from better ignore rules (gitignore
|
|
93
|
+
honored, lockfile/binary/1 MiB skips) and strictly-more-resolved imports
|
|
94
|
+
(tsconfig paths, package `exports`, go/cargo) — list them in the commit body.
|
|
95
|
+
- **Must be identical**: output schemas, rendering, scoring formulas,
|
|
96
|
+
attribution logic on identical inputs.
|
|
97
|
+
- **Investigate before accepting**: anything else (a cycle, hotspot, finding or
|
|
98
|
+
score changing for an unlisted reason). If the engine is more correct, update
|
|
99
|
+
the golden citing the cause; otherwise **fix codeindex and re-release** —
|
|
100
|
+
never patch around it in the consumer.
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@maxgfr/codeindex",
|
|
3
|
+
"version": "2.7.0",
|
|
4
|
+
"description": "Self-contained, deterministic repo-indexing engine: walk + language detection + symbol/import extraction (tree-sitter AST with regex fallback) + import resolution + typed cross-file link-graph + analytics. Ships as a single zero-dependency engine.mjs that consumer tools vendor.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"packageManager": "pnpm@10.33.0",
|
|
7
|
+
"main": "./scripts/engine.mjs",
|
|
8
|
+
"types": "./scripts/engine.d.mts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./scripts/engine.d.mts",
|
|
12
|
+
"import": "./scripts/engine.mjs",
|
|
13
|
+
"default": "./scripts/engine.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"codeindex": "scripts/cli.mjs"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"scripts/engine.mjs",
|
|
22
|
+
"scripts/engine.d.mts",
|
|
23
|
+
"scripts/cli.mjs",
|
|
24
|
+
"scripts/grammars",
|
|
25
|
+
"src",
|
|
26
|
+
"docs/MIGRATION.md"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup && node scripts/postbuild.mjs",
|
|
33
|
+
"grammars": "node scripts/fetch-grammars.mjs",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"test:e2e": "CODEINDEX_E2E=1 vitest run tests/e2e-real-repos.test.ts",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"check:build": "tsup && node scripts/postbuild.mjs && git diff --exit-code -- scripts/engine.mjs scripts/engine.d.mts scripts/cli.mjs scripts/grammars",
|
|
39
|
+
"demo": "node scripts/cli.mjs graph --repo tests/fixtures/mini-repo",
|
|
40
|
+
"release": "semantic-release"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"code-index",
|
|
44
|
+
"static-analysis",
|
|
45
|
+
"link-graph",
|
|
46
|
+
"symbol-extraction",
|
|
47
|
+
"tree-sitter",
|
|
48
|
+
"repo-indexing"
|
|
49
|
+
],
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"author": "maxgfr",
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "https://github.com/maxgfr/codeindex"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
58
|
+
"@semantic-release/exec": "^6.0.3",
|
|
59
|
+
"@semantic-release/git": "^10.0.1",
|
|
60
|
+
"@tree-sitter-grammars/tree-sitter-lua": "0.4.1",
|
|
61
|
+
"@types/node": "^20.14.0",
|
|
62
|
+
"semantic-release": "^24.2.0",
|
|
63
|
+
"tree-sitter-bash": "0.25.1",
|
|
64
|
+
"tree-sitter-c": "^0.24.1",
|
|
65
|
+
"tree-sitter-c-sharp": "^0.23.5",
|
|
66
|
+
"tree-sitter-cpp": "^0.23.4",
|
|
67
|
+
"tree-sitter-go": "^0.25.0",
|
|
68
|
+
"tree-sitter-java": "^0.23.5",
|
|
69
|
+
"tree-sitter-javascript": "^0.25.0",
|
|
70
|
+
"tree-sitter-php": "^0.24.2",
|
|
71
|
+
"tree-sitter-python": "^0.25.0",
|
|
72
|
+
"tree-sitter-ruby": "^0.23.1",
|
|
73
|
+
"tree-sitter-rust": "^0.24.0",
|
|
74
|
+
"tree-sitter-scala": "0.24.0",
|
|
75
|
+
"tree-sitter-typescript": "^0.23.2",
|
|
76
|
+
"tsup": "^8.3.0",
|
|
77
|
+
"typescript": "^5.5.0",
|
|
78
|
+
"vitest": "^4.1.0",
|
|
79
|
+
"web-tree-sitter": "^0.26.10"
|
|
80
|
+
},
|
|
81
|
+
"pnpm": {
|
|
82
|
+
"onlyBuiltDependencies": [
|
|
83
|
+
"esbuild"
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
"publishConfig": {
|
|
87
|
+
"access": "public"
|
|
88
|
+
}
|
|
89
|
+
}
|
package/scripts/cli.mjs
ADDED