ucn 3.8.4 → 3.8.5
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/.claude/skills/ucn/SKILL.md +6 -1
- package/README.md +270 -201
- package/cli/index.js +3 -2
- package/mcp/server.js +5 -1
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ Extract functions, trace call chains, find callers, and detect dead code — wit
|
|
|
26
26
|
- Language not supported (only JS/TS, Python, Go, Rust, Java, HTML)
|
|
27
27
|
- Finding files by name — use glob
|
|
28
28
|
|
|
29
|
-
## The
|
|
29
|
+
## The Commands You'll Use Most
|
|
30
30
|
|
|
31
31
|
### 1. `about` — First stop for any investigation
|
|
32
32
|
|
|
@@ -157,6 +157,7 @@ ucn [target] <command> [name] [--flags]
|
|
|
157
157
|
|
|
158
158
|
| Flag | When to use it |
|
|
159
159
|
|------|---------------|
|
|
160
|
+
| `--class-name=X` | Scope to specific class (e.g., `--class-name=Repository` for method `save`) |
|
|
160
161
|
| `--file=<pattern>` | Disambiguate when a name exists in multiple files (e.g., `--file=api`) |
|
|
161
162
|
| `--exclude=test,mock` | Focus on production code only |
|
|
162
163
|
| `--in=src/core` | Limit search to a subdirectory |
|
|
@@ -185,6 +186,10 @@ ucn [target] <command> [name] [--flags]
|
|
|
185
186
|
| `--include-uncertain` | Include ambiguous/uncertain matches in `context`/`smart`/`about` |
|
|
186
187
|
| `--show-confidence` | Show confidence scores (0.0–1.0) per caller/callee edge in `context`/`about` |
|
|
187
188
|
| `--min-confidence=N` | Filter edges below confidence threshold (e.g., `--min-confidence=0.7` keeps only high-confidence edges) |
|
|
189
|
+
| `--calls-only` | Only show call/test-case matches in `tests` (skip file-level results) |
|
|
190
|
+
| `--add-param=<name>` | Add a parameter (`plan` command). Combine with `--default=<value>` |
|
|
191
|
+
| `--remove-param=<name>` | Remove a parameter (`plan` command) |
|
|
192
|
+
| `--rename-to=<name>` | Rename a function (`plan` command) |
|
|
188
193
|
| `--include-exported` | Include exported symbols in `deadcode` results |
|
|
189
194
|
| `--include-decorated` | Include decorated/annotated symbols in `deadcode` results |
|
|
190
195
|
| `--framework=X` | Filter `entrypoints` by framework (e.g., `express`, `spring`, `celery`) |
|
package/README.md
CHANGED
|
@@ -1,34 +1,13 @@
|
|
|
1
1
|
# UCN - Universal Code Navigator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
See what code does before you touch it.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Who calls this function? → without grepping the whole project
|
|
7
|
-
- What breaks if I change this? → every call site, with arguments
|
|
8
|
-
- What does this function do? → extracted with dependencies inline
|
|
9
|
-
- What code is safe to delete? → verified unused symbols
|
|
10
|
-
|
|
11
|
-
One command replaces 3-4 grep+read cycles. Powered by tree-sitter.
|
|
5
|
+
Find symbols, trace callers, check impact, pick the right tests, extract code and spot what's dead - from the terminal.
|
|
12
6
|
|
|
13
7
|
[](https://www.npmjs.com/package/ucn)
|
|
14
8
|
[](LICENSE)
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
## 60-Second Quickstart
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm install -g ucn
|
|
22
|
-
|
|
23
|
-
ucn toc # project overview
|
|
24
|
-
ucn fn handleRequest # extract a function without reading the file
|
|
25
|
-
ucn about handleRequest # full picture: definition, callers, callees, tests
|
|
26
|
-
ucn impact handleRequest # all call sites with arguments
|
|
27
|
-
ucn trace main --depth=3 # call tree, no file reads
|
|
28
|
-
ucn deadcode # unused functions, AST-verified
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Supports JS/TS, Python, Go, Rust, Java, and HTML. Runs locally.
|
|
10
|
+
All commands, one engine, three surfaces:
|
|
32
11
|
|
|
33
12
|
```
|
|
34
13
|
Terminal AI Agents Agent Skills
|
|
@@ -43,11 +22,27 @@ Supports JS/TS, Python, Go, Rust, Java, and HTML. Runs locally.
|
|
|
43
22
|
└─────────────┘
|
|
44
23
|
```
|
|
45
24
|
|
|
25
|
+
Supports JavaScript, TypeScript, Python, Go, Rust, Java, and HTML inline scripts.
|
|
26
|
+
|
|
27
|
+
If you work with AI, add UCN as a [Skill or MCP](#ai-setup) and let the agent ask better code questions instead of reading whole files.
|
|
28
|
+
All commands ship as a single tool.
|
|
29
|
+
|
|
30
|
+
UCN is deliberately lightweight:
|
|
31
|
+
|
|
32
|
+
- **No background processes** - parses on demand, answers, exits
|
|
33
|
+
- **No language servers** - tree-sitter does the parsing, no compilation needed
|
|
34
|
+
- **MCP is optional** - only needed if you connect UCN to an AI agent, the CLI and Skill work on their own
|
|
35
|
+
|
|
46
36
|
---
|
|
47
37
|
|
|
48
|
-
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g ucn
|
|
49
40
|
|
|
50
|
-
|
|
41
|
+
ucn trace main --depth=3 # full execution flow
|
|
42
|
+
ucn about handleRequest # definition + callers + callees + tests
|
|
43
|
+
ucn impact handleRequest # every call site with arguments
|
|
44
|
+
ucn deadcode --exclude=test # unused code, AST-verified
|
|
45
|
+
```
|
|
51
46
|
|
|
52
47
|
"What happens when `build()` runs?"
|
|
53
48
|
|
|
@@ -55,47 +50,155 @@ AI agents waste tokens reading entire files to find one function, or grep for ca
|
|
|
55
50
|
$ ucn trace build --depth=2
|
|
56
51
|
|
|
57
52
|
build
|
|
58
|
-
├── detectProjectPattern (discovery.js:
|
|
59
|
-
│ ├── checkDir (discovery.js:
|
|
60
|
-
│ └── shouldIgnore (discovery.js:
|
|
61
|
-
├── parseGitignore (discovery.js:
|
|
62
|
-
├── expandGlob (discovery.js:
|
|
63
|
-
│ ├── parseGlobPattern (discovery.js:
|
|
64
|
-
│ ├── walkDir (discovery.js:
|
|
65
|
-
│ └── compareNames (discovery.js:
|
|
66
|
-
├── indexFile (project.js:
|
|
67
|
-
│ ├── addSymbol (project.js:
|
|
53
|
+
├── detectProjectPattern (core/discovery.js:399) 1x
|
|
54
|
+
│ ├── checkDir (core/discovery.js:403) 2x
|
|
55
|
+
│ └── shouldIgnore (core/discovery.js:347) 1x
|
|
56
|
+
├── parseGitignore (core/discovery.js:130) 1x
|
|
57
|
+
├── expandGlob (core/discovery.js:190) 1x
|
|
58
|
+
│ ├── parseGlobPattern (core/discovery.js:226) 1x
|
|
59
|
+
│ ├── walkDir (core/discovery.js:283) 1x
|
|
60
|
+
│ └── compareNames (core/discovery.js:169) 1x
|
|
61
|
+
├── indexFile (core/project.js:273) 1x
|
|
62
|
+
│ ├── addSymbol (core/project.js:343) 4x
|
|
68
63
|
│ ├── detectLanguage (languages/index.js:157) 1x
|
|
69
|
-
│ ├──
|
|
70
|
-
│ └── extractImports (imports.js:19) 1x
|
|
71
|
-
├── buildImportGraph (project.js:
|
|
72
|
-
└── buildInheritanceGraph (project.js:
|
|
64
|
+
│ ├── parse (core/parser.js:69) 1x
|
|
65
|
+
│ └── extractImports (core/imports.js:19) 1x
|
|
66
|
+
├── buildImportGraph (core/project.js:549) 1x
|
|
67
|
+
└── buildInheritanceGraph (core/project.js:627) 1x
|
|
73
68
|
```
|
|
74
69
|
|
|
75
|
-
One command. No files opened.
|
|
70
|
+
One command. No files opened. Every function located by file and line.
|
|
76
71
|
|
|
77
72
|
---
|
|
78
73
|
|
|
79
|
-
##
|
|
74
|
+
## Understand code you didn't write
|
|
75
|
+
|
|
76
|
+
`ucn about` gives you everything about a function in one shot - who calls it, what it calls, which tests cover it, and the source code.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
$ ucn about expandGlob
|
|
80
|
+
|
|
81
|
+
expandGlob (function)
|
|
82
|
+
════════════════════════════════════════════════════════════
|
|
83
|
+
core/discovery.js:190-221
|
|
84
|
+
expandGlob (pattern, options = {})
|
|
85
|
+
|
|
86
|
+
CALLERS (3):
|
|
87
|
+
cli/index.js:859 [runGlobCommand]
|
|
88
|
+
const files = expandGlob(pattern);
|
|
89
|
+
core/cache.js:274 [isCacheStale]
|
|
90
|
+
const currentFiles = expandGlob(pattern, globOpts);
|
|
91
|
+
core/project.js:195 [build]
|
|
92
|
+
const files = expandGlob(pattern, globOpts);
|
|
93
|
+
|
|
94
|
+
CALLEES (3):
|
|
95
|
+
parseGlobPattern [utility] - core/discovery.js:226
|
|
96
|
+
walkDir [utility] - core/discovery.js:283
|
|
97
|
+
compareNames [utility] - core/discovery.js:169
|
|
98
|
+
|
|
99
|
+
TESTS: 6 matches in 2 file(s)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Need to trace execution upward instead? `ucn reverse-trace fn` walks the caller chain back to entry points.
|
|
103
|
+
|
|
104
|
+
## Change code without breaking things
|
|
105
|
+
|
|
106
|
+
Before touching a function, check if all existing call sites match its signature:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
$ ucn verify expandGlob
|
|
110
|
+
|
|
111
|
+
expandGlob (pattern, options = {})
|
|
112
|
+
Expected arguments: 1-2
|
|
113
|
+
|
|
114
|
+
STATUS: ✓ All calls valid (7 calls, 0 mismatches)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Then preview the refactoring. UCN shows exactly what needs to change and where:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
$ ucn plan expandGlob --rename-to=expandGlobPattern
|
|
121
|
+
|
|
122
|
+
SIGNATURE CHANGE:
|
|
123
|
+
Before: expandGlob (pattern, options = {})
|
|
124
|
+
After: expandGlobPattern (pattern, options = {})
|
|
125
|
+
|
|
126
|
+
CHANGES NEEDED: 7 across 4 files
|
|
127
|
+
|
|
128
|
+
cli/index.js :859
|
|
129
|
+
const files = expandGlob(pattern);
|
|
130
|
+
→ const files = expandGlobPattern(pattern);
|
|
131
|
+
|
|
132
|
+
core/cache.js :274
|
|
133
|
+
const currentFiles = expandGlob(pattern, globOpts);
|
|
134
|
+
→ const currentFiles = expandGlobPattern(pattern, globOpts);
|
|
135
|
+
|
|
136
|
+
core/project.js :195
|
|
137
|
+
const files = expandGlob(pattern, globOpts);
|
|
138
|
+
→ const files = expandGlobPattern(pattern, globOpts);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Run `ucn diff-impact --staged` before committing to see what you changed and who calls it.
|
|
142
|
+
|
|
143
|
+
## Find what to clean up
|
|
144
|
+
|
|
145
|
+
Which tests should you run after a change? `affected-tests` walks the blast radius and finds every test that touches the affected functions:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
$ ucn affected-tests expandGlob
|
|
149
|
+
|
|
150
|
+
1 function changed → 18 functions affected (depth 3)
|
|
151
|
+
Summary: 18 affected → 12 test files, 11/18 functions covered (61%)
|
|
152
|
+
|
|
153
|
+
Uncovered (7): runGlobCommand, runProjectCommand, ...
|
|
154
|
+
⚠ These affected functions have no test references
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Find unused code
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
$ ucn deadcode --exclude=test
|
|
161
|
+
|
|
162
|
+
Dead code: 1 unused symbol(s)
|
|
163
|
+
|
|
164
|
+
core/discovery.js
|
|
165
|
+
[ 162- 166] legacyResolve (function)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Extract without reading the whole file
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
$ ucn fn compareNames
|
|
80
172
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
173
|
+
core/discovery.js:169
|
|
174
|
+
[ 169- 177] compareNames(a, b)
|
|
175
|
+
────────────────────────────────────────────────────────────
|
|
176
|
+
function compareNames(a, b) {
|
|
177
|
+
const aLower = a.toLowerCase();
|
|
178
|
+
const bLower = b.toLowerCase();
|
|
179
|
+
if (aLower < bLower) return -1;
|
|
180
|
+
if (aLower > bLower) return 1;
|
|
181
|
+
if (a < b) return -1;
|
|
182
|
+
if (a > b) return 1;
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
91
186
|
|
|
92
187
|
---
|
|
93
188
|
|
|
94
|
-
##
|
|
189
|
+
## Testing and reliability
|
|
190
|
+
|
|
191
|
+
- **Fast** - indexes its own ~25K-line codebase in under 100ms, cached after first run
|
|
192
|
+
- **Discipline** - every bug fix gets a regression test, test code is ~3x the source
|
|
193
|
+
- **Coverage** - every command, every supported language, every surface (CLI, MCP, interactive)
|
|
194
|
+
- **Systematic** - a harness exercises all command and flag combinations against real multi-language fixtures
|
|
195
|
+
- **Test types** - unit, integration, per-language regression, formatter, cache, MCP edge cases, architecture parity guards
|
|
95
196
|
|
|
96
|
-
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## AI Setup
|
|
97
200
|
|
|
98
|
-
|
|
201
|
+
### MCP
|
|
99
202
|
|
|
100
203
|
```bash
|
|
101
204
|
# Claude Code
|
|
@@ -138,12 +241,8 @@ VS Code uses `.vscode/mcp.json`:
|
|
|
138
241
|
|
|
139
242
|
</details>
|
|
140
243
|
|
|
141
|
-
All commands ship as a single MCP tool - under 2KB of context.
|
|
142
|
-
|
|
143
244
|
### Agent Skill (no server needed)
|
|
144
245
|
|
|
145
|
-
Drop-in for Claude Code or Codex CLI:
|
|
146
|
-
|
|
147
246
|
```bash
|
|
148
247
|
# Claude Code
|
|
149
248
|
mkdir -p ~/.claude/skills
|
|
@@ -156,156 +255,126 @@ cp -r "$(npm root -g)/ucn/.claude/skills/ucn" ~/.agents/skills/
|
|
|
156
255
|
|
|
157
256
|
---
|
|
158
257
|
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
---
|
|
267
|
-
|
|
268
|
-
## All commands
|
|
269
|
-
|
|
270
|
-
```
|
|
271
|
-
UNDERSTAND MODIFY SAFELY
|
|
272
|
-
───────────────────── ─────────────────────
|
|
273
|
-
about full picture impact all call sites
|
|
274
|
-
context callers + callees blast transitive impact
|
|
275
|
-
smart function + helpers diff-impact git diff + callers
|
|
276
|
-
trace call tree verify signature check
|
|
277
|
-
reverse-trace callers → root plan refactor preview
|
|
278
|
-
|
|
279
|
-
FIND & EXTRACT ARCHITECTURE
|
|
280
|
-
───────────────────── ─────────────────────
|
|
281
|
-
find locate definitions imports file dependencies
|
|
282
|
-
usages all occurrences exporters reverse dependencies
|
|
283
|
-
fn extract function graph dependency tree
|
|
284
|
-
class extract class circular-deps import cycles
|
|
285
|
-
toc project overview related sibling functions
|
|
286
|
-
deadcode unused code tests find test coverage
|
|
287
|
-
search text search affected-tests tests for changes
|
|
288
|
-
example best usage example stacktrace error trace context
|
|
289
|
-
lines extract line range api public API surface
|
|
290
|
-
expand drill into context typedef type definitions
|
|
291
|
-
file-exports file's exports
|
|
292
|
-
stats project stats
|
|
258
|
+
## Full help
|
|
259
|
+
|
|
260
|
+
```text
|
|
261
|
+
UCN - Universal Code Navigator
|
|
262
|
+
|
|
263
|
+
Supported: JavaScript, TypeScript, Python, Go, Rust, Java, HTML
|
|
264
|
+
|
|
265
|
+
Usage:
|
|
266
|
+
ucn [command] [args] Project mode (current directory)
|
|
267
|
+
ucn <file> [command] [args] Single file mode
|
|
268
|
+
ucn <dir> [command] [args] Project mode (specific directory)
|
|
269
|
+
ucn "pattern" [command] [args] Glob pattern mode
|
|
270
|
+
(Default output is text; add --json for machine-readable JSON)
|
|
271
|
+
|
|
272
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
273
|
+
UNDERSTAND CODE
|
|
274
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
275
|
+
about <name> Full picture (definition, callers, callees, tests, code)
|
|
276
|
+
context <name> Who calls this + what it calls (numbered for expand)
|
|
277
|
+
smart <name> Function + all dependencies inline
|
|
278
|
+
impact <name> What breaks if changed (call sites grouped by file)
|
|
279
|
+
blast <name> Transitive blast radius (callers of callers, --depth=N)
|
|
280
|
+
trace <name> Call tree visualization (--depth=N expands all children)
|
|
281
|
+
reverse-trace <name> Upward call chain to entry points (--depth=N, default 5)
|
|
282
|
+
related <name> Find similar functions (same file, shared deps)
|
|
283
|
+
example <name> Best usage example with context
|
|
284
|
+
|
|
285
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
286
|
+
FIND CODE
|
|
287
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
288
|
+
find <name> Find symbol definitions (supports glob: find "handle*")
|
|
289
|
+
usages <name> All usages grouped: definitions, calls, imports, references
|
|
290
|
+
toc Table of contents (compact; --detailed lists all symbols)
|
|
291
|
+
search <term> Text search (regex default, --context=N, --exclude=, --in=)
|
|
292
|
+
Structural: --type=function|class|call --param= --returns= --decorator= --exported --unused
|
|
293
|
+
tests <name> Find test files for a function
|
|
294
|
+
affected-tests <n> Tests affected by a change (blast + test detection, --depth=N)
|
|
295
|
+
|
|
296
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
297
|
+
EXTRACT CODE
|
|
298
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
299
|
+
fn <name>[,n2,...] Extract function(s) (comma-separated for bulk, --file)
|
|
300
|
+
class <name> Extract class
|
|
301
|
+
lines <range> Extract line range (e.g., lines 50-100)
|
|
302
|
+
expand <N> Show code for item N from context output
|
|
303
|
+
|
|
304
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
305
|
+
FILE DEPENDENCIES
|
|
306
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
307
|
+
imports <file> What does file import
|
|
308
|
+
exporters <file> Who imports this file
|
|
309
|
+
file-exports <file> What does file export
|
|
310
|
+
graph <file> Full dependency tree (--depth=N, --direction=imports|importers|both)
|
|
311
|
+
circular-deps Detect circular import chains (--file=, --exclude=)
|
|
312
|
+
|
|
313
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
314
|
+
REFACTORING HELPERS
|
|
315
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
316
|
+
plan <name> Preview refactoring (--add-param, --remove-param, --rename-to)
|
|
317
|
+
verify <name> Check all call sites match signature
|
|
318
|
+
diff-impact What changed in git diff and who calls it (--base, --staged)
|
|
319
|
+
deadcode Find unused functions/classes
|
|
320
|
+
entrypoints Detect framework entry points (routes, DI, tasks)
|
|
321
|
+
|
|
322
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
323
|
+
OTHER
|
|
324
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
325
|
+
api Show exported/public symbols
|
|
326
|
+
typedef <name> Find type definitions
|
|
327
|
+
stats Project statistics (--functions for per-function line counts)
|
|
328
|
+
stacktrace <text> Parse stack trace, show code at each frame (alias: stack)
|
|
329
|
+
|
|
330
|
+
Common Flags:
|
|
331
|
+
--file <pattern> Filter by file path (e.g., --file=routes)
|
|
332
|
+
--exclude=a,b Exclude patterns (e.g., --exclude=test,mock)
|
|
333
|
+
--in=<path> Only in path (e.g., --in=src/core)
|
|
334
|
+
--depth=N Trace/graph depth (default: 3, also expands all children)
|
|
335
|
+
--direction=X Graph direction: imports, importers, or both (default: both)
|
|
336
|
+
--all Expand truncated sections (about, trace, graph, related)
|
|
337
|
+
--top=N Limit results (find, deadcode)
|
|
338
|
+
--limit=N Limit result count (find, usages, search, deadcode, api, toc)
|
|
339
|
+
--max-files=N Max files to index (large projects)
|
|
340
|
+
--context=N Lines of context around matches
|
|
341
|
+
--json Machine-readable output
|
|
342
|
+
--code-only Filter out comments and strings
|
|
343
|
+
--with-types Include type definitions
|
|
344
|
+
--include-tests Include test files
|
|
345
|
+
--class-name=X Scope to specific class (e.g., --class-name=Repository)
|
|
346
|
+
--include-methods Include method calls (obj.fn) in caller/callee analysis
|
|
347
|
+
--include-uncertain Include ambiguous/uncertain matches
|
|
348
|
+
--show-confidence Show confidence scores per caller/callee edge
|
|
349
|
+
--min-confidence=N Filter edges below confidence threshold (0.0-1.0)
|
|
350
|
+
--include-exported Include exported symbols in deadcode
|
|
351
|
+
--no-regex Force plain text search (regex is default)
|
|
352
|
+
--functions Show per-function line counts (stats command)
|
|
353
|
+
--include-decorated Include decorated/annotated symbols in deadcode
|
|
354
|
+
--framework=X Filter entrypoints by framework (e.g., --framework=express,spring)
|
|
355
|
+
--exact Exact name match only (find)
|
|
356
|
+
--calls-only Only show call/test-case matches (tests)
|
|
357
|
+
--case-sensitive Case-sensitive text search (search)
|
|
358
|
+
--detailed List all symbols in toc (compact by default)
|
|
359
|
+
--top-level Show only top-level functions in toc
|
|
360
|
+
--max-lines=N Max source lines for class (large classes show summary)
|
|
361
|
+
--no-cache Disable caching
|
|
362
|
+
--clear-cache Clear cache before running
|
|
363
|
+
--base=<ref> Git ref for diff-impact (default: HEAD)
|
|
293
364
|
```
|
|
294
365
|
|
|
295
366
|
---
|
|
296
367
|
|
|
297
368
|
## Limitations
|
|
298
369
|
|
|
299
|
-
|
|
370
|
+
- Single-project scope - follows imports within the project, not into `node_modules` or `site-packages`
|
|
371
|
+
- No runtime execution - static analysis only
|
|
372
|
+
- Dynamic dispatch and reflection are only partially visible or invisible
|
|
373
|
+
- JS, TS, and Python method calls can be uncertain when receiver type is unknown
|
|
374
|
+
- Large repos take a few seconds on the first query, then use cache
|
|
300
375
|
|
|
301
|
-
|
|
302
|
-
- **Static analysis only** - Can't follow `eval()`, `getattr()`, reflection, or other dynamic dispatch.
|
|
303
|
-
- **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.
|
|
304
|
-
- **Single project scope** - Follows imports within the project but not into `node_modules` or `site-packages`.
|
|
305
|
-
- **First-query index time** - A few seconds on large projects. Cached incrementally after that.
|
|
376
|
+
If you need compiler diagnostics, taint analysis, or runtime semantics, those are different tools for different jobs. UCN trades that depth for speed, portability, and zero setup.
|
|
306
377
|
|
|
307
378
|
---
|
|
308
379
|
|
|
309
|
-
## License
|
|
310
|
-
|
|
311
380
|
MIT
|
package/cli/index.js
CHANGED
|
@@ -171,7 +171,7 @@ const VALUE_FLAGS = new Set([
|
|
|
171
171
|
'--add-param', '--remove-param', '--rename-to', '--default',
|
|
172
172
|
'--base', '--exclude', '--not', '--in', '--max-lines', '--class-name',
|
|
173
173
|
'--type', '--param', '--receiver', '--returns', '--decorator',
|
|
174
|
-
'--limit', '--max-files', '--min-confidence', '--stack'
|
|
174
|
+
'--limit', '--max-files', '--min-confidence', '--stack', '--framework'
|
|
175
175
|
]);
|
|
176
176
|
|
|
177
177
|
// Remove flags from args, then add args after -- (which are all positional)
|
|
@@ -1124,6 +1124,7 @@ Common Flags:
|
|
|
1124
1124
|
--code-only Filter out comments and strings
|
|
1125
1125
|
--with-types Include type definitions
|
|
1126
1126
|
--include-tests Include test files
|
|
1127
|
+
--class-name=X Scope to specific class (e.g., --class-name=Repository)
|
|
1127
1128
|
--include-methods Include method calls (obj.fn) in caller/callee analysis
|
|
1128
1129
|
--include-uncertain Include ambiguous/uncertain matches
|
|
1129
1130
|
--show-confidence Show confidence scores per caller/callee edge
|
|
@@ -1248,7 +1249,7 @@ Flags can be added per-command: context myFunc --include-methods
|
|
|
1248
1249
|
const tokens = input.split(/\s+/);
|
|
1249
1250
|
const command = tokens[0];
|
|
1250
1251
|
// Flags that take a space-separated value (--flag value)
|
|
1251
|
-
const valueFlagNames = new Set(['--file', '--in', '--base', '--add-param', '--remove-param', '--rename-to', '--default', '--depth', '--top', '--context', '--max-lines', '--direction', '--exclude', '--not', '--stack', '--type', '--param', '--receiver', '--returns', '--decorator', '--limit', '--max-files', '--min-confidence', '--class-name']);
|
|
1252
|
+
const valueFlagNames = new Set(['--file', '--in', '--base', '--add-param', '--remove-param', '--rename-to', '--default', '--depth', '--top', '--context', '--max-lines', '--direction', '--exclude', '--not', '--stack', '--type', '--param', '--receiver', '--returns', '--decorator', '--limit', '--max-files', '--min-confidence', '--class-name', '--framework']);
|
|
1252
1253
|
const flagTokens = [];
|
|
1253
1254
|
const argTokens = [];
|
|
1254
1255
|
const skipNext = new Set();
|
package/mcp/server.js
CHANGED
|
@@ -185,6 +185,7 @@ UNDERSTANDING CODE:
|
|
|
185
185
|
- smart <name>: Get a function's source with all called functions expanded inline (not constants/variables). Use to understand or modify a function and its dependencies in one read.
|
|
186
186
|
- trace <name>: Call tree from a function downward. Use to understand "what happens when X runs" — maps which modules a pipeline touches without reading files. Set depth (default: 3); setting depth expands all children.
|
|
187
187
|
- example <name>: Best real-world usage example. Automatically scores call sites by quality and returns the top one with context. Use to understand expected calling patterns.
|
|
188
|
+
- reverse_trace <name>: Upward call chain to entry points — who calls this, who calls those callers, etc. Use to find all paths that lead to a function. Set depth (default: 5) to control how far up. Complement to trace (which goes downward).
|
|
188
189
|
- related <name>: Sibling functions: same file, similar names, or shared callers/callees. Find companions to update together (e.g., serialize when you're changing deserialize). Name-based, not semantic.
|
|
189
190
|
|
|
190
191
|
FINDING CODE:
|
|
@@ -195,6 +196,7 @@ FINDING CODE:
|
|
|
195
196
|
- tests <name>: Find test files covering a function, test case names, and how it's called in tests. Use before modifying or to find test patterns to follow.
|
|
196
197
|
- affected_tests <name>: Which tests to run after changing a function. Combines blast (transitive callers) with test detection. Shows test files, coverage %, and uncovered functions. Use depth= to control depth.
|
|
197
198
|
- deadcode: Find dead code: functions/classes with zero callers. Use during cleanup to identify safely deletable code. Excludes exported, decorated, and test symbols by default — use include_exported/include_decorated/include_tests to expand.
|
|
199
|
+
- entrypoints: Detect framework entry points: routes, handlers, DI providers, tasks. Auto-detects Express, Flask, Spring, Gin, Actix, and more. Use framework= to filter by specific framework.
|
|
198
200
|
|
|
199
201
|
EXTRACTING CODE (use instead of reading entire files):
|
|
200
202
|
- fn <name>: Extract one or more functions. Comma-separated for bulk extraction (e.g. "parse,format,validate"). Use file to disambiguate.
|
|
@@ -207,6 +209,7 @@ FILE DEPENDENCIES (require file param):
|
|
|
207
209
|
- exporters: Every file that imports/depends on this file — shows dependents rather than dependencies. Use before moving, renaming, or deleting.
|
|
208
210
|
- file_exports: File's public API: all exported functions, classes, variables with signatures. Use to understand what a module offers before importing. Requires explicit export markers; use toc --detailed as fallback.
|
|
209
211
|
- graph: File-level dependency tree. Use to understand module architecture — which files form a cluster, what the dependency chain looks like. Set direction ("imports"/"importers"/"both"). Can be noisy — use depth=1 for large codebases.
|
|
212
|
+
- circular_deps: Detect circular import chains. Shows cycle paths and involved files. Use file= to check a specific file, exclude= to ignore paths.
|
|
210
213
|
|
|
211
214
|
REFACTORING:
|
|
212
215
|
- verify <name>: Check all call sites match function signature (argument count). Run before adding/removing parameters to catch breakage early.
|
|
@@ -272,7 +275,8 @@ server.registerTool(
|
|
|
272
275
|
returns: z.string().optional().describe('Filter by return type (structural search). E.g. "Promise", "error".'),
|
|
273
276
|
decorator: z.string().optional().describe('Filter by decorator/annotation (structural search). E.g. "Route", "Test".'),
|
|
274
277
|
exported: z.boolean().optional().describe('Only exported/public symbols (structural search).'),
|
|
275
|
-
unused: z.boolean().optional().describe('Only symbols with zero callers (structural search).')
|
|
278
|
+
unused: z.boolean().optional().describe('Only symbols with zero callers (structural search).'),
|
|
279
|
+
framework: z.string().optional().describe('Filter entrypoints by framework (e.g. "express", "spring", "flask"). Comma-separated for multiple.')
|
|
276
280
|
|
|
277
281
|
})
|
|
278
282
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ucn",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.5",
|
|
4
4
|
"mcpName": "io.github.mleoca/ucn",
|
|
5
5
|
"description": "Code intelligence toolkit for AI agents — extract functions, trace call chains, find callers, detect dead code without reading entire files. Works as MCP server, CLI, or agent skill. Supports JS/TS, Python, Go, Rust, Java.",
|
|
6
6
|
"main": "index.js",
|