@mishasinitcyn/betterrank 0.1.0 → 0.1.2

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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +168 -0
  3. package/package.json +1 -1
  4. package/src/cli.js +6 -6
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Misha Sinitcyn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # BetterRank
2
+
3
+ Structural code index with PageRank-ranked repo maps, symbol search, call-graph queries, and dependency analysis. Built on [tree-sitter](https://tree-sitter.github.io/) and [graphology](https://graphology.github.io/).
4
+
5
+ BetterRank parses your source files, builds a dependency graph, and ranks every symbol by structural importance using PageRank. Instead of grepping through thousands of files, ask questions like "what are the most important functions in this project?" or "who calls this function?" and get ranked, structured answers in seconds.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g @mishasinitcyn/betterrank
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ # Get a ranked overview of any project
17
+ betterrank map --root /path/to/project
18
+
19
+ # Search for symbols by name or parameter
20
+ betterrank search auth --root /path/to/project
21
+
22
+ # Who calls this function?
23
+ betterrank callers authenticateUser --root /path/to/project
24
+
25
+ # What depends on this file?
26
+ betterrank dependents src/auth/handlers.ts --root /path/to/project
27
+
28
+ # What does this file import?
29
+ betterrank deps src/auth/handlers.ts --root /path/to/project
30
+
31
+ # Local subgraph around a file
32
+ betterrank neighborhood src/auth/handlers.ts --root /path/to/project --limit 10
33
+ ```
34
+
35
+ ## How It Works
36
+
37
+ 1. **Parse**: Native tree-sitter extracts definitions (functions, classes, types) and references (calls, imports) from source files
38
+ 2. **Graph**: graphology MultiDirectedGraph with typed edges (DEFINES, REFERENCES, IMPORTS)
39
+ 3. **Rank**: PageRank scores every symbol by structural importance — heavily-imported utilities rank higher than leaf files
40
+ 4. **Cache**: mtime-based incremental updates. Only re-parses changed files. Cache lives at the platform cache directory (`~/Library/Caches/code-index/` on macOS, `~/.cache/code-index/` on Linux)
41
+
42
+ ## Supported Languages
43
+
44
+ JavaScript, TypeScript, Python, Rust, Go, Java, Ruby, C, C++, C#, PHP
45
+
46
+ ## Commands
47
+
48
+ ### `map` — Repo map
49
+
50
+ Summary of the most structurally important definitions, ranked by PageRank. Default limit is 50 symbols.
51
+
52
+ ```bash
53
+ betterrank map --root /path/to/project
54
+ betterrank map --root /path/to/project --limit 100
55
+ betterrank map --root /path/to/project --focus src/api/auth.ts,src/api/login.ts
56
+ betterrank map --root /path/to/project --count
57
+ ```
58
+
59
+ ### `search` — Find symbols by name or signature
60
+
61
+ Substring search across symbol names **and** full function signatures (including parameter names and types). Results ranked by PageRank.
62
+
63
+ ```bash
64
+ betterrank search encrypt --root /path/to/project
65
+ betterrank search max_age --root /path/to/project # matches param names too
66
+ betterrank search imp --root /path/to/project --kind function
67
+ ```
68
+
69
+ ### `symbols` — List definitions
70
+
71
+ ```bash
72
+ betterrank symbols --root /path/to/project
73
+ betterrank symbols --root /path/to/project --file src/auth.ts
74
+ betterrank symbols --root /path/to/project --kind function
75
+ ```
76
+
77
+ ### `callers` — Who calls this symbol
78
+
79
+ ```bash
80
+ betterrank callers authenticateUser --root /path/to/project
81
+ ```
82
+
83
+ ### `deps` — What does this file import
84
+
85
+ ```bash
86
+ betterrank deps src/auth.ts --root /path/to/project
87
+ ```
88
+
89
+ ### `dependents` — What imports this file
90
+
91
+ ```bash
92
+ betterrank dependents src/auth.ts --root /path/to/project
93
+ ```
94
+
95
+ ### `neighborhood` — Local subgraph around a file
96
+
97
+ ```bash
98
+ betterrank neighborhood src/auth.ts --root /path/to/project --count
99
+ betterrank neighborhood src/auth.ts --root /path/to/project --hops 2 --limit 10
100
+ ```
101
+
102
+ ### `structure` — File tree with symbol counts
103
+
104
+ ```bash
105
+ betterrank structure --root /path/to/project --depth 3
106
+ ```
107
+
108
+ ### `reindex` — Force full rebuild
109
+
110
+ ```bash
111
+ betterrank reindex --root /path/to/project
112
+ ```
113
+
114
+ ### `stats` — Index statistics
115
+
116
+ ```bash
117
+ betterrank stats --root /path/to/project
118
+ ```
119
+
120
+ ## Global Flags
121
+
122
+ | Flag | Description |
123
+ |---|---|
124
+ | `--root <path>` | Project root. **Always pass this explicitly.** |
125
+ | `--count` | Return counts only (no content) |
126
+ | `--offset N` | Skip first N results |
127
+ | `--limit N` | Max results to return (default: 50) |
128
+
129
+ ## Programmatic API
130
+
131
+ ```javascript
132
+ import { CodeIndex } from '@mishasinitcyn/betterrank';
133
+
134
+ const idx = new CodeIndex('/path/to/project');
135
+
136
+ const map = await idx.map({ limit: 100, focusFiles: ['src/main.ts'] });
137
+ const results = await idx.search({ query: 'auth', kind: 'function', limit: 10 });
138
+ const callers = await idx.callers({ symbol: 'authenticate' });
139
+ const deps = await idx.dependencies({ file: 'src/auth.ts' });
140
+ const dependents = await idx.dependents({ file: 'src/auth.ts' });
141
+ const hood = await idx.neighborhood({ file: 'src/auth.ts', hops: 2, maxFiles: 10 });
142
+
143
+ const stats = await idx.stats();
144
+ await idx.reindex();
145
+ ```
146
+
147
+ ## Ignore Configuration
148
+
149
+ Built-in defaults ignore `node_modules`, `dist`, `build`, `.venv`, etc. To add project-specific ignores, create `<project-root>/.code-index/config.json`:
150
+
151
+ ```json
152
+ {
153
+ "ignore": ["experiments/**", "legacy/**"]
154
+ }
155
+ ```
156
+
157
+ ## Cache
158
+
159
+ Cache lives at the platform cache directory:
160
+ - **macOS**: `~/Library/Caches/code-index/`
161
+ - **Linux**: `~/.cache/code-index/`
162
+ - **Windows**: `%LOCALAPPDATA%/code-index/Cache/`
163
+
164
+ Override with `CODE_INDEX_CACHE_DIR` env var. Cache files are disposable — delete anytime, they rebuild automatically.
165
+
166
+ ## License
167
+
168
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mishasinitcyn/betterrank",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Structural code index with PageRank-ranked repo maps, symbol search, call-graph queries, and dependency analysis. Built on tree-sitter and graphology.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/cli.js CHANGED
@@ -7,7 +7,7 @@ const DEFAULT_LIMIT = 50;
7
7
  const DEFAULT_DEPTH = 3;
8
8
 
9
9
  const USAGE = `
10
- code-index <command> [options]
10
+ betterrank <command> [options]
11
11
 
12
12
  Commands:
13
13
  map [--focus file1,file2] Repo map (ranked by PageRank)
@@ -78,7 +78,7 @@ async function main() {
78
78
 
79
79
  case 'search': {
80
80
  const query = flags._positional[0];
81
- if (!query) { console.error('Usage: code-index search <query> [--kind type]'); process.exit(1); }
81
+ if (!query) { console.error('Usage: betterrank search <query> [--kind type]'); process.exit(1); }
82
82
  const effectiveLimit = countMode ? undefined : (userLimit !== undefined ? userLimit : DEFAULT_LIMIT);
83
83
  const result = await idx.search({ query, kind: flags.kind, count: countMode, offset, limit: effectiveLimit });
84
84
  if (countMode) {
@@ -126,7 +126,7 @@ async function main() {
126
126
 
127
127
  case 'callers': {
128
128
  const symbol = flags._positional[0];
129
- if (!symbol) { console.error('Usage: code-index callers <symbol> [--file path]'); process.exit(1); }
129
+ if (!symbol) { console.error('Usage: betterrank callers <symbol> [--file path]'); process.exit(1); }
130
130
  const effectiveLimit = countMode ? undefined : (userLimit !== undefined ? userLimit : DEFAULT_LIMIT);
131
131
  const result = await idx.callers({ symbol, file: normalizeFilePath(flags.file), count: countMode, offset, limit: effectiveLimit });
132
132
  if (countMode) {
@@ -146,7 +146,7 @@ async function main() {
146
146
 
147
147
  case 'deps': {
148
148
  const file = normalizeFilePath(flags._positional[0]);
149
- if (!file) { console.error('Usage: code-index deps <file>'); process.exit(1); }
149
+ if (!file) { console.error('Usage: betterrank deps <file>'); process.exit(1); }
150
150
  const effectiveLimit = countMode ? undefined : (userLimit !== undefined ? userLimit : DEFAULT_LIMIT);
151
151
  const result = await idx.dependencies({ file, count: countMode, offset, limit: effectiveLimit });
152
152
  if (countMode) {
@@ -164,7 +164,7 @@ async function main() {
164
164
 
165
165
  case 'dependents': {
166
166
  const file = normalizeFilePath(flags._positional[0]);
167
- if (!file) { console.error('Usage: code-index dependents <file>'); process.exit(1); }
167
+ if (!file) { console.error('Usage: betterrank dependents <file>'); process.exit(1); }
168
168
  const effectiveLimit = countMode ? undefined : (userLimit !== undefined ? userLimit : DEFAULT_LIMIT);
169
169
  const result = await idx.dependents({ file, count: countMode, offset, limit: effectiveLimit });
170
170
  if (countMode) {
@@ -182,7 +182,7 @@ async function main() {
182
182
 
183
183
  case 'neighborhood': {
184
184
  const file = normalizeFilePath(flags._positional[0]);
185
- if (!file) { console.error('Usage: code-index neighborhood <file> [--hops N] [--max-files N]'); process.exit(1); }
185
+ if (!file) { console.error('Usage: betterrank neighborhood <file> [--hops N] [--max-files N]'); process.exit(1); }
186
186
  const hops = parseInt(flags.hops || '2', 10);
187
187
  const maxFilesFlag = flags['max-files'] ? parseInt(flags['max-files'], 10) : 15;
188
188