gitnexus 1.6.5-rc.2 → 1.6.5-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 +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/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +30 -12
- package/dist/cli/analyze.d.ts +18 -0
- package/dist/cli/analyze.js +33 -4
- package/dist/cli/augment.d.ts +1 -1
- package/dist/cli/augment.js +1 -1
- package/dist/cli/index.js +6 -1
- package/dist/cli/setup.js +6 -0
- package/dist/core/augmentation/engine.d.ts +2 -2
- package/dist/core/augmentation/engine.js +26 -6
- package/dist/core/embeddings/ast-utils.js +2 -1
- package/dist/core/embeddings/http-client.js +22 -6
- package/dist/core/group/extractors/grpc-extractor.js +2 -1
- package/dist/core/group/extractors/http-patterns/python.js +175 -0
- package/dist/core/group/extractors/http-route-extractor.js +2 -1
- package/dist/core/group/extractors/include-extractor.js +2 -1
- package/dist/core/group/extractors/thrift-extractor.js +2 -1
- package/dist/core/group/extractors/tree-sitter-scanner.js +2 -1
- 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.js +166 -47
- package/dist/core/ingestion/community-processor.js +18 -0
- package/dist/core/ingestion/heritage-processor.js +3 -2
- package/dist/core/ingestion/import-processor.js +2 -1
- package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
- package/dist/core/ingestion/import-resolvers/standard.js +27 -1
- package/dist/core/ingestion/import-resolvers/utils.js +4 -0
- package/dist/core/ingestion/languages/c/arity-metadata.d.ts +14 -0
- package/dist/core/ingestion/languages/c/arity-metadata.js +94 -0
- package/dist/core/ingestion/languages/c/arity.d.ts +6 -0
- package/dist/core/ingestion/languages/c/arity.js +18 -0
- package/dist/core/ingestion/languages/c/captures.d.ts +2 -0
- package/dist/core/ingestion/languages/c/captures.js +105 -0
- package/dist/core/ingestion/languages/c/header-scan.d.ts +7 -0
- package/dist/core/ingestion/languages/c/header-scan.js +55 -0
- package/dist/core/ingestion/languages/c/import-decomposer.d.ts +8 -0
- package/dist/core/ingestion/languages/c/import-decomposer.js +50 -0
- package/dist/core/ingestion/languages/c/import-target.d.ts +14 -0
- package/dist/core/ingestion/languages/c/import-target.js +57 -0
- package/dist/core/ingestion/languages/c/index.d.ts +11 -0
- package/dist/core/ingestion/languages/c/index.js +11 -0
- package/dist/core/ingestion/languages/c/interpret.d.ts +14 -0
- package/dist/core/ingestion/languages/c/interpret.js +48 -0
- package/dist/core/ingestion/languages/c/merge-bindings.d.ts +7 -0
- package/dist/core/ingestion/languages/c/merge-bindings.js +23 -0
- package/dist/core/ingestion/languages/c/query.d.ts +3 -0
- package/dist/core/ingestion/languages/c/query.js +161 -0
- package/dist/core/ingestion/languages/c/scope-resolver.d.ts +13 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +60 -0
- package/dist/core/ingestion/languages/c/simple-hooks.d.ts +14 -0
- package/dist/core/ingestion/languages/c/simple-hooks.js +19 -0
- package/dist/core/ingestion/languages/c/static-linkage.d.ts +13 -0
- package/dist/core/ingestion/languages/c/static-linkage.js +57 -0
- package/dist/core/ingestion/languages/c-cpp.js +10 -0
- package/dist/core/ingestion/languages/csharp/captures.js +2 -1
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +3 -2
- package/dist/core/ingestion/languages/go/captures.js +2 -1
- package/dist/core/ingestion/languages/go/range-binding.js +2 -1
- 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/languages/python/captures.js +2 -1
- package/dist/core/ingestion/languages/typescript/captures.js +2 -1
- package/dist/core/ingestion/parsing-processor.d.ts +22 -2
- package/dist/core/ingestion/parsing-processor.js +85 -50
- 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-resolution/contract/scope-resolver.d.ts +65 -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 +5 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +25 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +79 -7
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +7 -3
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +24 -4
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +21 -2
- 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 +31 -7
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -1
- package/dist/core/ingestion/tree-sitter-queries.js +10 -0
- package/dist/core/ingestion/workers/parse-worker.js +2 -1
- package/dist/core/lbug/lbug-adapter.d.ts +26 -0
- package/dist/core/lbug/lbug-adapter.js +174 -40
- package/dist/core/lbug/pool-adapter.js +19 -2
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +323 -29
- package/dist/core/tree-sitter/safe-parse.d.ts +6 -0
- package/dist/core/tree-sitter/safe-parse.js +32 -0
- package/dist/server/git-clone.js +10 -13
- package/dist/storage/file-hash.d.ts +47 -0
- package/dist/storage/file-hash.js +86 -0
- package/dist/storage/git.d.ts +17 -6
- package/dist/storage/git.js +46 -12
- package/dist/storage/parse-cache.d.ts +67 -0
- package/dist/storage/parse-cache.js +182 -0
- package/dist/storage/repo-manager.d.ts +41 -1
- package/dist/storage/repo-manager.js +17 -2
- package/hooks/claude/gitnexus-hook.cjs +8 -1
- package/hooks/claude/hook-lock.cjs +119 -0
- package/package.json +1 -1
- package/web/assets/{agent-BpHQleHE.js → agent-BG6RCOzz.js} +1 -1
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-F-tujre-.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-2GL7nOvO.js +36 -0
- package/web/assets/blockDiagram-7IZFK4PR-5AjX0pPU.js +132 -0
- package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-hLOeq7xC.js} +2 -2
- package/web/assets/chunk-2T2R6R2M-B_pq_2nf.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CpoohCFN.js +1 -0
- package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-CfqpR3Nr.js} +1 -1
- package/web/assets/chunk-4R4BOZG6-D3gm7tYj.js +159 -0
- package/web/assets/chunk-6764PJDD-WcI965eO.js +1 -0
- package/web/assets/chunk-AQ6EADP3-BpMj3rQl.js +1 -0
- package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-DSoCJlUA.js} +1 -1
- package/web/assets/chunk-C62D2QBJ-CvFF2PnB.js +1 -0
- package/web/assets/chunk-CEXFNPSA-DdNtJtrF.js +1 -0
- package/web/assets/chunk-J5EP6P6S-DtcVaAJI.js +1 -0
- package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-DElaNjc0.js} +1 -1
- package/web/assets/chunk-KGYTTC2M-D0K5or7e.js +1 -0
- package/web/assets/chunk-KRXBNO2N-DpR8iDt8.js +1 -0
- package/web/assets/chunk-LCXTWHL2-DdMObOEk.js +231 -0
- package/web/assets/chunk-LII3EMHJ-I78zXtzi.js +1 -0
- package/web/assets/chunk-RERM46MO-Betu1cSy.js +1 -0
- package/web/assets/chunk-RG4AUYOV-BUCJ2JP5.js +206 -0
- package/web/assets/chunk-RKZBBQEN-Cutpza0t.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-BFUxCvX2.js +1 -0
- package/web/assets/chunk-T5OCTHI4-DKwlkuvB.js +1 -0
- package/web/assets/chunk-UP6H54XL-0YWa0NDg.js +1 -0
- package/web/assets/chunk-UXSXWOXI-CSz0OXpz.js +1 -0
- package/web/assets/chunk-W44A43WB-AOmgoT-X.js +1 -0
- package/web/assets/{chunk-RWUO3TPN-DTWzAhQ1.js → chunk-ZXARS5L4-DIzgxjMw.js} +1 -1
- package/web/assets/classDiagram-KGZ6W3CR-BT-rn7LF.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-uR3nDadY.js +1 -0
- package/web/assets/{cose-bilkent-PNC4W37J-DdZq7Qz_.js → cose-bilkent-UX7MHV2Q-DCSCD1TK.js} +1 -1
- package/web/assets/dagre-ND4H6XIP-CsciHSij.js +4 -0
- package/web/assets/diagram-3NCE3AQN-BKUT5Rpc.js +43 -0
- package/web/assets/diagram-GF46GFSD-Dxb4hZSo.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-D3qus9Cn.js +3 -0
- package/web/assets/diagram-QXG6HAR7-r9BMLGGP.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-BGXqs7-m.js +10 -0
- package/web/assets/{erDiagram-GCSMX5X6-DfdN6iqF.js → erDiagram-L5TCEMPS-LgSWVrkZ.js} +2 -2
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-By7r3bla.js +1 -0
- package/web/assets/flowDiagram-H6V6AXG4-Bj_vV5ky.js +162 -0
- package/web/assets/ganttDiagram-JCBTUEKG-B1eVITSh.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-ClEP6RdE.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-BP0R-_FD.js +106 -0
- package/web/assets/{index-3NUCUW2s.js → index-oL-ZNYwb.js} +80 -81
- package/web/assets/info-J43DQDTF-KCYPFFUO-bBJRjmP5.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-Dmj4OEO3.js +2 -0
- package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-B3NgQ4lJ.js} +2 -2
- package/web/assets/{journeyDiagram-SO5T7YLQ-BW8oKa3N.js → journeyDiagram-M6C3CM3L-DALmL4_N.js} +3 -3
- package/web/assets/{kanban-definition-LJHFXRCJ-DzbOsR-2.js → kanban-definition-75IXJCU3-AvVbHpnN.js} +4 -4
- package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CqF6_ZN-.js} +1 -1
- package/web/assets/{mindmap-definition-2EUWGEK5-BIXGQALq.js → mindmap-definition-2TDM6QVE-B5c9VOzs.js} +28 -28
- package/web/assets/packet-YPE3B663-LP52Z2RK-1ZCldnu3.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-EhjHC5EE.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-Po2HSSR4.js +30 -0
- package/web/assets/quadrantDiagram-VICAPDV7-C47UxSZD.js +7 -0
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-CvXjgxlW.js +1 -0
- package/web/assets/{requirementDiagram-M5DCFWZL-CzUUrhQD.js → requirementDiagram-JXO7QTGE-CpECN_Hq.js} +6 -6
- package/web/assets/sankeyDiagram-URQDO5SZ-B3b7cLrS.js +40 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-CRJ95oVP.js +162 -0
- package/web/assets/stateDiagram-7D4R322I-C7U9b3ks.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-BQajbtov.js +1 -0
- package/web/assets/{timeline-definition-5SPVSISX-DkMiGj4Z.js → timeline-definition-O6YCAMPW-rtbk6BBo.js} +4 -4
- package/web/assets/treeView-BLDUP644-QA4HXRO3-R2o5gwfP.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-Cesmac_u.js +1 -0
- package/web/assets/{vennDiagram-IE5QUKF5-BCxMmf9q.js → vennDiagram-MWXL3ELB-W8Yoaayh.js} +3 -3
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-B9HYoRgA.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-DIZw5Abj.js +78 -0
- package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DGRtrj4P.js} +3 -3
- package/web/index.html +2 -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-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/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/flowDiagram-OTCZ4VVT-aAZw4c_M.js +0 -162
- 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/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
- package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
- 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/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/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
- package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
- 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-CG-ydtp4.js} +0 -0
|
@@ -5,6 +5,7 @@ import { generateId } from '../../lib/utils.js';
|
|
|
5
5
|
import { getLanguageFromFilename, SupportedLanguages } from '../../_shared/index.js';
|
|
6
6
|
import { extractVueScript, isVueSetupTopLevel } from './vue-sfc-extractor.js';
|
|
7
7
|
import { yieldToEventLoop } from './utils/event-loop.js';
|
|
8
|
+
import { parseSourceSafe } from '../tree-sitter/safe-parse.js';
|
|
8
9
|
import { isVerboseIngestionEnabled } from './utils/verbose.js';
|
|
9
10
|
import { getDefinitionNodeFromCaptures, findEnclosingClassInfo, getLabelFromCaptures, CLASS_CONTAINER_TYPES, } from './utils/ast-helpers.js';
|
|
10
11
|
import { detectFrameworkFromAST } from './framework-detection.js';
|
|
@@ -15,35 +16,18 @@ import { getTreeSitterBufferSize, getTreeSitterContentByteLength, TREE_SITTER_MA
|
|
|
15
16
|
// ============================================================================
|
|
16
17
|
// Worker-based parallel parsing
|
|
17
18
|
// ============================================================================
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
assignments: [],
|
|
31
|
-
heritage: [],
|
|
32
|
-
routes: [],
|
|
33
|
-
fetchCalls: [],
|
|
34
|
-
decoratorRoutes: [],
|
|
35
|
-
toolDefs: [],
|
|
36
|
-
ormQueries: [],
|
|
37
|
-
constructorBindings: [],
|
|
38
|
-
fileScopeBindings: [],
|
|
39
|
-
parsedFiles: [],
|
|
40
|
-
};
|
|
41
|
-
const total = files.length;
|
|
42
|
-
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
43
|
-
const chunkResults = await workerPool.dispatch(parseableFiles, (filesProcessed) => {
|
|
44
|
-
onFileProgress?.(Math.min(filesProcessed, total), total, 'Parsing...');
|
|
45
|
-
});
|
|
46
|
-
// Merge results from all workers into graph and symbol table
|
|
19
|
+
/**
|
|
20
|
+
* Merge a list of `ParseWorkerResult`s into the running graph + symbol
|
|
21
|
+
* table state and produce the chunk-aggregated `WorkerExtractedData`.
|
|
22
|
+
*
|
|
23
|
+
* Extracted from `processParsingWithWorkers` so the same merge logic can
|
|
24
|
+
* be applied to both freshly-parsed worker output AND cached worker
|
|
25
|
+
* output replayed during incremental analyze. Idempotent on the
|
|
26
|
+
* accumulator fields (push-only); idempotent on graph if the caller
|
|
27
|
+
* starts from a clean graph (otherwise duplicate `addNode` calls are
|
|
28
|
+
* silently no-op'd by `KnowledgeGraph`).
|
|
29
|
+
*/
|
|
30
|
+
export const mergeChunkResults = (graph, symbolTable, chunkResults) => {
|
|
47
31
|
const allImports = [];
|
|
48
32
|
const allCalls = [];
|
|
49
33
|
const allAssignments = [];
|
|
@@ -102,14 +86,70 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
102
86
|
if (result.fileScopeBindings)
|
|
103
87
|
for (const item of result.fileScopeBindings)
|
|
104
88
|
fileScopeBindingsByFile.push(item);
|
|
105
|
-
// RFC #909 Ring 2: aggregate per-file scope artifacts. Tolerant of
|
|
106
|
-
// workers that don't emit the field yet (older worker builds or
|
|
107
|
-
// partial rollouts), since the additive contract means undefined =
|
|
108
|
-
// "this worker produced no ParsedFiles for this chunk".
|
|
109
89
|
if (result.parsedFiles)
|
|
110
90
|
for (const item of result.parsedFiles)
|
|
111
91
|
allParsedFiles.push(item);
|
|
112
92
|
}
|
|
93
|
+
return {
|
|
94
|
+
imports: allImports,
|
|
95
|
+
calls: allCalls,
|
|
96
|
+
assignments: allAssignments,
|
|
97
|
+
heritage: allHeritage,
|
|
98
|
+
routes: allRoutes,
|
|
99
|
+
fetchCalls: allFetchCalls,
|
|
100
|
+
decoratorRoutes: allDecoratorRoutes,
|
|
101
|
+
toolDefs: allToolDefs,
|
|
102
|
+
ormQueries: allORMQueries,
|
|
103
|
+
constructorBindings: allConstructorBindings,
|
|
104
|
+
fileScopeBindings: fileScopeBindingsByFile,
|
|
105
|
+
parsedFiles: allParsedFiles,
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const processParsingWithWorkers = async (graph, files, symbolTable, astCache, workerPool, onFileProgress,
|
|
109
|
+
/**
|
|
110
|
+
* When provided, populated with the raw worker results before merging.
|
|
111
|
+
* Used by the incremental-indexing parse cache to capture the per-chunk
|
|
112
|
+
* worker output for caching across runs. The mutation happens in-place
|
|
113
|
+
* so the caller (parse-impl) can keep a reference. See
|
|
114
|
+
* `gitnexus/src/storage/parse-cache.ts`.
|
|
115
|
+
*/
|
|
116
|
+
outRawResults) => {
|
|
117
|
+
// Filter to parseable files only
|
|
118
|
+
const parseableFiles = [];
|
|
119
|
+
for (const file of files) {
|
|
120
|
+
const lang = getLanguageFromFilename(file.path);
|
|
121
|
+
if (lang)
|
|
122
|
+
parseableFiles.push({ path: file.path, content: file.content });
|
|
123
|
+
}
|
|
124
|
+
if (parseableFiles.length === 0)
|
|
125
|
+
return {
|
|
126
|
+
imports: [],
|
|
127
|
+
calls: [],
|
|
128
|
+
assignments: [],
|
|
129
|
+
heritage: [],
|
|
130
|
+
routes: [],
|
|
131
|
+
fetchCalls: [],
|
|
132
|
+
decoratorRoutes: [],
|
|
133
|
+
toolDefs: [],
|
|
134
|
+
ormQueries: [],
|
|
135
|
+
constructorBindings: [],
|
|
136
|
+
fileScopeBindings: [],
|
|
137
|
+
parsedFiles: [],
|
|
138
|
+
};
|
|
139
|
+
const total = files.length;
|
|
140
|
+
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
141
|
+
const chunkResults = await workerPool.dispatch(parseableFiles, (filesProcessed) => {
|
|
142
|
+
onFileProgress?.(Math.min(filesProcessed, total), total, 'Parsing...');
|
|
143
|
+
});
|
|
144
|
+
// Capture the raw chunk results for the incremental parse cache before
|
|
145
|
+
// merging — the cache stores the unmerged worker output so a future run
|
|
146
|
+
// can re-merge them into a fresh graph state.
|
|
147
|
+
if (outRawResults) {
|
|
148
|
+
for (const r of chunkResults)
|
|
149
|
+
outRawResults.push(r);
|
|
150
|
+
}
|
|
151
|
+
// Merge results from all workers into graph and symbol table.
|
|
152
|
+
const merged = mergeChunkResults(graph, symbolTable, chunkResults);
|
|
113
153
|
// Merge and log skipped languages from workers
|
|
114
154
|
const skippedLanguages = new Map();
|
|
115
155
|
for (const result of chunkResults) {
|
|
@@ -125,20 +165,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
125
165
|
}
|
|
126
166
|
// Final progress
|
|
127
167
|
onFileProgress?.(total, total, 'done');
|
|
128
|
-
return
|
|
129
|
-
imports: allImports,
|
|
130
|
-
calls: allCalls,
|
|
131
|
-
assignments: allAssignments,
|
|
132
|
-
heritage: allHeritage,
|
|
133
|
-
routes: allRoutes,
|
|
134
|
-
fetchCalls: allFetchCalls,
|
|
135
|
-
decoratorRoutes: allDecoratorRoutes,
|
|
136
|
-
toolDefs: allToolDefs,
|
|
137
|
-
ormQueries: allORMQueries,
|
|
138
|
-
constructorBindings: allConstructorBindings,
|
|
139
|
-
fileScopeBindings: fileScopeBindingsByFile,
|
|
140
|
-
parsedFiles: allParsedFiles,
|
|
141
|
-
};
|
|
168
|
+
return merged;
|
|
142
169
|
};
|
|
143
170
|
// ============================================================================
|
|
144
171
|
// Sequential fallback (original implementation)
|
|
@@ -274,7 +301,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
274
301
|
}
|
|
275
302
|
let tree;
|
|
276
303
|
try {
|
|
277
|
-
tree = parser
|
|
304
|
+
tree = parseSourceSafe(parser, parseContent, undefined, {
|
|
278
305
|
bufferSize: getTreeSitterBufferSize(parseContent),
|
|
279
306
|
});
|
|
280
307
|
}
|
|
@@ -561,7 +588,15 @@ export const processParsing = async (graph, files, symbolTable, astCache,
|
|
|
561
588
|
* Worker-mode parses skip — Trees can't cross MessageChannels.
|
|
562
589
|
* Pass `undefined` if no consumer needs cross-phase access.
|
|
563
590
|
*/
|
|
564
|
-
scopeTreeCache, onFileProgress, workerPool
|
|
591
|
+
scopeTreeCache, onFileProgress, workerPool,
|
|
592
|
+
/**
|
|
593
|
+
* Optional out-parameter for the incremental parse cache. When
|
|
594
|
+
* provided AND the worker-pool path runs successfully, populated
|
|
595
|
+
* with the raw `ParseWorkerResult[]` from the workers (pre-merge).
|
|
596
|
+
* Stays empty for the sequential fallback path (no per-chunk
|
|
597
|
+
* artifact to cache there). See `gitnexus/src/storage/parse-cache.ts`.
|
|
598
|
+
*/
|
|
599
|
+
outRawResults) => {
|
|
565
600
|
let lastProgress = 0;
|
|
566
601
|
const reportProgress = onFileProgress
|
|
567
602
|
? (current, total, detail) => {
|
|
@@ -578,7 +613,7 @@ scopeTreeCache, onFileProgress, workerPool) => {
|
|
|
578
613
|
logger.warn(`[scope-resolution prof] worker pool engaged for ${files.length} files — cross-phase tree cache will be empty; scope-resolution re-parses.`);
|
|
579
614
|
}
|
|
580
615
|
try {
|
|
581
|
-
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool, reportProgress);
|
|
616
|
+
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool, reportProgress, outRawResults);
|
|
582
617
|
}
|
|
583
618
|
catch (err) {
|
|
584
619
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -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>;
|
|
@@ -69,6 +69,8 @@ export const MIGRATED_LANGUAGES = new Set([
|
|
|
69
69
|
SupportedLanguages.CSharp,
|
|
70
70
|
SupportedLanguages.TypeScript,
|
|
71
71
|
SupportedLanguages.Go,
|
|
72
|
+
SupportedLanguages.C,
|
|
73
|
+
SupportedLanguages.PHP,
|
|
72
74
|
]);
|
|
73
75
|
/**
|
|
74
76
|
* Return the env-var name that controls a given language's registry-
|
|
@@ -342,6 +342,21 @@ export interface ScopeResolver {
|
|
|
342
342
|
* inheritance).
|
|
343
343
|
*/
|
|
344
344
|
buildMro(graph: KnowledgeGraph, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup): Map<string, string[]>;
|
|
345
|
+
/**
|
|
346
|
+
* Optional parallel MRO that EXCLUDES mixin-like augmentation (e.g., PHP
|
|
347
|
+
* traits). Returns the inheritance-only ancestor chain — the same kind
|
|
348
|
+
* of map as `buildMro` but built only from inheritance edges (EXTENDS).
|
|
349
|
+
*
|
|
350
|
+
* Used by the shared super-branch dispatch in `receiver-bound-calls`
|
|
351
|
+
* so that `parent::method()` walks the inheritance chain only, not the
|
|
352
|
+
* trait-augmented one. PHP semantics: `parent::` explicitly bypasses
|
|
353
|
+
* traits, even when a composed trait shadows a same-named parent method.
|
|
354
|
+
*
|
|
355
|
+
* Languages without mixin-like semantics leave this undefined — callers
|
|
356
|
+
* fall back to `buildMro`/`mroFor`, which for those languages is already
|
|
357
|
+
* the inheritance chain.
|
|
358
|
+
*/
|
|
359
|
+
readonly buildExtendsOnlyMro?: (graph: KnowledgeGraph, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup) => Map<string, string[]>;
|
|
345
360
|
/**
|
|
346
361
|
* Mutate `parsed.localDefs[i].ownerId` to point at the structural
|
|
347
362
|
* owner. Python's rule: methods (Function defs whose parent scope
|
|
@@ -414,6 +429,36 @@ export interface ScopeResolver {
|
|
|
414
429
|
* but is too loose as a default for strict module systems.
|
|
415
430
|
*/
|
|
416
431
|
readonly allowGlobalFreeCallFallback?: boolean;
|
|
432
|
+
/**
|
|
433
|
+
* Optional predicate to identify definitions with file-local linkage
|
|
434
|
+
* (e.g. C `static` functions). When provided, `pickUniqueGlobalCallable`
|
|
435
|
+
* excludes defs where `isFileLocalDef(def) === true` and the def lives
|
|
436
|
+
* in a different file from the caller. This prevents the global free-call
|
|
437
|
+
* fallback from creating CALLS edges to file-local symbols that are
|
|
438
|
+
* logically invisible from the caller's translation unit.
|
|
439
|
+
*
|
|
440
|
+
* Languages without file-local linkage semantics leave this undefined.
|
|
441
|
+
*/
|
|
442
|
+
readonly isFileLocalDef?: (def: SymbolDefinition) => boolean;
|
|
443
|
+
/**
|
|
444
|
+
* Optional predicate to gate free-call fallback emission by caller-side
|
|
445
|
+
* visibility. When provided, `pickUniqueGlobalCallable` rejects candidates
|
|
446
|
+
* the caller cannot legally reach — e.g., a PHP function in a different
|
|
447
|
+
* namespace with no `use function` import, which PHP runtime would treat
|
|
448
|
+
* as `Call to undefined function`. Returning `false` blocks the candidate;
|
|
449
|
+
* returning `true` allows it; undefined-default keeps current behavior
|
|
450
|
+
* (no visibility filtering, equivalent to "all candidates visible").
|
|
451
|
+
*
|
|
452
|
+
* The hook receives the caller's `ParsedFile` (so it can consult
|
|
453
|
+
* `parsedImports`, `moduleScope`, etc.) and the candidate `SymbolDefinition`.
|
|
454
|
+
* The predicate must be pure: same inputs → same answer.
|
|
455
|
+
*
|
|
456
|
+
* Languages without namespace-scoped function resolution leave this undefined.
|
|
457
|
+
*/
|
|
458
|
+
readonly isCallableVisibleFromCaller?: (ctx: {
|
|
459
|
+
readonly callerParsed: ParsedFile;
|
|
460
|
+
readonly candidate: SymbolDefinition;
|
|
461
|
+
}) => boolean;
|
|
417
462
|
/**
|
|
418
463
|
* Optional post-finalize hook to inject cross-file bindings that
|
|
419
464
|
* aren't modeled via explicit imports. Runs after
|
|
@@ -490,4 +535,24 @@ export interface ScopeResolver {
|
|
|
490
535
|
get(filePath: string): unknown;
|
|
491
536
|
};
|
|
492
537
|
}) => void;
|
|
538
|
+
/**
|
|
539
|
+
* Optional post-resolution pass: emit CALLS edges for member-call sites
|
|
540
|
+
* whose receiver cannot be typed by the scope chain (no `TypeRef`).
|
|
541
|
+
* Dynamically-typed languages with untyped/`mixed`/`Any` parameters use
|
|
542
|
+
* this hook to recover the call edge via workspace-wide method-name
|
|
543
|
+
* lookup, mirroring what their legacy resolvers did.
|
|
544
|
+
*
|
|
545
|
+
* Runs AFTER `emitReceiverBoundCalls` and BEFORE `emitFreeCallFallback`.
|
|
546
|
+
* Implementations MUST:
|
|
547
|
+
* - Skip sites already in `handledSites` (Invariant I2).
|
|
548
|
+
* - Add resolved site keys to `handledSites` before returning.
|
|
549
|
+
* - Stay narrow: a unique workspace-wide match is the safe baseline.
|
|
550
|
+
* Multi-candidate fallbacks should narrow by arity / argument types
|
|
551
|
+
* before emitting to keep false-positive rate bounded.
|
|
552
|
+
*
|
|
553
|
+
* Returns the number of edges emitted (for telemetry).
|
|
554
|
+
*
|
|
555
|
+
* Default: undefined (no unresolved-receiver fallback).
|
|
556
|
+
*/
|
|
557
|
+
readonly emitUnresolvedReceiverEdges?: (graph: KnowledgeGraph, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup, handledSites: Set<string>, model: SemanticModel) => number;
|
|
493
558
|
}
|
|
@@ -16,4 +16,4 @@
|
|
|
16
16
|
* can extend the return shape without breaking existing consumers.
|
|
17
17
|
*/
|
|
18
18
|
import type { MethodDispatchIndex } from '../../../../_shared/index.js';
|
|
19
|
-
export declare function buildPopulatedMethodDispatch(mroByDefId: ReadonlyMap<string, readonly string[]>): MethodDispatchIndex;
|
|
19
|
+
export declare function buildPopulatedMethodDispatch(mroByDefId: ReadonlyMap<string, readonly string[]>, extendsOnlyMroByDefId?: ReadonlyMap<string, readonly string[]>): MethodDispatchIndex;
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* can extend the return shape without breaking existing consumers.
|
|
17
17
|
*/
|
|
18
18
|
const EMPTY_DEFS = Object.freeze([]);
|
|
19
|
-
export function buildPopulatedMethodDispatch(mroByDefId) {
|
|
20
|
-
|
|
19
|
+
export function buildPopulatedMethodDispatch(mroByDefId, extendsOnlyMroByDefId) {
|
|
20
|
+
const base = {
|
|
21
21
|
mroByOwnerDefId: mroByDefId,
|
|
22
22
|
implsByInterfaceDefId: new Map(),
|
|
23
23
|
mroFor(ownerDefId) {
|
|
@@ -27,4 +27,14 @@ export function buildPopulatedMethodDispatch(mroByDefId) {
|
|
|
27
27
|
return EMPTY_DEFS;
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
|
+
if (extendsOnlyMroByDefId !== undefined) {
|
|
31
|
+
return {
|
|
32
|
+
...base,
|
|
33
|
+
extendsOnlyMroByOwnerDefId: extendsOnlyMroByDefId,
|
|
34
|
+
extendsOnlyMroFor(ownerDefId) {
|
|
35
|
+
return extendsOnlyMroByDefId.get(ownerDefId) ?? EMPTY_DEFS;
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return base;
|
|
30
40
|
}
|
|
@@ -105,6 +105,11 @@ export function isLinkableLabel(label) {
|
|
|
105
105
|
label === 'Interface' ||
|
|
106
106
|
label === 'Struct' ||
|
|
107
107
|
label === 'Enum' ||
|
|
108
|
+
// Trait nodes are linkable so MRO builders can bridge PHP/Rust trait
|
|
109
|
+
// defs between scope-resolution DefIds and the graph's node ids.
|
|
110
|
+
// IMPLEMENTS edges from classes to traits are otherwise invisible to
|
|
111
|
+
// the scope-resolution MRO pass.
|
|
112
|
+
label === 'Trait' ||
|
|
108
113
|
// Variable / Property are linkable too — receiver-bound write/read
|
|
109
114
|
// ACCESSES edges target field nodes (e.g. `user.name = "x"` →
|
|
110
115
|
// ACCESSES edge to User's `name` Variable/Property node).
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* Generic; promoted from `languages/python/scope-resolver.ts` per the scope-resolution
|
|
17
17
|
* generalization plan.
|
|
18
18
|
*/
|
|
19
|
-
import type { ParsedFile, Reference, ScopeId } from '../../../../_shared/index.js';
|
|
19
|
+
import type { ParsedFile, Reference, ScopeId, SymbolDefinition } from '../../../../_shared/index.js';
|
|
20
20
|
import type { KnowledgeGraph } from '../../../graph/types.js';
|
|
21
21
|
import type { ScopeResolutionIndexes } from '../../model/scope-resolution-indexes.js';
|
|
22
22
|
import type { SemanticModel } from '../../model/semantic-model.js';
|
|
@@ -26,4 +26,28 @@ export declare function emitFreeCallFallback(graph: KnowledgeGraph, scopes: Scop
|
|
|
26
26
|
readonly bySourceScope: ReadonlyMap<ScopeId, readonly Reference[]>;
|
|
27
27
|
}, handledSites: Set<string>, model: SemanticModel, workspaceIndex: WorkspaceResolutionIndex, options?: {
|
|
28
28
|
readonly allowGlobalFallback?: boolean;
|
|
29
|
+
readonly isFileLocalDef?: (def: SymbolDefinition) => boolean;
|
|
30
|
+
readonly isCallableVisibleFromCaller?: (ctx: {
|
|
31
|
+
readonly callerParsed: ParsedFile;
|
|
32
|
+
readonly candidate: SymbolDefinition;
|
|
33
|
+
}) => boolean;
|
|
29
34
|
}): number;
|
|
35
|
+
/** Walk up from the call-site scope to the enclosing class scope,
|
|
36
|
+
* pick a method member by name with overload narrowing on arity +
|
|
37
|
+
* argument types. Returns undefined if there's no enclosing class,
|
|
38
|
+
* no matching method, OR narrowing leaves multiple compatible
|
|
39
|
+
* candidates — in the multi-candidate case, picking
|
|
40
|
+
* `candidates[0]` would emit a high-confidence CALLS edge whose
|
|
41
|
+
* target depends on registration order rather than a defensible
|
|
42
|
+
* resolution. Mirrors `pickUniqueGlobalCallable`'s uniqueness check
|
|
43
|
+
* in the same file (Codex PR #1497 review, finding 2).
|
|
44
|
+
*
|
|
45
|
+
* Exported for unit testing — language-agnostic logic, exercised
|
|
46
|
+
* via synthetic stubs in `pick-implicit-this-overload.test.ts`. The
|
|
47
|
+
* production call site is `applyFreeCallFallback` immediately above. */
|
|
48
|
+
export declare function pickImplicitThisOverload(site: {
|
|
49
|
+
readonly inScope: ScopeId;
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly arity?: number;
|
|
52
|
+
readonly argumentTypes?: readonly string[];
|
|
53
|
+
}, scopes: ScopeResolutionIndexes, workspaceIndex: WorkspaceResolutionIndex, model: SemanticModel): SymbolDefinition | undefined;
|