scip-query 0.8.1 → 0.9.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.
Files changed (82) hide show
  1. package/README.md +22 -9
  2. package/dist/{chunk-2EC4JTHC.js → chunk-2DVVHNC3.js} +2 -2
  3. package/dist/{chunk-HVGNOUYP.js → chunk-2Y2WIJI4.js} +2 -2
  4. package/dist/{chunk-GMEBYEMU.js → chunk-3YQO3S5D.js} +2 -2
  5. package/dist/chunk-44G4P3GJ.js +2 -0
  6. package/dist/{chunk-ZIIQ55VK.js → chunk-6HP3BKIP.js} +2 -2
  7. package/dist/chunk-B32FX5KB.js +2 -0
  8. package/dist/{chunk-MKE7SEEX.js → chunk-FYT2PE7C.js} +2 -2
  9. package/dist/{chunk-66ORT3LS.js → chunk-HDA2V5DC.js} +2 -2
  10. package/dist/{chunk-4A4JFNWG.js → chunk-I66MQD5U.js} +2 -2
  11. package/dist/chunk-IBM6FXOQ.js +3 -0
  12. package/dist/{chunk-4B7YLRXX.js → chunk-ITUU3VE3.js} +2 -2
  13. package/dist/{chunk-QYQXPPDI.js → chunk-K3V6XUTL.js} +2 -2
  14. package/dist/{chunk-XSZ5NC4O.js → chunk-L6TOEQ2M.js} +2 -2
  15. package/dist/{chunk-JAMU6FLN.js → chunk-LBAMALDV.js} +2 -2
  16. package/dist/chunk-LR7E2ATW.js +8 -0
  17. package/dist/chunk-NM3BZXHA.js +2 -0
  18. package/dist/{chunk-NOVKLH2F.js → chunk-NO2TPMCQ.js} +1 -1
  19. package/dist/{chunk-SSINY7HL.js → chunk-OMNT7E2T.js} +2 -2
  20. package/dist/chunk-R3G6ERW7.js +7 -0
  21. package/dist/{chunk-7UZWNW4E.js → chunk-SEZZ24IG.js} +2 -2
  22. package/dist/{chunk-DJTJ3DLZ.js → chunk-SLX5XBCD.js} +2 -2
  23. package/dist/{chunk-K4Z3FCUJ.js → chunk-SQ6VENQY.js} +3 -3
  24. package/dist/chunk-T4AK46CM.js +16 -0
  25. package/dist/{chunk-FIPE5AQT.js → chunk-TA4DDU7J.js} +2 -2
  26. package/dist/{chunk-UQE3DSXY.js → chunk-TCCUWKH4.js} +2 -2
  27. package/dist/{chunk-HVXIXDLV.js → chunk-U254PV4S.js} +2 -2
  28. package/dist/chunk-UIWAZ2NT.js +2 -0
  29. package/dist/{chunk-K6YIGVL7.js → chunk-VHENVDS2.js} +2 -2
  30. package/dist/{chunk-SB6I6O3P.js → chunk-VQGQHIAT.js} +2 -2
  31. package/dist/{chunk-FTBT4RP2.js → chunk-VTF5EH22.js} +2 -2
  32. package/dist/{chunk-SLOIQKY7.js → chunk-Y3RUPPIU.js} +2 -2
  33. package/dist/{chunk-OIMM7KMI.js → chunk-YO6DU7QZ.js} +2 -2
  34. package/dist/{chunk-EM2PPDN7.js → chunk-YSSTUCNS.js} +2 -2
  35. package/dist/cli.js +167 -149
  36. package/dist/index.js +1 -1
  37. package/dist/postinstall.js +2 -2
  38. package/dist/queries/bottlenecks.js +1 -1
  39. package/dist/queries/change-surface.js +1 -1
  40. package/dist/queries/cleanup-plan.js +1 -1
  41. package/dist/queries/co-change.js +1 -1
  42. package/dist/queries/complexity-hotspots.js +1 -1
  43. package/dist/queries/complexity.js +1 -1
  44. package/dist/queries/dead.js +1 -1
  45. package/dist/queries/diff-gate.d.ts +4 -1
  46. package/dist/queries/diff-gate.js +1 -1
  47. package/dist/queries/diff-impact.d.ts +3 -1
  48. package/dist/queries/diff-impact.js +1 -1
  49. package/dist/queries/doc-drift.js +1 -1
  50. package/dist/queries/drift.js +1 -1
  51. package/dist/queries/extract-candidates.js +1 -1
  52. package/dist/queries/health.js +1 -1
  53. package/dist/queries/incomplete-migration.d.ts +71 -0
  54. package/dist/queries/incomplete-migration.js +2 -0
  55. package/dist/queries/index.d.ts +1 -0
  56. package/dist/queries/index.js +1 -1
  57. package/dist/queries/isolated.js +1 -1
  58. package/dist/queries/members.js +1 -1
  59. package/dist/queries/methods.js +1 -1
  60. package/dist/queries/passthrough-candidates.js +1 -1
  61. package/dist/queries/plan-context.js +1 -1
  62. package/dist/queries/recent-duplicates.js +1 -1
  63. package/dist/queries/redundant-reexports.js +1 -1
  64. package/dist/queries/self-audit.js +1 -1
  65. package/dist/queries/similar-files.js +1 -1
  66. package/dist/queries/similar.d.ts +15 -1
  67. package/dist/queries/similar.js +1 -1
  68. package/dist/queries/slice.js +1 -1
  69. package/dist/queries/stale-abstractions.js +1 -1
  70. package/dist/queries/surface.js +1 -1
  71. package/dist/queries/unused-params.js +1 -1
  72. package/dist/queries/wrapper-candidates.js +1 -1
  73. package/dist/runtime.js +1 -1
  74. package/package.json +5 -1
  75. package/skills/scip-ai-cleanup/SKILL.md +1 -1
  76. package/skills/scip-query/SKILL.md +79 -0
  77. package/dist/chunk-6P5W4U6G.js +0 -16
  78. package/dist/chunk-GTZAU7OL.js +0 -2
  79. package/dist/chunk-N5D5ZCBW.js +0 -7
  80. package/dist/chunk-OQSV6OS2.js +0 -2
  81. package/dist/chunk-RKTDEIHF.js +0 -2
  82. package/dist/chunk-XBFLIGWU.js +0 -3
@@ -1,16 +0,0 @@
1
- import{a as h}from"./chunk-NOVKLH2F.js";import{d as p}from"./chunk-64UY7VTR.js";import{c as u,f,h as g}from"./chunk-SOGLYIJ4.js";import{execFileSync as d}from"child_process";function A(e,n={}){let t=b(e,n);return t.note?C(t.note,t.changedFileLines):t.changedFiles.length===0?D(t.changedFileLines):I(t.changedFiles,[S(e,t.changedFiles,t.changedFiles)])}function b(e,n={}){let{base:t="HEAD"}=n;try{let s=F(e.config.projectRoot,t);return{changedFileLines:s,changedFiles:_(e,s),note:s.length===0?"No changed files found.":void 0}}catch{return{changedFileLines:[],changedFiles:[],note:"Unable to compute git diff."}}}function S(e,n,t){let s=new h(e),r=new Set(t),a=[],l=new Map,o=n.flatMap(i=>s.definitionsForFile(i)).filter(E).sort((i,m)=>i.relativePath.localeCompare(m.relativePath)||i.startLine-m.startLine),c=p(e,o);for(let i of o)x(e,i,t,r,a,l,c.get(i.symbolId)??new Set);return{changedSymbols:a,consumerEntries:[...l.entries()].map(([i,m])=>({file:i,symbols:[...m].sort()}))}}function I(e,n){let t=new Map,s=n.flatMap(a=>a.changedSymbols);for(let a of n)for(let l of a.consumerEntries){let o=t.get(l.file);o||(o=new Set,t.set(l.file,o));for(let c of l.symbols)o.add(c)}let r=N(t);return{changedFiles:[...e],changedSymbols:s,affectedConsumers:r,summary:{totalChangedFiles:e.length,totalChangedSymbols:s.length,totalAffectedFiles:r.length}}}function C(e,n=[]){return{changedFiles:n,changedSymbols:[],affectedConsumers:[],summary:{totalChangedFiles:n.length,totalChangedSymbols:0,totalAffectedFiles:0,note:e}}}function D(e){return{changedFiles:e,changedSymbols:[],affectedConsumers:[],summary:{totalChangedFiles:e.length,totalChangedSymbols:0,totalAffectedFiles:0,note:"Changed files are not present in the current SCIP index."}}}function F(e,n){let t=d("git",["diff","--name-only",n],{encoding:"utf-8",cwd:e,timeout:1e4}),s=d("git",["diff","--name-only","--cached",n],{encoding:"utf-8",cwd:e,timeout:1e4}),r=d("git",["ls-files","--others","--exclude-standard"],{encoding:"utf-8",cwd:e,timeout:1e4});return[...new Set([t,s,r].flatMap(a=>a.split(`
2
- `)).map(a=>a.trim()).filter(a=>a.length>0))]}function _(e,n){let t=[];for(let s of n){let r=e.get(`SELECT relative_path FROM documents
3
- WHERE relative_path LIKE ?
4
- LIMIT 1`,`%${s}`);r&&!e.isIgnored(r.relative_path)&&t.push(r.relative_path)}return t}function x(e,n,t,s,r,a,l){let o=Math.max(R(e,n.symbolId),l.size);if(!v(n,o))return;let c=u(n.symbol);r.push({symbol:n.symbol,shortName:c,file:n.relativePath,fanIn:o});for(let i of M(e,n.symbolId,t))y(e,s,a,i,c);for(let i of l)y(e,s,a,i,c)}function R(e,n){return e.get(`SELECT COUNT(DISTINCT c.document_id) AS fan_in
5
- FROM mentions m
6
- JOIN chunks c ON m.chunk_id = c.id
7
- WHERE m.symbol_id = ?
8
- AND m.role != 1`,n)?.fan_in??0}function M(e,n,t){return t.length===0?[]:e.all(`SELECT DISTINCT ref_d.relative_path
9
- FROM mentions m
10
- JOIN chunks c ON m.chunk_id = c.id
11
- JOIN documents ref_d ON c.document_id = ref_d.id
12
- WHERE m.symbol_id = ?
13
- AND m.role != 1
14
- AND ref_d.relative_path NOT IN (${t.map(()=>"?").join(",")})
15
- ${e.pathExclusionsFor("ref_d")}`,n,...t).map(r=>r.relative_path)}function y(e,n,t,s,r){if(e.isIgnored(s)||n.has(s))return;let a=t.get(s);a||(a=new Set,t.set(s,a)),a.add(r)}function N(e){return[...e.entries()].map(([n,t])=>({file:n,consumedSymbols:t.size})).sort((n,t)=>t.consumedSymbols-n.consumedSymbols)}function E(e){return!(g(e.symbol)||e.parentTypeName!==null&&!f(e.symbol))}function v(e,n){return f(e.symbol)||e.isTypeLike?!0:e.parentTypeName===null&&n>0}export{A as a,b,S as c,I as d};
16
- //# sourceMappingURL=chunk-6P5W4U6G.js.map
@@ -1,2 +0,0 @@
1
- import{a as F}from"./chunk-JTCEWV7Q.js";import{a as k}from"./chunk-AQYBOORI.js";import{a as z}from"./chunk-DJTJ3DLZ.js";import{a as $}from"./chunk-SSINY7HL.js";import{a as B}from"./chunk-QYQXPPDI.js";import{a as M}from"./chunk-SLOIQKY7.js";import{b as _}from"./chunk-K4Z3FCUJ.js";import{a as T}from"./chunk-HVXIXDLV.js";import{a as D}from"./chunk-2EC4JTHC.js";import{a as x,b as w}from"./chunk-OIMM7KMI.js";import{b as P}from"./chunk-4A4JFNWG.js";import{b as R,c as E}from"./chunk-N5D5ZCBW.js";import{a as L}from"./chunk-K6YIGVL7.js";import{a as A}from"./chunk-EKP7XJ6L.js";import{e as b,f as C}from"./chunk-TQTVM27C.js";function y(e){let i=X(e),{breakdown:t}=J(e),n=I(t,"risk"),r=I(t,"hygiene");return{score:Math.min(n,r),riskScore:n,hygieneScore:r,scoreBreakdown:t,overview:{documents:e.statsResult.documents,symbols:e.statsResult.symbols,indexSizeBytes:e.statsResult.indexSizeBytes},findings:{deadSymbols:e.dead.count,deadLoc:e.dead.loc,isolatedSymbols:e.isolated.count,isolatedLoc:e.isolated.loc,cycles:e.realCycleCount,similarPairs:e.similarCount,extractionCandidates:e.extractCount,wrappers:e.wrappers.count,passthroughs:e.passthroughs.count,staleTypes:e.stale.count,driftedFiles:e.drift.count,complexityHotspotCount:e.complexity.extremeCount,hiddenCouplingPairs:e.gitEvidence?.hiddenCoupling.pairCount??null},axes:q(e),validation:Y(e),suppressions:e.suppressions,actions:i,topComplexity:e.complexity.top,warnings:e.warnings.length>0?e.warnings:void 0}}function q(e){return{deletable:{loc:e.dead.loc+e.isolated.loc,symbols:e.dead.count+e.isolated.count},cycles:{count:e.realCycleCount},changeAmplification:e.gitEvidence?.amplification??null,hiddenCoupling:e.gitEvidence?.hiddenCoupling??null,churnWeightedComplexity:Q(e),evidenceQuality:{graphFindings:e.dead.count+e.isolated.count+e.realCycleCount,heuristicFindings:e.similarCount+e.extractCount+e.wrappers.count+e.passthroughs.count+e.stale.count+e.drift.count,userSuppressed:e.suppressions?.total??0}}}function Q(e){let i=e.gitEvidence?.fileStats;return i?e.complexity.top.map(t=>{let n=t.file?i[t.file]?.changes??0:0;return{...t,changes:n,weighted:h(t.score*Math.log2(1+n))}}).sort((t,n)=>n.weighted-t.weighted):null}function Y(e){let i=e.gitEvidence?.fileStats;if(!i)return null;let t={dead:e.dead.files??[],isolated:e.isolated.files??[],wrappers:e.wrappers.files??[],passthroughs:e.passthroughs.files??[],stale:e.stale.files??[]},n=new Set(Object.values(t).flat()),r=0,o=0,a=0;for(let[m,l]of Object.entries(i))n.has(m)?r+=l.fixChanges:(o+=l.fixChanges,a+=1);let p=n.size>0?h(r/n.size):0,u=a>0?h(o/a):0,f={};for(let[m,l]of Object.entries(t)){let d=new Set(l);if(d.size===0)continue;let g=0;for(let U of d)g+=i[U]?.fixChanges??0;let v=h(g/d.size);f[m]={flaggedFiles:d.size,fixDensity:v,lift:u>0?h(v/u):null}}return{flaggedFiles:n.size,flaggedFixDensity:p,baselineFixDensity:u,ratio:n.size>0&&u>0?h(p/u):null,byCategory:f}}function h(e){return Math.round(e*100)/100}function X(e){let i=[];if(e.dead.count>0&&i.push({category:"Dead code",evidence:"graph-fact",description:`${e.dead.count} symbols with zero references anywhere \u2014 safe to delete`,effort:"low",impact:"high",count:e.dead.count,locRecoverable:e.dead.loc}),e.isolated.count>0&&i.push({category:"Isolated symbols",evidence:"graph-fact",description:`${e.isolated.count} symbols completely disconnected from the codebase graph`,effort:"low",impact:"medium",count:e.isolated.count,locRecoverable:e.isolated.loc}),e.realCycleCount>0&&i.push({category:"Circular dependencies",evidence:"graph-fact",description:`${e.realCycleCount} cycle(s) \u2014 break with dependency inversion or module restructuring`,effort:"medium",impact:"high",count:e.realCycleCount,locRecoverable:0}),e.similarCount>0&&i.push({category:"Similar functions",evidence:"heuristic",description:`${e.similarCount} pairs with real logic overlap (beyond shared imports) \u2014 consolidation candidates`,effort:"medium",impact:"medium",count:e.similarCount,locRecoverable:0}),e.extractCount>0&&i.push({category:"Extraction candidates",evidence:"heuristic",description:`${e.extractCount} large functions with isolated callee clusters \u2014 extract method opportunities`,effort:"medium",impact:"medium",count:e.extractCount,locRecoverable:0}),e.wrappers.count>0&&i.push({category:"Wrapper functions",evidence:"heuristic",description:`${e.wrappers.count} single-consumer symbols that could be inlined`,effort:"low",impact:"low",count:e.wrappers.count,locRecoverable:e.wrappers.loc}),e.passthroughs.count>0&&i.push({category:"Passthrough functions",evidence:"heuristic",description:`${e.passthroughs.count} functions that just forward to one callee \u2014 unnecessary indirection`,effort:"low",impact:"low",count:e.passthroughs.count,locRecoverable:e.passthroughs.loc}),e.stale.count>0){let r=[];e.stale.unused>0&&r.push(`${e.stale.unused} unused`),e.stale.singleUse>0&&r.push(`${e.stale.singleUse} single-consumer (not in types file)`),i.push({category:"Stale abstractions",evidence:"heuristic",description:`${r.join(", ")} \u2014 premature abstraction`,effort:"low",impact:"medium",count:e.stale.count,locRecoverable:e.stale.loc})}if(e.drift.count>0){let r=[];e.drift.unusedImports>0&&r.push(`${e.drift.unusedImports} unused imports`),e.drift.layerViolations>0&&r.push(`${e.drift.layerViolations} layer violations`),i.push({category:"Structural drift",evidence:"heuristic",description:r.join(", "),effort:e.drift.layerViolations>0?"medium":"low",impact:e.drift.layerViolations>0?"medium":"low",count:e.drift.count,locRecoverable:0})}if(e.gitEvidence&&e.gitEvidence.hiddenCoupling.pairCount>0){let r=e.gitEvidence.hiddenCoupling.top[0];i.push({category:"Hidden coupling",evidence:"change-graph",description:`${e.gitEvidence.hiddenCoupling.pairCount} file pair(s) co-change without a dependency edge`+(r?` (e.g. ${r.fileA} \u2194 ${r.fileB})`:"")+" \u2014 name the shared concept or enforce the sync",effort:"medium",impact:"high",count:e.gitEvidence.hiddenCoupling.pairCount,locRecoverable:0})}let t={high:3,medium:2,low:1},n={low:3,medium:2,high:1};return i.sort((r,o)=>{let a=t[r.impact]*n[r.effort];return t[o.impact]*n[o.effort]-a}),i}var K={"dead-code":"risk",isolated:"risk",cycles:"risk",complexity:"risk","hidden-coupling":"risk",similar:"hygiene",extract:"hygiene",wrappers:"hygiene",passthroughs:"hygiene","stale-abstractions":"hygiene",drift:"hygiene"};function I(e,i){let t=e.filter(n=>n.kind===i).reduce((n,r)=>n+r.points,0);return Math.max(0,Math.min(100,100-t))}function J(e){let i=Math.max(e.statsResult.documents,1),t=Math.max(e.statsResult.symbols,1),n=[],r=(l,d,g)=>{d>0&&n.push({axis:l,points:d,detail:g,kind:K[l]??"hygiene"})},o=e.dead.count/t;r("dead-code",Math.min(20,Math.round(o*200)),`${e.dead.count} dead symbols (${e.dead.loc} LOC deletable)`);let a=e.isolated.count/t;r("isolated",Math.min(10,Math.round(a*200)),`${e.isolated.count} isolated symbols (${e.isolated.loc} LOC deletable)`),r("cycles",Math.min(15,e.realCycleCount*5),`${e.realCycleCount} real dependency cycle(s)`);let p=e.similarCount/t*1e3;r("similar",Math.min(10,Math.round(p)),`${e.similarCount} similar function pair(s)`);let u=e.extractCount/t*1e3;r("extract",Math.min(5,Math.round(u/2)),`${e.extractCount} extraction candidate(s)`),r("wrappers",Math.min(3,e.wrappers.count),`${e.wrappers.count} wrapper candidate(s)`),r("passthroughs",Math.min(3,e.passthroughs.count),`${e.passthroughs.count} passthrough candidate(s)`);let f=e.stale.count/Math.max(t*.1,1);r("stale-abstractions",Math.min(8,Math.round(f*10)),`${e.stale.count} stale abstraction(s)`);let m=e.drift.count/i;return r("drift",Math.min(5,Math.round(m*50)),`${e.drift.count} drift finding(s)`),r("complexity",Math.min(5,e.complexity.extremeCount*2),`${e.complexity.extremeCount} extreme complexity hotspot(s)`),e.gitEvidence&&r("hidden-coupling",Math.min(5,e.gitEvidence.hiddenCoupling.pairCount),`${e.gitEvidence.hiddenCoupling.pairCount} co-changing pair(s) without a dependency edge`),{breakdown:n}}import{getHeapStatistics as Z}from"v8";var ee=64*1024*1024;function H(){let e=globalThis.gc;if(!e)return;let i=Z();i.heap_size_limit-i.used_heap_size<ee||e()}var te=50,ie=75e3,ne=5e3,O=2500,re=["overview","dead","isolated","cycles","similar","extract-candidates","wrapper-candidates","passthrough-candidates","stale-abstractions","drift","complexity-hotspots","git-evidence","suppressions"],j={overview:(e,i,t,n)=>({phase:"overview",statsResult:n,warnings:t.warnings}),dead:(e,i,t)=>({phase:"dead",dead:ae(e,i,t)}),isolated:(e,i,t)=>({phase:"isolated",isolated:se(e,i,t)}),cycles:(e,i,t)=>({phase:"cycles",realCycleCount:ce(e,i,t)}),similar:(e,i,t)=>({phase:"similar",similarCount:ue(e,i,t)}),"extract-candidates":(e,i,t)=>({phase:"extract-candidates",extractCount:le(e,i,t)}),"wrapper-candidates":(e,i,t)=>({phase:"wrapper-candidates",wrappers:de(e,i,t)}),"passthrough-candidates":(e,i,t)=>({phase:"passthrough-candidates",passthroughs:he(e,i,t)}),"stale-abstractions":(e,i,t)=>({phase:"stale-abstractions",stale:pe(e,i,t)}),drift:(e,i,t)=>({phase:"drift",drift:ge(e,i,t)}),"complexity-hotspots":(e,i,t)=>({phase:"complexity-hotspots",complexity:be(e,i,t)}),"git-evidence":(e,i,t)=>({phase:"git-evidence",gitEvidence:me(e,t)}),suppressions:(e,i,t)=>({phase:"suppressions",suppressions:fe(e,t)})};function Ge(e,i={}){return N(e,i.full===!0,(t,n)=>{let r=oe(e,i.scope,t,n);return y(r)})}function We(e,i,t={}){return N(e,t.full===!0,(n,r)=>j[i](e,t.scope,r,n))}function N(e,i,t){let n=k(e),r=Ce(n,i);try{return t(n,r)}finally{x(e,{semanticProvider:!0}),H()}}function Ue(e){return y(G(e))}function G(e){let i=s(e,"overview");return{statsResult:i.statsResult,warnings:i.warnings,dead:s(e,"dead").dead,isolated:s(e,"isolated").isolated,realCycleCount:s(e,"cycles").realCycleCount,similarCount:s(e,"similar").similarCount,extractCount:s(e,"extract-candidates").extractCount,wrappers:s(e,"wrapper-candidates").wrappers,passthroughs:s(e,"passthrough-candidates").passthroughs,stale:s(e,"stale-abstractions").stale,drift:s(e,"drift").drift,complexity:s(e,"complexity-hotspots").complexity,gitEvidence:V(e,"git-evidence")?.gitEvidence??null,suppressions:V(e,"suppressions")?.suppressions??null}}function V(e,i){return e.find(t=>t.phase===i)}function s(e,i){let t=e.find(n=>n.phase===i);if(!t)throw new Error(`Missing health phase result: ${i}`);return t}function oe(e,i,t,n){return G(re.map(r=>j[r](e,i,n,t)))}function ae(e,i,t){return c(e,t,"dead",()=>{let n=w(e,{scope:i,minLoc:3,skipBarrels:!0,deadCodeOnly:!0,scanLimit:t.candidateScanLimit,semantic:!1});return S(He(e,n.symbols))})}function se(e,i,t){return c(e,t,"isolated",()=>{let n=B(e,{scope:i,minLoc:3,scanLimit:t.candidateScanLimit,semantic:!1});return S(Se(e,n))})}function ce(e,i,t){return c(e,t,"cycles",()=>A(e,{scope:i}).filter(r=>r.kind==="real").length)}function ue(e,i,t){return c(e,t,"similar",()=>_(e,{scope:i,minSimilarity:.6,limit:50,minCallees:4,scanLimit:t.candidateScanLimit,semantic:!1}).length)}function le(e,i,t){return c(e,t,"extract-candidates",()=>T(e,{scope:i,minLoc:15,minCallees:5,limit:50,scanLimit:t.candidateScanLimit,semantic:!1}).length)}function de(e,i,t){return W(e,t,"wrapper-candidates",()=>z(e,{scope:i,maxLoc:15,limit:50,scanLimit:t.candidateScanLimit,semantic:!1}))}function he(e,i,t){return W(e,t,"passthrough-candidates",()=>M(e,{scope:i,maxLoc:15,limit:50,scanLimit:t.candidateScanLimit,semantic:!1}))}function pe(e,i,t){return c(e,t,"stale-abstractions",()=>{let n=$(e,{scope:i,minLoc:3,limit:50,scanLimit:t.candidateScanLimit,semantic:!1}),r=n.filter(o=>o.consumers===0).length;return{count:n.length,loc:n.reduce((o,a)=>o+a.loc,0),files:[...new Set(n.map(o=>o.file))],unused:r,singleUse:n.length-r}})}function me(e,i){return c(e,i,"git-evidence",()=>{let t=R(e);if(!t)return null;let n=P(e,void 0,{limit:50}),r={};for(let[o,a]of t)r[o]={changes:a.changes,fixChanges:a.fixChanges};return{amplification:E(e),hiddenCoupling:{pairCount:n.findings.length,top:n.findings.slice(0,5).map(o=>({fileA:o.fileA,fileB:o.fileB,together:o.together,confidence:o.confidence}))},fileStats:r}})}function fe(e,i){return c(e,i,"suppressions",()=>{let t=F(e);return{total:t.total,byCategory:{...t.byCategory}}})}function ge(e,i,t){return c(e,t,"drift",()=>{let n=D(e,{scope:i,semantic:!1});return{count:n.unusedImports+n.layerViolations,unusedImports:n.unusedImports,layerViolations:n.layerViolations}})}function be(e,i,t){return c(e,t,"complexity-hotspots",()=>{let n=L(e,{scope:i,minLoc:10,limit:10,scanLimit:t.candidateScanLimit,semantic:!1});return{top:n.slice(0,5).map(r=>({symbol:r.shortName,score:r.score,file:r.file})),extremeCount:n.filter(r=>r.score>te).length}})}function Ce(e,i){return e.symbols>=ie||e.documents>=ne?i?{candidateScanLimit:void 0,releaseCachesBetweenPhases:!0,warnings:["Large index detected; running unbounded health analyses because --full was supplied."]}:{candidateScanLimit:O,releaseCachesBetweenPhases:!0,warnings:[`Large index detected; candidate-style health checks scanned their highest-priority ${O} symbols. Run "scip-query health --full" for unbounded candidate counts.`]}:{candidateScanLimit:void 0,releaseCachesBetweenPhases:!0,warnings:[]}}function xe(e,i){i.releaseCachesBetweenPhases&&(x(e),H())}function c(e,i,t,n){ye(t);try{return n()}finally{xe(e,i)}}function W(e,i,t,n){return c(e,i,t,()=>S(n()))}function ye(e){process.env.SCIP_QUERY_HEALTH_TRACE==="1"&&console.error(`[health] ${e}`)}function He(e,i){return i.filter(t=>!b(e,t.relativePath)&&!C(e,t.symbol,t.relativePath)&&t.kind==="dead-code")}function Se(e,i){return i.filter(t=>!b(e,t.relativePath)&&!C(e,t.symbol,t.relativePath))}function S(e){let i=new Set;for(let t of e){let n=t.relativePath??t.file;n&&i.add(n)}return{count:e.length,loc:e.reduce((t,n)=>t+n.loc,0),files:[...i]}}export{re as a,Ge as b,We as c,Ue as d};
2
- //# sourceMappingURL=chunk-GTZAU7OL.js.map
@@ -1,7 +0,0 @@
1
- import{d as g}from"./chunk-VDZL45XI.js";import{execFileSync as j}from"child_process";var R=2e3,w=50,M=/\b(?:fix(?:es|ed)?|bug|regression|hotfix)\b/i,h=g("git-commit-history",{clearGroups:["whole-project"]});function x(e){let t=y(e.config.projectRoot);if(!t)return null;let n=h.has(e)?h.get(e,()=>({head:"",history:null})):null;return n&&n.head===t?n.history:(h.invalidate(e),h.get(e,()=>({head:t,history:S(e.config.projectRoot,t)})).history)}function y(e){try{return C(e,["rev-parse","HEAD"]).trim()||null}catch{return null}}function C(e,t){return j("git",["-C",e,...t],{encoding:"utf-8",maxBuffer:64*1024*1024,stdio:["ignore","pipe","ignore"]})}function S(e,t){let n;try{n=C(e,["log","--no-merges","--name-only","-n",String(R),"--pretty=format:%x01%H%x00%ct%x00%s"])}catch{return null}let r=[],o=0;for(let s of n.split("")){if(s.trim()==="")continue;let c=s.indexOf(`
2
- `),f=c>=0?s.slice(0,c):s,[a,i,l]=f.split("\0");if(!a||!i)continue;let m=c>=0?s.slice(c+1).split(`
3
- `).map(u=>u.trim()).filter(u=>u!==""):[];if(m.length>w){o+=1;continue}r.push({hash:a,timestamp:Number(i)||0,subject:l??"",files:m})}return{head:t,commits:r,skippedBulkCommits:o}}function k(e){return M.test(e.subject)}function D(e){let t=x(e);if(!t)return null;let n=new Map;for(let r of t.commits){let o=k(r);for(let s of r.files){let c=n.get(s)??{changes:0,fixChanges:0,lastChangedAt:0};c.changes+=1,o&&(c.fixChanges+=1),r.timestamp>c.lastChangedAt&&(c.lastChangedAt=r.timestamp),n.set(s,c)}}return n}function T(e){let t=x(e);if(!t||t.commits.length===0)return null;let n=t.commits.map(r=>r.files.length).filter(r=>r>0).sort((r,o)=>r-o);return n.length===0?null:{medianFilesPerCommit:F(n,.5),p90FilesPerCommit:F(n,.9),commitsAnalyzed:n.length}}function F(e,t){let n=Math.min(e.length-1,Math.floor(e.length*t));return e[n]}var d=g("git-tracked-files",{clearGroups:["whole-project"]});function _(e){let t=y(e.config.projectRoot);if(!t)return null;let n=d.has(e)?d.get(e,()=>({head:"",files:null})):null;return n&&n.head===t?n.files:(d.invalidate(e),d.get(e,()=>{try{let r=C(e.config.projectRoot,["ls-files"]);return{head:t,files:new Set(r.split(`
4
- `).map(o=>o.trim()).filter(o=>o!==""))}}catch{return{head:t,files:null}}}).files)}var p=g("git-file-adds",{clearGroups:["whole-project"]});function v(e){let t=y(e.config.projectRoot);if(!t)return null;let n=p.has(e)?p.get(e,()=>({head:"",adds:null})):null;return n&&n.head===t?n.adds:(p.invalidate(e),p.get(e,()=>({head:t,adds:P(e.config.projectRoot)})).adds)}function P(e){let t;try{t=C(e,["log","--no-merges","--diff-filter=A","--name-only","-n",String(R),"--pretty=format:%x01%H%x00%ct%x00%s"])}catch{return null}let n=new Map,r=-1;for(let o of t.split("")){if(o.trim()==="")continue;r+=1;let s=o.indexOf(`
5
- `),c=s>=0?o.slice(0,s):o,[,f]=c.split("\0"),a=Number(f)||0;if(!(s<0))for(let i of o.slice(s+1).split(`
6
- `)){let l=i.trim();l!==""&&n.set(l,{commitsAgo:r,addedAt:a})}}return n}function E(e,t={}){let{minTogether:n=4,minConfidence:r=.6}=t,o=x(e);if(!o)return null;let s=new Map,c=new Map;for(let a of o.commits){let i=[...new Set(a.files)].sort();for(let l of i)s.set(l,(s.get(l)??0)+1);for(let l=0;l<i.length;l++)for(let m=l+1;m<i.length;m++){let u=`${i[l]}\0${i[m]}`;c.set(u,(c.get(u)??0)+1)}}let f=[];for(let[a,i]of c){if(i<n)continue;let[l,m]=a.split("\0"),u=s.get(l)??i,A=s.get(m)??i,b=Math.max(i/u,i/A);b<r||f.push({fileA:l,fileB:m,together:i,confidence:b,changesA:u,changesB:A})}return f.sort((a,i)=>i.together-a.together||i.confidence-a.confidence||a.fileA.localeCompare(i.fileA)),f}export{x as a,D as b,T as c,_ as d,v as e,E as f};
7
- //# sourceMappingURL=chunk-N5D5ZCBW.js.map
@@ -1,2 +0,0 @@
1
- import{a as F,d as A}from"./chunk-N5D5ZCBW.js";import{existsSync as k,readFileSync as z}from"fs";import{join as v}from"path";var b=/\.(?:md|mdx|rst|txt)$/i;function C(n){return/(?:^|\/)(?:docs\/plans|plans|adrs?|rfcs?|decisions|changelogs?|archive|reports?)\//i.test(n)||/(?:^|\/)CHANGELOG\.(?:md|mdx|rst|txt)$/i.test(n)}var T=3,U=/[A-Za-z0-9_@-]+(?:\/[A-Za-z0-9_.@-]+)+\.[A-Za-z0-9]{1,6}\b/g;function L(n,d={}){let{doc:s,limit:u=20,minCoupling:g=T}=d,t=F(n);if(!t)return{available:!1,commitsAnalyzed:0,docsScanned:0,findings:[]};let c=A(n)??new Set,r=new Map,p=new Map,m=new Set;for(let o of t.commits){let l=[...new Set(o.files)],S=l.filter(i=>b.test(i)),y=l.filter(i=>!b.test(i));for(let i of l){m.add(i);let a=r.get(i)??[];a.push(o.timestamp),r.set(i,a)}for(let i of S){let a=p.get(i);a||(a=new Map,p.set(i,a));for(let e of y)a.set(e,(a.get(e)??0)+1)}}let h=[...c].filter(o=>b.test(o)),M=j(c),x=[];for(let o of h){if(s!==void 0&&!o.includes(s)||s===void 0&&C(o)||!k(v(n.config.projectRoot,o)))continue;let l=Math.max(0,...r.get(o)??[]),S=new Map,{resolved:y,broken:i}=w(n,o,c,M,m);for(let e of y){if(e===o||b.test(e))continue;let f=(r.get(e)??[]).filter(D=>D>l).length;f!==0&&S.set(e,{file:e,evidence:"reference",coChanges:0,changesSinceDocUpdate:f})}for(let[e,f]of p.get(o)??[]){if(f<g||!c.has(e))continue;let D=(r.get(e)??[]).filter(E=>E>l).length;if(D===0)continue;let R=S.get(e);R?(R.evidence="both",R.coChanges=f):S.set(e,{file:e,evidence:"co-change",coChanges:f,changesSinceDocUpdate:D})}if(S.size===0&&i.length===0)continue;let a=[...S.values()].sort((e,f)=>f.changesSinceDocUpdate-e.changesSinceDocUpdate);x.push({doc:o,docLastChangedAt:l,staleness:a.reduce((e,f)=>e+f.changesSinceDocUpdate,0)+i.length*10,subjects:a.slice(0,8),brokenReferences:i})}return x.sort((o,l)=>l.staleness-o.staleness),{available:!0,commitsAnalyzed:t.commits.length,docsScanned:h.length,findings:x.slice(0,u)}}function H(n,d){let s=A(n)??new Set,u=j(s),g=[];for(let t of s){if(!b.test(t)||C(t)||!k(v(n.config.projectRoot,t)))continue;let{resolved:c}=w(n,t,s,u,new Set),r=[...c].filter(p=>d.has(p));r.length>0&&g.push({doc:t,cited:r.sort()})}return g}function j(n){let d=new Map;for(let s of n){let u=s.split("/");for(let g of[2,3]){if(u.length<g)continue;let t=u.slice(-g).join("/"),c=d.get(t)??[];c.push(s),d.set(t,c)}}return d}function w(n,d,s,u,g){let t=new Set,c=new Set,r;try{r=z(v(n.config.projectRoot,d),"utf-8")}catch{return{resolved:t,broken:[]}}for(let p of r.matchAll(U)){let m=p[0].replace(/^\.?\//,"");if(s.has(m)){t.add(m);continue}let h=u.get(m);if(h&&h.length===1){t.add(h[0]);continue}h&&h.length>1||g.has(m)&&c.add(m)}return{resolved:t,broken:[...c]}}export{C as a,L as b,H as c};
2
- //# sourceMappingURL=chunk-OQSV6OS2.js.map
@@ -1,2 +0,0 @@
1
- function m(n,e){let t=new Set;for(let r of n)e.has(r)&&t.add(r);return t}function M(n,e){let t=new Set;for(let r of n)e.has(r)||t.add(r);return t}function w(n,e){if(n.size===0&&e.size===0)return 0;let t=0;for(let o of n)e.has(o)&&(t+=1);let r=n.size+e.size-t;return r===0?0:t/r}function x(n){let e=n.length;if(e===0)return new Map;let t=new Map;for(let o of n)for(let s of o)t.set(s,(t.get(s)??0)+1);let r=new Map;for(let[o,s]of t)r.set(o,Math.log(e/s));return r}function p(n){let e=[...n.values()].sort((r,o)=>r-o);if(e.length===0)return 0;let t=Math.floor(e.length/2);return e.length%2===0?(e[t-1]+e[t])/2:e[t]}function v(n,e,t){let r=m(n,e);if(r.size===0)return{similarity:0,significantShared:[],trivialShared:[]};let o=0,s=0,T=0,l=new Set([...n,...e]);for(let i of l){let a=t.get(i)??0,f=n.has(i)?a:0,u=e.has(i)?a:0;o+=f*u,s+=f*f,T+=u*u}let h=Math.sqrt(s)*Math.sqrt(T),g=h>0?o/h:0,S=p(t),c=[],d=[];for(let i of r)(t.get(i)??0)>=S?c.push(i):d.push(i);return c.sort((i,a)=>(t.get(a)??0)-(t.get(i)??0)),{similarity:g,significantShared:c,trivialShared:d}}export{m as a,M as b,w as c,x as d,v as e};
2
- //# sourceMappingURL=chunk-RKTDEIHF.js.map
@@ -1,3 +0,0 @@
1
- import{a as G}from"./chunk-HVGNOUYP.js";import{a as L}from"./chunk-AQYBOORI.js";import{a as F}from"./chunk-DJTJ3DLZ.js";import{a as E}from"./chunk-SSINY7HL.js";import{a as x}from"./chunk-QYQXPPDI.js";import{a as B}from"./chunk-SLOIQKY7.js";import{a as N,b as v}from"./chunk-K4Z3FCUJ.js";import{a as A}from"./chunk-HVXIXDLV.js";import{a as D}from"./chunk-6P5W4U6G.js";import{c as R}from"./chunk-OQSV6OS2.js";import{a as w}from"./chunk-2EC4JTHC.js";import{b as k}from"./chunk-OIMM7KMI.js";import{a as p}from"./chunk-4A4JFNWG.js";import{f as $}from"./chunk-N5D5ZCBW.js";import{a as C}from"./chunk-EKP7XJ6L.js";import{a as S}from"./chunk-NOVKLH2F.js";import{e as h,f as d}from"./chunk-TQTVM27C.js";import{existsSync as j}from"fs";import{existsSync as H,readFileSync as I,writeFileSync as T}from"fs";import{isAbsolute as O,join as M}from"path";var U=75e3,q=5e3,z=2500;function J(e){let i=L(e);return i.symbols>=U||i.documents>=q?z:void 0}var K=".scipquery-baseline.json";function u(e,i){return i&&O(i)?i:M(e.config.projectRoot,i??K)}function P(e,i={}){let{scope:t}=i,s=J(e),o=[],f=k(e,{scope:t,minLoc:3,skipBarrels:!0,deadCodeOnly:!0,scanLimit:s,semantic:!1});for(let n of f.symbols)h(e,n.relativePath)||d(e,n.symbol,n.relativePath)||n.kind==="dead-code"&&o.push(`dead:${n.relativePath}:${n.shortName}`);for(let n of x(e,{scope:t,minLoc:3,scanLimit:s,semantic:!1}))h(e,n.relativePath)||d(e,n.symbol,n.relativePath)||o.push(`isolated:${n.relativePath}:${n.shortName}`);for(let n of C(e,{scope:t}))n.kind==="real"&&o.push(`cycle:${W(n.path)}`);for(let n of v(e,{scope:t,minSimilarity:.6,limit:50,minCallees:4,scanLimit:s,semantic:!1}))o.push(`similar:${[n.symbolA,n.symbolB].sort().join("|")}`);for(let n of A(e,{scope:t,minLoc:15,minCallees:5,limit:50,scanLimit:s,semantic:!1}))o.push(`extract:${n.relativePath}:${n.shortName}`);for(let n of F(e,{scope:t,maxLoc:15,limit:50,scanLimit:s,semantic:!1}))o.push(`wrapper:${n.file}:${n.shortName}`);for(let n of B(e,{scope:t,maxLoc:15,limit:50,scanLimit:s,semantic:!1}))o.push(`passthrough:${n.file}:${n.shortName}`);for(let n of E(e,{scope:t,minLoc:3,limit:50,scanLimit:s,semantic:!1}))o.push(`stale:${n.file}:${n.shortName}`);for(let n of w(e,{scope:t,semantic:!1}).results)n.kind!=="pattern-deviation"&&o.push(`drift:${n.kind}:${n.file}:${n.dep}`);return[...new Set(o)].sort()}function W(e){if(e.length===0)return"";let i=0;for(let t=1;t<e.length;t++)e[t]<e[i]&&(i=t);return[...e.slice(i),...e.slice(0,i)].join(">")}function ue(e,i={}){let t=P(e,{scope:i.scope}),s=u(e,i.path);return T(s,JSON.stringify({version:1,findings:t},null,2)+`
2
- `),{path:s,findingCount:t.length}}function _(e,i={}){let t=u(e,i.path);if(!H(t))throw new Error(`No baseline found at ${t}. Create one with: scip-query health --write-baseline`);let s=JSON.parse(I(t,"utf-8")),o=new Set(s.findings??[]),f=P(e,{scope:i.scope}),n=new Set(f);return{baselinePath:t,baselineCount:o.size,current:f,newFindings:f.filter(a=>!o.has(a)),fixedFindings:[...o].filter(a=>!n.has(a))}}function Ae(e,i={}){let t=i.base??"HEAD",{minTogether:s=6,minConfidence:o=.6,maxEchoChecks:f=10,minSimilarity:n=.8}=i,a=D(e,{base:t}),r=a.changedFiles,l=new Set(r),c={base:t,changedFiles:r,changedSymbols:a.changedSymbols.length,checksRun:[],skipped:[],findings:[],note:a.summary.note};return r.length===0||(Y(e,a.changedSymbols,l,f,n,c),Q(e,l,s,o,c),V(e,l,c),X(e,r,c),Z(e,a.changedSymbols,c),ee(e,c)),c}function Y(e,i,t,s,o,f){f.checksRun.push("echo");for(let n of i.slice(0,s)){let a=N(e,n.symbol,{minSimilarity:o,limit:3});for(let r of a){let l=r.fileA===n.file?r.fileB:r.fileA,c=r.fileA===n.file?r.shortNameB:r.shortNameA;t.has(l)||f.findings.push({check:"echo",message:`${n.shortName} (${n.file}) is ${Math.round(r.similarity*100)}% similar to established ${c} (${l})`,remediation:`Extend or reuse ${c} instead of keeping the re-implementation.`})}}i.length>s&&f.skipped.push({check:"echo",reason:`echo check capped at ${s} of ${i.length} changed symbols`})}function Q(e,i,t,s,o){let f=$(e,{minTogether:t,minConfidence:0});if(!f){o.skipped.push({check:"co-change-partner",reason:"no git history"});return}o.checksRun.push("co-change-partner");let n=new Set;for(let a of f){let r=i.has(a.fileA),l=i.has(a.fileB);if(r===l)continue;let c=r?a.fileA:a.fileB,m=r?a.fileB:a.fileA,g=r?a.changesA:a.changesB,y=g>0?a.together/g:0;if(y<s||p(m)||p(c)||!j(`${e.config.projectRoot}/${m}`))continue;let b=`${c}|${m}`;n.has(b)||(n.add(b),o.findings.push({check:"co-change-partner",message:`${c} changed, but ${m} did not \u2014 they change together ${a.together}x (${Math.round(y*100)}% of the time)`,remediation:`Update ${m} alongside this change, or confirm the coupling no longer holds.`}))}}function V(e,i,t){t.checksRun.push("doc-reference");for(let s of R(e,i))i.has(s.doc)||t.findings.push({check:"doc-reference",message:`${s.doc} cites ${s.cited.join(", ")} \u2014 changed in this diff, doc untouched`,remediation:`Re-read ${s.doc} and update its claims, or update its citations.`})}function X(e,i,t){t.checksRun.push("unused-params");for(let s of G(e,{files:i,limit:50}))t.findings.push({check:"unused-params",message:`${s.shortName} (${s.file}) has trailing unused parameter(s): ${s.unusedTrailing.join(", ")}`,remediation:"Drop the unused trailing parameters and their call-site arguments."})}function Z(e,i,t){t.checksRun.push("new-dead");let s=new S(e);for(let o of i)o.fanIn>0||s.fileKind(o.file)!=="test"&&(h(e,o.file)||d(e,o.symbol,o.file)||t.findings.push({check:"new-dead",message:`${o.shortName} (${o.file}) was changed but has zero indexed consumers`,remediation:"Wire it up, or remove it before it becomes permanent dead code."}))}function ee(e,i){if(!j(u(e))){i.skipped.push({check:"baseline",reason:"no .scipquery-baseline.json \u2014 run health --write-baseline to enable"});return}i.checksRun.push("baseline");let t=_(e);for(let s of t.newFindings)i.findings.push({check:"baseline",message:`new finding vs committed baseline: ${s}`,remediation:"Fix the finding, or knowingly accept it via health --write-baseline."})}export{P as a,ue as b,_ as c,Ae as d};
3
- //# sourceMappingURL=chunk-XBFLIGWU.js.map