gitnexus 1.6.5-rc.8 → 1.6.5
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/dist/_shared/scope-resolution/finalize-algorithm.js +10 -2
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +26 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/method-dispatch-index.js +22 -3
- package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +18 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +2 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +70 -16
- package/dist/cli/analyze.d.ts +30 -2
- package/dist/cli/analyze.js +45 -5
- package/dist/cli/index.js +8 -1
- package/dist/cli/setup.js +18 -0
- package/dist/cli/wiki.d.ts +2 -0
- package/dist/cli/wiki.js +11 -0
- package/dist/core/augmentation/engine.js +24 -4
- package/dist/core/embeddings/http-client.js +22 -6
- package/dist/core/incremental/shadow-candidates.d.ts +44 -0
- package/dist/core/incremental/shadow-candidates.js +74 -0
- package/dist/core/incremental/subgraph-extract.d.ts +64 -0
- package/dist/core/incremental/subgraph-extract.js +111 -0
- package/dist/core/ingestion/call-processor.d.ts +12 -1
- package/dist/core/ingestion/call-processor.js +183 -47
- package/dist/core/ingestion/class-extractors/configs/c-cpp.js +38 -0
- package/dist/core/ingestion/class-extractors/generic.js +8 -0
- package/dist/core/ingestion/class-types.d.ts +15 -0
- package/dist/core/ingestion/community-processor.js +18 -0
- package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
- package/dist/core/ingestion/import-resolvers/standard.js +31 -1
- package/dist/core/ingestion/import-resolvers/utils.js +4 -0
- package/dist/core/ingestion/languages/c-cpp.js +20 -2
- package/dist/core/ingestion/languages/cpp/adl.d.ts +141 -0
- package/dist/core/ingestion/languages/cpp/adl.js +478 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.d.ts +18 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.js +170 -0
- package/dist/core/ingestion/languages/cpp/arity.d.ts +17 -0
- package/dist/core/ingestion/languages/cpp/arity.js +31 -0
- package/dist/core/ingestion/languages/cpp/captures.d.ts +2 -0
- package/dist/core/ingestion/languages/cpp/captures.js +1131 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +31 -0
- package/dist/core/ingestion/languages/cpp/conversion-rank.js +47 -0
- package/dist/core/ingestion/languages/cpp/file-local-linkage.d.ts +118 -0
- package/dist/core/ingestion/languages/cpp/file-local-linkage.js +266 -0
- package/dist/core/ingestion/languages/cpp/header-scan.d.ts +8 -0
- package/dist/core/ingestion/languages/cpp/header-scan.js +50 -0
- package/dist/core/ingestion/languages/cpp/import-decomposer.d.ts +19 -0
- package/dist/core/ingestion/languages/cpp/import-decomposer.js +111 -0
- package/dist/core/ingestion/languages/cpp/import-target.d.ts +10 -0
- package/dist/core/ingestion/languages/cpp/import-target.js +13 -0
- package/dist/core/ingestion/languages/cpp/index.d.ts +11 -0
- package/dist/core/ingestion/languages/cpp/index.js +11 -0
- package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +67 -0
- package/dist/core/ingestion/languages/cpp/inline-namespaces.js +176 -0
- package/dist/core/ingestion/languages/cpp/interpret.d.ts +35 -0
- package/dist/core/ingestion/languages/cpp/interpret.js +113 -0
- package/dist/core/ingestion/languages/cpp/merge-bindings.d.ts +13 -0
- package/dist/core/ingestion/languages/cpp/merge-bindings.js +29 -0
- package/dist/core/ingestion/languages/cpp/query.d.ts +3 -0
- package/dist/core/ingestion/languages/cpp/query.js +508 -0
- package/dist/core/ingestion/languages/cpp/range-bindings.d.ts +20 -0
- package/dist/core/ingestion/languages/cpp/range-bindings.js +212 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.d.ts +17 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +246 -0
- package/dist/core/ingestion/languages/cpp/simple-hooks.d.ts +24 -0
- package/dist/core/ingestion/languages/cpp/simple-hooks.js +62 -0
- package/dist/core/ingestion/languages/cpp/two-phase-lookup.d.ts +76 -0
- package/dist/core/ingestion/languages/cpp/two-phase-lookup.js +195 -0
- package/dist/core/ingestion/languages/java/arity-metadata.d.ts +18 -0
- package/dist/core/ingestion/languages/java/arity-metadata.js +40 -0
- package/dist/core/ingestion/languages/java/arity.d.ts +10 -0
- package/dist/core/ingestion/languages/java/arity.js +24 -0
- package/dist/core/ingestion/languages/java/cache-stats.d.ts +15 -0
- package/dist/core/ingestion/languages/java/cache-stats.js +26 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +17 -0
- package/dist/core/ingestion/languages/java/captures.js +187 -0
- package/dist/core/ingestion/languages/java/import-decomposer.d.ts +18 -0
- package/dist/core/ingestion/languages/java/import-decomposer.js +85 -0
- package/dist/core/ingestion/languages/java/import-target.d.ts +17 -0
- package/dist/core/ingestion/languages/java/import-target.js +100 -0
- package/dist/core/ingestion/languages/java/index.d.ts +29 -0
- package/dist/core/ingestion/languages/java/index.js +29 -0
- package/dist/core/ingestion/languages/java/interpret.d.ts +13 -0
- package/dist/core/ingestion/languages/java/interpret.js +131 -0
- package/dist/core/ingestion/languages/java/merge-bindings.d.ts +12 -0
- package/dist/core/ingestion/languages/java/merge-bindings.js +40 -0
- package/dist/core/ingestion/languages/java/query.d.ts +30 -0
- package/dist/core/ingestion/languages/java/query.js +192 -0
- package/dist/core/ingestion/languages/java/receiver-binding.d.ts +11 -0
- package/dist/core/ingestion/languages/java/receiver-binding.js +95 -0
- package/dist/core/ingestion/languages/java/scope-resolver.d.ts +50 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +74 -0
- package/dist/core/ingestion/languages/java/simple-hooks.d.ts +13 -0
- package/dist/core/ingestion/languages/java/simple-hooks.js +34 -0
- package/dist/core/ingestion/languages/java.js +11 -0
- package/dist/core/ingestion/languages/php/arity-metadata.d.ts +28 -0
- package/dist/core/ingestion/languages/php/arity-metadata.js +63 -0
- package/dist/core/ingestion/languages/php/arity.d.ts +25 -0
- package/dist/core/ingestion/languages/php/arity.js +40 -0
- package/dist/core/ingestion/languages/php/cache-stats.d.ts +15 -0
- package/dist/core/ingestion/languages/php/cache-stats.js +26 -0
- package/dist/core/ingestion/languages/php/captures.d.ts +34 -0
- package/dist/core/ingestion/languages/php/captures.js +739 -0
- package/dist/core/ingestion/languages/php/import-decomposer.d.ts +28 -0
- package/dist/core/ingestion/languages/php/import-decomposer.js +265 -0
- package/dist/core/ingestion/languages/php/import-target.d.ts +47 -0
- package/dist/core/ingestion/languages/php/import-target.js +100 -0
- package/dist/core/ingestion/languages/php/index.d.ts +68 -0
- package/dist/core/ingestion/languages/php/index.js +72 -0
- package/dist/core/ingestion/languages/php/interpret.d.ts +36 -0
- package/dist/core/ingestion/languages/php/interpret.js +241 -0
- package/dist/core/ingestion/languages/php/merge-bindings.d.ts +19 -0
- package/dist/core/ingestion/languages/php/merge-bindings.js +47 -0
- package/dist/core/ingestion/languages/php/namespace-siblings.d.ts +51 -0
- package/dist/core/ingestion/languages/php/namespace-siblings.js +288 -0
- package/dist/core/ingestion/languages/php/query.d.ts +32 -0
- package/dist/core/ingestion/languages/php/query.js +326 -0
- package/dist/core/ingestion/languages/php/receiver-binding.d.ts +36 -0
- package/dist/core/ingestion/languages/php/receiver-binding.js +128 -0
- package/dist/core/ingestion/languages/php/scope-resolver.d.ts +23 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +358 -0
- package/dist/core/ingestion/languages/php/simple-hooks.d.ts +42 -0
- package/dist/core/ingestion/languages/php/simple-hooks.js +111 -0
- package/dist/core/ingestion/languages/php.d.ts +0 -7
- package/dist/core/ingestion/languages/php.js +15 -0
- package/dist/core/ingestion/markdown-processor.js +6 -1
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
- package/dist/core/ingestion/model/symbol-table.js +3 -0
- package/dist/core/ingestion/parsing-processor.d.ts +22 -2
- package/dist/core/ingestion/parsing-processor.js +123 -50
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +54 -2
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +5 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +119 -11
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +14 -0
- package/dist/core/ingestion/pipeline.d.ts +13 -0
- package/dist/core/ingestion/registry-primary-flag.js +2 -0
- package/dist/core/ingestion/scope-extractor.js +4 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +167 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +3 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +1 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +12 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.d.ts +1 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +12 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +16 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +36 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +204 -13
- package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +1 -1
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +55 -4
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +186 -5
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +10 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +207 -9
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +13 -1
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +6 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +17 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +86 -8
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +30 -0
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +90 -8
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +23 -0
- package/dist/core/ingestion/utils/ast-helpers.js +6 -1
- package/dist/core/ingestion/utils/template-arguments.d.ts +11 -0
- package/dist/core/ingestion/utils/template-arguments.js +65 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +3 -0
- package/dist/core/ingestion/workers/parse-worker.js +42 -1
- package/dist/core/lbug/lbug-adapter.d.ts +39 -0
- package/dist/core/lbug/lbug-adapter.js +348 -48
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +323 -29
- package/dist/core/search/hybrid-search.d.ts +3 -0
- package/dist/core/search/hybrid-search.js +23 -6
- package/dist/core/wiki/generator.js +4 -3
- package/dist/core/wiki/html-viewer.js +2 -1
- package/dist/core/wiki/llm-client.d.ts +4 -0
- package/dist/core/wiki/llm-client.js +3 -3
- package/dist/core/wiki/mermaid-sanitizer.d.ts +2 -0
- package/dist/core/wiki/mermaid-sanitizer.js +100 -0
- package/dist/mcp/local/local-backend.js +20 -7
- package/dist/storage/file-hash.d.ts +47 -0
- package/dist/storage/file-hash.js +86 -0
- package/dist/storage/parse-cache.d.ts +73 -0
- package/dist/storage/parse-cache.js +253 -0
- package/dist/storage/repo-manager.d.ts +41 -1
- package/dist/storage/repo-manager.js +61 -6
- package/hooks/claude/gitnexus-hook.cjs +42 -4
- package/hooks/claude/hook-db-lock-probe.cjs +238 -0
- package/hooks/claude/hook-lock.cjs +119 -0
- package/hooks/claude/win-rm-list-json.ps1 +76 -0
- package/package.json +1 -1
- package/scripts/build.js +6 -2
- package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +16 -16
- package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +16 -16
- package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +16 -16
- package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +16 -16
- package/web/assets/{agent-BpHQleHE.js → agent-D2kLt6Dl.js} +91 -91
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-DvIkEGkp.js +36 -0
- package/web/assets/blockDiagram-7IZFK4PR-B4niSLvR.js +132 -0
- package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-DIzEXalR.js} +6 -6
- package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +1 -0
- package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-BzGeeheI.js} +1 -1
- package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +159 -0
- package/web/assets/chunk-5IMINLNL-CnTLsXIV.js +1 -0
- package/web/assets/chunk-5VCL7Z4A-w1BCx98Z.js +1 -0
- package/web/assets/chunk-6764PJDD-ChwMM2z4.js +1 -0
- package/web/assets/chunk-67TQ5CYL-CChC2cAv.js +124 -0
- package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +10 -0
- package/web/assets/chunk-7W6UQGC5-CgFyfZ6k.js +1 -0
- package/web/assets/chunk-AQ6EADP3-CCFje6lL.js +1 -0
- package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-5E9ARdDQ.js} +1 -1
- package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +1 -0
- package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +1 -0
- package/web/assets/chunk-INKRHTLW-ELpfuk9h.js +70 -0
- package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +1 -0
- package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-Dcq_Qnyy.js} +1 -1
- package/web/assets/chunk-KGFNY3KK-W-VR57xb.js +62 -0
- package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +1 -0
- package/web/assets/chunk-KNLZD3CH-BuZBOcso.js +1 -0
- package/web/assets/chunk-KRXBNO2N-DH2NPM7I.js +1 -0
- package/web/assets/chunk-LCXTWHL2-CqJ0oo1x.js +231 -0
- package/web/assets/chunk-LII3EMHJ-3X33tCpU.js +1 -0
- package/web/assets/chunk-QA3QBVWF-D5Ha3GgB.js +2 -0
- package/web/assets/chunk-RERM46MO-DQNbXtfw.js +1 -0
- package/web/assets/chunk-RG4AUYOV-D0M6vdq9.js +206 -0
- package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +1 -0
- package/web/assets/chunk-T2UQINTJ-kGYG7ppP.js +1 -0
- package/web/assets/chunk-T5OCTHI4--9wWpVws.js +1 -0
- package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +1 -0
- package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +1 -0
- package/web/assets/chunk-UY5QBCOK-Du-c56gs.js +1 -0
- package/web/assets/chunk-W44A43WB-lrCpuupA.js +1 -0
- package/web/assets/chunk-ZXARS5L4-CSZRiyOf.js +1 -0
- package/web/assets/classDiagram-KGZ6W3CR-BB-saqC1.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-Bp2bAlS5.js +1 -0
- package/web/assets/cose-bilkent-UX7MHV2Q-BHv2bbtl.js +1 -0
- package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +4 -0
- package/web/assets/diagram-3NCE3AQN-BUxnDPOY.js +43 -0
- package/web/assets/diagram-GF46GFSD-BJTyqqvI.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-fUWreZzx.js +3 -0
- package/web/assets/diagram-QXG6HAR7-DilMHamP.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-8KUrarg1.js +10 -0
- package/web/assets/erDiagram-L5TCEMPS-Doj9mSiW.js +85 -0
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +1 -0
- package/web/assets/{flowDiagram-OTCZ4VVT-aAZw4c_M.js → flowDiagram-H6V6AXG4-BOSR-i3p.js} +12 -12
- package/web/assets/ganttDiagram-JCBTUEKG-BHQssTz6.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +106 -0
- package/web/assets/index-j4-NuleT.js +623 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-Ce_TvtaV.js +2 -0
- package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js} +6 -6
- package/web/assets/journeyDiagram-M6C3CM3L-DNPYCpvq.js +139 -0
- package/web/assets/kanban-definition-75IXJCU3-yYdfm8Kk.js +89 -0
- package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CrVLz8l7.js} +1 -1
- package/web/assets/mindmap-definition-2TDM6QVE-DFNEKM77.js +96 -0
- package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-iZAqpvhd.js +30 -0
- package/web/assets/quadrantDiagram-VICAPDV7-bAm6Hi_5.js +7 -0
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +1 -0
- package/web/assets/requirementDiagram-JXO7QTGE-CtDijhnf.js +84 -0
- package/web/assets/sankeyDiagram-URQDO5SZ-LFJz53u5.js +40 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-BdjvyCHM.js +162 -0
- package/web/assets/stateDiagram-7D4R322I-e5odN9fG.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-vPsvjR2D.js +1 -0
- package/web/assets/timeline-definition-O6YCAMPW-DPAksNQp.js +120 -0
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +1 -0
- package/web/assets/vennDiagram-MWXL3ELB-Dtlfdt7J.js +34 -0
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-B23uRMUC.js +78 -0
- package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DxwHeksW.js} +6 -6
- package/web/index.html +13 -2
- package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BUzkWgDl.js +0 -1
- package/web/assets/architectureDiagram-EMZXCZ2Q-CXbzok1G.js +0 -36
- package/web/assets/blockDiagram-IGV67L2C-DA1QJ4ZB.js +0 -132
- package/web/assets/chunk-3GS5O3IE-B8hpnia8.js +0 -231
- package/web/assets/chunk-3YCYZ6SJ-B-BVu21C.js +0 -1
- package/web/assets/chunk-6NTNNK5N-DW-jYSDr.js +0 -1
- package/web/assets/chunk-A34GCYZU-BbZl-IKy.js +0 -1
- package/web/assets/chunk-DJ7UZH7F-B5tMfF87.js +0 -1
- package/web/assets/chunk-DKKBVRCY-Djm-6K_e.js +0 -4
- package/web/assets/chunk-DU5LTGQ6-QPoynYcp.js +0 -1
- package/web/assets/chunk-FXACKDTF-jieSmbe2.js +0 -159
- package/web/assets/chunk-H3VCZNTA-8EMHZ3SV.js +0 -1
- package/web/assets/chunk-HN6EAY2L-CgE_agsD.js +0 -1
- package/web/assets/chunk-O5ABG6QK-DEZV1O19.js +0 -1
- package/web/assets/chunk-PK6DOVAG-BXv0JnsJ.js +0 -206
- package/web/assets/chunk-RNJOYNJ4-BiBkF9dN.js +0 -1
- package/web/assets/chunk-RWUO3TPN-DTWzAhQ1.js +0 -1
- package/web/assets/chunk-TBF5ZNIQ-BSl6s9lT.js +0 -1
- package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +0 -1
- package/web/assets/chunk-TYMNRAUI-D1NDLIMG.js +0 -1
- package/web/assets/chunk-VELTKBKT-C9dVN39o.js +0 -1
- package/web/assets/chunk-W7ZLLLMY-Bu-cdLzs.js +0 -1
- package/web/assets/chunk-WSB5WSVC-Dor71SOz.js +0 -1
- package/web/assets/chunk-XGPFEOL4-CUonLRle.js +0 -1
- package/web/assets/classDiagram-PPOCWD7C-Cdd6UdVv.js +0 -1
- package/web/assets/classDiagram-v2-23LJLIIU-DNhxY2Ib.js +0 -1
- package/web/assets/cose-bilkent-PNC4W37J-DdZq7Qz_.js +0 -1
- package/web/assets/dagre-E77IOHMT-Cfj_6e17.js +0 -4
- package/web/assets/diagram-H7BISOXX-BNvpsrBv.js +0 -43
- package/web/assets/diagram-JC5VWROH-Cn0rtDbJ.js +0 -24
- package/web/assets/diagram-LXUTUG65-CHfoVKNm.js +0 -10
- package/web/assets/diagram-WEHSV5V5-BLxHksnu.js +0 -24
- package/web/assets/erDiagram-GCSMX5X6-DfdN6iqF.js +0 -85
- package/web/assets/ganttDiagram-MUNLMDZQ-BEfC_7Or.js +0 -292
- package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-B6ZeRLP0.js +0 -1
- package/web/assets/gitGraphDiagram-3HKGZ4G3-CG0kC8Q5.js +0 -106
- package/web/assets/index-3NUCUW2s.js +0 -886
- package/web/assets/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
- package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
- package/web/assets/journeyDiagram-SO5T7YLQ-BW8oKa3N.js +0 -139
- package/web/assets/kanban-definition-LJHFXRCJ-DzbOsR-2.js +0 -89
- package/web/assets/mindmap-definition-2EUWGEK5-BIXGQALq.js +0 -96
- package/web/assets/packet-4T2RLAQJ-EV4IVRXR-Bs7ysNMU.js +0 -1
- package/web/assets/pie-ZZUOXDRM-N23DN5KN-Csi8nnbH.js +0 -1
- package/web/assets/pieDiagram-3IATQBI2-QY-u7P6a.js +0 -30
- package/web/assets/quadrantDiagram-E256RVCF-Di4aNiU8.js +0 -7
- package/web/assets/radar-PYXPWWZC-P6TP7ZYP-DJlyXh2-.js +0 -1
- package/web/assets/requirementDiagram-M5DCFWZL-CzUUrhQD.js +0 -84
- package/web/assets/sankeyDiagram-L3NBLAOT-D2fbMiIU.js +0 -10
- package/web/assets/sequenceDiagram-ZOUHS735-BNdkqguh.js +0 -157
- package/web/assets/stateDiagram-MLPALWAM-51_Q2w2L.js +0 -1
- package/web/assets/stateDiagram-v2-B5LQ5ZB2-8nHs2aNE.js +0 -1
- package/web/assets/timeline-definition-5SPVSISX-DkMiGj4Z.js +0 -120
- package/web/assets/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
- package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
- package/web/assets/vennDiagram-IE5QUKF5-BCxMmf9q.js +0 -34
- package/web/assets/wardley-RL74JXVD-BCRCBASE-CMStJhpn.js +0 -1
- package/web/assets/wardleyDiagram-XU3VSMPF-ijlLF77s.js +0 -20
- /package/web/assets/{context-builder-CqQNhRj1.js → context-builder-_HS0v2ma.js} +0 -0
|
@@ -11,40 +11,24 @@ import { getDefinitionNodeFromCaptures, findEnclosingClassInfo, getLabelFromCapt
|
|
|
11
11
|
import { detectFrameworkFromAST } from './framework-detection.js';
|
|
12
12
|
import { buildTypeEnv } from './type-env.js';
|
|
13
13
|
import { buildMethodProps, arityForIdFromInfo, typeTagForId, constTagForId, buildCollisionGroups, } from './utils/method-props.js';
|
|
14
|
+
import { extractTemplateArguments, templateArgumentsIdTag } from './utils/template-arguments.js';
|
|
14
15
|
import { logger } from '../logger.js';
|
|
15
16
|
import { getTreeSitterBufferSize, getTreeSitterContentByteLength, TREE_SITTER_MAX_BUFFER, } from './constants.js';
|
|
16
17
|
// ============================================================================
|
|
17
18
|
// Worker-based parallel parsing
|
|
18
19
|
// ============================================================================
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
assignments: [],
|
|
32
|
-
heritage: [],
|
|
33
|
-
routes: [],
|
|
34
|
-
fetchCalls: [],
|
|
35
|
-
decoratorRoutes: [],
|
|
36
|
-
toolDefs: [],
|
|
37
|
-
ormQueries: [],
|
|
38
|
-
constructorBindings: [],
|
|
39
|
-
fileScopeBindings: [],
|
|
40
|
-
parsedFiles: [],
|
|
41
|
-
};
|
|
42
|
-
const total = files.length;
|
|
43
|
-
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
44
|
-
const chunkResults = await workerPool.dispatch(parseableFiles, (filesProcessed) => {
|
|
45
|
-
onFileProgress?.(Math.min(filesProcessed, total), total, 'Parsing...');
|
|
46
|
-
});
|
|
47
|
-
// Merge results from all workers into graph and symbol table
|
|
20
|
+
/**
|
|
21
|
+
* Merge a list of `ParseWorkerResult`s into the running graph + symbol
|
|
22
|
+
* table state and produce the chunk-aggregated `WorkerExtractedData`.
|
|
23
|
+
*
|
|
24
|
+
* Extracted from `processParsingWithWorkers` so the same merge logic can
|
|
25
|
+
* be applied to both freshly-parsed worker output AND cached worker
|
|
26
|
+
* output replayed during incremental analyze. Idempotent on the
|
|
27
|
+
* accumulator fields (push-only); idempotent on graph if the caller
|
|
28
|
+
* starts from a clean graph (otherwise duplicate `addNode` calls are
|
|
29
|
+
* silently no-op'd by `KnowledgeGraph`).
|
|
30
|
+
*/
|
|
31
|
+
export const mergeChunkResults = (graph, symbolTable, chunkResults) => {
|
|
48
32
|
const allImports = [];
|
|
49
33
|
const allCalls = [];
|
|
50
34
|
const allAssignments = [];
|
|
@@ -75,6 +59,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
75
59
|
parameterTypes: sym.parameterTypes,
|
|
76
60
|
returnType: sym.returnType,
|
|
77
61
|
declaredType: sym.declaredType,
|
|
62
|
+
templateArguments: sym.templateArguments,
|
|
78
63
|
ownerId: sym.ownerId,
|
|
79
64
|
qualifiedName: sym.qualifiedName,
|
|
80
65
|
});
|
|
@@ -103,14 +88,70 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
103
88
|
if (result.fileScopeBindings)
|
|
104
89
|
for (const item of result.fileScopeBindings)
|
|
105
90
|
fileScopeBindingsByFile.push(item);
|
|
106
|
-
// RFC #909 Ring 2: aggregate per-file scope artifacts. Tolerant of
|
|
107
|
-
// workers that don't emit the field yet (older worker builds or
|
|
108
|
-
// partial rollouts), since the additive contract means undefined =
|
|
109
|
-
// "this worker produced no ParsedFiles for this chunk".
|
|
110
91
|
if (result.parsedFiles)
|
|
111
92
|
for (const item of result.parsedFiles)
|
|
112
93
|
allParsedFiles.push(item);
|
|
113
94
|
}
|
|
95
|
+
return {
|
|
96
|
+
imports: allImports,
|
|
97
|
+
calls: allCalls,
|
|
98
|
+
assignments: allAssignments,
|
|
99
|
+
heritage: allHeritage,
|
|
100
|
+
routes: allRoutes,
|
|
101
|
+
fetchCalls: allFetchCalls,
|
|
102
|
+
decoratorRoutes: allDecoratorRoutes,
|
|
103
|
+
toolDefs: allToolDefs,
|
|
104
|
+
ormQueries: allORMQueries,
|
|
105
|
+
constructorBindings: allConstructorBindings,
|
|
106
|
+
fileScopeBindings: fileScopeBindingsByFile,
|
|
107
|
+
parsedFiles: allParsedFiles,
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
const processParsingWithWorkers = async (graph, files, symbolTable, astCache, workerPool, onFileProgress,
|
|
111
|
+
/**
|
|
112
|
+
* When provided, populated with the raw worker results before merging.
|
|
113
|
+
* Used by the incremental-indexing parse cache to capture the per-chunk
|
|
114
|
+
* worker output for caching across runs. The mutation happens in-place
|
|
115
|
+
* so the caller (parse-impl) can keep a reference. See
|
|
116
|
+
* `gitnexus/src/storage/parse-cache.ts`.
|
|
117
|
+
*/
|
|
118
|
+
outRawResults) => {
|
|
119
|
+
// Filter to parseable files only
|
|
120
|
+
const parseableFiles = [];
|
|
121
|
+
for (const file of files) {
|
|
122
|
+
const lang = getLanguageFromFilename(file.path);
|
|
123
|
+
if (lang)
|
|
124
|
+
parseableFiles.push({ path: file.path, content: file.content });
|
|
125
|
+
}
|
|
126
|
+
if (parseableFiles.length === 0)
|
|
127
|
+
return {
|
|
128
|
+
imports: [],
|
|
129
|
+
calls: [],
|
|
130
|
+
assignments: [],
|
|
131
|
+
heritage: [],
|
|
132
|
+
routes: [],
|
|
133
|
+
fetchCalls: [],
|
|
134
|
+
decoratorRoutes: [],
|
|
135
|
+
toolDefs: [],
|
|
136
|
+
ormQueries: [],
|
|
137
|
+
constructorBindings: [],
|
|
138
|
+
fileScopeBindings: [],
|
|
139
|
+
parsedFiles: [],
|
|
140
|
+
};
|
|
141
|
+
const total = files.length;
|
|
142
|
+
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
143
|
+
const chunkResults = await workerPool.dispatch(parseableFiles, (filesProcessed) => {
|
|
144
|
+
onFileProgress?.(Math.min(filesProcessed, total), total, 'Parsing...');
|
|
145
|
+
});
|
|
146
|
+
// Capture the raw chunk results for the incremental parse cache before
|
|
147
|
+
// merging — the cache stores the unmerged worker output so a future run
|
|
148
|
+
// can re-merge them into a fresh graph state.
|
|
149
|
+
if (outRawResults) {
|
|
150
|
+
for (const r of chunkResults)
|
|
151
|
+
outRawResults.push(r);
|
|
152
|
+
}
|
|
153
|
+
// Merge results from all workers into graph and symbol table.
|
|
154
|
+
const merged = mergeChunkResults(graph, symbolTable, chunkResults);
|
|
114
155
|
// Merge and log skipped languages from workers
|
|
115
156
|
const skippedLanguages = new Map();
|
|
116
157
|
for (const result of chunkResults) {
|
|
@@ -126,20 +167,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
126
167
|
}
|
|
127
168
|
// Final progress
|
|
128
169
|
onFileProgress?.(total, total, 'done');
|
|
129
|
-
return
|
|
130
|
-
imports: allImports,
|
|
131
|
-
calls: allCalls,
|
|
132
|
-
assignments: allAssignments,
|
|
133
|
-
heritage: allHeritage,
|
|
134
|
-
routes: allRoutes,
|
|
135
|
-
fetchCalls: allFetchCalls,
|
|
136
|
-
decoratorRoutes: allDecoratorRoutes,
|
|
137
|
-
toolDefs: allToolDefs,
|
|
138
|
-
ormQueries: allORMQueries,
|
|
139
|
-
constructorBindings: allConstructorBindings,
|
|
140
|
-
fileScopeBindings: fileScopeBindingsByFile,
|
|
141
|
-
parsedFiles: allParsedFiles,
|
|
142
|
-
};
|
|
170
|
+
return merged;
|
|
143
171
|
};
|
|
144
172
|
// ============================================================================
|
|
145
173
|
// Sequential fallback (original implementation)
|
|
@@ -339,6 +367,20 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
339
367
|
})
|
|
340
368
|
: null;
|
|
341
369
|
const nodeLabel = extractedClassSymbol?.type ?? defaultNodeLabel;
|
|
370
|
+
const isClassLikeLabel = nodeLabel === 'Class' ||
|
|
371
|
+
nodeLabel === 'Struct' ||
|
|
372
|
+
nodeLabel === 'Interface' ||
|
|
373
|
+
nodeLabel === 'Enum' ||
|
|
374
|
+
nodeLabel === 'Record';
|
|
375
|
+
if (isClassLikeLabel &&
|
|
376
|
+
provider.classExtractor?.shouldSkipClassCapture?.({
|
|
377
|
+
captureMap,
|
|
378
|
+
definitionNode,
|
|
379
|
+
nameNode,
|
|
380
|
+
nodeLabel,
|
|
381
|
+
}) === true) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
342
384
|
// Synthesize name for constructors without explicit @name capture (e.g. Swift init)
|
|
343
385
|
if (!nameNode && nodeLabel !== 'Constructor' && !extractedClassSymbol)
|
|
344
386
|
return;
|
|
@@ -438,7 +480,26 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
438
480
|
arityTag += typeTagForId(cached.map, nodeName, arityForId, seqDefMethodInfo, language, cached.groups);
|
|
439
481
|
arityTag += constTagForId(cached.map, nodeName, arityForId, seqDefMethodInfo, cached.groups);
|
|
440
482
|
}
|
|
441
|
-
const
|
|
483
|
+
const classTemplateArguments = extractedClassSymbol?.templateArguments ??
|
|
484
|
+
provider.classExtractor?.extractTemplateArgumentsFromCapture?.({
|
|
485
|
+
captureMap,
|
|
486
|
+
definitionNode,
|
|
487
|
+
nameNode,
|
|
488
|
+
}) ??
|
|
489
|
+
(captureMap['template-arguments']
|
|
490
|
+
? extractTemplateArguments(captureMap['template-arguments'].text)
|
|
491
|
+
: undefined) ??
|
|
492
|
+
(nameNode && nameNode.text ? extractTemplateArguments(nameNode.text) : undefined);
|
|
493
|
+
const classTemplateTag = (nodeLabel === 'Class' ||
|
|
494
|
+
nodeLabel === 'Struct' ||
|
|
495
|
+
nodeLabel === 'Interface' ||
|
|
496
|
+
nodeLabel === 'Enum' ||
|
|
497
|
+
nodeLabel === 'Record') &&
|
|
498
|
+
classTemplateArguments !== undefined &&
|
|
499
|
+
classTemplateArguments.length > 0
|
|
500
|
+
? templateArgumentsIdTag(classTemplateArguments)
|
|
501
|
+
: '';
|
|
502
|
+
const nodeId = generateId(nodeLabel, `${file.path}:${qualifiedName}${classTemplateTag}${arityTag}`);
|
|
442
503
|
const classNodeForSymbol = definitionNodeForRange || definitionNode || nameNode;
|
|
443
504
|
const qualifiedTypeName = extractedClassSymbol?.qualifiedName ??
|
|
444
505
|
(classNodeForSymbol && provider.classExtractor?.isTypeDeclaration(classNodeForSymbol)
|
|
@@ -464,6 +525,9 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
464
525
|
? isVueSetupTopLevel(nameNode || definitionNodeForRange)
|
|
465
526
|
: cachedExportCheck(provider.exportChecker, nameNode || definitionNodeForRange, nodeName),
|
|
466
527
|
...(qualifiedTypeName !== undefined ? { qualifiedName: qualifiedTypeName } : {}),
|
|
528
|
+
...(classTemplateArguments !== undefined && classTemplateArguments.length > 0
|
|
529
|
+
? { templateArguments: classTemplateArguments }
|
|
530
|
+
: {}),
|
|
467
531
|
...(frameworkHint
|
|
468
532
|
? {
|
|
469
533
|
astFrameworkMultiplier: frameworkHint.entryPointMultiplier,
|
|
@@ -517,6 +581,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
517
581
|
parameterTypes: methodProps.parameterTypes,
|
|
518
582
|
returnType: methodProps.returnType,
|
|
519
583
|
declaredType,
|
|
584
|
+
templateArguments: classTemplateArguments,
|
|
520
585
|
ownerId: enclosingClassId ?? undefined,
|
|
521
586
|
qualifiedName: qualifiedTypeName,
|
|
522
587
|
});
|
|
@@ -562,7 +627,15 @@ export const processParsing = async (graph, files, symbolTable, astCache,
|
|
|
562
627
|
* Worker-mode parses skip — Trees can't cross MessageChannels.
|
|
563
628
|
* Pass `undefined` if no consumer needs cross-phase access.
|
|
564
629
|
*/
|
|
565
|
-
scopeTreeCache, onFileProgress, workerPool
|
|
630
|
+
scopeTreeCache, onFileProgress, workerPool,
|
|
631
|
+
/**
|
|
632
|
+
* Optional out-parameter for the incremental parse cache. When
|
|
633
|
+
* provided AND the worker-pool path runs successfully, populated
|
|
634
|
+
* with the raw `ParseWorkerResult[]` from the workers (pre-merge).
|
|
635
|
+
* Stays empty for the sequential fallback path (no per-chunk
|
|
636
|
+
* artifact to cache there). See `gitnexus/src/storage/parse-cache.ts`.
|
|
637
|
+
*/
|
|
638
|
+
outRawResults) => {
|
|
566
639
|
let lastProgress = 0;
|
|
567
640
|
const reportProgress = onFileProgress
|
|
568
641
|
? (current, total, detail) => {
|
|
@@ -579,7 +652,7 @@ scopeTreeCache, onFileProgress, workerPool) => {
|
|
|
579
652
|
logger.warn(`[scope-resolution prof] worker pool engaged for ${files.length} files — cross-phase tree cache will be empty; scope-resolution re-parses.`);
|
|
580
653
|
}
|
|
581
654
|
try {
|
|
582
|
-
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool, reportProgress);
|
|
655
|
+
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool, reportProgress, outRawResults);
|
|
583
656
|
}
|
|
584
657
|
catch (err) {
|
|
585
658
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { processCalls, buildImportedReturnTypes, buildImportedRawReturnTypes, } from '../call-processor.js';
|
|
11
11
|
import { createASTCache } from '../ast-cache.js';
|
|
12
|
-
import { getLanguageFromFilename } from '../../../_shared/index.js';
|
|
12
|
+
import { getLanguageFromFilename, } from '../../../_shared/index.js';
|
|
13
13
|
import { readFileContents } from '../filesystem-walker.js';
|
|
14
14
|
import { isLanguageAvailable } from '../../tree-sitter/parser-loader.js';
|
|
15
|
+
import { isRegistryPrimary } from '../registry-primary-flag.js';
|
|
15
16
|
import { topologicalLevelSort } from '../utils/graph-sort.js';
|
|
16
17
|
import { isDev } from '../utils/env.js';
|
|
17
18
|
import { logger } from '../../logger.js';
|
|
@@ -88,6 +89,40 @@ export async function runCrossFileBindingPropagation(graph, ctx, parseExportedTy
|
|
|
88
89
|
let crossFileResolved = 0;
|
|
89
90
|
const crossFileStart = Date.now();
|
|
90
91
|
const astCache = createASTCache(AST_CACHE_CAP);
|
|
92
|
+
// Compiled query objects keyed by language name. Shared across all processCalls
|
|
93
|
+
// invocations in this phase so the same tree-sitter query string is only
|
|
94
|
+
// compiled once per language instead of once per file (O(1) vs O(N)).
|
|
95
|
+
const compiledQueryCache = new Map();
|
|
96
|
+
// Snapshot total topological candidates for progress math. We walk the
|
|
97
|
+
// levels once more here (fast — no I/O) so we can report meaningful
|
|
98
|
+
// percentages rather than a frozen display.
|
|
99
|
+
let totalCandidates = 0;
|
|
100
|
+
for (const level of levels) {
|
|
101
|
+
for (const filePath of level) {
|
|
102
|
+
if (totalCandidates >= MAX_CROSS_FILE_REPROCESS)
|
|
103
|
+
break;
|
|
104
|
+
const imports = ctx.namedImportMap.get(filePath);
|
|
105
|
+
if (!imports)
|
|
106
|
+
continue;
|
|
107
|
+
if (!allPathSet.has(filePath))
|
|
108
|
+
continue;
|
|
109
|
+
const lang = getLanguageFromFilename(filePath);
|
|
110
|
+
if (!lang || !isLanguageAvailable(lang))
|
|
111
|
+
continue;
|
|
112
|
+
// Registry-primary languages have their call resolution handled by the
|
|
113
|
+
// scope-resolution pipeline — processCalls skips them immediately. Skip
|
|
114
|
+
// here too so we avoid the I/O cost (readFileContents) and map-building
|
|
115
|
+
// overhead for files that would be no-ops anyway.
|
|
116
|
+
if (isRegistryPrimary(lang))
|
|
117
|
+
continue;
|
|
118
|
+
totalCandidates++;
|
|
119
|
+
}
|
|
120
|
+
if (totalCandidates >= MAX_CROSS_FILE_REPROCESS)
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
const cappedTotal = Math.min(totalCandidates, MAX_CROSS_FILE_REPROCESS);
|
|
124
|
+
/** Emit a progress event every PROGRESS_INTERVAL files so the UI stays alive. */
|
|
125
|
+
const PROGRESS_INTERVAL = 25;
|
|
91
126
|
for (const level of levels) {
|
|
92
127
|
const levelCandidates = [];
|
|
93
128
|
for (const filePath of level) {
|
|
@@ -114,6 +149,11 @@ export async function runCrossFileBindingPropagation(graph, ctx, parseExportedTy
|
|
|
114
149
|
const lang = getLanguageFromFilename(filePath);
|
|
115
150
|
if (!lang || !isLanguageAvailable(lang))
|
|
116
151
|
continue;
|
|
152
|
+
// Registry-primary languages have their call resolution handled by the
|
|
153
|
+
// scope-resolution pipeline — processCalls skips them immediately. Skip
|
|
154
|
+
// here to avoid readFileContents I/O and map-building for no-op files.
|
|
155
|
+
if (isRegistryPrimary(lang))
|
|
156
|
+
continue;
|
|
117
157
|
levelCandidates.push({ filePath, seeded, importedReturns, importedRawReturns });
|
|
118
158
|
}
|
|
119
159
|
if (levelCandidates.length === 0)
|
|
@@ -136,8 +176,20 @@ export async function runCrossFileBindingPropagation(graph, ctx, parseExportedTy
|
|
|
136
176
|
if (importedRawReturns.size > 0) {
|
|
137
177
|
importedRawReturnTypesMap.set(filePath, importedRawReturns);
|
|
138
178
|
}
|
|
139
|
-
await processCalls(graph, reFile, astCache, ctx, undefined, exportedTypeMap, bindings.size > 0 ? bindings : undefined, importedReturnTypesMap.size > 0 ? importedReturnTypesMap : undefined, importedRawReturnTypesMap.size > 0 ? importedRawReturnTypesMap : undefined);
|
|
179
|
+
await processCalls(graph, reFile, astCache, ctx, undefined, exportedTypeMap, bindings.size > 0 ? bindings : undefined, importedReturnTypesMap.size > 0 ? importedReturnTypesMap : undefined, importedRawReturnTypesMap.size > 0 ? importedRawReturnTypesMap : undefined, undefined, undefined, compiledQueryCache);
|
|
140
180
|
crossFileResolved++;
|
|
181
|
+
// Emit progress every PROGRESS_INTERVAL files so the UI shows real
|
|
182
|
+
// movement instead of a frozen display (cross-file can take minutes
|
|
183
|
+
// on large repos with many cross-file imports).
|
|
184
|
+
if (crossFileResolved % PROGRESS_INTERVAL === 0 || crossFileResolved === cappedTotal) {
|
|
185
|
+
const pct = cappedTotal > 0 ? Math.round((crossFileResolved / cappedTotal) * 8) : 0;
|
|
186
|
+
onProgress({
|
|
187
|
+
phase: 'parsing',
|
|
188
|
+
percent: 82 + pct,
|
|
189
|
+
message: `Cross-file type propagation (${crossFileResolved}/${cappedTotal} files)...`,
|
|
190
|
+
stats: { filesProcessed: crossFileResolved, totalFiles, nodesCreated: graph.nodeCount },
|
|
191
|
+
});
|
|
192
|
+
}
|
|
141
193
|
}
|
|
142
194
|
if (crossFileResolved >= MAX_CROSS_FILE_REPROCESS) {
|
|
143
195
|
if (isDev)
|
|
@@ -54,5 +54,10 @@ export declare function runChunkedParseAndResolve(graph: KnowledgeGraph, scanned
|
|
|
54
54
|
* source. See plan
|
|
55
55
|
* docs/plans/2026-04-20-002-perf-parse-heritage-mro-plan.md (Unit 4). */
|
|
56
56
|
scopeTreeCache: ASTCache;
|
|
57
|
+
/** Worker-produced ParsedFile artifacts aggregated across chunks.
|
|
58
|
+
* Threaded into scope-resolution as a re-extract cache so the warm-
|
|
59
|
+
* cache analyze run can skip the dominant `extractParsedFile` cost
|
|
60
|
+
* (otherwise ~58s on a 1000-file repo). */
|
|
61
|
+
parsedFiles: import('../../../_shared/index.js').ParsedFile[];
|
|
57
62
|
}>;
|
|
58
63
|
export {};
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
14
|
import { BindingAccumulator, enrichExportedTypeMap, } from '../binding-accumulator.js';
|
|
15
|
-
import { processParsing } from '../parsing-processor.js';
|
|
15
|
+
import { processParsing, mergeChunkResults } from '../parsing-processor.js';
|
|
16
|
+
import { fileContentHash, computeChunkHash } from '../../../storage/parse-cache.js';
|
|
16
17
|
import { processImports, processImportsFromExtracted, buildImportResolutionContext, } from '../import-processor.js';
|
|
17
18
|
import { EMPTY_INDEX } from '../import-resolvers/utils.js';
|
|
18
19
|
import { processCalls, processCallsFromExtracted, processAssignmentsFromExtracted, processRoutesFromExtracted, seedCrossFileReceiverTypes, buildExportedTypeMapFromGraph, } from '../call-processor.js';
|
|
@@ -33,8 +34,22 @@ import { synthesizeWildcardImportBindings, needsSynthesis } from './wildcard-syn
|
|
|
33
34
|
import { extractORMQueriesInline } from './orm-extraction.js';
|
|
34
35
|
import { logger } from '../../logger.js';
|
|
35
36
|
// ── Constants ──────────────────────────────────────────────────────────────
|
|
36
|
-
/** Max bytes of source content to load per parse chunk.
|
|
37
|
-
|
|
37
|
+
/** Max bytes of source content to load per parse chunk.
|
|
38
|
+
*
|
|
39
|
+
* Memory bound for the worker pool dispatch + a granularity knob for
|
|
40
|
+
* the parse cache. A single file change invalidates only its enclosing
|
|
41
|
+
* chunk, so smaller budgets → finer-grained invalidation.
|
|
42
|
+
*
|
|
43
|
+
* Override via GITNEXUS_CHUNK_BYTE_BUDGET (bytes) — the default of 2MB
|
|
44
|
+
* gives a useful invalidation floor (~1/N chunks on a multi-MB repo)
|
|
45
|
+
* while keeping worker dispatch overhead under 5% on cold runs.
|
|
46
|
+
*/
|
|
47
|
+
const CHUNK_BYTE_BUDGET = (() => {
|
|
48
|
+
const env = Number(process.env.GITNEXUS_CHUNK_BYTE_BUDGET);
|
|
49
|
+
if (Number.isFinite(env) && env > 0)
|
|
50
|
+
return env;
|
|
51
|
+
return 2 * 1024 * 1024;
|
|
52
|
+
})();
|
|
38
53
|
/**
|
|
39
54
|
* Chunked parse + resolve loop.
|
|
40
55
|
*
|
|
@@ -64,6 +79,14 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
|
|
|
64
79
|
for (const [lang, count] of skippedByLang) {
|
|
65
80
|
logger.warn(`Skipping ${count} ${lang} file(s) — ${lang} parser not available (native binding may not have built). Try: npm rebuild tree-sitter-${lang}`);
|
|
66
81
|
}
|
|
82
|
+
// Sort parseableScanned alphabetically for stable chunk membership
|
|
83
|
+
// across runs (Finding 4). Without this, filesystem-scan order can
|
|
84
|
+
// shift between runs (notably on macOS APFS where directory entry
|
|
85
|
+
// order can change after modifications) — different files in the
|
|
86
|
+
// same chunk → different chunk hash → cache miss even when no file
|
|
87
|
+
// content changed. The cache also becomes platform-specific: a
|
|
88
|
+
// Linux-built cache misses on macOS for the same repo.
|
|
89
|
+
parseableScanned.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
67
90
|
const totalParseable = parseableScanned.length;
|
|
68
91
|
if (totalParseable === 0) {
|
|
69
92
|
onProgress({
|
|
@@ -164,6 +187,19 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
|
|
|
164
187
|
const deferredWorkerHeritage = [];
|
|
165
188
|
const deferredConstructorBindings = [];
|
|
166
189
|
const deferredAssignments = [];
|
|
190
|
+
// Aggregated per-file ParsedFile artifacts produced by workers' calls
|
|
191
|
+
// to `extractParsedFile`. Threaded through to the scope-resolution
|
|
192
|
+
// phase so it can SKIP its own re-extraction on cache hits — this is
|
|
193
|
+
// the second-half of the parse-cache speedup since scope-resolution's
|
|
194
|
+
// re-parse otherwise dominates the warm-cache wall-clock time.
|
|
195
|
+
const allParsedFiles = [];
|
|
196
|
+
// Incremental parse cache (Option B): chunk-level content-addressed.
|
|
197
|
+
// When the chunk's (filePath, content-hash) signature matches a prior
|
|
198
|
+
// run's, replay the cached ParseWorkerResult[] instead of dispatching
|
|
199
|
+
// to workers. See gitnexus/src/storage/parse-cache.ts.
|
|
200
|
+
const parseCache = options?.parseCache;
|
|
201
|
+
let chunkCacheHits = 0;
|
|
202
|
+
let chunkCacheMisses = 0;
|
|
167
203
|
try {
|
|
168
204
|
for (let chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) {
|
|
169
205
|
const chunkPaths = chunks[chunkIdx];
|
|
@@ -171,21 +207,76 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
|
|
|
171
207
|
const chunkFiles = chunkPaths
|
|
172
208
|
.filter((p) => chunkContents.has(p))
|
|
173
209
|
.map((p) => ({ path: p, content: chunkContents.get(p) }));
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
210
|
+
// Compute the chunk's content-hash signature (if cache available).
|
|
211
|
+
let chunkHash = null;
|
|
212
|
+
if (parseCache) {
|
|
213
|
+
const entries = chunkFiles.map((f) => ({
|
|
214
|
+
filePath: f.path,
|
|
215
|
+
contentHash: fileContentHash(f.content),
|
|
216
|
+
}));
|
|
217
|
+
chunkHash = computeChunkHash(entries);
|
|
218
|
+
}
|
|
219
|
+
let chunkWorkerData;
|
|
220
|
+
const cachedRaw = chunkHash ? parseCache.entries.get(chunkHash) : undefined;
|
|
221
|
+
// Track every chunk hash we touched so the orchestrator can
|
|
222
|
+
// prune stale entries (chunks whose composition no longer
|
|
223
|
+
// corresponds to a live chunk in the current scan) before saving.
|
|
224
|
+
if (parseCache && chunkHash)
|
|
225
|
+
parseCache.usedKeys.add(chunkHash);
|
|
226
|
+
if (cachedRaw && cachedRaw.length > 0) {
|
|
227
|
+
// Cache hit: replay the cached worker output through the same
|
|
228
|
+
// merge logic the live worker path uses.
|
|
229
|
+
chunkCacheHits++;
|
|
230
|
+
chunkWorkerData = mergeChunkResults(graph, symbolTable, cachedRaw);
|
|
231
|
+
if (isDev) {
|
|
232
|
+
logger.info(`📦 parse-cache HIT: chunk ${chunkIdx + 1}/${numChunks} (${chunkFiles.length} files, ${chunkHash.slice(0, 8)})`);
|
|
233
|
+
}
|
|
234
|
+
// Progress update so UI advances even on a cache hit.
|
|
235
|
+
const cachedFiles = chunkFiles.length;
|
|
177
236
|
onProgress({
|
|
178
237
|
phase: 'parsing',
|
|
179
|
-
percent: Math.round(
|
|
180
|
-
message: `Parsing chunk ${chunkIdx + 1}/${numChunks}...`,
|
|
181
|
-
detail: filePath,
|
|
238
|
+
percent: Math.round(20 + ((filesParsedSoFar + cachedFiles) / totalParseable) * 62),
|
|
239
|
+
message: `Parsing chunk ${chunkIdx + 1}/${numChunks} (cache)...`,
|
|
182
240
|
stats: {
|
|
183
|
-
filesProcessed:
|
|
241
|
+
filesProcessed: filesParsedSoFar + cachedFiles,
|
|
184
242
|
totalFiles: totalParseable,
|
|
185
243
|
nodesCreated: graph.nodeCount,
|
|
186
244
|
},
|
|
187
245
|
});
|
|
188
|
-
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// Cache miss: dispatch to workers, capture the raw results, store
|
|
249
|
+
// them under the chunk hash for the next run.
|
|
250
|
+
chunkCacheMisses++;
|
|
251
|
+
const rawResults = [];
|
|
252
|
+
chunkWorkerData = await processParsing(graph, chunkFiles, symbolTable, astCache, scopeTreeCache, (current, _total, filePath) => {
|
|
253
|
+
const globalCurrent = filesParsedSoFar + current;
|
|
254
|
+
const parsingProgress = 20 + (globalCurrent / totalParseable) * 62;
|
|
255
|
+
onProgress({
|
|
256
|
+
phase: 'parsing',
|
|
257
|
+
percent: Math.round(parsingProgress),
|
|
258
|
+
message: `Parsing chunk ${chunkIdx + 1}/${numChunks}...`,
|
|
259
|
+
detail: filePath,
|
|
260
|
+
stats: {
|
|
261
|
+
filesProcessed: globalCurrent,
|
|
262
|
+
totalFiles: totalParseable,
|
|
263
|
+
nodesCreated: graph.nodeCount,
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
}, workerPool,
|
|
267
|
+
// Capture raw results only when we have a cache to write to —
|
|
268
|
+
// otherwise we'd retain extra arrays for nothing.
|
|
269
|
+
parseCache && chunkHash ? rawResults : undefined);
|
|
270
|
+
// Persist the raw results for this chunk hash. Sequential path
|
|
271
|
+
// doesn't populate rawResults (it writes directly to graph), so
|
|
272
|
+
// small repos without worker pool simply don't cache. That's fine.
|
|
273
|
+
if (parseCache && chunkHash && rawResults.length > 0) {
|
|
274
|
+
parseCache.entries.set(chunkHash, rawResults);
|
|
275
|
+
if (isDev) {
|
|
276
|
+
logger.info(`📦 parse-cache MISS+store: chunk ${chunkIdx + 1}/${numChunks} (${chunkFiles.length} files, ${chunkHash.slice(0, 8)})`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
189
280
|
const chunkBasePercent = 20 + (filesParsedSoFar / totalParseable) * 62;
|
|
190
281
|
if (chunkWorkerData) {
|
|
191
282
|
await processImportsFromExtracted(graph, allPathObjects, chunkWorkerData.imports, ctx, (current, total) => {
|
|
@@ -217,6 +308,13 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
|
|
|
217
308
|
deferredWorkerHeritage.push(item);
|
|
218
309
|
for (const item of chunkWorkerData.constructorBindings)
|
|
219
310
|
deferredConstructorBindings.push(item);
|
|
311
|
+
// Aggregate worker-produced ParsedFile artifacts so scope-
|
|
312
|
+
// resolution can use them as a re-extraction cache (skips its
|
|
313
|
+
// own tree-sitter re-parse on warm runs).
|
|
314
|
+
if (chunkWorkerData.parsedFiles?.length) {
|
|
315
|
+
for (const item of chunkWorkerData.parsedFiles)
|
|
316
|
+
allParsedFiles.push(item);
|
|
317
|
+
}
|
|
220
318
|
if (chunkWorkerData.assignments?.length) {
|
|
221
319
|
for (const item of chunkWorkerData.assignments)
|
|
222
320
|
deferredAssignments.push(item);
|
|
@@ -297,6 +395,9 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
|
|
|
297
395
|
filesParsedSoFar += chunkFiles.length;
|
|
298
396
|
astCache.clear();
|
|
299
397
|
}
|
|
398
|
+
if (isDev && parseCache && (chunkCacheHits > 0 || chunkCacheMisses > 0)) {
|
|
399
|
+
logger.info(`📦 parse-cache summary: ${chunkCacheHits} chunk hit(s), ${chunkCacheMisses} miss(es) across ${numChunks} chunk(s)`);
|
|
400
|
+
}
|
|
300
401
|
const fullWorkerHeritageMap = deferredWorkerHeritage.length > 0
|
|
301
402
|
? buildHeritageMap(deferredWorkerHeritage, ctx, getHeritageStrategyForLanguage)
|
|
302
403
|
: undefined;
|
|
@@ -455,5 +556,12 @@ export async function runChunkedParseAndResolve(graph, scannedFiles, allPaths, t
|
|
|
455
556
|
// chunk-local `astCache` above is intentionally NOT exposed
|
|
456
557
|
// because parse-impl clears it between chunks.
|
|
457
558
|
scopeTreeCache,
|
|
559
|
+
// Per-file ParsedFile artifacts produced by workers' calls to
|
|
560
|
+
// `extractParsedFile`. Empty when only the sequential path ran
|
|
561
|
+
// (sequential doesn't go through the worker, and extracts ParsedFile
|
|
562
|
+
// inline rather than emitting it). Consumed by scope-resolution as
|
|
563
|
+
// a re-extraction cache: when the file's ParsedFile is here,
|
|
564
|
+
// scope-resolution skips its own `extractParsedFile` call.
|
|
565
|
+
parsedFiles: allParsedFiles,
|
|
458
566
|
};
|
|
459
567
|
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { PipelinePhase } from './types.js';
|
|
19
19
|
import type { BindingAccumulator } from '../binding-accumulator.js';
|
|
20
|
+
import type { ParsedFile } from '../../../_shared/index.js';
|
|
20
21
|
import type { ExtractedFetchCall, ExtractedRoute, ExtractedDecoratorRoute, ExtractedToolDef, ExtractedORMQuery } from '../workers/parse-worker.js';
|
|
21
22
|
import type { createResolutionContext } from '../model/resolution-context.js';
|
|
22
23
|
import type { ASTCache } from '../ast-cache.js';
|
|
@@ -70,5 +71,18 @@ export interface ParseOutput {
|
|
|
70
71
|
* `scopeTreeCache.clear()` after its extract loop finishes.
|
|
71
72
|
*/
|
|
72
73
|
readonly scopeTreeCache: ASTCache;
|
|
74
|
+
/**
|
|
75
|
+
* Per-file `ParsedFile` artifacts produced by workers' calls to
|
|
76
|
+
* `extractParsedFile`. Threaded through to `scopeResolutionPhase`
|
|
77
|
+
* as a re-extraction cache: when a file's ParsedFile is present here,
|
|
78
|
+
* scope-resolution can skip its own `extractParsedFile` (which would
|
|
79
|
+
* otherwise re-parse the file with tree-sitter on the main thread,
|
|
80
|
+
* costing ~58s on a 1000-file repo).
|
|
81
|
+
*
|
|
82
|
+
* Empty for files that went through the sequential parse fallback —
|
|
83
|
+
* sequential doesn't emit ParsedFile artifacts; scope-resolution
|
|
84
|
+
* falls back to a fresh extract for those.
|
|
85
|
+
*/
|
|
86
|
+
readonly parsedFiles: readonly ParsedFile[];
|
|
73
87
|
}
|
|
74
88
|
export declare const parsePhase: PipelinePhase<ParseOutput>;
|
|
@@ -32,5 +32,18 @@ export interface PipelineOptions {
|
|
|
32
32
|
minFiles?: number;
|
|
33
33
|
minBytes?: number;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Incremental-indexing parse cache. When provided:
|
|
37
|
+
* - The parse phase looks up each chunk's content hash in
|
|
38
|
+
* `parseCache.entries`. On hit, it replays the cached
|
|
39
|
+
* `ParseWorkerResult[]` instead of dispatching to workers.
|
|
40
|
+
* - On miss, it runs the workers as today and stores the new
|
|
41
|
+
* results in `parseCache.entries` keyed by chunk hash.
|
|
42
|
+
* The caller (`run-analyze.ts`) is responsible for loading the cache
|
|
43
|
+
* before the pipeline runs and persisting it after. Cache survives
|
|
44
|
+
* `--force` because keys are content-addressed.
|
|
45
|
+
* See `gitnexus/src/storage/parse-cache.ts`.
|
|
46
|
+
*/
|
|
47
|
+
parseCache?: import('../../storage/parse-cache.js').ParseCache;
|
|
35
48
|
}
|
|
36
49
|
export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void, options?: PipelineOptions) => Promise<PipelineResult>;
|
|
@@ -70,6 +70,8 @@ export const MIGRATED_LANGUAGES = new Set([
|
|
|
70
70
|
SupportedLanguages.TypeScript,
|
|
71
71
|
SupportedLanguages.Go,
|
|
72
72
|
SupportedLanguages.C,
|
|
73
|
+
SupportedLanguages.CPlusPlus,
|
|
74
|
+
SupportedLanguages.PHP,
|
|
73
75
|
]);
|
|
74
76
|
/**
|
|
75
77
|
* Return the env-var name that controls a given language's registry-
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
* - `ParsedFile.referenceSites` — pre-resolution usage facts.
|
|
60
60
|
*/
|
|
61
61
|
import { buildPositionIndex, buildScopeTree, canParentScope, makeScopeId } from '../../_shared/index.js';
|
|
62
|
+
import { extractTemplateArguments } from './utils/template-arguments.js';
|
|
62
63
|
// ─── Public entry point ─────────────────────────────────────────────────────
|
|
63
64
|
/**
|
|
64
65
|
* Drive the five extraction passes and return a `ParsedFile`.
|
|
@@ -362,6 +363,8 @@ function buildDefFromDeclarationMatch(match, anchor, filePath) {
|
|
|
362
363
|
return undefined;
|
|
363
364
|
const qualifiedCap = match['@declaration.qualified_name'];
|
|
364
365
|
const qualifiedName = qualifiedCap?.text;
|
|
366
|
+
const templateArguments = extractTemplateArguments(match['@declaration.template-arguments']?.text ?? '') ??
|
|
367
|
+
extractTemplateArguments(qualifiedName ?? nameCap.text);
|
|
365
368
|
// Optional arity metadata — producers (e.g. Python emit-captures)
|
|
366
369
|
// synthesize these on function/method declarations. Their absence is
|
|
367
370
|
// the normal case for other producers; readers treat undefined as
|
|
@@ -381,6 +384,7 @@ function buildDefFromDeclarationMatch(match, anchor, filePath) {
|
|
|
381
384
|
...(parameterTypes !== undefined ? { parameterTypes } : {}),
|
|
382
385
|
...(declaredType !== undefined ? { declaredType } : {}),
|
|
383
386
|
...(returnType !== undefined ? { returnType } : {}),
|
|
387
|
+
...(templateArguments !== undefined ? { templateArguments } : {}),
|
|
384
388
|
};
|
|
385
389
|
}
|
|
386
390
|
function parseIntCapture(cap) {
|