ucn 3.7.47 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/ucn/SKILL.md +32 -4
- package/README.md +16 -13
- package/cli/index.js +99 -10
- package/core/callers.js +36 -2
- package/core/deadcode.js +103 -3
- package/core/execute.js +97 -0
- package/core/output.js +397 -0
- package/core/project.js +924 -52
- package/core/registry.js +17 -7
- package/languages/go.js +7 -1
- package/languages/java.js +36 -2
- package/languages/javascript.js +199 -8
- package/languages/python.js +8 -2
- package/languages/rust.js +75 -4
- package/mcp/server.js +48 -3
- package/package.json +1 -1
package/mcp/server.js
CHANGED
|
@@ -181,6 +181,7 @@ UNDERSTANDING CODE:
|
|
|
181
181
|
- about <name>: Definition, source, callers, callees, and tests — everything in one call. Replaces 3-4 grep+read cycles. Your first stop for any function or class.
|
|
182
182
|
- context <name>: Who calls it and what does it call, without source code. Results are numbered for use with expand. For classes/structs, shows all methods instead.
|
|
183
183
|
- impact <name>: Every call site with actual arguments passed, grouped by file. Essential before changing a function signature — shows exactly what breaks.
|
|
184
|
+
- blast <name>: Transitive blast radius — callers of callers. Shows the full chain of functions affected if you change something. Like impact but recursive. Use depth (default: 3) to control how far up the chain to walk.
|
|
184
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.
|
|
185
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.
|
|
186
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.
|
|
@@ -190,8 +191,9 @@ FINDING CODE:
|
|
|
190
191
|
- find <name>: Locate definitions ranked by usage count. Supports glob patterns (e.g. find "handle*" or "_update*"). Use when you know the name but not the file.
|
|
191
192
|
- usages <name>: See every usage organized by type: definitions, calls, imports, references. Complete picture of how something is used. Use code_only=true to skip comments/strings.
|
|
192
193
|
- toc: Get a quick overview of a project you haven't seen before — file counts, line counts, function/class counts, entry points. Use detailed=true for full symbol listing.
|
|
193
|
-
- search <term>: Text search (like grep, respects .gitignore). Supports regex by default (e.g. "\\d+" or "foo|bar"). Supports context=N for surrounding lines, exclude/in for file filtering. Case-insensitive by default; set case_sensitive=true for exact case. Invalid regex auto-falls back to plain text.
|
|
194
|
+
- search <term>: Text search (like grep, respects .gitignore). Supports regex by default (e.g. "\\d+" or "foo|bar"). Supports context=N for surrounding lines, exclude/in for file filtering. Case-insensitive by default; set case_sensitive=true for exact case. Invalid regex auto-falls back to plain text. STRUCTURAL MODE: Add type=function|class|call|method|type to query the symbol index instead of text. Combine with param=, returns=, decorator=, receiver= (for calls), exported=true, unused=true. Term becomes optional name filter (glob). Example: type=function, param=Request → all functions taking Request.
|
|
194
195
|
- 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
|
+
- 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.
|
|
195
197
|
- 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.
|
|
196
198
|
|
|
197
199
|
EXTRACTING CODE (use instead of reading entire files):
|
|
@@ -260,7 +262,15 @@ server.registerTool(
|
|
|
260
262
|
top_level: z.boolean().optional().describe('Show only top-level functions in toc (exclude nested/indented)'),
|
|
261
263
|
class_name: z.string().optional().describe('Class name to scope method analysis (e.g. "MarketDataFetcher" for close)'),
|
|
262
264
|
limit: z.number().optional().describe('Max results to return (default: 500). Caps find, usages, search, deadcode, api, toc --detailed.'),
|
|
263
|
-
max_files: z.number().optional().describe('Max files to index (default: 10000). Use for very large codebases.')
|
|
265
|
+
max_files: z.number().optional().describe('Max files to index (default: 10000). Use for very large codebases.'),
|
|
266
|
+
// Structural search flags (search command)
|
|
267
|
+
type: z.string().optional().describe('Symbol type filter for structural search: function, class, call, method, type. Triggers index-based search.'),
|
|
268
|
+
param: z.string().optional().describe('Filter by parameter name or type (structural search). E.g. "Request", "ctx".'),
|
|
269
|
+
receiver: z.string().optional().describe('Filter calls by receiver (structural search, type=call). E.g. "db", "http".'),
|
|
270
|
+
returns: z.string().optional().describe('Filter by return type (structural search). E.g. "Promise", "error".'),
|
|
271
|
+
decorator: z.string().optional().describe('Filter by decorator/annotation (structural search). E.g. "Route", "Test".'),
|
|
272
|
+
exported: z.boolean().optional().describe('Only exported/public symbols (structural search).'),
|
|
273
|
+
unused: z.boolean().optional().describe('Only symbols with zero callers (structural search).')
|
|
264
274
|
|
|
265
275
|
})
|
|
266
276
|
},
|
|
@@ -309,6 +319,15 @@ server.registerTool(
|
|
|
309
319
|
return toolResult(output.formatImpact(result));
|
|
310
320
|
}
|
|
311
321
|
|
|
322
|
+
case 'blast': {
|
|
323
|
+
const index = getIndex(project_dir);
|
|
324
|
+
const { ok, result, error } = execute(index, 'blast', ep);
|
|
325
|
+
if (!ok) return toolResult(error); // soft error
|
|
326
|
+
return toolResult(output.formatBlast(result, {
|
|
327
|
+
allHint: 'Set depth to expand all children.',
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
|
|
312
331
|
case 'smart': {
|
|
313
332
|
const index = getIndex(project_dir);
|
|
314
333
|
const { ok, result, error } = execute(index, 'smart', ep);
|
|
@@ -326,6 +345,15 @@ server.registerTool(
|
|
|
326
345
|
}));
|
|
327
346
|
}
|
|
328
347
|
|
|
348
|
+
case 'reverse_trace': {
|
|
349
|
+
const index = getIndex(project_dir);
|
|
350
|
+
const { ok, result, error } = execute(index, 'reverseTrace', ep);
|
|
351
|
+
if (!ok) return toolResult(error);
|
|
352
|
+
return toolResult(output.formatReverseTrace(result, {
|
|
353
|
+
allHint: 'Set depth to expand all children.',
|
|
354
|
+
}));
|
|
355
|
+
}
|
|
356
|
+
|
|
329
357
|
case 'example': {
|
|
330
358
|
const index = getIndex(project_dir);
|
|
331
359
|
const { ok, result, error } = execute(index, 'example', ep);
|
|
@@ -378,8 +406,11 @@ server.registerTool(
|
|
|
378
406
|
|
|
379
407
|
case 'search': {
|
|
380
408
|
const index = getIndex(project_dir);
|
|
381
|
-
const { ok, result, error } = execute(index, 'search', ep);
|
|
409
|
+
const { ok, result, error, structural } = execute(index, 'search', ep);
|
|
382
410
|
if (!ok) return toolResult(error); // soft error
|
|
411
|
+
if (structural) {
|
|
412
|
+
return toolResult(output.formatStructuralSearch(result));
|
|
413
|
+
}
|
|
383
414
|
return toolResult(output.formatSearch(result, ep.term));
|
|
384
415
|
}
|
|
385
416
|
|
|
@@ -390,6 +421,13 @@ server.registerTool(
|
|
|
390
421
|
return toolResult(output.formatTests(result, ep.name));
|
|
391
422
|
}
|
|
392
423
|
|
|
424
|
+
case 'affected_tests': {
|
|
425
|
+
const index = getIndex(project_dir);
|
|
426
|
+
const { ok, result, error } = execute(index, 'affectedTests', ep);
|
|
427
|
+
if (!ok) return toolResult(error);
|
|
428
|
+
return toolResult(output.formatAffectedTests(result));
|
|
429
|
+
}
|
|
430
|
+
|
|
393
431
|
case 'deadcode': {
|
|
394
432
|
const index = getIndex(project_dir);
|
|
395
433
|
const { ok, result, error, note } = execute(index, 'deadcode', ep);
|
|
@@ -439,6 +477,13 @@ server.registerTool(
|
|
|
439
477
|
}));
|
|
440
478
|
}
|
|
441
479
|
|
|
480
|
+
case 'circular_deps': {
|
|
481
|
+
const index = getIndex(project_dir);
|
|
482
|
+
const { ok, result, error } = execute(index, 'circularDeps', ep);
|
|
483
|
+
if (!ok) return toolResult(error);
|
|
484
|
+
return toolResult(output.formatCircularDeps(result));
|
|
485
|
+
}
|
|
486
|
+
|
|
442
487
|
// ── Refactoring ─────────────────────────────────────────────
|
|
443
488
|
|
|
444
489
|
case 'verify': {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ucn",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
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",
|