ucn 5.5.2 → 5.6.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 +35 -12
- package/.claude/skills/ucn/references/commands.md +21 -17
- package/.claude/skills/ucn/references/resolution-rules.md +4 -0
- package/.claude/skills/ucn/references/trust-contract.md +4 -4
- package/CHANGELOG.md +474 -0
- package/README.md +71 -29
- package/cli/flags.js +184 -0
- package/cli/index.js +138 -324
- package/core/account.js +44 -87
- package/core/analysis.js +273 -107
- package/core/ast-analysis.js +2 -0
- package/core/bridge.js +29 -65
- package/core/cache.js +101 -16
- package/core/callers.js +352 -70
- package/core/capture.js +331 -0
- package/core/change-kinds.js +888 -0
- package/core/check.js +1117 -139
- package/core/client-receivers.js +189 -0
- package/core/command-contracts.js +7 -6
- package/core/constructed-class.js +1195 -0
- package/core/contract-membership.js +142 -0
- package/core/deadcode.js +388 -85
- package/core/deletion.js +401 -0
- package/core/discovery.js +104 -9
- 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 +3 -1
- package/core/inprocess-clients.js +41 -15
- package/core/ir.js +5 -1
- package/core/member-signatures.js +789 -0
- package/core/output/analysis-ext.js +20 -10
- package/core/output/analysis.js +98 -60
- package/core/output/check.js +98 -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 +30 -11
- package/core/output/refactoring.js +32 -0
- package/core/output/reporting.js +21 -2
- package/core/output/search.js +11 -2
- package/core/output/tracing.js +35 -7
- package/core/output-budget.js +124 -57
- 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-modules.js +6 -0
- package/core/reflection.js +166 -23
- package/core/registry.js +623 -72
- package/core/reporting.js +69 -34
- package/core/request-helpers.js +63 -7
- package/core/review-items.js +75 -0
- package/core/search.js +89 -128
- package/core/shared.js +0 -45
- package/core/snapshot.js +350 -0
- package/core/source-universe.js +707 -0
- package/core/test-units.js +3624 -0
- package/core/tracing.js +150 -96
- package/core/verify.js +27 -11
- 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 +422 -4
- package/languages/java.js +712 -0
- package/languages/javascript.js +1460 -2
- package/languages/lexical-scope.js +68 -0
- package/languages/python.js +1672 -1
- package/languages/rust.js +91 -0
- package/mcp/server.js +44 -110
- package/package.json +11 -6
|
@@ -1443,5 +1443,73 @@ function pythonClassBodyOrder(classNode, node, name) {
|
|
|
1443
1443
|
return before === 0 ? 'outer' : 'class';
|
|
1444
1444
|
}
|
|
1445
1445
|
|
|
1446
|
+
/**
|
|
1447
|
+
* The import statement that binds `name` for a reference at `node`, when
|
|
1448
|
+
* the nearest function scope binding the name binds it by that one
|
|
1449
|
+
* statement alone (`def f(): from m import Name`). Null when the name is
|
|
1450
|
+
* bound at module scope, by anything else, more than once, or the scope
|
|
1451
|
+
* declares it `global` / `nonlocal` or star-imports.
|
|
1452
|
+
*/
|
|
1453
|
+
function localImportStatement(node, language, name = node?.text) {
|
|
1454
|
+
if (familyOf(language) !== 'python' || !node?.parent) return null;
|
|
1455
|
+
let child = node;
|
|
1456
|
+
let crossedFunction = false;
|
|
1457
|
+
try {
|
|
1458
|
+
for (let scope = node.parent; scope; child = scope, scope = scope.parent) {
|
|
1459
|
+
switch (scope.type) {
|
|
1460
|
+
case 'function_definition': {
|
|
1461
|
+
const body = scope.childForFieldName('body');
|
|
1462
|
+
if (!sameNode(body, child)) continue;
|
|
1463
|
+
const sites = [];
|
|
1464
|
+
const info = pyScopeBindings(scope, body, name, true, true,
|
|
1465
|
+
(site, kind) => sites.push({ site, kind }));
|
|
1466
|
+
if (info.starImport || info.global || info.nonlocal) return null;
|
|
1467
|
+
if (sites.length === 0) { crossedFunction = true; continue; }
|
|
1468
|
+
if (sites.length !== 1 || sites[0].kind !== 'import') return null;
|
|
1469
|
+
let statement = sites[0].site;
|
|
1470
|
+
while (statement && statement.type !== 'import_statement' &&
|
|
1471
|
+
statement.type !== 'import_from_statement') statement = statement.parent;
|
|
1472
|
+
return statement || null;
|
|
1473
|
+
}
|
|
1474
|
+
case 'lambda': {
|
|
1475
|
+
if (!sameNode(scope.childForFieldName('body'), child)) continue;
|
|
1476
|
+
const names = [];
|
|
1477
|
+
pyParameterNames(scope.childForFieldName('parameters'), names);
|
|
1478
|
+
if (names.some(n => n.text === name)) return null;
|
|
1479
|
+
crossedFunction = true;
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
case 'class_definition': {
|
|
1483
|
+
const body = scope.childForFieldName('body');
|
|
1484
|
+
if (!sameNode(body, child) || crossedFunction) continue;
|
|
1485
|
+
const info = pyScopeBindings(scope, body, name, false, true);
|
|
1486
|
+
if (info.bound || info.starImport) return null;
|
|
1487
|
+
continue;
|
|
1488
|
+
}
|
|
1489
|
+
case 'list_comprehension': case 'set_comprehension':
|
|
1490
|
+
case 'dictionary_comprehension': case 'generator_expression': {
|
|
1491
|
+
const clauses = namedChildrenOf(scope).filter(c => c.type === 'for_in_clause');
|
|
1492
|
+
if (within(node, clauses[0]?.childForFieldName('right'))) continue;
|
|
1493
|
+
for (const clause of clauses) {
|
|
1494
|
+
const names = [];
|
|
1495
|
+
pyTargetNames(clause.childForFieldName('left'), names);
|
|
1496
|
+
if (names.some(n => n.text === name)) return null;
|
|
1497
|
+
}
|
|
1498
|
+
crossedFunction = true;
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
case 'module':
|
|
1502
|
+
return null;
|
|
1503
|
+
default:
|
|
1504
|
+
continue;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
} catch {
|
|
1508
|
+
return null;
|
|
1509
|
+
}
|
|
1510
|
+
return null;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1446
1513
|
module.exports = { referenceScope, referenceScopeNode, scopeFields, familyOf, rustLetBindingOf, rustSelfFieldBinding,
|
|
1514
|
+
localImportStatement,
|
|
1447
1515
|
pythonBindingSites, pythonClassBodyOrder, pythonScopeBindingKinds, goExpressionTypeArgument, jsPatternTarget };
|