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/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.7.47",
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",