gitnexus 1.6.4-rc.2 → 1.6.4-rc.21
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/README.md +35 -0
- package/dist/_shared/index.d.ts +1 -1
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +22 -14
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +298 -37
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts +23 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js +36 -2
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +47 -3
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.js +10 -2
- package/dist/_shared/scope-resolution/types.js.map +1 -1
- package/dist/cli/analyze.d.ts +6 -0
- package/dist/cli/analyze.js +35 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +31 -0
- package/dist/cli/index.js +13 -0
- package/dist/cli/setup.js +2 -2
- package/dist/core/embeddings/config.d.ts +2 -0
- package/dist/core/embeddings/config.js +36 -0
- package/dist/core/embeddings/embedder.js +11 -6
- package/dist/core/embeddings/embedding-pipeline.d.ts +7 -1
- package/dist/core/embeddings/embedding-pipeline.js +93 -29
- package/dist/core/embeddings/exact-search.d.ts +15 -0
- package/dist/core/embeddings/exact-search.js +27 -0
- package/dist/core/embeddings/types.d.ts +4 -0
- package/dist/core/embeddings/types.js +2 -0
- package/dist/core/group/config-parser.js +2 -0
- package/dist/core/group/matching.d.ts +3 -3
- package/dist/core/group/matching.js +46 -6
- package/dist/core/group/storage.js +2 -0
- package/dist/core/group/sync.js +1 -1
- package/dist/core/group/types.d.ts +18 -0
- package/dist/core/ingestion/call-processor.d.ts +3 -3
- package/dist/core/ingestion/call-processor.js +58 -65
- package/dist/core/ingestion/constants.d.ts +4 -3
- package/dist/core/ingestion/constants.js +8 -3
- package/dist/core/ingestion/finalize-orchestrator.js +6 -3
- package/dist/core/ingestion/heritage-processor.js +2 -2
- package/dist/core/ingestion/import-processor.js +1 -1
- package/dist/core/ingestion/language-provider.d.ts +8 -0
- package/dist/core/ingestion/languages/csharp/captures.js +4 -1
- package/dist/core/ingestion/languages/csharp/namespace-siblings.d.ts +14 -13
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +62 -50
- package/dist/core/ingestion/languages/python/captures.js +9 -1
- package/dist/core/ingestion/languages/python/index.d.ts +1 -1
- package/dist/core/ingestion/languages/python/index.js +1 -1
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +3 -1
- package/dist/core/ingestion/languages/python/simple-hooks.js +8 -0
- package/dist/core/ingestion/languages/python.js +28 -1
- package/dist/core/ingestion/languages/swift.js +14 -0
- package/dist/core/ingestion/languages/typescript/arity-metadata.d.ts +59 -0
- package/dist/core/ingestion/languages/typescript/arity-metadata.js +103 -0
- package/dist/core/ingestion/languages/typescript/arity.d.ts +37 -0
- package/dist/core/ingestion/languages/typescript/arity.js +54 -0
- package/dist/core/ingestion/languages/typescript/cache-stats.d.ts +17 -0
- package/dist/core/ingestion/languages/typescript/cache-stats.js +28 -0
- package/dist/core/ingestion/languages/typescript/captures.d.ts +28 -0
- package/dist/core/ingestion/languages/typescript/captures.js +451 -0
- package/dist/core/ingestion/languages/typescript/import-decomposer.d.ts +49 -0
- package/dist/core/ingestion/languages/typescript/import-decomposer.js +371 -0
- package/dist/core/ingestion/languages/typescript/import-target.d.ts +50 -0
- package/dist/core/ingestion/languages/typescript/import-target.js +61 -0
- package/dist/core/ingestion/languages/typescript/index.d.ts +94 -0
- package/dist/core/ingestion/languages/typescript/index.js +94 -0
- package/dist/core/ingestion/languages/typescript/interpret.d.ts +35 -0
- package/dist/core/ingestion/languages/typescript/interpret.js +317 -0
- package/dist/core/ingestion/languages/typescript/merge-bindings.d.ts +62 -0
- package/dist/core/ingestion/languages/typescript/merge-bindings.js +158 -0
- package/dist/core/ingestion/languages/typescript/query.d.ts +77 -0
- package/dist/core/ingestion/languages/typescript/query.js +778 -0
- package/dist/core/ingestion/languages/typescript/receiver-binding.d.ts +59 -0
- package/dist/core/ingestion/languages/typescript/receiver-binding.js +171 -0
- package/dist/core/ingestion/languages/typescript/scope-resolver.d.ts +16 -0
- package/dist/core/ingestion/languages/typescript/scope-resolver.js +113 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +71 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.js +131 -0
- package/dist/core/ingestion/languages/typescript.js +19 -0
- package/dist/core/ingestion/method-extractors/configs/swift.js +3 -4
- package/dist/core/ingestion/model/scope-resolution-indexes.d.ts +14 -1
- package/dist/core/ingestion/parsing-processor.js +20 -9
- package/dist/core/ingestion/pipeline-phases/processes.js +9 -4
- package/dist/core/ingestion/pipeline-phases/tools.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/tools.js +10 -4
- package/dist/core/ingestion/registry-primary-flag.d.ts +3 -1
- package/dist/core/ingestion/registry-primary-flag.js +4 -1
- package/dist/core/ingestion/scope-extractor-bridge.d.ts +5 -2
- package/dist/core/ingestion/scope-extractor-bridge.js +7 -2
- package/dist/core/ingestion/scope-extractor.js +19 -18
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +73 -11
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +48 -10
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +283 -14
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.d.ts +23 -2
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +109 -37
- package/dist/core/ingestion/scope-resolution/passes/mro.js +3 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +13 -5
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +11 -2
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +8 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +21 -5
- package/dist/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.d.ts +39 -0
- package/dist/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +65 -0
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +54 -11
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +105 -30
- package/dist/core/ingestion/type-extractors/swift.js +7 -4
- package/dist/core/ingestion/utils/ast-helpers.d.ts +2 -0
- package/dist/core/ingestion/utils/ast-helpers.js +12 -0
- package/dist/core/ingestion/utils/env.d.ts +10 -0
- package/dist/core/ingestion/utils/env.js +14 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +1 -0
- package/dist/core/ingestion/workers/parse-worker.js +15 -9
- package/dist/core/ingestion/workers/worker-pool.d.ts +11 -4
- package/dist/core/ingestion/workers/worker-pool.js +244 -48
- package/dist/core/lbug/extension-loader.d.ts +86 -0
- package/dist/core/lbug/extension-loader.js +184 -0
- package/dist/core/lbug/lbug-adapter.d.ts +18 -17
- package/dist/core/lbug/lbug-adapter.js +45 -73
- package/dist/core/lbug/pool-adapter.js +10 -28
- package/dist/core/platform/capabilities.d.ts +24 -0
- package/dist/core/platform/capabilities.js +54 -0
- package/dist/core/run-analyze.js +36 -9
- package/dist/core/search/bm25-index.d.ts +0 -17
- package/dist/core/search/bm25-index.js +10 -118
- package/dist/core/search/fts-indexes.d.ts +1 -0
- package/dist/core/search/fts-indexes.js +7 -0
- package/dist/core/search/fts-schema.d.ts +6 -0
- package/dist/core/search/fts-schema.js +7 -0
- package/dist/mcp/core/embedder.js +11 -4
- package/dist/mcp/local/local-backend.js +50 -15
- package/dist/server/api.d.ts +5 -0
- package/dist/server/api.js +113 -0
- package/hooks/claude/gitnexus-hook.cjs +11 -1
- package/package.json +6 -5
- package/scripts/build-tree-sitter-dart.cjs +42 -0
- package/scripts/build-tree-sitter-proto.cjs +1 -1
- package/scripts/build.js +22 -2
- package/scripts/install-duckdb-extension.mjs +37 -0
- package/vendor/tree-sitter-dart/README.md +18 -0
- package/vendor/tree-sitter-dart/binding.gyp +31 -0
- package/vendor/tree-sitter-dart/bindings/node/binding.cc +20 -0
- package/vendor/tree-sitter-dart/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-dart/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-dart/grammar.js +2895 -0
- package/vendor/tree-sitter-dart/package.json +18 -0
- package/vendor/tree-sitter-dart/queries/highlights.scm +246 -0
- package/vendor/tree-sitter-dart/queries/tags.scm +92 -0
- package/vendor/tree-sitter-dart/queries/test.scm +1 -0
- package/vendor/tree-sitter-dart/src/grammar.json +12459 -0
- package/vendor/tree-sitter-dart/src/node-types.json +15055 -0
- package/vendor/tree-sitter-dart/src/parser.c +196127 -0
- package/vendor/tree-sitter-dart/src/scanner.c +130 -0
- package/vendor/tree-sitter-dart/src/tree_sitter/alloc.h +54 -0
- package/vendor/tree-sitter-dart/src/tree_sitter/array.h +290 -0
- package/vendor/tree-sitter-dart/src/tree_sitter/parser.h +265 -0
- package/vendor/tree-sitter-swift/LICENSE +21 -0
- package/vendor/tree-sitter-swift/README.md +139 -0
- package/vendor/tree-sitter-swift/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-swift/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-swift/package.json +28 -0
- package/vendor/tree-sitter-swift/prebuilds/darwin-arm64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/darwin-x64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/linux-arm64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/linux-x64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/win32-arm64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/prebuilds/win32-x64/tree-sitter-swift.node +0 -0
- package/vendor/tree-sitter-swift/src/node-types.json +30694 -0
- package/web/assets/agent-DaprsFSX.js +597 -0
- package/web/assets/architecture-YZFGNWBL-S5CXDPWN-DEdGaPg2.js +1 -0
- package/web/assets/architectureDiagram-EMZXCZ2Q-Domyk_gO.js +36 -0
- package/web/assets/blockDiagram-IGV67L2C-B_2kD7tM.js +132 -0
- package/web/assets/c4Diagram-DFAF54RM-BhJJW8Gg.js +10 -0
- package/web/assets/chunk-3GS5O3IE-jlWIjPsl.js +231 -0
- package/web/assets/chunk-3YCYZ6SJ-Blq_IzZs.js +1 -0
- package/web/assets/chunk-6NTNNK5N-DyPc58pp.js +1 -0
- package/web/assets/chunk-7RZVMHOQ-BdIU-RGO.js +321 -0
- package/web/assets/chunk-A34GCYZU-BI2i_LdU.js +1 -0
- package/web/assets/chunk-AEOMTBSW-D7qjBMHW.js +1 -0
- package/web/assets/chunk-CilyBKbf.js +1 -0
- package/web/assets/chunk-DJ7UZH7F-i11ywiBl.js +1 -0
- package/web/assets/chunk-DKKBVRCY-1SffGI1N.js +4 -0
- package/web/assets/chunk-DU5LTGQ6-DaPeiwD5.js +1 -0
- package/web/assets/chunk-FXACKDTF-uhhi2PC2.js +159 -0
- package/web/assets/chunk-H3VCZNTA-IchcISDt.js +1 -0
- package/web/assets/chunk-HN6EAY2L-D7ZFMNrB.js +1 -0
- package/web/assets/chunk-KSICW3F5-C2tZmXwv.js +15 -0
- package/web/assets/chunk-O5ABG6QK-Bt-Km84H.js +1 -0
- package/web/assets/chunk-PK6DOVAG-ChlWY0BQ.js +206 -0
- package/web/assets/chunk-RNJOYNJ4-B724K7cW.js +1 -0
- package/web/assets/chunk-RWUO3TPN-DYn1XriD.js +1 -0
- package/web/assets/chunk-TBF5ZNIQ-DKtDz6ae.js +1 -0
- package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +1 -0
- package/web/assets/chunk-TYMNRAUI-g1h33cq-.js +1 -0
- package/web/assets/chunk-VELTKBKT-C9dVN39o.js +1 -0
- package/web/assets/chunk-W7ZLLLMY-Du-Hb9yb.js +1 -0
- package/web/assets/chunk-WSB5WSVC-B123clsZ.js +1 -0
- package/web/assets/chunk-XGPFEOL4-BR7Eue38.js +1 -0
- package/web/assets/classDiagram-PPOCWD7C-BglfKSs_.js +1 -0
- package/web/assets/classDiagram-v2-23LJLIIU-BSzTM28O.js +1 -0
- package/web/assets/context-builder-CqQNhRj1.js +15 -0
- package/web/assets/cose-bilkent-PNC4W37J-DCfErU-A.js +1 -0
- package/web/assets/dagre-E77IOHMT-tDRRhDoN.js +4 -0
- package/web/assets/diagram-H7BISOXX-CUVHlmAh.js +43 -0
- package/web/assets/diagram-JC5VWROH-BoyOxulB.js +24 -0
- package/web/assets/diagram-LXUTUG65-osr9hb7N.js +10 -0
- package/web/assets/diagram-WEHSV5V5-d8nUqS39.js +24 -0
- package/web/assets/erDiagram-GCSMX5X6-b-IwOhPS.js +85 -0
- package/web/assets/flowDiagram-OTCZ4VVT-Ott2Q0AP.js +162 -0
- package/web/assets/ganttDiagram-MUNLMDZQ-BYtgN_5s.js +292 -0
- package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-CFyBIGZq.js +1 -0
- package/web/assets/gitGraphDiagram-3HKGZ4G3-CsVD2gn4.js +106 -0
- package/web/assets/index-BleGLU8S.css +2 -0
- package/web/assets/index-C_xK08EW.js +885 -0
- package/web/assets/info-OMHHGYJF-BF2H5H6G-yjAxKEzh.js +1 -0
- package/web/assets/infoDiagram-MN7RKWGX-DXK0Unn5.js +2 -0
- package/web/assets/ishikawaDiagram-YMYX4NHK-CXsnC2FA.js +70 -0
- package/web/assets/journeyDiagram-SO5T7YLQ-BzZ07B-X.js +139 -0
- package/web/assets/kanban-definition-LJHFXRCJ-C6_EpAd9.js +89 -0
- package/web/assets/katex-GD7MH7QM-CJiOjBBJ.js +261 -0
- package/web/assets/mindmap-definition-2EUWGEK5-CCYGWZ1m.js +96 -0
- package/web/assets/packet-4T2RLAQJ-EV4IVRXR-B8k4E3IT.js +1 -0
- package/web/assets/pie-ZZUOXDRM-N23DN5KN-DdvfY118.js +1 -0
- package/web/assets/pieDiagram-3IATQBI2-RyvRlQb4.js +30 -0
- package/web/assets/quadrantDiagram-E256RVCF-Bfb6sxCx.js +7 -0
- package/web/assets/radar-PYXPWWZC-P6TP7ZYP-1EEDC_yU.js +1 -0
- package/web/assets/requirementDiagram-M5DCFWZL-DjvHDyvN.js +84 -0
- package/web/assets/sankeyDiagram-L3NBLAOT-CBCbbl8s.js +10 -0
- package/web/assets/sequenceDiagram-ZOUHS735-BscU8TUR.js +157 -0
- package/web/assets/stateDiagram-MLPALWAM-CJusEK2D.js +1 -0
- package/web/assets/stateDiagram-v2-B5LQ5ZB2-DImJ3PXD.js +1 -0
- package/web/assets/timeline-definition-5SPVSISX-DigPA1X8.js +120 -0
- package/web/assets/treeView-SZITEDCU-5DXDK3XO-CzPDt3aG.js +1 -0
- package/web/assets/treemap-W4RFUUIX-WYLRDWKO-B9Iqiorr.js +1 -0
- package/web/assets/vennDiagram-IE5QUKF5-C91UkZIf.js +34 -0
- package/web/assets/wardley-RL74JXVD-BCRCBASE-x42Qw7hp.js +1 -0
- package/web/assets/wardleyDiagram-XU3VSMPF-DloBhI0U.js +20 -0
- package/web/assets/xychartDiagram-ZHJ5623Y-BGWJvgwI.js +7 -0
- package/web/index.html +21 -0
- package/scripts/patch-tree-sitter-swift.cjs +0 -78
|
@@ -10,7 +10,7 @@ import { getDefinitionNodeFromCaptures, findEnclosingClassInfo, getLabelFromCapt
|
|
|
10
10
|
import { detectFrameworkFromAST } from './framework-detection.js';
|
|
11
11
|
import { buildTypeEnv } from './type-env.js';
|
|
12
12
|
import { buildMethodProps, arityForIdFromInfo, typeTagForId, constTagForId, buildCollisionGroups, } from './utils/method-props.js';
|
|
13
|
-
import { getTreeSitterBufferSize, TREE_SITTER_MAX_BUFFER } from './constants.js';
|
|
13
|
+
import { getTreeSitterBufferSize, getTreeSitterContentByteLength, TREE_SITTER_MAX_BUFFER, } from './constants.js';
|
|
14
14
|
// ============================================================================
|
|
15
15
|
// Worker-based parallel parsing
|
|
16
16
|
// ============================================================================
|
|
@@ -247,7 +247,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
247
247
|
continue;
|
|
248
248
|
}
|
|
249
249
|
// Skip files larger than the max tree-sitter buffer (32 MB)
|
|
250
|
-
if (file.content
|
|
250
|
+
if (getTreeSitterContentByteLength(file.content) > TREE_SITTER_MAX_BUFFER)
|
|
251
251
|
continue;
|
|
252
252
|
// Vue SFC preprocessing: extract <script> block content
|
|
253
253
|
let parseContent = file.content;
|
|
@@ -270,7 +270,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
270
270
|
let tree;
|
|
271
271
|
try {
|
|
272
272
|
tree = parser.parse(parseContent, undefined, {
|
|
273
|
-
bufferSize: getTreeSitterBufferSize(parseContent
|
|
273
|
+
bufferSize: getTreeSitterBufferSize(parseContent),
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
276
|
catch (parseError) {
|
|
@@ -412,10 +412,12 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
|
-
// Append #<paramCount> to
|
|
416
|
-
//
|
|
415
|
+
// Append #<paramCount> to owned callable IDs to disambiguate overloads.
|
|
416
|
+
// Top-level Function IDs stay stable; functions inside an owner may overload.
|
|
417
417
|
// When same-arity collisions exist, append ~type1,type2 for further disambiguation.
|
|
418
|
-
const needsAritySuffix = nodeLabel === 'Method' ||
|
|
418
|
+
const needsAritySuffix = nodeLabel === 'Method' ||
|
|
419
|
+
nodeLabel === 'Constructor' ||
|
|
420
|
+
(nodeLabel === 'Function' && enclosingClassId !== null);
|
|
419
421
|
let arityTag = needsAritySuffix && arityForId !== undefined ? `#${arityForId}` : '';
|
|
420
422
|
if (arityTag && seqDefMethods && seqDefMethodInfo && seqClassNodeId !== undefined) {
|
|
421
423
|
// Use cached method map + collision groups (built once per class, not per method)
|
|
@@ -555,6 +557,13 @@ export const processParsing = async (graph, files, symbolTable, astCache,
|
|
|
555
557
|
* Pass `undefined` if no consumer needs cross-phase access.
|
|
556
558
|
*/
|
|
557
559
|
scopeTreeCache, onFileProgress, workerPool) => {
|
|
560
|
+
let lastProgress = 0;
|
|
561
|
+
const reportProgress = onFileProgress
|
|
562
|
+
? (current, total, detail) => {
|
|
563
|
+
lastProgress = Math.max(lastProgress, current);
|
|
564
|
+
onFileProgress(lastProgress, total, detail);
|
|
565
|
+
}
|
|
566
|
+
: undefined;
|
|
558
567
|
if (workerPool) {
|
|
559
568
|
if (scopeTreeCache !== undefined && process.env.PROF_SCOPE_RESOLUTION === '1') {
|
|
560
569
|
// Trees can't cross MessageChannels, so worker-parsed files land
|
|
@@ -564,13 +573,15 @@ scopeTreeCache, onFileProgress, workerPool) => {
|
|
|
564
573
|
console.warn(`[scope-resolution prof] worker pool engaged for ${files.length} files — cross-phase tree cache will be empty; scope-resolution re-parses.`);
|
|
565
574
|
}
|
|
566
575
|
try {
|
|
567
|
-
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool,
|
|
576
|
+
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool, reportProgress);
|
|
568
577
|
}
|
|
569
578
|
catch (err) {
|
|
570
|
-
|
|
579
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
580
|
+
console.warn('Worker pool parsing stopped; continuing with sequential parser:', message);
|
|
581
|
+
reportProgress?.(lastProgress, files.length, `Sequential fallback after worker issue: ${message}`);
|
|
571
582
|
}
|
|
572
583
|
}
|
|
573
584
|
// Fallback: sequential parsing (no pre-extracted data)
|
|
574
|
-
await processParsingSequential(graph, files, symbolTable, astCache, scopeTreeCache,
|
|
585
|
+
await processParsingSequential(graph, files, symbolTable, astCache, scopeTreeCache, reportProgress);
|
|
575
586
|
return null;
|
|
576
587
|
};
|
|
@@ -84,12 +84,15 @@ export const processesPhase = {
|
|
|
84
84
|
}
|
|
85
85
|
list.push(url);
|
|
86
86
|
}
|
|
87
|
-
const
|
|
87
|
+
const toolsByHandlerId = new Map();
|
|
88
|
+
const toolsWithoutHandlerByFile = new Map();
|
|
88
89
|
for (const td of toolDefs) {
|
|
89
|
-
|
|
90
|
+
const key = td.handlerNodeId ?? td.filePath;
|
|
91
|
+
const targetMap = td.handlerNodeId ? toolsByHandlerId : toolsWithoutHandlerByFile;
|
|
92
|
+
let list = targetMap.get(key);
|
|
90
93
|
if (!list) {
|
|
91
94
|
list = [];
|
|
92
|
-
|
|
95
|
+
targetMap.set(key, list);
|
|
93
96
|
}
|
|
94
97
|
list.push(td.name);
|
|
95
98
|
}
|
|
@@ -118,7 +121,9 @@ export const processesPhase = {
|
|
|
118
121
|
linked++;
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
|
-
const
|
|
124
|
+
const exactToolNames = toolsByHandlerId.get(proc.entryPointId);
|
|
125
|
+
const fallbackToolNames = toolsWithoutHandlerByFile.get(entryFile);
|
|
126
|
+
const toolNames = exactToolNames ?? fallbackToolNames;
|
|
122
127
|
if (toolNames) {
|
|
123
128
|
for (const toolName of toolNames) {
|
|
124
129
|
const toolNodeId = generateId('Tool', toolName);
|
|
@@ -23,7 +23,13 @@ export const toolsPhase = {
|
|
|
23
23
|
if (seenToolNames.has(td.toolName))
|
|
24
24
|
continue;
|
|
25
25
|
seenToolNames.add(td.toolName);
|
|
26
|
-
|
|
26
|
+
const handlerNodeId = td.handlerNodeId && ctx.graph.getNode(td.handlerNodeId) ? td.handlerNodeId : undefined;
|
|
27
|
+
toolDefs.push({
|
|
28
|
+
name: td.toolName,
|
|
29
|
+
filePath: td.filePath,
|
|
30
|
+
description: td.description,
|
|
31
|
+
...(handlerNodeId !== undefined ? { handlerNodeId } : {}),
|
|
32
|
+
});
|
|
27
33
|
}
|
|
28
34
|
// TS tool definition arrays — require inputSchema nearby
|
|
29
35
|
const toolCandidatePaths = allPaths.filter((p) => (p.endsWith('.ts') || p.endsWith('.js')) &&
|
|
@@ -60,10 +66,10 @@ export const toolsPhase = {
|
|
|
60
66
|
label: 'Tool',
|
|
61
67
|
properties: { name: td.name, filePath: td.filePath, description: td.description },
|
|
62
68
|
});
|
|
63
|
-
const
|
|
69
|
+
const handlerId = td.handlerNodeId ?? generateId('File', td.filePath);
|
|
64
70
|
ctx.graph.addRelationship({
|
|
65
|
-
id: generateId('HANDLES_TOOL', `${
|
|
66
|
-
sourceId:
|
|
71
|
+
id: generateId('HANDLES_TOOL', `${handlerId}->${toolNodeId}`),
|
|
72
|
+
sourceId: handlerId,
|
|
67
73
|
targetId: toolNodeId,
|
|
68
74
|
type: 'HANDLES_TOOL',
|
|
69
75
|
confidence: 1.0,
|
|
@@ -56,7 +56,9 @@ import { SupportedLanguages } from '../../_shared/index.js';
|
|
|
56
56
|
* so this set also controls what gets silenced in the legacy DAG.
|
|
57
57
|
*
|
|
58
58
|
* Add a language here ONLY after shadow parity ≥ 99% fixtures / ≥ 98%
|
|
59
|
-
* corpus per RFC §6.4.
|
|
59
|
+
* corpus per RFC §6.4. TypeScript is temporarily accepted under the
|
|
60
|
+
* Ring 3 CI parity gate while corpus-level shadow-mode wiring is tracked
|
|
61
|
+
* in #927 for this migration.
|
|
60
62
|
*
|
|
61
63
|
* The set is intentionally a static TypeScript literal (not a JSON import,
|
|
62
64
|
* not an env lookup) so CI can discover it via `tsx` without a build step
|
|
@@ -56,7 +56,9 @@ import { SupportedLanguages } from '../../_shared/index.js';
|
|
|
56
56
|
* so this set also controls what gets silenced in the legacy DAG.
|
|
57
57
|
*
|
|
58
58
|
* Add a language here ONLY after shadow parity ≥ 99% fixtures / ≥ 98%
|
|
59
|
-
* corpus per RFC §6.4.
|
|
59
|
+
* corpus per RFC §6.4. TypeScript is temporarily accepted under the
|
|
60
|
+
* Ring 3 CI parity gate while corpus-level shadow-mode wiring is tracked
|
|
61
|
+
* in #927 for this migration.
|
|
60
62
|
*
|
|
61
63
|
* The set is intentionally a static TypeScript literal (not a JSON import,
|
|
62
64
|
* not an env lookup) so CI can discover it via `tsx` without a build step
|
|
@@ -65,6 +67,7 @@ import { SupportedLanguages } from '../../_shared/index.js';
|
|
|
65
67
|
export const MIGRATED_LANGUAGES = new Set([
|
|
66
68
|
SupportedLanguages.Python,
|
|
67
69
|
SupportedLanguages.CSharp,
|
|
70
|
+
SupportedLanguages.TypeScript,
|
|
68
71
|
]);
|
|
69
72
|
/**
|
|
70
73
|
* Return the env-var name that controls a given language's registry-
|
|
@@ -13,8 +13,11 @@
|
|
|
13
13
|
* `emitScopeCaptures`. Returns `undefined`; zero work done. This is
|
|
14
14
|
* the state of every language today — `ParsedFile` production stays
|
|
15
15
|
* dormant until a language migrates.
|
|
16
|
-
* 2.
|
|
17
|
-
*
|
|
16
|
+
* 2. Short-circuits empty / whitespace-only files. There is no scope
|
|
17
|
+
* content to extract, and some tree-sitter queries do not match an
|
|
18
|
+
* otherwise valid empty root node.
|
|
19
|
+
* 3. Invokes the hook + feeds its output to `ScopeExtractor.extract`.
|
|
20
|
+
* 4. **Swallows exceptions from either side.** A failure here returns
|
|
18
21
|
* `undefined` and emits a warning via `onWarn`; legacy parsing on
|
|
19
22
|
* the same file continues unaffected by the scope-extraction miss.
|
|
20
23
|
* Scope-based resolution is the new path under construction — it
|
|
@@ -13,8 +13,11 @@
|
|
|
13
13
|
* `emitScopeCaptures`. Returns `undefined`; zero work done. This is
|
|
14
14
|
* the state of every language today — `ParsedFile` production stays
|
|
15
15
|
* dormant until a language migrates.
|
|
16
|
-
* 2.
|
|
17
|
-
*
|
|
16
|
+
* 2. Short-circuits empty / whitespace-only files. There is no scope
|
|
17
|
+
* content to extract, and some tree-sitter queries do not match an
|
|
18
|
+
* otherwise valid empty root node.
|
|
19
|
+
* 3. Invokes the hook + feeds its output to `ScopeExtractor.extract`.
|
|
20
|
+
* 4. **Swallows exceptions from either side.** A failure here returns
|
|
18
21
|
* `undefined` and emits a warning via `onWarn`; legacy parsing on
|
|
19
22
|
* the same file continues unaffected by the scope-extraction miss.
|
|
20
23
|
* Scope-based resolution is the new path under construction — it
|
|
@@ -29,6 +32,8 @@ import { extract as extractScope } from './scope-extractor.js';
|
|
|
29
32
|
export function extractParsedFile(provider, sourceText, filePath, onWarn, cachedTree) {
|
|
30
33
|
if (provider.emitScopeCaptures === undefined)
|
|
31
34
|
return undefined;
|
|
35
|
+
if (sourceText.trim().length === 0)
|
|
36
|
+
return undefined;
|
|
32
37
|
try {
|
|
33
38
|
const captures = provider.emitScopeCaptures(sourceText, filePath, cachedTree);
|
|
34
39
|
return extractScope(captures, filePath, provider);
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
* - `ParsedFile.localDefs` — flattened union of `Scope.ownedDefs`.
|
|
59
59
|
* - `ParsedFile.referenceSites` — pre-resolution usage facts.
|
|
60
60
|
*/
|
|
61
|
-
import { buildPositionIndex, buildScopeTree, makeScopeId } from '../../_shared/index.js';
|
|
61
|
+
import { buildPositionIndex, buildScopeTree, canParentScope, makeScopeId } from '../../_shared/index.js';
|
|
62
62
|
// ─── Public entry point ─────────────────────────────────────────────────────
|
|
63
63
|
/**
|
|
64
64
|
* Drive the five extraction passes and return a `ParsedFile`.
|
|
@@ -210,7 +210,11 @@ function pass1BuildScopes(matches, filePath, provider) {
|
|
|
210
210
|
candidates.push({ match, range: anchor.range, kind, id });
|
|
211
211
|
}
|
|
212
212
|
// Sort by (startLine, startCol) ASC, (endLine, endCol) DESC so outer
|
|
213
|
-
// scopes appear before their children for parent-resolution.
|
|
213
|
+
// scopes appear before their children for parent-resolution. When two
|
|
214
|
+
// candidates have exactly equal ranges (e.g. a `compilation_unit` and
|
|
215
|
+
// the only top-level scope in the file — see `canParentScope`), Module
|
|
216
|
+
// sorts first so it lands on the stack ahead of the candidate that will
|
|
217
|
+
// claim it as parent.
|
|
214
218
|
candidates.sort((a, b) => {
|
|
215
219
|
if (a.range.startLine !== b.range.startLine)
|
|
216
220
|
return a.range.startLine - b.range.startLine;
|
|
@@ -218,13 +222,23 @@ function pass1BuildScopes(matches, filePath, provider) {
|
|
|
218
222
|
return a.range.startCol - b.range.startCol;
|
|
219
223
|
if (a.range.endLine !== b.range.endLine)
|
|
220
224
|
return b.range.endLine - a.range.endLine;
|
|
221
|
-
|
|
225
|
+
if (a.range.endCol !== b.range.endCol)
|
|
226
|
+
return b.range.endCol - a.range.endCol;
|
|
227
|
+
if (a.kind === b.kind)
|
|
228
|
+
return 0;
|
|
229
|
+
if (a.kind === 'Module')
|
|
230
|
+
return -1;
|
|
231
|
+
if (b.kind === 'Module')
|
|
232
|
+
return 1;
|
|
233
|
+
return 0;
|
|
222
234
|
});
|
|
223
235
|
const drafts = [];
|
|
224
236
|
const stack = []; // enclosing real scopes, outermost at [0]
|
|
225
237
|
for (const cand of candidates) {
|
|
226
|
-
// Pop the stack until the top
|
|
227
|
-
|
|
238
|
+
// Pop the stack until the top can parent this candidate (strict
|
|
239
|
+
// containment, plus the equal-range Module carve-out).
|
|
240
|
+
while (stack.length > 0 &&
|
|
241
|
+
!canParentScope(stack[stack.length - 1].range, cand.range, stack[stack.length - 1].kind, cand.kind)) {
|
|
228
242
|
stack.pop();
|
|
229
243
|
}
|
|
230
244
|
const parent = stack.length > 0 ? stack[stack.length - 1].id : null;
|
|
@@ -692,19 +706,6 @@ function rangesEqual(a, b) {
|
|
|
692
706
|
a.endLine === b.endLine &&
|
|
693
707
|
a.endCol === b.endCol);
|
|
694
708
|
}
|
|
695
|
-
function rangeStrictlyContains(outer, inner) {
|
|
696
|
-
if (outer.startLine === inner.startLine &&
|
|
697
|
-
outer.startCol === inner.startCol &&
|
|
698
|
-
outer.endLine === inner.endLine &&
|
|
699
|
-
outer.endCol === inner.endCol) {
|
|
700
|
-
return false;
|
|
701
|
-
}
|
|
702
|
-
const startsBefore = outer.startLine < inner.startLine ||
|
|
703
|
-
(outer.startLine === inner.startLine && outer.startCol <= inner.startCol);
|
|
704
|
-
const endsAfter = outer.endLine > inner.endLine ||
|
|
705
|
-
(outer.endLine === inner.endLine && outer.endCol >= inner.endCol);
|
|
706
|
-
return startsBefore && endsAfter;
|
|
707
|
-
}
|
|
708
709
|
/**
|
|
709
710
|
* Capture names that are never anchors — they are sub-tags nested inside a
|
|
710
711
|
* larger anchor (e.g., the receiver expression inside a `@reference.call`
|
|
@@ -88,14 +88,21 @@
|
|
|
88
88
|
* per-(caller, target) collapse semantics require multiple call
|
|
89
89
|
* sites in the same caller body not produce multiple edges.
|
|
90
90
|
*
|
|
91
|
-
* - **I3 — `propagateImportedReturnTypes` mutation timing.**
|
|
92
|
-
* pass mutates `Scope.typeBindings` (a plain `new Map(...)` from
|
|
91
|
+
* - **I3 — `propagateImportedReturnTypes` mutation timing + ordering.**
|
|
92
|
+
* The pass mutates `Scope.typeBindings` (a plain `new Map(...)` from
|
|
93
93
|
* `draftToScope`, NOT frozen). It MUST run AFTER `finalizeScopeModel`
|
|
94
94
|
* (so `indexes.bindings` is populated) and BEFORE
|
|
95
95
|
* `resolveReferenceSites` (so resolution sees the propagated types).
|
|
96
96
|
* The pass also re-runs `followChainPostFinalize` on every scope's
|
|
97
97
|
* typeBindings because scope-extractor's pass-4 already ran and
|
|
98
98
|
* missed any chain whose terminal lives in a foreign file.
|
|
99
|
+
* Within the pass, files are walked in `indexes.sccs` reverse-
|
|
100
|
+
* topological order (leaves first) so multi-hop alias chains
|
|
101
|
+
* (e.g. `models.User → service.user → app.user`) collapse to the
|
|
102
|
+
* terminal class in a single pass — every importer sees its
|
|
103
|
+
* source's already-chain-followed typeBindings. Cyclic SCCs reach
|
|
104
|
+
* a partial fixpoint within a single pass without iterating to
|
|
105
|
+
* convergence; `ts-circular` only asserts pipeline-no-throw.
|
|
99
106
|
*
|
|
100
107
|
* - **I4 — `emitReceiverBoundCalls` case order.** Cases are evaluated
|
|
101
108
|
* in this order; the FIRST that emits an edge wins:
|
|
@@ -129,14 +136,45 @@
|
|
|
129
136
|
* once per workspace at resolve time), and merging would create a
|
|
130
137
|
* god-interface that complicates future migrations.
|
|
131
138
|
*
|
|
132
|
-
* - **I8 —
|
|
133
|
-
* `indexes.bindings
|
|
134
|
-
* `
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
139
|
+
* - **I8 — Two-channel binding lifecycle.**
|
|
140
|
+
* `indexes.bindings` is the **finalize-output channel**. After
|
|
141
|
+
* `finalizeScopeModel` returns, its inner `BindingRef[]` arrays
|
|
142
|
+
* are deep-frozen by `materializeBindings` and MUST NOT be
|
|
143
|
+
* mutated by any post-finalize hook. Treat `indexes.bindings` as
|
|
144
|
+
* immutable from the moment `finalizeScopeModel` returns.
|
|
145
|
+
*
|
|
146
|
+
* `indexes.bindingAugmentations` is the **post-finalize
|
|
147
|
+
* append-only channel**. Hooks like `populateNamespaceSiblings`
|
|
148
|
+
* append cross-file bindings synthesized after finalize (C#
|
|
149
|
+
* same-namespace visibility, `using static` member exposure)
|
|
150
|
+
* into this channel, NOT into `indexes.bindings`. Inner arrays
|
|
151
|
+
* here are NEVER frozen — hooks `push()` directly. Any consumer
|
|
152
|
+
* that reads post-finalize workspace bindings MUST query both
|
|
153
|
+
* index channels via `lookupBindingsAt`
|
|
154
|
+
* (`scope-resolution/scope/walkers.ts`); the helper returns
|
|
155
|
+
* finalized refs first, appends unique augmentation refs after,
|
|
156
|
+
* and dedupes by `def.nodeId` so finalized metadata wins on
|
|
157
|
+
* duplicate defs. Per-`Scope.bindings` local declarations are the
|
|
158
|
+
* lexical extraction channel and remain a separate first-tier
|
|
159
|
+
* lookup for local shadowing.
|
|
160
|
+
*
|
|
161
|
+
* `Scope.typeBindings` remains mutable post-finalize per I6 (it
|
|
162
|
+
* is intentionally not frozen at any point).
|
|
163
|
+
*
|
|
164
|
+
* The `ReadonlyMap<...>` types on `ScopeResolutionIndexes` are
|
|
165
|
+
* compile-time read-guidance for consumers; structural mutation
|
|
166
|
+
* of `bindingAugmentations` is performed via a deliberate
|
|
167
|
+
* `as Map<...>` cast inside the hook implementations and is the
|
|
168
|
+
* ONLY sanctioned channel for post-finalize binding fanout.
|
|
169
|
+
*
|
|
170
|
+
* The dev-mode runtime validator
|
|
171
|
+
* (`validateBindingsImmutability` in
|
|
172
|
+
* `scope-resolution/validate-bindings-immutability.ts`) surfaces
|
|
173
|
+
* any drift — i.e. a hook writing to `indexes.bindings` instead
|
|
174
|
+
* of `bindingAugmentations`, or producing a non-frozen finalized
|
|
175
|
+
* bucket — via `onWarn` when explicitly enabled by
|
|
176
|
+
* `NODE_ENV === 'development' || VALIDATE_SEMANTIC_MODEL === '1'`
|
|
177
|
+
* (`VALIDATE_SEMANTIC_MODEL=0` is an explicit off switch).
|
|
140
178
|
*
|
|
141
179
|
* - **I9 — `SemanticModel` is the single authoritative symbol store.**
|
|
142
180
|
* Every symbol-indexed lookup (key = `nodeId | simpleName |
|
|
@@ -244,8 +282,32 @@ export interface ScopeResolver {
|
|
|
244
282
|
* resolvers that must distinguish "this module exists in the repo"
|
|
245
283
|
* from "this module is external" (Python's fallback resolver, for
|
|
246
284
|
* example).
|
|
285
|
+
*
|
|
286
|
+
* `resolutionConfig` is the opaque value returned by
|
|
287
|
+
* `loadResolutionConfig` (loaded once per workspace pass by the
|
|
288
|
+
* orchestrator). TypeScript uses this to thread `tsconfig.json` path
|
|
289
|
+
* aliases through to the standard resolver. Languages that don't
|
|
290
|
+
* need any extra config ignore the parameter.
|
|
291
|
+
*/
|
|
292
|
+
resolveImportTarget(targetRaw: string, fromFile: string, allFilePaths: ReadonlySet<string>, resolutionConfig?: unknown): string | null;
|
|
293
|
+
/**
|
|
294
|
+
* Optional one-shot loader for cross-file import-resolution config
|
|
295
|
+
* (e.g. tsconfig path aliases for TypeScript, go.mod paths for Go,
|
|
296
|
+
* composer.json autoload for PHP). The orchestrator calls this once
|
|
297
|
+
* per workspace pass with the repo root and threads the result into
|
|
298
|
+
* every subsequent `resolveImportTarget` call as the
|
|
299
|
+
* `resolutionConfig` parameter.
|
|
300
|
+
*
|
|
301
|
+
* Languages that don't need any per-workspace config leave this
|
|
302
|
+
* undefined; the orchestrator threads `undefined` to
|
|
303
|
+
* `resolveImportTarget` in that case. Returning `null` is also
|
|
304
|
+
* supported and equivalent to "no config available".
|
|
305
|
+
*
|
|
306
|
+
* May be sync or async — the orchestrator awaits the result. The
|
|
307
|
+
* shape is opaque to the orchestrator (`unknown`); the per-language
|
|
308
|
+
* `resolveImportTarget` casts it to the language's expected shape.
|
|
247
309
|
*/
|
|
248
|
-
|
|
310
|
+
loadResolutionConfig?(repoPath: string): Promise<unknown> | unknown;
|
|
249
311
|
/**
|
|
250
312
|
* Per-scope binding-merge precedence. The shared finalize pass
|
|
251
313
|
* collects bindings from multiple sources (local declarations,
|
|
@@ -88,14 +88,21 @@
|
|
|
88
88
|
* per-(caller, target) collapse semantics require multiple call
|
|
89
89
|
* sites in the same caller body not produce multiple edges.
|
|
90
90
|
*
|
|
91
|
-
* - **I3 — `propagateImportedReturnTypes` mutation timing.**
|
|
92
|
-
* pass mutates `Scope.typeBindings` (a plain `new Map(...)` from
|
|
91
|
+
* - **I3 — `propagateImportedReturnTypes` mutation timing + ordering.**
|
|
92
|
+
* The pass mutates `Scope.typeBindings` (a plain `new Map(...)` from
|
|
93
93
|
* `draftToScope`, NOT frozen). It MUST run AFTER `finalizeScopeModel`
|
|
94
94
|
* (so `indexes.bindings` is populated) and BEFORE
|
|
95
95
|
* `resolveReferenceSites` (so resolution sees the propagated types).
|
|
96
96
|
* The pass also re-runs `followChainPostFinalize` on every scope's
|
|
97
97
|
* typeBindings because scope-extractor's pass-4 already ran and
|
|
98
98
|
* missed any chain whose terminal lives in a foreign file.
|
|
99
|
+
* Within the pass, files are walked in `indexes.sccs` reverse-
|
|
100
|
+
* topological order (leaves first) so multi-hop alias chains
|
|
101
|
+
* (e.g. `models.User → service.user → app.user`) collapse to the
|
|
102
|
+
* terminal class in a single pass — every importer sees its
|
|
103
|
+
* source's already-chain-followed typeBindings. Cyclic SCCs reach
|
|
104
|
+
* a partial fixpoint within a single pass without iterating to
|
|
105
|
+
* convergence; `ts-circular` only asserts pipeline-no-throw.
|
|
99
106
|
*
|
|
100
107
|
* - **I4 — `emitReceiverBoundCalls` case order.** Cases are evaluated
|
|
101
108
|
* in this order; the FIRST that emits an edge wins:
|
|
@@ -129,14 +136,45 @@
|
|
|
129
136
|
* once per workspace at resolve time), and merging would create a
|
|
130
137
|
* god-interface that complicates future migrations.
|
|
131
138
|
*
|
|
132
|
-
* - **I8 —
|
|
133
|
-
* `indexes.bindings
|
|
134
|
-
* `
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
139
|
+
* - **I8 — Two-channel binding lifecycle.**
|
|
140
|
+
* `indexes.bindings` is the **finalize-output channel**. After
|
|
141
|
+
* `finalizeScopeModel` returns, its inner `BindingRef[]` arrays
|
|
142
|
+
* are deep-frozen by `materializeBindings` and MUST NOT be
|
|
143
|
+
* mutated by any post-finalize hook. Treat `indexes.bindings` as
|
|
144
|
+
* immutable from the moment `finalizeScopeModel` returns.
|
|
145
|
+
*
|
|
146
|
+
* `indexes.bindingAugmentations` is the **post-finalize
|
|
147
|
+
* append-only channel**. Hooks like `populateNamespaceSiblings`
|
|
148
|
+
* append cross-file bindings synthesized after finalize (C#
|
|
149
|
+
* same-namespace visibility, `using static` member exposure)
|
|
150
|
+
* into this channel, NOT into `indexes.bindings`. Inner arrays
|
|
151
|
+
* here are NEVER frozen — hooks `push()` directly. Any consumer
|
|
152
|
+
* that reads post-finalize workspace bindings MUST query both
|
|
153
|
+
* index channels via `lookupBindingsAt`
|
|
154
|
+
* (`scope-resolution/scope/walkers.ts`); the helper returns
|
|
155
|
+
* finalized refs first, appends unique augmentation refs after,
|
|
156
|
+
* and dedupes by `def.nodeId` so finalized metadata wins on
|
|
157
|
+
* duplicate defs. Per-`Scope.bindings` local declarations are the
|
|
158
|
+
* lexical extraction channel and remain a separate first-tier
|
|
159
|
+
* lookup for local shadowing.
|
|
160
|
+
*
|
|
161
|
+
* `Scope.typeBindings` remains mutable post-finalize per I6 (it
|
|
162
|
+
* is intentionally not frozen at any point).
|
|
163
|
+
*
|
|
164
|
+
* The `ReadonlyMap<...>` types on `ScopeResolutionIndexes` are
|
|
165
|
+
* compile-time read-guidance for consumers; structural mutation
|
|
166
|
+
* of `bindingAugmentations` is performed via a deliberate
|
|
167
|
+
* `as Map<...>` cast inside the hook implementations and is the
|
|
168
|
+
* ONLY sanctioned channel for post-finalize binding fanout.
|
|
169
|
+
*
|
|
170
|
+
* The dev-mode runtime validator
|
|
171
|
+
* (`validateBindingsImmutability` in
|
|
172
|
+
* `scope-resolution/validate-bindings-immutability.ts`) surfaces
|
|
173
|
+
* any drift — i.e. a hook writing to `indexes.bindings` instead
|
|
174
|
+
* of `bindingAugmentations`, or producing a non-frozen finalized
|
|
175
|
+
* bucket — via `onWarn` when explicitly enabled by
|
|
176
|
+
* `NODE_ENV === 'development' || VALIDATE_SEMANTIC_MODEL === '1'`
|
|
177
|
+
* (`VALIDATE_SEMANTIC_MODEL=0` is an explicit off switch).
|
|
140
178
|
*
|
|
141
179
|
* - **I9 — `SemanticModel` is the single authoritative symbol store.**
|
|
142
180
|
* Every symbol-indexed lookup (key = `nodeId | simpleName |
|