ucn 3.7.24 → 3.7.26

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 CHANGED
@@ -1,403 +1,109 @@
1
- # UCN - Universal Code Navigator
1
+ # UCN Universal Code Navigator
2
2
 
3
- UCN gives AI agents call-graph-level understanding of code. Instead of reading entire files, agents ask structural questions like: "who calls this function", "what breaks if I change it", "what's unused", and get precise, AST-verified answers. UCN parses JS/TS, Python, Go, Rust, Java, and HTML inline scripts with tree-sitter, then exposes 28 navigation commands as a CLI tool, MCP server, or agent skill.
3
+ AST-powered code intelligence from the terminal.
4
4
 
5
- Designed for large codebases where agents waste context on reading large files. UCN's surgical output means agents spend tokens on reasoning, not on ingesting thousands of lines to find three callers, discourages agents from cutting corners, as without UCN, agents working with large codebases tend to skip parts of the code structure, assuming they have "enough data".
5
+ UCN answers structural code questions instantly:
6
+ - Who calls this function?
7
+ - What breaks if I change this signature?
8
+ - What changed in this diff, and who depends on it?
9
+ - What code is safe to delete?
6
10
 
7
- Everything runs locally on your machine and nothing leaves your project.
8
- The ucn mcp is kept light, as all 28 commands ship as a single MCP tool, under 2k tokens total.
11
+ Instead of reading full files, UCN gives precise, AST-verified answers.
9
12
 
10
- ---
11
-
12
- ## What UCN does
13
-
14
- Precise answers without reading files.
15
-
16
- ```
17
- TASK COMMAND
18
- ───────────────────── ─────────────────────
19
-
20
- Pull one function from $ ucn fn handleRequest
21
- a 2000-line file → 20 lines, just that function
22
-
23
- Who calls this? Will they $ ucn impact handleRequest
24
- break if I change it? → 8 call sites, with arguments
25
-
26
- What happens when $ ucn trace main --depth=3
27
- main() runs? → full call tree, no file reads
28
-
29
- What can I safely delete? $ ucn deadcode
30
- → unused functions, AST-verified
31
-
32
- What depends on this file $ ucn graph src/routes.ts
33
- before I move it? → imports and importers tree
34
- ```
13
+ [![npm](https://img.shields.io/npm/v/ucn)](https://www.npmjs.com/package/ucn)
14
+ [![license](https://img.shields.io/npm/l/ucn)](LICENSE)
35
15
 
36
16
  ---
37
17
 
38
- ## Three Ways to it: ucn mcp, ucn skill, ucn cli
18
+ ## 60-Second Quickstart
39
19
 
40
- ```
41
- ┌──────────────────────────────────────────────────────────────────────┐
42
- │ │
43
- │ 1. CLI Use it directly from the terminal. │
44
- │ $ ucn about myFunc Works standalone, no agent required. │
45
- │ │
46
- │ 2. MCP Server Any MCP-compatible AI agent connects │
47
- │ $ ucn --mcp and gets 28 commands automatically. │
48
- │ │
49
- │ 3. Agent Skill Drop-in skill for Claude Code and │
50
- │ /ucn about myFunc OpenAI Codex CLI. No server needed. │
51
- │ │
52
- └──────────────────────────────────────────────────────────────────────┘
53
- ```
54
-
55
- ---
56
-
57
- ## How agents understand code today
58
-
59
- AI agents working with code typically do this:
20
+ ```bash
21
+ npm install -g ucn
60
22
 
61
- ```
62
- grep "functionName" → 47 matches, 23 files
63
-
64
-
65
- read file1.ts → 2000 lines... wrong function
66
-
67
-
68
- read file2.ts → 1500 lines... still not it
69
-
70
-
71
- read file3.ts → found it, finally
72
-
73
-
74
- grep "whoCallsThis" → start over
75
-
76
-
77
- ┌─────────────────────────────────────────┐
78
- │ Half the context window is gone. │
79
- │ The agent hasn't changed a single line.│
80
- └─────────────────────────────────────────┘
23
+ ucn about handleRequest # full picture: definition, callers, callees, tests
24
+ ucn impact handleRequest # all call sites with arguments
25
+ ucn trace main --depth=3 # call tree, no file reads
26
+ ucn deadcode # unused functions, AST-verified
81
27
  ```
82
28
 
83
- ---
84
-
85
- ## How UCN works: tree-sitter, locally
29
+ Parses JS/TS, Python, Go, Rust, Java, and HTML with tree-sitter. Runs locally.
86
30
 
87
31
  ```
88
- ┌──────────────────────────────────────────────┐
89
- Any AI Agent
90
- │ Claude Code · Cursor · Windsurf · Copilot │
91
- └───────────────────────┬──────────────────────┘
92
-
93
- MCP
94
-
95
-
96
- ┌───────────────────┐
97
- │ UCN MCP Server │
98
- │ 28 commands │
99
- │ runs locally │
100
- └────────┬──────────┘
101
-
102
- tree-sitter AST
103
-
104
- ┌─────────────────┴───────────────────┐
105
- │ Supported Languages │
106
- │ JS/TS, Python, Go, Rust, Java, HTML │
107
- └─────────────────────────────────────┘
32
+ Terminal AI Agents Agent Skills
33
+ │ │
34
+ CLI MCP Skill
35
+ └────────────────────┼───────────────────────┘
36
+
37
+ ┌──────┴──────┐
38
+ UCN Engine │
39
+ │ 28 commands │
40
+ │ tree-sitter │
41
+ └─────────────┘
108
42
  ```
109
43
 
110
44
  ---
111
45
 
112
- ## Before and after UCN
46
+ ## Why UCN
113
47
 
114
- ```
115
- WITHOUT UCN WITH UCN
116
- ────────────────────── ──────────────────────
117
-
118
- grep "processOrder" ucn impact "processOrder"
119
- │ │
120
- ▼ ▼
121
- 34 matches, mostly noise 8 call sites, grouped by file,
122
- │ with actual arguments passed
123
- ▼ │
124
- read service.ts (800 lines) │
125
- │ │
126
- ▼ │
127
- read handler.ts (600 lines) ucn smart "processOrder"
128
- │ │
129
- ▼ ▼
130
- read batch.ts (400 lines) function + all dependencies
131
- │ expanded inline
132
- ▼ │
133
- read orders.test (500 lines) │
134
- │ ▼
135
- ▼ Done. Full picture.
136
- grep "import.*processOrder" Ready to make the change.
137
-
138
-
139
- read routes.ts (300 lines)
140
-
141
-
142
- ... still not sure about full impact
143
-
144
-
145
- 8+ tool calls 2 tool calls
146
- Reads thousands of lines Reads zero full files
147
- Context spent on file contents Context spent on reasoning
148
- ```
48
+ UCN uses tree-sitter to parse code into an AST, then builds a call graph and symbol table on top of it. Instead of matching text, it understands which functions call which, what depends on what, and what's unused. Everything runs locally.
149
49
 
150
- After editing code, before committing:
50
+ "What happens when `build()` runs?"
151
51
 
152
52
  ```
153
- WITHOUT UCN WITH UCN
154
- ────────────────────── ──────────────────────
155
-
156
- git diff ucn diff_impact
157
- │ │
158
- ▼ ▼
159
- see changed lines, but which 13 modified functions
160
- functions do they belong to? 8 new functions
161
- │ 22 call sites across 9 files
162
- ▼ │
163
- read each file to map hunks ▼
164
- to function boundaries Each function shown with:
165
- │ • which lines changed
166
- ▼ • every downstream caller
167
- ucn impact on each function • caller context
168
- you identified (repeat 5-10x) │
169
- │ ▼
170
- ▼ Done. Full blast radius.
171
- hope you didn't miss one One command.
172
-
173
-
174
- 10+ tool calls 1 tool call
175
- ```
176
-
177
- ---
178
-
179
- ## Text search vs AST
53
+ $ ucn trace build --depth=2
180
54
 
181
- ```
182
- Code: processOrder(items, user)
183
-
184
-
185
- ┌─────────────────────────────────────────────────────────────────┐
186
- │ grep "processOrder" │
187
-
188
- ✓ processOrder(items, user) the actual call │
189
- ✗ // TODO: refactor processOrder ← comment, not a call │
190
- │ ✗ const processOrder = "label" ← string, not a call │
191
- ✗ order.processOrder() different class │
192
- ✗ import { processOrder } ← import, not a call │
193
-
194
- 5 results. 1 is what you wanted. │
195
- └─────────────────────────────────────────────────────────────────┘
196
-
197
-
198
- ┌─────────────────────────────────────────────────────────────────┐
199
- │ ucn context "processOrder" │
200
- │ │
201
- │ Callers: │
202
- │ handleCheckout src/api/checkout.ts:45 │
203
- │ batchProcess src/workers/batch.ts:12 │
204
- │ runDailyOrders src/jobs/daily.ts:88 │
205
- │ │
206
- │ Callees: │
207
- │ validateItems src/orders/validate.ts:20 │
208
- │ calculateTotal src/orders/pricing.ts:55 │
209
- │ saveOrder src/db/orders.ts:30 │
210
- │ │
211
- │ 3 callers, 3 callees. Verified from the AST. │
212
- └─────────────────────────────────────────────────────────────────┘
55
+ build
56
+ ├── detectProjectPattern (discovery.js:392) 1x
57
+ │ ├── checkDir (discovery.js:396) 2x
58
+ │ └── shouldIgnore (discovery.js:340) 1x
59
+ ├── parseGitignore (discovery.js:123) 1x
60
+ ├── expandGlob (discovery.js:183) 1x
61
+ ├── parseGlobPattern (discovery.js:219) 1x
62
+ ├── walkDir (discovery.js:276) 1x
63
+ └── compareNames (discovery.js:162) 1x
64
+ ├── indexFile (project.js:236) 1x
65
+ ├── addSymbol (project.js:293) 4x
66
+ ├── detectLanguage (languages/index.js:157) 1x
67
+ ├── parseFile (parser.js:93) 1x
68
+ └── extractImports (imports.js:19) 1x
69
+ ├── buildImportGraph (project.js:419) 1x
70
+ └── buildInheritanceGraph (project.js:465) 1x
213
71
  ```
214
72
 
215
- The tradeoff: text search works on any language and any text. UCN only works on 5 languages + HTML, but gives structural understanding within those.
73
+ One command. No files opened. The full execution flow with every function located by file and line.
216
74
 
217
75
  ---
218
76
 
219
- ## UCN commands in action
220
-
221
- Extract a function from a large file without reading it:
222
-
223
- ```
224
- $ ucn fn expandGlob
225
-
226
- core/discovery.js:135
227
- [ 135- 166] expandGlob(pattern, options = {})
228
- ────────────────────────────────────────────────────────────
229
- function expandGlob(pattern, options = {}) {
230
- const root = path.resolve(options.root || process.cwd());
231
- const ignores = options.ignores || DEFAULT_IGNORES;
232
- ...
233
- return files.sort(compareNames);
234
- }
235
- ```
236
-
237
- See who calls it and what it calls:
77
+ ## What it does
238
78
 
239
- ```
240
- $ ucn context expandGlob
79
+ | Task | Command | Output |
80
+ |------|---------|--------|
81
+ | Understand one symbol deeply | `ucn about expandGlob` | Definition, callers, callees, tests |
82
+ | Who calls this and what do they pass? | `ucn impact shouldIgnore` | Call sites with argument context |
83
+ | Map an execution path | `ucn trace expandGlob --depth=2` | Call tree |
84
+ | Extract just one function | `ucn fn expandGlob` | Surgical snippet, no file read |
85
+ | Check all call sites match signature | `ucn verify expandGlob` | Mismatch/uncertain call sites |
86
+ | Review branch impact | `ucn diff-impact --base=main` | Changed functions + downstream callers |
87
+ | Find deletable code | `ucn deadcode` | Unused symbols, AST-verified |
88
+ | Get function + helpers inline | `ucn smart shouldIgnore` | Source with dependencies expanded |
241
89
 
242
- Context for expandGlob:
243
- ════════════════════════════════════════════════════════════
244
-
245
- CALLERS (7):
246
- [1] cli/index.js:1847 [runGlobCommand]
247
- const files = expandGlob(pattern);
248
- [2] core/project.js:81
249
- const files = expandGlob(pattern, {
250
- [3] core/project.js:3434
251
- const currentFiles = expandGlob(pattern, { root: this.root });
252
- ...
253
-
254
- CALLEES (2):
255
- [8] parseGlobPattern [utility] - core/discovery.js:171
256
- [9] walkDir [utility] - core/discovery.js:227
257
- ```
258
-
259
- See what breaks if you change it:
260
-
261
- ```
262
- $ ucn impact shouldIgnore
263
-
264
- Impact analysis for shouldIgnore
265
- ════════════════════════════════════════════════════════════
266
- core/discovery.js:289
267
- shouldIgnore (name, ignores, parentDir)
268
-
269
- CALL SITES: 2
270
- Files affected: 1
271
-
272
- BY FILE:
273
-
274
- core/discovery.js (2 calls)
275
- :255 [walkDir]
276
- if (shouldIgnore(entry.name, options.ignores, dir)) continue;
277
- args: entry.name, options.ignores, dir
278
- :373 [detectProjectPattern]
279
- !shouldIgnore(entry.name, DEFAULT_IGNORES)) {
280
- args: entry.name, DEFAULT_IGNORES
281
- ```
282
-
283
- Get a function with all its dependencies inline:
284
-
285
- ```
286
- $ ucn smart shouldIgnore
287
-
288
- shouldIgnore (core/discovery.js:289)
289
- ════════════════════════════════════════════════════════════
290
- function shouldIgnore(name, ignores, parentDir) {
291
- for (const pattern of ignores) {
292
- if (pattern.includes('*')) {
293
- const regex = globToRegex(pattern);
294
- ...
295
- }
296
- }
297
- ...
298
- }
299
-
300
- ─── DEPENDENCIES ───
301
-
302
- // globToRegex [utility] (core/discovery.js:208)
303
- function globToRegex(glob) {
304
- let regex = glob.replace(/[.+^$[\]\\]/g, '\\$&');
305
- ...
306
- return new RegExp('^' + regex + '$');
307
- }
308
- ```
309
-
310
- Trace the call tree:
311
-
312
- ```
313
- $ ucn trace expandGlob --depth=2
314
-
315
- Call tree for expandGlob
316
- ════════════════════════════════════════════════════════════
317
-
318
- expandGlob
319
- ├── parseGlobPattern (core/discovery.js:171) [utility] 1x
320
- │ └── globToRegex (core/discovery.js:208) [utility] 1x
321
- └── walkDir (core/discovery.js:227) [utility] 1x
322
- └── shouldIgnore (core/discovery.js:289) [utility] 1x
323
- ```
324
-
325
- See the impact of your recent edits:
326
-
327
- ```
328
- $ ucn diff-impact --base=HEAD~1
329
-
330
- Diff Impact Analysis (vs HEAD~1)
331
- ════════════════════════════════════════════════════════════
332
- 3 modified, 1 new, 12 call sites across 4 files
333
-
334
- MODIFIED FUNCTIONS:
335
-
336
- processOrder
337
- src/orders/service.ts:45
338
- processOrder (items: Item[], user: User): Promise<Order>
339
- Lines added: 48-52
340
- Lines deleted: 49
341
- Callers (3):
342
- src/api/checkout.ts:89 [handleCheckout]
343
- await processOrder(cart.items, req.user)
344
- src/workers/batch.ts:12 [batchProcess]
345
- processOrder(order.items, systemUser)
346
- src/jobs/daily.ts:88 [runDailyOrders]
347
- results.push(await processOrder(items, admin))
348
-
349
- validateItems
350
- src/orders/validate.ts:20
351
- validateItems (items: Item[]): ValidationResult
352
- Lines added: 25-30
353
- Callers (2):
354
- src/orders/service.ts:46 [processOrder]
355
- const valid = validateItems(items)
356
- src/api/admin.ts:55 [bulkValidate]
357
- return items.map(i => validateItems([i]))
358
-
359
- NEW FUNCTIONS:
360
- calculateShipping — src/orders/shipping.ts:10
361
- calculateShipping (items: Item[], region: Region): number
362
-
363
- MODULE-LEVEL CHANGES:
364
- src/orders/service.ts: +5 lines, -1 lines
365
- ```
366
-
367
- Scoped to staged changes or a specific file:
368
-
369
- ```
370
- $ ucn diff-impact --staged # Only what's staged for commit
371
- $ ucn diff-impact --base=main # Everything since branching from main
372
- $ ucn diff-impact --file=src/orders # Only changes in this path
373
- ```
374
-
375
- Find unused code:
376
-
377
- ```
378
- $ ucn deadcode
379
-
380
- Dead code: 15 unused symbol(s)
90
+ ---
381
91
 
382
- cli/index.js
383
- [1649-1654] extractFunctionNameFromContent (function)
384
- core/project.js
385
- [1664-1694] findReExportsOf (method)
386
- [1998-2020] withCompleteness (method)
387
- ...
388
- ```
92
+ ## Setup
389
93
 
390
- ---
94
+ ### CLI
391
95
 
392
- ## Install
96
+ Already installed above. A few more examples:
393
97
 
394
98
  ```bash
395
- npm install -g ucn
99
+ ucn fn handleRequest --file api # extract function from specific file
100
+ ucn toc # project overview
101
+ ucn --interactive # REPL mode, index stays in memory
396
102
  ```
397
103
 
398
- ### As an MCP Server
104
+ ### MCP Server (for AI agents)
399
105
 
400
- One-line setup for supported clients:
106
+ One-line setup:
401
107
 
402
108
  ```bash
403
109
  # Claude Code
@@ -410,7 +116,8 @@ codex mcp add ucn -- npx -y ucn --mcp
410
116
  code --add-mcp '{"name":"ucn","command":"npx","args":["-y","ucn","--mcp"]}'
411
117
  ```
412
118
 
413
- Or add to your client's MCP config file manually:
119
+ <details>
120
+ <summary>Or add to the MCP config file manually</summary>
414
121
 
415
122
  ```json
416
123
  {
@@ -423,8 +130,7 @@ Or add to your client's MCP config file manually:
423
130
  }
424
131
  ```
425
132
 
426
- <details>
427
- <summary>VS Code Copilot uses a slightly different format (.vscode/mcp.json)</summary>
133
+ VS Code uses `.vscode/mcp.json`:
428
134
 
429
135
  ```json
430
136
  {
@@ -437,11 +143,14 @@ Or add to your client's MCP config file manually:
437
143
  }
438
144
  }
439
145
  ```
146
+
440
147
  </details>
441
148
 
442
- ### As a Claude Code / Codex Skill
149
+ All 28 commands ship as a single MCP tool, under 2KB of schema in the agent's context.
150
+
151
+ ### Agent Skill (no server needed)
443
152
 
444
- When MCP server is not needed, drop it in as a native skill:
153
+ Drop-in for Claude Code or Codex CLI:
445
154
 
446
155
  ```bash
447
156
  # Claude Code
@@ -453,135 +162,155 @@ mkdir -p ~/.agents/skills
453
162
  cp -r "$(npm root -g)/ucn/.claude/skills/ucn" ~/.agents/skills/
454
163
  ```
455
164
 
456
- ### As a CLI Tool
165
+ ---
457
166
 
458
- Works standalone from the terminal — no agent required:
167
+ ## Examples
168
+
169
+ **Extract a function** without reading the file:
459
170
 
460
- ```bash
461
- ucn toc # Project overview
462
- ucn about handleRequest # Understand a function
463
- ucn impact handleRequest # Before modifying
464
- ucn fn handleRequest --file api # Extract specific function
465
- ucn --interactive # Multiple queries, index stays in memory
466
171
  ```
172
+ $ ucn fn expandGlob
467
173
 
468
- ---
174
+ core/discovery.js:183
175
+ [ 183- 214] expandGlob(pattern, options = {})
176
+ ────────────────────────────────────────────────────────────
177
+ function expandGlob(pattern, options = {}) {
178
+ const root = path.resolve(options.root || process.cwd());
179
+ const ignores = options.ignores || DEFAULT_IGNORES;
180
+ ...
181
+ return files.sort(compareNames);
182
+ }
183
+ ```
469
184
 
470
- ## UCN workflows
185
+ **See callers and callees:**
471
186
 
472
- Investigating a bug:
473
- ```bash
474
- ucn about problematic_function # Understand it fully
475
- ucn trace problematic_function --depth=2 # See what it calls
476
187
  ```
188
+ $ ucn context expandGlob
477
189
 
478
- Before modifying a function:
479
- ```bash
480
- ucn impact the_function # Who will break?
481
- ucn smart the_function # See it + its helpers
482
- # ... make your changes ...
483
- ucn verify the_function # Did all call sites survive?
190
+ CALLERS (7):
191
+ [1] cli/index.js:785 [runGlobCommand]
192
+ const files = expandGlob(pattern);
193
+ [2] core/cache.js:149 [isCacheStale]
194
+ const currentFiles = expandGlob(pattern, globOpts);
195
+ [3] core/project.js:171 [build]
196
+ const files = expandGlob(pattern, globOpts);
197
+ ...
198
+
199
+ CALLEES (3):
200
+ [8] parseGlobPattern [utility] - core/discovery.js:219
201
+ [9] walkDir [utility] - core/discovery.js:276
202
+ [10] compareNames [utility] - core/discovery.js:162
484
203
  ```
485
204
 
486
- Before committing:
487
- ```bash
488
- ucn diff-impact # What did I change + who calls it?
489
- ucn diff-impact --base=main # Full branch impact vs main
490
- ucn diff-impact --staged # Only staged changes
205
+ **See impact of recent edits:**
206
+
491
207
  ```
208
+ $ ucn diff-impact --base=HEAD~1
492
209
 
493
- Periodic cleanup:
494
- ```bash
495
- ucn deadcode --exclude=test # What can be deleted?
496
- ucn toc # Project overview
210
+ 3 modified, 1 new, 12 call sites across 4 files
211
+
212
+ MODIFIED FUNCTIONS:
213
+
214
+ processOrder
215
+ src/orders/service.ts:45
216
+ Lines added: 48-52, Lines deleted: 49
217
+ Callers (3):
218
+ src/api/checkout.ts:89 [handleCheckout]
219
+ await processOrder(cart.items, req.user)
220
+ src/workers/batch.ts:12 [batchProcess]
221
+ processOrder(order.items, systemUser)
222
+ src/jobs/daily.ts:88 [runDailyOrders]
223
+ results.push(await processOrder(items, admin))
497
224
  ```
498
225
 
499
- ---
226
+ **Trace a call tree:**
500
227
 
501
- ## Limitations
228
+ ```
229
+ $ ucn trace expandGlob --depth=2
230
+
231
+ expandGlob
232
+ ├── parseGlobPattern (core/discovery.js:219) [utility] 1x
233
+ │ └── globToRegex (core/discovery.js:256) [utility] 1x
234
+ ├── walkDir (core/discovery.js:276) [utility] 1x
235
+ │ ├── compareNames (core/discovery.js:162) [utility] 1x
236
+ │ ├── shouldIgnore (core/discovery.js:340) [utility] 1x
237
+ │ └── walkDir (core/discovery.js:276) [utility] 1x (see above)
238
+ └── compareNames (core/discovery.js:162) [utility] 1x (see above)
239
+ ```
240
+
241
+ **Find unused code:**
502
242
 
503
243
  ```
504
- ┌──────────────────────────┬──────────────────────────────────────────┐
505
- │ Limitation │ What happens │
506
- ├──────────────────────────┼──────────────────────────────────────────┤
507
- │ │ │
508
- │ 5 languages + HTML │ JS/TS, Python, Go, Rust, Java.
509
- │ (no C, Ruby, PHP, etc.) │ Agents fall back to text search for │
510
- │ │ the rest. UCN complements, doesn't │
511
- │ │ replace. │
512
- │ │ │
513
- ├──────────────────────────┼──────────────────────────────────────────┤
514
- │ │ │
515
- │ Dynamic dispatch │ getattr(), reflection, eval() — UCN │
516
- │ │ does static analysis and can't follow │
517
- │ │ calls that only exist at runtime. │
518
- │ │ │
519
- ├──────────────────────────┼──────────────────────────────────────────┤
520
- │ │ │
521
- │ Duck-typed methods │ obj.method() in JS/TS/Python — when │
522
- │ │ the receiver type is ambiguous, results │
523
- │ │ are marked "uncertain" so the agent │
524
- │ │ knows to verify. Go/Rust/Java resolve │
525
- │ │ with high confidence. │
526
- │ │ │
527
- ├──────────────────────────┼──────────────────────────────────────────┤
528
- │ │ │
529
- │ Single project scope │ UCN follows imports within the project │
530
- │ │ but stops at the boundary — no tracing │
531
- │ │ into node_modules or site-packages. │
532
- │ │ │
533
- ├──────────────────────────┼──────────────────────────────────────────┤
534
- │ │ │
535
- │ First-query index time │ Tree-sitter index is built on first │
536
- │ │ query. A few seconds on large projects. │
537
- │ │ Cached and incrementally updated — │
538
- │ │ only changed files are re-indexed. │
539
- │ │ │
540
- └──────────────────────────┴──────────────────────────────────────────┘
244
+ $ ucn deadcode --exclude=test
245
+
246
+ Dead code: 1 unused symbol(s)
247
+
248
+ core/discovery.js
249
+ [ 162- 166] legacyResolve (function)
541
250
  ```
542
251
 
543
252
  ---
544
253
 
545
- ## All 28 Commands
254
+ ## Workflows
255
+
256
+ ```bash
257
+ # Investigating a bug
258
+ ucn about buggyFunction # understand it fully
259
+ ucn trace buggyFunction --depth=2 # see what it calls
260
+
261
+ # Before modifying code
262
+ ucn impact theFunction # who will break?
263
+ ucn smart theFunction # function + its helpers inline
264
+ # ... make changes ...
265
+ ucn verify theFunction # do all call sites still match?
266
+
267
+ # Before committing
268
+ ucn diff-impact --staged # what I changed + who calls it
269
+
270
+ # Cleanup
271
+ ucn deadcode --exclude=test # what can be deleted?
272
+ ```
273
+
274
+ ---
546
275
 
547
- All commands are accessible through a single `ucn` MCP tool with a `command` parameter.
276
+ ## All 28 commands
548
277
 
549
278
  ```
550
279
  UNDERSTAND MODIFY SAFELY
551
280
  ───────────────────── ─────────────────────
552
- about everything in one impact all call sites
553
- call: definition, with arguments
554
- callers, callees,
555
- tests, source diff_impact what changed in a
556
- git diff + who
557
- context callers + callees calls it
558
- (quick overview)
559
- verify check all sites
560
- smart function + helpers match signature
561
- expanded inline
562
- plan preview a refactor
563
- trace call tree — map before doing it
564
- a whole pipeline
565
-
566
-
567
- FIND & NAVIGATE ARCHITECTURE
281
+ about full picture impact all call sites
282
+ context callers + callees diff-impact git diff + callers
283
+ smart function + helpers verify signature check
284
+ trace call tree plan refactor preview
285
+
286
+ FIND & EXTRACT ARCHITECTURE
568
287
  ───────────────────── ─────────────────────
569
288
  find locate definitions imports file dependencies
570
- usages all occurrences exporters who depends on it
571
- fn extract a function graph dependency tree
572
- class extract a class related sibling functions
573
- toc project overview tests find tests
574
- deadcode unused functions stacktrace error trace context
289
+ usages all occurrences exporters reverse dependencies
290
+ fn extract function graph dependency tree
291
+ class extract class related sibling functions
292
+ toc project overview tests find test coverage
293
+ deadcode unused code stacktrace error trace context
575
294
  search text search api public API surface
576
295
  example best usage example typedef type definitions
577
- lines extract line range file_exports file's exports
578
- expand drill into context stats project size stats
296
+ lines extract line range file-exports file's exports
297
+ expand drill into context stats project stats
579
298
  ```
580
299
 
581
300
  ---
582
301
 
302
+ ## Limitations
303
+
304
+ UCN is static AST analysis, not runtime instrumentation.
305
+
306
+ - **5 languages + HTML** — JS/TS, Python, Go, Rust, Java. Falls back to text search for others.
307
+ - **Static analysis only** — Can't follow `eval()`, `getattr()`, reflection, or other dynamic dispatch.
308
+ - **Duck-typed methods** — `obj.method()` in JS/TS/Python is marked "uncertain" when the receiver type is ambiguous. Go/Rust/Java resolve with high confidence.
309
+ - **Single project scope** — Follows imports within the project but not into `node_modules` or `site-packages`.
310
+ - **First-query index time** — A few seconds on large projects. Cached incrementally after that.
311
+
312
+ ---
313
+
583
314
  ## License
584
315
 
585
316
  MIT
586
-
587
- UCN - Universal Code Navigator