ucn 3.8.23 → 3.8.25
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 +114 -11
- package/README.md +152 -156
- package/cli/index.js +363 -37
- package/core/analysis.js +936 -32
- package/core/bridge.js +1111 -0
- package/core/brief.js +408 -0
- package/core/cache.js +105 -5
- package/core/callers.js +72 -18
- package/core/check.js +200 -0
- package/core/discovery.js +57 -34
- package/core/entrypoints.js +638 -4
- package/core/execute.js +304 -5
- package/core/git-enrich.js +130 -0
- package/core/graph.js +24 -2
- package/core/output/analysis.js +157 -25
- package/core/output/brief.js +100 -0
- package/core/output/check.js +79 -0
- package/core/output/doctor.js +85 -0
- package/core/output/endpoints.js +239 -0
- package/core/output/extraction.js +2 -0
- package/core/output/find.js +126 -39
- package/core/output/graph.js +48 -15
- package/core/output/refactoring.js +103 -5
- package/core/output/reporting.js +63 -23
- package/core/output/search.js +110 -17
- package/core/output/shared.js +56 -2
- package/core/output.js +4 -0
- package/core/parser.js +8 -2
- package/core/project.js +39 -3
- package/core/registry.js +30 -14
- package/core/reporting.js +465 -2
- package/core/search.js +130 -10
- package/core/shared.js +101 -5
- package/core/tracing.js +16 -6
- package/core/verify.js +982 -95
- package/languages/go.js +91 -6
- package/languages/html.js +10 -0
- package/languages/java.js +151 -35
- package/languages/javascript.js +290 -33
- package/languages/python.js +78 -11
- package/languages/rust.js +267 -12
- package/languages/utils.js +315 -3
- package/mcp/server.js +91 -16
- package/package.json +9 -1
|
@@ -91,15 +91,56 @@ ucn deadcode --exclude=test # Skip test files (most useful)
|
|
|
91
91
|
ucn deadcode --include-decorated # Include framework-registered functions
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
### 7. `
|
|
94
|
+
### 7. `brief` — One-screen "before-I-touch-this" summary
|
|
95
|
+
|
|
96
|
+
AST-only summary of a function: typed signature, first sentence of docstring,
|
|
97
|
+
side-effect classification (fs/network/process/global_mutation), and complexity
|
|
98
|
+
metrics (branches, depth, line count). Lighter than `about`, more useful than
|
|
99
|
+
`fn` when you don't need the body.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
ucn brief fetch_user
|
|
103
|
+
# fetch_user(user_id: int): dict
|
|
104
|
+
# svc.py:4-8 (5 lines)
|
|
105
|
+
# "Fetch a user from the API."
|
|
106
|
+
# async: no | side_effects: [fs, network, process] | complexity: branches=2, depth=2
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 8. `doctor` — Project trust report
|
|
110
|
+
|
|
111
|
+
One command that tells you how much UCN trusts the index for this project:
|
|
112
|
+
file/symbol counts, language breakdown, dynamic-import / eval / reflection
|
|
113
|
+
blind spots, parse failures, and a verdict (HIGH/MEDIUM/LOW). Add `--deep` to
|
|
114
|
+
sample resolution coverage and bucket edges by confidence.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
ucn doctor # fast: counts + blind spots + verdict
|
|
118
|
+
ucn doctor --deep # also samples resolution coverage
|
|
119
|
+
ucn doctor --in=src/core # scope to a subtree
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 9. `check` — Pre-commit summary
|
|
123
|
+
|
|
124
|
+
Composes `diff-impact` + `verify` + `affected-tests` into one output. Lists
|
|
125
|
+
changed/added/deleted functions, flags signature drift across call sites,
|
|
126
|
+
calls out new functions with no callers, and recommends which tests to run.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
ucn check # vs HEAD
|
|
130
|
+
ucn check --base=main # vs main branch
|
|
131
|
+
ucn check --staged # only staged changes
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 10. `entrypoints` — Detect framework entry points
|
|
95
135
|
|
|
96
136
|
Lists functions registered as framework handlers (HTTP routes, DI beans, job schedulers, etc.). Detects patterns across Express, FastAPI, Flask, Spring, Gin, Actix, Celery, pytest, and more.
|
|
97
137
|
|
|
98
138
|
```bash
|
|
99
|
-
ucn entrypoints # All detected entry points
|
|
139
|
+
ucn entrypoints # All detected entry points (tests included by default)
|
|
100
140
|
ucn entrypoints --type=http # HTTP routes only
|
|
101
141
|
ucn entrypoints --framework=express # Specific framework
|
|
102
142
|
ucn entrypoints --file=routes/ # Scoped to files
|
|
143
|
+
ucn entrypoints --exclude-tests # Hide test fixtures (JUnit @Test, pytest, Rust #[test], etc.)
|
|
103
144
|
```
|
|
104
145
|
|
|
105
146
|
## When to Use the Other Commands
|
|
@@ -117,7 +158,7 @@ ucn entrypoints --file=routes/ # Scoped to files
|
|
|
117
158
|
| Understanding who depends on a file | `ucn exporters <file>` | Which files import it |
|
|
118
159
|
| See what a file exports | `ucn file-exports <file>` | All exported functions, classes, variables with signatures |
|
|
119
160
|
| Quick project overview | `ucn toc` | Every file with function/class counts and line counts |
|
|
120
|
-
| Project complexity stats | `ucn stats` | File counts, symbol counts, lines by language. `--functions` for per-function line counts |
|
|
161
|
+
| Project complexity stats | `ucn stats` | File counts, symbol counts, lines by language. `--functions` for per-function line counts. `--hot --top=N` for the most-called functions (orientation primitive on a new repo) |
|
|
121
162
|
| Find by glob pattern | `ucn find "handle*"` | Locate definitions matching a glob (supports * and ?) |
|
|
122
163
|
| Text search with context | `ucn search term --context=3` | Like grep -C 3, shows surrounding lines |
|
|
123
164
|
| Regex search (default) | `ucn search '\d+'` | Search supports regex by default (alternation, character classes, etc.) |
|
|
@@ -133,13 +174,62 @@ ucn entrypoints --file=routes/ # Scoped to files
|
|
|
133
174
|
| File-level dependency tree | `ucn graph <file> --depth=1` | Visual import tree. Setting `--depth=N` expands all children. Can be noisy — use depth=1 for large projects. For function-level flow, use `trace` instead |
|
|
134
175
|
| Are there circular dependencies? | `ucn circular-deps` | Detect circular import chains. `--file=<pattern>` filters to cycles involving a file. `--exclude=test` skips test files |
|
|
135
176
|
| What are the framework entry points? | `ucn entrypoints` | Lists all detected routes, DI beans, tasks, etc. Filter: `--type=http`, `--framework=express` |
|
|
177
|
+
| Polyglot route ↔ request matching | `ucn endpoints --bridge` | Server routes (Express/Fastify/Koa/NestJS/Flask/FastAPI/Spring/JAX-RS/Gin/Echo/Chi/Fiber/axum/actix/Next.js) ↔ client requests (fetch/axios/requests/httpx/RestTemplate/WebClient/reqwest). Match confidence: EXACT, PARTIAL, UNCERTAIN. Filter with `--method`, `--prefix`, `--server-only`, `--client-only`, `--unmatched`, `--hide-uncertain` |
|
|
136
178
|
| Find which tests cover a function | `ucn tests <name>` | Test files and test function names. Scope with `--file`, `--class-name`, `--exclude`, `--calls-only` |
|
|
137
|
-
| Extract specific lines from a file | `ucn lines --file=<file
|
|
179
|
+
| Extract specific lines from a file | `ucn lines 10-20 --file=<file>` | Pull a line range without reading the whole file |
|
|
138
180
|
| Find type definitions | `ucn typedef <name>` | Interfaces, enums, structs, traits, type aliases |
|
|
139
181
|
| See a project's public API | `ucn api` or `ucn api --file=<file>` | All exported/public symbols with signatures |
|
|
140
182
|
| Drill into context results | `ucn expand <N>` | Show source code for item N from a previous `context` call |
|
|
141
183
|
| Best usage example of a function | `ucn example <name>` | Finds and scores the best call site with surrounding context |
|
|
142
184
|
| Debug a stack trace | `ucn stacktrace --stack="<trace>"` | Parses stack frames and shows source context per frame |
|
|
185
|
+
| Quick look before touching a function | `ucn brief <name>` | Signature + docstring + side effects + complexity, one screen |
|
|
186
|
+
| Project trust report | `ucn doctor [--deep]` | Index coverage, blind spots, parse failures, verdict |
|
|
187
|
+
| Pre-commit summary | `ucn check [--base=main]` | Changed funcs + signature drift + affected tests in one shot |
|
|
188
|
+
| Find missing-await bugs | `ucn audit-async` | Lists async calls inside async functions that lack `await`. JS/TS/Python only. Filter with `--file`, `--exclude`, `--limit` |
|
|
189
|
+
|
|
190
|
+
## Reading Call-Site Patterns
|
|
191
|
+
|
|
192
|
+
`verify`, `impact`, and `about` annotate call sites with structural classification flags. Watch for these in summary lines (`Patterns: 4 in try, 4 in callback`) and per-call-site entries:
|
|
193
|
+
|
|
194
|
+
| Flag | What it means | Why it matters |
|
|
195
|
+
|------|--------------|---------------|
|
|
196
|
+
| `inLoop` | Call is inside a `for`/`while`/comprehension | N+1 query risk, repeated work, performance hot path |
|
|
197
|
+
| `inTry` | Call is wrapped in try/catch (or equivalent) | Errors are handled — different from "must fix" code paths |
|
|
198
|
+
| `inCallback` | Call sits inside a callback/lambda/closure that's not the enclosing function | Async deferred work, may run on a different stack frame |
|
|
199
|
+
| `inTestCase` | Call originates from inside a test function | Isolate production callers from test setup |
|
|
200
|
+
| `awaited` | Call's parent is `await` / `Promise.then` (JS/TS/Python) | Confirms async coordination — its absence on async callees signals a missing-await bug |
|
|
201
|
+
|
|
202
|
+
`audit-async` is the focused tool for the `awaited=false` case across an entire async function body.
|
|
203
|
+
|
|
204
|
+
## Confidence Scores
|
|
205
|
+
|
|
206
|
+
`about` and `context` show confidence per caller/callee edge by default (e.g. `confidence: 0.65 (scope-match)`). Resolution labels (high to low):
|
|
207
|
+
|
|
208
|
+
| Label | Score | Meaning |
|
|
209
|
+
|-------|-------|---------|
|
|
210
|
+
| `exact-binding` | 0.98 | Import or binding evidence — direct call |
|
|
211
|
+
| `same-class` | 0.92 | Method call resolved within the enclosing class |
|
|
212
|
+
| `receiver-hint` | 0.80 | Receiver type inferred (Go/Java/Rust) — e.g. `f.run()` where `f: Filter` |
|
|
213
|
+
| `scope-match` | 0.65 | Symbol resolved by name within a file/package scope |
|
|
214
|
+
| `name-only` | 0.40 | Name match only, no binding/scope evidence — review before trusting |
|
|
215
|
+
| `uncertain` | 0.25 | Ambiguous — multiple candidates, hidden unless `--include-uncertain` |
|
|
216
|
+
|
|
217
|
+
Filter or hide:
|
|
218
|
+
- `--min-confidence=0.7` — keep only high-confidence edges (≥ same-class)
|
|
219
|
+
- `--hide-confidence` — silence the scores (legacy `--no-confidence` is a silent alias)
|
|
220
|
+
- `--include-uncertain` — include otherwise-filtered low-confidence matches
|
|
221
|
+
|
|
222
|
+
## Symbol Handles (stable IDs)
|
|
223
|
+
|
|
224
|
+
Every result that lists a symbol emits a **handle** in the form `relativePath:line:name` (e.g. `core/api.ts:42:handler`). Pass it back to any name-accepting command and resolution is pinned to that exact definition — no name disambiguation, no `--file` needed.
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
ucn find handler # → emits src/api.ts:42:handler
|
|
228
|
+
ucn brief src/api.ts:42:handler # pins to that exact one
|
|
229
|
+
ucn impact src/api.ts:42:handler # same
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The shorter `relativePath:line` form (no `:name`) also works — UCN looks up the symbol by location. Plain names (`handler`) still work for the fuzzy/heuristic path.
|
|
143
233
|
|
|
144
234
|
## Command Format
|
|
145
235
|
|
|
@@ -157,14 +247,15 @@ ucn [target] <command> [name] [--flags]
|
|
|
157
247
|
|
|
158
248
|
| Flag | When to use it |
|
|
159
249
|
|------|---------------|
|
|
160
|
-
| `--class-name=X` | Scope to specific class (e.g., `--class-name=Repository` for method `save`). Works with `
|
|
250
|
+
| `--class-name=X` | Scope to specific class (e.g., `--class-name=Repository` for method `save`). Works with `about`, `context`, `impact`, `blast`, `smart`, `trace`, `reverse-trace`, `example`, `related`, `brief`, `find`, `usages`, `tests`, `affected-tests`, `fn`, `verify`, `plan`, `typedef` |
|
|
161
251
|
| `--file=<pattern>` | Disambiguate when a name exists in multiple files (e.g., `--file=api`) |
|
|
162
252
|
| `--exclude=test,mock` | Focus on production code only |
|
|
163
253
|
| `--in=src/core` | Limit search to a subdirectory |
|
|
164
254
|
| `--depth=N` | Control tree depth for `trace`, `graph`, and detail level for `find` (default 3). Also expands all children — no breadth limit |
|
|
165
|
-
| `--all` | Expand truncated sections
|
|
255
|
+
| `--all` | Expand truncated sections. Applies to `about`, `blast`, `trace`, `reverse-trace`, `related`, `find`, `toc`, `fn`, `class`, `graph`, `diff-impact` |
|
|
166
256
|
| `--include-tests` | Include test files in usage counts (`about`) and results (`find`, `usages`, `deadcode`). Callers always include tests. |
|
|
167
|
-
| `--
|
|
257
|
+
| `--exclude-tests` | Exclude test entries from `entrypoints` (tests are included by default since they ARE entry points). |
|
|
258
|
+
| `--include-methods` | Include `obj.method()` calls in caller/callee analysis. `impact` defaults to true (show all callable sites); other commands default to false (use `--no-include-methods` to opt out). Applies to `about`, `context`, `impact`, `verify`, `blast`, `smart`, `trace`, `reverse-trace`, `affected-tests` |
|
|
168
259
|
| `--base=<ref>` | Git ref for diff-impact (default: HEAD) |
|
|
169
260
|
| `--staged` | Analyze staged changes (diff-impact) |
|
|
170
261
|
| `--no-cache` | Force re-index after editing files |
|
|
@@ -172,19 +263,22 @@ ucn [target] <command> [name] [--flags]
|
|
|
172
263
|
| `--context=N` | Lines of surrounding context in `usages`/`search` output |
|
|
173
264
|
| `--no-regex` | Force plain text search (regex is default) |
|
|
174
265
|
| `--functions` | Show per-function line counts in `stats` (complexity audit) |
|
|
175
|
-
| `--
|
|
266
|
+
| `--hot` | List top N most-called functions in `stats` (use with `--top=N`, default 10). Best orientation primitive when entering a new repo |
|
|
267
|
+
| `--diverse` | Cluster `example` call sites by argument shape and return one representative per cluster (use with `--top=N`, default 3) |
|
|
268
|
+
| `--git` | Attach git enrichment to `about` / `brief`: last commit (ISO + author) and recent change count (last 30 days). Skipped silently when not a git repo |
|
|
269
|
+
| `--json` | Machine-readable JSON output. Some commands wrap in `{meta, data}` (e.g., `find`, `deadcode`); others return flat objects (e.g., `about`, `impact`, `verify`, `plan`, `imports`) — check each command's output shape |
|
|
176
270
|
| `--code-only` | Exclude matches in comments and strings (`search`/`usages`) |
|
|
177
271
|
| `--with-types` | Include related type definitions in `smart`/`about` output |
|
|
178
272
|
| `--detailed` | Show full symbol listing per file in `toc` |
|
|
179
273
|
| `--top-level` | Show only top-level functions in `toc` (exclude nested/indented) |
|
|
180
274
|
| `--top=N` | Limit result count (default: 10 for most commands) |
|
|
181
|
-
| `--limit=N` | Limit result count for `find`, `usages`, `
|
|
275
|
+
| `--limit=N` | Limit result count for `find`, `usages`, `toc`, `search`, `deadcode`, `entrypoints`, `endpoints`, `diff-impact`, `check`, `api`, `doctor`, `audit-async` |
|
|
182
276
|
| `--max-files=N` | Max files to index (for large projects with 10K+ files) |
|
|
183
277
|
| `--max-lines=N` | Max source lines for `class` (large classes show summary by default) |
|
|
184
278
|
| `--case-sensitive` | Case-sensitive text search (default: case-insensitive) |
|
|
185
279
|
| `--exact` | Exact name match only in `find`/`typedef` (no substring) |
|
|
186
|
-
| `--include-uncertain` | Include ambiguous/uncertain matches
|
|
187
|
-
| `--
|
|
280
|
+
| `--include-uncertain` | Include ambiguous/uncertain matches. Applies to `about`, `context`, `blast`, `smart`, `trace`, `reverse-trace`, `affected-tests` |
|
|
281
|
+
| `--hide-confidence` | Hide confidence scores (shown by default) in `context`/`about` |
|
|
188
282
|
| `--min-confidence=N` | Filter edges below confidence threshold (e.g., `--min-confidence=0.7` keeps only high-confidence edges) |
|
|
189
283
|
| `--calls-only` | Only show call/test-case matches in `tests` (skip file-level results) |
|
|
190
284
|
| `--add-param=<name>` | Add a parameter (`plan` command). Combine with `--default=<value>` |
|
|
@@ -193,6 +287,13 @@ ucn [target] <command> [name] [--flags]
|
|
|
193
287
|
| `--include-exported` | Include exported symbols in `deadcode` results |
|
|
194
288
|
| `--include-decorated` | Include decorated/annotated symbols in `deadcode` results |
|
|
195
289
|
| `--framework=X` | Filter `entrypoints` by framework (e.g., `express`, `spring`, `celery`) |
|
|
290
|
+
| `--bridge` | Match server routes to client requests (`endpoints`). Confidence tiers: EXACT, PARTIAL, UNCERTAIN |
|
|
291
|
+
| `--server-only` | Only list server routes (`endpoints`) |
|
|
292
|
+
| `--client-only` | Only list client requests (`endpoints`) |
|
|
293
|
+
| `--unmatched` | Only show routes/requests with no match (`endpoints`, pair with `--bridge`) |
|
|
294
|
+
| `--method=GET` | Filter by HTTP method (`endpoints`) |
|
|
295
|
+
| `--prefix=/api` | Filter routes/requests by path prefix (`endpoints`) |
|
|
296
|
+
| `--hide-uncertain` | Hide UNCERTAIN-confidence bridges (`endpoints`) |
|
|
196
297
|
| `--type=<kind>` | Structural search: `function`, `class`, `call`, `method`, `type`. Triggers index query instead of text grep |
|
|
197
298
|
| `--param=<name>` | Structural search: filter by parameter name or type (e.g., `--param=Request`) |
|
|
198
299
|
| `--receiver=<name>` | Structural search: filter calls by receiver (e.g., `--receiver=db` for all db.* calls) |
|
|
@@ -202,6 +303,8 @@ ucn [target] <command> [name] [--flags]
|
|
|
202
303
|
| `--unused` | Structural search: only symbols with zero callers |
|
|
203
304
|
| `--no-follow-symlinks` | Don't follow symbolic links during file discovery |
|
|
204
305
|
| `--workers=N` | Parallel build workers (auto-detect by default; `0` to disable; env: `UCN_WORKERS`) |
|
|
306
|
+
| `--deep` | `doctor` only: sample resolution coverage. Slower but produces confidence histogram. |
|
|
307
|
+
| `--compact` | One-line-per-item output for `about`/`context`/`find`/`usages`/`impact`. Halves token cost; same info. |
|
|
205
308
|
|
|
206
309
|
## Workflow Integration
|
|
207
310
|
|
package/README.md
CHANGED
|
@@ -51,21 +51,21 @@ ucn deadcode --exclude=test # unused code, AST-verified
|
|
|
51
51
|
$ ucn trace build --depth=2
|
|
52
52
|
|
|
53
53
|
build
|
|
54
|
-
├── detectProjectPattern (core/discovery.js:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
├──
|
|
58
|
-
├──
|
|
59
|
-
│
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
├──
|
|
63
|
-
│ ├──
|
|
64
|
-
│ ├── detectLanguage (languages/index.js:157) 1x
|
|
54
|
+
├── detectProjectPattern (core/discovery.js:431) 1x
|
|
55
|
+
├── parseGitignore (core/discovery.js:131) 1x
|
|
56
|
+
├── expandGlob (core/discovery.js:191) 1x
|
|
57
|
+
│ ├── parseGlobPattern (core/discovery.js:227) 1x
|
|
58
|
+
│ ├── walkDir (core/discovery.js:284) 1x
|
|
59
|
+
│ └── compareNames (core/discovery.js:170) 1x
|
|
60
|
+
├── parallelBuild (core/parallel-build.js:25) 1x
|
|
61
|
+
├── indexFile (core/project.js:310) 1x
|
|
62
|
+
│ ├── addSymbol (core/project.js:398) 4x
|
|
63
|
+
│ ├── detectLanguage (languages/index.js:209) 1x
|
|
65
64
|
│ ├── parse (core/parser.js:69) 1x
|
|
66
|
-
│
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
│ ├── extractImports (core/imports.js:19) 1x
|
|
66
|
+
│ └── extractExports (core/imports.js:44) 1x
|
|
67
|
+
├── buildImportGraph (core/project.js:631) 1x
|
|
68
|
+
└── buildInheritanceGraph (core/project.js:636) 1x
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
One command. No files opened. Every function located by file and line.
|
|
@@ -81,26 +81,28 @@ $ ucn about expandGlob
|
|
|
81
81
|
|
|
82
82
|
expandGlob (function)
|
|
83
83
|
════════════════════════════════════════════════════════════
|
|
84
|
-
core/discovery.js:
|
|
85
|
-
expandGlob (pattern, options = {})
|
|
84
|
+
core/discovery.js:191-222 → core/discovery.js:191:expandGlob
|
|
85
|
+
expandGlob (pattern: string, options: number = {}) : string[]
|
|
86
86
|
|
|
87
|
-
CALLERS (
|
|
88
|
-
|
|
87
|
+
CALLERS (7):
|
|
88
|
+
confidence: 0 high (>0.8), 7 medium (0.5-0.8), 0 low (<0.5)
|
|
89
|
+
cli/index.js:1190 [runGlobCommand]
|
|
89
90
|
const files = expandGlob(pattern);
|
|
90
|
-
|
|
91
|
+
confidence: 0.65 (scope-match)
|
|
92
|
+
core/cache.js:417 [isCacheStale]
|
|
91
93
|
const currentFiles = expandGlob(pattern, globOpts);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
confidence: 0.65 (scope-match)
|
|
95
|
+
... (5 more)
|
|
94
96
|
|
|
95
97
|
CALLEES (3):
|
|
96
|
-
parseGlobPattern [utility] - core/discovery.js:
|
|
97
|
-
walkDir [utility] - core/discovery.js:
|
|
98
|
-
compareNames [utility] - core/discovery.js:
|
|
98
|
+
parseGlobPattern [utility] - core/discovery.js:227
|
|
99
|
+
walkDir [utility] {fs} - core/discovery.js:284
|
|
100
|
+
compareNames [utility] - core/discovery.js:170
|
|
99
101
|
|
|
100
|
-
TESTS:
|
|
102
|
+
TESTS: 5 matches in 1 file(s)
|
|
101
103
|
```
|
|
102
104
|
|
|
103
|
-
Need to trace execution upward instead? `ucn reverse-trace fn` walks the caller chain back to entry points.
|
|
105
|
+
Each caller comes with a confidence score (`exact-binding`, `same-class`, `receiver-hint`, `scope-match`, `name-only`) so you can tell direct calls from name-only matches. Add `--hide-confidence` to silence the scores, or `--min-confidence=0.7` to drop everything below `same-class`. Add `--git` to see who last touched the function. Need to trace execution upward instead? `ucn reverse-trace fn` walks the caller chain back to entry points.
|
|
104
106
|
|
|
105
107
|
## Change code without breaking things
|
|
106
108
|
|
|
@@ -109,38 +111,100 @@ Before touching a function, check if all existing call sites match its signature
|
|
|
109
111
|
```
|
|
110
112
|
$ ucn verify expandGlob
|
|
111
113
|
|
|
112
|
-
expandGlob
|
|
114
|
+
Verification: expandGlob
|
|
115
|
+
════════════════════════════════════════════════════════════
|
|
116
|
+
core/discovery.js:191
|
|
117
|
+
expandGlob (pattern: string, options: number = {}) : string[]
|
|
118
|
+
|
|
113
119
|
Expected arguments: 1-2
|
|
114
120
|
|
|
115
|
-
STATUS: ✓ All calls valid
|
|
121
|
+
STATUS: ✓ All calls valid
|
|
122
|
+
Total calls: 7
|
|
123
|
+
Valid: 7
|
|
124
|
+
Mismatches: 0
|
|
125
|
+
Uncertain: 0
|
|
126
|
+
Patterns: 4 in try, 4 in callback
|
|
116
127
|
```
|
|
117
128
|
|
|
129
|
+
The `Patterns:` line surfaces structural classification of each call site — `inLoop`, `inTry`, `inCallback`, `inTestCase`, `awaited` — so you can spot risky call sites (e.g., calls inside loops, missing `await`) at a glance. Same line appears on `impact` and inside `about`.
|
|
130
|
+
|
|
118
131
|
Then preview the refactoring. UCN shows exactly what needs to change and where:
|
|
119
132
|
|
|
120
133
|
```
|
|
121
134
|
$ ucn plan expandGlob --rename-to=expandGlobPattern
|
|
122
135
|
|
|
136
|
+
Refactoring plan: rename
|
|
137
|
+
════════════════════════════════════════════════════════════
|
|
138
|
+
core/discovery.js:191
|
|
139
|
+
|
|
123
140
|
SIGNATURE CHANGE:
|
|
124
|
-
Before: expandGlob (pattern, options = {})
|
|
125
|
-
After: expandGlobPattern (pattern, options = {})
|
|
141
|
+
Before: expandGlob (pattern: string, options: number = {}) : string[]
|
|
142
|
+
After: expandGlobPattern (pattern: string, options: number = {}) : string[]
|
|
126
143
|
|
|
127
|
-
CHANGES NEEDED:
|
|
144
|
+
CHANGES NEEDED: 11
|
|
145
|
+
Files affected: 4
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
const files = expandGlob(pattern);
|
|
131
|
-
→ const files = expandGlobPattern(pattern);
|
|
147
|
+
BY FILE:
|
|
132
148
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
149
|
+
cli/index.js (2 changes)
|
|
150
|
+
:1190
|
|
151
|
+
const files = expandGlob(pattern);
|
|
152
|
+
→ Rename to: const files = expandGlobPattern(pattern);
|
|
153
|
+
:15
|
|
154
|
+
const { expandGlob, findProjectRoot } = require('../core/discovery');
|
|
155
|
+
→ Update import: const { expandGlobPattern, findProjectRoot } = require('../core/discovery');
|
|
136
156
|
|
|
137
|
-
core/project.js
|
|
138
|
-
const files = expandGlob(pattern, globOpts);
|
|
139
|
-
→ const files = expandGlobPattern(pattern, globOpts);
|
|
157
|
+
... (more changes in core/cache.js, core/project.js, test/integration.test.js)
|
|
140
158
|
```
|
|
141
159
|
|
|
142
160
|
Run `ucn diff-impact --staged` before committing to see what you changed and who calls it.
|
|
143
161
|
|
|
162
|
+
Or wrap the same checks in a single command:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
$ ucn check --staged
|
|
166
|
+
|
|
167
|
+
Pre-commit Check vs HEAD
|
|
168
|
+
════════════════════════════════════════════════════════════
|
|
169
|
+
Changed: 3 functions
|
|
170
|
+
parseFlags (cli/index.js:165) [MODIFIED] 2 callers
|
|
171
|
+
...
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`ucn check` composes `diff-impact` + `verify` + `affected-tests` in one shot — flags ADDED functions with no callers, signature drift across call sites, and recommends which tests to run.
|
|
175
|
+
|
|
176
|
+
## Get the lay of the land in a new repo
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
$ ucn brief fetch_user
|
|
180
|
+
fetch_user(user_id: int): dict
|
|
181
|
+
svc.py:4-8 (5 lines)
|
|
182
|
+
"Fetch a user from the API."
|
|
183
|
+
async: no | side_effects: [fs, network, process] | complexity: branches=2, depth=2
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
`brief` is the lighter alternative to `about` — typed signature, first sentence of the docstring, side-effect classification, and complexity, all in one screen. Pair with `--git` to see who last touched it and how often.
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
$ ucn doctor
|
|
190
|
+
|
|
191
|
+
UCN Trust Report — /path/to/project
|
|
192
|
+
Index: 144 files, 1569 symbols
|
|
193
|
+
Languages: javascript (74%), typescript (13%), java (4%), python (3%), rust (3%), go (3%)
|
|
194
|
+
Cache: fresh, 221ms build
|
|
195
|
+
...
|
|
196
|
+
Trust level: HIGH
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`doctor` reports how much UCN trusts the index — file/symbol counts, blind spots (dynamic imports, eval, reflection), parse failures, and a verdict. Use `--deep` to also sample resolution coverage.
|
|
200
|
+
|
|
201
|
+
`entrypoints` lists detected framework handlers (HTTP routes, DI beans, jobs, tests):
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
ucn entrypoints --type=http --framework=spring # narrow to one framework
|
|
205
|
+
ucn entrypoints --exclude-tests # tests are included by default
|
|
206
|
+
```
|
|
207
|
+
|
|
144
208
|
## Find what to clean up
|
|
145
209
|
|
|
146
210
|
Which tests should you run after a change? `affected-tests` walks the blast radius and finds every test that touches the affected functions:
|
|
@@ -148,11 +212,22 @@ Which tests should you run after a change? `affected-tests` walks the blast radi
|
|
|
148
212
|
```
|
|
149
213
|
$ ucn affected-tests expandGlob
|
|
150
214
|
|
|
151
|
-
|
|
152
|
-
|
|
215
|
+
affected-tests: expandGlob
|
|
216
|
+
════════════════════════════════════════════════════════════
|
|
217
|
+
core/discovery.js:191
|
|
218
|
+
1 function changed → 15 functions affected (depth 3)
|
|
219
|
+
|
|
220
|
+
Test files to run (19):
|
|
153
221
|
|
|
154
|
-
|
|
222
|
+
test/integration.test.js (covers: expandGlob, build, idx, setupProject)
|
|
223
|
+
L47: index.build(null, { quiet: true }); [call]
|
|
224
|
+
L167: const files = expandGlob('**/*.go', { root: tmpDir }); [call]
|
|
225
|
+
...
|
|
226
|
+
|
|
227
|
+
Uncovered (10): runGlobCommand, main, runProjectCommand, ...
|
|
155
228
|
⚠ These affected functions have no test references
|
|
229
|
+
|
|
230
|
+
Summary: 15 affected → 19 test files, 5/15 functions covered (33%)
|
|
156
231
|
```
|
|
157
232
|
|
|
158
233
|
## Find unused code
|
|
@@ -160,19 +235,47 @@ Uncovered (7): runGlobCommand, runProjectCommand, ...
|
|
|
160
235
|
```
|
|
161
236
|
$ ucn deadcode --exclude=test
|
|
162
237
|
|
|
163
|
-
Dead code:
|
|
238
|
+
Dead code: 3 unused symbol(s)
|
|
239
|
+
|
|
240
|
+
core/bridge.js
|
|
241
|
+
[ 90- 92] endsWithWildcard (function)
|
|
242
|
+
[ 258- 265] parsePythonDecorator (function)
|
|
243
|
+
core/search.js
|
|
244
|
+
[1409-1445] _testBodyReferencesClass (function)
|
|
245
|
+
|
|
246
|
+
325 exported symbol(s) excluded (all have callers). Use --include-exported to audit them.
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Find missing-await bugs:
|
|
164
250
|
|
|
165
|
-
core/discovery.js
|
|
166
|
-
[ 162- 166] legacyResolve (function)
|
|
167
251
|
```
|
|
252
|
+
ucn audit-async
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Lists async calls inside async functions that lack `await` (JS/TS/Python).
|
|
256
|
+
|
|
257
|
+
## Map your API surface across languages
|
|
258
|
+
|
|
259
|
+
UCN can match server routes to client requests across the supported languages — Express/Fastify/Koa/NestJS/Next.js, Flask/FastAPI, Spring/JAX-RS, Go net/http (Gin/Echo/Chi/Fiber), axum/actix-web on the server side; fetch/axios, requests/httpx, RestTemplate/WebClient, reqwest on the client side.
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
ucn endpoints --bridge
|
|
263
|
+
|
|
264
|
+
# Filters
|
|
265
|
+
ucn endpoints --bridge --unmatched # routes with no client / clients with no server
|
|
266
|
+
ucn endpoints --bridge --method=POST
|
|
267
|
+
ucn endpoints --bridge --prefix=/api
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Match confidence: `EXACT` (literal-literal), `PARTIAL` (server param ↔ client literal), `UNCERTAIN` (template-literal client). Use `--hide-uncertain` to drop the noisy tier.
|
|
168
271
|
|
|
169
272
|
## Extract without reading the whole file
|
|
170
273
|
|
|
171
274
|
```
|
|
172
275
|
$ ucn fn compareNames
|
|
173
276
|
|
|
174
|
-
core/discovery.js:
|
|
175
|
-
[
|
|
277
|
+
core/discovery.js:170
|
|
278
|
+
[ 170- 178] compareNames(a, b)
|
|
176
279
|
────────────────────────────────────────────────────────────
|
|
177
280
|
function compareNames(a, b) {
|
|
178
281
|
const aLower = a.toLowerCase();
|
|
@@ -258,114 +361,7 @@ cp -r "$(npm root -g)/ucn/.claude/skills/ucn" ~/.agents/skills/
|
|
|
258
361
|
|
|
259
362
|
## Full help
|
|
260
363
|
|
|
261
|
-
|
|
262
|
-
UCN - Universal Code Navigator
|
|
263
|
-
|
|
264
|
-
Supported: JavaScript, TypeScript, Python, Go, Rust, Java, HTML
|
|
265
|
-
|
|
266
|
-
Usage:
|
|
267
|
-
ucn [command] [args] Project mode (current directory)
|
|
268
|
-
ucn <file> [command] [args] Single file mode
|
|
269
|
-
ucn <dir> [command] [args] Project mode (specific directory)
|
|
270
|
-
ucn "pattern" [command] [args] Glob pattern mode
|
|
271
|
-
(Default output is text; add --json for machine-readable JSON)
|
|
272
|
-
|
|
273
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
274
|
-
UNDERSTAND CODE
|
|
275
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
276
|
-
about <name> Full picture (definition, callers, callees, tests, code)
|
|
277
|
-
context <name> Who calls this + what it calls (numbered for expand)
|
|
278
|
-
smart <name> Function + all dependencies inline
|
|
279
|
-
impact <name> What breaks if changed (call sites grouped by file)
|
|
280
|
-
blast <name> Transitive blast radius (callers of callers, --depth=N)
|
|
281
|
-
trace <name> Call tree visualization (--depth=N expands all children)
|
|
282
|
-
reverse-trace <name> Upward call chain to entry points (--depth=N, default 5)
|
|
283
|
-
related <name> Find similar functions (same file, shared deps)
|
|
284
|
-
example <name> Best usage example with context
|
|
285
|
-
|
|
286
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
287
|
-
FIND CODE
|
|
288
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
289
|
-
find <name> Find symbol definitions (supports glob: find "handle*")
|
|
290
|
-
usages <name> All usages grouped: definitions, calls, imports, references
|
|
291
|
-
toc Table of contents (compact; --detailed lists all symbols)
|
|
292
|
-
search <term> Text search (regex default, --context=N, --exclude=, --in=)
|
|
293
|
-
Structural: --type=function|class|call --param= --returns= --decorator= --exported --unused
|
|
294
|
-
tests <name> Find test files for a function
|
|
295
|
-
affected-tests <n> Tests affected by a change (blast + test detection, --depth=N)
|
|
296
|
-
|
|
297
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
298
|
-
EXTRACT CODE
|
|
299
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
300
|
-
fn <name>[,n2,...] Extract function(s) (comma-separated for bulk, --file)
|
|
301
|
-
class <name> Extract class
|
|
302
|
-
lines <range> Extract line range (e.g., lines 50-100)
|
|
303
|
-
expand <N> Show code for item N from context output
|
|
304
|
-
|
|
305
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
306
|
-
FILE DEPENDENCIES
|
|
307
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
308
|
-
imports <file> What does file import
|
|
309
|
-
exporters <file> Who imports this file
|
|
310
|
-
file-exports <file> What does file export
|
|
311
|
-
graph <file> Full dependency tree (--depth=N, --direction=imports|importers|both)
|
|
312
|
-
circular-deps Detect circular import chains (--file=, --exclude=)
|
|
313
|
-
|
|
314
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
315
|
-
REFACTORING HELPERS
|
|
316
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
317
|
-
plan <name> Preview refactoring (--add-param, --remove-param, --rename-to)
|
|
318
|
-
verify <name> Check all call sites match signature
|
|
319
|
-
diff-impact What changed in git diff and who calls it (--base, --staged)
|
|
320
|
-
deadcode Find unused functions/classes
|
|
321
|
-
entrypoints Detect framework entry points (routes, DI, tasks)
|
|
322
|
-
|
|
323
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
324
|
-
OTHER
|
|
325
|
-
═══════════════════════════════════════════════════════════════════════════════
|
|
326
|
-
api Show exported/public symbols
|
|
327
|
-
typedef <name> Find type definitions
|
|
328
|
-
stats Project statistics (--functions for per-function line counts)
|
|
329
|
-
stacktrace <text> Parse stack trace, show code at each frame (alias: stack)
|
|
330
|
-
|
|
331
|
-
Common Flags:
|
|
332
|
-
--file <pattern> Filter by file path (e.g., --file=routes)
|
|
333
|
-
--exclude=a,b Exclude patterns (e.g., --exclude=test,mock)
|
|
334
|
-
--in=<path> Only in path (e.g., --in=src/core)
|
|
335
|
-
--depth=N Trace/graph depth (default: 3, also expands all children)
|
|
336
|
-
--direction=X Graph direction: imports, importers, or both (default: both)
|
|
337
|
-
--all Expand truncated sections (about, trace, graph, related)
|
|
338
|
-
--top=N Limit results (find, deadcode)
|
|
339
|
-
--limit=N Limit result count (find, usages, search, deadcode, api, toc)
|
|
340
|
-
--max-files=N Max files to index (large projects)
|
|
341
|
-
--context=N Lines of context around matches
|
|
342
|
-
--json Machine-readable output
|
|
343
|
-
--code-only Filter out comments and strings
|
|
344
|
-
--with-types Include type definitions
|
|
345
|
-
--include-tests Include test files
|
|
346
|
-
--class-name=X Scope to specific class (e.g., --class-name=Repository)
|
|
347
|
-
--include-methods Include method calls (obj.fn) in caller/callee analysis
|
|
348
|
-
--include-uncertain Include ambiguous/uncertain matches
|
|
349
|
-
--no-confidence Hide confidence scores (shown by default)
|
|
350
|
-
--min-confidence=N Filter edges below confidence threshold (0.0-1.0)
|
|
351
|
-
--include-exported Include exported symbols in deadcode
|
|
352
|
-
--no-regex Force plain text search (regex is default)
|
|
353
|
-
--functions Show per-function line counts (stats command)
|
|
354
|
-
--include-decorated Include decorated/annotated symbols in deadcode
|
|
355
|
-
--framework=X Filter entrypoints by framework (e.g., --framework=express,spring)
|
|
356
|
-
--exact Exact name match only (find)
|
|
357
|
-
--calls-only Only show call/test-case matches (tests)
|
|
358
|
-
--case-sensitive Case-sensitive text search (search)
|
|
359
|
-
--detailed List all symbols in toc (compact by default)
|
|
360
|
-
--top-level Show only top-level functions in toc
|
|
361
|
-
--max-lines=N Max source lines for class (large classes show summary)
|
|
362
|
-
--no-cache Disable caching
|
|
363
|
-
--clear-cache Clear cache before running
|
|
364
|
-
--base=<ref> Git ref for diff-impact (default: HEAD)
|
|
365
|
-
--staged Analyze staged changes (diff-impact)
|
|
366
|
-
--no-follow-symlinks Don't follow symbolic links
|
|
367
|
-
-i, --interactive Keep index in memory for multiple queries
|
|
368
|
-
```
|
|
364
|
+
Run `ucn --help` for the full command list and flags.
|
|
369
365
|
|
|
370
366
|
---
|
|
371
367
|
|