scip-query 0.15.0 → 0.16.1
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 +41 -1
- package/README.md +148 -66
- package/dist/augment-vue-worker.js +1 -1
- package/dist/chunk-2EU6WVR3.js +3 -0
- package/dist/chunk-2HFXPIBT.js +2 -0
- package/dist/chunk-2LGPMYS2.js +35 -0
- package/dist/chunk-2Y7YX54K.js +16 -0
- package/dist/chunk-363TZ64I.js +2 -0
- package/dist/chunk-3I34FZ6R.js +2 -0
- package/dist/chunk-3LAKH6BV.js +2 -0
- package/dist/chunk-3M2UCPFS.js +3 -0
- package/dist/chunk-3OPIMH42.js +2 -0
- package/dist/{chunk-QZOAOLLZ.js → chunk-3YAZH3JU.js} +2 -2
- package/dist/chunk-5P26M63Y.js +2 -0
- package/dist/{chunk-72FR7KEZ.js → chunk-5TVNLPUM.js} +14 -12
- package/dist/chunk-5UKDCXVC.js +5 -0
- package/dist/{chunk-R7U2I55B.js → chunk-5XDNFOAH.js} +2 -2
- package/dist/chunk-62Y3PC27.js +4 -0
- package/dist/chunk-6DNE65QS.js +40 -0
- package/dist/{chunk-N2OTJWC2.js → chunk-6EVORGCB.js} +2 -2
- package/dist/chunk-6GZ7LM7S.js +2 -0
- package/dist/chunk-753JWTUH.js +3 -0
- package/dist/chunk-7II7NFRV.js +4 -0
- package/dist/{chunk-M7EEHYSU.js → chunk-7RAS466A.js} +2 -2
- package/dist/chunk-A46JTKTM.js +5 -0
- package/dist/{chunk-2XRXEIRK.js → chunk-AAMZRDJT.js} +2 -2
- package/dist/chunk-AMPN2VMF.js +3 -0
- package/dist/{chunk-6XA4LDHY.js → chunk-B3X6KU75.js} +2 -2
- package/dist/chunk-BFWVHD2P.js +16 -0
- package/dist/chunk-BVHP2B4D.js +61 -0
- package/dist/{chunk-BUNDZ6K2.js → chunk-BVUA3GZC.js} +2 -2
- package/dist/{chunk-EDSD3VJK.js → chunk-CKIAEVGM.js} +2 -2
- package/dist/chunk-CM4EZLW4.js +2 -0
- package/dist/chunk-CS3FXTUC.js +2 -0
- package/dist/chunk-CVBS2FD4.js +2 -0
- package/dist/chunk-D5OXYOJP.js +7 -0
- package/dist/chunk-DA34GNNO.js +29 -0
- package/dist/chunk-DKK2H4D7.js +7 -0
- package/dist/chunk-EBSSCVR4.js +5 -0
- package/dist/{chunk-OXTM2RX3.js → chunk-EVCSXWER.js} +2 -2
- package/dist/chunk-FFIYGYQR.js +67 -0
- package/dist/chunk-G4KQ7S74.js +20 -0
- package/dist/{chunk-44P4SJFN.js → chunk-GWWYLYD3.js} +2 -2
- package/dist/chunk-HGUNWXJX.js +2 -0
- package/dist/chunk-HLRWOFXC.js +9 -0
- package/dist/{chunk-YQKECTPV.js → chunk-IRIM3SUR.js} +2 -2
- package/dist/chunk-JHK2DMUQ.js +4 -0
- package/dist/chunk-JQ2PCFZW.js +3 -0
- package/dist/chunk-JRFCWCOD.js +16 -0
- package/dist/chunk-JXAJDINF.js +2 -0
- package/dist/chunk-K32ZOW3P.js +2 -0
- package/dist/{chunk-3H5OSDF7.js → chunk-KI4WPR7Q.js} +2 -2
- package/dist/{chunk-43GKP6LI.js → chunk-KP2DJY7D.js} +2 -2
- package/dist/{chunk-YTVKPJXW.js → chunk-L27UIF3E.js} +2 -2
- package/dist/chunk-LT6AHYVY.js +18 -0
- package/dist/chunk-MCNWCJYL.js +11 -0
- package/dist/{chunk-K6UI6EBZ.js → chunk-MZB3DTHW.js} +2 -2
- package/dist/chunk-NLRWGGPY.js +8 -0
- package/dist/chunk-NLVKD45E.js +13 -0
- package/dist/chunk-OO6S4ECV.js +112 -0
- package/dist/{chunk-QYOPMTZ6.js → chunk-OYGKBDAD.js} +2 -2
- package/dist/chunk-P5QZILZ4.js +2 -0
- package/dist/chunk-P5XHIJHI.js +2 -0
- package/dist/chunk-PCCMMI2M.js +3 -0
- package/dist/{chunk-2TPCIPYA.js → chunk-Q65QYKU7.js} +2 -2
- package/dist/{chunk-K7SPOJHZ.js → chunk-QB7NRST4.js} +2 -2
- package/dist/{chunk-7JZRFDCU.js → chunk-QSNG3NHQ.js} +2 -2
- package/dist/chunk-QVZSWLLZ.js +2 -0
- package/dist/chunk-RLB7FZKR.js +10 -0
- package/dist/{chunk-KYB7FPXT.js → chunk-RPMT6MTX.js} +2 -2
- package/dist/chunk-RQWNF2RM.js +2 -0
- package/dist/chunk-RYFIRFYJ.js +4 -0
- package/dist/{chunk-QARYU7R3.js → chunk-S2FZILCF.js} +2 -2
- package/dist/{chunk-HV27H2V2.js → chunk-S3IXCXW2.js} +2 -2
- package/dist/{chunk-TYCZ7S4I.js → chunk-S5MTSES5.js} +2 -2
- package/dist/chunk-S5RZQA6V.js +2 -0
- package/dist/{chunk-PEHDARNC.js → chunk-SEEJPIWG.js} +2 -2
- package/dist/chunk-SOCS3467.js +2 -0
- package/dist/chunk-U6BJVXWQ.js +2 -0
- package/dist/chunk-UO4IADXJ.js +38 -0
- package/dist/{chunk-ZEO4CXQR.js → chunk-VLSI5MYU.js} +2 -2
- package/dist/chunk-VSQRU3AP.js +2 -0
- package/dist/chunk-VYQY75NA.js +2 -0
- package/dist/{chunk-NOKUZU56.js → chunk-VZCR3VQY.js} +2 -2
- package/dist/chunk-W3ZVRLCH.js +2 -0
- package/dist/chunk-WA64GKWB.js +20 -0
- package/dist/chunk-WFRZGMWJ.js +71 -0
- package/dist/chunk-WN6XEYVX.js +2 -0
- package/dist/chunk-XAEU4ROB.js +101 -0
- package/dist/chunk-XBPAJASV.js +2 -0
- package/dist/{chunk-GY3HAWUA.js → chunk-XC6PUFNN.js} +2 -2
- package/dist/chunk-Y42DMR6F.js +6 -0
- package/dist/chunk-YCVYOV4A.js +7 -0
- package/dist/{chunk-WPZPB42I.js → chunk-YD37KSEK.js} +2 -2
- package/dist/{chunk-V5W7H7V4.js → chunk-YFEJIYWH.js} +2 -2
- package/dist/chunk-YSUD2S7T.js +3 -0
- package/dist/{chunk-KJCDEDQW.js → chunk-ZEKBAMCN.js} +2 -2
- package/dist/chunk-ZHGUZKJL.js +2 -0
- package/dist/cli.js +586 -312
- package/dist/{config-types-aCgyLrvE.d.ts → config-types-SVkUIufk.d.ts} +8 -2
- package/dist/{db-DwCdT3rv.d.ts → db-CS0TuVH6.d.ts} +1 -1
- package/dist/{git-history-Dao3_Pu9.d.ts → git-history-ChNHbfZQ.d.ts} +2 -1
- package/dist/{health-nJUidasZ.d.ts → health-Btal3mQi.d.ts} +4 -4
- package/dist/index.d.ts +7 -5
- package/dist/index.js +1 -19
- package/dist/queries/affected.d.ts +2 -2
- package/dist/queries/affected.js +1 -1
- package/dist/queries/bottlenecks.d.ts +8 -2
- package/dist/queries/bottlenecks.js +1 -1
- package/dist/queries/by-kind.d.ts +2 -2
- package/dist/queries/by-kind.js +1 -1
- package/dist/queries/call-graph.d.ts +2 -2
- package/dist/queries/call-graph.js +1 -1
- package/dist/queries/change-surface.d.ts +2 -2
- package/dist/queries/change-surface.js +1 -1
- package/dist/queries/cleanup-plan.d.ts +2 -2
- package/dist/queries/cleanup-plan.js +1 -1
- package/dist/queries/co-change.d.ts +4 -3
- package/dist/queries/co-change.js +1 -1
- package/dist/queries/code.d.ts +2 -2
- package/dist/queries/code.js +1 -1
- package/dist/queries/complexity-hotspots.d.ts +3 -3
- package/dist/queries/complexity-hotspots.js +1 -1
- package/dist/queries/complexity.d.ts +5 -4
- package/dist/queries/complexity.js +1 -1
- package/dist/queries/convergence.d.ts +2 -2
- package/dist/queries/convergence.js +1 -1
- package/dist/queries/coupling.d.ts +2 -2
- package/dist/queries/coupling.js +1 -1
- package/dist/queries/cycles.d.ts +2 -2
- package/dist/queries/cycles.js +1 -1
- package/dist/queries/dataflow.d.ts +2 -2
- package/dist/queries/dataflow.js +1 -1
- package/dist/queries/dead.d.ts +12 -3
- package/dist/queries/dead.js +1 -1
- package/dist/queries/decorative-checkers.d.ts +2 -2
- package/dist/queries/decorative-checkers.js +1 -1
- package/dist/queries/deep-chains.d.ts +8 -3
- package/dist/queries/deep-chains.js +1 -1
- package/dist/queries/deps.d.ts +2 -2
- package/dist/queries/deps.js +1 -1
- package/dist/queries/diff-gate.d.ts +5 -4
- package/dist/queries/diff-gate.js +1 -1
- package/dist/queries/diff-impact.d.ts +3 -3
- package/dist/queries/diff-impact.js +1 -1
- package/dist/queries/doc-drift.d.ts +4 -2
- package/dist/queries/doc-drift.js +1 -1
- package/dist/queries/drift.d.ts +2 -2
- package/dist/queries/drift.js +1 -1
- package/dist/queries/duplicate-bodies.d.ts +3 -3
- package/dist/queries/duplicate-bodies.js +1 -1
- package/dist/queries/extract-candidates.d.ts +2 -2
- package/dist/queries/extract-candidates.js +1 -1
- package/dist/queries/fan.d.ts +11 -5
- package/dist/queries/fan.js +1 -1
- package/dist/queries/files.d.ts +2 -2
- package/dist/queries/health.d.ts +3 -3
- package/dist/queries/health.js +1 -1
- package/dist/queries/hierarchy.d.ts +2 -2
- package/dist/queries/hierarchy.js +1 -1
- package/dist/queries/hotspots.d.ts +2 -2
- package/dist/queries/hotspots.js +1 -1
- package/dist/queries/imports.d.ts +2 -2
- package/dist/queries/imports.js +1 -1
- package/dist/queries/incomplete-migration.d.ts +3 -3
- package/dist/queries/incomplete-migration.js +1 -1
- package/dist/queries/index.d.ts +5 -5
- package/dist/queries/index.js +1 -1
- package/dist/queries/isolated.d.ts +2 -2
- package/dist/queries/isolated.js +1 -1
- package/dist/queries/locality-candidates.d.ts +2 -2
- package/dist/queries/locality-candidates.js +1 -1
- package/dist/queries/members.d.ts +2 -2
- package/dist/queries/members.js +1 -1
- package/dist/queries/methods.d.ts +2 -2
- package/dist/queries/methods.js +1 -1
- package/dist/queries/not-implemented.d.ts +2 -2
- package/dist/queries/not-implemented.js +1 -1
- package/dist/queries/outline.d.ts +2 -2
- package/dist/queries/outline.js +1 -1
- package/dist/queries/passthrough-candidates.d.ts +3 -3
- package/dist/queries/passthrough-candidates.js +1 -1
- package/dist/queries/plan-context.d.ts +4 -4
- package/dist/queries/plan-context.js +1 -1
- package/dist/queries/react-component-duplicates.d.ts +4 -2
- package/dist/queries/react-component-duplicates.js +1 -1
- package/dist/queries/react-hook-candidates.d.ts +4 -2
- package/dist/queries/react-hook-candidates.js +1 -1
- package/dist/queries/react-large-component-pressure.d.ts +2 -2
- package/dist/queries/react-large-component-pressure.js +1 -1
- package/dist/queries/recent-duplicates.d.ts +4 -2
- package/dist/queries/recent-duplicates.js +1 -1
- package/dist/queries/redundant-reexports.d.ts +2 -2
- package/dist/queries/redundant-reexports.js +1 -1
- package/dist/queries/refs.d.ts +2 -2
- package/dist/queries/refs.js +1 -1
- package/dist/queries/self-audit.d.ts +2 -2
- package/dist/queries/self-audit.js +1 -1
- package/dist/queries/similar-chains.d.ts +2 -2
- package/dist/queries/similar-chains.js +1 -1
- package/dist/queries/similar-files.d.ts +2 -2
- package/dist/queries/similar-files.js +1 -1
- package/dist/queries/similar-signatures.d.ts +2 -2
- package/dist/queries/similar-signatures.js +1 -1
- package/dist/queries/similar.d.ts +2 -2
- package/dist/queries/similar.js +1 -1
- package/dist/queries/slice.d.ts +2 -2
- package/dist/queries/slice.js +1 -1
- package/dist/queries/stale-abstractions.d.ts +2 -2
- package/dist/queries/stale-abstractions.js +1 -1
- package/dist/queries/stats.d.ts +2 -2
- package/dist/queries/surface.d.ts +2 -2
- package/dist/queries/surface.js +1 -1
- package/dist/queries/symbols.d.ts +2 -2
- package/dist/queries/symbols.js +1 -1
- package/dist/queries/system.d.ts +2 -2
- package/dist/queries/system.js +1 -1
- package/dist/queries/test-quality.d.ts +2 -2
- package/dist/queries/test-quality.js +1 -1
- package/dist/queries/trace.d.ts +2 -2
- package/dist/queries/trace.js +1 -1
- package/dist/queries/twin-ab.d.ts +2 -2
- package/dist/queries/twin-ab.js +1 -1
- package/dist/queries/twin-drift.d.ts +2 -2
- package/dist/queries/twin-drift.js +1 -1
- package/dist/queries/unused-imports.d.ts +2 -2
- package/dist/queries/unused-imports.js +1 -1
- package/dist/queries/unused-params.d.ts +2 -2
- package/dist/queries/unused-params.js +1 -1
- package/dist/queries/vue-component-duplicates.d.ts +4 -2
- package/dist/queries/vue-component-duplicates.js +1 -1
- package/dist/queries/vue-composable-candidates.d.ts +4 -2
- package/dist/queries/vue-composable-candidates.js +1 -1
- package/dist/queries/vue-large-view-pressure.d.ts +2 -2
- package/dist/queries/vue-large-view-pressure.js +1 -1
- package/dist/queries/wrapper-candidates.d.ts +2 -2
- package/dist/queries/wrapper-candidates.js +1 -1
- package/dist/reindex-worker.js +256 -12
- package/dist/reindex.d.ts +29 -3
- package/dist/reindex.js +251 -22
- package/dist/runtime.d.ts +8 -4
- package/dist/runtime.js +2 -2
- 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-DeAbuJ2b.d.ts → scip-cli-BKL-26TZ.d.ts} +2 -2
- package/dist/{symbol-types-DaoeXKUt.d.ts → symbol-types-BgWU6lhL.d.ts} +2 -0
- package/dist/watch-server.js +42 -0
- package/docs/AGENT_GUIDE.md +110 -34
- package/docs/AI_FAILURE_MODES.md +8 -3
- package/docs/COMMAND_REFERENCE.md +10 -6
- package/docs/REGEX_POLICY.md +3 -1
- package/docs/accuracy-audit-checklist.md +300 -0
- package/docs/accuracy-hardening-goal.md +493 -54
- package/docs/analyzer-inventory.md +31 -23
- package/docs/analyzer-validation-ledger.md +51 -21
- package/package.json +2 -1
- package/scripts/build-scip-windows.mjs +7 -7
- package/skills/_shared/SKILL.md +20 -19
- package/skills/scip-calibrate/SKILL.md +4 -2
- package/skills/scip-hyper-optimization/SKILL.md +5 -1
- package/skills/scip-query/SKILL.md +1 -1
- package/skills/scip-setup/SKILL.md +104 -4
- package/skills/scip-verify/SKILL.md +20 -14
- package/dist/chunk-27HMTUJE.js +0 -3
- package/dist/chunk-27XEGMCT.js +0 -7
- package/dist/chunk-3AMWF6V5.js +0 -3
- package/dist/chunk-4SCMYKD6.js +0 -2
- package/dist/chunk-5AAAEZ2Z.js +0 -2
- package/dist/chunk-5JRMZMLM.js +0 -2
- package/dist/chunk-5VY3RIEI.js +0 -38
- package/dist/chunk-6JUAGXR4.js +0 -4
- package/dist/chunk-6KDOYKCB.js +0 -40
- package/dist/chunk-6KMTPNZL.js +0 -3
- package/dist/chunk-7COVQPQQ.js +0 -9
- package/dist/chunk-7S5E7KWT.js +0 -2
- package/dist/chunk-7TVFPOD7.js +0 -102
- package/dist/chunk-A6KSEIRN.js +0 -61
- package/dist/chunk-AAMURYOK.js +0 -4
- package/dist/chunk-BP7S6V3M.js +0 -20
- package/dist/chunk-BRBF3E5X.js +0 -35
- package/dist/chunk-BZXE3HO4.js +0 -6
- package/dist/chunk-CXQQOXSI.js +0 -10
- package/dist/chunk-EVZSAR3S.js +0 -2
- package/dist/chunk-GMOEX7EV.js +0 -2
- package/dist/chunk-GNG622H3.js +0 -3
- package/dist/chunk-GUDKRIGW.js +0 -7
- package/dist/chunk-GULVO6NF.js +0 -43
- package/dist/chunk-HZZQKNVE.js +0 -2
- package/dist/chunk-I4R3SNMR.js +0 -2
- package/dist/chunk-IMQFJ53K.js +0 -2
- package/dist/chunk-ISLWJ4PY.js +0 -10
- package/dist/chunk-IUSSGHJO.js +0 -2
- package/dist/chunk-J5WVNZ6O.js +0 -2
- package/dist/chunk-JJUX2OAP.js +0 -2
- package/dist/chunk-JZBGTSAB.js +0 -13
- package/dist/chunk-K5N5RNGM.js +0 -2
- package/dist/chunk-KSJ544IV.js +0 -5
- package/dist/chunk-LY7NMOBW.js +0 -2
- package/dist/chunk-N23FT4EZ.js +0 -2
- package/dist/chunk-NCVFKOLB.js +0 -2
- package/dist/chunk-PESEPWZO.js +0 -2
- package/dist/chunk-PMY4UFGV.js +0 -2
- package/dist/chunk-Q7PWDXL5.js +0 -5
- package/dist/chunk-QVGFVRKD.js +0 -2
- package/dist/chunk-R5336VHZ.js +0 -2
- package/dist/chunk-RLB6SG25.js +0 -2
- package/dist/chunk-SFDVBARK.js +0 -2
- package/dist/chunk-TG7QSYCJ.js +0 -2
- package/dist/chunk-UHPWZCYQ.js +0 -3
- package/dist/chunk-URSSPS5H.js +0 -2
- package/dist/chunk-WIBFXSYB.js +0 -6
- package/dist/chunk-WMO2VZZK.js +0 -3
- package/dist/chunk-WS3Z6W3M.js +0 -65
- package/dist/chunk-X3DTIEMU.js +0 -18
- package/dist/chunk-X5C43YVI.js +0 -2
- package/dist/chunk-X7CHWTZ2.js +0 -72
- package/dist/chunk-XDESMVOL.js +0 -4
- package/dist/chunk-XZBLZHXL.js +0 -16
- package/dist/chunk-YBGC7HTY.js +0 -3
- package/dist/chunk-ZMGBWSFZ.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `scip-query` are documented here. This file starts at 0.11.0; everything below covers behavior changes made since the 0.10.12 release.
|
|
4
4
|
|
|
5
|
+
## [0.16.1]
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- Outcome history now uses one committed `.scipquery/events/*.json` file per event instead of appending to `.scipquery/ledger/events.jsonl`. This makes concurrent branch writes touch independent paths. The reader remains backward compatible, and the next gate write migrates valid legacy records before removing the old file and its scoped merge rule.
|
|
10
|
+
|
|
11
|
+
## [0.16.0]
|
|
12
|
+
|
|
13
|
+
### Notable (setup and automatic indexing)
|
|
14
|
+
|
|
15
|
+
- **`setup` is now an interactive project wizard.** In a terminal, `scip-query setup` presents a keyboard-controlled checklist for detected language indexers, detected Tree-sitter AST parsers, bundled agent skills, checkout-local hooks, automatic refresh, and the optional initial health audit. `--yes` accepts the recommended defaults for automation, while `--json` remains non-interactive. The redraw logic keeps the checklist anchored while moving with the arrow keys.
|
|
16
|
+
- **Detected AST parser packages can be installed by setup.** Setup installs the Tree-sitter runtime and detected language grammars using the versions pinned by `scip-query`, then probes them again and reports any recovery action. Developers no longer need to discover the package-specific npm commands themselves.
|
|
17
|
+
- **Automatic indexing is demand-started and project-local.** Setup enables automatic refresh unless an existing project explicitly opted out, starts or reuses the checkout's watch service, and verifies the service deadline and language capabilities. The service wakes when the project is used, idles when there is no work, and keeps hook preferences in ignored checkout-local files rather than repository records.
|
|
18
|
+
- **Setup guidance now describes the optimal TypeScript and Rust paths.** The bundled `scip-setup` skill and README cover TypeScript SCIP indexing, persistent `ts-morph` semantics, conditional workspace project shards, Rust SCIP indexing through `rust-analyzer`, durable demand-started Rust semantic sessions, Tree-sitter fallbacks, capability verification, and the distinction between committed records, checkout preferences, and user-environment changes.
|
|
19
|
+
|
|
20
|
+
### Performance (eliminating repeated work)
|
|
21
|
+
|
|
22
|
+
- **Incremental TypeScript SCIP documents and semantic fragments.** TypeScript indexing persists per-document SCIP fragments, computes a conservative affected-file closure, and republishes only affected documents into generation-based SQLite indexes. Shadow-mode measurements expose predicted versus actually changed documents before the affected-set optimization is trusted for a project.
|
|
23
|
+
- **Persistent TypeScript semantic sessions.** Repeated semantic queries reuse loaded TypeScript projects and exact caller/reference fragments across requests and processes. Workspace mode updates only the owned project and invalidates dependent projects when necessary; a single-project repository continues to use the compiler project's own incremental behavior rather than being artificially split.
|
|
24
|
+
- **Generation-based SQLite publication and repair.** Incremental index updates publish an immutable generation and atomically make it current, retain a recovery generation, and diagnose or repair damaged generation state instead of forcing every refresh through a full rebuild.
|
|
25
|
+
- **Durable Rust semantic reuse.** Rust semantic queries reuse complete `rust-analyzer` responses through a readiness-aware durable session, with ordered protocol barriers, deadline-bounded synchronization, stale-response rejection, and worker fallback. A stopped durable session in `status` means demand-idle, not unavailable.
|
|
26
|
+
- **Faster cold TypeScript dead analysis and `twin-drift`.** Exact TypeScript caller resolution is batched and cached, while full `twin-drift` scans prune impossible candidates earlier and use indexed lookup paths.
|
|
27
|
+
- **New repeated-work instrumentation.** Work identities and `work-audit` profiles attribute repeated computation to subsystems so optimization candidates can be selected from measured reuse misses instead of command-level wall time alone.
|
|
28
|
+
|
|
29
|
+
### Accuracy and credibility
|
|
30
|
+
|
|
31
|
+
- **TypeScript detector certification.** Factual dead-code evidence and TypeScript graph, architecture, React, and Vue signals gained calibrated fixtures and evidence contracts. Vue reference identities are qualified correctly, navigation callers exclude reference-only edges, and capability output distinguishes syntax-only checks from semantic verification.
|
|
32
|
+
- **Rust detector hardening.** Dead-code evidence now preserves implicit imports and excludes trait requirements, trait implementations, convention-driven twins, and trait wrappers where the apparent duplicate or unused symbol is part of Rust's language contract. Signature candidates are restricted to cases the available evidence can support.
|
|
33
|
+
- **Python detector hardening.** Python liveness now preserves runtime exports, protocol hooks, and model/framework conventions that consume symbols indirectly.
|
|
34
|
+
- **Investigatory health findings are labeled as candidates.** Composite health output discloses capability limits and keeps heuristic findings investigatory instead of presenting them as automatically actionable facts. Accuracy roadmaps now record which detector families were calibrated, certified, unsupported, or deliberately limited.
|
|
35
|
+
|
|
36
|
+
### Fixes and maintenance
|
|
37
|
+
|
|
38
|
+
- Setup now applies automatic-refresh defaults consistently and keeps local setup preferences separate from committed repository records.
|
|
39
|
+
- Full-result query limits remain within SQLite's parameter limits instead of failing on large candidate sets.
|
|
40
|
+
- The repository's own actionable health findings were resolved; remaining reviewed signals are recorded as explicit suppressions rather than silently ignored.
|
|
41
|
+
|
|
5
42
|
## [0.15.0]
|
|
6
43
|
|
|
7
44
|
### Breaking (behavior change for one command)
|
|
@@ -10,8 +47,11 @@ All notable changes to `scip-query` are documented here. This file starts at 0.1
|
|
|
10
47
|
|
|
11
48
|
### Notable (new capabilities)
|
|
12
49
|
|
|
50
|
+
- **`setup` now completes automatic-indexing installation instead of only describing it.** A project with no prior watch decision gets `watch.enabled: true`; an existing explicit `false` remains an opt-out, and `setup --guided` presents enablement as a recommended consent choice. Setup starts or reuses the project service after reindexing, verifies its published clean-idle deadline, and reports Rust's final durable/worker transport, lifecycle state, and fallback after the health audit. The status read itself is passive; semantic health work may legitimately wake rust-analyzer. `init` now writes the same enabled demand-started default.
|
|
13
51
|
- **Committed outcome-event ledger.** Hook-mode `diff-gate` runs now mirror finding transitions (caught / resolved / suppressed / reopened) into `.scipquery/ledger/events.jsonl` — an append-only, one-event-per-line log stamped with the HEAD commit and, when known, the finding's SCIP symbol. A scoped `.gitattributes` (`merge=union`) is written alongside it, so concurrent appends from different branches merge without conflict; read-side dedupe by `(check, findingId, event, commit)` absorbs replays. Unlike the per-machine `evidence.db` ledger, this file is meant to be committed: outcome history survives re-clones and aggregates across every machine and agent working the repo. Ledger writes never block the hook — failures degrade to a stderr note.
|
|
14
52
|
- **New command: `effectiveness`.** Reads the committed event ledger and reports, per diff-gate check: findings caught, fixed by code changes (disappeared without a suppression), suppressed, still open, reopened, `moved` (rename noise — a resolved id whose symbol was re-caught under a new id at the same commit), precision (fixed ÷ concluded), and median days-to-fix. `--since 30d|12w|<ISO date>` windows by when the finding was caught, `--check <name>` filters, `--json` emits the standard envelope. This is the tool keeping score on itself: suppressions count against a detector's precision, fixes count for it.
|
|
53
|
+
- **Setup now reports and enforces ownership scopes.** Guided actions and setup results identify repository records to commit, checkout preferences to keep local, and user-environment changes. Project hooks always target `.codex/hooks.json` and `.claude/settings.local.json`, are excluded through `.git/info/exclude`, and refuse to alter an already tracked target. `--shared` remains accepted as a deprecated compatibility flag but no longer writes tracked Claude settings. Guided indexer consent now controls the installer, and the decorative parser-runtime question was removed.
|
|
54
|
+
- **Installed Stop hooks now update effectiveness history.** The normal `hook-stop` path shares the same caught/resolved/suppressed/reopened recorder as legacy `diff-gate --hook`, including clean runs that resolve earlier findings. Generated agent guidance requires committing suppression and outcome records while forbidding commits of checkout hook files; project uninstall names those shared records as intentionally preserved.
|
|
15
55
|
|
|
16
56
|
### Breaking (behavior change for one config key)
|
|
17
57
|
|
|
@@ -26,7 +66,7 @@ All notable changes to `scip-query` are documented here. This file starts at 0.1
|
|
|
26
66
|
### Breaking (one-way doors — read before upgrading)
|
|
27
67
|
|
|
28
68
|
- **`npm install` no longer installs anything beyond the package itself.** Postinstall used to symlink skills into your home directory and could shell out to `brew`/`go install` for missing toolchains. It now prints exactly one line — `scip-query installed -- run 'scip-query setup' in a repo to enable skills, hooks, and the index.` — and does nothing else. Run `scip-query setup` explicitly in a project to get skills, hooks, and a first index.
|
|
29
|
-
- **Project hooks
|
|
69
|
+
- **Project hooks are checkout-local.** `scip-query setup` (and `setup-hooks`) write Codex and Claude Code hooks to `.codex/hooks.json` and `.claude/settings.local.json`, exclude both through `.git/info/exclude`, and will not mutate a path Git already tracks. A teammate's agent tooling preferences therefore do not land in Git. The old `setup-hooks --shared` input is deprecated and now has the same local behavior. `setup-hooks --remove` writes an ignored decline tombstone so a later `setup` won't silently re-add hooks you removed; `--force` overrides it.
|
|
30
70
|
- **Suppression IDs use a new stable hash.** `.scipquery.json` suppression `id`s are now derived from `(check, symbol, file)` only, not the full match set, so an unrelated new similar function elsewhere no longer silently un-suppresses an accepted finding. Existing legacy-format IDs still match (dual-matching) — nothing in your config needs to change today — but `config-validate` now prints an info diagnostic naming the stable replacement for each legacy entry.
|
|
31
71
|
- **Windows no longer ships a vendored `scip.exe`.** The 39 MB vendored binary is gone. Windows installs now receive the binary through `scip-query-scip-windows`, a universal (x64 + arm64) os-gated optional npm dependency fetched only on Windows; resolution order is PATH → `SCIP_QUERY_SCIP_BIN` env → sidecar package → printed instructions. Publishing the main package auto-builds and auto-publishes the sidecar (`prepublishOnly`). Set `SCIP_QUERY_SCIP_BIN` to a local `scip.exe` to override.
|
|
32
72
|
- **`convergence` is deprecated.** Use `similar <symbol1> <symbol2> --plan` instead. `convergence` still works (as a thin alias) but is not the documented path going forward.
|
package/README.md
CHANGED
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
<a href="https://www.apache.org/licenses/LICENSE-2.0"><img alt="License" src="https://img.shields.io/npm/l/scip-query.svg"></a>
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Coding agents operate at too concrete a level of abstraction. They work in files and grep, while every decision that actually matters — does a helper for this already exist, what depends on the thing I'm about to change, is this migration finished or just started — lives one level up, in symbols, references, and history. `scip-query` raises agents to that level: a TypeScript CLI and npm package built on SCIP indexes, git history, language-aware source analysis, and your repository's own checks.
|
|
24
24
|
|
|
25
|
-
Agents are
|
|
25
|
+
The failure mode it targets is specific. Agents are genuinely good at editing the code in front of them; what they lose is the whole-repository model across a long task. They re-implement helpers they never saw, plan from partial context, migrate three call sites and abandon the other two, miss the file that always changes with the one they touched, and declare a diff finished while it quietly adds duplication, dead code, and docs that now lie. None of that is a syntax error, so nothing stops it — it just accumulates until complexity nukes your development momentum.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
So the loop this tool enforces is evidence at every step: map the target and its blast radius, plan from repository facts, check for reuse before adding a concept, detect unfinished migrations and hidden coupling, and gate the finished diff. It does not replace the compiler, tests, or review. The point is to make structural evidence so cheap to ask for that agents actually ask — and to make "done" something the repository gets a vote on.
|
|
28
28
|
|
|
29
29
|
## How Agents Use It
|
|
30
30
|
|
|
@@ -34,14 +34,14 @@ Two layers, wired by `scip-query setup`:
|
|
|
34
34
|
|
|
35
35
|
**Invoked** — the agent routes work through skills, each carrying its own short command list so it never navigates the full CLI:
|
|
36
36
|
|
|
37
|
-
| Phase | Skill
|
|
38
|
-
| --------- |
|
|
39
|
-
| Orient | `scip-explore`
|
|
40
|
-
| Plan | `scip-concrete-plan` (one change) · `scip-conductor` (a program) | `plan-context`, `change-surface`, `co-change`
|
|
41
|
-
| Reuse | (taught in-loop by the planning skills)
|
|
42
|
-
| Implement | your agent + the post-change check for the change type
|
|
43
|
-
| Verify | `scip-verify` (closeout) + the ambient diff gate
|
|
44
|
-
| Clean up | `scip-cleanup-audit` → `scip-cleanup-improve`
|
|
37
|
+
| Phase | Skill | Commands underneath (also usable directly) |
|
|
38
|
+
| --------- | ---------------------------------------------------------------- | ---------------------------------------------------- |
|
|
39
|
+
| Orient | `scip-explore` | `system`, `trace`, `plan-context`, `call-graph` |
|
|
40
|
+
| Plan | `scip-concrete-plan` (one change) · `scip-conductor` (a program) | `plan-context`, `change-surface`, `co-change` |
|
|
41
|
+
| Reuse | (taught in-loop by the planning skills) | `similar`, `duplicate-bodies`, `recent-duplicates` |
|
|
42
|
+
| Implement | your agent + the post-change check for the change type | `incomplete-migration`, `unused-params`, `co-change` |
|
|
43
|
+
| Verify | `scip-verify` (closeout) + the ambient diff gate | `diff-impact`, `diff-gate`, `health --baseline` |
|
|
44
|
+
| Clean up | `scip-cleanup-audit` → `scip-cleanup-improve` | `cleanup-plan --verify`, `dead`, `twin-drift` |
|
|
45
45
|
|
|
46
46
|
Interrogation lenses go deeper on demand: `scip-integrity-audit` ("is this implementation real?"), `scip-twin-drift`, `scip-claim-audit`, `scip-probe-reachability`, and `scip-maintainability`. The full map with essential differences is in [Bundled skills](#bundled-skills); every command remains directly invocable for humans and scripts.
|
|
47
47
|
|
|
@@ -53,12 +53,21 @@ React and Vue repositories get additional framework-aware checks for repeated co
|
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
55
|
npm install -g scip-query@latest
|
|
56
|
-
scip-query setup #
|
|
57
|
-
scip-query check-deps
|
|
58
|
-
scip-query reindex
|
|
56
|
+
scip-query setup # interactive checklist in a terminal
|
|
59
57
|
```
|
|
60
58
|
|
|
61
|
-
|
|
59
|
+
The setup checklist detects the repository's languages and offers to install or
|
|
60
|
+
repair the matching SCIP indexers, Tree-sitter AST parsers, agent skills, and
|
|
61
|
+
checkout-local hooks. It enables demand-started automatic incremental indexing,
|
|
62
|
+
builds the first index, verifies semantic and checker capabilities, and can run
|
|
63
|
+
the optional full health audit. Use the arrow keys and Space to change the
|
|
64
|
+
selection, then Enter to continue.
|
|
65
|
+
|
|
66
|
+
For automation, use `scip-query setup --yes` to accept recommended defaults or
|
|
67
|
+
`scip-query setup --json` for a non-interactive machine-readable report. Use
|
|
68
|
+
`--no-hooks`, `--no-skills`, `--no-parsers`, or `--no-health` only when that
|
|
69
|
+
scope is intentionally managed elsewhere. Or run without a global install:
|
|
70
|
+
`npx scip-query@latest setup`.
|
|
62
71
|
|
|
63
72
|
### If npm warns about install scripts
|
|
64
73
|
|
|
@@ -70,7 +79,7 @@ which leaves the native modules unbuilt. Every script on that list is expected:
|
|
|
70
79
|
- `better-sqlite3` — builds/downloads the native SQLite binding that backs the index
|
|
71
80
|
- `tree-sitter` + the per-language grammars — native parsers behind multi-language source facts
|
|
72
81
|
|
|
73
|
-
Approve them and re-run the builds (`--allow-scripts-pending` only
|
|
82
|
+
Approve them and re-run the builds (`--allow-scripts-pending` only _lists_ — the approving forms
|
|
74
83
|
are `npm approve-scripts <pkg> ...` or `--all`):
|
|
75
84
|
|
|
76
85
|
```bash
|
|
@@ -110,7 +119,7 @@ scip-query health --write-baseline
|
|
|
110
119
|
|
|
111
120
|
## Evidence and Confidence
|
|
112
121
|
|
|
113
|
-
`scip-query`
|
|
122
|
+
A claim you can't trace to evidence is a vibe. `scip-query` labels every answer with where it came from and how much weight it deserves:
|
|
114
123
|
|
|
115
124
|
```mermaid
|
|
116
125
|
flowchart LR
|
|
@@ -127,17 +136,24 @@ flowchart LR
|
|
|
127
136
|
4. **Git-history signals** for churn, co-change, recency, and documentation drift.
|
|
128
137
|
5. **Repository-toolchain verification** for supported cleanup plans.
|
|
129
138
|
|
|
130
|
-
Heuristic findings are candidates for inspection, not
|
|
139
|
+
Heuristic findings are candidates for inspection, not verdicts — the finding always sounds right, because it was generated to; only the code knows. Run `scip-query capabilities` to see which evidence and verification layers are available for the current repository and language.
|
|
131
140
|
|
|
132
141
|
## Language and Framework Coverage
|
|
133
142
|
|
|
134
143
|
Graph navigation works through supported [SCIP](https://github.com/sourcegraph/scip) indexers. Higher-confidence augmentation and verification vary by language and project toolchain. TypeScript currently has the richest semantic augmentation. React and Vue add built-in framework-aware maintainability checks on top of the core workflow.
|
|
135
144
|
|
|
145
|
+
Rust projects are indexed through rust-analyzer's SCIP output. Compiler-backed
|
|
146
|
+
Rust reference, callee, signature, and module/use evidence runs through a
|
|
147
|
+
demand-started durable rust-analyzer session with bounded worker fallback.
|
|
148
|
+
Capability and status output distinguish indexer readiness, semantic readiness,
|
|
149
|
+
the selected transport, and whether the idle helper is currently stopped or
|
|
150
|
+
live.
|
|
151
|
+
|
|
136
152
|
Clojure projects are indexed through `scip-clojure`. Source fallback adds namespace imports, callable/callsite evidence, and protocol/record member evidence for `.clj`, `.cljs`, and `.cljc` files. When the project has `clj-kondo` available, cleanup-plan verification can use `clj-kondo --lint .`. Clojure does not currently have a scip-query semantic provider equivalent to TypeScript's `ts-morph` layer; capability output reports that boundary explicitly.
|
|
137
153
|
|
|
138
154
|
## Cleaning Up AI-Generated Code
|
|
139
155
|
|
|
140
|
-
|
|
156
|
+
Every check here exists because I watched the failure mode happen — in AI-generated codebases I inherited and rebuilt, and in my own agent sessions. AI-assisted development doesn't rot a codebase in general; it rots it in specific, recurring shapes, and each shape gets its own detector. The full catalog, with prevention wiring for each one, is in [docs/AI_FAILURE_MODES.md](docs/AI_FAILURE_MODES.md):
|
|
141
157
|
|
|
142
158
|
**1. Find the echoes.** Agents re-implement helpers, hooks, composables, and frontend components they didn't know existed. `recent-duplicates` makes similarity _directional_ using git file ages - which side is the established original, which is the recent echo.
|
|
143
159
|
|
|
@@ -226,19 +242,19 @@ scip-query suppress SQABC123DEF456 --check echo --reason "intentional compatibil
|
|
|
226
242
|
|
|
227
243
|
This writes one file per suppression under `.scipquery/suppressions/` — commit it with your change. One-file-per-suppression means two branches suppressing different findings merge without conflict; the legacy `suppressions[]` array in `.scipquery.json` is still honored (read-only). Every suppression requires a reason plus either a stable finding id or a `check` (optionally narrowed by `file`). Check+file suppressions are allowed but warn because they waive every matching finding in that file. `diff-gate --json` reports both active and suppressed findings.
|
|
228
244
|
|
|
229
|
-
**12. Measure whether the gate is earning its keep.** Every
|
|
245
|
+
**12. Measure whether the gate is earning its keep.** Every completed `diff-gate` run, including JSON and installed Stop-hook runs, writes each finding transition to its own committed `.scipquery/events/*.json` file. Independent branches add independent paths instead of editing one shared ledger file, so ordinary event writes do not create merge conflicts. A finding that disappears on a later run against the same non-null HEAD is a verified fix. If HEAD changed or Git evidence is unavailable, the disappearance is reported as `unverified` rather than credited as a fix. A suppressed finding was noise or an accepted trade-off:
|
|
230
246
|
|
|
231
247
|
```bash
|
|
232
248
|
scip-query effectiveness --since 30d
|
|
233
249
|
```
|
|
234
250
|
|
|
235
251
|
```
|
|
236
|
-
check caught fixed suppressed open moved precision median-days-to-fix
|
|
237
|
-
echo 14
|
|
238
|
-
new-dead 6 5 0 1 0 100% 0.3
|
|
252
|
+
check caught fixed suppressed open moved unverified precision median-days-to-fix
|
|
253
|
+
echo 14 10 2 1 0 1 83% 0.8
|
|
254
|
+
new-dead 6 5 0 1 0 0 100% 0.3
|
|
239
255
|
```
|
|
240
256
|
|
|
241
|
-
`precision` is fixed ÷ (fixed + suppressed)
|
|
257
|
+
`precision` is verified fixed ÷ (verified fixed + suppressed). `moved` separates rename churn, while `unverified` prevents a commit or missing Git identity from masquerading as a confirmed repair. Run diff-gate once to record the finding and again after the repair, before committing, to earn same-HEAD verification. Filter with `--check <name>`, window with `--since 30d|12w|<ISO date>`, and get machine-readable output with `--json`. Because the event files are committed, the numbers survive re-clones and aggregate across every machine and agent working the repo. Legacy `.scipquery/ledger/events.jsonl` records remain readable and are migrated to individual files on the next gate write. Standalone health/cleanup commands are not yet outcome-tracked because they do not all expose a complete-scan contract.
|
|
242
258
|
|
|
243
259
|
Before any edit, `plan-context <target>` bundles the structural picture — definitions, references, call graph, blast radius — plus a HISTORY section: churn, fix-commit density, and the files that usually change together with the target ("editing this usually means editing these").
|
|
244
260
|
|
|
@@ -295,40 +311,66 @@ Heuristic detectors carry guardrails learned from real codebases: published `pac
|
|
|
295
311
|
|
|
296
312
|
One-line "essential difference" per skill — read this table before the Routes table in `skills/scip-query/SKILL.md` if two names sound alike.
|
|
297
313
|
|
|
298
|
-
| Skill
|
|
299
|
-
|
|
|
300
|
-
| `scip-query`
|
|
301
|
-
| `scip-explore`
|
|
302
|
-
| `scip-concrete-plan`
|
|
303
|
-
| `scip-conductor`
|
|
304
|
-
| `scip-debug`
|
|
305
|
-
| `scip-triage-issue`
|
|
306
|
-
| `scip-verify`
|
|
307
|
-
| `scip-cleanup-audit`
|
|
308
|
-
| `scip-cleanup-improve`
|
|
309
|
-
| `scip-maintainability`
|
|
310
|
-
| `scip-integrity-audit`
|
|
311
|
-
| `scip-calibrate`
|
|
312
|
-
| `scip-twin-drift`
|
|
313
|
-
| `scip-claim-audit`
|
|
314
|
-
| `scip-probe-reachability`
|
|
315
|
-
| `scip-api-impact`
|
|
316
|
-
| `scip-directory-architecture` | Folder/ownership layout.
|
|
317
|
-
| `scip-doc-reconcile`
|
|
318
|
-
| `scip-diagram`
|
|
319
|
-
| `scip-react-maintainability`
|
|
320
|
-
| `scip-vue-maintainability`
|
|
321
|
-
| `scip-language-playbook`
|
|
322
|
-
| `scip-hyper-optimization`
|
|
323
|
-
| `scip-tla-model-system`
|
|
324
|
-
| `scip-setup`
|
|
325
|
-
| `_shared`
|
|
314
|
+
| Skill | Essential difference |
|
|
315
|
+
| ----------------------------- | -------------------------------------------------------------------------------------- |
|
|
316
|
+
| `scip-query` | Router: dispatches codebase work to the specialist skill below. |
|
|
317
|
+
| `scip-explore` | Understand before touching. |
|
|
318
|
+
| `scip-concrete-plan` | Specify ONE change so an executor can't guess. |
|
|
319
|
+
| `scip-conductor` | Run a multi-phase program (delegate, verify handoffs, pre-registered benchmarks). |
|
|
320
|
+
| `scip-debug` | Root-cause a failure. |
|
|
321
|
+
| `scip-triage-issue` | Package a report into an actionable issue+fix plan. |
|
|
322
|
+
| `scip-verify` | Post-change closeout gate. |
|
|
323
|
+
| `scip-cleanup-audit` | Rank findings, no edits. |
|
|
324
|
+
| `scip-cleanup-improve` | Autonomously fix confirmed findings. |
|
|
325
|
+
| `scip-maintainability` | Is this well-organized (scattered concepts, accidental variation)? |
|
|
326
|
+
| `scip-integrity-audit` | Is this real (decorative checkers, faked implementations, dead fallback-hidden paths)? |
|
|
327
|
+
| `scip-calibrate` | Measure detector precision on a repo before trusting scores or gating anyone. |
|
|
328
|
+
| `scip-twin-drift` | Same-name implementations that drifted apart. |
|
|
329
|
+
| `scip-claim-audit` | Status words derived vs asserted. |
|
|
330
|
+
| `scip-probe-reachability` | Prove parser/AST branches actually fire. |
|
|
331
|
+
| `scip-api-impact` | Blast radius before changing public surfaces. |
|
|
332
|
+
| `scip-directory-architecture` | Folder/ownership layout. |
|
|
333
|
+
| `scip-doc-reconcile` | Docs vs code drift. |
|
|
334
|
+
| `scip-diagram` | Visual artifacts. |
|
|
335
|
+
| `scip-react-maintainability` | Framework-specific reuse lens (React). |
|
|
336
|
+
| `scip-vue-maintainability` | Framework-specific reuse lens (Vue). |
|
|
337
|
+
| `scip-language-playbook` | Which commands per language. |
|
|
338
|
+
| `scip-hyper-optimization` | Performance campaigns without output changes. |
|
|
339
|
+
| `scip-tla-model-system` | Formal models tied to code evidence. |
|
|
340
|
+
| `scip-setup` | Adopt or repair scip-query in a repo. |
|
|
341
|
+
| `_shared` | Reference loaded by other skills, not user-invoked. |
|
|
326
342
|
|
|
327
343
|
The confusable clusters, disambiguated: `scip-concrete-plan` (one change) vs `scip-conductor` (a program of changes with delegation); `scip-cleanup-audit` (report only) vs `scip-cleanup-improve` (autonomous fixing loop); `scip-verify` (did this specific change land safely) vs `scip-integrity-audit` (does this code actually work at all) vs `scip-maintainability` (is this well organized) vs `scip-twin-drift` (one drifted same-name pair specifically); `scip-directory-architecture` (folder ownership) vs `scip-maintainability` (deeper structural compression). `skills/scip-query/SKILL.md`'s Tie-Breaks section has the full routing logic.
|
|
328
344
|
|
|
329
|
-
Project setup writes reviewable
|
|
330
|
-
|
|
331
|
-
For a project, run `scip-query setup`. It
|
|
345
|
+
Project setup writes reviewable checkout-local lifecycle hooks for Codex and Claude Code (`.codex/hooks.json` and `.claude/settings.local.json`). A checkout-local hook is an agent-tool preference whose defining trait is that it applies to one clone rather than expressing team policy. Setup adds both paths to that clone's `.git/info/exclude`, so they do not appear in commits, and refuses to rewrite either path if it is already tracked. `setup-hooks --shared` remains accepted only as a deprecated compatibility flag; it no longer writes `.claude/settings.json`. These hooks add scip-query context at session start, route prompts toward the right skill, and run an advisory Stop-hook wrapper around the diff gate only for that repository. The Stop hook sends feedback to the agent by default instead of blocking; set `SCIP_QUERY_STOP_HOOK_MODE=warn` for a warning-only hook response, or `SCIP_QUERY_STOP_HOOK_MODE=block` to enforce the gate. Set `SCIP_QUERY_SKIP_HOOK_INSTALL=1` or run `scip-query setup --no-hooks` to skip hook installation during setup, and run `scip-query setup-hooks --json` later to repair the current checkout's hooks.
|
|
346
|
+
|
|
347
|
+
For a project, run `scip-query setup`. It enables demand-started automatic
|
|
348
|
+
indexing unless the project already has an explicit `watch.enabled: false`,
|
|
349
|
+
starts or reuses the project service, verifies its clean-idle deadline, and
|
|
350
|
+
reports Rust's final durable/worker semantic selection and lifecycle state.
|
|
351
|
+
The status read is passive; the setup health audit may make a semantic request
|
|
352
|
+
that wakes rust-analyzer, after which the helper exits on clean idle.
|
|
353
|
+
It also installs/refreshes skills, configures project-local hooks unless
|
|
354
|
+
skipped, checks indexer readiness, attempts configured indexer remediation,
|
|
355
|
+
refreshes the index, smoke-tests representative command families, writes
|
|
356
|
+
`docs/scip-query/health-dossier.md` and `.json` when the optional health pass is
|
|
357
|
+
selected, reports the health score and items needing attention, and seeds
|
|
358
|
+
AGENTS.md/CLAUDE.md guidance. Use
|
|
359
|
+
the default terminal checklist to accept or decline the recommended automatic
|
|
360
|
+
indexing action and other project-local changes (`--guided` reopens it
|
|
361
|
+
explicitly). After setup,
|
|
362
|
+
`scip-cleanup-audit` confirms raw signals and `scip-cleanup-improve` keeps
|
|
363
|
+
fixing the worst confirmed items until no safe confirmed cleanup remains. Use
|
|
364
|
+
`scip-query setup --git-hook` when you also want a local pre-commit diff gate.
|
|
365
|
+
CI setup is intentionally separate.
|
|
366
|
+
|
|
367
|
+
Setup classifies every change by where its facts belong:
|
|
368
|
+
|
|
369
|
+
- **Repository records (commit):** shared project policy and history whose value comes from surviving clones and branches, including `.scipquery.json`, AGENTS/CLAUDE guidance, health dossiers, `.scipquery/suppressions/*.json`, and `.scipquery/ledger/`.
|
|
370
|
+
- **Checkout preferences (do not commit):** integration settings for one clone, including `.codex/hooks.json`, `.claude/settings.local.json`, `.git/info/exclude`, and an optional `.git/hooks/pre-commit` backstop.
|
|
371
|
+
- **User environment:** installed skills and language indexers used across checkouts on that machine.
|
|
372
|
+
|
|
373
|
+
Rebuildable indexes, caches, and service state are runtime state: generated working data whose defining trait is that source plus configuration can reproduce it. They remain outside the repository by default. `setup --guided` labels each question with its scope, and both human and JSON setup reports return the resulting scope buckets.
|
|
332
374
|
|
|
333
375
|
## Formal Models (TLA+)
|
|
334
376
|
|
|
@@ -347,7 +389,8 @@ scip-query tla fetch-tools # download the pinned tla2t
|
|
|
347
389
|
## Quick Start
|
|
348
390
|
|
|
349
391
|
```bash
|
|
350
|
-
scip-query setup
|
|
392
|
+
scip-query setup # interactive: languages, indexers, parsers, hooks, indexing, capabilities
|
|
393
|
+
scip-query status --capabilities
|
|
351
394
|
|
|
352
395
|
scip-query stats
|
|
353
396
|
scip-query system src/auth
|
|
@@ -394,9 +437,23 @@ Vue single-file components are handled through the JavaScript/TypeScript indexer
|
|
|
394
437
|
|
|
395
438
|
By default, indexes live in `~/.cache/scip-query/projects/<hash>/`, keeping project directories clean. Override paths with `.scipquery.json` or `SCIP_QUERY_*` environment variables. Reindexing writes per-language SCIP shards next to the SQLite index, so a mixed-language repo can reuse unchanged language outputs and rerun only the languages whose source/config inputs changed.
|
|
396
439
|
|
|
440
|
+
Each rebuilt generation also records an affected-set shadow beside the index:
|
|
441
|
+
the files a future incremental writer would recompute, the normalized
|
|
442
|
+
documents/facts that the authoritative full rebuild actually changed, recall,
|
|
443
|
+
and any conservative fallback reason. `scip-query status` shows a compact
|
|
444
|
+
summary and telemetry path; `status --json` exposes the structured
|
|
445
|
+
`affectedSetShadow` object. Shadow results are observational in this phase and
|
|
446
|
+
never decide which indexer runs or which generation publishes.
|
|
447
|
+
|
|
397
448
|
TypeScript monorepos can opt into project sharding with `indexer.typescript.projectMode: "workspace"`. In that mode, `scip-query` discovers repo-local TypeScript project roots, runs one `scip-typescript` process per project with bounded concurrency, merges the shard protobufs, and still publishes one TypeScript language index. Set `indexer.typescript.projects` to an explicit list of project directories or tsconfig paths when automatic discovery is too broad. When `projects` is set to a non-empty list, it is authoritative: only the listed projects are indexed, automatic discovery does not run, and the repo root is not re-added alongside them (even if the root tsconfig covers subdirectories) — files that are only covered by an excluded root tsconfig (e.g. shared ambient `.d.ts` files) drop out of the index, so pick the list deliberately. An empty or absent `projects` falls back to full discovery, unchanged. Workspace mode also caches each project shard: reindexing after an edit reruns only the changed projects and their dependents (workspace `package.json` dependencies and tsconfig `paths`/`references` targets count as dependencies), serves untouched projects from `language-indexes/typescript-projects/`, and reports every reuse decision in `reindex --json` shard diagnostics. Set `indexerConcurrency` when a repo needs a persistent worker cap; CLI `--indexer-concurrency` and `SCIP_QUERY_INDEXER_CONCURRENCY` still override ad hoc runs.
|
|
398
449
|
Use `indexer.typescript.pnpmWorkspaces` only with the default single-project mode; workspace mode passes explicit projects instead.
|
|
399
450
|
|
|
451
|
+
Do not enable workspace mode merely because a repository uses TypeScript. Use
|
|
452
|
+
it when the repository has multiple real tsconfig/project boundaries and the
|
|
453
|
+
setup/readiness evidence confirms them. Single-project repositories already
|
|
454
|
+
reuse unchanged TypeScript documents and keep a persistent ts-morph Project in
|
|
455
|
+
the demand-started service.
|
|
456
|
+
|
|
400
457
|
Clojure projects can pass a project-local `scip-clojure` config file through `.scipquery.json`:
|
|
401
458
|
|
|
402
459
|
```json
|
|
@@ -430,10 +487,11 @@ It creates a minimal `.scipquery.json`:
|
|
|
430
487
|
{
|
|
431
488
|
"languages": ["typescript"],
|
|
432
489
|
"watch": {
|
|
433
|
-
"enabled":
|
|
434
|
-
"debounceMs":
|
|
435
|
-
"cooldownMs":
|
|
490
|
+
"enabled": true,
|
|
491
|
+
"debounceMs": 250,
|
|
492
|
+
"cooldownMs": 0,
|
|
436
493
|
"gitPollMs": 2000,
|
|
494
|
+
"idleTimeoutMs": 600000,
|
|
437
495
|
"autoRefresh": true
|
|
438
496
|
}
|
|
439
497
|
}
|
|
@@ -442,7 +500,31 @@ It creates a minimal `.scipquery.json`:
|
|
|
442
500
|
Add optional fields such as `indexerConcurrency`, `indexer`, `entryRoots`,
|
|
443
501
|
`declaredCouplings`, and `suppressions` only when the project needs them.
|
|
444
502
|
|
|
445
|
-
`scip-query
|
|
503
|
+
`scip-query init` and a first `scip-query setup` enable this lifecycle. An
|
|
504
|
+
existing explicit `watch.enabled: false` remains an opt-out unless guided setup
|
|
505
|
+
selects the recommended enable action. With `watch.enabled`, normal commands
|
|
506
|
+
and agent hooks wake one per-project
|
|
507
|
+
background service. Relevant file/Git activity keeps it alive; it exits after
|
|
508
|
+
`idleTimeoutMs` of clean inactivity and wakes on the next command. Set the idle
|
|
509
|
+
timeout to `0` to keep it running. `scip-query watch` still provides foreground
|
|
510
|
+
mode, while `watch --daemon`, `watch --status`, and `watch --stop` expose the
|
|
511
|
+
background lifecycle. Both modes share one project lock, so only one can own an
|
|
512
|
+
index cache.
|
|
513
|
+
|
|
514
|
+
The same demand-started service lazily owns TypeScript compiler Projects after
|
|
515
|
+
the first command that needs ts-morph semantics. Separate CLI processes reuse
|
|
516
|
+
that session through a repository-local atomic mailbox; source-only index
|
|
517
|
+
generations refresh the existing Projects, while configuration or uncertain
|
|
518
|
+
changes replace them. `watch --status` reports Project/session/request counts.
|
|
519
|
+
If the service is stopped, incompatible, busy beyond its bound, or returns an
|
|
520
|
+
invalid response, the command falls back to the existing in-process ts-morph
|
|
521
|
+
provider.
|
|
522
|
+
|
|
523
|
+
Rust semantic requests use a separate demand-started durable rust-analyzer
|
|
524
|
+
session by default. It remains stopped until a Rust semantic request needs it,
|
|
525
|
+
exits after its clean idle period, and automatically falls back to the
|
|
526
|
+
per-command worker on helper/readiness/timeout/request failure. Set
|
|
527
|
+
`SCIP_RUST_SEMANTIC_DURABLE_SESSION=0` for an explicit worker-only opt-out.
|
|
446
528
|
|
|
447
529
|
Use `declaredCouplings` for files that intentionally form one maintenance unit.
|
|
448
530
|
These pairs are treated as structurally linked by `co-change` and health, while
|
|
@@ -473,12 +555,12 @@ dead and isolated cleanup detectors.
|
|
|
473
555
|
|
|
474
556
|
Useful environment variables:
|
|
475
557
|
|
|
476
|
-
| Variable | Purpose
|
|
477
|
-
| ------------------------- |
|
|
478
|
-
| `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory
|
|
479
|
-
| `SCIP_QUERY_INDEX_DB` | Override the SQLite database path
|
|
480
|
-
| `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path
|
|
481
|
-
| `SCIP_QUERY_CACHE_DIR` | Override the cache directory
|
|
558
|
+
| Variable | Purpose |
|
|
559
|
+
| ------------------------- | ---------------------------------------------------------------------- |
|
|
560
|
+
| `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
|
|
561
|
+
| `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
|
|
562
|
+
| `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
|
|
563
|
+
| `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
|
|
482
564
|
| `SCIP_QUERY_SCIP_BIN` | Path to a local `scip` binary (overrides PATH and the Windows sidecar) |
|
|
483
565
|
|
|
484
566
|
Query results are filtered through the project's `.gitignore`. If none exists, common generated directories such as `dist/`, `target/`, `node_modules/`, and `.venv/` are excluded by default.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{c as t}from"./chunk-JRFCWCOD.js";import"./chunk-FFIYGYQR.js";import{writeFileSync as o}from"fs";import{workerData as s}from"worker_threads";var e=s;try{let r=t({projectRoot:e.projectRoot,dbPath:e.dbPath,tsconfig:e.tsconfig,vueFiles:e.vueFiles,tasks:e.tasks});o(e.resultPath,JSON.stringify({ok:!0,result:r}))}catch(r){o(e.resultPath,JSON.stringify({ok:!1,error:r instanceof Error?r.message:String(r)}))}finally{let r=new Int32Array(e.sharedBuffer);Atomics.add(r,0,1),Atomics.notify(r,0)}
|
|
2
2
|
//# sourceMappingURL=augment-vue-worker.js.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{a as S}from"./chunk-S2FZILCF.js";import{a as y}from"./chunk-MZB3DTHW.js";import{a as P}from"./chunk-B75HZHUP.js";import{a as x}from"./chunk-3I34FZ6R.js";import{a as h,g as b}from"./chunk-NLRWGGPY.js";import{a as v}from"./chunk-BGBBVSH4.js";import{d as l,e as p,h as d}from"./chunk-OO6S4ECV.js";import{a as u,h as m,i as g}from"./chunk-NLVKD45E.js";import{z as f}from"./chunk-WFRZGMWJ.js";import{basename as L,extname as D}from"path";function K(n,e){let{scope:i,maxLoc:t=15,limit:r=30,scanLimit:a}=e??{},s=new x(n);return y({candidates:()=>A(n,s,i,t),orderCandidates:P,scanLimit:a,profile:{name:"passthrough-candidates"},prepare:o=>s.calleeMap(o,{semantic:e?.semantic!==!1}),evaluate:(o,c)=>w(n,o,c.get(o.symbolId)??[]),orderResults:(o,c)=>o.loc-c.loc||o.file.localeCompare(c.file),limit:r})}function w(n,e,i){let t=j(i);if(t.size!==1||!m(n,e.relativePath,e.startLine,e.endLine))return null;let[,r]=[...t.entries()][0],a=I(n,e,r),s=T(n,e),o=a.length>0||s.length>0?"signal":"direct";return{symbol:e.symbol,shortName:l(e.symbol),file:e.relativePath,startLine:e.startLine,endLine:e.endLine,loc:v(e),forwardsTo:r.symbol,forwardsToShort:l(r.symbol),forwardsToFile:r.file,actionTier:o,boundaryEvidence:a,publicFacadeEvidence:s,recommendation:E(o,a,s)}}function I(n,e,i){return S(n,e.relativePath,e.startLine,"passthrough","explicit ignore-passthrough comment",[{label:"passthrough name",value:l(e.symbol)},{label:"callee name",value:l(i.symbol)},{label:"passthrough module",value:L(e.relativePath,D(e.relativePath))},{label:"callee module",value:L(i.file,D(i.file))}])}function E(n,e,i){if(n==="signal"){if(i.length>0)return`Review the public API before inlining; public-facade evidence: ${i.slice(0,2).join("; ")}.`;let t=e.filter(F);return t.length>0?`Review the public API before inlining; public-surface evidence: ${t.slice(0,2).join("; ")}.`:`Review the boundary before inlining; boundary evidence: ${e.slice(0,2).join("; ")}.`}return"Inline or remove this passthrough unless an external API or runtime registration depends on the forwarding name."}function T(n,e){return C(n,e)?h(n,e.relativePath)?["exported passthrough is declared on the package public surface"]:b(n,e.symbol,e.relativePath)?["exported passthrough matches configured or framework public entry surface"]:[]:[]}function C(n,e){let i=f(n,e.relativePath);if(i.length===0)return!1;let t=p(e.symbol);if(!t)return!1;let r=i.slice(Math.max(0,e.startLine-2),e.startLine+1).join(`
|
|
2
|
+
`),a=u(t);return new RegExp(`^\\s*export\\s+(?:default\\s+)?(?:(?:async\\s+)?function\\s+${a}\\b|(?:const|let|var)\\s+${a}\\b)`,"m").test(r)?!0:R(i,t)}function R(n,e){if(!e)return!1;let i=new RegExp(`^\\s*export\\s*\\{[^}\\n]*\\b${u(e)}\\b`);return n.some(t=>i.test(t))}function F(n){return n.includes("public surface")}function j(n){let e=n.some(t=>d(t.symbol))?n.filter(t=>d(t.symbol)):n,i=new Map;for(let t of e)i.has(t.symbol)||i.set(t.symbol,t);return i}function A(n,e,i,t){return e.productionCallableDefinitions({scope:i,minLoc:3,maxLoc:t,requireFunctionLikeSymbol:!0,excludeRustTraitImplMembers:!0}).filter(r=>!g(n,r))}export{K as a,C as b};
|
|
3
|
+
//# sourceMappingURL=chunk-2EU6WVR3.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{E as s}from"./chunk-MCNWCJYL.js";var p=new Set(["componentDidCatch","componentDidMount","componentDidUpdate","componentWillUnmount","getDerivedStateFromError","getDerivedStateFromProps","getSnapshotBeforeUpdate","render","shouldComponentUpdate","UNSAFE_componentWillMount","UNSAFE_componentWillReceiveProps","UNSAFE_componentWillUpdate"]);function l(i,t){if(!t.parentTypeName||!/\.[cm]?[jt]sx?$/.test(t.relativePath))return!1;let r=s(i,t.relativePath);if(!r)return!1;let n=r.rootNode.descendantsOfType("method_definition").find(a=>a.startPosition.row<=t.startLine&&a.endPosition.row>=t.endLine);if(!n)return!1;if(/\boverride\b/.test(n.text.slice(0,Math.max(0,n.text.indexOf("{")))))return!0;let e=n.parent;for(;e&&e.type!=="class_declaration"&&e.type!=="class";)e=e.parent;if(!e)return!1;let o=e.text.slice(0,Math.max(0,e.text.indexOf("{")));return/\bimplements\b/.test(o)||/\bextends\b/.test(o)?!0:p.has(t.leaf)&&/\bextends\s+(?:React\.)?(?:Component|PureComponent)\b/.test(o)}export{l as a};
|
|
2
|
+
//# sourceMappingURL=chunk-2HFXPIBT.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import{a as g}from"./chunk-QB7NRST4.js";import{h as p}from"./chunk-DA34GNNO.js";import{a as f}from"./chunk-YSUD2S7T.js";import{d as u,e as _,i as N}from"./chunk-OO6S4ECV.js";import{p as d}from"./chunk-NLVKD45E.js";import{B as l,b as c}from"./chunk-MCNWCJYL.js";import{a as I}from"./chunk-64MNV6AB.js";import{y as b}from"./chunk-WFRZGMWJ.js";function Y(e,t,r={}){return T(e,t,r)?.map(s=>({symbol:s.symbol,shortName:s.shortName,fromFile:s.fromFile}))??[]}function Z(e,t){let r=f(e,t),s=O(e,t);if(s.length>0&&!x(r))return s;let o=k(e,t,r);return h(t)&&o.length>0?o:D([...s,...o])}function G(e,t,r={}){let s=g(e,t);if(!s)return[];let o=S(e,s),n=r.semantic===!1?null:E(e,s);return(n?R(n,o):o).filter(m=>!m.used).map(m=>({symbol:m.symbol,shortName:m.shortName,importedIn:m.importer}))}function R(e,t){let r=new Map;for(let o of t){let n=r.get(o.shortName);n?n.push(o):r.set(o.shortName,[o])}let s=e.map(o=>{let n=r.get(o.shortName),i=n?.shift();return n?.length===0&&r.delete(o.shortName),i?{...o,used:o.used||i.used}:o});return s.push(...[...r.values()].flat()),s}function O(e,t){return e.all(`SELECT DISTINCT gs.symbol, d.relative_path AS importer
|
|
2
|
+
FROM mentions m
|
|
3
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
4
|
+
JOIN documents d ON c.document_id = d.id
|
|
5
|
+
JOIN global_symbols gs ON m.symbol_id = gs.id
|
|
6
|
+
WHERE gs.symbol LIKE ?
|
|
7
|
+
AND m.role = 2
|
|
8
|
+
ORDER BY d.relative_path`,`%${t}%`).filter(s=>!e.isIgnored(s.importer)).map(s=>({symbol:s.symbol,shortName:u(s.symbol),fromFile:s.importer}))}function k(e,t,r=f(e,t)){let s=r?.relativePath??null,o=r?_(r.symbol):t.replace(/\(\)$/,""),n=r?N(r.symbol):!1,i=new Set;for(let a of I(e,{includeIgnored:!1}))for(let F of d(e,a))M(F,a,{targetFile:s,targetLeaf:o,targetIsModule:n,targetPattern:t})&&i.add(a);let m=h(t)?t.trim():null;return[...i].sort().map(a=>({symbol:m??r?.symbol??o,shortName:m??(r?u(r.symbol):o),fromFile:a}))}function x(e){return!!(e&&(e.symbol.startsWith("scip-clojure ")||l(e.relativePath)==="clojure"))}function D(e){let t=new Set,r=[];for(let s of e){let o=`${s.symbol}|${s.fromFile}`;t.has(o)||(t.add(o),r.push(s))}return r.sort((s,o)=>s.fromFile.localeCompare(o.fromFile)||s.shortName.localeCompare(o.shortName))}function M(e,t,r){return!e.sourcePath||r.targetFile&&c(e.sourcePath)!==c(r.targetFile)?!1:e.kind==="side-effect"||r.targetFile&&$(t)||e.kind==="namespace"&&P(e,r.targetPattern)||r.targetIsModule||e.kind==="named"&&e.importedName===r.targetLeaf?!0:e.kind==="namespace"&&e.usedMembers.includes(r.targetLeaf)}function P(e,t){let r=t.trim().replace(/\(\)$/,"");return h(r)?e.importedName===r||e.localName===r:!1}function h(e){let t=e.trim().replace(/\(\)$/,"");return t.includes(".")&&!t.includes("/")&&!t.includes(":")}function T(e,t,r={}){let s=g(e,t);return s?L(e,s,r)??(r.semantic===!1?null:E(e,s))??S(e,s):null}function L(e,t,r){let o=e.all(`SELECT DISTINCT
|
|
9
|
+
gs.symbol,
|
|
10
|
+
def_d.relative_path AS from_file,
|
|
11
|
+
imp_d.relative_path AS importer,
|
|
12
|
+
EXISTS (
|
|
13
|
+
SELECT 1
|
|
14
|
+
FROM mentions ref_m
|
|
15
|
+
JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
|
|
16
|
+
WHERE ref_m.symbol_id = gs.id
|
|
17
|
+
AND ref_m.role != 1
|
|
18
|
+
AND ref_c.document_id = imp_d.id
|
|
19
|
+
) AS used
|
|
20
|
+
FROM mentions m
|
|
21
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
22
|
+
JOIN documents imp_d ON c.document_id = imp_d.id
|
|
23
|
+
JOIN global_symbols gs ON m.symbol_id = gs.id
|
|
24
|
+
LEFT JOIN (
|
|
25
|
+
SELECT m2.symbol_id, c2.document_id
|
|
26
|
+
FROM mentions m2
|
|
27
|
+
JOIN chunks c2 ON m2.chunk_id = c2.id
|
|
28
|
+
WHERE m2.role = 1
|
|
29
|
+
GROUP BY m2.symbol_id
|
|
30
|
+
) sym_def ON sym_def.symbol_id = gs.id
|
|
31
|
+
LEFT JOIN documents def_d ON sym_def.document_id = def_d.id
|
|
32
|
+
WHERE imp_d.relative_path = ?
|
|
33
|
+
AND m.role = 2
|
|
34
|
+
ORDER BY def_d.relative_path, gs.symbol`,t).filter(n=>!e.isIgnored(n.importer));if(o.length>0){let n=r.semantic===!1?[]:p(e,t);return o.map(i=>({symbol:i.symbol,shortName:u(i.symbol),fromFile:i.from_file??"(external)",importer:i.importer,used:i.used!==0||n.some(m=>m.isUsed&&m.sourcePath===i.from_file)}))}return null}function E(e,t){let r=p(e,t);return r.length>0?r.map(s=>{let o=y(s.importedName,s.localName,s.kind);return{symbol:o,shortName:o,fromFile:s.sourcePath??"(external)",importer:t,used:s.kind==="side-effect"?!0:s.isUsed}}):null}function S(e,t){let r=A(t,b(e,t));return d(e,t).map(s=>{let o=y(s.importedName,s.localName,s.kind),n=s.kind==="side-effect"||v(t,s)||r.has(s.localName??s.importedName)?!0:s.used;return{symbol:o,shortName:o,fromFile:s.sourcePath??"(external)",importer:t,used:n}})}function A(e,t){let r=new Set;if(l(e)!=="python")return r;let s=/(?:^|\n)\s*__all__\s*(?:\+?=)\s*[[(]([\s\S]*?)[\])]/g;for(let o of t.matchAll(s)){let n=o[1]??"";for(let i of n.matchAll(/(['"])([A-Za-z_]\w*)\1/g))r.add(i[2])}return r}function v(e,t){if(l(e)!=="rust"||t.used||t.kind==="side-effect")return!1;let r=t.localName??t.importedName;return r==="_"||/^[A-Z]/.test(r)}function y(e,t,r){return r==="namespace"&&e==="*"&&t?`* as ${t}`:r==="default"&&t?`default as ${t}`:r==="side-effect"?"(side effect import)":t&&t!==e?`${e} as ${t}`:e}function $(e){return/\.(?:c|h|cc|cpp|cxx|hpp|hh|hxx)$/i.test(e)}export{Y as a,Z as b,G as c};
|
|
35
|
+
//# sourceMappingURL=chunk-2LGPMYS2.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{d as A,i as T}from"./chunk-DA34GNNO.js";import{d as I}from"./chunk-YSUD2S7T.js";import{e as d,s as w,z as P}from"./chunk-OO6S4ECV.js";import{a as v,b as F,f as h,p as y}from"./chunk-NLVKD45E.js";import{B as k,L as R,a as D,c as p}from"./chunk-MCNWCJYL.js";import{c as u,d as M,y as m}from"./chunk-WFRZGMWJ.js";function L(e,r,n,t={}){if(!n)return[];let i=m(e,r);return i?i.indexOf(n)===-1?[]:(x(e,r).get(n)??[]).filter(o=>!J(o,t)):[]}function J(e,r){return typeof r.excludeStartLine=="number"&&typeof r.excludeEndLine=="number"&&e>=r.excludeStartLine&&e<=r.excludeEndLine}var Y=u("file-identifiers",{clearGroups:["whole-project","source-file"]});function O(e,r){let n=h(e,r);return n?n.fileIdentifiers:Y.get(e,r,()=>new Set(x(e,r).keys()))}var W=u("file-ident-lines",{clearGroups:["whole-project","source-file"]});function x(e,r){let n=h(e,r);return n?n.identifierLineMap:W.get(e,r,()=>X(e,r))}var V=u("file-idents-by-line",{clearGroups:["whole-project","source-file"]});function pe(e,r){let n=h(e,r);return n?n.identifiersByLine:V.get(e,r,()=>{let t=x(e,r),i=0;for(let o of t.values()){let c=o[o.length-1];c!==void 0&&c>i&&(i=c)}let a=new Array(i+1);for(let o=0;o<=i;o+=1)a[o]=new Set;for(let[o,c]of t)for(let s of c)a[s].add(o);return a})}function X(e,r){let n=new Map,t=(c,s)=>{let l=n.get(c);if(!l){n.set(c,[s]);return}l[l.length-1]!==s&&l.push(s)},i=m(e,r);if(!i)return n;let a=F(i).split(/\r?\n/),o=/\b([A-Za-z_$][\w$]*)\b/g;for(let c=0;c<a.length;c+=1){let s=a[c]??"";for(let l of s.matchAll(o))l[1]&&t(l[1],c)}return n}function Le(e,r){let n=z(e);return n?r.filter(t=>z(t.file)===n):r}function _e(e,r,n,t){let i=n.find(a=>a.file===r);if(i)return i;if(t){let a=new Set(y(e,r).map(o=>o.sourcePath).filter(o=>!!o));for(let o of n)for(let c of a)if(p(c,o.file))return o;return null}return n.length===1?n[0]:null}function z(e){let r=k(e);return r?r==="typescript"||r==="tsx"||r==="javascript"?"javascript-family":r:null}var q=M("global-leaf-index",{clearGroups:["whole-project"]});function E(e){return q.get(e,()=>{let r=e.all(`SELECT gs.id, gs.symbol,
|
|
2
|
+
COALESCE(der_doc.relative_path, mention_doc.relative_path) AS relative_path
|
|
3
|
+
FROM global_symbols gs
|
|
4
|
+
LEFT JOIN defn_enclosing_ranges der ON der.symbol_id = gs.id
|
|
5
|
+
LEFT JOIN documents der_doc ON der_doc.id = der.document_id
|
|
6
|
+
LEFT JOIN (
|
|
7
|
+
SELECT m.symbol_id, MIN(d.relative_path) AS relative_path
|
|
8
|
+
FROM mentions m
|
|
9
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
10
|
+
JOIN documents d ON c.document_id = d.id
|
|
11
|
+
WHERE m.role = 1
|
|
12
|
+
GROUP BY m.symbol_id
|
|
13
|
+
) mention_doc ON mention_doc.symbol_id = gs.id
|
|
14
|
+
WHERE 1 = 1
|
|
15
|
+
${e.symbolNoiseFor("gs")}`),n=new Map;for(let t of r){if(!t.relative_path||e.isIgnored(t.relative_path))continue;let i=d(t.symbol);if(!i)continue;let a=n.get(i);a||(a=[],n.set(i,a)),a.some(o=>o.symbolId===t.id)||a.push({symbol:t.symbol,symbolId:t.id,file:t.relative_path})}return n})}var K=u("source-import-paths-by-local-name",{clearGroups:["whole-project","source-file"]});function $(e,r){let n=D(r);return K.get(e,n,()=>Q(e,n))}function Q(e,r){let n=new Map;for(let t of y(e,r)){if(!t.sourcePath)continue;let i=t.localName??t.importedName;if(i&&j(n,i,t.sourcePath),t.kind==="namespace")for(let a of t.usedMembers)j(n,a,t.sourcePath)}return n}function j(e,r,n){let t=e.get(r);t||(t=new Set,e.set(r,t)),t.add(n)}var B=/[A-Za-z_$][A-Za-z0-9_$]*/g,G=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ee=512;function C(e){let r=[],n=!1;for(let t of e)t&&(n=!0,G.test(t)||r.push(t));return{candidateNames:e,hasUsableCandidate:n,nonIdentifierNames:r}}function H(e,r){let n=te(r)?r:C(r);if(n.candidateNames.size===0||!n.hasUsableCandidate)return!0;if(n.candidateNames.size<=ee){for(let i of n.candidateNames)if(i){if(G.test(i)){if(ne(i).test(e))return!0;continue}if(e.includes(i))return!0}return!1}B.lastIndex=0;let t;for(;(t=B.exec(e))!==null;)if(n.candidateNames.has(t[0]))return!0;for(let i of n.nonIdentifierNames)if(e.includes(i))return!0;return!1}function te(e){return"candidateNames"in e}function ne(e){return new RegExp(`(?<![A-Za-z_$0-9])${v(e)}(?![A-Za-z_$0-9])`)}function N(e,r,n){let t=E(e).get(n);if(!t||t.length===0)return[];if(t.length===1)return[g(t[0])];let i=t.filter(s=>s.file===r);if(i.length>0)return i.map(g);let a=$(e,r),o=a.get(n);if(o)for(let s of o){let l=t.filter(f=>p(s,f.file));if(l.length>0)return l.map(g)}let c=new Set;for(let s of a.values())for(let l of s)c.add(l);for(let s of c){let l=t.filter(f=>p(s,f.file));if(l.length>0&&l.length===t.length)return l.map(g)}return[]}function Be(e,r,n){let t=N(e,r,n);if(t.length>0)return t;let i=E(e).get(n);return!i||i.length===0?[]:i.map(g)}function U(e,r,n={}){let t=I(e,r);if(!t)return[];let i=d(t.symbol);if(!i)return[];if(n.semantic!==!1){let o=T(e,{...t,leaf:i,parentTypeName:null,isFunctionLike:!1,isTypeLike:!1,kind:null,documentation:null,enclosingSymbol:null});if(o.length>0){let c=new Map;for(let s of o){let l=c.get(s.file)??[];l.push(s.line),c.set(s.file,l)}return _(e,c)}}let a=new Map;for(let o of R(e)){let c=m(e,o);if(!c||c.indexOf(i)===-1||o!==t.relativePath&&!N(e,o,i).some(f=>f.symbolId===t.symbolId))continue;let s=L(e,o,i,o===t.relativePath?{excludeStartLine:t.startLine,excludeEndLine:t.endLine}:{});s.length>0&&a.set(o,s)}return _(e,a)}function Ge(e,r,n={}){let t=new Map;for(let s of r){if(!s.leaf)continue;let l=t.get(s.leaf)??[];l.push(s),t.set(s.leaf,l)}if(t.size===0)return new Map;let i=new Set(r.map(s=>s.symbolId)),a=new Set(t.keys()),o=C(a),c=new Map;for(let s of R(e)){if(n.skipPath?.(s)||!H(m(e,s),o))continue;let l=O(e,s);if(l.size!==0){for(let f of l)if(t.has(f))for(let b of N(e,s,f)){if(!i.has(b.symbolId)||s===b.relativePath)continue;let S=c.get(b.symbolId);S||(S=new Set,c.set(b.symbolId,S)),S.add(s)}}}return c}function g(e){return{symbolId:e.symbolId,symbol:e.symbol,relativePath:e.file}}function _(e,r){let n=[],t=new Set;for(let[i,a]of r){let o=w(e,i);for(let c of a){let s=P(o,c),l=`${i}|${c}|${s?.symbol??""}`;t.has(l)||(t.add(l),n.push({file:i,line:c,enclosingSymbol:s?.symbol??null}))}}return n}function re(e,r){let n=le(e,r);return n?_(e,oe(e,n.match,n.identifier)):[]}function Ve(e,r,n={}){return ie(e,r,n).map(t=>({file:t.file,line:t.line,enclosingSymbol:t.enclosingSymbol}))}function ie(e,r,n={}){let t=U(e,r,{semantic:n.semantic}),i=t.length>0?Z(t,"source-attribution"):Z(re(e,r),"scip-reference-chunk");return n.includeIgnored===!0?i:i.filter(a=>!e.isIgnored(a.file))}function Z(e,r){return e.map(n=>({...n,provenance:r}))}function oe(e,r,n){let t=new Map;for(let[i,a]of se(e,r.symbolId))t.set(i,ae(e,i,a,r,n));return t}function se(e,r){let n=new Map;for(let t of A(e,[r])){if(e.isIgnored(t.relative_path))continue;let i=n.get(t.relative_path);i||(i=[],n.set(t.relative_path,i)),i.push({start_line:t.chunk_start,end_line:t.chunk_end})}return n}function ae(e,r,n,t,i){let a=r===t.relativePath?{excludeStartLine:t.startLine,excludeEndLine:t.endLine}:{},o=i?L(e,r,i,a):[];return n.flatMap(c=>ce(o,c))}function ce(e,r){let n=e.filter(t=>t>=r.start_line&&t<=r.end_line);return n.length>0?n:[r.start_line]}function le(e,r){let n=I(e,r);return n?{match:n,identifier:d(n.symbol)||null}:null}export{x as a,pe as b,Le as c,_e as d,E as e,C as f,H as g,$ as h,N as i,Be as j,Ge as k,re as l,Ve as m};
|
|
16
|
+
//# sourceMappingURL=chunk-2Y7YX54K.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as u}from"./chunk-3I34FZ6R.js";import{a as h}from"./chunk-UO4IADXJ.js";import{m as S}from"./chunk-2Y7YX54K.js";import{a as d,c as b}from"./chunk-YSUD2S7T.js";import{d as m,z as y}from"./chunk-OO6S4ECV.js";function v(e,o,l={}){let{direction:c="backward",maxDepth:s=3}=l,r=d(e,o);return r?c==="backward"?w(e,r,s,{semantic:l.semantic!==!1}):M(e,r,{semantic:l.semantic!==!1}):null}function w(e,o,l,c){let s=[],r=new Set([o.symbol]),t=[o];for(let n=1;n<=l&&t.length!==0;n++){let i=[];for(let p of t){let g=h(e,p,{semantic:c.semantic});for(let a of g){if(r.has(a.symbol))continue;r.add(a.symbol),s.push({symbol:a.symbol,shortName:m(a.symbol),file:a.file,relationship:n===1?"referenced within definition (callee)":`depth ${n} callee`});let f=b(e,a.symbol);f&&!e.isIgnored(f.relativePath)&&i.push(f)}}t=i}return{symbol:o.symbol,shortName:m(o.symbol),direction:"backward",connectedSymbols:s}}function M(e,o,l){let c=new Set,s=[],r=new u(e);for(let t of S(e,o,{semantic:l.semantic})){if(s.length>=30)break;let n=t.enclosingSymbol??y(r.definitionsForFile(t.file),t.line)?.symbol??null;if(!n||n===o.symbol)continue;let i=b(e,n);!i||e.isIgnored(i.relativePath)||c.has(i.symbol)||(c.add(i.symbol),s.push({symbol:i.symbol,shortName:m(i.symbol),file:i.relativePath,relationship:`references target at ${t.file}:${t.line+1}`}))}return s.sort((t,n)=>t.file.localeCompare(n.file)),{symbol:o.symbol,shortName:m(o.symbol),direction:"forward",connectedSymbols:s}}export{v as a};
|
|
2
|
+
//# sourceMappingURL=chunk-363TZ64I.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{b as I,f as W,g as Y}from"./chunk-NLRWGGPY.js";import{a as x}from"./chunk-BGBBVSH4.js";import{b as U,d as X,e as Z,f as $}from"./chunk-UO4IADXJ.js";import{a as _,f as z,g as J,i as N,j as Q}from"./chunk-2Y7YX54K.js";import{a as B}from"./chunk-G4KQ7S74.js";import{a as j,g as k,h as T,j as V,k as G,s as D,u as H,v as O,w as P}from"./chunk-OO6S4ECV.js";import{m as F}from"./chunk-NLVKD45E.js";import{B as R,C as E,L as K}from"./chunk-MCNWCJYL.js";import{a as q}from"./chunk-64MNV6AB.js";import{B as h,s as w,y as A}from"./chunk-WFRZGMWJ.js";function ee(n,e,t){let r=e.identifierResolution==="strict"?N:Q,l=e.candidateNames?z(e.candidateNames):null,o=0,f=0,m=0,p=0,y="";for(let a of e.paths)if(o+=1,y=a,!(!R(a)&&!(e.includeVueSfc&&E(a)))&&!n.isIgnored(a)&&!e.skipPath?.(a))try{if(l&&!J(A(n,a),l))continue;f+=1;let S=(s,u,v,b)=>{if(e.candidateNames&&!e.candidateNames.has(s))return;m+=1;let g=e.resolveTargets?e.resolveTargets({sourceFile:a,name:s,kind:u,defaultTargets:b}):b();for(let L of g)p+=1,t({sourceFile:a,name:s,target:L,occurrences:v,kind:u})},M=_(n,a);for(let[s,u]of M)S(s,"identifier",u.length,()=>r(n,a,s));for(let s of F(n,a,{includeCrossLanguageDispatchNames:e.includeCrossLanguageDispatchNames,includeRustAttributeNames:e.includeRustAttributeNames})){let u=s.kind==="cross-language-dispatch"?()=>N(n,a,s.name):()=>r(n,a,s.name);S(s.name,s.kind,s.occurrences,u)}}finally{e.afterPath?.(a),o%10===0&&w("source-reference-scan.progress",()=>{},()=>({scannedPaths:o,currentPath:y,candidateMatchedPaths:f,visitedNames:m,visitedHits:p}))}}function ne(n,e={}){let{scope:t,files:r,minLoc:l=1,maxLoc:o=Number.POSITIVE_INFINITY,excludeSymbol:f,excludeEntrySurfaces:m=!1,excludeTypesFiles:p=!1,excludeRootedSymbols:y=!1,requireFunctionLikeSymbol:a=!1,requireCallableSymbol:C=!1,excludeRustTraitImplMembers:S=!1,includeSuppressed:M=!1,sortByLocDesc:s=!1}=e,u=[],v=re(n,{scope:t,files:r,requireFunctionLikeSymbol:a,requireCallableSymbol:C}),b=new Map,g=new Map,L=i=>{let c=b.get(i);if(c!==void 0)return c;let d=W(n,i);return b.set(i,d),d},ie=i=>{let c=g.get(i);if(c!==void 0)return c;let d=I(i);return g.set(i,d),d};for(let i of v){let c=i.relativePath;if(n.isIgnored(c)||m&&L(c)||!oe(i,{requireFunctionLikeSymbol:a,requireCallableSymbol:C})||f!==void 0&&i.symbol===f)continue;let d=x(i);d<l||d>o||p&&ae(c)||y&&Y(n,i.symbol,c)||S&&V(i.symbol)||ie(c)!=="test"&&(G(i.symbol)||!M&&h(n,c,i.startLine)||u.push(i))}return s?u.sort((i,c)=>x(c)-x(i)):u}function re(n,e){return e.files!==void 0?[...new Set(e.files.map(r=>r.replace(/\\/g,"/")))].sort().filter(r=>!e.scope||r.includes(e.scope)).flatMap(r=>D(n,r)):e.requireCallableSymbol?P(n,{scope:e.scope,symbolMatches:k,sqlPrefilter:"callable"}):e.requireFunctionLikeSymbol?P(n,{scope:e.scope,symbolMatches:T,sqlPrefilter:"function-like"}):O(n,e.scope)}function oe(n,e){return e.requireCallableSymbol?k(n.symbol):e.requireFunctionLikeSymbol?T(n.symbol):n.isFunctionLike}function ae(n){return(n.split("/").pop()??"").includes("types")}var te=class{constructor(e){this.db=e}db;scopedDefinitions(e){return H(this.db,e)}definitionsForFile(e){return D(this.db,e)}productionCallableDefinitions(e={}){return ne(this.db,e)}calleeMap(e,t={}){return U(this.db,e,t)}crossFileCallerMap(e,t={}){return X(this.db,e,t)}sourceFallbackCallerFiles(e,t={}){return Z(this.db,e,t)}callerFileMap(e,t={}){return $(this.db,e,t)}frameworkReferencedSymbolIds(e){let t=new Map;for(let l of e){if(!l.leaf)continue;let o=t.get(l.leaf)??[];o.push(l.symbolId),t.set(l.leaf,o)}let r=new Set;for(let l of q(this.db,{includeIgnored:!1}))if(R(l)==="rust")for(let{name:o}of F(this.db,l,{includeRustAttributeNames:!0}))for(let f of t.get(o)??[])r.add(f);return r}symbolsWithNonSelfCallees(e,t={}){if(e.length===0)return new Set;let r=new Map(e.map(o=>[o.symbolId,o.symbol])),l=this.calleeMap(e,t);return new Set([...l.entries()].filter(([o,f])=>{let m=r.get(o);return f.some(p=>p.symbol!==m)}).map(([o])=>o))}fileDependencyGraph(e){return B(this.db,e)}fileKind(e){return I(e)}hasSuppressionComment(e){return h(this.db,e.relativePath,e.startLine)}sourceFiles(){return K(this.db)}scanSourceReferences(e,t){ee(this.db,e,t)}callableSignature(e){let t=j(this.db).forFile(e.relativePath,{facts:!0}).facts?.callables.find(r=>r.startLine===e.startLine&&r.endLine===e.endLine);return t?{paramCount:t.paramCount}:null}};export{te as a};
|
|
2
|
+
//# sourceMappingURL=chunk-3I34FZ6R.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as R,b as H}from"./chunk-ZEKBAMCN.js";import{a as B,b,c as y,e as h,f as k}from"./chunk-B3X6KU75.js";import{a as p,b as g}from"./chunk-KMVGRIO2.js";import{N as v}from"./chunk-MCNWCJYL.js";function V(e,s={}){let{minSimilarity:m=.45,minSharedBehaviors:i=6,limit:o=20,scope:c,scanLimit:n,filePattern:d,focusFiles:f}=s,l=v(e).reactProfiles({scope:c,minBehaviorTokens:Math.max(3,i),scanLimit:n}).map(r=>({file:r.file,component:r.name,tokens:r.behaviorTokens,profile:r})),t=R(l,r=>r.tokens);return H({profiles:l,limit:o,filePattern:d,focusFiles:f,candidateIndex:t,profile:{name:"react-hook-candidates"},compare:(r,a)=>C(r,a,m,i),sort:(r,a)=>a.similarity-r.similarity||r.fileA.localeCompare(a.fileA)||r.componentA.localeCompare(a.componentA)||r.fileB.localeCompare(a.fileB)||r.componentB.localeCompare(a.componentB)})}function C(e,s,m,i){let o=p(e.tokens,s.tokens);if(o.size<i||!E(o))return null;let c=b(e.tokens,s.tokens);if(c<m)return null;let n=h(o,"hook:"),d=h(o,"react-hook:"),f=h(o,"effect:"),l=h(o,"state:"),t=h(o,"request:"),r=h(o,"handler:"),a=h(o,"handler-verb:"),u=A({sharedHooks:n,sharedReactHooks:d,sharedEffects:f,sharedState:l,sharedRequests:t,sharedHandlers:r,sharedHandlerVerbs:a});return{fileA:e.file,componentA:e.component,fileB:s.file,componentB:s.component,similarity:c,tokenCountA:e.tokens.size,tokenCountB:s.tokens.size,sharedTokens:k(o),sharedHooks:n,sharedReactHooks:d,sharedEffects:f,sharedState:l,sharedRequests:t,sharedHandlers:r,sharedHandlerVerbs:a,evidenceClass:u.evidenceClass,actionTier:u.actionTier,evidenceClassReasons:u.reasons,recommendation:u.recommendation,uniqueToA:k(g(e.tokens,s.tokens)).slice(0,25),uniqueToB:k(g(s.tokens,e.tokens)).slice(0,25),reason:P({sharedHooks:n,sharedReactHooks:d,sharedEffects:f,sharedState:l,sharedRequests:t,sharedHandlers:r,sharedHandlerVerbs:a}),locA:e.profile.loc,locB:s.profile.loc}}function A(e){return B({genericWords:q,stripPrefixes:w,primitiveGroups:[{values:e.sharedReactHooks,reasonPrefix:"shared React primitives",bucket:"generic"},{values:e.sharedEffects,reasonPrefix:"shared lifecycle primitive",bucket:"generic"}],nameGroups:[{names:e.sharedHooks,label:"shared hook",fallbackBucket:"shared-abstraction"},{names:e.sharedRequests,label:"shared request",fallbackBucket:"generic"},{names:e.sharedState,label:"shared state",fallbackBucket:"generic"},{names:e.sharedHandlers,label:"shared handler",fallbackBucket:"generic"},{names:e.sharedHandlerVerbs,label:"shared action verb",fallbackBucket:"generic"}],recommendation:S})}function S(e){switch(e){case"domain-behavior":return"Review for a shared hook, controller, or feature module around the named domain behavior.";case"mixed":return"Separate generic React mechanics from domain-specific behavior before extracting a shared hook.";case"shared-abstraction":return"Review the existing shared hook usage first; extract only if duplicated behavior remains outside it.";case"generic-workflow-scaffolding":return"Treat as support evidence for a repeated workflow shape, not direct hook-extraction evidence."}}function E(e){let s=0,m=0,i=0,o=0,c=0,n=0,d=0;for(let t of e)t.startsWith("hook:")?s+=1:t.startsWith("react-hook:")?m+=1:t.startsWith("effect:")?i+=1:t.startsWith("request:")?o+=1:t.startsWith("handler:")||t.startsWith("handler-verb:")?c+=1:t.startsWith("state:")?n+=1:t.startsWith("state-hook:")&&(d+=1);let f=n+d,l=s+m+i+o+c+f;return y([{name:"requests",count:o},{name:"customHooks",count:s},{name:"namedStates",count:n},{name:"handlers",count:c},{name:"effects",count:i},{name:"reactHooks",count:m},{name:"namedBehavior",count:l}],[{min:{requests:1,namedBehavior:4},reason:"shared request workflow"},{min:{customHooks:1,requests:1,namedBehavior:5},reason:"shared custom hook and request workflow"},{min:{customHooks:1,namedStates:1,namedBehavior:5},reason:"shared custom hook and state"},{min:{customHooks:1,handlers:2,namedBehavior:5},reason:"shared custom hook and handlers"},{min:{namedStates:1,handlers:2,effects:1,namedBehavior:5},reason:"shared stateful effects"},{min:{namedStates:1,handlers:2,reactHooks:2,namedBehavior:5},reason:"shared stateful React primitives"}]).pass}function P(e){let s=[];return e.sharedHooks.length&&s.push(`shared hooks: ${e.sharedHooks.join(", ")}`),e.sharedReactHooks.length&&s.push(`shared React hooks: ${e.sharedReactHooks.join(", ")}`),e.sharedEffects.length&&s.push(`shared effects: ${e.sharedEffects.join(", ")}`),e.sharedState.length&&s.push(`shared state: ${e.sharedState.join(", ")}`),e.sharedRequests.length&&s.push(`shared requests: ${e.sharedRequests.join(", ")}`),e.sharedHandlers.length&&s.push(`shared handlers: ${e.sharedHandlers.slice(0,6).join(", ")}`),e.sharedHandlerVerbs.length&&s.push(`shared action verbs: ${e.sharedHandlerVerbs.slice(0,6).join(", ")}`),s.join("; ")||"shared React behavior profile"}var q=new Set(["add","apply","async","callback","cancel","change","clear","close","create","data","delete","draft","edit","effect","error","fetch","filter","form","handle","has","is","item","items","load","loader","loading","memo","name","open","reducer","refresh","ref","remove","request","reset","resource","row","rows","save","saving","search","select","selected","state","store","submit","toggle","update","use","value"]),w=[/^use(?=[A-Z])/,/^handle(?=[A-Z])/,/^is(?=[A-Z])/,/^has(?=[A-Z])/];export{V as a};
|
|
2
|
+
//# sourceMappingURL=chunk-3LAKH6BV.js.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
function m(e){try{return process.kill(e,0),!0}catch(n){return typeof n=="object"&&n!==null&&"code"in n&&n.code==="EPERM"}}import{mkdirSync as t,renameSync as c,writeFileSync as s}from"fs";import{dirname as l}from"path";function d(e,n,r={}){t(l(e),{recursive:!0});let o=`${e}.${process.pid}.${Date.now()}.tmp`,i=JSON.stringify(n,null,r.spacing);s(o,r.trailingNewline?`${i}
|
|
2
|
+
`:i),c(o,e)}export{m as a,d as b};
|
|
3
|
+
//# sourceMappingURL=chunk-3M2UCPFS.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as C,b}from"./chunk-ZEKBAMCN.js";import{a as P,c as y,e as r,f}from"./chunk-B3X6KU75.js";import{a as g,b as h,c as k}from"./chunk-KMVGRIO2.js";import{N as v}from"./chunk-MCNWCJYL.js";function L(e,i={}){let{minSimilarity:o=.62,minTokens:n=8,limit:c=20,scope:l,scanLimit:u,filePattern:m,focusFiles:d}=i,s=B(e,{scope:l,minTokens:n,scanLimit:u}),p=C(s,t=>t.tokens);return b({profiles:s,limit:c,filePattern:m,focusFiles:d,candidateIndex:p,profile:{name:"vue-component-duplicates"},compare:(t,a)=>V(t,a,o),sort:(t,a)=>a.similarity-t.similarity||t.fileA.localeCompare(a.fileA)||t.fileB.localeCompare(a.fileB)})}function B(e,i){return v(e).vueProfiles({scope:i.scope,minTemplateTokens:i.minTokens,scanLimit:i.scanLimit}).map(o=>({file:o.file,tokens:o.templateTokens,loc:T(o)}))}function T(e){return e.totalLines}function V(e,i,o){let n=g(e.tokens,i.tokens);if(n.size<6||!R(n))return null;let c=k(e.tokens,i.tokens);if(c<o)return null;let l=r(n,"component:"),u=r(n,"prop:"),m=r(n,"event:"),d=r(n,"directive:"),s=r(n,"slot:"),p=r(n,"id:"),t=S({sharedComponents:l,sharedProps:u,sharedEvents:m,sharedDirectives:d,sharedSlots:s,sharedIdentifiers:p});return{fileA:e.file,fileB:i.file,similarity:c,tokenCountA:e.tokens.size,tokenCountB:i.tokens.size,sharedTokens:f(n),sharedComponents:l,sharedProps:u,sharedEvents:m,sharedDirectives:d,sharedSlots:s,sharedIdentifiers:p,evidenceClass:t.evidenceClass,actionTier:t.actionTier,evidenceClassReasons:t.reasons,recommendation:t.recommendation,uniqueToA:f(h(e.tokens,i.tokens)).slice(0,25),uniqueToB:f(h(i.tokens,e.tokens)).slice(0,25),locA:e.loc,locB:i.loc}}function R(e){let i=0,o=0;for(let n of e)n.startsWith("component:")&&(i+=1),(n.startsWith("prop:")||n.startsWith("event:")||n.startsWith("directive:")||n.startsWith("slot:"))&&(o+=1);return y([{name:"component",count:i},{name:"behavior",count:o}],[{min:{component:1},reason:"shared custom component"},{min:{behavior:3},reason:"shared Vue template structure"}]).pass}function S(e){return P({genericWords:x,primitiveGroups:[{values:e.sharedProps,reasonPrefix:"shared props",bucket:"generic"},{values:e.sharedEvents,reasonPrefix:"shared events",bucket:"generic"},{values:e.sharedDirectives,reasonPrefix:"shared directives",bucket:"generic"},{values:e.sharedSlots,reasonPrefix:"shared slots",bucket:"generic"}],nameGroups:[{names:e.sharedComponents,label:"shared component",fallbackBucket:"generic"},{names:e.sharedIdentifiers,label:"shared identifier",fallbackBucket:"generic"}],recommendation:w})}function w(e){switch(e){case"domain-behavior":case"mixed":return"Review for a shared component or feature-specific Vue primitive around the named domain structure.";case"shared-abstraction":return"Review the existing shared component usage first; extract only if duplicated structure remains outside it.";case"generic-workflow-scaffolding":return"Generic structural overlap \u2014 verify intent before consolidating."}}var x=new Set(["actions","app","button","card","content","container","dialog","field","form","header","input","item","label","layout","list","modal","page","panel","row","section","shell","table","text","toolbar","ui","value","view","wrapper"]);export{L as a};
|
|
2
|
+
//# sourceMappingURL=chunk-3OPIMH42.js.map
|