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
package/dist/cli/analyze.js
CHANGED
|
@@ -86,6 +86,20 @@ function ensureHeap() {
|
|
|
86
86
|
}
|
|
87
87
|
return true;
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Whether the post-index skill step should run.
|
|
91
|
+
*
|
|
92
|
+
* The gated block does two things in sequence: (1) generates the community
|
|
93
|
+
* skill files from `--skills`, and (2) re-runs `generateAIContextFiles` so
|
|
94
|
+
* AGENTS.md/CLAUDE.md can reference the freshly written skills. Both are
|
|
95
|
+
* suppressed together — `--index-only` drops the entire step, not just the
|
|
96
|
+
* community-skill write. Name retained for the test contract; see call site
|
|
97
|
+
* in `analyzeCommand` for the AGENTS.md/CLAUDE.md re-generation it also gates.
|
|
98
|
+
*
|
|
99
|
+
* Kept as a pure helper so the `--index-only --skills` contract is unit-tested
|
|
100
|
+
* without booting the full analyze pipeline (#742 review).
|
|
101
|
+
*/
|
|
102
|
+
export const shouldGenerateCommunitySkillFiles = (options, pipelineResult) => Boolean(options?.skills && pipelineResult && !options?.indexOnly);
|
|
89
103
|
export const analyzeCommand = async (inputPath, options) => {
|
|
90
104
|
if (ensureHeap())
|
|
91
105
|
return;
|
|
@@ -151,6 +165,15 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
151
165
|
process.env.GITNEXUS_EMBEDDING_DEVICE = options.embeddingDevice;
|
|
152
166
|
}
|
|
153
167
|
console.log('\n GitNexus Analyzer\n');
|
|
168
|
+
// `--index-only` is the stronger contract — it suppresses every form of file
|
|
169
|
+
// injection, including community skill writes that `--skills` would normally
|
|
170
|
+
// produce. Surface the override explicitly so users don't wonder why a
|
|
171
|
+
// pipeline re-index ran but no skill files appeared. The pipeline still
|
|
172
|
+
// re-runs (see `force: options?.force || options?.skills` below); the warning
|
|
173
|
+
// is purely about the dropped post-index write step.
|
|
174
|
+
if (options?.indexOnly && options?.skills) {
|
|
175
|
+
console.log(' Note: --index-only overrides --skills; community skill files will not be written.\n');
|
|
176
|
+
}
|
|
154
177
|
let repoPath;
|
|
155
178
|
if (inputPath) {
|
|
156
179
|
repoPath = path.resolve(inputPath);
|
|
@@ -285,6 +308,9 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
285
308
|
const t0 = Date.now();
|
|
286
309
|
// ── Run shared analysis orchestrator ───────────────────────────────
|
|
287
310
|
try {
|
|
311
|
+
const skipAll = options?.indexOnly;
|
|
312
|
+
const skipAgentsMd = skipAll || options?.skipAgentsMd;
|
|
313
|
+
const skipSkills = skipAll || options?.skipSkills;
|
|
288
314
|
const result = await runFullAnalysis(repoPath, {
|
|
289
315
|
// Pipeline re-index — OR'd with --skills because skill generation
|
|
290
316
|
// needs a fresh pipelineResult. Has no bearing on the registry
|
|
@@ -294,8 +320,14 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
294
320
|
embeddingsNodeLimit,
|
|
295
321
|
dropEmbeddings: options?.dropEmbeddings,
|
|
296
322
|
skipGit: options?.skipGit,
|
|
297
|
-
skipAgentsMd
|
|
298
|
-
|
|
323
|
+
skipAgentsMd,
|
|
324
|
+
skipSkills,
|
|
325
|
+
// commander.js `.option('--no-stats', …)` registers the flag as
|
|
326
|
+
// `options.stats` (boolean, default true; `false` when the user
|
|
327
|
+
// passed --no-stats). Reading `options?.noStats` here returns
|
|
328
|
+
// undefined every time, so the flag was a no-op on the markdown
|
|
329
|
+
// rewrite path before this fix. See #1477.
|
|
330
|
+
noStats: options?.stats === false,
|
|
299
331
|
registryName: options?.name,
|
|
300
332
|
// Registry-collision bypass — its own CLI flag, intentionally NOT
|
|
301
333
|
// overloading --force. A user who hits the collision guard should
|
|
@@ -335,8 +367,10 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
335
367
|
// exit code and an actionable error instead of being mistaken for
|
|
336
368
|
// a healthy index.
|
|
337
369
|
await assertAnalysisFinalized(repoPath);
|
|
338
|
-
// Skill generation (CLI-only, uses pipeline result from analysis)
|
|
339
|
-
|
|
370
|
+
// Skill generation (CLI-only, uses pipeline result from analysis).
|
|
371
|
+
// Gated so `--index-only --skills` skips community skill writes too
|
|
372
|
+
// (`shouldGenerateCommunitySkillFiles` — see unit test).
|
|
373
|
+
if (shouldGenerateCommunitySkillFiles(options, result.pipelineResult)) {
|
|
340
374
|
updateBar(99, 'Generating skill files...');
|
|
341
375
|
try {
|
|
342
376
|
const { generateSkillFiles } = await import('./skill-gen.js');
|
|
@@ -364,7 +398,13 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
364
398
|
communities: s.communities,
|
|
365
399
|
clusters: aggregatedClusterCount,
|
|
366
400
|
processes: s.processes,
|
|
367
|
-
}, skillResult.skills, {
|
|
401
|
+
}, skillResult.skills, {
|
|
402
|
+
skipAgentsMd,
|
|
403
|
+
skipSkills,
|
|
404
|
+
// Mirror runFullAnalysis `noStats` bridge (#1477) — same expression;
|
|
405
|
+
// exercised on the `--skills` path by analyze-no-stats-bridge.test.ts.
|
|
406
|
+
noStats: options?.stats === false,
|
|
407
|
+
});
|
|
368
408
|
}
|
|
369
409
|
}
|
|
370
410
|
catch {
|
package/dist/cli/index.js
CHANGED
|
@@ -21,9 +21,14 @@ program
|
|
|
21
21
|
'Optional [limit] overrides the 50,000-node safety cap; pass 0 to disable the cap entirely.')
|
|
22
22
|
.option('--drop-embeddings', 'Drop existing embeddings on rebuild. By default, an `analyze` without `--embeddings` ' +
|
|
23
23
|
'preserves any embeddings already present in the index.')
|
|
24
|
-
.option('--skills', 'Generate repo-specific skill files from detected communities'
|
|
24
|
+
.option('--skills', 'Generate repo-specific skill files from detected communities ' +
|
|
25
|
+
'(no-op when --index-only is also set).')
|
|
25
26
|
.option('--skip-agents-md', 'Skip updating the gitnexus section in AGENTS.md and CLAUDE.md')
|
|
26
27
|
.option('--no-stats', 'Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md')
|
|
28
|
+
.option('--skip-skills', 'Skip installing standard GitNexus skill files under .claude/skills/gitnexus/. ' +
|
|
29
|
+
'Does not suppress community skills from --skills (those use .claude/skills/generated/). ' +
|
|
30
|
+
'Use --index-only to skip all AI-context file injection.')
|
|
31
|
+
.option('--index-only', 'Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)')
|
|
27
32
|
.option('--skip-git', 'Treat the provided path/cwd as the index root and skip parent git-root discovery')
|
|
28
33
|
.option('--name <alias>', 'Register this repo under a custom name in ~/.gitnexus/registry.json ' +
|
|
29
34
|
'(disambiguates repos whose paths share a basename, e.g. two different .../app folders)')
|
|
@@ -98,6 +103,8 @@ program
|
|
|
98
103
|
.option('--reasoning-model', 'Mark deployment as reasoning model (o1/o3/o4-mini) — strips temperature, uses max_completion_tokens')
|
|
99
104
|
.option('--no-reasoning-model', 'Disable reasoning model mode (overrides saved config)')
|
|
100
105
|
.option('--concurrency <n>', 'Parallel LLM calls (default: 3)', '3')
|
|
106
|
+
.option('--timeout <seconds>', 'Per-attempt LLM request timeout in seconds (default: 60)')
|
|
107
|
+
.option('--retries <n>', 'Max LLM retry attempts per request (default: 3)')
|
|
101
108
|
.option('--gist', 'Publish wiki as a public GitHub Gist after generation')
|
|
102
109
|
.option('-v, --verbose', 'Enable verbose output (show LLM commands and responses)')
|
|
103
110
|
.option('--review', 'Stop after grouping to review module structure before generating pages')
|
package/dist/cli/setup.js
CHANGED
|
@@ -308,6 +308,24 @@ async function installClaudeCodeHooks(result) {
|
|
|
308
308
|
catch {
|
|
309
309
|
// Script not found in source — skip
|
|
310
310
|
}
|
|
311
|
+
try {
|
|
312
|
+
await fs.copyFile(path.join(pluginHooksPath, 'hook-lock.cjs'), path.join(destHooksDir, 'hook-lock.cjs'));
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
// Helper not found in source — skip
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
await fs.copyFile(path.join(pluginHooksPath, 'hook-db-lock-probe.cjs'), path.join(destHooksDir, 'hook-db-lock-probe.cjs'));
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
// Helper not found in source — skip
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
await fs.copyFile(path.join(pluginHooksPath, 'win-rm-list-json.ps1'), path.join(destHooksDir, 'win-rm-list-json.ps1'));
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
// Helper not found in source — skip
|
|
328
|
+
}
|
|
311
329
|
const hookPath = path.join(destHooksDir, 'gitnexus-hook.cjs').replace(/\\/g, '/');
|
|
312
330
|
// Escape backslashes FIRST, then quotes (CodeQL js/incomplete-sanitization).
|
|
313
331
|
// The previous shape `replace(/"/g, '\\"')` alone would let `path\with"quote`
|
package/dist/cli/wiki.d.ts
CHANGED
package/dist/cli/wiki.js
CHANGED
|
@@ -304,6 +304,17 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
|
+
// ── Apply per-run overrides not saved to config ────────────────────
|
|
308
|
+
if (options?.timeout) {
|
|
309
|
+
const secs = parseInt(options.timeout, 10);
|
|
310
|
+
if (!isNaN(secs) && secs > 0)
|
|
311
|
+
llmConfig.requestTimeoutMs = secs * 1000;
|
|
312
|
+
}
|
|
313
|
+
if (options?.retries) {
|
|
314
|
+
const n = parseInt(options.retries, 10);
|
|
315
|
+
if (!isNaN(n) && n > 0)
|
|
316
|
+
llmConfig.maxAttempts = n;
|
|
317
|
+
}
|
|
307
318
|
// ── Setup progress bar with elapsed timer ──────────────────────────
|
|
308
319
|
const bar = new cliProgress.SingleBar({
|
|
309
320
|
format: ' {bar} {percentage}% | {phase}',
|
|
@@ -76,6 +76,9 @@ async function findRepoForCwd(cwd) {
|
|
|
76
76
|
export async function augment(pattern, cwd) {
|
|
77
77
|
if (!pattern || pattern.length < 3)
|
|
78
78
|
return '';
|
|
79
|
+
const patternFirstWord = pattern.trim().replace(/'/g, "''").split(/\s+/)[0];
|
|
80
|
+
if (!patternFirstWord || patternFirstWord.length < 2)
|
|
81
|
+
return '';
|
|
79
82
|
const workDir = cwd || process.cwd();
|
|
80
83
|
try {
|
|
81
84
|
const repo = await findRepoForCwd(workDir);
|
|
@@ -90,9 +93,7 @@ export async function augment(pattern, cwd) {
|
|
|
90
93
|
await initLbug(repoId, repo.lbugPath);
|
|
91
94
|
}
|
|
92
95
|
// Step 1: BM25 search (fast, no embeddings)
|
|
93
|
-
const { results: bm25Results } = await searchFTSFromLbug(pattern, 10, repoId);
|
|
94
|
-
if (bm25Results.length === 0)
|
|
95
|
-
return '';
|
|
96
|
+
const { results: bm25Results, ftsAvailable } = await searchFTSFromLbug(pattern, 10, repoId);
|
|
96
97
|
// Step 2: Map BM25 file results to symbols
|
|
97
98
|
const symbolMatches = [];
|
|
98
99
|
for (const result of bm25Results.slice(0, 5)) {
|
|
@@ -100,7 +101,7 @@ export async function augment(pattern, cwd) {
|
|
|
100
101
|
try {
|
|
101
102
|
const symbols = await executeQuery(repoId, `
|
|
102
103
|
MATCH (n) WHERE n.filePath = '${escaped}'
|
|
103
|
-
AND n.name CONTAINS '${
|
|
104
|
+
AND n.name CONTAINS '${patternFirstWord}'
|
|
104
105
|
RETURN n.id AS id, n.name AS name, labels(n)[0] AS type, n.filePath AS filePath
|
|
105
106
|
LIMIT 3
|
|
106
107
|
`);
|
|
@@ -118,6 +119,25 @@ export async function augment(pattern, cwd) {
|
|
|
118
119
|
/* skip */
|
|
119
120
|
}
|
|
120
121
|
}
|
|
122
|
+
// When FTS indexes are unavailable (read-only DB, first run before indexes are built),
|
|
123
|
+
// fall back to a direct name CONTAINS query so enrichment still works.
|
|
124
|
+
if (symbolMatches.length === 0 && !ftsAvailable) {
|
|
125
|
+
const fallbackRows = await executeQuery(repoId, `
|
|
126
|
+
MATCH (n)
|
|
127
|
+
WHERE n.name CONTAINS '${patternFirstWord}'
|
|
128
|
+
RETURN n.id AS id, n.name AS name, labels(n)[0] AS type, n.filePath AS filePath
|
|
129
|
+
LIMIT 5
|
|
130
|
+
`).catch(() => []);
|
|
131
|
+
for (const sym of fallbackRows) {
|
|
132
|
+
symbolMatches.push({
|
|
133
|
+
nodeId: sym.id || sym[0],
|
|
134
|
+
name: sym.name || sym[1],
|
|
135
|
+
type: sym.type || sym[2],
|
|
136
|
+
filePath: sym.filePath || sym[3],
|
|
137
|
+
score: 1.0,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
121
141
|
if (symbolMatches.length === 0)
|
|
122
142
|
return '';
|
|
123
143
|
// Step 3: Batch-fetch callers/callees/processes/cohesion for top matches
|
|
@@ -30,8 +30,11 @@ const readConfig = () => {
|
|
|
30
30
|
const rawDims = process.env.GITNEXUS_EMBEDDING_DIMS;
|
|
31
31
|
let dimensions;
|
|
32
32
|
if (rawDims !== undefined) {
|
|
33
|
+
if (!/^\d+$/.test(rawDims)) {
|
|
34
|
+
throw new Error(`GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${rawDims}"`);
|
|
35
|
+
}
|
|
33
36
|
const parsed = parseInt(rawDims, 10);
|
|
34
|
-
if (
|
|
37
|
+
if (parsed <= 0) {
|
|
35
38
|
throw new Error(`GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${rawDims}"`);
|
|
36
39
|
}
|
|
37
40
|
dimensions = parsed;
|
|
@@ -73,9 +76,22 @@ const safeUrl = (url) => {
|
|
|
73
76
|
* @param model - Model name for the request body
|
|
74
77
|
* @param apiKey - Bearer token (only used in Authorization header)
|
|
75
78
|
* @param batchIndex - Logical batch number (for error context)
|
|
76
|
-
* @param
|
|
79
|
+
* @param dimensions - Optional output-vector size. When provided, sent as
|
|
80
|
+
* the `dimensions` field in the request body. Endpoints that implement
|
|
81
|
+
* Matryoshka truncation (OpenAI text-embedding-3-*, Cohere embed-v3,
|
|
82
|
+
* Voyage) return a truncated vector at that size; endpoints that do not
|
|
83
|
+
* recognise the field may ignore it or return 400. Leave
|
|
84
|
+
* `GITNEXUS_EMBEDDING_DIMS` unset for strict backends that reject
|
|
85
|
+
* unknown fields.
|
|
77
86
|
*/
|
|
78
|
-
const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0) => {
|
|
87
|
+
const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0, dimensions) => {
|
|
88
|
+
const requestBody = {
|
|
89
|
+
input: batch,
|
|
90
|
+
model,
|
|
91
|
+
};
|
|
92
|
+
if (dimensions !== undefined) {
|
|
93
|
+
requestBody.dimensions = dimensions;
|
|
94
|
+
}
|
|
79
95
|
let resp;
|
|
80
96
|
try {
|
|
81
97
|
resp = await resilientFetch(url, {
|
|
@@ -85,7 +101,7 @@ const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0) => {
|
|
|
85
101
|
'Content-Type': 'application/json',
|
|
86
102
|
Authorization: `Bearer ${apiKey}`,
|
|
87
103
|
},
|
|
88
|
-
body: JSON.stringify(
|
|
104
|
+
body: JSON.stringify(requestBody),
|
|
89
105
|
}, {
|
|
90
106
|
breakerKey: HTTP_BREAKER_KEY,
|
|
91
107
|
retry: { maxAttempts: HTTP_MAX_RETRIES + 1, baseDelayMs: HTTP_RETRY_BACKOFF_MS },
|
|
@@ -130,7 +146,7 @@ export const httpEmbed = async (texts) => {
|
|
|
130
146
|
for (let i = 0; i < texts.length; i += HTTP_BATCH_SIZE) {
|
|
131
147
|
const batch = texts.slice(i, i + HTTP_BATCH_SIZE);
|
|
132
148
|
const batchIndex = Math.floor(i / HTTP_BATCH_SIZE);
|
|
133
|
-
const items = await httpEmbedBatch(url, batch, config.model, config.apiKey, batchIndex);
|
|
149
|
+
const items = await httpEmbedBatch(url, batch, config.model, config.apiKey, batchIndex, config.dimensions);
|
|
134
150
|
if (items.length !== batch.length) {
|
|
135
151
|
throw new Error(`Embedding endpoint returned ${items.length} vectors for ${batch.length} texts ` +
|
|
136
152
|
`(${safeUrl(url)}, batch ${batchIndex})`);
|
|
@@ -164,7 +180,7 @@ export const httpEmbedQuery = async (text) => {
|
|
|
164
180
|
if (!config)
|
|
165
181
|
throw new Error('HTTP embedding not configured');
|
|
166
182
|
const url = `${config.baseUrl}/embeddings`;
|
|
167
|
-
const items = await httpEmbedBatch(url, [text], config.model, config.apiKey);
|
|
183
|
+
const items = await httpEmbedBatch(url, [text], config.model, config.apiKey, 0, config.dimensions);
|
|
168
184
|
if (!items.length) {
|
|
169
185
|
throw new Error(`Embedding endpoint returned empty response (${safeUrl(url)})`);
|
|
170
186
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shadow-candidate path derivation for incremental indexing.
|
|
3
|
+
*
|
|
4
|
+
* Background — Bugbot review on PR #1479:
|
|
5
|
+
* queryImporters() on a NEWLY ADDED file returns 0 importers in the
|
|
6
|
+
* pre-pipeline DB, because the new file's IMPORTS rows haven't been
|
|
7
|
+
* written yet. But pre-existing files may have IMPORTS edges that
|
|
8
|
+
* *resolved to a sibling path*, and the newcomer can now steal that
|
|
9
|
+
* resolution under standard JS/TS module-resolution rules. Without
|
|
10
|
+
* pulling those pre-existing files into the writable set, their
|
|
11
|
+
* stale CALLS edges remain pointing at the OLD resolution target.
|
|
12
|
+
*
|
|
13
|
+
* Given an added file path, this helper enumerates the pre-existing
|
|
14
|
+
* file paths whose import-resolution claim the newcomer can steal.
|
|
15
|
+
* Caller filters the candidates against the prior-run `fileHashes`
|
|
16
|
+
* map so we only query importers of paths that actually existed.
|
|
17
|
+
*
|
|
18
|
+
* Shadow patterns covered (resolution-priority-aware):
|
|
19
|
+
*
|
|
20
|
+
* (a) Same basename, different extension —
|
|
21
|
+
* added `foo/bar.ts` shadows `foo/bar.{tsx,js,jsx,mjs,cjs,d.ts}`.
|
|
22
|
+
* (b) Bare-file beats directory-style index —
|
|
23
|
+
* added `foo/bar.ts` shadows `foo/bar/index.{ts,tsx,...}`.
|
|
24
|
+
* (c) Directory-index beats bare-file —
|
|
25
|
+
* added `foo/index.ts` shadows `foo.{ts,tsx,...}` (rare but real,
|
|
26
|
+
* e.g. converting a single-file module into a directory module).
|
|
27
|
+
*
|
|
28
|
+
* Resolution-order priority is conservatively wide: we enumerate ALL
|
|
29
|
+
* common extensions because we don't know which the importer actually
|
|
30
|
+
* specified, and over-seeding is harmless (extra BFS work, but the
|
|
31
|
+
* subgraph extract still gates write-back by file membership).
|
|
32
|
+
*
|
|
33
|
+
* Cross-platform path separators: candidates are emitted with both `/`
|
|
34
|
+
* and `\` for shadow pattern (b), since the caller's prior fileHashes
|
|
35
|
+
* map may use either depending on the OS that wrote it.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Enumerate pre-existing paths whose import-resolution `added` can steal.
|
|
39
|
+
*
|
|
40
|
+
* @param added — repo-relative path of a newly-added file
|
|
41
|
+
* @returns deduplicated list of candidate paths (NOT filtered against
|
|
42
|
+
* any known-files set — caller does that)
|
|
43
|
+
*/
|
|
44
|
+
export declare const shadowCandidatesFor: (added: string) => string[];
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shadow-candidate path derivation for incremental indexing.
|
|
3
|
+
*
|
|
4
|
+
* Background — Bugbot review on PR #1479:
|
|
5
|
+
* queryImporters() on a NEWLY ADDED file returns 0 importers in the
|
|
6
|
+
* pre-pipeline DB, because the new file's IMPORTS rows haven't been
|
|
7
|
+
* written yet. But pre-existing files may have IMPORTS edges that
|
|
8
|
+
* *resolved to a sibling path*, and the newcomer can now steal that
|
|
9
|
+
* resolution under standard JS/TS module-resolution rules. Without
|
|
10
|
+
* pulling those pre-existing files into the writable set, their
|
|
11
|
+
* stale CALLS edges remain pointing at the OLD resolution target.
|
|
12
|
+
*
|
|
13
|
+
* Given an added file path, this helper enumerates the pre-existing
|
|
14
|
+
* file paths whose import-resolution claim the newcomer can steal.
|
|
15
|
+
* Caller filters the candidates against the prior-run `fileHashes`
|
|
16
|
+
* map so we only query importers of paths that actually existed.
|
|
17
|
+
*
|
|
18
|
+
* Shadow patterns covered (resolution-priority-aware):
|
|
19
|
+
*
|
|
20
|
+
* (a) Same basename, different extension —
|
|
21
|
+
* added `foo/bar.ts` shadows `foo/bar.{tsx,js,jsx,mjs,cjs,d.ts}`.
|
|
22
|
+
* (b) Bare-file beats directory-style index —
|
|
23
|
+
* added `foo/bar.ts` shadows `foo/bar/index.{ts,tsx,...}`.
|
|
24
|
+
* (c) Directory-index beats bare-file —
|
|
25
|
+
* added `foo/index.ts` shadows `foo.{ts,tsx,...}` (rare but real,
|
|
26
|
+
* e.g. converting a single-file module into a directory module).
|
|
27
|
+
*
|
|
28
|
+
* Resolution-order priority is conservatively wide: we enumerate ALL
|
|
29
|
+
* common extensions because we don't know which the importer actually
|
|
30
|
+
* specified, and over-seeding is harmless (extra BFS work, but the
|
|
31
|
+
* subgraph extract still gates write-back by file membership).
|
|
32
|
+
*
|
|
33
|
+
* Cross-platform path separators: candidates are emitted with both `/`
|
|
34
|
+
* and `\` for shadow pattern (b), since the caller's prior fileHashes
|
|
35
|
+
* map may use either depending on the OS that wrote it.
|
|
36
|
+
*/
|
|
37
|
+
const SHADOW_EXTS = ['.d.ts', '.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'];
|
|
38
|
+
/**
|
|
39
|
+
* Enumerate pre-existing paths whose import-resolution `added` can steal.
|
|
40
|
+
*
|
|
41
|
+
* @param added — repo-relative path of a newly-added file
|
|
42
|
+
* @returns deduplicated list of candidate paths (NOT filtered against
|
|
43
|
+
* any known-files set — caller does that)
|
|
44
|
+
*/
|
|
45
|
+
export const shadowCandidatesFor = (added) => {
|
|
46
|
+
const ext = SHADOW_EXTS.find((e) => added.endsWith(e));
|
|
47
|
+
if (!ext)
|
|
48
|
+
return [];
|
|
49
|
+
const noExt = added.slice(0, -ext.length);
|
|
50
|
+
const out = new Set();
|
|
51
|
+
// (a) Same basename, different extension.
|
|
52
|
+
for (const alt of SHADOW_EXTS) {
|
|
53
|
+
if (alt !== ext)
|
|
54
|
+
out.add(noExt + alt);
|
|
55
|
+
}
|
|
56
|
+
// (b) Bare file beats sibling directory-style index.
|
|
57
|
+
for (const idx of SHADOW_EXTS) {
|
|
58
|
+
out.add(`${noExt}/index${idx}`);
|
|
59
|
+
out.add(`${noExt}\\index${idx}`);
|
|
60
|
+
}
|
|
61
|
+
// (c) New `foo/index.ext` shadows old `foo.ext`.
|
|
62
|
+
const idxSuffixSlash = '/index';
|
|
63
|
+
const idxSuffixBack = '\\index';
|
|
64
|
+
let dir = null;
|
|
65
|
+
if (noExt.endsWith(idxSuffixSlash))
|
|
66
|
+
dir = noExt.slice(0, -idxSuffixSlash.length);
|
|
67
|
+
else if (noExt.endsWith(idxSuffixBack))
|
|
68
|
+
dir = noExt.slice(0, -idxSuffixBack.length);
|
|
69
|
+
if (dir !== null) {
|
|
70
|
+
for (const alt of SHADOW_EXTS)
|
|
71
|
+
out.add(dir + alt);
|
|
72
|
+
}
|
|
73
|
+
return [...out];
|
|
74
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subgraph extraction for incremental DB writeback.
|
|
3
|
+
*
|
|
4
|
+
* Given the FULL ctx.graph produced by the pipeline (all files parsed,
|
|
5
|
+
* all phases run) and the set of file paths whose DB rows must be
|
|
6
|
+
* replaced, produce a smaller KnowledgeGraph that contains:
|
|
7
|
+
*
|
|
8
|
+
* - Every node whose `properties.filePath` is in `toWriteSet`.
|
|
9
|
+
* - Every graph-wide node (Community, Process) — these are regenerated
|
|
10
|
+
* each run by the communities/processes phases and must be fully
|
|
11
|
+
* rewritten.
|
|
12
|
+
* - Every relationship where AT LEAST ONE endpoint is in the writable
|
|
13
|
+
* set above. Relationships entirely between unchanged-file nodes
|
|
14
|
+
* are skipped — their rows are still in the DB and re-inserting
|
|
15
|
+
* them would PK-conflict at COPY time.
|
|
16
|
+
*
|
|
17
|
+
* The resulting subgraph is what gets passed to `loadGraphToLbug` after
|
|
18
|
+
* the orchestrator has deleted the corresponding DB rows. Hydrated
|
|
19
|
+
* unchanged-file rows are never touched in the DB.
|
|
20
|
+
*
|
|
21
|
+
* # Cross-file edge consistency (Finding 1)
|
|
22
|
+
*
|
|
23
|
+
* `extractChangedSubgraph` intentionally does NOT expand the set it is
|
|
24
|
+
* given — expansion is the orchestrator's job, so the SAME expanded set
|
|
25
|
+
* can be fed to both `deleteNodesForFile` and this function (asymmetry
|
|
26
|
+
* between the delete set and the write set silently corrupts the DB).
|
|
27
|
+
* `computeEffectiveWriteSet` below performs the boundary-crossing 1-hop
|
|
28
|
+
* walk; the orchestrator composes it with its importer-BFS expansion and
|
|
29
|
+
* passes the result here.
|
|
30
|
+
*
|
|
31
|
+
* Why the 1-hop walk is needed: consider a barrel re-export change —
|
|
32
|
+
* file C (a barrel) shifts `export { foo } from './b'` to
|
|
33
|
+
* `export { foo } from './d'`. After scope resolution, file A's CALLS
|
|
34
|
+
* edge to `foo` resolves to D instead of B, even though A's content is
|
|
35
|
+
* byte-for-byte identical:
|
|
36
|
+
*
|
|
37
|
+
* - Old A→B edge survives in DB (neither A nor B is changed → not deleted)
|
|
38
|
+
* - New A→D edge is missing (neither A nor D in writable set → skipped)
|
|
39
|
+
*
|
|
40
|
+
* Pulling the unchanged-side file of every writable-boundary-crossing
|
|
41
|
+
* edge into the write set fixes both halves: the orchestrator's
|
|
42
|
+
* `DETACH DELETE` cleans up the stale unchanged-side rows, and the new
|
|
43
|
+
* cross-file edges land because at least one endpoint is now writable.
|
|
44
|
+
*
|
|
45
|
+
* Limitation (documented): if a file X *stopped* importing from a
|
|
46
|
+
* changed file C, X has no edge to C in the new graph, so this 1-hop
|
|
47
|
+
* walk doesn't catch it. The orchestrator's importer-BFS (which reads
|
|
48
|
+
* IMPORTS from the pre-pipeline DB) covers that case instead.
|
|
49
|
+
*/
|
|
50
|
+
import type { KnowledgeGraph } from '../graph/types.js';
|
|
51
|
+
export declare const extractChangedSubgraph: (fullGraph: KnowledgeGraph, toWriteSet: ReadonlySet<string>) => KnowledgeGraph;
|
|
52
|
+
/**
|
|
53
|
+
* Public — derive the EFFECTIVE write-set: `toWriteSet` expanded by one
|
|
54
|
+
* hop along every edge in the new graph that crosses the writable
|
|
55
|
+
* boundary (one endpoint in a writable file, the other in an unchanged
|
|
56
|
+
* file). The unchanged-side file is pulled in so its stale rows are
|
|
57
|
+
* deleted + rewritten in lockstep with the changed side.
|
|
58
|
+
*
|
|
59
|
+
* Single pass over the edge list. Does NOT mutate `toWriteSet`. The
|
|
60
|
+
* orchestrator MUST feed the returned set to both `deleteNodesForFile`
|
|
61
|
+
* and `extractChangedSubgraph` — feeding the unexpanded set to either
|
|
62
|
+
* one leaves stale rows or PK-conflicts at COPY time.
|
|
63
|
+
*/
|
|
64
|
+
export declare const computeEffectiveWriteSet: (fullGraph: KnowledgeGraph, toWriteSet: ReadonlySet<string>) => Set<string>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subgraph extraction for incremental DB writeback.
|
|
3
|
+
*
|
|
4
|
+
* Given the FULL ctx.graph produced by the pipeline (all files parsed,
|
|
5
|
+
* all phases run) and the set of file paths whose DB rows must be
|
|
6
|
+
* replaced, produce a smaller KnowledgeGraph that contains:
|
|
7
|
+
*
|
|
8
|
+
* - Every node whose `properties.filePath` is in `toWriteSet`.
|
|
9
|
+
* - Every graph-wide node (Community, Process) — these are regenerated
|
|
10
|
+
* each run by the communities/processes phases and must be fully
|
|
11
|
+
* rewritten.
|
|
12
|
+
* - Every relationship where AT LEAST ONE endpoint is in the writable
|
|
13
|
+
* set above. Relationships entirely between unchanged-file nodes
|
|
14
|
+
* are skipped — their rows are still in the DB and re-inserting
|
|
15
|
+
* them would PK-conflict at COPY time.
|
|
16
|
+
*
|
|
17
|
+
* The resulting subgraph is what gets passed to `loadGraphToLbug` after
|
|
18
|
+
* the orchestrator has deleted the corresponding DB rows. Hydrated
|
|
19
|
+
* unchanged-file rows are never touched in the DB.
|
|
20
|
+
*
|
|
21
|
+
* # Cross-file edge consistency (Finding 1)
|
|
22
|
+
*
|
|
23
|
+
* `extractChangedSubgraph` intentionally does NOT expand the set it is
|
|
24
|
+
* given — expansion is the orchestrator's job, so the SAME expanded set
|
|
25
|
+
* can be fed to both `deleteNodesForFile` and this function (asymmetry
|
|
26
|
+
* between the delete set and the write set silently corrupts the DB).
|
|
27
|
+
* `computeEffectiveWriteSet` below performs the boundary-crossing 1-hop
|
|
28
|
+
* walk; the orchestrator composes it with its importer-BFS expansion and
|
|
29
|
+
* passes the result here.
|
|
30
|
+
*
|
|
31
|
+
* Why the 1-hop walk is needed: consider a barrel re-export change —
|
|
32
|
+
* file C (a barrel) shifts `export { foo } from './b'` to
|
|
33
|
+
* `export { foo } from './d'`. After scope resolution, file A's CALLS
|
|
34
|
+
* edge to `foo` resolves to D instead of B, even though A's content is
|
|
35
|
+
* byte-for-byte identical:
|
|
36
|
+
*
|
|
37
|
+
* - Old A→B edge survives in DB (neither A nor B is changed → not deleted)
|
|
38
|
+
* - New A→D edge is missing (neither A nor D in writable set → skipped)
|
|
39
|
+
*
|
|
40
|
+
* Pulling the unchanged-side file of every writable-boundary-crossing
|
|
41
|
+
* edge into the write set fixes both halves: the orchestrator's
|
|
42
|
+
* `DETACH DELETE` cleans up the stale unchanged-side rows, and the new
|
|
43
|
+
* cross-file edges land because at least one endpoint is now writable.
|
|
44
|
+
*
|
|
45
|
+
* Limitation (documented): if a file X *stopped* importing from a
|
|
46
|
+
* changed file C, X has no edge to C in the new graph, so this 1-hop
|
|
47
|
+
* walk doesn't catch it. The orchestrator's importer-BFS (which reads
|
|
48
|
+
* IMPORTS from the pre-pipeline DB) covers that case instead.
|
|
49
|
+
*/
|
|
50
|
+
import { createKnowledgeGraph } from '../graph/graph.js';
|
|
51
|
+
const isGraphWide = (label) => label === 'Community' || label === 'Process';
|
|
52
|
+
/**
|
|
53
|
+
* Build a Map<nodeId, filePath> for every File-bound node in the graph.
|
|
54
|
+
* Graph-wide nodes (Community/Process) have no filePath and are filtered.
|
|
55
|
+
*/
|
|
56
|
+
const indexNodeFilePaths = (fullGraph) => {
|
|
57
|
+
const idx = new Map();
|
|
58
|
+
fullGraph.forEachNode((n) => {
|
|
59
|
+
const fp = n.properties?.filePath;
|
|
60
|
+
if (fp)
|
|
61
|
+
idx.set(n.id, fp);
|
|
62
|
+
});
|
|
63
|
+
return idx;
|
|
64
|
+
};
|
|
65
|
+
export const extractChangedSubgraph = (fullGraph, toWriteSet) => {
|
|
66
|
+
const sub = createKnowledgeGraph();
|
|
67
|
+
const writableNodeIds = new Set();
|
|
68
|
+
fullGraph.forEachNode((n) => {
|
|
69
|
+
const filePath = n.properties?.filePath;
|
|
70
|
+
const include = (filePath && toWriteSet.has(filePath)) || isGraphWide(n.label);
|
|
71
|
+
if (include) {
|
|
72
|
+
sub.addNode(n);
|
|
73
|
+
writableNodeIds.add(n.id);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
fullGraph.forEachRelationship((r) => {
|
|
77
|
+
if (writableNodeIds.has(r.sourceId) || writableNodeIds.has(r.targetId)) {
|
|
78
|
+
sub.addRelationship(r);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return sub;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Public — derive the EFFECTIVE write-set: `toWriteSet` expanded by one
|
|
85
|
+
* hop along every edge in the new graph that crosses the writable
|
|
86
|
+
* boundary (one endpoint in a writable file, the other in an unchanged
|
|
87
|
+
* file). The unchanged-side file is pulled in so its stale rows are
|
|
88
|
+
* deleted + rewritten in lockstep with the changed side.
|
|
89
|
+
*
|
|
90
|
+
* Single pass over the edge list. Does NOT mutate `toWriteSet`. The
|
|
91
|
+
* orchestrator MUST feed the returned set to both `deleteNodesForFile`
|
|
92
|
+
* and `extractChangedSubgraph` — feeding the unexpanded set to either
|
|
93
|
+
* one leaves stale rows or PK-conflicts at COPY time.
|
|
94
|
+
*/
|
|
95
|
+
export const computeEffectiveWriteSet = (fullGraph, toWriteSet) => {
|
|
96
|
+
const nodeFilePaths = indexNodeFilePaths(fullGraph);
|
|
97
|
+
const expanded = new Set(toWriteSet);
|
|
98
|
+
fullGraph.forEachRelationship((r) => {
|
|
99
|
+
const sourcePath = nodeFilePaths.get(r.sourceId);
|
|
100
|
+
const targetPath = nodeFilePaths.get(r.targetId);
|
|
101
|
+
if (!sourcePath || !targetPath)
|
|
102
|
+
return; // skip edges to graph-wide nodes
|
|
103
|
+
const sourceWritable = toWriteSet.has(sourcePath);
|
|
104
|
+
const targetWritable = toWriteSet.has(targetPath);
|
|
105
|
+
if (sourceWritable && !targetWritable)
|
|
106
|
+
expanded.add(targetPath);
|
|
107
|
+
else if (targetWritable && !sourceWritable)
|
|
108
|
+
expanded.add(sourcePath);
|
|
109
|
+
});
|
|
110
|
+
return expanded;
|
|
111
|
+
};
|
|
@@ -2,8 +2,10 @@ import { KnowledgeGraph } from '../graph/types.js';
|
|
|
2
2
|
import { ASTCache } from './ast-cache.js';
|
|
3
3
|
import type { SymbolDefinition } from '../../_shared/index.js';
|
|
4
4
|
import type { SymbolTableReader, HeritageMap, ExtractedHeritage } from './model/index.js';
|
|
5
|
+
import Parser from 'tree-sitter';
|
|
5
6
|
import type { ResolutionContext } from './model/resolution-context.js';
|
|
6
7
|
import type { TieredCandidates } from './model/resolution-context.js';
|
|
8
|
+
import { SupportedLanguages } from '../../_shared/index.js';
|
|
7
9
|
import type { TypeEnvironment } from './type-env.js';
|
|
8
10
|
import type { BindingAccumulator } from './binding-accumulator.js';
|
|
9
11
|
import type { ExtractedCall, ExtractedAssignment, ExtractedRoute, ExtractedFetchCall, FileConstructorBindings } from './workers/parse-worker.js';
|
|
@@ -73,7 +75,16 @@ importedBindingsMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
|
|
|
73
75
|
* Consulted ONLY when SymbolTable has no unambiguous match (local-first principle). */
|
|
74
76
|
importedReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
|
|
75
77
|
/** Phase 14 E3: cross-file RAW return types for for-loop element extraction. Keyed by filePath → Map<calleeName, rawReturnType>. */
|
|
76
|
-
importedRawReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>, heritageMap?: HeritageMap, bindingAccumulator?: BindingAccumulator
|
|
78
|
+
importedRawReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>, heritageMap?: HeritageMap, bindingAccumulator?: BindingAccumulator,
|
|
79
|
+
/**
|
|
80
|
+
* Optional cache for compiled `Parser.Query` objects keyed by language name.
|
|
81
|
+
* When provided, compiled queries are reused across calls instead of being
|
|
82
|
+
* re-compiled from the query string for every file. Callers that invoke
|
|
83
|
+
* `processCalls` many times with single-file batches (e.g. the cross-file
|
|
84
|
+
* propagation phase) should pass a long-lived map here to avoid O(N)
|
|
85
|
+
* query recompilation overhead.
|
|
86
|
+
*/
|
|
87
|
+
compiledQueryCache?: Map<SupportedLanguages, Parser.Query>) => Promise<ExtractedHeritage[]>;
|
|
77
88
|
/** Per-file cache for module-alias widening. Cleared between files. */
|
|
78
89
|
type WidenCache = Map<string, readonly SymbolDefinition[]>;
|
|
79
90
|
/**
|