ucn 5.5.3 → 5.6.1
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 +37 -12
- package/.claude/skills/ucn/references/commands.md +18 -14
- package/.claude/skills/ucn/references/resolution-rules.md +4 -0
- package/.claude/skills/ucn/references/trust-contract.md +4 -4
- package/CHANGELOG.md +485 -0
- package/README.md +66 -29
- package/cli/flags.js +184 -0
- package/cli/index.js +137 -324
- package/core/account.js +44 -87
- package/core/analysis.js +274 -108
- package/core/ast-analysis.js +2 -0
- package/core/bridge.js +14 -0
- package/core/cache.js +103 -16
- package/core/call-fit.js +130 -0
- package/core/callers.js +353 -71
- package/core/capture.js +363 -0
- package/core/change-kinds.js +1107 -0
- package/core/check.js +1150 -139
- package/core/command-contracts.js +8 -7
- package/core/constructed-class.js +1195 -0
- package/core/contract-membership.js +142 -0
- package/core/deadcode.js +455 -106
- package/core/deletion.js +421 -0
- package/core/discovery.js +104 -9
- package/core/entrypoint-toml.js +110 -0
- package/core/entrypoints.js +12 -6
- package/core/evidence-bands.js +68 -0
- package/core/evidence-bands.json +44 -0
- package/core/execute.js +172 -161
- package/core/hot-summary.js +241 -0
- package/core/index-ir.js +5 -3
- package/core/ir.js +6 -2
- package/core/member-signatures.js +789 -0
- package/core/outgoing-check.js +116 -0
- package/core/output/analysis-ext.js +20 -10
- package/core/output/analysis.js +98 -60
- package/core/output/check.js +101 -37
- package/core/output/doctor.js +34 -1
- package/core/output/find.js +2 -1
- package/core/output/lines.js +63 -3
- package/core/output/public.js +29 -11
- package/core/output/refactoring.js +32 -0
- package/core/output/reporting.js +19 -2
- package/core/output/search.js +14 -2
- package/core/output/tracing.js +36 -8
- package/core/output-budget.js +146 -61
- package/core/parallel-build.js +3 -3
- package/core/project.js +106 -23
- package/core/provenance-type.js +12 -5
- package/core/public-command.js +35 -9
- package/core/python-binding-identity.js +707 -0
- package/core/python-modules.js +6 -0
- package/core/reflection.js +248 -31
- package/core/registry.js +623 -72
- package/core/reporting.js +69 -34
- package/core/review-items.js +75 -0
- package/core/runtime-entrypoints.js +159 -0
- package/core/search.js +148 -164
- package/core/shared.js +0 -45
- package/core/snapshot.js +350 -0
- package/core/source-universe.js +707 -0
- package/core/test-units.js +3698 -0
- package/core/tracing.js +270 -658
- package/core/verify.js +63 -22
- package/languages/adapter.js +8 -3
- package/languages/c-family.js +12 -0
- package/languages/csharp.js +634 -0
- package/languages/go.js +120 -0
- package/languages/index.js +466 -4
- package/languages/java.js +712 -0
- package/languages/javascript.js +1498 -6
- package/languages/lexical-scope.js +68 -0
- package/languages/python.js +1708 -3
- package/languages/rust.js +209 -104
- package/languages/static-js.js +88 -0
- package/mcp/server.js +44 -110
- package/package.json +11 -5
package/mcp/server.js
CHANGED
|
@@ -29,13 +29,16 @@ const {
|
|
|
29
29
|
FLAG_APPLICABILITY,
|
|
30
30
|
REVERSE_PARAM_MAP,
|
|
31
31
|
generateMcpParamSection,
|
|
32
|
+
mcpParamProperties,
|
|
33
|
+
paramValues,
|
|
34
|
+
GLOBAL_PARAMS,
|
|
32
35
|
resolveCommand,
|
|
33
36
|
suggestCommand,
|
|
34
37
|
v4MigrationHint,
|
|
35
38
|
formatSurfaceMessage,
|
|
36
39
|
} = require('../core/registry');
|
|
37
40
|
const { execute } = require('../core/execute');
|
|
38
|
-
const { sourceRangeTarget } = require('../core/public-command');
|
|
41
|
+
const { sourceRangeTarget, noOpNotes } = require('../core/public-command');
|
|
39
42
|
const { describeError, UcnError } = require('../core/errors');
|
|
40
43
|
const { applyOutputBudget, MAX_OUTPUT_CHARS } = require('../core/output-budget');
|
|
41
44
|
|
|
@@ -124,13 +127,14 @@ const server = new StdioMcpServer({
|
|
|
124
127
|
// TOOL HELPERS
|
|
125
128
|
// ============================================================================
|
|
126
129
|
|
|
127
|
-
function toolResult(text, command, maxChars, suffixNote, params = {}) {
|
|
130
|
+
function toolResult(text, command, maxChars, suffixNote, params = {}, peerText) {
|
|
128
131
|
const suffix = suffixNote || '';
|
|
129
132
|
const budget = applyOutputBudget(text + suffix, {
|
|
130
133
|
command,
|
|
131
134
|
maxChars,
|
|
132
135
|
surface: 'mcp',
|
|
133
136
|
params,
|
|
137
|
+
...(typeof peerText === 'string' && { peerText: peerText + suffix }),
|
|
134
138
|
});
|
|
135
139
|
// The text block is the ONLY payload channel. Truncation facts live in the
|
|
136
140
|
// text itself (the OUTPUT TRUNCATED notice carries full size, limit, and
|
|
@@ -236,107 +240,40 @@ const CONCISE_TOOL_DESCRIPTION = `Auditable AST code intelligence for JavaScript
|
|
|
236
240
|
Use UCN for semantic questions: exact definitions, symbol-aware callers/callees, change impact, test selection, dependencies, APIs, entry points, and focused audits. Use grep/ripgrep for simple literals, error messages, configuration, filenames, Markdown, and unsupported languages. UCN search is worthwhile when AST structure, code-only filtering, or the shared agent contract matters.
|
|
237
241
|
|
|
238
242
|
18 task-oriented commands:
|
|
239
|
-
- repo: repository overview; sections
|
|
240
|
-
- show: one symbol; sections
|
|
243
|
+
- repo: repository overview; sections=${paramValues('sections', 'repo').join(',')} selects detail. Reports skipped unsupported source explicitly and hands it to grep/language-native tooling.
|
|
244
|
+
- show: one symbol; sections=${paramValues('sections', 'show').join(',')}.
|
|
241
245
|
- find/usages/search/source: locate definitions, literal-name occurrences, literal text (regex=true selects the linear-time RE2-compatible engine), AST structure, or exact source. Find activity is pinned confirmed + visible-unverified candidates; proved other-target calls are separate.
|
|
242
|
-
- trace: direction
|
|
246
|
+
- trace: direction=${paramValues('direction', 'trace').join(' or ')}; to=${paramValues('to', 'trace').join('|')} follows callers to roots.
|
|
243
247
|
- impact: symbol impact when name is set; Git-diff impact when it is omitted.
|
|
244
|
-
- tests: static direct links by default; depth>0 includes transitive affected links. Empty results are not runtime coverage proof.
|
|
248
|
+
- tests: static direct links by default; depth>0 includes transitive affected links. Each test is named by its file, suites and name, with the command that runs it where the runner is proven. Empty results are not runtime coverage proof.
|
|
245
249
|
- deps/api/entrypoints/endpoints: architecture and public surfaces.
|
|
246
|
-
- check: symbol signature check when name is set; precommit check when omitted. plan previews the selected declaration plus indexed call/import/export edits.
|
|
250
|
+
- check: symbol signature check when name is set; precommit check when omitted (per changed symbol: BLOCKED = a break was observed, REVIEW = change exposure or a changed call cannot be settled, READY = no unresolved exposure in the modeled checks, not compiler or runtime proof; staged=true reads the git index, not the worktree). plan previews the selected declaration plus indexed call/import/export edits; with delete=true it assesses deleting the declaration (no-static-dependents, has-static-dependents, or review with the reason), by the rule deadcode applies to every name. A .ucn.json "kind": "application" lets exported symbols be assessed.
|
|
247
251
|
- deadcode/audit_async/stacktrace: focused audits and runtime evidence. Computed dispatch is reported as a health/deletion blind spot; unknown decorators and member-assigned handlers are withheld from default dead-code claims.
|
|
248
252
|
|
|
249
|
-
CONFIRMED carries target-identity evidence. UNVERIFIED is possible and requires review; when same-name definitions compete, show returns their stable handles once above the sites. ACCOUNT conserves observed literal-name lines; an observed-text zero never claims semantic completeness or safe deletion. Evidence weights are ordinal, not probabilities. Warnings, excluded reasons, and contract metadata remain visible when caller evidence is returned. Releases are gated on pinned real repositories: sampled callers, callees, value references, and dead-code claims are compared with ts-morph, Pyright, gopls, rust-analyzer, JDT LS, Roslyn, and clangd, and one handle's claims must agree across find, show, source, impact, tests, check, and caller trace.` + generateMcpParamSection();
|
|
253
|
+
CONFIRMED carries target-identity evidence. UNVERIFIED is possible and requires review; when same-name definitions compete, show returns their stable handles once above the sites. ACCOUNT conserves observed literal-name lines; an observed-text zero never claims semantic completeness or safe deletion. CONTRACT is a state: text-complete means every literal-name line of project source was classified, never that aliases, indirect calls, generated code or runtime dispatch are absent. Source UCN reads without analyzing (bundles, paths excluded in .ucn.json, oversized files, unsupported languages) is searched for each name and listed only when the name occurs there; a path that cannot be read degrades every account. repo health states the scope once. Evidence weights are ordinal, not probabilities. Warnings, excluded reasons, and contract metadata remain visible when caller evidence is returned. Releases are gated on pinned real repositories: sampled callers, callees, value references, and dead-code claims are compared with ts-morph, Pyright, gopls, rust-analyzer, JDT LS, Roslyn, and clangd, and one handle's claims must agree across find, show, source, impact, tests, check, and caller trace.` + generateMcpParamSection();
|
|
250
254
|
|
|
251
255
|
// The default description is the only public contract. The former verbose
|
|
252
256
|
// description is intentionally not selectable: it documented retired commands
|
|
253
257
|
// and made the single MCP tool difficult for agents to parse.
|
|
254
258
|
const TOOL_DESCRIPTION = CONCISE_TOOL_DESCRIPTION;
|
|
255
259
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// Keep the public JSON Schema and runtime validation rules in one dependency-
|
|
262
|
-
// free object. Unknown keys remain allowed so the handler can return typo and
|
|
263
|
-
// applicability guidance instead of silently changing the requested answer.
|
|
260
|
+
// The public JSON Schema and the runtime validation rules are one object,
|
|
261
|
+
// written from the registry's parameter table: a type, a bound, a value list
|
|
262
|
+
// or a default stated here is the one the engine uses. Unknown keys remain
|
|
263
|
+
// allowed so the handler can return typo and applicability guidance instead
|
|
264
|
+
// of silently changing the requested answer.
|
|
264
265
|
const INPUT_SHAPE = {
|
|
265
|
-
command:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
include_methods: booleanParam('Include method callees where receiver evidence permits. Caller-bearing views always tier method sites.'),
|
|
277
|
-
expand_unverified: booleanParam('trace callers: follow unverified edges; downstream nodes remain marked possible, never confirmed.'),
|
|
278
|
-
min_confidence: numberParam('Minimum ordinal evidence weight (legacy name; not a probability) for caller/callee edges', { minimum: 0, maximum: 1 }),
|
|
279
|
-
show_confidence: booleanParam('show: resolution-evidence labels default to visible; set false to hide them. Numeric weights are ordinal, not probabilities.'),
|
|
280
|
-
unreachable_only: booleanParam('show/impact: retain only relationships unreachable from detected entry points.'),
|
|
281
|
-
with_types: booleanParam('show: include related type definitions.'),
|
|
282
|
-
with_source: booleanParam('Attach exact source to find results.'),
|
|
283
|
-
detailed: booleanParam('repo files: show symbols per file; deps: include import declarations and importers.'),
|
|
284
|
-
exact: booleanParam('Exact name match only (no substring matching)'),
|
|
285
|
-
in: stringParam('Only search in this directory path (e.g. "src/core")'),
|
|
286
|
-
top: integerParam('Max results to show (default: 10). Must be a positive integer.', { exclusiveMinimum: 0, maximum: 10000 }),
|
|
287
|
-
depth: integerParam('Max depth (default: 3 for trace, 2 for deps); expands all children. Non-negative integer.', { minimum: 0, maximum: 100 }),
|
|
288
|
-
code_only: booleanParam('Exclude matches in comments and strings'),
|
|
289
|
-
context: integerParam('Lines of context around each match. Non-negative integer.', { minimum: 0, maximum: 1000 }),
|
|
290
|
-
include_exported: booleanParam('Include exported symbols in deadcode results'),
|
|
291
|
-
include_decorated: booleanParam('Include decorated/annotated symbols in deadcode results'),
|
|
292
|
-
calls_only: booleanParam('tests: retain direct calls and test-case matches only.'),
|
|
293
|
-
max_lines: integerParam('source: maximum lines per declaration; raw mode discloses any truncation.', { exclusiveMinimum: 0, maximum: 1000000 }),
|
|
294
|
-
direction: stringParam('trace: callees/callers. deps: imports/importers/both.', { enum: ['callees', 'callers', 'imports', 'importers', 'both'] }),
|
|
295
|
-
to: stringParam('trace with direction=callers: continue toward entry points.', { enum: ['entrypoints'] }),
|
|
296
|
-
cycles: booleanParam('deps: report circular imports instead of a file graph.'),
|
|
297
|
-
term: stringParam('Literal search term by default. Set regex=true only for regular-expression syntax.'),
|
|
298
|
-
regex: booleanParam('Treat search term as a regular expression (default: false/literal). Ordinary patterns run in an RE2-compatible linear-time engine; unsafe nested repetition is rejected.'),
|
|
299
|
-
functions: booleanParam('repo stats: include per-function line counts sorted by size.'),
|
|
300
|
-
hot: booleanParam('repo stats: include the top N most-called functions.'),
|
|
301
|
-
diverse: booleanParam('show example: return representatives from distinct argument shapes.'),
|
|
302
|
-
lines: booleanParam('find/usages/search/show/impact: path:line:text listings without default row caps; explicit top/limit still apply. show accepts callers/callees sections, default callers. Tier tags follow a tab; accounting and notes follow as "# " lines. MCP transport budgets still apply and preserve accounting.'),
|
|
303
|
-
raw: booleanParam('source: code text without a header or line-number gutter, including full large classes. Notes follow as "# " lines; MCP transport budgets still apply.'),
|
|
304
|
-
git: booleanParam('show summary: attach last-modified, author, and recent-change metadata.'),
|
|
305
|
-
add_param: stringParam('Parameter name to add (plan command)'),
|
|
306
|
-
remove_param: stringParam('Parameter name to remove (plan command)'),
|
|
307
|
-
rename_to: stringParam('New name for the function, method, or type (plan command)'),
|
|
308
|
-
default_value: stringParam('Default value for added parameter (plan command)'),
|
|
309
|
-
stack: stringParam('The stack trace text to parse (stacktrace command)'),
|
|
310
|
-
range: stringParam('source line range, e.g. "10-20" or "15", of the file given as file or name.'),
|
|
311
|
-
base: stringParam('Git ref (default: HEAD). impact/check without a symbol: diff against it; check with a symbol: compare the declaration with its version there. E.g. "HEAD~3", "main", a commit SHA'),
|
|
312
|
-
staged: booleanParam('impact/check without a symbol: analyze staged changes.'),
|
|
313
|
-
deep: booleanParam('repo: include health and sample the ordinal resolution-evidence profile, not accuracy.'),
|
|
314
|
-
compact: booleanParam('Compact output defaults to true for show/impact and false for usages; set the opposite value to change that command\'s presentation.'),
|
|
315
|
-
case_sensitive: booleanParam('Case-sensitive search (default: false, case-insensitive)'),
|
|
316
|
-
all: booleanParam('Lift formatter and result caps where supported.'),
|
|
317
|
-
top_level: booleanParam('repo files: show only top-level functions.'),
|
|
318
|
-
class_name: stringParam('Class name to scope method analysis (e.g. "MarketDataFetcher" for close)'),
|
|
319
|
-
line: integerParam('Definition line pin. Resolves the symbol defined at this exact line (the middle component of a file:line:name handle). Disambiguates same-file same-name definitions.', { exclusiveMinimum: 0, maximum: Number.MAX_SAFE_INTEGER }),
|
|
320
|
-
limit: integerParam('Max results to return (default: 500; structural search: 50; usages and lines: uncapped). Caps find, usages, search, deadcode, api, and repo files. find text shows the top 5 in detail and counts the rest; limit raises both. Must be a positive integer.', { exclusiveMinimum: 0, maximum: 1000000 }),
|
|
321
|
-
max_files: integerParam('Max files to index (default: 10000). Use for very large codebases. Must be a positive integer.', { exclusiveMinimum: 0, maximum: 10000000 }),
|
|
322
|
-
max_chars: integerParam('Max output characters, not UTF-8 bytes, including notes and preserved metadata. Broad sweep commands (repo, entrypoints, endpoints, deadcode, deps, check, audit_async) default to 3K; all other commands default to 10K. Maximum: 100K. all=true lifts formatter caps but keeps the 100K transport ceiling.', { exclusiveMinimum: 0, maximum: 100000 }),
|
|
323
|
-
type: stringParam('Symbol type filter for structural search: function, class, call, method, type, state, field, constant, macro. Triggers index-based search.'),
|
|
324
|
-
param: stringParam('Filter by parameter name or type (structural search). E.g. "Request", "ctx".'),
|
|
325
|
-
receiver: stringParam('Filter calls by receiver (structural search, type=call). E.g. "db", "http".'),
|
|
326
|
-
returns: stringParam('Filter by return type (structural search). E.g. "Promise", "error".'),
|
|
327
|
-
decorator: stringParam('Filter by decorator/annotation (structural search). E.g. "Route", "Test".'),
|
|
328
|
-
exported: booleanParam('Only exported/public symbols (structural search).'),
|
|
329
|
-
unused: booleanParam('Only symbols with zero callers (structural search).'),
|
|
330
|
-
framework: stringParam('Filter entrypoints by framework (e.g. "express", "spring", "flask"). Comma-separated for multiple.'),
|
|
331
|
-
follow_symlinks: booleanParam('Follow symlinks during file discovery (default: true)'),
|
|
332
|
-
include_bundled: booleanParam('Index *.min.js and *.bundle.js files (default: false). Source maps remain disclosed but unindexed. Bypasses the shared cache.'),
|
|
333
|
-
bridge: booleanParam('Match server routes to client requests (endpoints command).'),
|
|
334
|
-
server_only: booleanParam('Only list server routes (endpoints command).'),
|
|
335
|
-
client_only: booleanParam('Only list client requests (endpoints command).'),
|
|
336
|
-
unmatched: booleanParam('Only show unmatched routes/requests (endpoints command).'),
|
|
337
|
-
method: stringParam('Filter by HTTP method (e.g. "GET", "POST") for endpoints.'),
|
|
338
|
-
prefix: stringParam('Filter routes/requests by path prefix (endpoints command).'),
|
|
339
|
-
hide_uncertain: booleanParam('Hide uncertain (interpolated-path) bridges (endpoints command).'),
|
|
266
|
+
command: {
|
|
267
|
+
type: 'string',
|
|
268
|
+
description: `UCN task command. One of: ${getMcpCommandEnum().join(', ')}.`,
|
|
269
|
+
enum: getMcpCommandEnum(),
|
|
270
|
+
},
|
|
271
|
+
project_dir: {
|
|
272
|
+
type: 'string',
|
|
273
|
+
description: 'Non-empty absolute path, or a path relative to the MCP server process working directory, identifying the project to analyze.',
|
|
274
|
+
minLength: 1,
|
|
275
|
+
},
|
|
276
|
+
...mcpParamProperties(),
|
|
340
277
|
};
|
|
341
278
|
|
|
342
279
|
const INPUT_SCHEMA = {
|
|
@@ -415,7 +352,7 @@ server.registerTool(
|
|
|
415
352
|
if (applicable) {
|
|
416
353
|
// Truly global options — apply to all commands (build/display control).
|
|
417
354
|
// Command-specific params (name, term, stack, range, etc.) are in FLAG_APPLICABILITY.
|
|
418
|
-
const coreParams = new Set(
|
|
355
|
+
const coreParams = new Set(GLOBAL_PARAMS);
|
|
419
356
|
for (const key of Object.keys(ep)) {
|
|
420
357
|
if (coreParams.has(key)) continue;
|
|
421
358
|
if (!applicable.includes(key) && ep[key] !== undefined &&
|
|
@@ -436,34 +373,23 @@ server.registerTool(
|
|
|
436
373
|
if (strippedParams.length > 0) {
|
|
437
374
|
noteParts.push(`${strippedParams.join(', ')} ignored (not applicable to ${command}).`);
|
|
438
375
|
}
|
|
439
|
-
|
|
440
|
-
noteParts.push(`include_methods=true has no effect on '${command}' — method calls are always tiered by receiver evidence.`);
|
|
441
|
-
}
|
|
376
|
+
for (const note of noOpNotes(canonicalCommand, ep)) noteParts.push(formatSurfaceMessage(note, 'mcp'));
|
|
442
377
|
if (projectScopeNote) noteParts.push(projectScopeNote);
|
|
443
378
|
noteParts.push(...unknownParamNotes);
|
|
444
379
|
const strippedNote = noteParts.length > 0
|
|
445
380
|
? '\n\n' + noteParts.map(part => `Note: ${part}`).join('\n')
|
|
446
381
|
: '';
|
|
382
|
+
// In a line listing everything that is not a record is a "# " line.
|
|
383
|
+
const listingNote = noteParts.length > 0
|
|
384
|
+
? '\n' + noteParts.map(part => `# Note: ${part}`).join('\n')
|
|
385
|
+
: '';
|
|
447
386
|
|
|
448
387
|
// Wrap toolResult to auto-inject command + maxChars + stripping note
|
|
449
|
-
const tr = (text) => toolResult(text, command, maxChars, strippedNote, ep);
|
|
388
|
+
const tr = (text, peerText) => toolResult(text, command, maxChars, ep.lines ? listingNote : strippedNote, ep, peerText);
|
|
450
389
|
// Wrap toolError to include stripping note on error paths too
|
|
451
390
|
const te = strippedNote
|
|
452
391
|
? (msg) => toolError(msg + strippedNote)
|
|
453
392
|
: toolError;
|
|
454
|
-
// Translate CLI flag syntax in execute-layer notes to MCP param
|
|
455
|
-
// syntax — the deadcode exported/decorated hints were already
|
|
456
|
-
// param-styled, but limit/depth/truncation notes leaked
|
|
457
|
-
// '--limit N' / '--max-files N' / '--all' at this surface.
|
|
458
|
-
const mn = (note) => note && note
|
|
459
|
-
.replace(/--limit N\b/g, 'limit=<n>')
|
|
460
|
-
.replace(/--max-files N\b/g, 'max_files=<n>')
|
|
461
|
-
.replace(/--depth=N\b/g, 'depth=<n>')
|
|
462
|
-
.replace(/--detailed\b/g, 'detailed=true')
|
|
463
|
-
.replace(/--all\b/g, 'all=true')
|
|
464
|
-
.replace(/--expand-unverified\b/g, 'expand_unverified=true')
|
|
465
|
-
.replace(/--(\w[\w-]*)/g, (_m, f) => f.replace(/-/g, '_'));
|
|
466
|
-
|
|
467
393
|
let index = null; // Track for post-command cache save
|
|
468
394
|
try {
|
|
469
395
|
// Public v5 has one MCP dispatch path. The canonical registry,
|
|
@@ -514,7 +440,6 @@ server.registerTool(
|
|
|
514
440
|
|
|
515
441
|
const presentationExecution = {
|
|
516
442
|
...execution,
|
|
517
|
-
note: mn(execution.note),
|
|
518
443
|
surface: 'mcp',
|
|
519
444
|
};
|
|
520
445
|
return tr(output.formatPublicText(
|
|
@@ -522,6 +447,11 @@ server.registerTool(
|
|
|
522
447
|
execution.result,
|
|
523
448
|
ep,
|
|
524
449
|
presentationExecution,
|
|
450
|
+
), ep.lines || ep.raw ? undefined : output.formatPublicText(
|
|
451
|
+
canonicalCommand,
|
|
452
|
+
execution.result,
|
|
453
|
+
ep,
|
|
454
|
+
{ ...execution, surface: 'cli' },
|
|
525
455
|
));
|
|
526
456
|
|
|
527
457
|
} catch (e) {
|
|
@@ -540,6 +470,10 @@ server.registerTool(
|
|
|
540
470
|
try { index.saveCache(); } catch (_) { /* best-effort */ }
|
|
541
471
|
index.callsCacheDirty = false;
|
|
542
472
|
}
|
|
473
|
+
// A HOT ranking this request computed, for the next session.
|
|
474
|
+
if (index && !ep.includeBundled && !ep.maxFiles && index.hotSummaryDirty) {
|
|
475
|
+
try { index.saveHotSummaries(); } catch (_) { /* best-effort */ }
|
|
476
|
+
}
|
|
543
477
|
}
|
|
544
478
|
}
|
|
545
479
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ucn",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.1",
|
|
4
4
|
"mcpName": "io.github.mleoca/ucn",
|
|
5
5
|
"description": "Auditable AST code intelligence for AI agents: 18 task-oriented commands through one MCP tool, CLI, or agent skill. Supports JS/TS, Python, Go, Rust, Java, C, C++, C#, and HTML.",
|
|
6
6
|
"main": "index.js",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"ucn-mcp": "mcp/server.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"version": "node scripts/sync-server-version.js && git add server.json",
|
|
13
|
-
"test": "node --test test/audit-5.4.0.test.js test/audit-5.3.8.test.js test/audit-5.3.7.test.js test/audit-5.3.6.test.js test/evidence-provenance.test.js test/provenance-unit.test.js test/provenance-scope.test.js test/shell-output.test.js test/parser-unit.test.js test/integration.test.js test/cache.test.js test/formatter.test.js test/interactive.test.js test/feature.test.js test/regression-js.test.js test/regression-py.test.js test/regression-go.test.js test/regression-java.test.js test/regression-rust.test.js test/regression-c-family.test.js test/regression-cross.test.js test/regression-mcp.test.js test/mcp-protocol.test.js test/mcp-sdk-compat.test.js test/dependency-security.test.js test/regression-parser.test.js test/regression-commands.test.js test/regression-fixes.test.js test/regression-bugfixes.test.js test/release-surface-regressions.test.js test/prerelease-audit.test.js test/release-readiness-audit.test.js test/cross-language.test.js test/accuracy.test.js test/command-coverage.test.js test/perf-optimizations.test.js test/performance-gate-policy.test.js test/oracle-gate-policy.test.js test/outcome-policy.test.js test/consistency-eval.test.js test/agent-public-surface-benchmark.test.js test/command-contracts.test.js test/language-adapter.test.js test/systematic-test.js test/mcp-edge-cases.js test/conservation.test.js test/parity-test.js test/trust-matrix.test.js",
|
|
12
|
+
"version": "node scripts/sync-server-version.js && node scripts/changelog.js && git add server.json CHANGELOG.md",
|
|
13
|
+
"test": "node --test test/audit-5.4.0.test.js test/audit-5.3.8.test.js test/audit-5.3.7.test.js test/audit-5.3.6.test.js test/evidence-provenance.test.js test/evidence-bands.test.js test/constructed-receiver.test.js test/provenance-unit.test.js test/provenance-scope.test.js test/shell-output.test.js test/param-table.test.js test/changelog.test.js test/repo-facts.test.js test/parser-unit.test.js test/integration.test.js test/cache.test.js test/formatter.test.js test/interactive.test.js test/feature.test.js test/regression-js.test.js test/regression-py.test.js test/regression-go.test.js test/regression-java.test.js test/regression-rust.test.js test/regression-c-family.test.js test/regression-cross.test.js test/regression-mcp.test.js test/mcp-protocol.test.js test/mcp-sdk-compat.test.js test/dependency-security.test.js test/regression-parser.test.js test/regression-commands.test.js test/regression-fixes.test.js test/regression-bugfixes.test.js test/release-surface-regressions.test.js test/prerelease-audit.test.js test/release-readiness-audit.test.js test/cross-language.test.js test/accuracy.test.js test/command-coverage.test.js test/perf-optimizations.test.js test/performance-gate-policy.test.js test/oracle-gate-policy.test.js test/outcome-policy.test.js test/outcome-mutations.test.js test/source-universe.test.js test/deletion.test.js test/check-change-kinds.test.js test/check-outgoing.test.js test/check-performance.test.js test/test-units.test.js test/check-staged.test.js test/consistency-eval.test.js test/agent-public-surface-benchmark.test.js test/command-contracts.test.js test/language-adapter.test.js test/systematic-test.js test/mcp-edge-cases.js test/conservation.test.js test/parity-test.js test/trust-matrix.test.js",
|
|
14
14
|
"benchmark:agent": "node test/agent-public-surface-benchmark.js",
|
|
15
15
|
"benchmark:agent:gate": "node test/agent-public-surface-benchmark.js --gate",
|
|
16
16
|
"benchmark:agent:legacy": "node test/agent-understanding-benchmark.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"eval:host-calibration": "node eval/lib/host-calibration.js --pin",
|
|
22
22
|
"eval:consistency": "node eval/run-consistency-eval.js --project .",
|
|
23
23
|
"profile:callers": "node eval/profile-callers.js",
|
|
24
|
-
"
|
|
24
|
+
"profile:check": "node eval/profile-check.js",
|
|
25
|
+
"lint": "eslint core/ cli/ mcp/ languages/ eval/run-*.js eval/*-gate-policy.js eval/outcome-policy.js eval/outcome-mutations.js eval/deletion-matrix-cases.js eval/check-matrix-cases.js eval/check-outgoing-cases.js eval/test-unit-matrix-cases.js eval/profile-callers.js eval/profile-check.js eval/oracles/*.js",
|
|
25
26
|
"verify": "npm run lint && npm test",
|
|
26
27
|
"trust:gate:semantic": "node eval/run-oracle-eval.js --release --min-precision 0.98 --max-unscored-ratio 0.10",
|
|
27
28
|
"trust:gate:deadcode": "node eval/run-deadcode-eval.js --release --sample 100 --arm default",
|
|
@@ -30,8 +31,13 @@
|
|
|
30
31
|
"trust:gate:consistency": "node eval/run-consistency-eval.js --release --sample 40",
|
|
31
32
|
"trust:gate:agent": "node test/agent-public-surface-benchmark.js --gate",
|
|
32
33
|
"trust:gate:fast": "node --expose-gc eval/run-performance-gate.js --repo preact-signals,httpx --queries 20 && node eval/run-oracle-eval.js --repo preact-signals,httpx --min-precision 0.98 && node eval/run-consistency-eval.js --repo preact-signals,httpx --sample 20 --gate",
|
|
33
|
-
"trust:gate": "
|
|
34
|
+
"trust:gate:matrices": "node eval/run-deletion-matrix.js && node eval/run-check-matrix.js && node eval/run-test-unit-matrix.js",
|
|
35
|
+
"trust:gate:outcome": "node eval/run-outcome-eval.js --gate",
|
|
36
|
+
"trust:gate": "npm run trust:gate:performance && npm run trust:gate:semantic && npm run trust:gate:deadcode && npm run trust:gate:consistency && npm run trust:gate:agent && npm run trust:gate:matrices && npm run trust:gate:outcome",
|
|
34
37
|
"eval:outcome": "node eval/run-outcome-eval.js",
|
|
38
|
+
"eval:deletion-matrix": "node eval/run-deletion-matrix.js",
|
|
39
|
+
"eval:check-matrix": "node eval/run-check-matrix.js",
|
|
40
|
+
"eval:test-unit-matrix": "node eval/run-test-unit-matrix.js",
|
|
35
41
|
"eval:census": "node eval/run-unverified-census.js"
|
|
36
42
|
},
|
|
37
43
|
"keywords": [
|