scip-query 0.7.2 → 0.8.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.
Files changed (174) hide show
  1. package/README.md +179 -221
  2. package/dist/augment-vue-worker.js +1 -1
  3. package/dist/{chunk-OPWOX7NT.js → chunk-2EC4JTHC.js} +2 -2
  4. package/dist/{chunk-SVSLAUSJ.js → chunk-46ILZVMX.js} +2 -2
  5. package/dist/chunk-4A4JFNWG.js +2 -0
  6. package/dist/{chunk-QBXTQODK.js → chunk-4B7YLRXX.js} +2 -2
  7. package/dist/chunk-64UY7VTR.js +63 -0
  8. package/dist/chunk-66ORT3LS.js +2 -0
  9. package/dist/{chunk-VMS5YTBS.js → chunk-6G76D2YM.js} +2 -2
  10. package/dist/{chunk-PEU24CSY.js → chunk-6P5W4U6G.js} +2 -2
  11. package/dist/chunk-6ZFKI5EP.js +40 -0
  12. package/dist/{chunk-EVXQF7DM.js → chunk-7I6KNKE3.js} +2 -2
  13. package/dist/{chunk-EIGCLVKK.js → chunk-7TYJD45F.js} +2 -2
  14. package/dist/chunk-7UZWNW4E.js +2 -0
  15. package/dist/{chunk-GIRI7FHW.js → chunk-AGW2MVIO.js} +2 -2
  16. package/dist/chunk-APLCSDXL.js +4 -0
  17. package/dist/{chunk-JDFWJ7VK.js → chunk-BCFED24F.js} +2 -2
  18. package/dist/chunk-CVRXOP6M.js +3 -0
  19. package/dist/{chunk-2QNKEJ7R.js → chunk-D43L5PQF.js} +2 -2
  20. package/dist/chunk-DJTJ3DLZ.js +7 -0
  21. package/dist/chunk-EAU4RDFG.js +2 -0
  22. package/dist/{chunk-BI4F6GXI.js → chunk-EKP7XJ6L.js} +2 -2
  23. package/dist/{chunk-LLL7THVV.js → chunk-EM2PPDN7.js} +2 -2
  24. package/dist/{chunk-6QC7SCKV.js → chunk-FIPE5AQT.js} +2 -2
  25. package/dist/chunk-FTBT4RP2.js +7 -0
  26. package/dist/{chunk-TB2OYNRS.js → chunk-GD7XRHSV.js} +2 -2
  27. package/dist/{chunk-XDXZP3BE.js → chunk-GMEBYEMU.js} +2 -2
  28. package/dist/chunk-GTZAU7OL.js +2 -0
  29. package/dist/chunk-HVGNOUYP.js +2 -0
  30. package/dist/chunk-HVXIXDLV.js +2 -0
  31. package/dist/{chunk-5TB4N27G.js → chunk-I7OTKWNY.js} +2 -2
  32. package/dist/{chunk-RFCR2BRD.js → chunk-JAMU6FLN.js} +2 -2
  33. package/dist/chunk-JTCEWV7Q.js +2 -0
  34. package/dist/chunk-K4Z3FCUJ.js +6 -0
  35. package/dist/{chunk-WJQFABZN.js → chunk-K6YIGVL7.js} +2 -2
  36. package/dist/chunk-MKE7SEEX.js +2 -0
  37. package/dist/chunk-N5D5ZCBW.js +7 -0
  38. package/dist/{chunk-ROZNBWIF.js → chunk-NGLRXEWN.js} +2 -2
  39. package/dist/{chunk-IFGEPTH5.js → chunk-NK7TQQG4.js} +2 -2
  40. package/dist/chunk-NOVKLH2F.js +2 -0
  41. package/dist/chunk-OIMM7KMI.js +2 -0
  42. package/dist/chunk-OQSV6OS2.js +2 -0
  43. package/dist/chunk-PBGTMPJ7.js +2 -0
  44. package/dist/{chunk-YH6TTQEI.js → chunk-PCMVXWDC.js} +4 -4
  45. package/dist/{chunk-U75WH4XG.js → chunk-PE4EJOLN.js} +2 -2
  46. package/dist/chunk-PLFYFZX3.js +2 -0
  47. package/dist/{chunk-HTVLH3NL.js → chunk-QYQXPPDI.js} +2 -2
  48. package/dist/{chunk-P7UMQ7R7.js → chunk-RCRK4E7E.js} +2 -2
  49. package/dist/chunk-RIXOMSOR.js +20 -0
  50. package/dist/chunk-SB6I6O3P.js +2 -0
  51. package/dist/{chunk-X2JB54QF.js → chunk-SDGCKEB7.js} +2 -2
  52. package/dist/chunk-SLOIQKY7.js +2 -0
  53. package/dist/{chunk-4VYIZV3S.js → chunk-SOGLYIJ4.js} +4 -4
  54. package/dist/chunk-SSINY7HL.js +4 -0
  55. package/dist/{chunk-FU5WRWAN.js → chunk-TFO4OMJZ.js} +2 -2
  56. package/dist/chunk-TH4JVC34.js +71 -0
  57. package/dist/chunk-TQTVM27C.js +6 -0
  58. package/dist/{chunk-QP6FLI6D.js → chunk-TR5AU6A5.js} +2 -2
  59. package/dist/{chunk-4LKJMRT5.js → chunk-UQE3DSXY.js} +2 -2
  60. package/dist/{chunk-LXJTDFOV.js → chunk-UUDYI3FF.js} +2 -2
  61. package/dist/chunk-VDZL45XI.js +2 -0
  62. package/dist/{chunk-XANDY7N5.js → chunk-VN6B6HFB.js} +2 -2
  63. package/dist/{chunk-SDPP5KVQ.js → chunk-WC43FMAB.js} +2 -2
  64. package/dist/chunk-WEJYUS5O.js +2 -0
  65. package/dist/chunk-WQFOZIID.js +4 -0
  66. package/dist/chunk-XBFLIGWU.js +3 -0
  67. package/dist/{chunk-TGNL3ZKZ.js → chunk-XSZ5NC4O.js} +2 -2
  68. package/dist/{chunk-4T35WUCX.js → chunk-Z2AJQ7VA.js} +2 -2
  69. package/dist/{chunk-S5VMVNFM.js → chunk-ZIIQ55VK.js} +2 -2
  70. package/dist/chunk-ZJ737ZMD.js +2 -0
  71. package/dist/cli.js +171 -173
  72. package/dist/health-C6r2VgpA.d.ts +234 -0
  73. package/dist/index.d.ts +11 -18
  74. package/dist/index.js +1 -1
  75. package/dist/postinstall.js +4 -4
  76. package/dist/queries/affected.js +1 -1
  77. package/dist/queries/bottlenecks.js +1 -1
  78. package/dist/queries/by-kind.js +1 -1
  79. package/dist/queries/call-graph.js +1 -1
  80. package/dist/queries/change-surface.js +1 -1
  81. package/dist/queries/cleanup-plan.d.ts +66 -0
  82. package/dist/queries/cleanup-plan.js +2 -0
  83. package/dist/queries/co-change.d.ts +42 -0
  84. package/dist/queries/co-change.js +2 -0
  85. package/dist/queries/code.js +1 -1
  86. package/dist/queries/complexity-hotspots.js +1 -1
  87. package/dist/queries/complexity.js +1 -1
  88. package/dist/queries/convergence.js +1 -1
  89. package/dist/queries/coupling.js +1 -1
  90. package/dist/queries/cycles.js +1 -1
  91. package/dist/queries/dataflow.js +1 -1
  92. package/dist/queries/dead.js +1 -1
  93. package/dist/queries/deep-chains.js +1 -1
  94. package/dist/queries/deps.js +1 -1
  95. package/dist/queries/diff-gate.d.ts +52 -0
  96. package/dist/queries/diff-gate.js +2 -0
  97. package/dist/queries/diff-impact.js +1 -1
  98. package/dist/queries/doc-drift.d.ts +69 -0
  99. package/dist/queries/doc-drift.js +2 -0
  100. package/dist/queries/drift.js +1 -1
  101. package/dist/queries/extract-candidates.js +1 -1
  102. package/dist/queries/fan.js +1 -1
  103. package/dist/queries/health.d.ts +1 -1
  104. package/dist/queries/health.js +1 -1
  105. package/dist/queries/hierarchy.js +1 -1
  106. package/dist/queries/hotspots.js +1 -1
  107. package/dist/queries/imports.js +1 -1
  108. package/dist/queries/index.d.ts +38 -2
  109. package/dist/queries/index.js +1 -1
  110. package/dist/queries/isolated.js +1 -1
  111. package/dist/queries/members.js +1 -1
  112. package/dist/queries/methods.js +1 -1
  113. package/dist/queries/outline.d.ts +1 -0
  114. package/dist/queries/outline.js +1 -1
  115. package/dist/queries/passthrough-candidates.js +1 -1
  116. package/dist/queries/plan-context.d.ts +65 -0
  117. package/dist/queries/plan-context.js +2 -0
  118. package/dist/queries/recent-duplicates.d.ts +48 -0
  119. package/dist/queries/recent-duplicates.js +2 -0
  120. package/dist/queries/redundant-reexports.js +1 -1
  121. package/dist/queries/refs.js +1 -1
  122. package/dist/queries/self-audit.d.ts +58 -0
  123. package/dist/queries/self-audit.js +2 -0
  124. package/dist/queries/similar-chains.js +1 -1
  125. package/dist/queries/similar-files.d.ts +6 -0
  126. package/dist/queries/similar-files.js +1 -1
  127. package/dist/queries/similar-signatures.js +1 -1
  128. package/dist/queries/similar.js +1 -1
  129. package/dist/queries/slice.js +1 -1
  130. package/dist/queries/stale-abstractions.js +1 -1
  131. package/dist/queries/surface.js +1 -1
  132. package/dist/queries/symbols.js +1 -1
  133. package/dist/queries/system.js +1 -1
  134. package/dist/queries/trace.js +1 -1
  135. package/dist/queries/unused-params.d.ts +38 -0
  136. package/dist/queries/unused-params.js +2 -0
  137. package/dist/queries/wrapper-candidates.js +1 -1
  138. package/dist/reindex-worker.js +1 -1
  139. package/dist/reindex.js +1 -1
  140. package/dist/runtime.d.ts +3 -2
  141. package/dist/runtime.js +2 -2
  142. package/package.json +33 -1
  143. package/skills/concrete-plan/SKILL.md +37 -7
  144. package/skills/scip-ai-cleanup/SKILL.md +145 -0
  145. package/skills/scip-debloat/SKILL.md +37 -7
  146. package/skills/scip-doc-reconcile/SKILL.md +100 -0
  147. package/skills/scip-explore/SKILL.md +22 -9
  148. package/skills/scip-language-playbook/SKILL.md +4 -4
  149. package/skills/scip-maintainability/SKILL.md +264 -0
  150. package/skills/scip-verify/SKILL.md +2 -2
  151. package/dist/chunk-3X43EYFU.js +0 -3
  152. package/dist/chunk-4GPWGSOE.js +0 -40
  153. package/dist/chunk-5RGK4YA5.js +0 -63
  154. package/dist/chunk-5TT47UMX.js +0 -44
  155. package/dist/chunk-6QH2L26C.js +0 -71
  156. package/dist/chunk-6SR4UNWI.js +0 -2
  157. package/dist/chunk-6XEWA6FX.js +0 -2
  158. package/dist/chunk-7WHNTKSD.js +0 -2
  159. package/dist/chunk-BOVNTAKQ.js +0 -3
  160. package/dist/chunk-D62LLANH.js +0 -2
  161. package/dist/chunk-EDXML2HI.js +0 -4
  162. package/dist/chunk-EZQOVY3C.js +0 -2
  163. package/dist/chunk-IODTPF5H.js +0 -20
  164. package/dist/chunk-KJ6CW6EK.js +0 -2
  165. package/dist/chunk-NBUINPSH.js +0 -2
  166. package/dist/chunk-NHDPYW7O.js +0 -2
  167. package/dist/chunk-NKJKI6SE.js +0 -2
  168. package/dist/chunk-OPZQIJZU.js +0 -7
  169. package/dist/chunk-P3PVY6TX.js +0 -2
  170. package/dist/chunk-QE6MGGUY.js +0 -2
  171. package/dist/chunk-QVPYMZUJ.js +0 -6
  172. package/dist/chunk-RCJEFQOK.js +0 -4
  173. package/dist/chunk-UHMJYNTK.js +0 -2
  174. package/dist/health-x7B4Xu_6.d.ts +0 -119
@@ -0,0 +1,2 @@
1
+ import{a}from"../chunk-HVGNOUYP.js";import"../chunk-V76FCF5F.js";import"../chunk-MX6F756F.js";import"../chunk-NOVKLH2F.js";import"../chunk-TQTVM27C.js";import"../chunk-RIXOMSOR.js";import"../chunk-EAU4RDFG.js";import"../chunk-PCMVXWDC.js";import"../chunk-6ZFKI5EP.js";import"../chunk-64UY7VTR.js";import"../chunk-7I6KNKE3.js";import"../chunk-APLCSDXL.js";import"../chunk-WEJYUS5O.js";import"../chunk-PBGTMPJ7.js";import"../chunk-SOGLYIJ4.js";import"../chunk-WQFOZIID.js";import"../chunk-NN3O7TPH.js";import"../chunk-VDZL45XI.js";export{a as unusedParams};
2
+ //# sourceMappingURL=unused-params.js.map
@@ -1,2 +1,2 @@
1
- import{a}from"../chunk-OPZQIJZU.js";import"../chunk-3X43EYFU.js";import"../chunk-V76FCF5F.js";import"../chunk-MX6F756F.js";import"../chunk-NBUINPSH.js";import"../chunk-NKJKI6SE.js";import"../chunk-IODTPF5H.js";import"../chunk-P3PVY6TX.js";import"../chunk-YH6TTQEI.js";import"../chunk-4GPWGSOE.js";import"../chunk-5RGK4YA5.js";import"../chunk-EVXQF7DM.js";import"../chunk-RCJEFQOK.js";import"../chunk-BOVNTAKQ.js";import"../chunk-KJ6CW6EK.js";import"../chunk-4VYIZV3S.js";import"../chunk-5TT47UMX.js";import"../chunk-NHDPYW7O.js";import"../chunk-NN3O7TPH.js";export{a as wrapperCandidates};
1
+ import{a}from"../chunk-DJTJ3DLZ.js";import"../chunk-CVRXOP6M.js";import"../chunk-V76FCF5F.js";import"../chunk-MX6F756F.js";import"../chunk-NOVKLH2F.js";import"../chunk-TQTVM27C.js";import"../chunk-RIXOMSOR.js";import"../chunk-EAU4RDFG.js";import"../chunk-PCMVXWDC.js";import"../chunk-6ZFKI5EP.js";import"../chunk-64UY7VTR.js";import"../chunk-7I6KNKE3.js";import"../chunk-APLCSDXL.js";import"../chunk-WEJYUS5O.js";import"../chunk-PBGTMPJ7.js";import"../chunk-SOGLYIJ4.js";import"../chunk-WQFOZIID.js";import"../chunk-NN3O7TPH.js";import"../chunk-VDZL45XI.js";export{a as wrapperCandidates};
2
2
  //# sourceMappingURL=wrapper-candidates.js.map
@@ -1,4 +1,4 @@
1
- import{a as P,b as N}from"./chunk-6QH2L26C.js";import{a as m,e as M}from"./chunk-LWYIGRHR.js";import{execFileSync as ln}from"child_process";import{closeSync as pn,existsSync as E,mkdirSync as ie,mkdtempSync as cn,openSync as gn,readFileSync as dn,renameSync as $,rmSync as B,writeFileSync as ae}from"fs";import{basename as S,dirname as d,extname as mn,join as g}from"path";import{execFileSync as ge}from"child_process";import{existsSync as de,readdirSync as A}from"fs";import{extname as _,join as T}from"path";var me=new Set([".git",".hg",".svn",".idea",".vscode","node_modules","vendor","dist","build","target","bin","obj",".dart_tool",".gradle",".next",".venv","venv","__pycache__"]),fe=[{language:"typescript",files:["tsconfig.json","tsconfig.base.json"],extensions:[".ts",".tsx",".mts",".cts"]},{language:"rust",files:["Cargo.toml"],extensions:[".rs"]},{language:"go",files:["go.mod"],extensions:[".go"]},{language:"java",files:["pom.xml","build.gradle","build.gradle.kts"],extensions:[".java"]},{language:"kotlin",files:["build.gradle.kts"],extensions:[".kt",".kts"]},{language:"scala",files:["build.sbt"],extensions:[".scala"]},{language:"python",files:["pyproject.toml","setup.py","setup.cfg","Pipfile"],extensions:[".py",".pyi"]},{language:"ruby",files:["Gemfile"],extensions:[".rb"]},{language:"cpp",files:["compile_commands.json","CMakeLists.txt","Makefile"],extensions:[".cc",".cpp",".cxx",".hpp",".hh",".hxx"]},{language:"c",files:["compile_commands.json","CMakeLists.txt","Makefile"],extensions:[".c",".h"]},{language:"csharp",globs:["*.csproj","*.sln"],extensions:[".cs"]},{language:"vb",globs:["*.vbproj"],extensions:[".vb"]},{language:"dart",files:["pubspec.yaml"],extensions:[".dart"]},{language:"php",files:["composer.json"],extensions:[".php"]},{language:"javascript",files:["package.json"],extensions:[".js",".jsx",".mjs",".cjs"]}];function U(e){let n=[],t=he(e),r=Se(e);for(let i of fe){if(xe(e,i.files)){n.push(i.language);continue}if(ye(t,i.globs)){n.push(i.language);continue}ve(r,i.extensions)&&n.push(i.language)}return n.includes("typescript")&&F(n,"javascript"),n.includes("cpp")&&!r.has(".c")&&F(n,"c"),n}function he(e){try{return A(e)}catch{return[]}}function xe(e,n){return n?.length?n.some(t=>de(T(e,t))):!1}function ye(e,n){return n?.length?e.some(t=>n.some(r=>be(t,r))):!1}function be(e,n){if(n==="*")return!0;if(!n.includes("*"))return e===n;let[t,r]=n.split("*");return e.startsWith(t??"")&&e.endsWith(r??"")}function Se(e){let n=Pe(e);if(n)return n;let t=new Set,r=[e];for(;r.length>0;){let i=r.pop();if(!i)continue;let a;try{a=A(i,{withFileTypes:!0})}catch{continue}for(let s of a){if(s.name.startsWith(".")&&!s.name.endsWith("proj")&&!s.name.endsWith("sln")&&s.isDirectory())continue;let o=T(i,s.name);if(s.isDirectory()){me.has(s.name)||r.push(o);continue}let c=_(s.name).toLowerCase();c&&t.add(c)}}return t}function Pe(e){try{let n=ge("git",["-C",e,"ls-files","-co","--exclude-standard","--","."],{encoding:"utf-8",maxBuffer:26214400,stdio:["ignore","pipe","ignore"]}),t=new Set;for(let r of n.split(`
1
+ import{a as P,b as N}from"./chunk-TH4JVC34.js";import{a as m,e as M}from"./chunk-LWYIGRHR.js";import{execFileSync as ln}from"child_process";import{closeSync as pn,existsSync as E,mkdirSync as ie,mkdtempSync as cn,openSync as gn,readFileSync as dn,renameSync as $,rmSync as B,writeFileSync as ae}from"fs";import{basename as S,dirname as d,extname as mn,join as g}from"path";import{execFileSync as ge}from"child_process";import{existsSync as de,readdirSync as A}from"fs";import{extname as _,join as T}from"path";var me=new Set([".git",".hg",".svn",".idea",".vscode","node_modules","vendor","dist","build","target","bin","obj",".dart_tool",".gradle",".next",".venv","venv","__pycache__"]),fe=[{language:"typescript",files:["tsconfig.json","tsconfig.base.json"],extensions:[".ts",".tsx",".mts",".cts"]},{language:"rust",files:["Cargo.toml"],extensions:[".rs"]},{language:"go",files:["go.mod"],extensions:[".go"]},{language:"java",files:["pom.xml","build.gradle","build.gradle.kts"],extensions:[".java"]},{language:"kotlin",files:["build.gradle.kts"],extensions:[".kt",".kts"]},{language:"scala",files:["build.sbt"],extensions:[".scala"]},{language:"python",files:["pyproject.toml","setup.py","setup.cfg","Pipfile"],extensions:[".py",".pyi"]},{language:"ruby",files:["Gemfile"],extensions:[".rb"]},{language:"cpp",files:["compile_commands.json","CMakeLists.txt","Makefile"],extensions:[".cc",".cpp",".cxx",".hpp",".hh",".hxx"]},{language:"c",files:["compile_commands.json","CMakeLists.txt","Makefile"],extensions:[".c",".h"]},{language:"csharp",globs:["*.csproj","*.sln"],extensions:[".cs"]},{language:"vb",globs:["*.vbproj"],extensions:[".vb"]},{language:"dart",files:["pubspec.yaml"],extensions:[".dart"]},{language:"php",files:["composer.json"],extensions:[".php"]},{language:"javascript",files:["package.json"],extensions:[".js",".jsx",".mjs",".cjs"]}];function U(e){let n=[],t=he(e),r=Se(e);for(let i of fe){if(xe(e,i.files)){n.push(i.language);continue}if(ye(t,i.globs)){n.push(i.language);continue}ve(r,i.extensions)&&n.push(i.language)}return n.includes("typescript")&&F(n,"javascript"),n.includes("cpp")&&!r.has(".c")&&F(n,"c"),n}function he(e){try{return A(e)}catch{return[]}}function xe(e,n){return n?.length?n.some(t=>de(T(e,t))):!1}function ye(e,n){return n?.length?e.some(t=>n.some(r=>be(t,r))):!1}function be(e,n){if(n==="*")return!0;if(!n.includes("*"))return e===n;let[t,r]=n.split("*");return e.startsWith(t??"")&&e.endsWith(r??"")}function Se(e){let n=Pe(e);if(n)return n;let t=new Set,r=[e];for(;r.length>0;){let i=r.pop();if(!i)continue;let a;try{a=A(i,{withFileTypes:!0})}catch{continue}for(let s of a){if(s.name.startsWith(".")&&!s.name.endsWith("proj")&&!s.name.endsWith("sln")&&s.isDirectory())continue;let o=T(i,s.name);if(s.isDirectory()){me.has(s.name)||r.push(o);continue}let c=_(s.name).toLowerCase();c&&t.add(c)}}return t}function Pe(e){try{let n=ge("git",["-C",e,"ls-files","-co","--exclude-standard","--","."],{encoding:"utf-8",maxBuffer:26214400,stdio:["ignore","pipe","ignore"]}),t=new Set;for(let r of n.split(`
2
2
  `)){if(!r)continue;let i=_(r).toLowerCase();i&&t.add(i)}return t}catch{return null}}function ve(e,n){return n?.length?n.some(t=>e.has(t)):!1}function F(e,n){let t=e.indexOf(n);t!==-1&&e.splice(t,1)}import{existsSync as W,readdirSync as Ie}from"fs";import{join as v}from"path";var ke={typescript:{language:"typescript",indexerBinary:"scip-typescript",checkCommand:"npx scip-typescript --version",indexArgs:({outputPath:e,pnpmWorkspaces:n,indexerBinary:t})=>{let r=["index","--infer-tsconfig","--output",e,"--no-progress-bar"];return n&&r.splice(1,0,"--pnpm-workspaces"),{binary:t,args:r}},markerFiles:["tsconfig.json"],installMethods:[{label:"npm",prerequisite:"npm",binary:"npm",args:["install","-g","@sourcegraph/scip-typescript"]}],installUrl:"https://github.com/sourcegraph/scip-typescript",bundledNpmPackage:"@sourcegraph/scip-typescript"},javascript:{language:"javascript",indexerBinary:"scip-typescript",checkCommand:"npx scip-typescript --version",indexArgs:({outputPath:e,indexerBinary:n})=>({binary:n,args:["index","--infer-tsconfig","--output",e,"--no-progress-bar"]}),markerFiles:["package.json"],installMethods:[{label:"npm",prerequisite:"npm",binary:"npm",args:["install","-g","@sourcegraph/scip-typescript"]}],installUrl:"https://github.com/sourcegraph/scip-typescript",bundledNpmPackage:"@sourcegraph/scip-typescript"},java:{language:"java",indexerBinary:"scip-java",checkCommand:"scip-java --version",indexArgs:({outputPath:e})=>({binary:"scip-java",args:["index","--output",e]}),markerFiles:["pom.xml","build.gradle"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-java/releases"},scala:{language:"scala",indexerBinary:"scip-java",checkCommand:"scip-java --version",indexArgs:({outputPath:e})=>({binary:"scip-java",args:["index","--output",e]}),markerFiles:["build.sbt"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-java/releases"},kotlin:{language:"kotlin",indexerBinary:"scip-java",checkCommand:"scip-java --version",indexArgs:({outputPath:e})=>({binary:"scip-java",args:["index","--output",e]}),markerFiles:["build.gradle.kts"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-java/releases"},rust:{language:"rust",indexerBinary:"rust-analyzer",checkCommand:"rust-analyzer --version",indexArgs:({outputPath:e})=>({binary:"rust-analyzer",args:["scip",".","--output",e]}),markerFiles:["Cargo.toml"],installMethods:[{label:"rustup",prerequisite:"rustup",binary:"rustup",args:["component","add","rust-analyzer"]}],installUrl:"https://github.com/rust-lang/rust-analyzer"},python:{language:"python",indexerBinary:"scip-python-plus",binaryAliases:["scip-python"],checkCommand:"scip-python-plus --version",indexArgs:({outputPath:e,indexerBinary:n})=>({binary:n,args:["index","--output",e,"--project-name","project"]}),markerFiles:["pyproject.toml","setup.py"],installMethods:[{label:"npm",prerequisite:"npm",binary:"npm",args:["install","-g","scip-python-plus"]}],installUrl:"https://github.com/PlunderStruck/scip-python",bundledNpmPackage:"scip-python-plus"},ruby:{language:"ruby",indexerBinary:"scip-ruby",checkCommand:"scip-ruby --version",indexArgs:({indexerBinary:e})=>({binary:e,args:["--dir","."]}),defaultOutputPath:"index.scip",markerFiles:["Gemfile"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-ruby/releases"},go:{language:"go",indexerBinary:"scip-go",checkCommand:"scip-go --version",indexArgs:({outputPath:e})=>({binary:"scip-go",args:["--output",e]}),markerFiles:["go.mod"],installMethods:[{label:"go install",prerequisite:"go",binary:"go",args:["install","github.com/sourcegraph/scip-go@latest"]}],installUrl:"https://github.com/sourcegraph/scip-go"},cpp:{language:"cpp",indexerBinary:"scip-clang",checkCommand:"scip-clang --version",indexArgs:({outputPath:e})=>({binary:"scip-clang",args:["--compdb-path","compile_commands.json","--index-output-path",e]}),markerFiles:["CMakeLists.txt","Makefile"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-clang/releases"},c:{language:"c",indexerBinary:"scip-clang",checkCommand:"scip-clang --version",indexArgs:({outputPath:e})=>({binary:"scip-clang",args:["--compdb-path","compile_commands.json","--index-output-path",e]}),markerFiles:["CMakeLists.txt","Makefile"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-clang/releases"},csharp:{language:"csharp",indexerBinary:"scip-dotnet",checkCommand:"scip-dotnet --version",indexArgs:({projectRoot:e,outputPath:n})=>({binary:"scip-dotnet",args:["index",q(e,[".sln",".csproj"])??e,"--output",n,"--working-directory",e]}),markerFiles:["*.csproj","*.sln"],installMethods:[{label:"dotnet",prerequisite:"dotnet",binary:"dotnet",args:["tool","install","--global","scip-dotnet"]}],installUrl:"https://github.com/sourcegraph/scip-dotnet/releases"},vb:{language:"vb",indexerBinary:"scip-dotnet",checkCommand:"scip-dotnet --version",indexArgs:({projectRoot:e,outputPath:n})=>({binary:"scip-dotnet",args:["index",q(e,[".sln",".vbproj"])??e,"--output",n,"--working-directory",e]}),markerFiles:["*.vbproj","*.sln"],installMethods:[{label:"dotnet",prerequisite:"dotnet",binary:"dotnet",args:["tool","install","--global","scip-dotnet"]}],installUrl:"https://github.com/sourcegraph/scip-dotnet/releases"},dart:{language:"dart",indexerBinary:"scip-dart",checkCommand:"scip-dart --version",indexArgs:({indexerBinary:e,outputPath:n})=>({binary:e,args:["--output",n]}),markerFiles:["pubspec.yaml"],installMethods:[{label:"dart pub",prerequisite:"dart",binary:"dart",args:["pub","global","activate","scip_dart"]}],installUrl:"https://github.com/Workiva/scip-dart/releases"},php:{language:"php",indexerBinary:"scip-php",projectLocalBinaries:["vendor/davidrjenni/scip-php/bin/scip-php","vendor/bin/scip-php"],checkCommand:"scip-php --version",indexArgs:({projectRoot:e,indexerBinary:n})=>{let t=v(e,"vendor","bin","scip-php"),r=v(e,"vendor","davidrjenni","scip-php","bin","scip-php");return{binary:"php",args:["-d","error_reporting=E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED",W(r)?r:W(t)?t:n]}},defaultOutputPath:"index.scip",markerFiles:["composer.json"],installMethods:[],installUrl:"https://github.com/davidrjenni/scip-php/releases"}};function z(e){return ke[e]}function q(e,n){let t;try{t=Ie(e)}catch{return null}for(let r of t)if(n.some(i=>r.endsWith(i)))return v(e,r);return null}import{readFileSync as Re,writeFileSync as De}from"fs";import{create as I}from"@bufbuild/protobuf";import{deserializeSCIP as Ce,serializeSCIP as je,DocumentSchema as Oe,IndexSchema as Le,SymbolInformationSchema as we}from"@c4312/scip";function Ee(e){if(e.length===0)throw new Error("Cannot merge zero SCIP indexes");if(e.length===1)return e[0];let n=$e(e),t=Be(e.flatMap(i=>i.documents??[])),r=G(e.flatMap(i=>i.externalSymbols??[]));return I(Le,{metadata:n,documents:t,externalSymbols:r})}function J(e,n){if(e.length===0)throw new Error("Cannot merge zero SCIP files");let t=e.map(i=>Ce(Re(i))),r=Ee(t);return De(n,Buffer.from(je(r))),{documentCount:r.documents.length,externalSymbolCount:r.externalSymbols.length,inputCount:e.length}}function $e(e){let n=e[0]?.metadata;if(!n)return;let t=n.projectRoot;for(let r of e.slice(1)){let i=r.metadata?.projectRoot;if(t&&i&&i!==t)throw new Error(`Cannot merge SCIP indexes with different project roots: ${t} vs ${i}`)}return n}function Be(e){let n=new Map;for(let t of e){let r=n.get(t.relativePath);if(!r){n.set(t.relativePath,t);continue}n.set(t.relativePath,I(Oe,{language:r.language||t.language,relativePath:r.relativePath||t.relativePath,occurrences:[...r.occurrences,...t.occurrences],symbols:G([...r.symbols,...t.symbols]),text:Ne(r.text,t.text),positionEncoding:r.positionEncoding||t.positionEncoding}))}return[...n.values()]}function G(e){let n=new Map;for(let t of e){let r=n.get(t.symbol);if(!r){n.set(t.symbol,t);continue}n.set(t.symbol,I(we,{symbol:r.symbol,documentation:Fe([...r.documentation,...t.documentation]),relationships:Me([...r.relationships,...t.relationships]),kind:r.kind||t.kind,displayName:r.displayName||t.displayName,enclosingSymbol:r.enclosingSymbol||t.enclosingSymbol,signatureDocumentation:r.signatureDocumentation??t.signatureDocumentation}))}return[...n.values()]}function Me(e){let n=new Set,t=[];for(let r of e){let i=[r.symbol,r.isReference?"1":"0",r.isImplementation?"1":"0",r.isTypeDefinition?"1":"0",r.isDefinition?"1":"0"].join("|");n.has(i)||(n.add(i),t.push(r))}return t}function Ne(e,n){return e?n?e.length>=n.length?e:n:e:n}function Fe(e){return[...new Set(e)]}import{readFileSync as Ae,writeFileSync as _e}from"fs";import{create as H}from"@bufbuild/protobuf";import{deserializeSCIP as Te,DocumentSchema as Ue,IndexSchema as We,serializeSCIP as qe,SymbolRole as ze}from"@c4312/scip";function X(e){let n;try{n=Te(Ae(e))}catch{return{removedDefinitionOccurrences:0,touchedDocuments:0}}let t=Je(n);return t.removedDefinitionOccurrences>0&&_e(e,Buffer.from(qe(t.index))),{removedDefinitionOccurrences:t.removedDefinitionOccurrences,touchedDocuments:t.touchedDocuments}}function Je(e){let n=new Set;for(let a of e.documents)for(let s of a.symbols)s.symbol&&n.add(s.symbol);for(let a of e.externalSymbols)a.symbol&&n.add(a.symbol);let t=0,r=0,i=[];for(let a of e.documents){let s=a.occurrences.filter(o=>(o.symbolRoles&ze.Definition)===0||n.has(o.symbol)?!0:(t+=1,!1));if(s.length===a.occurrences.length){i.push(a);continue}r+=1,i.push(H(Ue,{language:a.language,relativePath:a.relativePath,occurrences:s,symbols:a.symbols,text:a.text,positionEncoding:a.positionEncoding}))}return{index:t===0?e:H(We,{metadata:e.metadata,documents:i,externalSymbols:e.externalSymbols}),removedDefinitionOccurrences:t,touchedDocuments:r}}import{execFile as Ge}from"child_process";import{existsSync as h,renameSync as R,rmSync as D}from"fs";import{cpus as He}from"os";import{join as Q}from"path";function Xe(e,n,t){if(!e.defaultOutputPath)return;let r=Q(n,e.defaultOutputPath);t!==r&&h(r)&&R(r,t)}function Qe(e,n,t){if(!e.defaultOutputPath)return null;let r=Q(n,e.defaultOutputPath);if(r===t)return null;let i=`${t}.default-output-backup`;return D(i,{force:!0}),h(r)?(R(r,i),{defaultOutputPath:r,backupPath:i}):{defaultOutputPath:r,backupPath:null}}function Ke(e){e&&(D(e.defaultOutputPath,{force:!0}),e.backupPath&&h(e.backupPath)&&R(e.backupPath,e.defaultOutputPath))}function Ve(e,n){if(e<=1)return 1;let t=Number(process.env.SCIP_QUERY_INDEXER_CONCURRENCY??0),r=Number.isFinite(n)&&n&&n>0?n:Number.isFinite(t)&&t>0?t:Math.min(2,Math.max(1,He().length-1));return Math.max(1,Math.min(e,Math.floor(r)))}async function K(e,n,t,r){let i=e.filter(u=>u.config.defaultOutputPath),a=e.filter(u=>!u.config.defaultOutputPath),s=[],o=Ve(a.length,r),c=await Ze(a,o,u=>k(u,n,t));if(o>1){let u=new Map;for(let p of c.filter(l=>l.skipped)){let l=a.find(f=>f.language===p.language);l&&(t(`Retrying ${l.language} indexer serially after parallel failure...`),u.set(l.language,await k(l,n,t)))}s.push(...c.map(p=>u.get(p.language)??p))}else s.push(...c);for(let u of i)s.push(await k(u,n,t));return s.sort((u,p)=>e.findIndex(l=>l.language===u.language)-e.findIndex(l=>l.language===p.language))}async function k(e,n,t){t(`Indexing ${e.language} with ${e.resolvedBinary}...`),D(e.scipPath,{force:!0});let r=Qe(e.config,n,e.scipPath);try{await Ye(e.binary,e.args,{cwd:n,env:e.env,maxBuffer:50*1024*1024}),Xe(e.config,n,e.scipPath)}catch(i){let a=i instanceof Error?i.message:String(i),s=`${e.resolvedBinary} indexer failed: ${a.split(`
3
3
  `)[0]}`;return t(`Skipping ${e.language}: ${s}`),{language:e.language,scipPath:e.scipPath,skipped:{language:e.language,reason:s}}}finally{Ke(r)}if(!h(e.scipPath)){let i=`${e.resolvedBinary} indexer completed but did not produce ${e.scipPath}`;return t(`Skipping ${e.language}: ${i}`),{language:e.language,scipPath:e.scipPath,skipped:{language:e.language,reason:i}}}return{language:e.language,scipPath:e.scipPath}}function Ye(e,n,t){return new Promise((r,i)=>{Ge(e,[...n],t,a=>{a?i(a):r()})})}async function Ze(e,n,t){if(e.length===0)return[];let r=new Array(e.length),i=0,a=Math.max(1,Math.min(e.length,n)),s=Array.from({length:a},async()=>{for(;i<e.length;){let o=i++;r[o]=await t(e[o])}});return await Promise.all(s),r}import{execFileSync as j}from"child_process";import{existsSync as C,readFileSync as en}from"fs";import{createRequire as nn}from"module";import{platform as tn}from"os";import{dirname as V,join as x}from"path";var rn=nn(import.meta.url);function O(e){return[e.indexerBinary,...e.binaryAliases??[]]}function L(e){let n=O(e);return n.length===1?n[0]:n.join(" or ")}function y(e){for(let n of O(e))if(m(n))return n;return sn(e)}function Y(e){return y(e)!==null||an(e)}function an(e){return Z(e)!==null}function sn(e){let n=Z(e);if(!n)return null;let r=JSON.parse(en(n,"utf8")).bin;if(!r)return null;if(typeof r=="string")return x(V(n),r);for(let i of O(e)){let a=r[i];if(a)return x(V(n),a)}return null}function Z(e){if(!e.bundledNpmPackage)return null;try{return rn.resolve(`${e.bundledNpmPackage}/package.json`)}catch{return null}}function ee(e,n){for(let t of e.projectLocalBinaries??[]){let r=x(n,t);if(C(r))return r}return null}function ne(e,n=process.env,t=e.indexerBinary){if(e.indexerBinary!=="scip-dotnet"||re(t,n))return n;let r=on(t,n);return r?{...n,DOTNET_ROOT:r}:n}function te(e,n){let t=e.installMethods,r=L(e);if(!t?.length)return n(`No auto-install method available for ${r}.`),e.installUrl&&n(`Install manually from: ${e.installUrl}`),!1;for(let i of t)if(m(i.prerequisite)){n(`Installing ${r} via ${i.label}...`);try{j(i.binary,i.args,{stdio:"inherit",timeout:3e5,env:process.env});let a=y(e);if(a){let s=a===e.indexerBinary?"":` (using ${a})`;return n(`Successfully installed ${r} via ${i.label}${s}`),!0}n(`${i.label} command completed but ${r} was not found on PATH`)}catch(a){let s=a instanceof Error?a.message:String(a);n(`${i.label} install failed: ${s}`)}}return n(`Could not auto-install ${r}.`),e.installUrl&&n(`Install manually from: ${e.installUrl}`),!1}function on(e,n){for(let t of un(n))if(re(e,{...n,DOTNET_ROOT:t}))return t;return null}function un(e){let n=[],t=e.DOTNET_ROOT;if(t&&C(t)&&n.push(t),tn()==="darwin"&&m("brew"))try{let r=j("brew",["--prefix","dotnet@9"],{stdio:"pipe",env:e}).toString().trim(),i=x(r,"libexec");C(i)&&!n.includes(i)&&n.push(i)}catch{}return n}function re(e,n){try{return j(e,["--version"],{stdio:"pipe",env:n}),!0}catch{return!1}}async function se(e){let{projectRoot:n,maxHeapMb:t=8192,onStatus:r=console.log,skipAutoInstall:i=!1}=e,a=fn(e),s=Date.now();ie(d(a.outputScip),{recursive:!0}),ie(d(a.outputDb),{recursive:!0});let o=e.languages??U(n);if(o.length===0)throw new Error("No supported languages detected in this project. Looked for: tsconfig.json, Cargo.toml, go.mod, pyproject.toml, etc.");r(`Detected languages: ${o.join(", ")}`);let c=wn(n,o,{pnpmWorkspaces:e.pnpmWorkspaces}),u=On(g(d(a.outputDb),"index.lock")),p=null;try{let l=hn({opts:e,paths:a,languages:o,fingerprint:c,start:s,onStatus:r});if(l)return l;Pn(i,r);let f=xn(a);return p=f.runDir,await yn({opts:e,languages:o,projectRoot:n,paths:a,tempPaths:f,fingerprint:c,start:s,maxHeapMb:t,skipAutoInstall:i,onStatus:r})}finally{p&&B(p,{recursive:!0,force:!0}),u()}}function fn(e){let n=e.outputScip??g(e.projectRoot,"index.scip"),t=e.outputDb??g(e.projectRoot,"index.db");return{outputScip:n,outputDb:t,metaPath:g(d(t),"meta.json")}}function hn(e){if(e.opts.skipIfUnchanged===!1||!E(e.paths.outputScip)||!E(e.paths.outputDb)||!En(e.paths.metaPath,e.fingerprint))return null;P({projectRoot:e.opts.projectRoot,dbPath:e.paths.outputDb,onStatus:e.onStatus});let n=Date.now()-e.start;return e.onStatus(`Index unchanged; reused existing SQLite index in ${(n/1e3).toFixed(1)}s`),{languages:e.languages,indexPath:e.paths.outputScip,dbPath:e.paths.outputDb,durationMs:n,reused:!0,skipped:[]}}function xn(e){let n=cn(g(d(e.outputDb),"reindex-"));return{runDir:n,tempOutputScip:g(n,S(e.outputScip)),tempOutputDb:g(n,S(e.outputDb)),tempMetaPath:g(n,S(e.metaPath))}}async function yn(e){let n={...process.env,NODE_OPTIONS:`--max-old-space-size=${e.maxHeapMb}`},{indexedOutputs:t,skippedLanguages:r}=await bn(e,n);Sn(e,n,t,r);let i=Date.now()-e.start;return e.onStatus(`Done in ${(i/1e3).toFixed(1)}s`),{languages:t.map(a=>a.language),indexPath:e.paths.outputScip,dbPath:e.paths.outputDb,durationMs:i,reused:!1,skipped:r}}async function bn(e,n){let{preparedRuns:t,skippedLanguages:r}=vn({languages:e.languages,tempOutputScip:e.tempPaths.tempOutputScip,projectRoot:e.projectRoot,env:n,skipAutoInstall:e.skipAutoInstall,pnpmWorkspaces:e.opts.pnpmWorkspaces,onStatus:e.onStatus}),i=await K(t,e.projectRoot,e.onStatus,e.opts.indexerConcurrency),{indexedOutputs:a}=kn(i,r);return Rn(a,r,e.languages,e.opts.allowPartial,e.onStatus),{indexedOutputs:a,skippedLanguages:r}}function Sn(e,n,t,r){Dn(t,e.tempPaths.tempOutputScip,e.onStatus),Cn(e.tempPaths.tempOutputScip,e.tempPaths.tempOutputDb,n,e.onStatus),P({projectRoot:e.projectRoot,dbPath:e.tempPaths.tempOutputDb,onStatus:e.onStatus}),$n(e.tempPaths.tempMetaPath,{version:2,status:r.length===0?"complete":"partial",updatedAt:new Date().toISOString(),fingerprint:e.fingerprint,requestedLanguages:e.languages,indexedLanguages:t.map(i=>i.language),skipped:[...r]}),Ln({tempOutputScip:e.tempPaths.tempOutputScip,tempOutputDb:e.tempPaths.tempOutputDb,tempMetaPath:e.tempPaths.tempMetaPath,outputScip:e.paths.outputScip,outputDb:e.paths.outputDb,metaPath:e.paths.metaPath})}function Pn(e,n){if(!m("scip")){if(e)throw new Error(`The scip CLI is required but not found on PATH.
4
4
  Install from: https://github.com/sourcegraph/scip/releases`);if(n("scip CLI not found on PATH. Attempting auto-install..."),!M(n))throw new Error(`The scip CLI is required but could not be installed.
package/dist/reindex.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as f,e as L}from"./chunk-LWYIGRHR.js";import{a as Z}from"./chunk-TKDJQ2WD.js";import{a as Y,b as Q}from"./chunk-KJ6CW6EK.js";import"./chunk-NHDPYW7O.js";import"./chunk-NN3O7TPH.js";import{execFileSync as nr}from"child_process";import{closeSync as tr,existsSync as q,mkdirSync as $e,mkdtempSync as rr,openSync as ir,readFileSync as or,renameSync as K,rmSync as X,writeFileSync as Be}from"fs";import{basename as C,dirname as b,extname as sr,join as m}from"path";import We from"better-sqlite3";import{execFileSync as He}from"child_process";import{existsSync as Je,readdirSync as ze,readFileSync as Ge}from"fs";import{extname as S,join as ee}from"path";function y(e){let n=new Set((e.extensions??Y).map(o=>o.toLowerCase()));if(n.size===0)return{scanned:0,inserted:0,existing:0};if(!Je(e.dbPath))throw new Error(`SCIP SQLite database not found at ${e.dbPath}`);let t=Z(e.projectRoot),r=qe(e.projectRoot,n).filter(o=>!t.isIgnored(o)),i=new We(e.dbPath);try{let o=Xe(i,r),s=i.prepare(`INSERT OR IGNORE INTO documents (language, relative_path, position_encoding, text)
1
+ import{a as f,e as L}from"./chunk-LWYIGRHR.js";import{a as Z}from"./chunk-TKDJQ2WD.js";import{a as Y,b as Q}from"./chunk-PBGTMPJ7.js";import"./chunk-NN3O7TPH.js";import"./chunk-VDZL45XI.js";import{execFileSync as nr}from"child_process";import{closeSync as tr,existsSync as q,mkdirSync as $e,mkdtempSync as rr,openSync as ir,readFileSync as or,renameSync as K,rmSync as X,writeFileSync as Be}from"fs";import{basename as C,dirname as b,extname as sr,join as m}from"path";import We from"better-sqlite3";import{execFileSync as He}from"child_process";import{existsSync as Je,readdirSync as ze,readFileSync as Ge}from"fs";import{extname as S,join as ee}from"path";function y(e){let n=new Set((e.extensions??Y).map(o=>o.toLowerCase()));if(n.size===0)return{scanned:0,inserted:0,existing:0};if(!Je(e.dbPath))throw new Error(`SCIP SQLite database not found at ${e.dbPath}`);let t=Z(e.projectRoot),r=qe(e.projectRoot,n).filter(o=>!t.isIgnored(o)),i=new We(e.dbPath);try{let o=Xe(i,r),s=i.prepare(`INSERT OR IGNORE INTO documents (language, relative_path, position_encoding, text)
2
2
  VALUES (?, ?, NULL, ?)`),u=i.transaction(g=>{let l=0;for(let p of g){if(o.has(p))continue;let d=Ge(ee(e.projectRoot,p),"utf-8"),Ue=s.run(Ye(p),p,d);l+=Number(Ue.changes)}return l})(r),c={scanned:r.length,inserted:u,existing:r.length-u};return e.onStatus?.(`Augmented SQLite documents with ${u} auxiliary source file${u===1?"":"s"} (${c.existing} already present).`),c}finally{i.close()}}function qe(e,n){let t=Ke(e,n);if(t)return t;let r=[],i=o=>{let s=o?ee(e,o):e,a;try{a=ze(s,{withFileTypes:!0})}catch{return}for(let u of a){if(Q.has(u.name))continue;let c=o?`${o}/${u.name}`:u.name;if(u.isDirectory()){i(c);continue}n.has(S(u.name).toLowerCase())&&r.push(c)}};return i(""),r.sort()}function Ke(e,n){try{return He("git",["-C",e,"ls-files","-co","--exclude-standard","--","."],{encoding:"utf-8",maxBuffer:26214400,stdio:["ignore","pipe","ignore"]}).split(`
3
3
  `).filter(r=>r&&n.has(S(r).toLowerCase())).sort()}catch{return null}}function Xe(e,n){let t=new Set,r=500;for(let i=0;i<n.length;i+=r){let o=n.slice(i,i+r),s=e.prepare(`SELECT relative_path FROM documents WHERE relative_path IN (${o.map(()=>"?").join(",")})`).all(...o);for(let a of s)t.add(a.relative_path)}return t}function Ye(e){return S(e).toLowerCase()===".vue"?"vue":S(e).replace(/^\./,"").toLowerCase()||"source"}import{execFileSync as Qe}from"child_process";import{existsSync as Ze,readdirSync as te}from"fs";import{extname as re,join as ie}from"path";var en=new Set([".git",".hg",".svn",".idea",".vscode","node_modules","vendor","dist","build","target","bin","obj",".dart_tool",".gradle",".next",".venv","venv","__pycache__"]),nn=[{language:"typescript",files:["tsconfig.json","tsconfig.base.json"],extensions:[".ts",".tsx",".mts",".cts"]},{language:"rust",files:["Cargo.toml"],extensions:[".rs"]},{language:"go",files:["go.mod"],extensions:[".go"]},{language:"java",files:["pom.xml","build.gradle","build.gradle.kts"],extensions:[".java"]},{language:"kotlin",files:["build.gradle.kts"],extensions:[".kt",".kts"]},{language:"scala",files:["build.sbt"],extensions:[".scala"]},{language:"python",files:["pyproject.toml","setup.py","setup.cfg","Pipfile"],extensions:[".py",".pyi"]},{language:"ruby",files:["Gemfile"],extensions:[".rb"]},{language:"cpp",files:["compile_commands.json","CMakeLists.txt","Makefile"],extensions:[".cc",".cpp",".cxx",".hpp",".hh",".hxx"]},{language:"c",files:["compile_commands.json","CMakeLists.txt","Makefile"],extensions:[".c",".h"]},{language:"csharp",globs:["*.csproj","*.sln"],extensions:[".cs"]},{language:"vb",globs:["*.vbproj"],extensions:[".vb"]},{language:"dart",files:["pubspec.yaml"],extensions:[".dart"]},{language:"php",files:["composer.json"],extensions:[".php"]},{language:"javascript",files:["package.json"],extensions:[".js",".jsx",".mjs",".cjs"]}];function w(e){let n=[],t=tn(e),r=an(e);for(let i of nn){if(rn(e,i.files)){n.push(i.language);continue}if(on(t,i.globs)){n.push(i.language);continue}cn(r,i.extensions)&&n.push(i.language)}return n.includes("typescript")&&ne(n,"javascript"),n.includes("cpp")&&!r.has(".c")&&ne(n,"c"),n}function tn(e){try{return te(e)}catch{return[]}}function rn(e,n){return n?.length?n.some(t=>Ze(ie(e,t))):!1}function on(e,n){return n?.length?e.some(t=>n.some(r=>sn(t,r))):!1}function sn(e,n){if(n==="*")return!0;if(!n.includes("*"))return e===n;let[t,r]=n.split("*");return e.startsWith(t??"")&&e.endsWith(r??"")}function an(e){let n=un(e);if(n)return n;let t=new Set,r=[e];for(;r.length>0;){let i=r.pop();if(!i)continue;let o;try{o=te(i,{withFileTypes:!0})}catch{continue}for(let s of o){if(s.name.startsWith(".")&&!s.name.endsWith("proj")&&!s.name.endsWith("sln")&&s.isDirectory())continue;let a=ie(i,s.name);if(s.isDirectory()){en.has(s.name)||r.push(a);continue}let u=re(s.name).toLowerCase();u&&t.add(u)}}return t}function un(e){try{let n=Qe("git",["-C",e,"ls-files","-co","--exclude-standard","--","."],{encoding:"utf-8",maxBuffer:26214400,stdio:["ignore","pipe","ignore"]}),t=new Set;for(let r of n.split(`
4
4
  `)){if(!r)continue;let i=re(r).toLowerCase();i&&t.add(i)}return t}catch{return null}}function cn(e,n){return n?.length?n.some(t=>e.has(t)):!1}function ne(e,n){let t=e.indexOf(n);t!==-1&&e.splice(t,1)}import{existsSync as oe,readdirSync as ln}from"fs";import{join as O}from"path";var ae={typescript:{language:"typescript",indexerBinary:"scip-typescript",checkCommand:"npx scip-typescript --version",indexArgs:({outputPath:e,pnpmWorkspaces:n,indexerBinary:t})=>{let r=["index","--infer-tsconfig","--output",e,"--no-progress-bar"];return n&&r.splice(1,0,"--pnpm-workspaces"),{binary:t,args:r}},markerFiles:["tsconfig.json"],installMethods:[{label:"npm",prerequisite:"npm",binary:"npm",args:["install","-g","@sourcegraph/scip-typescript"]}],installUrl:"https://github.com/sourcegraph/scip-typescript",bundledNpmPackage:"@sourcegraph/scip-typescript"},javascript:{language:"javascript",indexerBinary:"scip-typescript",checkCommand:"npx scip-typescript --version",indexArgs:({outputPath:e,indexerBinary:n})=>({binary:n,args:["index","--infer-tsconfig","--output",e,"--no-progress-bar"]}),markerFiles:["package.json"],installMethods:[{label:"npm",prerequisite:"npm",binary:"npm",args:["install","-g","@sourcegraph/scip-typescript"]}],installUrl:"https://github.com/sourcegraph/scip-typescript",bundledNpmPackage:"@sourcegraph/scip-typescript"},java:{language:"java",indexerBinary:"scip-java",checkCommand:"scip-java --version",indexArgs:({outputPath:e})=>({binary:"scip-java",args:["index","--output",e]}),markerFiles:["pom.xml","build.gradle"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-java/releases"},scala:{language:"scala",indexerBinary:"scip-java",checkCommand:"scip-java --version",indexArgs:({outputPath:e})=>({binary:"scip-java",args:["index","--output",e]}),markerFiles:["build.sbt"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-java/releases"},kotlin:{language:"kotlin",indexerBinary:"scip-java",checkCommand:"scip-java --version",indexArgs:({outputPath:e})=>({binary:"scip-java",args:["index","--output",e]}),markerFiles:["build.gradle.kts"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-java/releases"},rust:{language:"rust",indexerBinary:"rust-analyzer",checkCommand:"rust-analyzer --version",indexArgs:({outputPath:e})=>({binary:"rust-analyzer",args:["scip",".","--output",e]}),markerFiles:["Cargo.toml"],installMethods:[{label:"rustup",prerequisite:"rustup",binary:"rustup",args:["component","add","rust-analyzer"]}],installUrl:"https://github.com/rust-lang/rust-analyzer"},python:{language:"python",indexerBinary:"scip-python-plus",binaryAliases:["scip-python"],checkCommand:"scip-python-plus --version",indexArgs:({outputPath:e,indexerBinary:n})=>({binary:n,args:["index","--output",e,"--project-name","project"]}),markerFiles:["pyproject.toml","setup.py"],installMethods:[{label:"npm",prerequisite:"npm",binary:"npm",args:["install","-g","scip-python-plus"]}],installUrl:"https://github.com/PlunderStruck/scip-python",bundledNpmPackage:"scip-python-plus"},ruby:{language:"ruby",indexerBinary:"scip-ruby",checkCommand:"scip-ruby --version",indexArgs:({indexerBinary:e})=>({binary:e,args:["--dir","."]}),defaultOutputPath:"index.scip",markerFiles:["Gemfile"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-ruby/releases"},go:{language:"go",indexerBinary:"scip-go",checkCommand:"scip-go --version",indexArgs:({outputPath:e})=>({binary:"scip-go",args:["--output",e]}),markerFiles:["go.mod"],installMethods:[{label:"go install",prerequisite:"go",binary:"go",args:["install","github.com/sourcegraph/scip-go@latest"]}],installUrl:"https://github.com/sourcegraph/scip-go"},cpp:{language:"cpp",indexerBinary:"scip-clang",checkCommand:"scip-clang --version",indexArgs:({outputPath:e})=>({binary:"scip-clang",args:["--compdb-path","compile_commands.json","--index-output-path",e]}),markerFiles:["CMakeLists.txt","Makefile"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-clang/releases"},c:{language:"c",indexerBinary:"scip-clang",checkCommand:"scip-clang --version",indexArgs:({outputPath:e})=>({binary:"scip-clang",args:["--compdb-path","compile_commands.json","--index-output-path",e]}),markerFiles:["CMakeLists.txt","Makefile"],installMethods:[],installUrl:"https://github.com/sourcegraph/scip-clang/releases"},csharp:{language:"csharp",indexerBinary:"scip-dotnet",checkCommand:"scip-dotnet --version",indexArgs:({projectRoot:e,outputPath:n})=>({binary:"scip-dotnet",args:["index",se(e,[".sln",".csproj"])??e,"--output",n,"--working-directory",e]}),markerFiles:["*.csproj","*.sln"],installMethods:[{label:"dotnet",prerequisite:"dotnet",binary:"dotnet",args:["tool","install","--global","scip-dotnet"]}],installUrl:"https://github.com/sourcegraph/scip-dotnet/releases"},vb:{language:"vb",indexerBinary:"scip-dotnet",checkCommand:"scip-dotnet --version",indexArgs:({projectRoot:e,outputPath:n})=>({binary:"scip-dotnet",args:["index",se(e,[".sln",".vbproj"])??e,"--output",n,"--working-directory",e]}),markerFiles:["*.vbproj","*.sln"],installMethods:[{label:"dotnet",prerequisite:"dotnet",binary:"dotnet",args:["tool","install","--global","scip-dotnet"]}],installUrl:"https://github.com/sourcegraph/scip-dotnet/releases"},dart:{language:"dart",indexerBinary:"scip-dart",checkCommand:"scip-dart --version",indexArgs:({indexerBinary:e,outputPath:n})=>({binary:e,args:["--output",n]}),markerFiles:["pubspec.yaml"],installMethods:[{label:"dart pub",prerequisite:"dart",binary:"dart",args:["pub","global","activate","scip_dart"]}],installUrl:"https://github.com/Workiva/scip-dart/releases"},php:{language:"php",indexerBinary:"scip-php",projectLocalBinaries:["vendor/davidrjenni/scip-php/bin/scip-php","vendor/bin/scip-php"],checkCommand:"scip-php --version",indexArgs:({projectRoot:e,indexerBinary:n})=>{let t=O(e,"vendor","bin","scip-php"),r=O(e,"vendor","davidrjenni","scip-php","bin","scip-php");return{binary:"php",args:["-d","error_reporting=E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED",oe(r)?r:oe(t)?t:n]}},defaultOutputPath:"index.scip",markerFiles:["composer.json"],installMethods:[],installUrl:"https://github.com/davidrjenni/scip-php/releases"}};function D(e){return ae[e]}function se(e,n){let t;try{t=ln(e)}catch{return null}for(let r of t)if(n.some(i=>r.endsWith(i)))return O(e,r);return null}import{readFileSync as gn,writeFileSync as pn}from"fs";import{create as V}from"@bufbuild/protobuf";import{deserializeSCIP as dn,serializeSCIP as mn,DocumentSchema as fn,IndexSchema as hn,SymbolInformationSchema as bn}from"@c4312/scip";function ue(e){if(e.length===0)throw new Error("Cannot merge zero SCIP indexes");if(e.length===1)return e[0];let n=yn(e),t=xn(e.flatMap(i=>i.documents??[])),r=ce(e.flatMap(i=>i.externalSymbols??[]));return V(hn,{metadata:n,documents:t,externalSymbols:r})}function T(e,n){if(e.length===0)throw new Error("Cannot merge zero SCIP files");let t=e.map(i=>dn(gn(i))),r=ue(t);return pn(n,Buffer.from(mn(r))),{documentCount:r.documents.length,externalSymbolCount:r.externalSymbols.length,inputCount:e.length}}function yn(e){let n=e[0]?.metadata;if(!n)return;let t=n.projectRoot;for(let r of e.slice(1)){let i=r.metadata?.projectRoot;if(t&&i&&i!==t)throw new Error(`Cannot merge SCIP indexes with different project roots: ${t} vs ${i}`)}return n}function xn(e){let n=new Map;for(let t of e){let r=n.get(t.relativePath);if(!r){n.set(t.relativePath,t);continue}n.set(t.relativePath,V(fn,{language:r.language||t.language,relativePath:r.relativePath||t.relativePath,occurrences:[...r.occurrences,...t.occurrences],symbols:ce([...r.symbols,...t.symbols]),text:Rn(r.text,t.text),positionEncoding:r.positionEncoding||t.positionEncoding}))}return[...n.values()]}function ce(e){let n=new Map;for(let t of e){let r=n.get(t.symbol);if(!r){n.set(t.symbol,t);continue}n.set(t.symbol,V(bn,{symbol:r.symbol,documentation:vn([...r.documentation,...t.documentation]),relationships:Sn([...r.relationships,...t.relationships]),kind:r.kind||t.kind,displayName:r.displayName||t.displayName,enclosingSymbol:r.enclosingSymbol||t.enclosingSymbol,signatureDocumentation:r.signatureDocumentation??t.signatureDocumentation}))}return[...n.values()]}function Sn(e){let n=new Set,t=[];for(let r of e){let i=[r.symbol,r.isReference?"1":"0",r.isImplementation?"1":"0",r.isTypeDefinition?"1":"0",r.isDefinition?"1":"0"].join("|");n.has(i)||(n.add(i),t.push(r))}return t}function Rn(e,n){return e?n?e.length>=n.length?e:n:e:n}function vn(e){return[...new Set(e)]}import{execFileSync as kn}from"child_process";import{createHash as In}from"crypto";import{readdirSync as Pn,readFileSync as Cn}from"fs";import{join as le}from"path";function Ln(e){return(wn(e)??On(e)).filter(n=>n&&!ge(n)).sort()}function R(e){return Ln(e).map(n=>{let t=le(e,n);try{let r=Cn(t);return{path:n,size:r.byteLength,hash:In("sha256").update(r).digest("hex")}}catch{return{path:n,size:-1,hash:"unreadable"}}})}function wn(e){try{return kn("git",["-C",e,"ls-files","-co","--exclude-standard","--","."],{encoding:"utf-8",maxBuffer:50*1024*1024,stdio:["ignore","pipe","ignore"]}).split(`
package/dist/runtime.d.ts CHANGED
@@ -97,8 +97,9 @@ interface InstallSkillsResult {
97
97
  alreadyLinked: string[];
98
98
  }
99
99
  /**
100
- * Install scip-query skills into both Claude Code (~/.claude/skills/)
101
- * and Codex (~/.codex/skills/). Uses symlinks (junctions on Windows)
100
+ * Install scip-query skills into Claude Code (~/.claude/skills/),
101
+ * Codex (~/.codex/skills/), and the shared agents skill root (~/.agents/skills/).
102
+ * Uses symlinks (junctions on Windows)
102
103
  * so skills auto-update when the package updates.
103
104
  */
104
105
  declare function installSkills(opts?: {
package/dist/runtime.js CHANGED
@@ -1,3 +1,3 @@
1
- import{b as j,c as b,d as W}from"./chunk-LWYIGRHR.js";import{a as y}from"./chunk-TKDJQ2WD.js";import{readFileSync as _,writeFileSync as D,existsSync as C,mkdirSync as F}from"fs";import{join as l,resolve as w}from"path";import{createHash as L}from"crypto";import{homedir as $}from"os";var v=".scipquery.json",A={enabled:!1,debounceMs:3e4,cooldownMs:6e4,ignore:[]};function N(i){let t=l(i,v);if(!C(t))return{};try{let e=_(t,"utf-8");return JSON.parse(e)}catch{return{}}}function P(i){return{...A,...i.watch}}function O(i,t){let e=process.env.SCIP_QUERY_CACHE_DIR;if(e)return g(e);if(t?.dbPath)return g(w(i,t.dbPath));let o=process.env.XDG_CACHE_HOME||l($(),".cache"),n=L("sha256").update(w(i)).digest("hex").slice(0,12),r=l(o,"scip-query","projects",n);return g(r)}function f(i,t){let e=O(i,t);return{cacheDir:e,dbPath:l(e,"index.db"),indexPath:l(e,"index.scip"),metaPath:l(e,"meta.json")}}function M(i,t){let e=l(i,v);return C(e)||D(e,JSON.stringify({languages:t,watch:{enabled:!1,debounceMs:3e4,cooldownMs:6e4}},null,2)+`
2
- `),e}function g(i){return F(i,{recursive:!0}),i}import{watch as q}from"fs";import{existsSync as R,renameSync as I}from"fs";import{join as U,relative as H}from"path";import{fork as G}from"child_process";import X from"ignore";var m=class{projectRoot;watchConfig;indexPaths;languages;pnpmWorkspaces;onStatus;onReindexComplete;onError;status={state:"idle"};debounceTimer=null;cooldownTimer=null;dirty=!1;changedFiles=0;reindexInFlight=!1;lastReindexEnd=0;fsWatchers=[];gitignoreFilter;extraIgnore;stopped=!1;constructor(t){this.projectRoot=t.projectRoot,this.watchConfig=P(t.config),this.indexPaths=f(t.projectRoot,t.config),this.languages=t.languages,this.pnpmWorkspaces=t.config.indexer?.typescript?.pnpmWorkspaces??!1,this.onStatus=t.onStatus??(()=>{}),this.onReindexComplete=t.onReindexComplete??(()=>{}),this.onError=t.onError??(e=>console.error(e.message)),this.gitignoreFilter=y(t.projectRoot),this.extraIgnore=X(),this.watchConfig.ignore.length>0&&this.extraIgnore.add(this.watchConfig.ignore)}start(){this.stopped=!1,this.setStatus({state:"idle"});try{let t=q(this.projectRoot,{recursive:!0},(e,s)=>{s&&!this.stopped&&this.handleFileChange(s)});this.fsWatchers.push(t)}catch{this.onError(new Error("Failed to start file watcher. On Linux, you may need to increase inotify limits: sysctl -w fs.inotify.max_user_watches=524288"))}}stop(){this.stopped=!0;for(let t of this.fsWatchers)t.close();this.fsWatchers=[],this.clearDebounceTimer(),this.clearCooldownTimer(),this.setStatus({state:"idle"})}handleFileChange(t){let e=H(this.projectRoot,U(this.projectRoot,t));if(this.gitignoreFilter.isIgnored(e)||this.extraIgnore.ignores(e)||t.endsWith("index.db")||t.endsWith("index.scip")||t.endsWith("index.db.tmp")||t.endsWith(".scipquery.json"))return;if(this.changedFiles++,this.reindexInFlight){this.dirty=!0,this.setStatus({state:"indexing",startedAt:this.status.startedAt});return}if(this.status.state==="cooldown"){this.dirty=!0,this.setStatus({state:"cooldown",until:this.status.until,dirty:!0});return}this.clearDebounceTimer();let s=Date.now()+this.watchConfig.debounceMs;this.setStatus({state:"waiting",changedFiles:this.changedFiles,reindexAt:s}),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.triggerReindex()},this.watchConfig.debounceMs)}triggerReindex(){if(this.reindexInFlight||this.stopped)return;let t=Date.now()-this.lastReindexEnd;if(this.lastReindexEnd>0&&t<this.watchConfig.cooldownMs){let s=this.watchConfig.cooldownMs-t;this.dirty=!0;let o=Date.now()+s;this.setStatus({state:"cooldown",until:o,dirty:!0}),this.cooldownTimer=setTimeout(()=>{this.cooldownTimer=null,this.dirty&&!this.stopped&&(this.dirty=!1,this.triggerReindex())},s);return}this.reindexInFlight=!0,this.dirty=!1,this.changedFiles=0;let e=Date.now();this.setStatus({state:"indexing",startedAt:e}),this.runReindex().then(s=>{if(this.reindexInFlight=!1,this.lastReindexEnd=Date.now(),this.onReindexComplete(s),this.dirty&&!this.stopped){let o=Date.now()+this.watchConfig.cooldownMs;this.setStatus({state:"cooldown",until:o,dirty:!0}),this.cooldownTimer=setTimeout(()=>{this.cooldownTimer=null,this.dirty&&!this.stopped?(this.dirty=!1,this.triggerReindex()):this.setStatus({state:"idle"})},this.watchConfig.cooldownMs)}else this.setStatus({state:"idle"})}).catch(s=>{this.reindexInFlight=!1,this.lastReindexEnd=Date.now(),this.onError(s instanceof Error?s:new Error(String(s))),this.setStatus({state:"idle"})})}runReindex(){return new Promise((t,e)=>{let s=Date.now(),o=this.indexPaths.dbPath+".tmp",n=B(this.indexPaths.indexPath),r=G(new URL("./reindex-worker.js",import.meta.url).pathname,[],{env:{...process.env,SCIP_REINDEX_PROJECT_ROOT:this.projectRoot,SCIP_REINDEX_OUTPUT_SCIP:n,SCIP_REINDEX_OUTPUT_DB:o,SCIP_REINDEX_LANGUAGES:this.languages?.join(",")??"",SCIP_REINDEX_PNPM_WORKSPACES:this.pnpmWorkspaces?"1":""},stdio:"pipe"});r.on("exit",d=>{if(d===0)try{R(o)&&I(o,this.indexPaths.dbPath),R(n)&&I(n,this.indexPaths.indexPath),t(Date.now()-s)}catch(a){e(new Error(`Atomic swap failed: ${a}`))}else e(new Error(`Reindex worker exited with code ${d}`))}),r.on("error",e)})}setStatus(t){this.status=t,this.onStatus(t)}clearDebounceTimer(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}clearCooldownTimer(){this.cooldownTimer&&(clearTimeout(this.cooldownTimer),this.cooldownTimer=null)}};function B(i){return i.endsWith(".scip")?i.slice(0,-5)+".tmp.scip":i+".tmp.scip"}import{existsSync as x,mkdirSync as J,symlinkSync as V,readlinkSync as K,unlinkSync as Q}from"fs";import{join as p,dirname as T,resolve as S}from"path";import{homedir as k,platform as Y}from"os";import{fileURLToPath as z}from"url";var Z=Y()==="win32",tt=["concrete-plan","scip-explore","scip-debloat","scip-verify","scip-language-playbook"];function et(i={}){let t=i.quiet?()=>{}:console.log,e=z(import.meta.url),s=S(T(e),"..","skills"),o=[p(k(),".claude","skills"),p(k(),".codex","skills")],n={installed:[],skipped:[],alreadyLinked:[]};for(let r of o){let d=T(r);if(!x(d))continue;J(r,{recursive:!0});let a=r.includes(".codex")?"Codex":"Claude";for(let c of tt){let u=p(s,c),h=p(r,c);if(!x(u)){n.skipped.push(`${a}/${c}`);continue}if(x(h)){try{let E=K(h);if(S(E)===S(u)){n.alreadyLinked.push(`${a}/${c}`),t(` ok: ${c} \u2192 ${a} (already linked)`);continue}}catch{n.skipped.push(`${a}/${c}`),t(` skip: ${c} \u2192 ${a} (exists, not a symlink)`);continue}Q(h)}V(u,h,Z?"junction":"dir"),n.installed.push(`${a}/${c}`),t(` done: ${c} \u2192 ${a}`)}}return n}export{m as Watcher,b as getScipVersion,M as initProjectConfig,et as installSkills,j as isScipInstalled,N as loadProjectConfig,W as printScipInstallInstructions,f as resolveIndexPaths};
1
+ import{b,c as j,d as W}from"./chunk-LWYIGRHR.js";import{a as w}from"./chunk-TKDJQ2WD.js";import{readFileSync as _,writeFileSync as D,existsSync as v,mkdirSync as F}from"fs";import{join as l,resolve as C}from"path";import{createHash as L}from"crypto";import{homedir as $}from"os";var P=".scipquery.json",A={enabled:!1,debounceMs:3e4,cooldownMs:6e4,ignore:[]};function N(i){let t=l(i,P);if(!v(t))return{};try{let e=_(t,"utf-8");return JSON.parse(e)}catch{return{}}}function R(i){return{...A,...i.watch}}function O(i,t){let e=process.env.SCIP_QUERY_CACHE_DIR;if(e)return g(e);if(t?.dbPath)return g(C(i,t.dbPath));let n=process.env.XDG_CACHE_HOME||l($(),".cache"),o=L("sha256").update(C(i)).digest("hex").slice(0,12),r=l(n,"scip-query","projects",o);return g(r)}function f(i,t){let e=O(i,t);return{cacheDir:e,dbPath:l(e,"index.db"),indexPath:l(e,"index.scip"),metaPath:l(e,"meta.json")}}function M(i,t){let e=l(i,P);return v(e)||D(e,JSON.stringify({languages:t,watch:{enabled:!1,debounceMs:3e4,cooldownMs:6e4}},null,2)+`
2
+ `),e}function g(i){return F(i,{recursive:!0}),i}import{watch as q}from"fs";import{existsSync as I,renameSync as T}from"fs";import{join as U,relative as H}from"path";import{fork as G}from"child_process";import X from"ignore";var m=class{projectRoot;watchConfig;indexPaths;languages;pnpmWorkspaces;onStatus;onReindexComplete;onError;status={state:"idle"};debounceTimer=null;cooldownTimer=null;dirty=!1;changedFiles=0;reindexInFlight=!1;lastReindexEnd=0;fsWatchers=[];gitignoreFilter;extraIgnore;stopped=!1;constructor(t){this.projectRoot=t.projectRoot,this.watchConfig=R(t.config),this.indexPaths=f(t.projectRoot,t.config),this.languages=t.languages,this.pnpmWorkspaces=t.config.indexer?.typescript?.pnpmWorkspaces??!1,this.onStatus=t.onStatus??(()=>{}),this.onReindexComplete=t.onReindexComplete??(()=>{}),this.onError=t.onError??(e=>console.error(e.message)),this.gitignoreFilter=w(t.projectRoot),this.extraIgnore=X(),this.watchConfig.ignore.length>0&&this.extraIgnore.add(this.watchConfig.ignore)}start(){this.stopped=!1,this.setStatus({state:"idle"});try{let t=q(this.projectRoot,{recursive:!0},(e,s)=>{s&&!this.stopped&&this.handleFileChange(s)});this.fsWatchers.push(t)}catch{this.onError(new Error("Failed to start file watcher. On Linux, you may need to increase inotify limits: sysctl -w fs.inotify.max_user_watches=524288"))}}stop(){this.stopped=!0;for(let t of this.fsWatchers)t.close();this.fsWatchers=[],this.clearDebounceTimer(),this.clearCooldownTimer(),this.setStatus({state:"idle"})}handleFileChange(t){let e=H(this.projectRoot,U(this.projectRoot,t));if(this.gitignoreFilter.isIgnored(e)||this.extraIgnore.ignores(e)||t.endsWith("index.db")||t.endsWith("index.scip")||t.endsWith("index.db.tmp")||t.endsWith(".scipquery.json"))return;if(this.changedFiles++,this.reindexInFlight){this.dirty=!0,this.setStatus({state:"indexing",startedAt:this.status.startedAt});return}if(this.status.state==="cooldown"){this.dirty=!0,this.setStatus({state:"cooldown",until:this.status.until,dirty:!0});return}this.clearDebounceTimer();let s=Date.now()+this.watchConfig.debounceMs;this.setStatus({state:"waiting",changedFiles:this.changedFiles,reindexAt:s}),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.triggerReindex()},this.watchConfig.debounceMs)}triggerReindex(){if(this.reindexInFlight||this.stopped)return;let t=Date.now()-this.lastReindexEnd;if(this.lastReindexEnd>0&&t<this.watchConfig.cooldownMs){let s=this.watchConfig.cooldownMs-t;this.dirty=!0;let n=Date.now()+s;this.setStatus({state:"cooldown",until:n,dirty:!0}),this.cooldownTimer=setTimeout(()=>{this.cooldownTimer=null,this.dirty&&!this.stopped&&(this.dirty=!1,this.triggerReindex())},s);return}this.reindexInFlight=!0,this.dirty=!1,this.changedFiles=0;let e=Date.now();this.setStatus({state:"indexing",startedAt:e}),this.runReindex().then(s=>{if(this.reindexInFlight=!1,this.lastReindexEnd=Date.now(),this.onReindexComplete(s),this.dirty&&!this.stopped){let n=Date.now()+this.watchConfig.cooldownMs;this.setStatus({state:"cooldown",until:n,dirty:!0}),this.cooldownTimer=setTimeout(()=>{this.cooldownTimer=null,this.dirty&&!this.stopped?(this.dirty=!1,this.triggerReindex()):this.setStatus({state:"idle"})},this.watchConfig.cooldownMs)}else this.setStatus({state:"idle"})}).catch(s=>{this.reindexInFlight=!1,this.lastReindexEnd=Date.now(),this.onError(s instanceof Error?s:new Error(String(s))),this.setStatus({state:"idle"})})}runReindex(){return new Promise((t,e)=>{let s=Date.now(),n=this.indexPaths.dbPath+".tmp",o=B(this.indexPaths.indexPath),r=G(new URL("./reindex-worker.js",import.meta.url).pathname,[],{env:{...process.env,SCIP_REINDEX_PROJECT_ROOT:this.projectRoot,SCIP_REINDEX_OUTPUT_SCIP:o,SCIP_REINDEX_OUTPUT_DB:n,SCIP_REINDEX_LANGUAGES:this.languages?.join(",")??"",SCIP_REINDEX_PNPM_WORKSPACES:this.pnpmWorkspaces?"1":""},stdio:"pipe"});r.on("exit",h=>{if(h===0)try{I(n)&&T(n,this.indexPaths.dbPath),I(o)&&T(o,this.indexPaths.indexPath),t(Date.now()-s)}catch(a){e(new Error(`Atomic swap failed: ${a}`))}else e(new Error(`Reindex worker exited with code ${h}`))}),r.on("error",e)})}setStatus(t){this.status=t,this.onStatus(t)}clearDebounceTimer(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}clearCooldownTimer(){this.cooldownTimer&&(clearTimeout(this.cooldownTimer),this.cooldownTimer=null)}};function B(i){return i.endsWith(".scip")?i.slice(0,-5)+".tmp.scip":i+".tmp.scip"}import{existsSync as x,mkdirSync as J,symlinkSync as V,readlinkSync as K,unlinkSync as Q}from"fs";import{join as d,dirname as k,resolve as S}from"path";import{homedir as y,platform as Y}from"os";import{fileURLToPath as z}from"url";var Z=Y()==="win32",tt=["concrete-plan","scip-ai-cleanup","scip-explore","scip-debloat","scip-doc-reconcile","scip-maintainability","scip-verify","scip-language-playbook"];function et(i={}){let t=i.quiet?()=>{}:console.log,e=z(import.meta.url),s=S(k(e),"..","skills"),n=[d(y(),".claude","skills"),d(y(),".codex","skills"),d(y(),".agents","skills")],o={installed:[],skipped:[],alreadyLinked:[]};for(let r of n){let h=k(r);if(!x(h))continue;J(r,{recursive:!0});let a=it(r);for(let c of tt){let u=d(s,c),p=d(r,c);if(!x(u)){o.skipped.push(`${a}/${c}`);continue}if(x(p)){try{let E=K(p);if(S(E)===S(u)){o.alreadyLinked.push(`${a}/${c}`),t(` ok: ${c} \u2192 ${a} (already linked)`);continue}}catch{o.skipped.push(`${a}/${c}`),t(` skip: ${c} \u2192 ${a} (exists, not a symlink)`);continue}Q(p)}V(u,p,Z?"junction":"dir"),o.installed.push(`${a}/${c}`),t(` done: ${c} \u2192 ${a}`)}}return o}function it(i){return i.includes(".codex")?"Codex":i.includes(".agents")?"Agents":"Claude"}export{m as Watcher,j as getScipVersion,M as initProjectConfig,et as installSkills,b as isScipInstalled,N as loadProjectConfig,W as printScipInstallInstructions,f as resolveIndexPaths};
3
3
  //# sourceMappingURL=runtime.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scip-query",
3
- "version": "0.7.2",
3
+ "version": "0.8.1",
4
4
  "description": "Language-agnostic code intelligence CLI powered by SCIP indexes",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,6 +43,14 @@
43
43
  "import": "./dist/queries/change-surface.js",
44
44
  "types": "./dist/queries/change-surface.d.ts"
45
45
  },
46
+ "./queries/cleanup-plan": {
47
+ "import": "./dist/queries/cleanup-plan.js",
48
+ "types": "./dist/queries/cleanup-plan.d.ts"
49
+ },
50
+ "./queries/co-change": {
51
+ "import": "./dist/queries/co-change.js",
52
+ "types": "./dist/queries/co-change.d.ts"
53
+ },
46
54
  "./queries/code": {
47
55
  "import": "./dist/queries/code.js",
48
56
  "types": "./dist/queries/code.d.ts"
@@ -83,10 +91,18 @@
83
91
  "import": "./dist/queries/deps.js",
84
92
  "types": "./dist/queries/deps.d.ts"
85
93
  },
94
+ "./queries/diff-gate": {
95
+ "import": "./dist/queries/diff-gate.js",
96
+ "types": "./dist/queries/diff-gate.d.ts"
97
+ },
86
98
  "./queries/diff-impact": {
87
99
  "import": "./dist/queries/diff-impact.js",
88
100
  "types": "./dist/queries/diff-impact.d.ts"
89
101
  },
102
+ "./queries/doc-drift": {
103
+ "import": "./dist/queries/doc-drift.js",
104
+ "types": "./dist/queries/doc-drift.d.ts"
105
+ },
90
106
  "./queries/drift": {
91
107
  "import": "./dist/queries/drift.js",
92
108
  "types": "./dist/queries/drift.d.ts"
@@ -143,6 +159,14 @@
143
159
  "import": "./dist/queries/passthrough-candidates.js",
144
160
  "types": "./dist/queries/passthrough-candidates.d.ts"
145
161
  },
162
+ "./queries/plan-context": {
163
+ "import": "./dist/queries/plan-context.js",
164
+ "types": "./dist/queries/plan-context.d.ts"
165
+ },
166
+ "./queries/recent-duplicates": {
167
+ "import": "./dist/queries/recent-duplicates.js",
168
+ "types": "./dist/queries/recent-duplicates.d.ts"
169
+ },
146
170
  "./queries/redundant-reexports": {
147
171
  "import": "./dist/queries/redundant-reexports.js",
148
172
  "types": "./dist/queries/redundant-reexports.d.ts"
@@ -151,6 +175,10 @@
151
175
  "import": "./dist/queries/refs.js",
152
176
  "types": "./dist/queries/refs.d.ts"
153
177
  },
178
+ "./queries/self-audit": {
179
+ "import": "./dist/queries/self-audit.js",
180
+ "types": "./dist/queries/self-audit.d.ts"
181
+ },
154
182
  "./queries/similar": {
155
183
  "import": "./dist/queries/similar.js",
156
184
  "types": "./dist/queries/similar.d.ts"
@@ -195,6 +223,10 @@
195
223
  "import": "./dist/queries/trace.js",
196
224
  "types": "./dist/queries/trace.d.ts"
197
225
  },
226
+ "./queries/unused-params": {
227
+ "import": "./dist/queries/unused-params.js",
228
+ "types": "./dist/queries/unused-params.d.ts"
229
+ },
198
230
  "./queries/wrapper-candidates": {
199
231
  "import": "./dist/queries/wrapper-candidates.js",
200
232
  "types": "./dist/queries/wrapper-candidates.d.ts"
@@ -23,9 +23,39 @@ You are writing a production implementation plan as a markdown checklist. Every
23
23
 
24
24
  ---
25
25
 
26
+ ## Gather Context Fast
27
+
28
+ Start every plan with the bundled context command — it replaces a half-dozen
29
+ separate queries and adds evidence no single query has:
30
+
31
+ ```bash
32
+ scip-query plan-context <symbol-or-file>
33
+ ```
34
+
35
+ Use its sections directly in the plan:
36
+
37
+ - **DEFINITIONS / REFERENCES / CALL GRAPH / DOWNSTREAM IMPACT** — the Source
38
+ citations for your steps.
39
+ - **HISTORY** — files that usually change together with the target. If the
40
+ plan edits the target, the plan MUST either cover its co-change partners or
41
+ state why they're untouched this time. This is how plans stop causing drift.
42
+ - **CHANGE RISK** — high-risk consumers get their own verification steps.
43
+
44
+ Two pre-plan checks that prevent planning mistakes:
45
+
46
+ ```bash
47
+ scip-query doc-drift <standard.md> # is the standard this plan follows stale?
48
+ scip-query recent-duplicates # does the helper you're about to plan already exist?
49
+ ```
50
+
51
+ If `doc-drift` shows the standard's referenced code moved on without it,
52
+ updating that standard becomes step 0 of the plan. If the plan creates a new
53
+ helper, cite the `similar` / `recent-duplicates` evidence that nothing
54
+ established already does the job.
55
+
26
56
  ## Symbol Lookup Tips
27
57
 
28
- scip-query accepts partial symbol names — you don't need the full SCIP symbol path. These all work:
58
+ `scip-query` accepts partial symbol names — you don't need the full SCIP symbol path. These all work:
29
59
 
30
60
  ```bash
31
61
  scip-query code processVegaMention # just the function name
@@ -52,7 +82,7 @@ scip-query code 'src/modules/chat/chat.service.ts:100-200'
52
82
 
53
83
  **If "Symbol not found":**
54
84
  1. Try a shorter/simpler name — `login` instead of `AuthService:login`
55
- 2. Try `scip-query symbols <file>` to see what symbols exist in the file
85
+ 2. Try `scip-query outline <file>` to see what symbols exist in the file
56
86
  3. Try `scip-query trace <name>` which uses a different lookup path
57
87
  4. Use the `file:line-line` syntax for `code` if you know the location
58
88
 
@@ -67,13 +97,13 @@ This skill deliberately excludes `Grep` and `Read` from its allowed tools. This
67
97
  - Using `Read` via a subagent to browse files for discovery. Subagents must also use scip-query.
68
98
  - Spawning Explore agents that fall back to grep and file reads. If a subagent's output does not cite scip-query commands, reject its findings and re-run.
69
99
 
70
- **Instead, use scip-query (full reference at `/Users/aydansalois/Documents/GitHub/scip-query/README.md`):**
100
+ **Instead, use scip-query (full reference at `/Users/aydansalois/Documents/GitHub/scip-query/docs/COMMAND_REFERENCE.md`):**
71
101
 
72
102
  | You want to... | Use this |
73
103
  |---|---|
74
104
  | **Read source code** | `scip-query code <symbol>` (reads file, bounded to definition range) |
75
105
  | **Read source with context** | `scip-query code <symbol> -C 5` (5 extra lines above/below) |
76
- | Find a symbol / list file contents | `scip-query symbols <file>` (all symbols with line ranges + signatures) |
106
+ | Find a symbol / list file contents | `scip-query outline <file>` (all symbols with line ranges + signatures) |
77
107
  | Find files by name | `scip-query files <pattern>` |
78
108
  | See callers + callees | `scip-query call-graph <symbol>` |
79
109
  | Full module map | `scip-query system <module>` |
@@ -107,7 +137,7 @@ If none of these can answer your question, say so explicitly in the plan rather
107
137
 
108
138
  ### Full Documentation
109
139
 
110
- - **Every command with options and examples:** `/Users/aydansalois/Documents/GitHub/scip-query/README.md`
140
+ - **Every command with options and examples:** `/Users/aydansalois/Documents/GitHub/scip-query/docs/COMMAND_REFERENCE.md`
111
141
  - **Goal-oriented agent workflows:** `/Users/aydansalois/Documents/GitHub/scip-query/docs/AGENT_GUIDE.md`
112
142
 
113
143
  ---
@@ -284,7 +314,7 @@ You have the `scip-query` CLI for compiler-resolved code intelligence. Use it fo
284
314
  Navigation:
285
315
  - `scip-query code <symbol>` — read source code (bounded to definition range)
286
316
  - `scip-query code <symbol> -C 5` — read source with 5 extra context lines
287
- - `scip-query symbols <file>` — all symbols in a file with line ranges + signatures
317
+ - `scip-query outline <file>` — all symbols in a file with line ranges + signatures
288
318
  - `scip-query files <pattern>` — find files by name
289
319
  - `scip-query refs <symbol>` — every file referencing a symbol
290
320
  - `scip-query trace <symbol>` — definition + signature + all references
@@ -314,7 +344,7 @@ Quality:
314
344
  - `scip-query complexity-hotspots` — riskiest symbols
315
345
  - `scip-query cycles` — circular dependencies
316
346
 
317
- Full command reference: /Users/aydansalois/Documents/GitHub/scip-query/README.md
347
+ Full command reference: /Users/aydansalois/Documents/GitHub/scip-query/docs/COMMAND_REFERENCE.md
318
348
  Agent workflows guide: /Users/aydansalois/Documents/GitHub/scip-query/docs/AGENT_GUIDE.md
319
349
 
320
350
  ### Rules
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: scip-ai-cleanup
3
+ description: Clean up AI-generated code rot using scip-query's change-graph and verification tooling. Finds recent re-implementations of established code, drifting standards docs, speculative parameters, hidden coupling, and produces compiler-verified deletion plans. Sets up the CI ratchet so findings never regress.
4
+ allowed-tools: [Bash, Write, Edit, Glob, Agent, TaskCreate, TaskUpdate, TaskGet, TaskList]
5
+ keywords: [ai-slop, ai-generated, cleanup, duplicates, echo, doc-drift, standards, stale-docs, cleanup-plan, verify, co-change, ratchet, baseline, unused-params]
6
+ ---
7
+
8
+ # AI-Generated Code Cleanup with scip-query
9
+
10
+ AI-assisted development rots a codebase in specific, detectable ways: agents
11
+ re-implement helpers they didn't know existed, leave half-wired parallel
12
+ implementations behind, add parameters "for later" that never come, and the
13
+ standards docs written FOR agents drift away from the code — so the next agent
14
+ implements against a dead spec. None of this is visible in a single file;
15
+ all of it is visible in the reference graph + the git change graph.
16
+
17
+ This skill runs the full sweep and ends with a compiler-verified deletion
18
+ plan and a CI ratchet.
19
+
20
+ ## When to Use This Skill
21
+
22
+ - "Clean up the AI slop in this repo"
23
+ - "Did the agents duplicate code?"
24
+ - "Are our standards docs stale?"
25
+ - "What can we safely delete?"
26
+ - "Set up a quality gate for agent-written code"
27
+
28
+ ## Hard Rules
29
+
30
+ 1. **Evidence first.** Run `scip-query status` and `scip-query reindex` before
31
+ trusting graph facts. All detectors print whether they're heuristic.
32
+ 2. **Verify before deleting.** Findings are candidates; only
33
+ `cleanup-plan --verify` output stamped COMPILER-VERIFIED is proof.
34
+ A FAILED verification is signal too — its errors name the references the
35
+ static evidence missed. Never delete on a failed batch.
36
+ 3. **Echoes consolidate INTO the established side.** When recent code
37
+ duplicates older code, extend the original and delete the echo — not the
38
+ reverse. The established side has the consumers and the bug-fix history.
39
+ 4. **Fix the doc or delete the doc — never leave it lying.** A stale standards
40
+ doc actively misleads every agent that reads it.
41
+
42
+ ## The Sweep
43
+
44
+ ### Step 1: Recent re-implementations (echoes)
45
+
46
+ ```bash
47
+ scip-query recent-duplicates --window 100
48
+ ```
49
+
50
+ - `ECHO` — recent code duplicating established code. Read both sides, then
51
+ migrate the echo's callers to the established symbol and delete the echo.
52
+ - `TWIN` — both sides landed recently (often one agent session duplicating
53
+ itself). Pick the better-placed one, consolidate before they diverge.
54
+ - Widen `--window` on slow-moving repos; narrow it right after a big agent
55
+ session.
56
+
57
+ ### Step 2: Drifting and lying docs
58
+
59
+ ```bash
60
+ scip-query doc-drift
61
+ scip-query doc-drift AGENTS.md # detail mode for one doc
62
+ ```
63
+
64
+ - `BROKEN REFERENCE` lines are the worst class: the doc cites files that no
65
+ longer exist. Fix those citations first.
66
+ - `referenced by doc` subjects changed after the doc's last update — re-read
67
+ the subject files and update the doc's claims (or delete the doc).
68
+ - Re-run after updating: staleness should drop to 0 for the docs you touched.
69
+
70
+ ### Step 3: Speculative generality
71
+
72
+ ```bash
73
+ scip-query unused-params
74
+ ```
75
+
76
+ Trailing parameters no body uses — already scoped to removals that are
77
+ type-safe by construction (TS/JS, trailing-only, no parameter properties).
78
+ Drop the parameters and any arguments at call sites.
79
+
80
+ ### Step 4: Hidden coupling
81
+
82
+ ```bash
83
+ scip-query co-change
84
+ ```
85
+
86
+ File pairs that repeatedly change in the same commits with NO dependency
87
+ edge: hand-synchronized artifacts (schema ↔ inventory doc ↔ generator
88
+ script, backend schema ↔ frontend store, .env.example ↔ env parser).
89
+ For each pair, either name the shared concept in code (one source of truth)
90
+ or add a contract test that fails when one side changes without the other.
91
+
92
+ ### Step 5: Compiler-verified deletion
93
+
94
+ ```bash
95
+ scip-query cleanup-plan --verify
96
+ ```
97
+
98
+ - Batches are ordered: batch 0 is graph-fact dead now; batch n is dead once
99
+ batch n-1 lands (the cascade). Apply ONE batch at a time.
100
+ - `COMPILER-VERIFIED` means the deletion was applied in a throwaway worktree
101
+ and your own checker (tsc / cargo check) passed differentially.
102
+ - `FAILED` errors name real references — usually barrel export lines or
103
+ imports that must be removed together with the symbol, occasionally a
104
+ detector false positive. Investigate before deleting anything.
105
+ - The `blocked` list explains why candidates can't cascade (e.g. a spec file
106
+ still references them).
107
+
108
+ ### Step 6: Ratchet it
109
+
110
+ ```bash
111
+ scip-query health --write-baseline # commit .scipquery-baseline.json
112
+ scip-query health --baseline # exit 1 on any NEW finding — wire into CI
113
+ scip-query diff-gate # per-diff gate: echoes, missing partners, uncited docs
114
+ ```
115
+
116
+ `diff-gate` is the leading indicator: run it on every agent commit / PR
117
+ (`--base origin/main` in CI). Each finding carries a remediation the agent
118
+ can apply directly.
119
+
120
+ After each cleanup round, re-run `--write-baseline` to ratchet the count
121
+ down. The gate is "don't get worse" — objective and ungameable.
122
+
123
+ ## Before Writing New Code (prevention)
124
+
125
+ Tell implementing agents to run these BEFORE writing a helper or reading a
126
+ standard:
127
+
128
+ ```bash
129
+ scip-query plan-context <symbol-or-file> # structure + HISTORY (churn, co-change partners)
130
+ scip-query similar <new-function-name> # does this already exist?
131
+ scip-query doc-drift <standard.md> # is the standard I'm about to follow stale?
132
+ ```
133
+
134
+ The HISTORY section of plan-context lists the files that usually change with
135
+ the target — the edit checklist that prevents the drift this skill cleans up.
136
+
137
+ ## Reporting
138
+
139
+ End with a prioritized summary:
140
+
141
+ 1. Echoes/twins consolidated (LOC removed, callers migrated)
142
+ 2. Docs fixed vs deleted (staleness before → after)
143
+ 3. Compiler-verified deletions applied (LOC, batches)
144
+ 4. Hidden couplings resolved (named mechanism or contract test added)
145
+ 5. Baseline ratcheted: N findings → M
@@ -9,6 +9,8 @@ keywords: [debloat, clean, cleanup, refactor, dead-code, duplication, dry, conso
9
9
 
10
10
  You are performing a comprehensive codebase audit to find every opportunity to reduce bloat, eliminate duplication, consolidate similar code, remove unnecessary abstractions, and improve structural health. You are thorough — you check from every angle, not just the obvious ones. Every finding must come from `scip-query`.
11
11
 
12
+ This is not a score-maxing workflow. Health scores, finding counts, and LOC totals are diagnostic signals. The objective is to make the codebase easier to understand and safer to change by removing unnecessary structure, naming hidden policies, and preserving real behavior.
13
+
12
14
  ---
13
15
 
14
16
  ## When to Use This Skill
@@ -28,19 +30,47 @@ You are performing a comprehensive codebase audit to find every opportunity to r
28
30
 
29
31
  1. **Run `scip-query health` first.** It aggregates all analyses and gives you the prioritized starting point. Don't skip it.
30
32
 
31
- 2. **Check from every angle.** Dead code is the easy win. Go deeper similar functions, stale abstractions, wrapper indirection, pattern drift, convergence opportunities, passthrough functions. Each catches a different class of bloat.
33
+ 2. **Do not chase the score.** Do not recommend work merely because it raises `health`, reduces a detector count, or deletes LOC. A finding is actionable only when the change removes a real maintenance burden while preserving required behavior.
34
+
35
+ 3. **Check from every angle.** Dead code is the easy win. Go deeper — similar functions, stale abstractions, wrapper indirection, pattern drift, convergence opportunities, passthrough functions. Each catches a different class of bloat.
32
36
 
33
- 3. **Verify before recommending deletion.** Before saying "delete X," confirm it's truly unused: check `scip-query refs`, `scip-query affected`, and whether it's an entry point (CLI, worker, test file). Entry points appear dead because nothing imports them.
37
+ 4. **Verify before recommending deletion.** Before saying "delete X," confirm it's truly unused: check `scip-query refs`, `scip-query affected`, and whether it's an entry point (CLI, worker, test file). Entry points appear dead because nothing imports them.
34
38
 
35
- 4. **Produce concrete actions.** Don't say "there's some duplication." Say "functions A and B have 80% callee overlap consolidate into a shared helper with the 2 divergent callees as parameters (per `scip-query convergence A B`)."
39
+ 5. **Distinguish accidental variation from essential variation.** Accidental variation is difference in code shape that does not reflect a real behavior, domain, runtime, or compatibility difference. Essential variation is difference that must remain because the real units differ. Consolidate the first; preserve the second.
36
40
 
37
- 5. **The report goes in `reports/debloat/YYYY-MM-DD-<scope>.md`.** If no reports directory exists, use the project root.
41
+ 6. **Produce concrete actions.** Don't say "there's some duplication." Say "functions A and B have 80% callee overlap — consolidate into a shared helper with the 2 divergent callees as parameters (per `scip-query convergence A B`)."
42
+
43
+ 7. **The report goes in `reports/debloat/YYYY-MM-DD-<scope>.md`.** If no reports directory exists, use the project root.
38
44
 
39
45
  ---
40
46
 
47
+ ## Start Here: The Verified Pipeline
48
+
49
+ Before working the angles below one by one, run the high-leverage trio:
50
+
51
+ ```bash
52
+ scip-query cleanup-plan --verify # cascade dead-code plan, COMPILER-VERIFIED per batch
53
+ scip-query recent-duplicates # recent code that re-implements established code
54
+ scip-query doc-drift # docs whose referenced code moved on without them
55
+ ```
56
+
57
+ `cleanup-plan --verify` subsumes the manual dead-code workflow: it runs dead
58
+ code to a fixpoint (deleting batch 0 makes batch 1 dead), applies each batch
59
+ in a throwaway worktree, and runs the project's own checker (tsc / cargo
60
+ check) differentially. Only act on batches stamped COMPILER-VERIFIED; FAILED
61
+ output names the references the static evidence missed. For AI-generated
62
+ codebases specifically, prefer the dedicated scip-ai-cleanup skill.
63
+
64
+ After cleanup, ratchet the result so it never regresses:
65
+
66
+ ```bash
67
+ scip-query health --write-baseline # commit .scipquery-baseline.json
68
+ scip-query health --baseline # CI gate: exit 1 on any NEW finding
69
+ ```
70
+
41
71
  ## Symbol Lookup Tips
42
72
 
43
- scip-query accepts partial symbol names — you don't need the full SCIP symbol path. These all work:
73
+ `scip-query` accepts partial symbol names — you don't need the full SCIP symbol path. These all work:
44
74
 
45
75
  ```bash
46
76
  scip-query code processVegaMention # just the function name
@@ -67,7 +97,7 @@ scip-query code 'src/modules/chat/chat.service.ts:100-200'
67
97
 
68
98
  **If "Symbol not found":**
69
99
  1. Try a shorter/simpler name — `login` instead of `AuthService:login`
70
- 2. Try `scip-query symbols <file>` to see what symbols exist in the file
100
+ 2. Try `scip-query outline <file>` to see what symbols exist in the file
71
101
  3. Try `scip-query trace <name>` which uses a different lookup path
72
102
  4. Use the `file:line-line` syntax for `code` if you know the location
73
103
 
@@ -276,7 +306,7 @@ scip-query reindex # Ensure index is fresh
276
306
  scip-query health # Get the full report
277
307
  ```
278
308
 
279
- Read the health score, the findings breakdown, and the prioritized action list. This is your roadmap.
309
+ Read the health score, the findings breakdown, and the prioritized action list as evidence. They are not the goal. Use them to find places where unnecessary structure, hidden policy, accidental variation, or disconnected code creates maintenance cost.
280
310
 
281
311
  ### Phase 2: Deep Scan (10-15 minutes)
282
312