codebaseiq 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +481 -0
- package/LICENSE +202 -0
- package/README.md +349 -0
- package/dist/augment-vue-worker.js +2 -0
- package/dist/call-graph-evidence-gNsxjCW8.d.ts +16 -0
- package/dist/change-analysis-types-CCtoCHbC.d.ts +9 -0
- package/dist/chunk-2Q2LW5JW.js +14 -0
- package/dist/chunk-2X7V4HS4.js +88 -0
- package/dist/chunk-34WBMAYK.js +2 -0
- package/dist/chunk-35NLDRZC.js +2 -0
- package/dist/chunk-362QOSFD.js +3 -0
- package/dist/chunk-3IER7Q6H.js +12 -0
- package/dist/chunk-3JSXXYTZ.js +345 -0
- package/dist/chunk-3LCDIREB.js +4 -0
- package/dist/chunk-476NR5B7.js +2 -0
- package/dist/chunk-4FC325IF.js +30 -0
- package/dist/chunk-4WKDMDEW.js +9 -0
- package/dist/chunk-4XTAUQFD.js +2 -0
- package/dist/chunk-5PUWMSDU.js +26 -0
- package/dist/chunk-5VKBFZZU.js +3 -0
- package/dist/chunk-6BQ3DSPK.js +2 -0
- package/dist/chunk-6CS3UQTN.js +3 -0
- package/dist/chunk-6MUIJMVL.js +6 -0
- package/dist/chunk-6NW7MU72.js +40 -0
- package/dist/chunk-6OAHRI2D.js +6 -0
- package/dist/chunk-6YTSKJJ3.js +2 -0
- package/dist/chunk-7FND7D7N.js +2 -0
- package/dist/chunk-7MGU3HPH.js +2 -0
- package/dist/chunk-7NVGT435.js +2 -0
- package/dist/chunk-7XAN6GKB.js +2 -0
- package/dist/chunk-AAQQPKCU.js +2 -0
- package/dist/chunk-ADTBPVUZ.js +21 -0
- package/dist/chunk-AKB7V7TV.js +2 -0
- package/dist/chunk-ANFVSJWQ.js +11 -0
- package/dist/chunk-B2OB55RR.js +3 -0
- package/dist/chunk-B3UYV66Z.js +4 -0
- package/dist/chunk-B75HZHUP.js +2 -0
- package/dist/chunk-BFFZDZQV.js +2 -0
- package/dist/chunk-BGBBVSH4.js +2 -0
- package/dist/chunk-BH5F2Q4O.js +2 -0
- package/dist/chunk-BJ6SQAEN.js +2 -0
- package/dist/chunk-BMYOV5GP.js +77 -0
- package/dist/chunk-BVAJLC5A.js +7 -0
- package/dist/chunk-C6SBF2WH.js +4 -0
- package/dist/chunk-C74PPYLA.js +3 -0
- package/dist/chunk-C7QOQX32.js +8 -0
- package/dist/chunk-CAUCPUOF.js +7 -0
- package/dist/chunk-CO5R3UNA.js +2 -0
- package/dist/chunk-CQP3THUZ.js +7 -0
- package/dist/chunk-CVYSU6BX.js +16 -0
- package/dist/chunk-CWONGW6P.js +3 -0
- package/dist/chunk-DDZ7VHWV.js +20 -0
- package/dist/chunk-DGXRDLV5.js +2 -0
- package/dist/chunk-DO6WQD2T.js +3 -0
- package/dist/chunk-DQMDCD24.js +2 -0
- package/dist/chunk-DR2LURYU.js +3 -0
- package/dist/chunk-DRENNWRG.js +2 -0
- package/dist/chunk-ECQBG7PW.js +564 -0
- package/dist/chunk-EF2R3WNQ.js +2 -0
- package/dist/chunk-ELNRLMC5.js +29 -0
- package/dist/chunk-EMNIHCRB.js +18 -0
- package/dist/chunk-ENCCHKM6.js +5 -0
- package/dist/chunk-EZNMUY67.js +5 -0
- package/dist/chunk-FAJQ7LWY.js +3 -0
- package/dist/chunk-FDGD5AB5.js +2 -0
- package/dist/chunk-FETNQCFO.js +117 -0
- package/dist/chunk-FM5BPL4V.js +60 -0
- package/dist/chunk-FQKZWM4L.js +49 -0
- package/dist/chunk-FW53T7EB.js +2 -0
- package/dist/chunk-G6XFR4ZL.js +4 -0
- package/dist/chunk-GCHRX4YW.js +4 -0
- package/dist/chunk-GTIYTDRE.js +562 -0
- package/dist/chunk-GTXSJDCO.js +2 -0
- package/dist/chunk-GW6Z3WGY.js +2 -0
- package/dist/chunk-H3LGFZVK.js +2 -0
- package/dist/chunk-HKQUXIFO.js +2 -0
- package/dist/chunk-HOA5YGOH.js +3 -0
- package/dist/chunk-HPJRBHVT.js +3 -0
- package/dist/chunk-HRWGYWRJ.js +49 -0
- package/dist/chunk-I2T2LLK2.js +4 -0
- package/dist/chunk-ICFDQHAM.js +3 -0
- package/dist/chunk-ID63777H.js +4 -0
- package/dist/chunk-IJ4HMYBE.js +3 -0
- package/dist/chunk-ILMHV3KM.js +2 -0
- package/dist/chunk-IOP6FWIM.js +2 -0
- package/dist/chunk-IRQOAM5G.js +2 -0
- package/dist/chunk-J77SU6VA.js +38 -0
- package/dist/chunk-JE3WZ6II.js +2 -0
- package/dist/chunk-JEJLSICM.js +4 -0
- package/dist/chunk-JOIRNPPY.js +2 -0
- package/dist/chunk-JSOYNVWH.js +3 -0
- package/dist/chunk-KMITESMT.js +2 -0
- package/dist/chunk-KUW32IRO.js +2 -0
- package/dist/chunk-KWVHSKHK.js +31 -0
- package/dist/chunk-L4NRUAGJ.js +18 -0
- package/dist/chunk-L57ZKWVG.js +6 -0
- package/dist/chunk-LTA3BRZX.js +2 -0
- package/dist/chunk-LU3BMVH2.js +10 -0
- package/dist/chunk-LZYFLFEH.js +2 -0
- package/dist/chunk-MOVBWNIP.js +16 -0
- package/dist/chunk-MVB3DAEY.js +3 -0
- package/dist/chunk-N3IQCBCF.js +29 -0
- package/dist/chunk-NAUD7LCA.js +2 -0
- package/dist/chunk-NCZUNH3E.js +109 -0
- package/dist/chunk-NE6IU5ZD.js +5 -0
- package/dist/chunk-NEDP5RFQ.js +60 -0
- package/dist/chunk-NMTSZXCL.js +2 -0
- package/dist/chunk-NNJ2KZZG.js +4 -0
- package/dist/chunk-NNO6A2PO.js +2 -0
- package/dist/chunk-NNOKTMZT.js +20 -0
- package/dist/chunk-O6QTXQPJ.js +13 -0
- package/dist/chunk-OANDYLJQ.js +2 -0
- package/dist/chunk-OFBE4NGP.js +2 -0
- package/dist/chunk-OGTFJ3XD.js +2 -0
- package/dist/chunk-OL6KJP3N.js +16 -0
- package/dist/chunk-OLF4MA5W.js +8 -0
- package/dist/chunk-OTOKVOJ3.js +2 -0
- package/dist/chunk-OVTS4DKB.js +2 -0
- package/dist/chunk-OZYRSMSH.js +3 -0
- package/dist/chunk-P5XHIJHI.js +2 -0
- package/dist/chunk-PBI2LFKH.js +2 -0
- package/dist/chunk-PIOMTC27.js +2 -0
- package/dist/chunk-PTAWHLVJ.js +6 -0
- package/dist/chunk-PX4RYAAK.js +2 -0
- package/dist/chunk-PYAB5SM6.js +7 -0
- package/dist/chunk-Q5ELPRKQ.js +2 -0
- package/dist/chunk-Q65CQ4XL.js +2 -0
- package/dist/chunk-Q72QSKXC.js +308 -0
- package/dist/chunk-QCN62RTF.js +3 -0
- package/dist/chunk-QDCCHMVZ.js +2 -0
- package/dist/chunk-QHRNXP3C.js +3 -0
- package/dist/chunk-QKPLA6IC.js +2 -0
- package/dist/chunk-QOKYJ33H.js +2 -0
- package/dist/chunk-QW7EP6WI.js +21 -0
- package/dist/chunk-R2NOK63J.js +4 -0
- package/dist/chunk-RBAS5ZHI.js +2 -0
- package/dist/chunk-RDBI2RXU.js +9 -0
- package/dist/chunk-RKEJ6VTF.js +73 -0
- package/dist/chunk-RR7SX44N.js +35 -0
- package/dist/chunk-RU65DDUP.js +215 -0
- package/dist/chunk-SELM5MER.js +2 -0
- package/dist/chunk-SGX43S2L.js +2 -0
- package/dist/chunk-SMRBZ6EC.js +2 -0
- package/dist/chunk-SNNWPCN7.js +4 -0
- package/dist/chunk-ST7V3SKN.js +2 -0
- package/dist/chunk-SWHMHUKF.js +2 -0
- package/dist/chunk-SYDJMPES.js +2 -0
- package/dist/chunk-SZD2KF7Q.js +2 -0
- package/dist/chunk-T3DGWPXM.js +3 -0
- package/dist/chunk-TFZB6XTM.js +239 -0
- package/dist/chunk-TIIC3ZE7.js +2 -0
- package/dist/chunk-TRRC4ZJ7.js +2 -0
- package/dist/chunk-TXXOEMZJ.js +2 -0
- package/dist/chunk-UBGWN7I4.js +2 -0
- package/dist/chunk-UCD3H3UZ.js +5 -0
- package/dist/chunk-UDS562V4.js +5 -0
- package/dist/chunk-UNBY47BC.js +3 -0
- package/dist/chunk-UP3BUZR5.js +74 -0
- package/dist/chunk-UXM43C7T.js +3 -0
- package/dist/chunk-UZGZB3VB.js +3 -0
- package/dist/chunk-VE5AVNMP.js +2 -0
- package/dist/chunk-VEXUL62T.js +2 -0
- package/dist/chunk-VFY6Y2H6.js +61 -0
- package/dist/chunk-VUIYB2V3.js +2 -0
- package/dist/chunk-VXYS3FZD.js +23 -0
- package/dist/chunk-WE5RZHZ7.js +5 -0
- package/dist/chunk-WMPRTGH2.js +2 -0
- package/dist/chunk-WOQBZPIF.js +2 -0
- package/dist/chunk-XLQ3GLWZ.js +2 -0
- package/dist/chunk-XME3HPXZ.js +2 -0
- package/dist/chunk-XMQ23E27.js +2 -0
- package/dist/chunk-XWUOUWYI.js +2 -0
- package/dist/chunk-XZEE23VG.js +5 -0
- package/dist/chunk-Y6KHROC3.js +7 -0
- package/dist/chunk-YESXMKX3.js +3 -0
- package/dist/chunk-YMGZZEW4.js +2 -0
- package/dist/chunk-YSNONTJ2.js +2 -0
- package/dist/chunk-YUKYB54I.js +1 -0
- package/dist/chunk-YVCIMIOC.js +12 -0
- package/dist/chunk-Z54RD7VL.js +3 -0
- package/dist/chunk-ZKX2FRS6.js +15 -0
- package/dist/chunk-ZMI2JSX2.js +2 -0
- package/dist/chunk-ZV3JV5G5.js +8 -0
- package/dist/chunk-ZZ3MWF33.js +4 -0
- package/dist/chunk-ZZXSWSN6.js +2 -0
- package/dist/cli-context-3SNLDYBM.js +3 -0
- package/dist/cli-context-T3B7W6GG.js +2 -0
- package/dist/cli-program-YNOXO72B.js +7 -0
- package/dist/cli.js +3 -0
- package/dist/code-DlqpBDd0.d.ts +121 -0
- package/dist/command-descriptors-6AOUKWW7.js +346 -0
- package/dist/command-descriptors-ZFKJSRUP.js +344 -0
- package/dist/command-panels-SZONPMLJ.js +3 -0
- package/dist/config-types-BNoC96J3.d.ts +560 -0
- package/dist/db-D7sauVFH.d.ts +95 -0
- package/dist/direct-navigation-DP4LVMRX.js +3 -0
- package/dist/direct-navigation-FLUS3BT6.js +2 -0
- package/dist/exploration-topology-BG4v30HZ.d.ts +256 -0
- package/dist/file-dep-graph-Bqg3t3Px.d.ts +4 -0
- package/dist/file-kind-BKCVMNUf.d.ts +10 -0
- package/dist/frontend-behavior-evidence-EfM4_9bc.d.ts +4 -0
- package/dist/git-history-ChNHbfZQ.d.ts +13 -0
- package/dist/graph-evidence-BIFqyisO.d.ts +131 -0
- package/dist/health-DJaZXg8I.d.ts +340 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.js +2 -0
- package/dist/invocation-command-descriptors-QT2JMY5J.js +3 -0
- package/dist/invocation-command-descriptors-YN4QJEAX.js +2 -0
- package/dist/next-anchor-candidates-BwMczMvX.d.ts +90 -0
- package/dist/output-continuation-command-2V2SL4TD.js +2 -0
- package/dist/output-continuation-command-65J5IP3O.js +3 -0
- package/dist/postinstall.js +3 -0
- package/dist/project-reindex-5JOKXAXT.js +2 -0
- package/dist/project-reindex-UQBIKO4M.js +3 -0
- package/dist/queries/affected.d.ts +40 -0
- package/dist/queries/affected.js +2 -0
- package/dist/queries/anchors.d.ts +123 -0
- package/dist/queries/anchors.js +2 -0
- package/dist/queries/architecture.d.ts +166 -0
- package/dist/queries/architecture.js +2 -0
- package/dist/queries/bottlenecks.d.ts +68 -0
- package/dist/queries/bottlenecks.js +2 -0
- package/dist/queries/by-kind.d.ts +27 -0
- package/dist/queries/by-kind.js +2 -0
- package/dist/queries/call-graph.d.ts +52 -0
- package/dist/queries/call-graph.js +2 -0
- package/dist/queries/change-surface.d.ts +55 -0
- package/dist/queries/change-surface.js +2 -0
- package/dist/queries/cleanup-plan.d.ts +66 -0
- package/dist/queries/cleanup-plan.js +2 -0
- package/dist/queries/co-change.d.ts +90 -0
- package/dist/queries/co-change.js +2 -0
- package/dist/queries/code.d.ts +6 -0
- package/dist/queries/code.js +2 -0
- package/dist/queries/complexity-hotspots.d.ts +61 -0
- package/dist/queries/complexity-hotspots.js +2 -0
- package/dist/queries/complexity.d.ts +74 -0
- package/dist/queries/complexity.js +2 -0
- package/dist/queries/context.d.ts +146 -0
- package/dist/queries/context.js +2 -0
- package/dist/queries/convergence.d.ts +33 -0
- package/dist/queries/convergence.js +2 -0
- package/dist/queries/coupling.d.ts +32 -0
- package/dist/queries/coupling.js +2 -0
- package/dist/queries/cycles.d.ts +66 -0
- package/dist/queries/cycles.js +2 -0
- package/dist/queries/dataflow.d.ts +77 -0
- package/dist/queries/dataflow.js +2 -0
- package/dist/queries/dead.d.ts +58 -0
- package/dist/queries/dead.js +2 -0
- package/dist/queries/decorative-checkers.d.ts +34 -0
- package/dist/queries/decorative-checkers.js +2 -0
- package/dist/queries/deep-chains.d.ts +5 -0
- package/dist/queries/deep-chains.js +2 -0
- package/dist/queries/dependence-slice.d.ts +46 -0
- package/dist/queries/dependence-slice.js +2 -0
- package/dist/queries/dependency-depth.d.ts +49 -0
- package/dist/queries/dependency-depth.js +2 -0
- package/dist/queries/deps.d.ts +15 -0
- package/dist/queries/deps.js +2 -0
- package/dist/queries/diff-impact.d.ts +165 -0
- package/dist/queries/diff-impact.js +2 -0
- package/dist/queries/doc-drift.d.ts +115 -0
- package/dist/queries/doc-drift.js +2 -0
- package/dist/queries/drift.d.ts +79 -0
- package/dist/queries/drift.js +2 -0
- package/dist/queries/duplicate-bodies.d.ts +55 -0
- package/dist/queries/duplicate-bodies.js +2 -0
- package/dist/queries/entry-map.d.ts +121 -0
- package/dist/queries/entry-map.js +2 -0
- package/dist/queries/evidence.d.ts +70 -0
- package/dist/queries/evidence.js +2 -0
- package/dist/queries/extract-candidates.d.ts +52 -0
- package/dist/queries/extract-candidates.js +2 -0
- package/dist/queries/fan.d.ts +53 -0
- package/dist/queries/fan.js +2 -0
- package/dist/queries/files.d.ts +20 -0
- package/dist/queries/files.js +2 -0
- package/dist/queries/health.d.ts +8 -0
- package/dist/queries/health.js +2 -0
- package/dist/queries/hierarchy.d.ts +21 -0
- package/dist/queries/hierarchy.js +2 -0
- package/dist/queries/hotspots.d.ts +42 -0
- package/dist/queries/hotspots.js +2 -0
- package/dist/queries/imports.d.ts +34 -0
- package/dist/queries/imports.js +2 -0
- package/dist/queries/incomplete-migration.d.ts +90 -0
- package/dist/queries/incomplete-migration.js +2 -0
- package/dist/queries/index.d.ts +180 -0
- package/dist/queries/index.js +2 -0
- package/dist/queries/isolated.d.ts +24 -0
- package/dist/queries/isolated.js +2 -0
- package/dist/queries/locality-candidates.d.ts +51 -0
- package/dist/queries/locality-candidates.js +2 -0
- package/dist/queries/members.d.ts +21 -0
- package/dist/queries/members.js +2 -0
- package/dist/queries/methods.d.ts +43 -0
- package/dist/queries/methods.js +2 -0
- package/dist/queries/not-implemented.d.ts +33 -0
- package/dist/queries/not-implemented.js +2 -0
- package/dist/queries/outline.d.ts +22 -0
- package/dist/queries/outline.js +2 -0
- package/dist/queries/passthrough-candidates.d.ts +41 -0
- package/dist/queries/passthrough-candidates.js +2 -0
- package/dist/queries/plan-context.d.ts +33 -0
- package/dist/queries/plan-context.js +2 -0
- package/dist/queries/react-component-duplicates.d.ts +39 -0
- package/dist/queries/react-component-duplicates.js +2 -0
- package/dist/queries/react-hook-candidates.d.ts +44 -0
- package/dist/queries/react-hook-candidates.js +2 -0
- package/dist/queries/react-large-component-pressure.d.ts +34 -0
- package/dist/queries/react-large-component-pressure.js +2 -0
- package/dist/queries/recent-duplicates.d.ts +79 -0
- package/dist/queries/recent-duplicates.js +2 -0
- package/dist/queries/redundant-reexports.d.ts +37 -0
- package/dist/queries/redundant-reexports.js +2 -0
- package/dist/queries/reference-neighborhood.d.ts +4 -0
- package/dist/queries/reference-neighborhood.js +2 -0
- package/dist/queries/reference-reachability.d.ts +48 -0
- package/dist/queries/reference-reachability.js +2 -0
- package/dist/queries/refs.d.ts +13 -0
- package/dist/queries/refs.js +2 -0
- package/dist/queries/self-audit.d.ts +65 -0
- package/dist/queries/self-audit.js +2 -0
- package/dist/queries/similar-chains.d.ts +48 -0
- package/dist/queries/similar-chains.js +2 -0
- package/dist/queries/similar-files.d.ts +35 -0
- package/dist/queries/similar-files.js +2 -0
- package/dist/queries/similar-signatures.d.ts +46 -0
- package/dist/queries/similar-signatures.js +2 -0
- package/dist/queries/similar.d.ts +187 -0
- package/dist/queries/similar.js +2 -0
- package/dist/queries/slice.d.ts +4 -0
- package/dist/queries/slice.js +2 -0
- package/dist/queries/source-inspection.d.ts +209 -0
- package/dist/queries/source-inspection.js +2 -0
- package/dist/queries/source-search.d.ts +85 -0
- package/dist/queries/source-search.js +2 -0
- package/dist/queries/stale-abstractions.d.ts +72 -0
- package/dist/queries/stale-abstractions.js +2 -0
- package/dist/queries/stats.d.ts +15 -0
- package/dist/queries/stats.js +2 -0
- package/dist/queries/surface.d.ts +22 -0
- package/dist/queries/surface.js +2 -0
- package/dist/queries/symbols.d.ts +14 -0
- package/dist/queries/symbols.js +2 -0
- package/dist/queries/system-map.d.ts +449 -0
- package/dist/queries/system-map.js +2 -0
- package/dist/queries/system.d.ts +21 -0
- package/dist/queries/system.js +2 -0
- package/dist/queries/test-quality.d.ts +56 -0
- package/dist/queries/test-quality.js +2 -0
- package/dist/queries/trace.d.ts +68 -0
- package/dist/queries/trace.js +2 -0
- package/dist/queries/twin-ab.d.ts +66 -0
- package/dist/queries/twin-ab.js +2 -0
- package/dist/queries/twin-drift.d.ts +119 -0
- package/dist/queries/twin-drift.js +2 -0
- package/dist/queries/unused-imports.d.ts +4 -0
- package/dist/queries/unused-imports.js +2 -0
- package/dist/queries/unused-params.d.ts +38 -0
- package/dist/queries/unused-params.js +2 -0
- package/dist/queries/value-flow.d.ts +42 -0
- package/dist/queries/value-flow.js +2 -0
- package/dist/queries/vue-component-duplicates.d.ts +43 -0
- package/dist/queries/vue-component-duplicates.js +2 -0
- package/dist/queries/vue-composable-candidates.d.ts +44 -0
- package/dist/queries/vue-composable-candidates.js +2 -0
- package/dist/queries/vue-large-view-pressure.d.ts +41 -0
- package/dist/queries/vue-large-view-pressure.js +2 -0
- package/dist/queries/wrapper-candidates.d.ts +34 -0
- package/dist/queries/wrapper-candidates.js +2 -0
- package/dist/reindex-worker.js +3 -0
- package/dist/reindex.d.ts +254 -0
- package/dist/reindex.js +298 -0
- package/dist/repository-text-C0Q8VYdN.d.ts +19 -0
- package/dist/runtime.d.ts +555 -0
- package/dist/runtime.js +4 -0
- package/dist/rust-semantic-session-server.js +2 -0
- package/dist/rust-semantic-session-worker.js +2 -0
- package/dist/rust-semantic-worker.js +2 -0
- package/dist/scip-cli-B7N3haxa.d.ts +67 -0
- package/dist/source-snippet-_wrcgmZc.d.ts +15 -0
- package/dist/symbol-types-BIQwfoAx.d.ts +74 -0
- package/dist/typescript-mailbox-worker.js +2 -0
- package/dist/watch-server.js +8 -0
- package/docs/AGENT_GUIDE.md +148 -0
- package/docs/AI_FAILURE_MODES.md +43 -0
- package/docs/API.md +40 -0
- package/docs/API_EVOLUTION.md +77 -0
- package/docs/CLI_JSON_OUTPUT.md +389 -0
- package/docs/COMMAND_REFERENCE.md +294 -0
- package/docs/CONFIGURATION_WRITE_SAFETY.md +131 -0
- package/docs/DETECTOR_GUIDE.md +46 -0
- package/docs/DURABILITY.md +159 -0
- package/docs/INDEX_GENERATIONS.md +167 -0
- package/docs/LOCK_PROTOCOL.md +133 -0
- package/docs/MAILBOX_LIFECYCLE.md +224 -0
- package/docs/REGEX_POLICY.md +36 -0
- package/docs/REINDEX_METADATA_COMPATIBILITY.md +104 -0
- package/docs/RUST_DURABLE_SESSION_PROTOCOL.md +126 -0
- package/docs/SECURITY_MODEL.md +125 -0
- package/docs/TELEMETRY_RETENTION.md +84 -0
- package/docs/TIME_SEMANTICS.md +77 -0
- package/docs/WATCH_REFRESH_REQUESTS.md +123 -0
- package/docs/WINDOWS_SIDECAR_RELEASE.md +424 -0
- package/docs/accuracy-audit-checklist.md +304 -0
- package/docs/accuracy-hardening-goal.md +500 -0
- package/docs/analyzer-inventory.md +78 -0
- package/docs/analyzer-validation-protocol.md +84 -0
- package/docs/architecture-coherence-vision.md +254 -0
- package/docs/assets/codebaseiq-logo-dark.svg +21 -0
- package/docs/assets/codebaseiq-logo.svg +24 -0
- package/docs/locality-analyzer-design.md +193 -0
- package/docs/schemas/cli-json-envelope.schema.json +237 -0
- package/docs/schemas/cli-output-page.schema.json +104 -0
- package/docs/schemas/npm-release-state.schema.json +146 -0
- package/docs/schemas/observation-receipt.schema.json +164 -0
- package/docs/schemas/project-config.schema.json +318 -0
- package/docs/schemas/suppression-record.schema.json +79 -0
- package/docs/schemas/windows-sidecar-provenance.schema.json +137 -0
- package/package.json +482 -0
- package/scripts/build-codebaseiq-windows.mjs +197 -0
- package/scripts/codebaseiq-windows-provenance.mjs +364 -0
- package/scripts/evidence-product-contract.mjs +197 -0
- package/scripts/verify-codebaseiq-windows.mjs +29 -0
- package/skills/codebaseiq/SKILL.md +75 -0
- package/skills/codebaseiq/agents/openai.yaml +4 -0
- package/skills/codebaseiq-explore/SKILL.md +34 -0
- package/skills/codebaseiq-explore/agents/openai.yaml +4 -0
- package/skills/concrete-plan/SKILL.md +79 -0
- package/skills/concrete-plan/agents/openai.yaml +4 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Architecture Coherence Vision
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
codebaseiq should help a maintainer answer two different questions:
|
|
6
|
+
|
|
7
|
+
1. What architecture does this codebase actually have?
|
|
8
|
+
2. Where does the implementation contradict the architecture the project intends to preserve?
|
|
9
|
+
|
|
10
|
+
The dependency graph can answer neither question alone. It records which files rely on which other files. Architectural judgment connects those facts to the real responsibilities, public contracts, runtime boundaries, and maintenance work that gave the code its structure.
|
|
11
|
+
|
|
12
|
+
The product vision is therefore a combination of:
|
|
13
|
+
|
|
14
|
+
- an `architecture` query that measures declared boundaries and dependency rules;
|
|
15
|
+
- a directory-architecture skill that helps an agent discover, name, test, and gradually enforce those rules;
|
|
16
|
+
- drift and health integrations that expose architectural changes without pretending every unusual import is a defect.
|
|
17
|
+
|
|
18
|
+
## Vocabulary
|
|
19
|
+
|
|
20
|
+
An architectural boundary is a named group of code with one stable reason to change, such as a domain model, rendering subsystem, persistence adapter, compiler frontend, or deployable service. A folder often represents a boundary, but a folder is only evidence of one: the decisive fact is the responsibility its files jointly serve.
|
|
21
|
+
|
|
22
|
+
A dependency edge is a directed relationship from code that relies on something to the code it relies on. For an import, `A -> B` means file A imports file B. The direction matters because changes to B can force changes in A.
|
|
23
|
+
|
|
24
|
+
A boundary edge is the same relationship after file edges are grouped by their architectural boundaries. Ten imports from UI files into domain files form one `ui -> domain` boundary edge with ten pieces of file-level evidence.
|
|
25
|
+
|
|
26
|
+
An allowed edge is a boundary dependency that agrees with a declared rule. A forbidden edge is an actual dependency that contradicts a declared rule about which responsibilities may rely on which others. Files being far apart or living under different directories does not by itself make the edge forbidden.
|
|
27
|
+
|
|
28
|
+
A reciprocal dependency is a pair of boundary edges in both directions, such as `source -> parser` and `parser -> source`. It is a review signal because neither boundary can change independently, but it can be intentional when the named boundaries are really one subsystem or meet through a deliberately shared contract.
|
|
29
|
+
|
|
30
|
+
A strongly connected component is a group of boundaries where every member can reach every other member through dependency edges. Its essential consequence is mutual change pressure: no member is directionally independent of the group. A component with many boundaries is evidence that the current names may not describe real separation.
|
|
31
|
+
|
|
32
|
+
A cycle-break candidate is a boundary edge inside a dependency cycle whose small amount of file-level evidence makes it a plausible place to inspect first. It is not automatically the correct edge to remove; a single import can expose either an accidental shortcut or a legitimate contract that the boundary model failed to name.
|
|
33
|
+
|
|
34
|
+
An architecture policy is the project-owned configuration that names boundaries and records dependency directions the maintainers are prepared to defend. Its rules are stronger than inferred folder conventions because the project explicitly chose them.
|
|
35
|
+
|
|
36
|
+
An architecture ratchet is an enforcement rule that permits recorded existing debt while preventing new violations. It lets a large codebase improve incrementally without requiring a speculative rewrite before the policy becomes useful.
|
|
37
|
+
|
|
38
|
+
Architectural coherence is the degree to which actual dependencies, named responsibilities, and declared dependency rules describe the same system. The tool should report the evidence needed to improve that alignment, not reduce coherence to a single score.
|
|
39
|
+
|
|
40
|
+
## Why `drift` Is Not Enough
|
|
41
|
+
|
|
42
|
+
Drift is movement away from a reference state or established pattern. A system can be statically incoherent without having changed recently, and it can change while remaining coherent. Therefore architecture needs a first-class report rather than being hidden inside `drift`.
|
|
43
|
+
|
|
44
|
+
`codebaseiq architecture` owns the complete boundary graph and policy
|
|
45
|
+
evaluation. `codebaseiq drift --architecture` reuses that report to show
|
|
46
|
+
direct declared violations together with mapping coverage and report-only
|
|
47
|
+
signals; it does not maintain a second policy engine.
|
|
48
|
+
|
|
49
|
+
Before this work, the source-layer table in
|
|
50
|
+
`src/queries/cleanup/drift-policy.ts` embedded repository-specific knowledge in
|
|
51
|
+
a general-purpose command. An unrelated repository using folders such as
|
|
52
|
+
`src/core` and `src/runtime` could therefore inherit codebaseiq's rules. That
|
|
53
|
+
table has now been removed: drift consumes only explicit project
|
|
54
|
+
configuration, and an unconfigured repository receives no architecture
|
|
55
|
+
violations.
|
|
56
|
+
|
|
57
|
+
## Configuration Model
|
|
58
|
+
|
|
59
|
+
The first configuration shape should be small enough to understand without learning a policy language:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"architecture": {
|
|
64
|
+
"boundaries": [
|
|
65
|
+
{ "name": "domain", "paths": ["src/domain/**"] },
|
|
66
|
+
{ "name": "source", "paths": ["src/source/**"] },
|
|
67
|
+
{ "name": "runtime", "paths": ["src/runtime/**"] }
|
|
68
|
+
],
|
|
69
|
+
"allowedDependencies": {
|
|
70
|
+
"domain": [],
|
|
71
|
+
"source": ["domain"],
|
|
72
|
+
"runtime": ["domain", "source"]
|
|
73
|
+
},
|
|
74
|
+
"requireCompletePolicy": true,
|
|
75
|
+
"requireAcyclic": true
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
A boundary row names code; it does not yet prohibit anything. An `allowedDependencies` row is closed: when a row exists for `source`, every cross-boundary dependency not listed in that row is forbidden. A missing row means the project has not made a rule for that boundary yet. Same-boundary dependencies remain allowed.
|
|
81
|
+
|
|
82
|
+
This distinction lets a large repository describe mature boundaries first while leaving emerging or disputed areas in discovery mode.
|
|
83
|
+
|
|
84
|
+
`requireCompletePolicy` turns that gradual-discovery model into a finished
|
|
85
|
+
contract: every configured boundary must have a closed row, including an empty
|
|
86
|
+
row for a boundary that may depend on nothing. `requireAcyclic` independently
|
|
87
|
+
forbids multi-boundary strongly connected components. A project should enable
|
|
88
|
+
both only after the observed graph has been classified and repaired.
|
|
89
|
+
|
|
90
|
+
`requireCompleteCoverage` gives boundary ownership normative force: every
|
|
91
|
+
indexed, non-ignored file must match exactly one declared boundary. Without the
|
|
92
|
+
flag, unmapped and ambiguous files remain visible coverage facts but cannot
|
|
93
|
+
block work.
|
|
94
|
+
|
|
95
|
+
`requireResolvedBoundaries` closes the gap the dependency rules leave open. Same-boundary
|
|
96
|
+
dependencies are always allowed, so every edge inside a boundary is discarded
|
|
97
|
+
before `requireAcyclic` runs — which means a boundary coarse enough to contain
|
|
98
|
+
both sides of a cycle passes the check while saying nothing about the code
|
|
99
|
+
inside it. The rule quotients each boundary by its sub-directories and requires
|
|
100
|
+
that quotient to be acyclic too, so "no cycles" keeps its meaning as boundaries
|
|
101
|
+
grow. It reports the narrowest internal edge as the inspection point, because a
|
|
102
|
+
hidden cycle is usually one import against a dominant direction rather than a
|
|
103
|
+
tangle.
|
|
104
|
+
|
|
105
|
+
Four narrower rules close the remaining holes. `requireMinimalPolicy` rejects a
|
|
106
|
+
declared allowance no edge uses, because `requireCompletePolicy` checks only
|
|
107
|
+
that a row exists and a stale row widens the policy silently.
|
|
108
|
+
`maxBoundaryFanOut` and global `maxBoundaryFiles` bound growth, since coarseness
|
|
109
|
+
was otherwise caught only when it hid a cycle. A boundary-specific `maxFiles`
|
|
110
|
+
overrides the global file ceiling only for that reviewed responsibility.
|
|
111
|
+
`testPaths` brings test files back
|
|
112
|
+
under enforcement — they are excluded from the compiler project and so from the
|
|
113
|
+
index, which put them outside every rule — judging each test against the
|
|
114
|
+
boundary of the code it covers, while still allowing it to reach anything that
|
|
115
|
+
subject transitively reaches or that reaches the subject. And a boundary may set
|
|
116
|
+
`subUnits: "file"` when its members form layers inside one directory.
|
|
117
|
+
|
|
118
|
+
The failure it prevents is specific: this repository's own configuration
|
|
119
|
+
declared 14 boundaries with `requireAcyclic: true` and reported zero cycles,
|
|
120
|
+
while six of those boundaries — holding 85% of all files — each contained an
|
|
121
|
+
internal cycle. The clean result was an artifact of granularity, not a property
|
|
122
|
+
of the code.
|
|
123
|
+
|
|
124
|
+
## What the Analyzer Should Report
|
|
125
|
+
|
|
126
|
+
The report should preserve both policy truth and graph evidence:
|
|
127
|
+
|
|
128
|
+
- mapped, unmapped, and ambiguously mapped files;
|
|
129
|
+
- boundary edges with importer count, imported-file count, total file-edge count, and representative file edges;
|
|
130
|
+
- forbidden edges, grouped by boundary pair rather than emitted as a flood of individual imports;
|
|
131
|
+
- reciprocal boundary pairs;
|
|
132
|
+
- strongly connected boundary components;
|
|
133
|
+
- the narrowest internal edges to inspect first for each component;
|
|
134
|
+
- policy coverage: which boundaries have closed dependency rows and which remain descriptive only.
|
|
135
|
+
- resolved `export ... from` dependencies as well as ordinary imports, so
|
|
136
|
+
published barrel and package surfaces are governed;
|
|
137
|
+
|
|
138
|
+
The output tiers should remain explicit:
|
|
139
|
+
|
|
140
|
+
- **Direct finding:** an actual edge contradicts a declared rule, or a declared acyclicity rule is violated.
|
|
141
|
+
- **Signal:** reciprocity, a large connected component, low policy coverage, an unmapped file, or a narrow cycle-break candidate.
|
|
142
|
+
|
|
143
|
+
Inferred signals should not reduce health scores or block diffs until external calibration shows that acting on them reliably improves real codebases.
|
|
144
|
+
|
|
145
|
+
## Applying This to an Existing Large Codebase
|
|
146
|
+
|
|
147
|
+
The tool cannot discover the “best architecture” by optimizing graph shape. The best available architecture is the clearest model that preserves the system's real responsibilities and necessary behavior while reducing accidental change pressure. Finding it requires a staged investigation.
|
|
148
|
+
|
|
149
|
+
### 1. Inventory the system's referents
|
|
150
|
+
|
|
151
|
+
Read the repository guidance, package manifests, deployable entry points, routes, public exports, databases, message boundaries, tests, and build graph. Use codebaseiq to map consumers, dependencies, change surfaces, cycles, locality candidates, and historical co-change.
|
|
152
|
+
|
|
153
|
+
This identifies what the code actually does and which units already behave as maintenance units.
|
|
154
|
+
|
|
155
|
+
### 2. Name candidate boundaries
|
|
156
|
+
|
|
157
|
+
Do not assume every top-level directory is a layer. A layer is a responsibility ordered by dependency direction, such as presentation over application over domain. A subsystem is a responsibility that owns an end-to-end capability, such as authentication or a compiler. A package is a publication or build unit. A service is an independently running unit.
|
|
158
|
+
|
|
159
|
+
The architecture model may contain all four. The useful name is the one that predicts why its code changes and what it may depend on.
|
|
160
|
+
|
|
161
|
+
### 3. Classify boundary maturity
|
|
162
|
+
|
|
163
|
+
- A mature boundary is repeatedly expressed by code, documentation, tests, entry points, ownership, or history.
|
|
164
|
+
- An emerging boundary has a coherent responsibility but inconsistent placement or dependencies.
|
|
165
|
+
- An accidental boundary is mainly a convenience bucket, legacy pile, generated directory, or recent edit cluster.
|
|
166
|
+
|
|
167
|
+
Only mature boundaries should receive closed dependency rules initially.
|
|
168
|
+
|
|
169
|
+
### 4. Build a descriptive model first
|
|
170
|
+
|
|
171
|
+
Add boundary path patterns without `allowedDependencies` rows. Run `codebaseiq architecture --json` to inspect mapping coverage, actual boundary edges, reciprocal pairs, and connected components.
|
|
172
|
+
|
|
173
|
+
Revise names and path membership when the graph reveals that a supposed boundary has no independent responsibility or that one responsibility is split across several folders.
|
|
174
|
+
|
|
175
|
+
### 5. Declare the rules supported by evidence
|
|
176
|
+
|
|
177
|
+
For each mature boundary, state which other boundaries it is allowed to depend on and why. Record uncertain edges as unresolved decisions instead of silently allowing the entire current graph.
|
|
178
|
+
|
|
179
|
+
Run the report again. A forbidden edge is now a testable disagreement between implementation and policy, not the tool's opinion about directory distance.
|
|
180
|
+
|
|
181
|
+
### 6. Review and ratchet
|
|
182
|
+
|
|
183
|
+
Run `codebaseiq architecture` after changing a declared boundary or one of its
|
|
184
|
+
consumers. The report applies configured dependency rules exactly and cites the
|
|
185
|
+
files that create each forbidden edge. Repositories that want a broader
|
|
186
|
+
maintenance ratchet can record reviewed health findings with `codebaseiq health
|
|
187
|
+
--write-baseline` and compare later scans with `codebaseiq health --baseline`.
|
|
188
|
+
Neither command decides whether an arbitrary coding task is complete.
|
|
189
|
+
|
|
190
|
+
### 7. Migrate narrow seams
|
|
191
|
+
|
|
192
|
+
Start with a narrow edge whose few file dependencies cross a mature rule. Determine whether the right repair is to move code, invert a dependency, extract a genuinely shared contract, combine falsely separated boundaries, or revise the policy.
|
|
193
|
+
|
|
194
|
+
Verify each slice with tests, typechecking, incomplete-migration checks,
|
|
195
|
+
architecture analysis, and `diff-impact` before taking the next one.
|
|
196
|
+
|
|
197
|
+
## Example: Vega 2.0
|
|
198
|
+
|
|
199
|
+
For a codebase the size of Vega 2.0, the first pass should not invent a universal stack of layers. It should:
|
|
200
|
+
|
|
201
|
+
1. identify workspace packages, applications, servers, public entry points, data stores, and major feature or compiler/rendering subsystems;
|
|
202
|
+
2. map actual dependency traffic between those units;
|
|
203
|
+
3. read the architecture and ownership claims already present in docs and package surfaces;
|
|
204
|
+
4. classify candidate boundaries as mature, emerging, or accidental;
|
|
205
|
+
5. configure the mature boundaries descriptively;
|
|
206
|
+
6. inspect reciprocal pairs and large connected components with their file-edge breadth;
|
|
207
|
+
7. close dependency rows only where the intended direction is supported;
|
|
208
|
+
8. record reviewed violations and check each relevant change against the declared rules;
|
|
209
|
+
9. migrate one narrow, high-confidence seam at a time.
|
|
210
|
+
|
|
211
|
+
The initial result may be a mixture of layers and subsystems. That is preferable to forcing a neat diagram that contradicts the software. The model becomes stronger as verified migrations and maintenance history provide new facts.
|
|
212
|
+
|
|
213
|
+
## Delivery Sequence
|
|
214
|
+
|
|
215
|
+
### Slice 1: explicit measurement — implemented
|
|
216
|
+
|
|
217
|
+
- Add architecture configuration types and validation.
|
|
218
|
+
- Extract the reusable strongly-connected-component algorithm already embedded in `deep-chains`.
|
|
219
|
+
- Add a pure architecture graph analyzer and `codebaseiq architecture`.
|
|
220
|
+
- Extend the directory-architecture skill with the discover, declare, measure, and ratchet workflow.
|
|
221
|
+
- Keep architecture findings distinct from ordinary code-smell scoring.
|
|
222
|
+
|
|
223
|
+
### Slice 2: replace implicit drift policy — implemented
|
|
224
|
+
|
|
225
|
+
- Move codebaseiq's source-boundary rules into its `.codebaseiq.json`.
|
|
226
|
+
- Make drift consume architecture findings instead of repository-specific hardcoded folder rules.
|
|
227
|
+
- Add `drift --architecture` as a summary view.
|
|
228
|
+
- Preserve unused-import drift and keep sibling-pattern deviation opt-in.
|
|
229
|
+
|
|
230
|
+
### Slice 3: baselines and enforcement — implemented locally; external calibration remains
|
|
231
|
+
|
|
232
|
+
- Give architecture findings stable identities.
|
|
233
|
+
- Add report-only health visibility.
|
|
234
|
+
- Support an optional repository health baseline for teams that want a ratchet.
|
|
235
|
+
- Calibrate on codebaseiq, Vega 2.0, Stable Management, and structurally different external repositories before any score deduction.
|
|
236
|
+
|
|
237
|
+
### Slice 4: discovery assistance
|
|
238
|
+
|
|
239
|
+
- Add candidate-boundary evidence that combines paths, entry points, public surfaces, dependency neighborhoods, and co-change history.
|
|
240
|
+
- Have the skill produce a reviewable architecture draft, never silently write closed rules.
|
|
241
|
+
- Measure whether suggested boundaries and repairs survive maintainer review and reduce future cross-boundary churn.
|
|
242
|
+
|
|
243
|
+
## Success Criteria
|
|
244
|
+
|
|
245
|
+
The architecture feature is effective when:
|
|
246
|
+
|
|
247
|
+
- an unconfigured repository never inherits codebaseiq-specific rules;
|
|
248
|
+
- a configured forbidden edge is reported with concrete import evidence;
|
|
249
|
+
- broad and narrow boundary edges are distinguishable;
|
|
250
|
+
- large cycles are summarized without flooding the user;
|
|
251
|
+
- the agent can explain why each proposed boundary exists in the running system;
|
|
252
|
+
- existing debt can be ratcheted without a rewrite;
|
|
253
|
+
- acting on a recommendation improves ownership or dependency direction in externally reviewed codebases;
|
|
254
|
+
- the tool is willing to say “the policy is incomplete” instead of manufacturing certainty.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="136" viewBox="0 0 560 136" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">codebaseiq</title>
|
|
3
|
+
<desc id="desc">A minimal codebaseiq wordmark with a bright blue underscore cursor for dark backgrounds.</desc>
|
|
4
|
+
<style>
|
|
5
|
+
.wordmark {
|
|
6
|
+
fill: #F8FAFC;
|
|
7
|
+
font-family: Helvetica, Arial, sans-serif;
|
|
8
|
+
font-size: 58px;
|
|
9
|
+
font-weight: 700;
|
|
10
|
+
letter-spacing: 0;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
<text
|
|
14
|
+
class="wordmark"
|
|
15
|
+
x="38"
|
|
16
|
+
y="83"
|
|
17
|
+
textLength="372"
|
|
18
|
+
lengthAdjust="spacingAndGlyphs"
|
|
19
|
+
>codebaseiq</text>
|
|
20
|
+
<rect x="430" y="76" width="50" height="8" rx="4" fill="#60A5FA" />
|
|
21
|
+
</svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="136" viewBox="0 0 560 136" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">codebaseiq</title>
|
|
3
|
+
<desc id="desc">A minimal codebaseiq wordmark with a blue underscore cursor.</desc>
|
|
4
|
+
<style>
|
|
5
|
+
.wordmark {
|
|
6
|
+
fill: #111827;
|
|
7
|
+
font-family: Helvetica, Arial, sans-serif;
|
|
8
|
+
font-size: 58px;
|
|
9
|
+
font-weight: 700;
|
|
10
|
+
letter-spacing: 0;
|
|
11
|
+
}
|
|
12
|
+
.cursor {
|
|
13
|
+
fill: #2563EB;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
<text
|
|
17
|
+
class="wordmark"
|
|
18
|
+
x="38"
|
|
19
|
+
y="83"
|
|
20
|
+
textLength="372"
|
|
21
|
+
lengthAdjust="spacingAndGlyphs"
|
|
22
|
+
>codebaseiq</text>
|
|
23
|
+
<rect class="cursor" x="430" y="76" width="50" height="8" rx="4" />
|
|
24
|
+
</svg>
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Locality Analyzer Design
|
|
2
|
+
|
|
3
|
+
This document designs the missing analyzer family identified during the analyzer inventory: a tool that evaluates where extracted code belongs. It is intentionally a design document, not a production implementation.
|
|
4
|
+
|
|
5
|
+
The problem shows up most clearly after React or Vue large-component work. An agent can reduce a large file by extracting components, hooks, helpers, or composables, but it may dump all of them into a flat folder beside the original file. That can make the size metric better while making ownership, reuse, and navigation worse.
|
|
6
|
+
|
|
7
|
+
## Core Concepts
|
|
8
|
+
|
|
9
|
+
Code locality is the placement relation between a source unit and the files that use it. It concerns real files, directories, imports, consumers, tests, and package boundaries; its essential characteristic is that code belongs at the nearest stable home that all legitimate consumers can reach without making the API broader than the concept deserves.
|
|
10
|
+
|
|
11
|
+
A source unit is a file, symbol, component, hook, composable, type, or helper that the analyzer can name and trace. It is the smallest unit whose placement can be judged from references, imports, and directory structure.
|
|
12
|
+
|
|
13
|
+
A consumer set is the set of files or symbols that import, call, render, instantiate, or otherwise rely on a source unit. Its essential role is to reveal whether a unit is private to one place, shared within a feature, shared across a domain, or actually reusable across the application.
|
|
14
|
+
|
|
15
|
+
An ownership boundary is a directory, package, route, feature, domain, or module boundary that indicates who should be allowed to change a unit. It is not just a path prefix; it is the codebase's visible grouping of reasons to change.
|
|
16
|
+
|
|
17
|
+
An abstraction level is the height of a unit's meaning relative to product code. A button primitive, route panel, invoice calculation, GraphQL client, and test fixture can all be TypeScript functions or components, but they belong at different levels because they serve different kinds of callers.
|
|
18
|
+
|
|
19
|
+
A shared folder is a directory whose name or import pattern says that multiple nearby units may depend on it. Its essential risk is that it can either preserve local reuse or become a dumping ground that erases ownership.
|
|
20
|
+
|
|
21
|
+
A global shared folder is a repository-wide shared directory such as `src/shared`, `src/lib`, `src/components`, or `packages/shared`. Its essential risk is API inflation: code placed there becomes easier to depend on from anywhere, so the placement should require cross-feature or cross-package evidence.
|
|
22
|
+
|
|
23
|
+
## Command Shape
|
|
24
|
+
|
|
25
|
+
Proposed command:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
codebaseiq locality-candidates [symbol-or-file]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Useful options:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
codebaseiq locality-candidates apps/web/src/routes/HorsesView.tsx --json
|
|
35
|
+
codebaseiq locality-candidates --scope apps/web/src --since HEAD~20
|
|
36
|
+
codebaseiq locality-candidates --changed-only --base origin/main
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The command should be report-only at first. Its action tier is contextual signal: it guides placement and review, but it should not move files automatically.
|
|
40
|
+
|
|
41
|
+
## Inputs
|
|
42
|
+
|
|
43
|
+
The analyzer should combine existing evidence rather than invent a separate world model.
|
|
44
|
+
|
|
45
|
+
| Input | Source | Why it matters |
|
|
46
|
+
| ----------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
47
|
+
| Candidate source unit | Explicit argument, changed files, large component/view pressure, extract candidates | Chooses what placement is being judged |
|
|
48
|
+
| Consumer files and symbols | `refs`, `imported-by`, `rdeps`, call graph, JSX/Vue render facts | Shows who actually uses the unit |
|
|
49
|
+
| Current path and import path | filesystem path, import graph | Reveals whether the unit is already local, feature-shared, or global |
|
|
50
|
+
| Nearest common ancestor | consumer file paths | Finds the smallest directory all consumers share |
|
|
51
|
+
| Feature and route roots | path names such as `routes`, `pages`, `features`, `modules`, `domains` | Distinguishes product areas from generic infrastructure |
|
|
52
|
+
| Package or workspace boundary | package manifests, tsconfig references, workspace layout | Prevents app-local concepts from leaking into shared packages |
|
|
53
|
+
| Test adjacency | test file paths and references | Keeps test helpers near their tests unless production consumers exist |
|
|
54
|
+
| Naming evidence | source unit name, directory names, imported symbols | Distinguishes product concepts from generic primitives |
|
|
55
|
+
| Historical co-change | `co-change`, git history | Shows whether the unit changes with one feature or several |
|
|
56
|
+
| Existing local conventions | sibling folder names and import patterns | Avoids recommendations that fight the codebase's own organization |
|
|
57
|
+
|
|
58
|
+
## Placement Tiers
|
|
59
|
+
|
|
60
|
+
| Tier | Recommendation | Strong evidence | Common mistake caught |
|
|
61
|
+
| ---------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
62
|
+
| `same-file` | Keep the unit in the original file. | One consumer, no independent tests, name only makes sense inside the parent. | Extracting a private branch into a needless helper file. |
|
|
63
|
+
| `sibling-private` | Put it next to the parent in a private local folder. | Two or more consumers under one page/component folder, no outside imports. | Creating a route-local `components` folder under global `src/components`. |
|
|
64
|
+
| `feature-local-shared` | Put it under the nearest feature/module shared folder. | Consumers span files in one feature root but not outside it. | Moving feature-specific hooks into app-wide `shared`. |
|
|
65
|
+
| `domain-shared` | Put it under a domain or bounded context folder. | Consumers cross feature roots but share domain nouns and co-change history. | Duplicating business rules in several features or over-generalizing them into `lib`. |
|
|
66
|
+
| `app-shared` | Put it under app-level shared UI or utility space. | Consumers cross domains inside one app and the name is generic enough for app reuse. | Keeping a genuinely reusable primitive hidden inside one feature. |
|
|
67
|
+
| `package-shared` | Put it in a shared workspace package. | Consumers cross package/workspace boundaries, and package API ownership is intended. | Importing across workspace internals or copying contracts between packages. |
|
|
68
|
+
| `no-extraction` | Do not extract, or inline it back. | One consumer, weak name, no independent concept, extraction only satisfies a size metric. | Size-score gaming through thin files and local indirection. |
|
|
69
|
+
|
|
70
|
+
The output should include confidence, reasons, counterevidence, and the exact consumer set.
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"candidate": "apps/web/src/features/horses/HorseStatusPanel.tsx",
|
|
75
|
+
"currentTier": "app-shared",
|
|
76
|
+
"recommendedTier": "feature-local-shared",
|
|
77
|
+
"confidence": "medium",
|
|
78
|
+
"consumers": ["apps/web/src/features/horses/HorseProfile.tsx", "apps/web/src/features/horses/HorseList.tsx"],
|
|
79
|
+
"nearestCommonAncestor": "apps/web/src/features/horses",
|
|
80
|
+
"reasons": [
|
|
81
|
+
"all production consumers are inside one feature root",
|
|
82
|
+
"candidate name uses the Horses domain noun",
|
|
83
|
+
"no package or cross-domain consumers found"
|
|
84
|
+
],
|
|
85
|
+
"counterevidence": ["component name is presentational enough that future app-level reuse is possible"],
|
|
86
|
+
"suggestedHome": "apps/web/src/features/horses/components/HorseStatusPanel.tsx"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Analyzer Pairing
|
|
91
|
+
|
|
92
|
+
The locality analyzer should not replace existing analyzers. It should complete their story.
|
|
93
|
+
|
|
94
|
+
| Existing analyzer | What it says today | Locality companion question |
|
|
95
|
+
| ---------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
96
|
+
| `react-large-component-pressure` | This React component is too large. | If pieces are extracted, which ones are private, feature-local, or shared? |
|
|
97
|
+
| `vue-large-view-pressure` | This Vue SFC is too large. | Should extracted child components/composables live beside the view, in the feature, or in app shared? |
|
|
98
|
+
| `extract-candidates` | This function contains a possible extraction cluster. | Would the extracted helper have one real owner or a broader consumer set? |
|
|
99
|
+
| `react-hook-candidates`, `vue-composable-candidates` | Several components repeat behavior. | Is the hook/composable local to one feature or reusable across domains? |
|
|
100
|
+
| `recent-duplicates`, `echo` | New code duplicates older code. | Which existing owner should the new code reuse, and would reuse widen the wrong API? |
|
|
101
|
+
| `incomplete-migration` | A helper extraction stopped halfway. | Is the helper in the right place for all remaining call sites? |
|
|
102
|
+
| `co-change` | Files move together historically. | Does history imply a hidden shared owner or only a local synchronization point? |
|
|
103
|
+
|
|
104
|
+
## Algorithm Sketch
|
|
105
|
+
|
|
106
|
+
1. Resolve the candidate to a file or symbol.
|
|
107
|
+
2. Collect direct consumers through references, imports, render facts, and reverse dependencies.
|
|
108
|
+
3. Remove consumers that are tests unless the candidate is test-only.
|
|
109
|
+
4. Compute the nearest common ancestor of production consumers.
|
|
110
|
+
5. Identify boundary markers in and above that ancestor: `app`, `apps`, `packages`, `routes`, `pages`, `features`, `modules`, `domains`, `shared`, `components`, `hooks`, `composables`, `lib`, `utils`, `services`, `stores`, and `contracts`.
|
|
111
|
+
6. Classify the current home and the smallest legitimate home.
|
|
112
|
+
7. Compare names from the candidate, directories, and consumers to decide whether the concept is domain-specific or generic.
|
|
113
|
+
8. Check workspace/package boundaries to prevent cross-package leakage.
|
|
114
|
+
9. Use co-change history as supporting evidence, not as a hard rule.
|
|
115
|
+
10. Emit a recommendation only when the consumer set and boundary evidence agree.
|
|
116
|
+
|
|
117
|
+
The first implementation can avoid automatic tree moves entirely. The valuable output is a review-grade explanation: "this extracted component is global today, but all consumers are in one feature, so feature-local shared is the smallest honest home."
|
|
118
|
+
|
|
119
|
+
## Precision Rules
|
|
120
|
+
|
|
121
|
+
The analyzer should prefer "no confident recommendation" over pretending all placement is obvious.
|
|
122
|
+
|
|
123
|
+
Report `same-file` or `no-extraction` when a candidate has one consumer and no independent concept name.
|
|
124
|
+
|
|
125
|
+
Report `sibling-private` when all consumers sit below one component, route, or view folder and no outside production import exists.
|
|
126
|
+
|
|
127
|
+
Report `feature-local-shared` when consumers share a feature root and imports do not cross into other feature roots.
|
|
128
|
+
|
|
129
|
+
Report `domain-shared` only when path names, symbol names, or co-change evidence show the same product domain across multiple feature roots.
|
|
130
|
+
|
|
131
|
+
Report `app-shared` only when consumers cross domains inside one app and the unit is not named after one feature.
|
|
132
|
+
|
|
133
|
+
Report `package-shared` only when consumers cross package boundaries and package exports make that sharing intentional.
|
|
134
|
+
|
|
135
|
+
Downrank a recommendation when imports come only through barrels, tests are the only second consumer, the candidate name is generic but behavior is domain-specific, or the nearest common ancestor is the repo root.
|
|
136
|
+
|
|
137
|
+
## Skill-First Option
|
|
138
|
+
|
|
139
|
+
Before production implementation, this can ship as a bundled workflow skill.
|
|
140
|
+
|
|
141
|
+
Proposed skill name:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
scip-locality-review
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The skill would tell agents to run:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
codebaseiq context <target> --full
|
|
151
|
+
codebaseiq imported-by <symbol>
|
|
152
|
+
codebaseiq rdeps <file>
|
|
153
|
+
codebaseiq co-change <file> --full
|
|
154
|
+
codebaseiq react-large-component-pressure <scope> --full
|
|
155
|
+
codebaseiq vue-large-view-pressure <scope> --full
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Then it would require the agent to answer:
|
|
159
|
+
|
|
160
|
+
1. What is the exact consumer set?
|
|
161
|
+
2. What is the nearest common owner all consumers share?
|
|
162
|
+
3. Is the concept product-specific, feature-specific, app-generic, or package-level?
|
|
163
|
+
4. Does the current path make the API wider than the consumer set requires?
|
|
164
|
+
5. Would a move reduce imports and ownership confusion without creating a new global dumping ground?
|
|
165
|
+
|
|
166
|
+
This is a good first step because it turns the product question into a repeatable checklist while we gather validation labels for the eventual command.
|
|
167
|
+
|
|
168
|
+
## Validation Plan
|
|
169
|
+
|
|
170
|
+
Use the validation corpus from `docs/analyzer-validation-protocol.md` and track the work under `docs/analyzer-validation-ledger.md`.
|
|
171
|
+
|
|
172
|
+
For React, inspect Vega_2.0 large components and hook candidates. A true positive is a recommendation that would place an extracted unit closer to its actual consumers without hiding a real shared primitive.
|
|
173
|
+
|
|
174
|
+
For Vue, inspect Stable_Management large views and composable candidates. A true positive is a recommendation that distinguishes route-local child components from feature-level composables and app-level UI primitives.
|
|
175
|
+
|
|
176
|
+
For codebaseiq itself, inspect analyzer/helper extractions. A true positive is a recommendation that keeps detector-private helpers near their detector unless multiple detector families actually consume them.
|
|
177
|
+
|
|
178
|
+
For Rust smoke coverage, run the command only after SCIP data supports the same source-unit questions. Until then, locality validation on Rust should be marked unsupported rather than failed.
|
|
179
|
+
|
|
180
|
+
Validation result: `docs/validation/2026-06-21-locality-analyzer-validation-result.md` recommends a report-only or skill-first implementation, with `actionTier: "signal"` and explicit consumer-coverage caveats. React `.tsx` samples had usable `rdeps` evidence, but Vue SFC samples had weak reverse-dependency coverage, so the first implementation must not recommend concrete destinations unless exact consumers are known.
|
|
181
|
+
|
|
182
|
+
## Score Integration
|
|
183
|
+
|
|
184
|
+
Locality findings should not immediately reduce health like dead code. They are contextual signals.
|
|
185
|
+
|
|
186
|
+
The health score can later use them as signal backlog pressure when they combine with other evidence:
|
|
187
|
+
|
|
188
|
+
- Large component pressure plus globalized local children.
|
|
189
|
+
- Extract candidates plus one-consumer helper files.
|
|
190
|
+
- Recent duplicates plus a clear existing local owner.
|
|
191
|
+
- Co-change clusters plus no shared owner directory.
|
|
192
|
+
|
|
193
|
+
The score should not punish a single "could be more local" suggestion. It should punish repeated evidence that code organization is being flattened until ownership is unclear.
|