codesift-mcp 0.9.0 → 0.9.10

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 (1325) hide show
  1. package/README.md +39 -23
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +88 -2
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/help.d.ts +1 -1
  6. package/dist/cli/help.d.ts.map +1 -1
  7. package/dist/cli/help.js +18 -0
  8. package/dist/cli/help.js.map +1 -1
  9. package/dist/cli/hooks/input.d.ts +11 -0
  10. package/dist/cli/hooks/input.d.ts.map +1 -0
  11. package/dist/cli/hooks/input.js +111 -0
  12. package/dist/cli/hooks/input.js.map +1 -0
  13. package/dist/cli/hooks/post-tool-use.d.ts +2 -0
  14. package/dist/cli/hooks/post-tool-use.d.ts.map +1 -0
  15. package/dist/cli/hooks/post-tool-use.js +339 -0
  16. package/dist/cli/hooks/post-tool-use.js.map +1 -0
  17. package/dist/cli/hooks/pre-compact.d.ts +2 -0
  18. package/dist/cli/hooks/pre-compact.d.ts.map +1 -0
  19. package/dist/cli/hooks/pre-compact.js +41 -0
  20. package/dist/cli/hooks/pre-compact.js.map +1 -0
  21. package/dist/cli/hooks/pre-tool-use.d.ts +5 -0
  22. package/dist/cli/hooks/pre-tool-use.d.ts.map +1 -0
  23. package/dist/cli/hooks/pre-tool-use.js +215 -0
  24. package/dist/cli/hooks/pre-tool-use.js.map +1 -0
  25. package/dist/cli/hooks/session.d.ts +5 -0
  26. package/dist/cli/hooks/session.d.ts.map +1 -0
  27. package/dist/cli/hooks/session.js +188 -0
  28. package/dist/cli/hooks/session.js.map +1 -0
  29. package/dist/cli/hooks/shared.d.ts +6 -0
  30. package/dist/cli/hooks/shared.d.ts.map +1 -0
  31. package/dist/cli/hooks/shared.js +70 -0
  32. package/dist/cli/hooks/shared.js.map +1 -0
  33. package/dist/cli/hooks/wiki.d.ts +10 -0
  34. package/dist/cli/hooks/wiki.d.ts.map +1 -0
  35. package/dist/cli/hooks/wiki.js +202 -0
  36. package/dist/cli/hooks/wiki.js.map +1 -0
  37. package/dist/cli/hooks.d.ts +5 -16
  38. package/dist/cli/hooks.d.ts.map +1 -1
  39. package/dist/cli/hooks.js +5 -1132
  40. package/dist/cli/hooks.js.map +1 -1
  41. package/dist/cli/setup/claude.d.ts +4 -0
  42. package/dist/cli/setup/claude.d.ts.map +1 -0
  43. package/dist/cli/setup/claude.js +123 -0
  44. package/dist/cli/setup/claude.js.map +1 -0
  45. package/dist/cli/setup/codex.d.ts +12 -0
  46. package/dist/cli/setup/codex.d.ts.map +1 -0
  47. package/dist/cli/setup/codex.js +182 -0
  48. package/dist/cli/setup/codex.js.map +1 -0
  49. package/dist/cli/setup/cursor.d.ts +3 -0
  50. package/dist/cli/setup/cursor.d.ts.map +1 -0
  51. package/dist/cli/setup/cursor.js +6 -0
  52. package/dist/cli/setup/cursor.js.map +1 -0
  53. package/dist/cli/setup/fs.d.ts +6 -0
  54. package/dist/cli/setup/fs.d.ts.map +1 -0
  55. package/dist/cli/setup/fs.js +44 -0
  56. package/dist/cli/setup/fs.js.map +1 -0
  57. package/dist/cli/setup/gemini.d.ts +5 -0
  58. package/dist/cli/setup/gemini.d.ts.map +1 -0
  59. package/dist/cli/setup/gemini.js +46 -0
  60. package/dist/cli/setup/gemini.js.map +1 -0
  61. package/dist/cli/setup/hooks.d.ts +12 -0
  62. package/dist/cli/setup/hooks.d.ts.map +1 -0
  63. package/dist/cli/setup/hooks.js +29 -0
  64. package/dist/cli/setup/hooks.js.map +1 -0
  65. package/dist/cli/setup/mcp.d.ts +13 -0
  66. package/dist/cli/setup/mcp.d.ts.map +1 -0
  67. package/dist/cli/setup/mcp.js +104 -0
  68. package/dist/cli/setup/mcp.js.map +1 -0
  69. package/dist/cli/setup/rules.d.ts +4 -0
  70. package/dist/cli/setup/rules.d.ts.map +1 -0
  71. package/dist/cli/setup/rules.js +157 -0
  72. package/dist/cli/setup/rules.js.map +1 -0
  73. package/dist/cli/setup/types.d.ts +24 -0
  74. package/dist/cli/setup/types.d.ts.map +1 -0
  75. package/dist/cli/setup/types.js +2 -0
  76. package/dist/cli/setup/types.js.map +1 -0
  77. package/dist/cli/setup.d.ts +8 -48
  78. package/dist/cli/setup.d.ts.map +1 -1
  79. package/dist/cli/setup.js +49 -724
  80. package/dist/cli/setup.js.map +1 -1
  81. package/dist/config.d.ts +15 -0
  82. package/dist/config.d.ts.map +1 -1
  83. package/dist/config.js +56 -2
  84. package/dist/config.js.map +1 -1
  85. package/dist/formatter-dispatch.d.ts +53 -0
  86. package/dist/formatter-dispatch.d.ts.map +1 -0
  87. package/dist/formatter-dispatch.js +54 -0
  88. package/dist/formatter-dispatch.js.map +1 -0
  89. package/dist/formatters-analysis.d.ts +9 -0
  90. package/dist/formatters-analysis.d.ts.map +1 -0
  91. package/dist/formatters-analysis.js +166 -0
  92. package/dist/formatters-analysis.js.map +1 -0
  93. package/dist/formatters-core.d.ts +200 -0
  94. package/dist/formatters-core.d.ts.map +1 -0
  95. package/dist/formatters-core.js +206 -0
  96. package/dist/formatters-core.js.map +1 -0
  97. package/dist/formatters-graph.d.ts +124 -0
  98. package/dist/formatters-graph.d.ts.map +1 -0
  99. package/dist/formatters-graph.js +175 -0
  100. package/dist/formatters-graph.js.map +1 -0
  101. package/dist/formatters-nextjs.d.ts +22 -0
  102. package/dist/formatters-nextjs.d.ts.map +1 -0
  103. package/dist/formatters-nextjs.js +394 -0
  104. package/dist/formatters-nextjs.js.map +1 -0
  105. package/dist/formatters.d.ts +8 -349
  106. package/dist/formatters.d.ts.map +1 -1
  107. package/dist/formatters.js +10 -929
  108. package/dist/formatters.js.map +1 -1
  109. package/dist/parser/astro-template/preprocess.d.ts +12 -0
  110. package/dist/parser/astro-template/preprocess.d.ts.map +1 -0
  111. package/dist/parser/astro-template/preprocess.js +34 -0
  112. package/dist/parser/astro-template/preprocess.js.map +1 -0
  113. package/dist/parser/astro-template/resolution.d.ts +16 -0
  114. package/dist/parser/astro-template/resolution.d.ts.map +1 -0
  115. package/dist/parser/astro-template/resolution.js +58 -0
  116. package/dist/parser/astro-template/resolution.js.map +1 -0
  117. package/dist/parser/astro-template/scanner.d.ts +4 -0
  118. package/dist/parser/astro-template/scanner.d.ts.map +1 -0
  119. package/dist/parser/astro-template/scanner.js +71 -0
  120. package/dist/parser/astro-template/scanner.js.map +1 -0
  121. package/dist/parser/astro-template/state.d.ts +22 -0
  122. package/dist/parser/astro-template/state.d.ts.map +1 -0
  123. package/dist/parser/astro-template/state.js +48 -0
  124. package/dist/parser/astro-template/state.js.map +1 -0
  125. package/dist/parser/astro-template/tag-processor.d.ts +3 -0
  126. package/dist/parser/astro-template/tag-processor.d.ts.map +1 -0
  127. package/dist/parser/astro-template/tag-processor.js +63 -0
  128. package/dist/parser/astro-template/tag-processor.js.map +1 -0
  129. package/dist/parser/astro-template/types.d.ts +42 -0
  130. package/dist/parser/astro-template/types.d.ts.map +1 -0
  131. package/dist/parser/astro-template/types.js +2 -0
  132. package/dist/parser/astro-template/types.js.map +1 -0
  133. package/dist/parser/astro-template.d.ts +2 -45
  134. package/dist/parser/astro-template.d.ts.map +1 -1
  135. package/dist/parser/astro-template.js +7 -168
  136. package/dist/parser/astro-template.js.map +1 -1
  137. package/dist/parser/extractors/_shared.js +1 -1
  138. package/dist/parser/extractors/_shared.js.map +1 -1
  139. package/dist/parser/extractors/astro.js +1 -1
  140. package/dist/parser/extractors/astro.js.map +1 -1
  141. package/dist/parser/extractors/conversation.js +1 -1
  142. package/dist/parser/extractors/conversation.js.map +1 -1
  143. package/dist/parser/extractors/hono-app-discovery.d.ts +4 -0
  144. package/dist/parser/extractors/hono-app-discovery.d.ts.map +1 -0
  145. package/dist/parser/extractors/hono-app-discovery.js +169 -0
  146. package/dist/parser/extractors/hono-app-discovery.js.map +1 -0
  147. package/dist/parser/extractors/hono-ast-utils.d.ts +6 -0
  148. package/dist/parser/extractors/hono-ast-utils.d.ts.map +1 -0
  149. package/dist/parser/extractors/hono-ast-utils.js +77 -0
  150. package/dist/parser/extractors/hono-ast-utils.js.map +1 -0
  151. package/dist/parser/extractors/hono-context-extractor.d.ts +15 -0
  152. package/dist/parser/extractors/hono-context-extractor.d.ts.map +1 -0
  153. package/dist/parser/extractors/hono-context-extractor.js +191 -0
  154. package/dist/parser/extractors/hono-context-extractor.js.map +1 -0
  155. package/dist/parser/extractors/hono-middleware-extractor.d.ts +38 -0
  156. package/dist/parser/extractors/hono-middleware-extractor.d.ts.map +1 -0
  157. package/dist/parser/extractors/hono-middleware-extractor.js +480 -0
  158. package/dist/parser/extractors/hono-middleware-extractor.js.map +1 -0
  159. package/dist/parser/extractors/hono-openapi-extractor.d.ts +11 -0
  160. package/dist/parser/extractors/hono-openapi-extractor.d.ts.map +1 -0
  161. package/dist/parser/extractors/hono-openapi-extractor.js +119 -0
  162. package/dist/parser/extractors/hono-openapi-extractor.js.map +1 -0
  163. package/dist/parser/extractors/hono-route-extractor.d.ts +11 -0
  164. package/dist/parser/extractors/hono-route-extractor.d.ts.map +1 -0
  165. package/dist/parser/extractors/hono-route-extractor.js +128 -0
  166. package/dist/parser/extractors/hono-route-extractor.js.map +1 -0
  167. package/dist/parser/extractors/hono-route-utils.d.ts +11 -0
  168. package/dist/parser/extractors/hono-route-utils.d.ts.map +1 -0
  169. package/dist/parser/extractors/hono-route-utils.js +40 -0
  170. package/dist/parser/extractors/hono-route-utils.js.map +1 -0
  171. package/dist/parser/extractors/hono-runtime-extractor.d.ts +17 -0
  172. package/dist/parser/extractors/hono-runtime-extractor.d.ts.map +1 -0
  173. package/dist/parser/extractors/hono-runtime-extractor.js +141 -0
  174. package/dist/parser/extractors/hono-runtime-extractor.js.map +1 -0
  175. package/dist/parser/extractors/hono.d.ts +5 -79
  176. package/dist/parser/extractors/hono.d.ts.map +1 -1
  177. package/dist/parser/extractors/hono.js +32 -1159
  178. package/dist/parser/extractors/hono.js.map +1 -1
  179. package/dist/parser/extractors/kotlin-ast-helpers.d.ts +43 -0
  180. package/dist/parser/extractors/kotlin-ast-helpers.d.ts.map +1 -0
  181. package/dist/parser/extractors/kotlin-ast-helpers.js +187 -0
  182. package/dist/parser/extractors/kotlin-ast-helpers.js.map +1 -0
  183. package/dist/parser/extractors/kotlin-test-symbols.d.ts +21 -0
  184. package/dist/parser/extractors/kotlin-test-symbols.d.ts.map +1 -0
  185. package/dist/parser/extractors/kotlin-test-symbols.js +162 -0
  186. package/dist/parser/extractors/kotlin-test-symbols.js.map +1 -0
  187. package/dist/parser/extractors/kotlin.d.ts.map +1 -1
  188. package/dist/parser/extractors/kotlin.js +3 -334
  189. package/dist/parser/extractors/kotlin.js.map +1 -1
  190. package/dist/parser/extractors/markdown.js +1 -1
  191. package/dist/parser/extractors/markdown.js.map +1 -1
  192. package/dist/parser/extractors/prisma.js +1 -1
  193. package/dist/parser/extractors/prisma.js.map +1 -1
  194. package/dist/parser/extractors/sql-boundaries.d.ts +3 -0
  195. package/dist/parser/extractors/sql-boundaries.d.ts.map +1 -0
  196. package/dist/parser/extractors/sql-boundaries.js +19 -0
  197. package/dist/parser/extractors/sql-boundaries.js.map +1 -0
  198. package/dist/parser/extractors/sql-columns.d.ts +14 -0
  199. package/dist/parser/extractors/sql-columns.d.ts.map +1 -0
  200. package/dist/parser/extractors/sql-columns.js +59 -0
  201. package/dist/parser/extractors/sql-columns.js.map +1 -0
  202. package/dist/parser/extractors/sql-docstrings.d.ts +2 -0
  203. package/dist/parser/extractors/sql-docstrings.d.ts.map +1 -0
  204. package/dist/parser/extractors/sql-docstrings.js +45 -0
  205. package/dist/parser/extractors/sql-docstrings.js.map +1 -0
  206. package/dist/parser/extractors/sql-end-scanner.d.ts +5 -0
  207. package/dist/parser/extractors/sql-end-scanner.d.ts.map +1 -0
  208. package/dist/parser/extractors/sql-end-scanner.js +84 -0
  209. package/dist/parser/extractors/sql-end-scanner.js.map +1 -0
  210. package/dist/parser/extractors/sql-jinja.d.ts +2 -0
  211. package/dist/parser/extractors/sql-jinja.d.ts.map +1 -0
  212. package/dist/parser/extractors/sql-jinja.js +8 -0
  213. package/dist/parser/extractors/sql-jinja.js.map +1 -0
  214. package/dist/parser/extractors/sql-matcher-catalog.d.ts +9 -0
  215. package/dist/parser/extractors/sql-matcher-catalog.d.ts.map +1 -0
  216. package/dist/parser/extractors/sql-matcher-catalog.js +15 -0
  217. package/dist/parser/extractors/sql-matcher-catalog.js.map +1 -0
  218. package/dist/parser/extractors/sql-matchers.d.ts +9 -0
  219. package/dist/parser/extractors/sql-matchers.d.ts.map +1 -0
  220. package/dist/parser/extractors/sql-matchers.js +20 -0
  221. package/dist/parser/extractors/sql-matchers.js.map +1 -0
  222. package/dist/parser/extractors/sql-offsets.d.ts +2 -0
  223. package/dist/parser/extractors/sql-offsets.d.ts.map +1 -0
  224. package/dist/parser/extractors/sql-offsets.js +25 -0
  225. package/dist/parser/extractors/sql-offsets.js.map +1 -0
  226. package/dist/parser/extractors/sql-parens.d.ts +4 -0
  227. package/dist/parser/extractors/sql-parens.d.ts.map +1 -0
  228. package/dist/parser/extractors/sql-parens.js +70 -0
  229. package/dist/parser/extractors/sql-parens.js.map +1 -0
  230. package/dist/parser/extractors/sql-symbols.d.ts +11 -0
  231. package/dist/parser/extractors/sql-symbols.d.ts.map +1 -0
  232. package/dist/parser/extractors/sql-symbols.js +23 -0
  233. package/dist/parser/extractors/sql-symbols.js.map +1 -0
  234. package/dist/parser/extractors/sql.d.ts +2 -30
  235. package/dist/parser/extractors/sql.d.ts.map +1 -1
  236. package/dist/parser/extractors/sql.js +23 -496
  237. package/dist/parser/extractors/sql.js.map +1 -1
  238. package/dist/parser/extractors/typescript-cjs-nodes.d.ts +5 -0
  239. package/dist/parser/extractors/typescript-cjs-nodes.d.ts.map +1 -0
  240. package/dist/parser/extractors/typescript-cjs-nodes.js +148 -0
  241. package/dist/parser/extractors/typescript-cjs-nodes.js.map +1 -0
  242. package/dist/parser/extractors/typescript-class-nodes.d.ts +8 -0
  243. package/dist/parser/extractors/typescript-class-nodes.d.ts.map +1 -0
  244. package/dist/parser/extractors/typescript-class-nodes.js +183 -0
  245. package/dist/parser/extractors/typescript-class-nodes.js.map +1 -0
  246. package/dist/parser/extractors/typescript-declaration-nodes.d.ts +5 -0
  247. package/dist/parser/extractors/typescript-declaration-nodes.d.ts.map +1 -0
  248. package/dist/parser/extractors/typescript-declaration-nodes.js +105 -0
  249. package/dist/parser/extractors/typescript-declaration-nodes.js.map +1 -0
  250. package/dist/parser/extractors/typescript-module-nodes.d.ts +6 -0
  251. package/dist/parser/extractors/typescript-module-nodes.d.ts.map +1 -0
  252. package/dist/parser/extractors/typescript-module-nodes.js +151 -0
  253. package/dist/parser/extractors/typescript-module-nodes.js.map +1 -0
  254. package/dist/parser/extractors/typescript-react.d.ts +11 -0
  255. package/dist/parser/extractors/typescript-react.d.ts.map +1 -0
  256. package/dist/parser/extractors/typescript-react.js +101 -0
  257. package/dist/parser/extractors/typescript-react.js.map +1 -0
  258. package/dist/parser/extractors/typescript-shared.d.ts +26 -0
  259. package/dist/parser/extractors/typescript-shared.d.ts.map +1 -0
  260. package/dist/parser/extractors/typescript-shared.js +101 -0
  261. package/dist/parser/extractors/typescript-shared.js.map +1 -0
  262. package/dist/parser/extractors/typescript-test-nodes.d.ts +4 -0
  263. package/dist/parser/extractors/typescript-test-nodes.d.ts.map +1 -0
  264. package/dist/parser/extractors/typescript-test-nodes.js +112 -0
  265. package/dist/parser/extractors/typescript-test-nodes.js.map +1 -0
  266. package/dist/parser/extractors/typescript-type-nodes.d.ts +6 -0
  267. package/dist/parser/extractors/typescript-type-nodes.d.ts.map +1 -0
  268. package/dist/parser/extractors/typescript-type-nodes.js +48 -0
  269. package/dist/parser/extractors/typescript-type-nodes.js.map +1 -0
  270. package/dist/parser/extractors/typescript.d.ts.map +1 -1
  271. package/dist/parser/extractors/typescript.js +68 -1127
  272. package/dist/parser/extractors/typescript.js.map +1 -1
  273. package/dist/parser/parser-manager.d.ts.map +1 -1
  274. package/dist/parser/parser-manager.js +5 -0
  275. package/dist/parser/parser-manager.js.map +1 -1
  276. package/dist/parser/symbol-extractor.d.ts +1 -12
  277. package/dist/parser/symbol-extractor.d.ts.map +1 -1
  278. package/dist/parser/symbol-extractor.js +2 -24
  279. package/dist/parser/symbol-extractor.js.map +1 -1
  280. package/dist/parser/symbol-utils.d.ts +4 -0
  281. package/dist/parser/symbol-utils.d.ts.map +1 -0
  282. package/dist/parser/symbol-utils.js +20 -0
  283. package/dist/parser/symbol-utils.js.map +1 -0
  284. package/dist/register-tool-groups/analysis/cross-repo.d.ts +4 -0
  285. package/dist/register-tool-groups/analysis/cross-repo.d.ts.map +1 -0
  286. package/dist/register-tool-groups/analysis/cross-repo.js +108 -0
  287. package/dist/register-tool-groups/analysis/cross-repo.js.map +1 -0
  288. package/dist/register-tool-groups/analysis/review.d.ts +3 -0
  289. package/dist/register-tool-groups/analysis/review.d.ts.map +1 -0
  290. package/dist/register-tool-groups/analysis/review.js +96 -0
  291. package/dist/register-tool-groups/analysis/review.js.map +1 -0
  292. package/dist/register-tool-groups/analysis/workspace.d.ts +3 -0
  293. package/dist/register-tool-groups/analysis/workspace.d.ts.map +1 -0
  294. package/dist/register-tool-groups/analysis/workspace.js +82 -0
  295. package/dist/register-tool-groups/analysis/workspace.js.map +1 -0
  296. package/dist/register-tool-groups/analysis.d.ts +3 -0
  297. package/dist/register-tool-groups/analysis.d.ts.map +1 -0
  298. package/dist/register-tool-groups/analysis.js +541 -0
  299. package/dist/register-tool-groups/analysis.js.map +1 -0
  300. package/dist/register-tool-groups/astro.d.ts +3 -0
  301. package/dist/register-tool-groups/astro.d.ts.map +1 -0
  302. package/dist/register-tool-groups/astro.js +302 -0
  303. package/dist/register-tool-groups/astro.js.map +1 -0
  304. package/dist/register-tool-groups/core/index.d.ts +3 -0
  305. package/dist/register-tool-groups/core/index.d.ts.map +1 -0
  306. package/dist/register-tool-groups/core/index.js +96 -0
  307. package/dist/register-tool-groups/core/index.js.map +1 -0
  308. package/dist/register-tool-groups/core/meta.d.ts +3 -0
  309. package/dist/register-tool-groups/core/meta.d.ts.map +1 -0
  310. package/dist/register-tool-groups/core/meta.js +180 -0
  311. package/dist/register-tool-groups/core/meta.js.map +1 -0
  312. package/dist/register-tool-groups/core/schema.d.ts +3 -0
  313. package/dist/register-tool-groups/core/schema.d.ts.map +1 -0
  314. package/dist/register-tool-groups/core/schema.js +16 -0
  315. package/dist/register-tool-groups/core/schema.js.map +1 -0
  316. package/dist/register-tool-groups/core/search.d.ts +4 -0
  317. package/dist/register-tool-groups/core/search.d.ts.map +1 -0
  318. package/dist/register-tool-groups/core/search.js +262 -0
  319. package/dist/register-tool-groups/core/search.js.map +1 -0
  320. package/dist/register-tool-groups/core/symbols.d.ts +3 -0
  321. package/dist/register-tool-groups/core/symbols.d.ts.map +1 -0
  322. package/dist/register-tool-groups/core/symbols.js +338 -0
  323. package/dist/register-tool-groups/core/symbols.js.map +1 -0
  324. package/dist/register-tool-groups/core.d.ts +3 -0
  325. package/dist/register-tool-groups/core.d.ts.map +1 -0
  326. package/dist/register-tool-groups/core.js +12 -0
  327. package/dist/register-tool-groups/core.js.map +1 -0
  328. package/dist/register-tool-groups/deps.d.ts +10 -0
  329. package/dist/register-tool-groups/deps.d.ts.map +1 -0
  330. package/dist/register-tool-groups/deps.js +6 -0
  331. package/dist/register-tool-groups/deps.js.map +1 -0
  332. package/dist/register-tool-groups/handler-wrappers.d.ts +63 -0
  333. package/dist/register-tool-groups/handler-wrappers.d.ts.map +1 -0
  334. package/dist/register-tool-groups/handler-wrappers.js +106 -0
  335. package/dist/register-tool-groups/handler-wrappers.js.map +1 -0
  336. package/dist/register-tool-groups/hono.d.ts +3 -0
  337. package/dist/register-tool-groups/hono.d.ts.map +1 -0
  338. package/dist/register-tool-groups/hono.js +179 -0
  339. package/dist/register-tool-groups/hono.js.map +1 -0
  340. package/dist/register-tool-groups/index.d.ts +3 -0
  341. package/dist/register-tool-groups/index.d.ts.map +1 -0
  342. package/dist/register-tool-groups/index.js +28 -0
  343. package/dist/register-tool-groups/index.js.map +1 -0
  344. package/dist/register-tool-groups/kotlin.d.ts +3 -0
  345. package/dist/register-tool-groups/kotlin.d.ts.map +1 -0
  346. package/dist/register-tool-groups/kotlin.js +162 -0
  347. package/dist/register-tool-groups/kotlin.js.map +1 -0
  348. package/dist/register-tool-groups/meta.d.ts +3 -0
  349. package/dist/register-tool-groups/meta.d.ts.map +1 -0
  350. package/dist/register-tool-groups/meta.js +563 -0
  351. package/dist/register-tool-groups/meta.js.map +1 -0
  352. package/dist/register-tool-groups/nextjs.d.ts +3 -0
  353. package/dist/register-tool-groups/nextjs.d.ts.map +1 -0
  354. package/dist/register-tool-groups/nextjs.js +78 -0
  355. package/dist/register-tool-groups/nextjs.js.map +1 -0
  356. package/dist/register-tool-groups/php.d.ts +3 -0
  357. package/dist/register-tool-groups/php.d.ts.map +1 -0
  358. package/dist/register-tool-groups/php.js +312 -0
  359. package/dist/register-tool-groups/php.js.map +1 -0
  360. package/dist/register-tool-groups/python.d.ts +3 -0
  361. package/dist/register-tool-groups/python.d.ts.map +1 -0
  362. package/dist/register-tool-groups/python.js +366 -0
  363. package/dist/register-tool-groups/python.js.map +1 -0
  364. package/dist/register-tool-groups/react.d.ts +3 -0
  365. package/dist/register-tool-groups/react.d.ts.map +1 -0
  366. package/dist/register-tool-groups/react.js +119 -0
  367. package/dist/register-tool-groups/react.js.map +1 -0
  368. package/dist/register-tool-groups/shared.d.ts +156 -0
  369. package/dist/register-tool-groups/shared.d.ts.map +1 -0
  370. package/dist/register-tool-groups/shared.js +182 -0
  371. package/dist/register-tool-groups/shared.js.map +1 -0
  372. package/dist/register-tool-groups/sql.d.ts +3 -0
  373. package/dist/register-tool-groups/sql.d.ts.map +1 -0
  374. package/dist/register-tool-groups/sql.js +260 -0
  375. package/dist/register-tool-groups/sql.js.map +1 -0
  376. package/dist/register-tool-loaders.d.ts +22 -22
  377. package/dist/register-tool-loaders.d.ts.map +1 -1
  378. package/dist/register-tools/autoload.d.ts +8 -0
  379. package/dist/register-tools/autoload.d.ts.map +1 -0
  380. package/dist/register-tools/autoload.js +517 -0
  381. package/dist/register-tools/autoload.js.map +1 -0
  382. package/dist/register-tools/discovery.d.ts +55 -0
  383. package/dist/register-tools/discovery.d.ts.map +1 -0
  384. package/dist/register-tools/discovery.js +206 -0
  385. package/dist/register-tools/discovery.js.map +1 -0
  386. package/dist/register-tools/runtime.d.ts +89 -0
  387. package/dist/register-tools/runtime.d.ts.map +1 -0
  388. package/dist/register-tools/runtime.js +491 -0
  389. package/dist/register-tools/runtime.js.map +1 -0
  390. package/dist/register-tools.d.ts +5 -172
  391. package/dist/register-tools.d.ts.map +1 -1
  392. package/dist/register-tools.js +27 -4878
  393. package/dist/register-tools.js.map +1 -1
  394. package/dist/search/bm25.js +1 -1
  395. package/dist/search/bm25.js.map +1 -1
  396. package/dist/search/tool-embedding-cache.d.ts +4 -0
  397. package/dist/search/tool-embedding-cache.d.ts.map +1 -0
  398. package/dist/search/tool-embedding-cache.js +44 -0
  399. package/dist/search/tool-embedding-cache.js.map +1 -0
  400. package/dist/search/tool-embedding-storage.d.ts +8 -0
  401. package/dist/search/tool-embedding-storage.d.ts.map +1 -0
  402. package/dist/search/tool-embedding-storage.js +56 -0
  403. package/dist/search/tool-embedding-storage.js.map +1 -0
  404. package/dist/search/tool-ranker-bm25.d.ts +6 -0
  405. package/dist/search/tool-ranker-bm25.d.ts.map +1 -0
  406. package/dist/search/tool-ranker-bm25.js +40 -0
  407. package/dist/search/tool-ranker-bm25.js.map +1 -0
  408. package/dist/search/tool-ranker-orchestrator.d.ts +3 -0
  409. package/dist/search/tool-ranker-orchestrator.d.ts.map +1 -0
  410. package/dist/search/tool-ranker-orchestrator.js +49 -0
  411. package/dist/search/tool-ranker-orchestrator.js.map +1 -0
  412. package/dist/search/tool-ranker-reasoning.d.ts +4 -0
  413. package/dist/search/tool-ranker-reasoning.d.ts.map +1 -0
  414. package/dist/search/tool-ranker-reasoning.js +35 -0
  415. package/dist/search/tool-ranker-reasoning.js.map +1 -0
  416. package/dist/search/tool-ranker-signal-math.d.ts +6 -0
  417. package/dist/search/tool-ranker-signal-math.d.ts.map +1 -0
  418. package/dist/search/tool-ranker-signal-math.js +51 -0
  419. package/dist/search/tool-ranker-signal-math.js.map +1 -0
  420. package/dist/search/tool-ranker-signals.d.ts +20 -0
  421. package/dist/search/tool-ranker-signals.d.ts.map +1 -0
  422. package/dist/search/tool-ranker-signals.js +50 -0
  423. package/dist/search/tool-ranker-signals.js.map +1 -0
  424. package/dist/search/tool-ranker-types.d.ts +26 -0
  425. package/dist/search/tool-ranker-types.d.ts.map +1 -0
  426. package/dist/search/tool-ranker-types.js +2 -0
  427. package/dist/search/tool-ranker-types.js.map +1 -0
  428. package/dist/search/tool-ranker.d.ts +6 -89
  429. package/dist/search/tool-ranker.d.ts.map +1 -1
  430. package/dist/search/tool-ranker.js +5 -419
  431. package/dist/search/tool-ranker.js.map +1 -1
  432. package/dist/server-helpers/repo-resolution.d.ts +45 -0
  433. package/dist/server-helpers/repo-resolution.d.ts.map +1 -0
  434. package/dist/server-helpers/repo-resolution.js +113 -0
  435. package/dist/server-helpers/repo-resolution.js.map +1 -0
  436. package/dist/server-helpers/response-hints.d.ts +9 -0
  437. package/dist/server-helpers/response-hints.d.ts.map +1 -0
  438. package/dist/server-helpers/response-hints.js +225 -0
  439. package/dist/server-helpers/response-hints.js.map +1 -0
  440. package/dist/server-helpers.d.ts +14 -35
  441. package/dist/server-helpers.d.ts.map +1 -1
  442. package/dist/server-helpers.js +53 -320
  443. package/dist/server-helpers.js.map +1 -1
  444. package/dist/server.d.ts.map +1 -1
  445. package/dist/server.js +41 -1
  446. package/dist/server.js.map +1 -1
  447. package/dist/storage/usage-tracker.d.ts.map +1 -1
  448. package/dist/storage/usage-tracker.js +12 -0
  449. package/dist/storage/usage-tracker.js.map +1 -1
  450. package/dist/tools/astro-actions/ast.d.ts +14 -0
  451. package/dist/tools/astro-actions/ast.d.ts.map +1 -0
  452. package/dist/tools/astro-actions/ast.js +75 -0
  453. package/dist/tools/astro-actions/ast.js.map +1 -0
  454. package/dist/tools/astro-actions/audit.d.ts +5 -0
  455. package/dist/tools/astro-actions/audit.d.ts.map +1 -0
  456. package/dist/tools/astro-actions/audit.js +102 -0
  457. package/dist/tools/astro-actions/audit.js.map +1 -0
  458. package/dist/tools/astro-actions/callers.d.ts +9 -0
  459. package/dist/tools/astro-actions/callers.d.ts.map +1 -0
  460. package/dist/tools/astro-actions/callers.js +84 -0
  461. package/dist/tools/astro-actions/callers.js.map +1 -0
  462. package/dist/tools/astro-actions/parser.d.ts +3 -0
  463. package/dist/tools/astro-actions/parser.d.ts.map +1 -0
  464. package/dist/tools/astro-actions/parser.js +156 -0
  465. package/dist/tools/astro-actions/parser.js.map +1 -0
  466. package/dist/tools/astro-actions/types.d.ts +58 -0
  467. package/dist/tools/astro-actions/types.d.ts.map +1 -0
  468. package/dist/tools/astro-actions/types.js +2 -0
  469. package/dist/tools/astro-actions/types.js.map +1 -0
  470. package/dist/tools/astro-actions/zod-ast.d.ts +7 -0
  471. package/dist/tools/astro-actions/zod-ast.d.ts.map +1 -0
  472. package/dist/tools/astro-actions/zod-ast.js +51 -0
  473. package/dist/tools/astro-actions/zod-ast.js.map +1 -0
  474. package/dist/tools/astro-actions.d.ts +6 -46
  475. package/dist/tools/astro-actions.d.ts.map +1 -1
  476. package/dist/tools/astro-actions.js +6 -545
  477. package/dist/tools/astro-actions.js.map +1 -1
  478. package/dist/tools/astro-content-collections/diagnostics.d.ts +3 -0
  479. package/dist/tools/astro-content-collections/diagnostics.d.ts.map +1 -0
  480. package/dist/tools/astro-content-collections/diagnostics.js +277 -0
  481. package/dist/tools/astro-content-collections/diagnostics.js.map +1 -0
  482. package/dist/tools/astro-content-collections/discovery.d.ts +6 -0
  483. package/dist/tools/astro-content-collections/discovery.d.ts.map +1 -0
  484. package/dist/tools/astro-content-collections/discovery.js +152 -0
  485. package/dist/tools/astro-content-collections/discovery.js.map +1 -0
  486. package/dist/tools/astro-content-collections/schema.d.ts +15 -0
  487. package/dist/tools/astro-content-collections/schema.d.ts.map +1 -0
  488. package/dist/tools/astro-content-collections/schema.js +119 -0
  489. package/dist/tools/astro-content-collections/schema.js.map +1 -0
  490. package/dist/tools/astro-content-collections/types.d.ts +61 -0
  491. package/dist/tools/astro-content-collections/types.d.ts.map +1 -0
  492. package/dist/tools/astro-content-collections/types.js +2 -0
  493. package/dist/tools/astro-content-collections/types.js.map +1 -0
  494. package/dist/tools/astro-content-collections.d.ts +5 -40
  495. package/dist/tools/astro-content-collections.d.ts.map +1 -1
  496. package/dist/tools/astro-content-collections.js +42 -449
  497. package/dist/tools/astro-content-collections.js.map +1 -1
  498. package/dist/tools/astro-routes.js +1 -1
  499. package/dist/tools/astro-routes.js.map +1 -1
  500. package/dist/tools/complexity-tools.d.ts +6 -0
  501. package/dist/tools/complexity-tools.d.ts.map +1 -1
  502. package/dist/tools/complexity-tools.js +26 -0
  503. package/dist/tools/complexity-tools.js.map +1 -1
  504. package/dist/tools/context-levels/l0.d.ts +4 -0
  505. package/dist/tools/context-levels/l0.d.ts.map +1 -0
  506. package/dist/tools/context-levels/l0.js +17 -0
  507. package/dist/tools/context-levels/l0.js.map +1 -0
  508. package/dist/tools/context-levels/l1.d.ts +4 -0
  509. package/dist/tools/context-levels/l1.d.ts.map +1 -0
  510. package/dist/tools/context-levels/l1.js +26 -0
  511. package/dist/tools/context-levels/l1.js.map +1 -0
  512. package/dist/tools/context-levels/l2.d.ts +4 -0
  513. package/dist/tools/context-levels/l2.d.ts.map +1 -0
  514. package/dist/tools/context-levels/l2.js +36 -0
  515. package/dist/tools/context-levels/l2.js.map +1 -0
  516. package/dist/tools/context-levels/l3.d.ts +4 -0
  517. package/dist/tools/context-levels/l3.d.ts.map +1 -0
  518. package/dist/tools/context-levels/l3.js +30 -0
  519. package/dist/tools/context-levels/l3.js.map +1 -0
  520. package/dist/tools/context-levels/shared.d.ts +2 -0
  521. package/dist/tools/context-levels/shared.d.ts.map +1 -0
  522. package/dist/tools/context-levels/shared.js +4 -0
  523. package/dist/tools/context-levels/shared.js.map +1 -0
  524. package/dist/tools/context-levels/types.d.ts +34 -0
  525. package/dist/tools/context-levels/types.d.ts.map +1 -0
  526. package/dist/tools/context-levels/types.js +2 -0
  527. package/dist/tools/context-levels/types.js.map +1 -0
  528. package/dist/tools/context-tools.d.ts +2 -34
  529. package/dist/tools/context-tools.d.ts.map +1 -1
  530. package/dist/tools/context-tools.js +11 -127
  531. package/dist/tools/context-tools.js.map +1 -1
  532. package/dist/tools/conversation-cache.d.ts +6 -0
  533. package/dist/tools/conversation-cache.d.ts.map +1 -0
  534. package/dist/tools/conversation-cache.js +29 -0
  535. package/dist/tools/conversation-cache.js.map +1 -0
  536. package/dist/tools/conversation-index-tools.d.ts +39 -0
  537. package/dist/tools/conversation-index-tools.d.ts.map +1 -0
  538. package/dist/tools/conversation-index-tools.js +136 -0
  539. package/dist/tools/conversation-index-tools.js.map +1 -0
  540. package/dist/tools/conversation-paths.d.ts +4 -0
  541. package/dist/tools/conversation-paths.d.ts.map +1 -0
  542. package/dist/tools/conversation-paths.js +15 -0
  543. package/dist/tools/conversation-paths.js.map +1 -0
  544. package/dist/tools/conversation-search-tools.d.ts +52 -0
  545. package/dist/tools/conversation-search-tools.d.ts.map +1 -0
  546. package/dist/tools/conversation-search-tools.js +229 -0
  547. package/dist/tools/conversation-search-tools.js.map +1 -0
  548. package/dist/tools/conversation-tools.d.ts +6 -113
  549. package/dist/tools/conversation-tools.d.ts.map +1 -1
  550. package/dist/tools/conversation-tools.js +4 -464
  551. package/dist/tools/conversation-tools.js.map +1 -1
  552. package/dist/tools/cross-repo-outbound-lexer/call-detectors.d.ts +5 -0
  553. package/dist/tools/cross-repo-outbound-lexer/call-detectors.d.ts.map +1 -0
  554. package/dist/tools/cross-repo-outbound-lexer/call-detectors.js +76 -0
  555. package/dist/tools/cross-repo-outbound-lexer/call-detectors.js.map +1 -0
  556. package/dist/tools/cross-repo-outbound-lexer/context.d.ts +18 -0
  557. package/dist/tools/cross-repo-outbound-lexer/context.d.ts.map +1 -0
  558. package/dist/tools/cross-repo-outbound-lexer/context.js +33 -0
  559. package/dist/tools/cross-repo-outbound-lexer/context.js.map +1 -0
  560. package/dist/tools/cross-repo-outbound-lexer/literal-readers.d.ts +6 -0
  561. package/dist/tools/cross-repo-outbound-lexer/literal-readers.d.ts.map +1 -0
  562. package/dist/tools/cross-repo-outbound-lexer/literal-readers.js +65 -0
  563. package/dist/tools/cross-repo-outbound-lexer/literal-readers.js.map +1 -0
  564. package/dist/tools/cross-repo-outbound-lexer/non-code-states.d.ts +3 -0
  565. package/dist/tools/cross-repo-outbound-lexer/non-code-states.d.ts.map +1 -0
  566. package/dist/tools/cross-repo-outbound-lexer/non-code-states.js +103 -0
  567. package/dist/tools/cross-repo-outbound-lexer/non-code-states.js.map +1 -0
  568. package/dist/tools/cross-repo-outbound-lexer/template-reader.d.ts +3 -0
  569. package/dist/tools/cross-repo-outbound-lexer/template-reader.d.ts.map +1 -0
  570. package/dist/tools/cross-repo-outbound-lexer/template-reader.js +82 -0
  571. package/dist/tools/cross-repo-outbound-lexer/template-reader.js.map +1 -0
  572. package/dist/tools/cross-repo-outbound-lexer/types.d.ts +18 -0
  573. package/dist/tools/cross-repo-outbound-lexer/types.d.ts.map +1 -0
  574. package/dist/tools/cross-repo-outbound-lexer/types.js +2 -0
  575. package/dist/tools/cross-repo-outbound-lexer/types.js.map +1 -0
  576. package/dist/tools/cross-repo-outbound-lexer.d.ts +5 -31
  577. package/dist/tools/cross-repo-outbound-lexer.d.ts.map +1 -1
  578. package/dist/tools/cross-repo-outbound-lexer.js +75 -575
  579. package/dist/tools/cross-repo-outbound-lexer.js.map +1 -1
  580. package/dist/tools/dependency-audit-freshness-tools.d.ts +3 -0
  581. package/dist/tools/dependency-audit-freshness-tools.d.ts.map +1 -0
  582. package/dist/tools/dependency-audit-freshness-tools.js +62 -0
  583. package/dist/tools/dependency-audit-freshness-tools.js.map +1 -0
  584. package/dist/tools/dependency-audit-license-tools.d.ts +5 -0
  585. package/dist/tools/dependency-audit-license-tools.d.ts.map +1 -0
  586. package/dist/tools/dependency-audit-license-tools.js +75 -0
  587. package/dist/tools/dependency-audit-license-tools.js.map +1 -0
  588. package/dist/tools/dependency-audit-lockfile-tools.d.ts +3 -0
  589. package/dist/tools/dependency-audit-lockfile-tools.d.ts.map +1 -0
  590. package/dist/tools/dependency-audit-lockfile-tools.js +147 -0
  591. package/dist/tools/dependency-audit-lockfile-tools.js.map +1 -0
  592. package/dist/tools/dependency-audit-tools.d.ts +2 -54
  593. package/dist/tools/dependency-audit-tools.d.ts.map +1 -1
  594. package/dist/tools/dependency-audit-tools.js +69 -484
  595. package/dist/tools/dependency-audit-tools.js.map +1 -1
  596. package/dist/tools/dependency-audit-types.d.ts +65 -0
  597. package/dist/tools/dependency-audit-types.d.ts.map +1 -0
  598. package/dist/tools/dependency-audit-types.js +19 -0
  599. package/dist/tools/dependency-audit-types.js.map +1 -0
  600. package/dist/tools/dependency-audit-vulnerability-tools.d.ts +4 -0
  601. package/dist/tools/dependency-audit-vulnerability-tools.d.ts.map +1 -0
  602. package/dist/tools/dependency-audit-vulnerability-tools.js +103 -0
  603. package/dist/tools/dependency-audit-vulnerability-tools.js.map +1 -0
  604. package/dist/tools/diff-tools.d.ts.map +1 -1
  605. package/dist/tools/diff-tools.js +5 -7
  606. package/dist/tools/diff-tools.js.map +1 -1
  607. package/dist/tools/impact-tools.d.ts.map +1 -1
  608. package/dist/tools/impact-tools.js +5 -4
  609. package/dist/tools/impact-tools.js.map +1 -1
  610. package/dist/tools/index-shared.d.ts +17 -0
  611. package/dist/tools/index-shared.d.ts.map +1 -0
  612. package/dist/tools/index-shared.js +18 -0
  613. package/dist/tools/index-shared.js.map +1 -0
  614. package/dist/tools/index-tools/file-indexer.d.ts +27 -0
  615. package/dist/tools/index-tools/file-indexer.d.ts.map +1 -0
  616. package/dist/tools/index-tools/file-indexer.js +223 -0
  617. package/dist/tools/index-tools/file-indexer.js.map +1 -0
  618. package/dist/tools/index-tools/folder-indexer.d.ts +21 -0
  619. package/dist/tools/index-tools/folder-indexer.d.ts.map +1 -0
  620. package/dist/tools/index-tools/folder-indexer.js +399 -0
  621. package/dist/tools/index-tools/folder-indexer.js.map +1 -0
  622. package/dist/tools/index-tools/folder-merge.d.ts +23 -0
  623. package/dist/tools/index-tools/folder-merge.d.ts.map +1 -0
  624. package/dist/tools/index-tools/folder-merge.js +205 -0
  625. package/dist/tools/index-tools/folder-merge.js.map +1 -0
  626. package/dist/tools/index-tools/parse.d.ts +35 -0
  627. package/dist/tools/index-tools/parse.d.ts.map +1 -0
  628. package/dist/tools/index-tools/parse.js +262 -0
  629. package/dist/tools/index-tools/parse.js.map +1 -0
  630. package/dist/tools/index-tools/registry.d.ts +40 -0
  631. package/dist/tools/index-tools/registry.d.ts.map +1 -0
  632. package/dist/tools/index-tools/registry.js +258 -0
  633. package/dist/tools/index-tools/registry.js.map +1 -0
  634. package/dist/tools/index-tools/snapshots.d.ts +51 -0
  635. package/dist/tools/index-tools/snapshots.d.ts.map +1 -0
  636. package/dist/tools/index-tools/snapshots.js +223 -0
  637. package/dist/tools/index-tools/snapshots.js.map +1 -0
  638. package/dist/tools/index-tools/state.d.ts +8 -0
  639. package/dist/tools/index-tools/state.d.ts.map +1 -0
  640. package/dist/tools/index-tools/state.js +6 -0
  641. package/dist/tools/index-tools/state.js.map +1 -0
  642. package/dist/tools/index-tools/types.d.ts +20 -0
  643. package/dist/tools/index-tools/types.d.ts.map +1 -0
  644. package/dist/tools/index-tools/types.js +2 -0
  645. package/dist/tools/index-tools/types.js.map +1 -0
  646. package/dist/tools/index-tools/watcher.d.ts +10 -0
  647. package/dist/tools/index-tools/watcher.d.ts.map +1 -0
  648. package/dist/tools/index-tools/watcher.js +130 -0
  649. package/dist/tools/index-tools/watcher.js.map +1 -0
  650. package/dist/tools/index-tools.d.ts +16 -152
  651. package/dist/tools/index-tools.d.ts.map +1 -1
  652. package/dist/tools/index-tools.js +12 -1674
  653. package/dist/tools/index-tools.js.map +1 -1
  654. package/dist/tools/kotlin-extension-tools.d.ts +16 -0
  655. package/dist/tools/kotlin-extension-tools.d.ts.map +1 -0
  656. package/dist/tools/kotlin-extension-tools.js +31 -0
  657. package/dist/tools/kotlin-extension-tools.js.map +1 -0
  658. package/dist/tools/kotlin-flow-tools.d.ts +12 -0
  659. package/dist/tools/kotlin-flow-tools.d.ts.map +1 -0
  660. package/dist/tools/kotlin-flow-tools.js +72 -0
  661. package/dist/tools/kotlin-flow-tools.js.map +1 -0
  662. package/dist/tools/kotlin-kmp-tools.d.ts +29 -0
  663. package/dist/tools/kotlin-kmp-tools.d.ts.map +1 -0
  664. package/dist/tools/kotlin-kmp-tools.js +87 -0
  665. package/dist/tools/kotlin-kmp-tools.js.map +1 -0
  666. package/dist/tools/kotlin-sealed-tools.d.ts +27 -0
  667. package/dist/tools/kotlin-sealed-tools.d.ts.map +1 -0
  668. package/dist/tools/kotlin-sealed-tools.js +130 -0
  669. package/dist/tools/kotlin-sealed-tools.js.map +1 -0
  670. package/dist/tools/kotlin-suspend-tools.d.ts +24 -0
  671. package/dist/tools/kotlin-suspend-tools.d.ts.map +1 -0
  672. package/dist/tools/kotlin-suspend-tools.js +161 -0
  673. package/dist/tools/kotlin-suspend-tools.js.map +1 -0
  674. package/dist/tools/kotlin-tools.d.ts +6 -141
  675. package/dist/tools/kotlin-tools.d.ts.map +1 -1
  676. package/dist/tools/kotlin-tools.js +6 -571
  677. package/dist/tools/kotlin-tools.js.map +1 -1
  678. package/dist/tools/nest-audit-tools.d.ts +43 -0
  679. package/dist/tools/nest-audit-tools.d.ts.map +1 -0
  680. package/dist/tools/nest-audit-tools.js +232 -0
  681. package/dist/tools/nest-audit-tools.js.map +1 -0
  682. package/dist/tools/nest-di-tools.d.ts +32 -0
  683. package/dist/tools/nest-di-tools.d.ts.map +1 -0
  684. package/dist/tools/nest-di-tools.js +161 -0
  685. package/dist/tools/nest-di-tools.js.map +1 -0
  686. package/dist/tools/nest-guard-tools.d.ts +34 -0
  687. package/dist/tools/nest-guard-tools.d.ts.map +1 -0
  688. package/dist/tools/nest-guard-tools.js +240 -0
  689. package/dist/tools/nest-guard-tools.js.map +1 -0
  690. package/dist/tools/nest-lifecycle-tools.d.ts +16 -0
  691. package/dist/tools/nest-lifecycle-tools.d.ts.map +1 -0
  692. package/dist/tools/nest-lifecycle-tools.js +54 -0
  693. package/dist/tools/nest-lifecycle-tools.js.map +1 -0
  694. package/dist/tools/nest-module-tools.d.ts +28 -0
  695. package/dist/tools/nest-module-tools.d.ts.map +1 -0
  696. package/dist/tools/nest-module-tools.js +86 -0
  697. package/dist/tools/nest-module-tools.js.map +1 -0
  698. package/dist/tools/nest-pipeline-tools.d.ts +32 -0
  699. package/dist/tools/nest-pipeline-tools.d.ts.map +1 -0
  700. package/dist/tools/nest-pipeline-tools.js +122 -0
  701. package/dist/tools/nest-pipeline-tools.js.map +1 -0
  702. package/dist/tools/nest-route-tools.d.ts +43 -0
  703. package/dist/tools/nest-route-tools.d.ts.map +1 -0
  704. package/dist/tools/nest-route-tools.js +261 -0
  705. package/dist/tools/nest-route-tools.js.map +1 -0
  706. package/dist/tools/nest-shared-tools.d.ts +13 -0
  707. package/dist/tools/nest-shared-tools.d.ts.map +1 -0
  708. package/dist/tools/nest-shared-tools.js +36 -0
  709. package/dist/tools/nest-shared-tools.js.map +1 -0
  710. package/dist/tools/nest-tools.d.ts +18 -195
  711. package/dist/tools/nest-tools.d.ts.map +1 -1
  712. package/dist/tools/nest-tools.js +11 -1140
  713. package/dist/tools/nest-tools.js.map +1 -1
  714. package/dist/tools/pattern-registry.d.ts +4 -0
  715. package/dist/tools/pattern-registry.d.ts.map +1 -0
  716. package/dist/tools/pattern-registry.js +3 -0
  717. package/dist/tools/pattern-registry.js.map +1 -0
  718. package/dist/tools/pattern-tools.d.ts +5 -46
  719. package/dist/tools/pattern-tools.d.ts.map +1 -1
  720. package/dist/tools/pattern-tools.js +4 -1102
  721. package/dist/tools/pattern-tools.js.map +1 -1
  722. package/dist/tools/patterns/adapters/astro.d.ts +3 -0
  723. package/dist/tools/patterns/adapters/astro.d.ts.map +1 -0
  724. package/dist/tools/patterns/adapters/astro.js +56 -0
  725. package/dist/tools/patterns/adapters/astro.js.map +1 -0
  726. package/dist/tools/patterns/adapters/common.d.ts +3 -0
  727. package/dist/tools/patterns/adapters/common.d.ts.map +1 -0
  728. package/dist/tools/patterns/adapters/common.js +38 -0
  729. package/dist/tools/patterns/adapters/common.js.map +1 -0
  730. package/dist/tools/patterns/adapters/database.d.ts +3 -0
  731. package/dist/tools/patterns/adapters/database.d.ts.map +1 -0
  732. package/dist/tools/patterns/adapters/database.js +32 -0
  733. package/dist/tools/patterns/adapters/database.js.map +1 -0
  734. package/dist/tools/patterns/adapters/hono.d.ts +3 -0
  735. package/dist/tools/patterns/adapters/hono.d.ts.map +1 -0
  736. package/dist/tools/patterns/adapters/hono.js +32 -0
  737. package/dist/tools/patterns/adapters/hono.js.map +1 -0
  738. package/dist/tools/patterns/adapters/kotlin.d.ts +3 -0
  739. package/dist/tools/patterns/adapters/kotlin.d.ts.map +1 -0
  740. package/dist/tools/patterns/adapters/kotlin.js +50 -0
  741. package/dist/tools/patterns/adapters/kotlin.js.map +1 -0
  742. package/dist/tools/patterns/adapters/nest.d.ts +3 -0
  743. package/dist/tools/patterns/adapters/nest.d.ts.map +1 -0
  744. package/dist/tools/patterns/adapters/nest.js +122 -0
  745. package/dist/tools/patterns/adapters/nest.js.map +1 -0
  746. package/dist/tools/patterns/adapters/nextjs.d.ts +4 -0
  747. package/dist/tools/patterns/adapters/nextjs.d.ts.map +1 -0
  748. package/dist/tools/patterns/adapters/nextjs.js +59 -0
  749. package/dist/tools/patterns/adapters/nextjs.js.map +1 -0
  750. package/dist/tools/patterns/adapters/php.d.ts +3 -0
  751. package/dist/tools/patterns/adapters/php.d.ts.map +1 -0
  752. package/dist/tools/patterns/adapters/php.js +157 -0
  753. package/dist/tools/patterns/adapters/php.js.map +1 -0
  754. package/dist/tools/patterns/adapters/python.d.ts +3 -0
  755. package/dist/tools/patterns/adapters/python.d.ts.map +1 -0
  756. package/dist/tools/patterns/adapters/python.js +72 -0
  757. package/dist/tools/patterns/adapters/python.js.map +1 -0
  758. package/dist/tools/patterns/adapters/react.d.ts +4 -0
  759. package/dist/tools/patterns/adapters/react.d.ts.map +1 -0
  760. package/dist/tools/patterns/adapters/react.js +345 -0
  761. package/dist/tools/patterns/adapters/react.js.map +1 -0
  762. package/dist/tools/patterns/catalog.d.ts +8 -0
  763. package/dist/tools/patterns/catalog.d.ts.map +1 -0
  764. package/dist/tools/patterns/catalog.js +30 -0
  765. package/dist/tools/patterns/catalog.js.map +1 -0
  766. package/dist/tools/patterns/execution.d.ts +38 -0
  767. package/dist/tools/patterns/execution.d.ts.map +1 -0
  768. package/dist/tools/patterns/execution.js +298 -0
  769. package/dist/tools/patterns/execution.js.map +1 -0
  770. package/dist/tools/patterns/types.d.ts +13 -0
  771. package/dist/tools/patterns/types.d.ts.map +1 -0
  772. package/dist/tools/patterns/types.js +2 -0
  773. package/dist/tools/patterns/types.js.map +1 -0
  774. package/dist/tools/pg-drift-compare.d.ts +3 -0
  775. package/dist/tools/pg-drift-compare.d.ts.map +1 -0
  776. package/dist/tools/pg-drift-compare.js +30 -0
  777. package/dist/tools/pg-drift-compare.js.map +1 -0
  778. package/dist/tools/pg-drift-schema.d.ts +5 -0
  779. package/dist/tools/pg-drift-schema.d.ts.map +1 -0
  780. package/dist/tools/pg-drift-schema.js +28 -0
  781. package/dist/tools/pg-drift-schema.js.map +1 -0
  782. package/dist/tools/pg-drift-types.d.ts +25 -0
  783. package/dist/tools/pg-drift-types.d.ts.map +1 -0
  784. package/dist/tools/pg-drift-types.js +2 -0
  785. package/dist/tools/pg-drift-types.js.map +1 -0
  786. package/dist/tools/pg-drift.d.ts +5 -0
  787. package/dist/tools/pg-drift.d.ts.map +1 -0
  788. package/dist/tools/pg-drift.js +30 -0
  789. package/dist/tools/pg-drift.js.map +1 -0
  790. package/dist/tools/pg-introspect-formatters.d.ts +7 -0
  791. package/dist/tools/pg-introspect-formatters.d.ts.map +1 -0
  792. package/dist/tools/pg-introspect-formatters.js +66 -0
  793. package/dist/tools/pg-introspect-formatters.js.map +1 -0
  794. package/dist/tools/pg-introspect-tools.d.ts +5 -146
  795. package/dist/tools/pg-introspect-tools.d.ts.map +1 -1
  796. package/dist/tools/pg-introspect-tools.js +3 -395
  797. package/dist/tools/pg-introspect-tools.js.map +1 -1
  798. package/dist/tools/pg-introspection.d.ts +90 -0
  799. package/dist/tools/pg-introspection.d.ts.map +1 -0
  800. package/dist/tools/pg-introspection.js +288 -0
  801. package/dist/tools/pg-introspection.js.map +1 -0
  802. package/dist/tools/php-active-record-tools.d.ts +22 -0
  803. package/dist/tools/php-active-record-tools.d.ts.map +1 -0
  804. package/dist/tools/php-active-record-tools.js +165 -0
  805. package/dist/tools/php-active-record-tools.js.map +1 -0
  806. package/dist/tools/php-event-tools.d.ts +21 -0
  807. package/dist/tools/php-event-tools.d.ts.map +1 -0
  808. package/dist/tools/php-event-tools.js +205 -0
  809. package/dist/tools/php-event-tools.js.map +1 -0
  810. package/dist/tools/php-god-model-tools.d.ts +34 -0
  811. package/dist/tools/php-god-model-tools.d.ts.map +1 -0
  812. package/dist/tools/php-god-model-tools.js +88 -0
  813. package/dist/tools/php-god-model-tools.js.map +1 -0
  814. package/dist/tools/php-import-utils.d.ts +10 -0
  815. package/dist/tools/php-import-utils.d.ts.map +1 -0
  816. package/dist/tools/php-import-utils.js +71 -0
  817. package/dist/tools/php-import-utils.js.map +1 -0
  818. package/dist/tools/php-namespace-tools.d.ts +10 -0
  819. package/dist/tools/php-namespace-tools.d.ts.map +1 -0
  820. package/dist/tools/php-namespace-tools.js +98 -0
  821. package/dist/tools/php-namespace-tools.js.map +1 -0
  822. package/dist/tools/php-nplus1-tools.d.ts +27 -0
  823. package/dist/tools/php-nplus1-tools.d.ts.map +1 -0
  824. package/dist/tools/php-nplus1-tools.js +191 -0
  825. package/dist/tools/php-nplus1-tools.js.map +1 -0
  826. package/dist/tools/php-project-audit-tools.d.ts +31 -0
  827. package/dist/tools/php-project-audit-tools.d.ts.map +1 -0
  828. package/dist/tools/php-project-audit-tools.js +173 -0
  829. package/dist/tools/php-project-audit-tools.js.map +1 -0
  830. package/dist/tools/php-security-tools.d.ts +24 -0
  831. package/dist/tools/php-security-tools.d.ts.map +1 -0
  832. package/dist/tools/php-security-tools.js +172 -0
  833. package/dist/tools/php-security-tools.js.map +1 -0
  834. package/dist/tools/php-service-tools.d.ts +25 -0
  835. package/dist/tools/php-service-tools.d.ts.map +1 -0
  836. package/dist/tools/php-service-tools.js +326 -0
  837. package/dist/tools/php-service-tools.js.map +1 -0
  838. package/dist/tools/php-tools.d.ts +21 -255
  839. package/dist/tools/php-tools.d.ts.map +1 -1
  840. package/dist/tools/php-tools.js +12 -1423
  841. package/dist/tools/php-tools.js.map +1 -1
  842. package/dist/tools/php-view-tools.d.ts +76 -0
  843. package/dist/tools/php-view-tools.d.ts.map +1 -0
  844. package/dist/tools/php-view-tools.js +413 -0
  845. package/dist/tools/php-view-tools.js.map +1 -0
  846. package/dist/tools/plan-turn/formatter.d.ts +3 -0
  847. package/dist/tools/plan-turn/formatter.d.ts.map +1 -0
  848. package/dist/tools/plan-turn/formatter.js +88 -0
  849. package/dist/tools/plan-turn/formatter.js.map +1 -0
  850. package/dist/tools/plan-turn/framework-context.d.ts +5 -0
  851. package/dist/tools/plan-turn/framework-context.d.ts.map +1 -0
  852. package/dist/tools/plan-turn/framework-context.js +68 -0
  853. package/dist/tools/plan-turn/framework-context.js.map +1 -0
  854. package/dist/tools/plan-turn/framework-data.d.ts +5 -0
  855. package/dist/tools/plan-turn/framework-data.d.ts.map +1 -0
  856. package/dist/tools/plan-turn/framework-data.js +48 -0
  857. package/dist/tools/plan-turn/framework-data.js.map +1 -0
  858. package/dist/tools/plan-turn/orchestrator.d.ts +4 -0
  859. package/dist/tools/plan-turn/orchestrator.d.ts.map +1 -0
  860. package/dist/tools/plan-turn/orchestrator.js +262 -0
  861. package/dist/tools/plan-turn/orchestrator.js.map +1 -0
  862. package/dist/tools/plan-turn/query-parser.d.ts +6 -0
  863. package/dist/tools/plan-turn/query-parser.d.ts.map +1 -0
  864. package/dist/tools/plan-turn/query-parser.js +60 -0
  865. package/dist/tools/plan-turn/query-parser.js.map +1 -0
  866. package/dist/tools/plan-turn/recommendations.d.ts +11 -0
  867. package/dist/tools/plan-turn/recommendations.d.ts.map +1 -0
  868. package/dist/tools/plan-turn/recommendations.js +93 -0
  869. package/dist/tools/plan-turn/recommendations.js.map +1 -0
  870. package/dist/tools/plan-turn/stale-index.d.ts +4 -0
  871. package/dist/tools/plan-turn/stale-index.d.ts.map +1 -0
  872. package/dist/tools/plan-turn/stale-index.js +17 -0
  873. package/dist/tools/plan-turn/stale-index.js.map +1 -0
  874. package/dist/tools/plan-turn/types.d.ts +61 -0
  875. package/dist/tools/plan-turn/types.d.ts.map +1 -0
  876. package/dist/tools/plan-turn/types.js +2 -0
  877. package/dist/tools/plan-turn/types.js.map +1 -0
  878. package/dist/tools/plan-turn-tools.d.ts +8 -111
  879. package/dist/tools/plan-turn-tools.d.ts.map +1 -1
  880. package/dist/tools/plan-turn-tools.js +6 -696
  881. package/dist/tools/plan-turn-tools.js.map +1 -1
  882. package/dist/tools/project-profile-express.d.ts +3 -0
  883. package/dist/tools/project-profile-express.d.ts.map +1 -0
  884. package/dist/tools/project-profile-express.js +46 -0
  885. package/dist/tools/project-profile-express.js.map +1 -0
  886. package/dist/tools/project-profile-extractors.d.ts +9 -0
  887. package/dist/tools/project-profile-extractors.d.ts.map +1 -0
  888. package/dist/tools/project-profile-extractors.js +312 -0
  889. package/dist/tools/project-profile-extractors.js.map +1 -0
  890. package/dist/tools/project-profile-fs.d.ts +3 -0
  891. package/dist/tools/project-profile-fs.d.ts.map +1 -0
  892. package/dist/tools/project-profile-fs.js +19 -0
  893. package/dist/tools/project-profile-fs.js.map +1 -0
  894. package/dist/tools/project-profile-hono.d.ts +13 -0
  895. package/dist/tools/project-profile-hono.d.ts.map +1 -0
  896. package/dist/tools/project-profile-hono.js +110 -0
  897. package/dist/tools/project-profile-hono.js.map +1 -0
  898. package/dist/tools/project-profile-imports.d.ts +6 -0
  899. package/dist/tools/project-profile-imports.d.ts.map +1 -0
  900. package/dist/tools/project-profile-imports.js +95 -0
  901. package/dist/tools/project-profile-imports.js.map +1 -0
  902. package/dist/tools/project-profile-nest.d.ts +8 -0
  903. package/dist/tools/project-profile-nest.d.ts.map +1 -0
  904. package/dist/tools/project-profile-nest.js +352 -0
  905. package/dist/tools/project-profile-nest.js.map +1 -0
  906. package/dist/tools/project-profile-next.d.ts +5 -0
  907. package/dist/tools/project-profile-next.d.ts.map +1 -0
  908. package/dist/tools/project-profile-next.js +92 -0
  909. package/dist/tools/project-profile-next.js.map +1 -0
  910. package/dist/tools/project-profile-persistence.d.ts +3 -0
  911. package/dist/tools/project-profile-persistence.d.ts.map +1 -0
  912. package/dist/tools/project-profile-persistence.js +19 -0
  913. package/dist/tools/project-profile-persistence.js.map +1 -0
  914. package/dist/tools/project-profile-php.d.ts +8 -0
  915. package/dist/tools/project-profile-php.d.ts.map +1 -0
  916. package/dist/tools/project-profile-php.js +76 -0
  917. package/dist/tools/project-profile-php.js.map +1 -0
  918. package/dist/tools/project-profile-python.d.ts +5 -0
  919. package/dist/tools/project-profile-python.d.ts.map +1 -0
  920. package/dist/tools/project-profile-python.js +51 -0
  921. package/dist/tools/project-profile-python.js.map +1 -0
  922. package/dist/tools/project-profile-react.d.ts +6 -0
  923. package/dist/tools/project-profile-react.d.ts.map +1 -0
  924. package/dist/tools/project-profile-react.js +106 -0
  925. package/dist/tools/project-profile-react.js.map +1 -0
  926. package/dist/tools/project-profile-stack.d.ts +3 -0
  927. package/dist/tools/project-profile-stack.d.ts.map +1 -0
  928. package/dist/tools/project-profile-stack.js +354 -0
  929. package/dist/tools/project-profile-stack.js.map +1 -0
  930. package/dist/tools/project-profile-summary.d.ts +30 -0
  931. package/dist/tools/project-profile-summary.d.ts.map +1 -0
  932. package/dist/tools/project-profile-summary.js +112 -0
  933. package/dist/tools/project-profile-summary.js.map +1 -0
  934. package/dist/tools/project-profile-types.d.ts +315 -0
  935. package/dist/tools/project-profile-types.d.ts.map +1 -0
  936. package/dist/tools/project-profile-types.js +2 -0
  937. package/dist/tools/project-profile-types.js.map +1 -0
  938. package/dist/tools/project-tools.d.ts +17 -383
  939. package/dist/tools/project-tools.d.ts.map +1 -1
  940. package/dist/tools/project-tools.js +35 -1621
  941. package/dist/tools/project-tools.js.map +1 -1
  942. package/dist/tools/python-audit/aggregate.d.ts +3 -0
  943. package/dist/tools/python-audit/aggregate.d.ts.map +1 -0
  944. package/dist/tools/python-audit/aggregate.js +103 -0
  945. package/dist/tools/python-audit/aggregate.js.map +1 -0
  946. package/dist/tools/python-audit/checks/anti-patterns.d.ts +6 -0
  947. package/dist/tools/python-audit/checks/anti-patterns.d.ts.map +1 -0
  948. package/dist/tools/python-audit/checks/anti-patterns.js +14 -0
  949. package/dist/tools/python-audit/checks/anti-patterns.js.map +1 -0
  950. package/dist/tools/python-audit/checks/celery.d.ts +2 -0
  951. package/dist/tools/python-audit/checks/celery.d.ts.map +1 -0
  952. package/dist/tools/python-audit/checks/celery.js +5 -0
  953. package/dist/tools/python-audit/checks/celery.js.map +1 -0
  954. package/dist/tools/python-audit/checks/circular-imports.d.ts +2 -0
  955. package/dist/tools/python-audit/checks/circular-imports.d.ts.map +1 -0
  956. package/dist/tools/python-audit/checks/circular-imports.js +5 -0
  957. package/dist/tools/python-audit/checks/circular-imports.js.map +1 -0
  958. package/dist/tools/python-audit/checks/dead-code.d.ts +2 -0
  959. package/dist/tools/python-audit/checks/dead-code.d.ts.map +1 -0
  960. package/dist/tools/python-audit/checks/dead-code.js +5 -0
  961. package/dist/tools/python-audit/checks/dead-code.js.map +1 -0
  962. package/dist/tools/python-audit/checks/dependencies.d.ts +2 -0
  963. package/dist/tools/python-audit/checks/dependencies.d.ts.map +1 -0
  964. package/dist/tools/python-audit/checks/dependencies.js +5 -0
  965. package/dist/tools/python-audit/checks/dependencies.js.map +1 -0
  966. package/dist/tools/python-audit/checks/django-settings.d.ts +2 -0
  967. package/dist/tools/python-audit/checks/django-settings.d.ts.map +1 -0
  968. package/dist/tools/python-audit/checks/django-settings.js +5 -0
  969. package/dist/tools/python-audit/checks/django-settings.js.map +1 -0
  970. package/dist/tools/python-audit/checks/framework-wiring.d.ts +2 -0
  971. package/dist/tools/python-audit/checks/framework-wiring.d.ts.map +1 -0
  972. package/dist/tools/python-audit/checks/framework-wiring.js +5 -0
  973. package/dist/tools/python-audit/checks/framework-wiring.js.map +1 -0
  974. package/dist/tools/python-audit/checks/pytest-fixtures.d.ts +2 -0
  975. package/dist/tools/python-audit/checks/pytest-fixtures.d.ts.map +1 -0
  976. package/dist/tools/python-audit/checks/pytest-fixtures.js +5 -0
  977. package/dist/tools/python-audit/checks/pytest-fixtures.js.map +1 -0
  978. package/dist/tools/python-audit/runner.d.ts +5 -0
  979. package/dist/tools/python-audit/runner.d.ts.map +1 -0
  980. package/dist/tools/python-audit/runner.js +18 -0
  981. package/dist/tools/python-audit/runner.js.map +1 -0
  982. package/dist/tools/python-audit/types.d.ts +43 -0
  983. package/dist/tools/python-audit/types.d.ts.map +1 -0
  984. package/dist/tools/python-audit/types.js +2 -0
  985. package/dist/tools/python-audit/types.js.map +1 -0
  986. package/dist/tools/python-audit.d.ts +3 -39
  987. package/dist/tools/python-audit.d.ts.map +1 -1
  988. package/dist/tools/python-audit.js +34 -233
  989. package/dist/tools/python-audit.js.map +1 -1
  990. package/dist/tools/react-compiler-tools.d.ts +37 -0
  991. package/dist/tools/react-compiler-tools.d.ts.map +1 -0
  992. package/dist/tools/react-compiler-tools.js +104 -0
  993. package/dist/tools/react-compiler-tools.js.map +1 -0
  994. package/dist/tools/react-component-tree-tools.d.ts +58 -0
  995. package/dist/tools/react-component-tree-tools.d.ts.map +1 -0
  996. package/dist/tools/react-component-tree-tools.js +292 -0
  997. package/dist/tools/react-component-tree-tools.js.map +1 -0
  998. package/dist/tools/react-context-tools.d.ts +41 -0
  999. package/dist/tools/react-context-tools.d.ts.map +1 -0
  1000. package/dist/tools/react-context-tools.js +76 -0
  1001. package/dist/tools/react-context-tools.js.map +1 -0
  1002. package/dist/tools/react-hooks-tools.d.ts +58 -0
  1003. package/dist/tools/react-hooks-tools.d.ts.map +1 -0
  1004. package/dist/tools/react-hooks-tools.js +144 -0
  1005. package/dist/tools/react-hooks-tools.js.map +1 -0
  1006. package/dist/tools/react-quickstart-tools.d.ts +59 -0
  1007. package/dist/tools/react-quickstart-tools.d.ts.map +1 -0
  1008. package/dist/tools/react-quickstart-tools.js +164 -0
  1009. package/dist/tools/react-quickstart-tools.js.map +1 -0
  1010. package/dist/tools/react-render-tools.d.ts +75 -0
  1011. package/dist/tools/react-render-tools.d.ts.map +1 -0
  1012. package/dist/tools/react-render-tools.js +234 -0
  1013. package/dist/tools/react-render-tools.js.map +1 -0
  1014. package/dist/tools/react-shared-tools.d.ts +5 -0
  1015. package/dist/tools/react-shared-tools.d.ts.map +1 -0
  1016. package/dist/tools/react-shared-tools.js +12 -0
  1017. package/dist/tools/react-shared-tools.js.map +1 -0
  1018. package/dist/tools/react-suspense-tools.d.ts +29 -0
  1019. package/dist/tools/react-suspense-tools.d.ts.map +1 -0
  1020. package/dist/tools/react-suspense-tools.js +269 -0
  1021. package/dist/tools/react-suspense-tools.js.map +1 -0
  1022. package/dist/tools/react-tools.d.ts +19 -340
  1023. package/dist/tools/react-tools.d.ts.map +1 -1
  1024. package/dist/tools/react-tools.js +10 -1263
  1025. package/dist/tools/react-tools.js.map +1 -1
  1026. package/dist/tools/review-diff/check-runner.d.ts +5 -0
  1027. package/dist/tools/review-diff/check-runner.d.ts.map +1 -0
  1028. package/dist/tools/review-diff/check-runner.js +26 -0
  1029. package/dist/tools/review-diff/check-runner.js.map +1 -0
  1030. package/dist/tools/review-diff/checks/astro-hydration.d.ts +8 -0
  1031. package/dist/tools/review-diff/checks/astro-hydration.d.ts.map +1 -0
  1032. package/dist/tools/review-diff/checks/astro-hydration.js +54 -0
  1033. package/dist/tools/review-diff/checks/astro-hydration.js.map +1 -0
  1034. package/dist/tools/review-diff/checks/blast-radius.d.ts +7 -0
  1035. package/dist/tools/review-diff/checks/blast-radius.d.ts.map +1 -0
  1036. package/dist/tools/review-diff/checks/blast-radius.js +39 -0
  1037. package/dist/tools/review-diff/checks/blast-radius.js.map +1 -0
  1038. package/dist/tools/review-diff/checks/breaking.d.ts +13 -0
  1039. package/dist/tools/review-diff/checks/breaking.d.ts.map +1 -0
  1040. package/dist/tools/review-diff/checks/breaking.js +115 -0
  1041. package/dist/tools/review-diff/checks/breaking.js.map +1 -0
  1042. package/dist/tools/review-diff/checks/bug-patterns.d.ts +8 -0
  1043. package/dist/tools/review-diff/checks/bug-patterns.d.ts.map +1 -0
  1044. package/dist/tools/review-diff/checks/bug-patterns.js +130 -0
  1045. package/dist/tools/review-diff/checks/bug-patterns.js.map +1 -0
  1046. package/dist/tools/review-diff/checks/complexity.d.ts +8 -0
  1047. package/dist/tools/review-diff/checks/complexity.d.ts.map +1 -0
  1048. package/dist/tools/review-diff/checks/complexity.js +41 -0
  1049. package/dist/tools/review-diff/checks/complexity.js.map +1 -0
  1050. package/dist/tools/review-diff/checks/coupling.d.ts +7 -0
  1051. package/dist/tools/review-diff/checks/coupling.d.ts.map +1 -0
  1052. package/dist/tools/review-diff/checks/coupling.js +52 -0
  1053. package/dist/tools/review-diff/checks/coupling.js.map +1 -0
  1054. package/dist/tools/review-diff/checks/dead-code.d.ts +7 -0
  1055. package/dist/tools/review-diff/checks/dead-code.d.ts.map +1 -0
  1056. package/dist/tools/review-diff/checks/dead-code.js +39 -0
  1057. package/dist/tools/review-diff/checks/dead-code.js.map +1 -0
  1058. package/dist/tools/review-diff/checks/hotspots.d.ts +8 -0
  1059. package/dist/tools/review-diff/checks/hotspots.d.ts.map +1 -0
  1060. package/dist/tools/review-diff/checks/hotspots.js +39 -0
  1061. package/dist/tools/review-diff/checks/hotspots.js.map +1 -0
  1062. package/dist/tools/review-diff/checks/secrets.d.ts +7 -0
  1063. package/dist/tools/review-diff/checks/secrets.d.ts.map +1 -0
  1064. package/dist/tools/review-diff/checks/secrets.js +38 -0
  1065. package/dist/tools/review-diff/checks/secrets.js.map +1 -0
  1066. package/dist/tools/review-diff/checks/test-gaps.d.ts +16 -0
  1067. package/dist/tools/review-diff/checks/test-gaps.d.ts.map +1 -0
  1068. package/dist/tools/review-diff/checks/test-gaps.js +77 -0
  1069. package/dist/tools/review-diff/checks/test-gaps.js.map +1 -0
  1070. package/dist/tools/review-diff/constants.d.ts +6 -0
  1071. package/dist/tools/review-diff/constants.d.ts.map +1 -0
  1072. package/dist/tools/review-diff/constants.js +16 -0
  1073. package/dist/tools/review-diff/constants.js.map +1 -0
  1074. package/dist/tools/review-diff/file-pattern.d.ts +2 -0
  1075. package/dist/tools/review-diff/file-pattern.d.ts.map +1 -0
  1076. package/dist/tools/review-diff/file-pattern.js +9 -0
  1077. package/dist/tools/review-diff/file-pattern.js.map +1 -0
  1078. package/dist/tools/review-diff/orchestrator.d.ts +3 -0
  1079. package/dist/tools/review-diff/orchestrator.d.ts.map +1 -0
  1080. package/dist/tools/review-diff/orchestrator.js +173 -0
  1081. package/dist/tools/review-diff/orchestrator.js.map +1 -0
  1082. package/dist/tools/review-diff/scoring.d.ts +31 -0
  1083. package/dist/tools/review-diff/scoring.d.ts.map +1 -0
  1084. package/dist/tools/review-diff/scoring.js +82 -0
  1085. package/dist/tools/review-diff/scoring.js.map +1 -0
  1086. package/dist/tools/review-diff/timeout.d.ts +5 -0
  1087. package/dist/tools/review-diff/timeout.d.ts.map +1 -0
  1088. package/dist/tools/review-diff/timeout.js +14 -0
  1089. package/dist/tools/review-diff/timeout.js.map +1 -0
  1090. package/dist/tools/review-diff/types.d.ts +56 -0
  1091. package/dist/tools/review-diff/types.d.ts.map +1 -0
  1092. package/dist/tools/review-diff/types.js +2 -0
  1093. package/dist/tools/review-diff/types.js.map +1 -0
  1094. package/dist/tools/review-diff-tools.d.ts +19 -147
  1095. package/dist/tools/review-diff-tools.d.ts.map +1 -1
  1096. package/dist/tools/review-diff-tools.js +18 -941
  1097. package/dist/tools/review-diff-tools.js.map +1 -1
  1098. package/dist/tools/route-shared.d.ts +6 -0
  1099. package/dist/tools/route-shared.d.ts.map +1 -0
  1100. package/dist/tools/route-shared.js +37 -0
  1101. package/dist/tools/route-shared.js.map +1 -0
  1102. package/dist/tools/route-tools.d.ts +1 -7
  1103. package/dist/tools/route-tools.d.ts.map +1 -1
  1104. package/dist/tools/route-tools.js +2 -22
  1105. package/dist/tools/route-tools.js.map +1 -1
  1106. package/dist/tools/search-tools/constants.d.ts +33 -0
  1107. package/dist/tools/search-tools/constants.d.ts.map +1 -0
  1108. package/dist/tools/search-tools/constants.js +54 -0
  1109. package/dist/tools/search-tools/constants.js.map +1 -0
  1110. package/dist/tools/search-tools/ripgrep.d.ts +13 -0
  1111. package/dist/tools/search-tools/ripgrep.d.ts.map +1 -0
  1112. package/dist/tools/search-tools/ripgrep.js +138 -0
  1113. package/dist/tools/search-tools/ripgrep.js.map +1 -0
  1114. package/dist/tools/search-tools/semantic-search.d.ts +9 -0
  1115. package/dist/tools/search-tools/semantic-search.d.ts.map +1 -0
  1116. package/dist/tools/search-tools/semantic-search.js +19 -0
  1117. package/dist/tools/search-tools/semantic-search.js.map +1 -0
  1118. package/dist/tools/search-tools/symbol-search.d.ts +4 -0
  1119. package/dist/tools/search-tools/symbol-search.d.ts.map +1 -0
  1120. package/dist/tools/search-tools/symbol-search.js +146 -0
  1121. package/dist/tools/search-tools/symbol-search.js.map +1 -0
  1122. package/dist/tools/search-tools/text-search.d.ts +10 -0
  1123. package/dist/tools/search-tools/text-search.d.ts.map +1 -0
  1124. package/dist/tools/search-tools/text-search.js +260 -0
  1125. package/dist/tools/search-tools/text-search.js.map +1 -0
  1126. package/dist/tools/search-tools/types.d.ts +28 -0
  1127. package/dist/tools/search-tools/types.d.ts.map +1 -0
  1128. package/dist/tools/search-tools/types.js +2 -0
  1129. package/dist/tools/search-tools/types.js.map +1 -0
  1130. package/dist/tools/search-tools/zero-hit.d.ts +3 -0
  1131. package/dist/tools/search-tools/zero-hit.d.ts.map +1 -0
  1132. package/dist/tools/search-tools/zero-hit.js +92 -0
  1133. package/dist/tools/search-tools/zero-hit.js.map +1 -0
  1134. package/dist/tools/search-tools.d.ts +5 -64
  1135. package/dist/tools/search-tools.d.ts.map +1 -1
  1136. package/dist/tools/search-tools.js +4 -770
  1137. package/dist/tools/search-tools.js.map +1 -1
  1138. package/dist/tools/secret-detectors.d.ts +12 -0
  1139. package/dist/tools/secret-detectors.d.ts.map +1 -0
  1140. package/dist/tools/secret-detectors.js +86 -0
  1141. package/dist/tools/secret-detectors.js.map +1 -0
  1142. package/dist/tools/secret-file-scanner.d.ts +7 -0
  1143. package/dist/tools/secret-file-scanner.d.ts.map +1 -0
  1144. package/dist/tools/secret-file-scanner.js +52 -0
  1145. package/dist/tools/secret-file-scanner.js.map +1 -0
  1146. package/dist/tools/secret-scan-cache.d.ts +6 -0
  1147. package/dist/tools/secret-scan-cache.d.ts.map +1 -0
  1148. package/dist/tools/secret-scan-cache.js +14 -0
  1149. package/dist/tools/secret-scan-cache.js.map +1 -0
  1150. package/dist/tools/secret-scan-shared.d.ts +5 -0
  1151. package/dist/tools/secret-scan-shared.d.ts.map +1 -0
  1152. package/dist/tools/secret-scan-shared.js +4 -0
  1153. package/dist/tools/secret-scan-shared.js.map +1 -0
  1154. package/dist/tools/secret-scan-types.d.ts +21 -0
  1155. package/dist/tools/secret-scan-types.d.ts.map +1 -0
  1156. package/dist/tools/secret-scan-types.js +2 -0
  1157. package/dist/tools/secret-scan-types.js.map +1 -0
  1158. package/dist/tools/secret-tools.d.ts +3 -75
  1159. package/dist/tools/secret-tools.d.ts.map +1 -1
  1160. package/dist/tools/secret-tools.js +4 -316
  1161. package/dist/tools/secret-tools.js.map +1 -1
  1162. package/dist/tools/sql-audit-tools.d.ts +42 -0
  1163. package/dist/tools/sql-audit-tools.d.ts.map +1 -0
  1164. package/dist/tools/sql-audit-tools.js +130 -0
  1165. package/dist/tools/sql-audit-tools.js.map +1 -0
  1166. package/dist/tools/sql-column-tools.d.ts +28 -0
  1167. package/dist/tools/sql-column-tools.d.ts.map +1 -0
  1168. package/dist/tools/sql-column-tools.js +58 -0
  1169. package/dist/tools/sql-column-tools.js.map +1 -0
  1170. package/dist/tools/sql-complexity-tools.d.ts +22 -0
  1171. package/dist/tools/sql-complexity-tools.d.ts.map +1 -0
  1172. package/dist/tools/sql-complexity-tools.js +60 -0
  1173. package/dist/tools/sql-complexity-tools.js.map +1 -0
  1174. package/dist/tools/sql-dml-safety-tools.d.ts +26 -0
  1175. package/dist/tools/sql-dml-safety-tools.d.ts.map +1 -0
  1176. package/dist/tools/sql-dml-safety-tools.js +104 -0
  1177. package/dist/tools/sql-dml-safety-tools.js.map +1 -0
  1178. package/dist/tools/sql-drift-tools.d.ts +39 -0
  1179. package/dist/tools/sql-drift-tools.d.ts.map +1 -0
  1180. package/dist/tools/sql-drift-tools.js +238 -0
  1181. package/dist/tools/sql-drift-tools.js.map +1 -0
  1182. package/dist/tools/sql-lint-schema-tools.d.ts +28 -0
  1183. package/dist/tools/sql-lint-schema-tools.d.ts.map +1 -0
  1184. package/dist/tools/sql-lint-schema-tools.js +96 -0
  1185. package/dist/tools/sql-lint-schema-tools.js.map +1 -0
  1186. package/dist/tools/sql-migration-diff-tools.d.ts +24 -0
  1187. package/dist/tools/sql-migration-diff-tools.d.ts.map +1 -0
  1188. package/dist/tools/sql-migration-diff-tools.js +120 -0
  1189. package/dist/tools/sql-migration-diff-tools.js.map +1 -0
  1190. package/dist/tools/sql-orphan-table-tools.d.ts +20 -0
  1191. package/dist/tools/sql-orphan-table-tools.d.ts.map +1 -0
  1192. package/dist/tools/sql-orphan-table-tools.js +70 -0
  1193. package/dist/tools/sql-orphan-table-tools.js.map +1 -0
  1194. package/dist/tools/sql-query-tools.d.ts +32 -0
  1195. package/dist/tools/sql-query-tools.d.ts.map +1 -0
  1196. package/dist/tools/sql-query-tools.js +130 -0
  1197. package/dist/tools/sql-query-tools.js.map +1 -0
  1198. package/dist/tools/sql-schema-tools.d.ts +47 -0
  1199. package/dist/tools/sql-schema-tools.d.ts.map +1 -0
  1200. package/dist/tools/sql-schema-tools.js +202 -0
  1201. package/dist/tools/sql-schema-tools.js.map +1 -0
  1202. package/dist/tools/sql-shared-tools.d.ts +6 -0
  1203. package/dist/tools/sql-shared-tools.d.ts.map +1 -0
  1204. package/dist/tools/sql-shared-tools.js +59 -0
  1205. package/dist/tools/sql-shared-tools.js.map +1 -0
  1206. package/dist/tools/sql-tools.d.ts +25 -296
  1207. package/dist/tools/sql-tools.d.ts.map +1 -1
  1208. package/dist/tools/sql-tools.js +15 -1232
  1209. package/dist/tools/sql-tools.js.map +1 -1
  1210. package/dist/tools/status-tools.js +1 -1
  1211. package/dist/tools/status-tools.js.map +1 -1
  1212. package/dist/tools/workspace-tools.d.ts +1 -1
  1213. package/dist/tools/yii3-migration-categories-application.d.ts +4 -0
  1214. package/dist/tools/yii3-migration-categories-application.d.ts.map +1 -0
  1215. package/dist/tools/yii3-migration-categories-application.js +56 -0
  1216. package/dist/tools/yii3-migration-categories-application.js.map +1 -0
  1217. package/dist/tools/yii3-migration-categories-infrastructure.d.ts +4 -0
  1218. package/dist/tools/yii3-migration-categories-infrastructure.d.ts.map +1 -0
  1219. package/dist/tools/yii3-migration-categories-infrastructure.js +67 -0
  1220. package/dist/tools/yii3-migration-categories-infrastructure.js.map +1 -0
  1221. package/dist/tools/yii3-migration-categories-model-view.d.ts +4 -0
  1222. package/dist/tools/yii3-migration-categories-model-view.d.ts.map +1 -0
  1223. package/dist/tools/yii3-migration-categories-model-view.js +59 -0
  1224. package/dist/tools/yii3-migration-categories-model-view.js.map +1 -0
  1225. package/dist/tools/yii3-migration-categories-runtime.d.ts +4 -0
  1226. package/dist/tools/yii3-migration-categories-runtime.d.ts.map +1 -0
  1227. package/dist/tools/yii3-migration-categories-runtime.js +49 -0
  1228. package/dist/tools/yii3-migration-categories-runtime.js.map +1 -0
  1229. package/dist/tools/yii3-migration-categories.d.ts +5 -0
  1230. package/dist/tools/yii3-migration-categories.d.ts.map +1 -0
  1231. package/dist/tools/yii3-migration-categories.js +18 -0
  1232. package/dist/tools/yii3-migration-categories.js.map +1 -0
  1233. package/dist/tools/yii3-migration-report.d.ts +4 -0
  1234. package/dist/tools/yii3-migration-report.d.ts.map +1 -0
  1235. package/dist/tools/yii3-migration-report.js +88 -0
  1236. package/dist/tools/yii3-migration-report.js.map +1 -0
  1237. package/dist/tools/yii3-migration-scanner.d.ts +28 -0
  1238. package/dist/tools/yii3-migration-scanner.d.ts.map +1 -0
  1239. package/dist/tools/yii3-migration-scanner.js +87 -0
  1240. package/dist/tools/yii3-migration-scanner.js.map +1 -0
  1241. package/dist/tools/yii3-migration-tools.d.ts +4 -73
  1242. package/dist/tools/yii3-migration-tools.d.ts.map +1 -1
  1243. package/dist/tools/yii3-migration-tools.js +5 -433
  1244. package/dist/tools/yii3-migration-tools.js.map +1 -1
  1245. package/dist/tools/yii3-migration-types.d.ts +50 -0
  1246. package/dist/tools/yii3-migration-types.d.ts.map +1 -0
  1247. package/dist/tools/yii3-migration-types.js +3 -0
  1248. package/dist/tools/yii3-migration-types.js.map +1 -0
  1249. package/dist/utils/git-validation.d.ts +24 -0
  1250. package/dist/utils/git-validation.d.ts.map +1 -1
  1251. package/dist/utils/git-validation.js +30 -0
  1252. package/dist/utils/git-validation.js.map +1 -1
  1253. package/dist/utils/source-stripper/code-handler.d.ts +3 -0
  1254. package/dist/utils/source-stripper/code-handler.d.ts.map +1 -0
  1255. package/dist/utils/source-stripper/code-handler.js +79 -0
  1256. package/dist/utils/source-stripper/code-handler.js.map +1 -0
  1257. package/dist/utils/source-stripper/comment-handler.d.ts +4 -0
  1258. package/dist/utils/source-stripper/comment-handler.d.ts.map +1 -0
  1259. package/dist/utils/source-stripper/comment-handler.js +24 -0
  1260. package/dist/utils/source-stripper/comment-handler.js.map +1 -0
  1261. package/dist/utils/source-stripper/machine.d.ts +2 -0
  1262. package/dist/utils/source-stripper/machine.d.ts.map +1 -0
  1263. package/dist/utils/source-stripper/machine.js +34 -0
  1264. package/dist/utils/source-stripper/machine.js.map +1 -0
  1265. package/dist/utils/source-stripper/regex-handler.d.ts +3 -0
  1266. package/dist/utils/source-stripper/regex-handler.d.ts.map +1 -0
  1267. package/dist/utils/source-stripper/regex-handler.js +44 -0
  1268. package/dist/utils/source-stripper/regex-handler.js.map +1 -0
  1269. package/dist/utils/source-stripper/state.d.ts +4 -0
  1270. package/dist/utils/source-stripper/state.d.ts.map +1 -0
  1271. package/dist/utils/source-stripper/state.js +20 -0
  1272. package/dist/utils/source-stripper/state.js.map +1 -0
  1273. package/dist/utils/source-stripper/string-handler.d.ts +3 -0
  1274. package/dist/utils/source-stripper/string-handler.d.ts.map +1 -0
  1275. package/dist/utils/source-stripper/string-handler.js +19 -0
  1276. package/dist/utils/source-stripper/string-handler.js.map +1 -0
  1277. package/dist/utils/source-stripper/template-handler.d.ts +4 -0
  1278. package/dist/utils/source-stripper/template-handler.d.ts.map +1 -0
  1279. package/dist/utils/source-stripper/template-handler.js +40 -0
  1280. package/dist/utils/source-stripper/template-handler.js.map +1 -0
  1281. package/dist/utils/source-stripper/types.d.ts +17 -0
  1282. package/dist/utils/source-stripper/types.d.ts.map +1 -0
  1283. package/dist/utils/source-stripper/types.js +4 -0
  1284. package/dist/utils/source-stripper/types.js.map +1 -0
  1285. package/dist/utils/source-stripper.d.ts +0 -21
  1286. package/dist/utils/source-stripper.d.ts.map +1 -1
  1287. package/dist/utils/source-stripper.js +6 -234
  1288. package/dist/utils/source-stripper.js.map +1 -1
  1289. package/dist/utils/walk/errors.d.ts +4 -0
  1290. package/dist/utils/walk/errors.d.ts.map +1 -0
  1291. package/dist/utils/walk/errors.js +18 -0
  1292. package/dist/utils/walk/errors.js.map +1 -0
  1293. package/dist/utils/walk/filters.d.ts +11 -0
  1294. package/dist/utils/walk/filters.d.ts.map +1 -0
  1295. package/dist/utils/walk/filters.js +53 -0
  1296. package/dist/utils/walk/filters.js.map +1 -0
  1297. package/dist/utils/walk/limits.d.ts +10 -0
  1298. package/dist/utils/walk/limits.d.ts.map +1 -0
  1299. package/dist/utils/walk/limits.js +22 -0
  1300. package/dist/utils/walk/limits.js.map +1 -0
  1301. package/dist/utils/walk/traversal.d.ts +9 -0
  1302. package/dist/utils/walk/traversal.d.ts.map +1 -0
  1303. package/dist/utils/walk/traversal.js +38 -0
  1304. package/dist/utils/walk/traversal.js.map +1 -0
  1305. package/dist/utils/walk/types.d.ts +18 -0
  1306. package/dist/utils/walk/types.d.ts.map +1 -0
  1307. package/dist/utils/walk/types.js +2 -0
  1308. package/dist/utils/walk/types.js.map +1 -0
  1309. package/dist/utils/walk.d.ts +4 -65
  1310. package/dist/utils/walk.d.ts.map +1 -1
  1311. package/dist/utils/walk.js +23 -151
  1312. package/dist/utils/walk.js.map +1 -1
  1313. package/package.json +7 -6
  1314. package/rules/codesift.md +1 -1
  1315. package/rules/codesift.mdc +1 -1
  1316. package/rules/codex.md +1 -1
  1317. package/rules/gemini.md +1 -1
  1318. package/dist/tools/hono-conditional-middleware.d.ts +0 -27
  1319. package/dist/tools/hono-conditional-middleware.d.ts.map +0 -1
  1320. package/dist/tools/hono-conditional-middleware.js +0 -62
  1321. package/dist/tools/hono-conditional-middleware.js.map +0 -1
  1322. package/dist/tools/hono-env-regression.d.ts +0 -29
  1323. package/dist/tools/hono-env-regression.d.ts.map +0 -1
  1324. package/dist/tools/hono-env-regression.js +0 -157
  1325. package/dist/tools/hono-env-regression.js.map +0 -1
@@ -1,981 +1,19 @@
1
- import { readFile, stat, unlink, rm, mkdir as mkdirAsync } from "node:fs/promises";
2
- import { join, relative, resolve, basename, dirname } from "node:path";
3
- import { openSync, closeSync, statSync, unlinkSync, writeFileSync, renameSync } from "node:fs";
1
+ import { stat, rm, mkdir as mkdirAsync } from "node:fs/promises";
2
+ import { join, basename } from "node:path";
4
3
  import { execFileSync } from "node:child_process";
5
- import { createHash } from "node:crypto";
6
- import { EXTRACTOR_VERSIONS } from "./project-tools.js";
7
- import { extractMarkdownSymbols, extractPrismaSymbols, extractAstroSymbols, extractConversationSymbols } from "../parser/symbol-extractor.js";
8
- import { runTreeSitterParse } from "../parser/parser-pool.js";
9
- import { extractSqlSymbols, stripJinjaTokens } from "../parser/extractors/sql.js";
10
- import { getLanguageForExtension, getLanguageForPath } from "../parser/parser-manager.js";
11
- import { saveIndex, loadIndex, loadIndexOrStale, getIndexPath, saveIncremental, removeFileFromIndex } from "../storage/index-store.js";
12
- import { clearTsconfigCache } from "../utils/tsconfig-paths.js";
13
- import { registerRepo, listRepos as listRegistryRepos, getRepo, removeRepo, getRepoName, updateRepoMeta, resolveRegisteredRepoMeta } from "../storage/registry.js";
14
- import { startWatcher, stopWatcher } from "../storage/watcher.js";
15
- import { buildBM25Index } from "../search/bm25.js";
16
- import { buildSymbolText, createEmbeddingProvider } from "../search/semantic.js";
17
- import { loadEmbeddings, saveEmbeddings, saveEmbeddingMeta, getEmbeddingPath, getEmbeddingMetaPath, batchEmbed } from "../storage/embedding-store.js";
18
- import { saveChunks, saveChunkEmbeddings, loadChunkEmbeddings, getChunkPath, getChunkEmbeddingPath } from "../storage/chunk-store.js";
19
- import { chunkFile, chunkBySymbols } from "../search/chunker.js";
20
- import { loadConfig } from "../config.js";
21
4
  import { validateGitUrl, validateGitRef } from "../utils/git-validation.js";
22
- import { walkDirectory } from "../utils/walk.js";
23
- import { onFileChanged as scanOnChanged, onFileDeleted as scanOnDeleted, scanFileForSecrets } from "./secret-tools.js";
24
- import { getGraphPath } from "../storage/graph-store.js";
25
- import { getSnapshotPath, loadHashSnapshot, saveHashSnapshot, HASH_SNAPSHOT_VERSION } from "../storage/hash-snapshot.js";
26
- const PARSE_CONCURRENCY = 8;
27
- const CHUNK_EMBEDDING_BATCH_SIZE = 96;
5
+ import { loadConfig } from "../config.js";
6
+ import { stopWatcher } from "../storage/watcher.js";
7
+ import { indexFolder, resetIndexFolderRedundancyForTesting } from "./index-tools/folder-indexer.js";
8
+ import { indexFile, clearLastIndexedStateForTesting, ensureIndexFresh, resetFreshnessCache } from "./index-tools/file-indexer.js";
9
+ import { listAllRepos, invalidateCache, getBM25Index, getCodeIndex, getEmbeddingCache, autoIndexCurrentRepo, _cachedEmbeddingReposForTesting, _embeddingLoadCountForTesting, _resetEmbeddingLoadCountForTesting } from "./index-tools/registry.js";
10
+ import { embedSymbols } from "./index-tools/parse.js";
11
+ import { drainLegacyHashQueue, ASTRO_LOCK_FILENAME, EXTRACTOR_VERSIONS_FILENAME, checkAstroExtractorVersion } from "./index-tools/snapshots.js";
12
+ import { activeWatchers, bm25Indexes, codeIndexes, embeddingCaches } from "./index-tools/state.js";
28
13
  const GIT_CLONE_TIMEOUT_MS = 120_000;
29
14
  const GIT_CHECKOUT_TIMEOUT_MS = 30_000;
30
15
  const GIT_PULL_TIMEOUT_MS = 60_000;
31
- /**
32
- * Default cap on files returned by walkDirectory during indexFolder. Without
33
- * this, repos with hundreds of thousands of code files (large CMS, monorepos,
34
- * vendored data sets) accumulate symbols in memory and OOM the Node process,
35
- * which manifests to MCP clients as a "Connection closed" error mid-index.
36
- *
37
- * 50_000 covers every project we've seen in practice; the largest indexed
38
- * monorepo (tgm-survey-platform) is around 5_000 files. Override via the
39
- * MCP `max_files` argument or CODESIFT_MAX_FILES env var when a legitimately
40
- * larger repo needs full coverage.
41
- */
42
- const DEFAULT_MAX_FILES = 50_000;
43
- function getDefaultMaxFiles() {
44
- const envVal = process.env.CODESIFT_MAX_FILES;
45
- if (envVal) {
46
- const parsed = Number.parseInt(envVal, 10);
47
- if (Number.isFinite(parsed) && parsed > 0)
48
- return parsed;
49
- }
50
- return DEFAULT_MAX_FILES;
51
- }
52
- // Active watchers and in-memory indexes keyed by repo name
53
- const activeWatchers = new Map();
54
- const bm25Indexes = new Map();
55
- const codeIndexes = new Map();
56
- const embeddingCaches = new Map();
57
- // Tracks last successful full indexFolder run keyed by absolute rootPath, used
58
- // to short-circuit redundant scans while a watcher is keeping the index live.
59
- // Populated at the end of every indexFolder call that completes normally.
60
- const lastFullIndexAt = new Map();
61
- /**
62
- * Window during which a re-run of indexFolder against the same root is treated
63
- * as redundant when a watcher is active. Telemetry showed 35 calls > 30s and a
64
- * 786s outlier — these are agents defensively re-indexing repos the watcher is
65
- * already maintaining. 60s matches the "fresh enough" threshold used elsewhere.
66
- */
67
- const INDEX_FOLDER_REDUNDANT_WINDOW_MS = 60_000;
68
- /** Test-only — clear short-circuit state between cases. */
69
- export function resetIndexFolderRedundancyForTesting() {
70
- lastFullIndexAt.clear();
71
- }
72
- /**
73
- * Parse a single file and extract its symbols + metadata.
74
- * Returns null if the file cannot be parsed.
75
- */
76
- async function parseOneFile(filePath, repoRoot, repoName) {
77
- try {
78
- const stat = await import("node:fs/promises").then((fs) => fs.stat(filePath));
79
- const source = await readFile(filePath, "utf-8");
80
- // CRITICAL-1 (TOCTOU parse↔hash): hash the EXACT source string we parse,
81
- // here — never via a post-parse re-read. A re-read can observe a different
82
- // on-disk version if the file is modified between parse and hash, pairing
83
- // OLD symbols with a NEW sha so future runs permanently reuse mismatched
84
- // symbols. The sha is NOT persisted inside FileEntry; callers thread it
85
- // into the hash snapshot (and it saves one extra full read per parsed file).
86
- const fileSha1 = createHash("sha1").update(source).digest("hex");
87
- const relPath = relative(repoRoot, filePath);
88
- const baseName = filePath.split("/").pop() ?? "";
89
- // Use full-path resolver so multi-dot suffixes like `.gradle.kts` beat
90
- // single-extension lookups (which would otherwise map to plain Kotlin).
91
- const language = getLanguageForPath(filePath)
92
- ?? (baseName.startsWith(".env") ? "config" : "unknown");
93
- let symbols;
94
- let effectiveLanguage = language;
95
- if (language === "markdown") {
96
- symbols = extractMarkdownSymbols(source, relPath, repoName);
97
- }
98
- else if (language === "prisma") {
99
- symbols = extractPrismaSymbols(source, relPath, repoName);
100
- }
101
- else if (language === "astro") {
102
- symbols = extractAstroSymbols(source, relPath, repoName);
103
- }
104
- else if (language === "conversation") {
105
- symbols = extractConversationSymbols(source, relPath, repoName);
106
- }
107
- else if (language === "sql") {
108
- // SQL: regex extractor, no tree-sitter. Detect Jinja/dbt templates.
109
- const hasJinja = /\{\{|\{%|\{#/.test(source);
110
- if (hasJinja) {
111
- const stripped = stripJinjaTokens(source);
112
- symbols = extractSqlSymbols(stripped, relPath, repoName, source);
113
- effectiveLanguage = "sql-jinja";
114
- }
115
- else {
116
- symbols = extractSqlSymbols(source, relPath, repoName);
117
- }
118
- }
119
- else if (language === "config" || language === "text_stub") {
120
- // text_stub: Swift/Dart/Scala/etc. — indexed as FileEntry but no symbol
121
- // extraction until a tree-sitter grammar + extractor is added.
122
- // search_text (ripgrep path) and scan_secrets still work on these files.
123
- symbols = [];
124
- }
125
- else {
126
- // Tree-sitter languages (TS/JS/Python/Go/Rust/Java/Ruby/PHP/CSS/Kotlin):
127
- // dispatch to the worker pool. Synchronously-hung WASM parses kill the
128
- // worker (terminated on timeout) instead of the MCP server itself.
129
- // See src/parser/parser-pool.ts for details.
130
- try {
131
- symbols = await runTreeSitterParse({ filePath, source, language, relPath, repoName });
132
- }
133
- catch (err) {
134
- const message = err instanceof Error ? err.message : String(err);
135
- console.warn(`[codesift] worker parse failed for ${relPath}: ${message}`);
136
- return null;
137
- }
138
- }
139
- const entry = {
140
- path: relPath,
141
- language: effectiveLanguage,
142
- symbol_count: symbols.length,
143
- last_modified: Date.now(),
144
- mtime_ms: Math.round(stat.mtimeMs),
145
- };
146
- return { symbols, entry, sha1: fileSha1 };
147
- }
148
- catch (err) {
149
- const message = err instanceof Error ? err.message : String(err);
150
- console.warn(`[codesift] Failed to parse ${relative(repoRoot, filePath)}: ${message}`);
151
- return null;
152
- }
153
- }
154
- /**
155
- * Parse files in parallel batches.
156
- */
157
- async function parseFiles(files, repoRoot, repoName) {
158
- const allSymbols = [];
159
- const fileEntries = [];
160
- // CRITICAL-1: sha1 of the exact parsed source, keyed by relPath. Carried out
161
- // of parseOneFile so the snapshot never re-reads (and never races) the file.
162
- const shas = {};
163
- for (let i = 0; i < files.length; i += PARSE_CONCURRENCY) {
164
- const batch = files.slice(i, i + PARSE_CONCURRENCY);
165
- const results = await Promise.all(batch.map((filePath) => parseOneFile(filePath, repoRoot, repoName)));
166
- for (const result of results) {
167
- if (result) {
168
- allSymbols.push(...result.symbols);
169
- fileEntries.push(result.entry);
170
- shas[result.entry.path] = result.sha1;
171
- }
172
- }
173
- }
174
- return { symbols: allSymbols, fileEntries, shas };
175
- }
176
- // ---------------------------------------------------------------------------
177
- // Dirty propagation — mark caller files stale when a callee signature changes
178
- // ---------------------------------------------------------------------------
179
- /**
180
- * Compute a hash of a symbol's public interface (name + kind + signature).
181
- * Body changes don't trigger propagation — only signature changes.
182
- */
183
- function computeSignatureHash(sym) {
184
- const key = `${sym.name}|${sym.kind}|${sym.signature ?? ""}`;
185
- return createHash("sha256").update(key).digest("hex").slice(0, 16);
186
- }
187
- /**
188
- * Detect signature changes and mark caller files as stale.
189
- * Returns the set of files marked stale.
190
- */
191
- function propagateDirtySignatures(oldSymbols, newSymbols, fileEntries) {
192
- // Build old signature hashes
193
- const oldHashes = new Map();
194
- for (const sym of oldSymbols) {
195
- oldHashes.set(sym.id, computeSignatureHash(sym));
196
- }
197
- // Find symbols with changed signatures
198
- const changedSymbolFiles = new Set();
199
- for (const sym of newSymbols) {
200
- const oldHash = oldHashes.get(sym.id);
201
- if (oldHash && oldHash !== computeSignatureHash(sym)) {
202
- changedSymbolFiles.add(sym.file);
203
- }
204
- }
205
- if (changedSymbolFiles.size === 0)
206
- return new Set();
207
- // Find files that import from changed files (1 level of callers)
208
- // Use a simple heuristic: check if any symbol source mentions a changed file's name
209
- const changedBasenames = new Set();
210
- for (const f of changedSymbolFiles) {
211
- const base = f.split("/").pop()?.replace(/\.\w+$/, "");
212
- if (base)
213
- changedBasenames.add(base);
214
- }
215
- const staleFiles = new Set();
216
- for (const sym of newSymbols) {
217
- if (changedSymbolFiles.has(sym.file))
218
- continue; // Don't mark the changed file itself
219
- if (!sym.source)
220
- continue;
221
- for (const base of changedBasenames) {
222
- if (sym.source.includes(base)) {
223
- staleFiles.add(sym.file);
224
- break;
225
- }
226
- }
227
- }
228
- // Mark stale in file entries (clear mtime so next index re-parses them)
229
- for (const entry of fileEntries) {
230
- if (staleFiles.has(entry.path)) {
231
- entry.stale = true;
232
- delete entry.mtime_ms; // Force re-parse on next indexFolder
233
- }
234
- }
235
- return staleFiles;
236
- }
237
- /**
238
- * Embed symbols using the configured embedding provider.
239
- * Non-fatal — BM25 search still works if embedding fails.
240
- */
241
- export async function embedSymbols(symbols, indexPath, repoName, config) {
242
- if (!config.embeddingProvider)
243
- return;
244
- const embeddingPath = getEmbeddingPath(indexPath);
245
- const metaPath = getEmbeddingMetaPath(indexPath);
246
- try {
247
- const provider = createEmbeddingProvider(config.embeddingProvider, config);
248
- const symbolTexts = new Map(symbols.map((s) => [s.id, buildSymbolText(s)]));
249
- const existing = await loadEmbeddings(embeddingPath);
250
- const embeddings = await batchEmbed(symbolTexts, existing, (texts) => provider.embed(texts, "document"), config.embeddingBatchSize, repoName);
251
- await saveEmbeddings(embeddingPath, embeddings);
252
- await saveEmbeddingMeta(metaPath, {
253
- model: provider.model,
254
- provider: config.embeddingProvider,
255
- dimensions: provider.dimensions,
256
- symbol_count: embeddings.size,
257
- updated_at: Date.now(),
258
- });
259
- embeddingCaches.set(repoName, embeddings);
260
- }
261
- catch (err) {
262
- const message = err instanceof Error ? err.message : String(err);
263
- console.error(`[codesift] Embedding failed for ${repoName}: ${message}`);
264
- }
265
- }
266
- /**
267
- * Read files in parallel batches and split each into chunks.
268
- */
269
- async function readAndChunkFiles(fileEntries, rootPath, repoName, symbols) {
270
- const allChunks = [];
271
- for (let i = 0; i < fileEntries.length; i += PARSE_CONCURRENCY) {
272
- const batch = fileEntries.slice(i, i + PARSE_CONCURRENCY);
273
- const batchResults = await Promise.all(batch.map(async (entry) => {
274
- const fullPath = join(rootPath, entry.path);
275
- try {
276
- const content = await readFile(fullPath, "utf-8");
277
- if (symbols) {
278
- const fileSymbols = symbols
279
- .filter((s) => s.file === entry.path)
280
- .map((s) => ({ name: s.name, start_line: s.start_line, end_line: s.end_line }));
281
- return chunkBySymbols(entry.path, content, repoName, fileSymbols);
282
- }
283
- return chunkFile(entry.path, content, repoName);
284
- }
285
- catch (err) {
286
- const message = err instanceof Error ? err.message : String(err);
287
- console.warn(`[codesift] Failed to read ${entry.path} for chunking: ${message}`);
288
- return [];
289
- }
290
- }));
291
- for (const chunks of batchResults) {
292
- allChunks.push(...chunks);
293
- }
294
- }
295
- return allChunks;
296
- }
297
- /**
298
- * Embed file chunks using the configured embedding provider.
299
- * Non-fatal — symbol-level and BM25 search still work if this fails.
300
- */
301
- async function embedChunks(fileEntries, rootPath, repoName, indexPath, config, symbols) {
302
- if (!config.embeddingProvider)
303
- return;
304
- const chunkPath = getChunkPath(indexPath);
305
- const chunkEmbeddingPath = getChunkEmbeddingPath(indexPath);
306
- try {
307
- const provider = createEmbeddingProvider(config.embeddingProvider, config);
308
- const existingChunkEmbeddings = await loadChunkEmbeddings(chunkEmbeddingPath) ?? new Map();
309
- const allChunks = await readAndChunkFiles(fileEntries, rootPath, repoName, symbols);
310
- if (allChunks.length > 0) {
311
- const chunkTexts = new Map(allChunks.map((c) => [c.id, c.text]));
312
- const chunkEmbeddings = await batchEmbed(chunkTexts, existingChunkEmbeddings, (texts) => provider.embed(texts, "document"), CHUNK_EMBEDDING_BATCH_SIZE, `${repoName}:chunks`);
313
- await saveChunks(chunkPath, allChunks);
314
- await saveChunkEmbeddings(chunkEmbeddingPath, chunkEmbeddings);
315
- }
316
- }
317
- catch (err) {
318
- const message = err instanceof Error ? err.message : String(err);
319
- console.error(`[codesift] Chunk embedding failed for ${repoName}: ${message}`);
320
- }
321
- }
322
- /**
323
- * Decide whether a previously stored index no longer reflects the working
324
- * tree. Samples up to 256 of its file paths (even stride) and stats them;
325
- * when at least half are gone the old index is treated as stale. Used by the
326
- * indexFolder sanity check to break the poisoned-baseline deadlock: an old
327
- * index bloated with since-deleted trees (.worktrees/, vendored dirs) would
328
- * otherwise reject every honest reindex as "truncated" forever.
329
- */
330
- const STALE_SAMPLE_LIMIT = 256;
331
- const STALE_MISSING_FRACTION = 0.5;
332
- async function isExistingIndexStale(existing, rootPath) {
333
- const paths = existing.files.map((f) => f.path);
334
- if (paths.length === 0)
335
- return true;
336
- const stride = Math.max(1, Math.floor(paths.length / STALE_SAMPLE_LIMIT));
337
- const sampled = [];
338
- for (let i = 0; i < paths.length && sampled.length < STALE_SAMPLE_LIMIT; i += stride) {
339
- const p = paths[i];
340
- if (p)
341
- sampled.push(p);
342
- }
343
- let missing = 0;
344
- await Promise.all(sampled.map(async (relPath) => {
345
- try {
346
- await stat(join(rootPath, relPath));
347
- }
348
- catch {
349
- missing++;
350
- }
351
- }));
352
- return missing >= sampled.length * STALE_MISSING_FRACTION;
353
- }
354
- /**
355
- * Read a file and return the sha1 hex of its UTF-8 content, or null on read
356
- * failure (deleted mid-walk, permission error). Code-sized files only — same
357
- * assumption parseOneFile already makes. Non-throwing: callers treat null as
358
- * "could not hash → fall through to re-parse".
359
- */
360
- async function sha1OfFile(absPath) {
361
- try {
362
- const content = await readFile(absPath, "utf-8");
363
- return createHash("sha1").update(content).digest("hex");
364
- }
365
- catch {
366
- return null;
367
- }
368
- }
369
- /**
370
- * Exported for unit testing only — not part of the public API.
371
- *
372
- * Drains a legacy-hash queue: hashes each file, then re-stats to confirm the
373
- * mtime has not drifted since the decision-time stat. Entries whose mtime
374
- * drifted (or whose stat fails) are omitted from the returned map so the next
375
- * run re-parses them rather than reusing symbols against a mismatched sha.
376
- *
377
- * @param queue Items from the legacyHashQueue (relPath + filePath + decision-time mtimeMs).
378
- * @param hashFn Injectable hash function (default: sha1OfFile). Tests inject a
379
- * function that also modifies the file so they can trigger the
380
- * TOCTOU drift-detection path without real concurrency.
381
- * @param statFn Injectable stat function (default: fs.stat). Tests can stub this
382
- * to return a post-modification mtime.
383
- */
384
- export async function drainLegacyHashQueue(queue, hashFn = sha1OfFile, statFn = (p) => import("node:fs/promises").then((m) => m.stat(p))) {
385
- const result = {};
386
- for (let i = 0; i < queue.length; i += PARSE_CONCURRENCY) {
387
- const batch = queue.slice(i, i + PARSE_CONCURRENCY);
388
- const shas = await Promise.all(batch.map((q) => hashFn(q.filePath)));
389
- const stats = await Promise.all(batch.map((q) => statFn(q.filePath).then((st) => Math.round(st.mtimeMs), () => null)));
390
- batch.forEach((q, j) => {
391
- const currentMtime = stats[j];
392
- if (currentMtime === null || currentMtime !== q.mtimeMs) {
393
- // Mtime drifted or file gone — omit so next run re-parses.
394
- return;
395
- }
396
- // Omit on null hash — never persist an empty-string sentinel that a
397
- // snapshot reader could mistake for a valid sha1.
398
- if (shas[j])
399
- result[q.relPath] = shas[j];
400
- });
401
- }
402
- return result;
403
- }
404
- export async function indexFolder(folderPath, options) {
405
- if (!folderPath || typeof folderPath !== "string") {
406
- throw new Error("folderPath is required and must be a non-empty string");
407
- }
408
- const rootPath = resolve(folderPath);
409
- const repoName = getRepoName(rootPath);
410
- // Short-circuit: if a watcher is already keeping the index for this root
411
- // live and we re-indexed recently, return a skipped status instead of
412
- // walking the filesystem again.
413
- if (!options?.force) {
414
- const lastTs = lastFullIndexAt.get(rootPath);
415
- const watcher = activeWatchers.get(repoName);
416
- if (watcher && lastTs && Date.now() - lastTs < INDEX_FOLDER_REDUNDANT_WINDOW_MS) {
417
- return {
418
- repo: repoName,
419
- root: rootPath,
420
- file_count: 0,
421
- symbol_count: 0,
422
- duration_ms: 0,
423
- status: "skipped",
424
- reason: "watcher active, recent index",
425
- last_indexed: new Date(lastTs).toISOString(),
426
- hint: "pass force=true to override",
427
- };
428
- }
429
- }
430
- // Clear tsconfig path resolver cache so config edits between runs take effect.
431
- // The two-level cache (configCache + dirToConfigCache) is module-level and
432
- // would otherwise serve stale alias mappings if a user edited tsconfig.json
433
- // between successive index_folder calls within the same MCP server process.
434
- clearTsconfigCache();
435
- const config = loadConfig();
436
- const startTime = Date.now();
437
- const indexPath = getIndexPath(config.dataDir, rootPath);
438
- // Read .codesiftignore for user-defined exclude patterns
439
- let excludePatterns;
440
- try {
441
- const ignoreContent = await readFile(join(rootPath, ".codesiftignore"), "utf-8");
442
- excludePatterns = ignoreContent
443
- .split("\n")
444
- .map((line) => line.replace(/#.*$/, "").trim())
445
- .filter((line) => line.length > 0);
446
- if (excludePatterns.length === 0)
447
- excludePatterns = undefined;
448
- }
449
- catch {
450
- // .codesiftignore not found — proceed without patterns
451
- }
452
- // Walk directory and collect parseable files. maxFiles caps unbounded walks
453
- // (huge monorepos, vendored data sets) before they OOM the process — see
454
- // DEFAULT_MAX_FILES rationale above.
455
- const maxFiles = options?.max_files ?? getDefaultMaxFiles();
456
- const files = await walkDirectory(rootPath, {
457
- includePaths: options?.include_paths,
458
- excludePatterns,
459
- maxFiles,
460
- fileFilter: (ext, name) => !!getLanguageForExtension(ext) || (name?.startsWith(".env") ?? false),
461
- });
462
- const hitFileLimit = files.length >= maxFiles;
463
- if (hitFileLimit) {
464
- console.error(`[codesift] index_folder: ${rootPath} hit max_files=${maxFiles}; ` +
465
- `partial index. Pass include_paths to scope the walk or raise max_files.`);
466
- }
467
- // mtime-based incremental: skip files unchanged since last index
468
- const existing = await loadIndex(indexPath);
469
- const mtimeMap = new Map();
470
- if (existing) {
471
- for (const f of existing.files) {
472
- if (f.mtime_ms)
473
- mtimeMap.set(f.path, f.mtime_ms);
474
- }
475
- }
476
- // Persistent hash snapshot (Task 6): relPath → sha1 from the previous index.
477
- // mtime stays the cheap pre-filter (unchanged mtime → reuse without hashing,
478
- // the fastest path). When mtime *changed*, the snapshot sha1 lets us still
479
- // reuse symbols for touch/checkout no-op rewrites that bumped mtime without
480
- // changing content — something mtime-only logic could never catch.
481
- // null when absent/corrupt/version-or-repo-mismatch → degrade to full parse.
482
- const snapshotPath = getSnapshotPath(indexPath);
483
- let oldSnapshot = existing
484
- ? await loadHashSnapshot(snapshotPath, repoName)
485
- : null;
486
- // Staleness guard (Task 6, CRITICAL-2): an incremental saveIncremental /
487
- // removeFileFromIndex advances index.updated_at WITHOUT touching the
488
- // snapshot. If saveIndex landed but the subsequent snapshot save failed (or
489
- // an incremental edit ran after the last full index), the on-disk snapshot
490
- // is OLDER than the index and its SHAs may no longer match the indexed
491
- // symbols — carrying them forward (fast path) or sha-matching against them
492
- // (changed path) would produce wrong reuse on revert+touch sequences. When
493
- // the snapshot predates the index, discard it: the legacy hash-now
494
- // convergence path below repopulates a fresh, correct snapshot this run.
495
- // Guard uses strict inequality (!==), not <. The fresh-write contract is
496
- // snapshot.created_at === index.updated_at exactly (created_at is anchored to
497
- // codeIndex.updated_at, not a fresh Date.now()). So ANY mismatch — older OR
498
- // newer — means the snapshot is not the one paired with this index and must
499
- // be discarded. A FUTURE created_at (e.g. a snapshot written against a later,
500
- // since-rolled-back index, or clock skew) is just as untrustworthy as a stale
501
- // one: its SHAs may not match the indexed symbols.
502
- if (oldSnapshot && existing && oldSnapshot.created_at !== existing.updated_at) {
503
- console.warn(`[codesift] hash-snapshot older than index — rebuilding (${repoName})`);
504
- oldSnapshot = null;
505
- }
506
- const filesToParse = [];
507
- const keptSymbols = [];
508
- const keptEntries = [];
509
- // sha1 of every file in the NEW index, by relPath. Populated for reused files
510
- // here (from the old snapshot when present, else hashed-now for convergence)
511
- // and for parsed files after parseFiles resolves.
512
- const newSnapshotFiles = {};
513
- // CRITICAL-1: reused files whose sha1 must be (re)computed because the old
514
- // snapshot lacks it (legacy snapshot-less index, or stale snapshot discarded
515
- // above). Collected here and hashed AFTER the loop in PARSE_CONCURRENCY
516
- // batches instead of one serial await per file inside the loop — on a first
517
- // run after upgrade against a many-thousand-file repo the serial version cost
518
- // thousands of sequential awaits. Behavior is identical, wall-clock is
519
- // parallelized.
520
- //
521
- // mtimeMs: the mtime observed at decision time (the moment we confirmed
522
- // mtime === prevMtime and placed the file in the queue). We re-stat after
523
- // hashing to detect any concurrent modification that landed between the two
524
- // operations. If the mtime drifted, we omit the file from newSnapshotFiles
525
- // entirely — the missing sha causes the next cold run to re-parse, avoiding
526
- // a snapshot that pairs new-content sha against old (reused) symbols.
527
- const legacyHashQueue = [];
528
- // PERF: pre-build per-file lookups ONCE before the reuse loop. Both reuse
529
- // branches need (a) the existing index's symbols for a given relPath and (b)
530
- // its FileEntry. Doing `existing.symbols.filter(s => s.file === relPath)` /
531
- // `existing.files.find(f => f.path === relPath)` per file is O(files ×
532
- // symbols) and O(files²) respectively — quadratic, and on a many-thousand
533
- // file/symbol repo that dominated the reuse-heavy fast path. A single pass
534
- // builds Map lookups each branch hits in O(1). Built only when there's an
535
- // existing index to reuse from.
536
- const symbolsByFile = new Map();
537
- const fileEntryByPath = new Map();
538
- if (existing) {
539
- for (const sym of existing.symbols) {
540
- const list = symbolsByFile.get(sym.file);
541
- if (list)
542
- list.push(sym);
543
- else
544
- symbolsByFile.set(sym.file, [sym]);
545
- }
546
- for (const fe of existing.files) {
547
- fileEntryByPath.set(fe.path, fe);
548
- }
549
- }
550
- if (mtimeMap.size > 0) {
551
- const { stat } = await import("node:fs/promises");
552
- for (const filePath of files) {
553
- const relPath = relative(rootPath, filePath);
554
- const prevMtime = mtimeMap.get(relPath);
555
- if (prevMtime !== undefined) {
556
- const fileEntry = fileEntryByPath.get(relPath);
557
- // Force re-parse if file is marked stale (callee signature changed)
558
- if (fileEntry?.stale) {
559
- filesToParse.push(filePath);
560
- continue;
561
- }
562
- try {
563
- const st = await stat(filePath);
564
- if (Math.round(st.mtimeMs) === prevMtime) {
565
- // Fast path: mtime unchanged → reuse symbols without hashing.
566
- const fileSymbols = symbolsByFile.get(relPath) ?? [];
567
- if (fileEntry) {
568
- keptSymbols.push(...fileSymbols);
569
- keptEntries.push(fileEntry);
570
- // Carry the sha1 forward: reuse from old snapshot if present,
571
- // else DEFER hashing so legacy (snapshot-less) indexes converge
572
- // to a complete snapshot after one run — without paying a serial
573
- // hash per file inside this loop.
574
- const carried = oldSnapshot?.files[relPath];
575
- if (carried !== undefined) {
576
- newSnapshotFiles[relPath] = carried;
577
- }
578
- else {
579
- legacyHashQueue.push({ relPath, filePath, mtimeMs: Math.round(st.mtimeMs) });
580
- }
581
- continue;
582
- }
583
- }
584
- else {
585
- // mtime changed — hash decides reuse vs re-parse. This catches
586
- // touch/checkout that bumped mtime without changing content.
587
- const snapSha = oldSnapshot?.files[relPath];
588
- if (snapSha !== undefined && fileEntry && !fileEntry.stale) {
589
- const currentSha = await sha1OfFile(filePath);
590
- if (currentSha !== null && currentSha === snapSha) {
591
- const fileSymbols = symbolsByFile.get(relPath) ?? [];
592
- keptSymbols.push(...fileSymbols);
593
- // FIX: the file's mtime changed but content is identical (touch /
594
- // checkout no-op rewrite). Reuse the symbols, but DON'T carry the
595
- // stale FileEntry verbatim — its mtime_ms still holds the OLD
596
- // mtime, so every future run would see mtime !== prevMtime and
597
- // re-hash this file forever, permanently degrading it off the
598
- // mtime fast path. Clone the entry with mtime_ms bumped to the
599
- // CURRENT stat's mtime so the next run takes the cheap fast path.
600
- keptEntries.push({ ...fileEntry, mtime_ms: Math.round(st.mtimeMs) });
601
- newSnapshotFiles[relPath] = currentSha;
602
- continue;
603
- }
604
- }
605
- }
606
- }
607
- catch { /* file may have been deleted — reparse */ }
608
- }
609
- filesToParse.push(filePath);
610
- }
611
- }
612
- else {
613
- filesToParse.push(...files);
614
- }
615
- // Drain the deferred legacy-hash queue (CRITICAL-1): files reused via the
616
- // mtime fast path that had no carried sha1 (legacy snapshot-less index, or a
617
- // stale snapshot discarded by the guard above). See drainLegacyHashQueue for
618
- // the TOCTOU guard details — entries whose mtime drifted between decision
619
- // time and hash time are omitted so the next run re-parses rather than
620
- // reusing symbols against a mismatched sha.
621
- if (legacyHashQueue.length > 0) {
622
- const drained = await drainLegacyHashQueue(legacyHashQueue);
623
- Object.assign(newSnapshotFiles, drained);
624
- }
625
- // Parse only changed/new files
626
- const { symbols: parsedSymbols, fileEntries: parsedEntries, shas: parsedShas } = await parseFiles(filesToParse, rootPath, repoName);
627
- const symbols = [...keptSymbols, ...parsedSymbols];
628
- const fileEntries = [...keptEntries, ...parsedEntries];
629
- // Record sha1s for the files that were actually parsed (changed/new).
630
- // CRITICAL-1 (TOCTOU): these hashes come straight from parseOneFile — they
631
- // are the sha1 of the EXACT source string that produced the symbols, so the
632
- // snapshot can never pair old symbols with a newer file's sha. Only entries
633
- // that survived parseFiles (parseOneFile returned non-null) have a sha here,
634
- // keeping the snapshot in lockstep with fileEntries. The previous post-parse
635
- // double-read loop is gone — one fewer full read per parsed file.
636
- for (const entry of parsedEntries) {
637
- const sha = parsedShas[entry.path];
638
- if (sha !== undefined)
639
- newSnapshotFiles[entry.path] = sha;
640
- }
641
- // Dirty propagation: detect signature changes and mark caller files stale
642
- if (existing && filesToParse.length > 0 && filesToParse.length < files.length) {
643
- const staleFiles = propagateDirtySignatures(existing.symbols, symbols, fileEntries);
644
- if (staleFiles.size > 0) {
645
- console.error(`[codesift] Dirty propagation: ${staleFiles.size} caller files marked stale`);
646
- }
647
- }
648
- // Invalidate code index cache (BM25 is rebuilt below from the FINAL symbol
649
- // set — possibly merged with out-of-scope existing symbols, see merge block).
650
- codeIndexes.delete(repoName);
651
- // Sanity check: don't overwrite a complete index with a partial one
652
- // (WASM crash or walk failure can produce truncated results).
653
- //
654
- // IMPORTANT: skip the guard when the walk was explicitly narrowed — either
655
- // max_files was hit (truncated at cap) or include_paths scoped the walk to a
656
- // subdirectory. In both cases the small result count is EXPECTED and rejecting
657
- // it would be a false positive (the "1139 vs 9512" bug class). For unrestricted
658
- // walks the guard stays as-is, protecting against genuine silent truncations.
659
- //
660
- // CRITICAL (T7 correctness fix): skipping the guard is necessary but NOT
661
- // sufficient. A scoped/capped walk only SEES a narrow slice of the repo; if we
662
- // persisted that slice as the WHOLE index we would wipe every out-of-scope
663
- // file's symbols from index+snapshot (worse than the guard's old reject,
664
- // which at least preserved the prior index). So for scoped/capped walks with
665
- // an existing index we MERGE: keep out-of-scope existing entries verbatim and
666
- // overlay the walk's results. See the merge block below.
667
- //
668
- // "max_files hit" detection: files.length === effective maxFiles. This is the
669
- // only signal walkDirectory exposes (it sets limitReached internally but does
670
- // not surface it on the return value). A 1-in-a-million exact-count false
671
- // positive (repo has exactly maxFiles parseable files) is accepted — the
672
- // guard skip is conservative (allows write), not destructive.
673
- const DROP_THRESHOLD = 0.5; // Reject if new index has <50% of old file count
674
- const walkExplicitlyCapped = hitFileLimit;
675
- const walkExplicitlyScoped = options?.include_paths !== undefined && options.include_paths.length > 0;
676
- // MIN_GUARD_FILES: the unrestricted guard only arms above this existing
677
- // file_count (`existing.file_count > 50` below). The scoped-granularity guard
678
- // mirrors that shape against the in-scope subset so a tiny scope can't be
679
- // rejected on noise. Single source of truth so both guards stay in lockstep.
680
- const MIN_GUARD_FILES = 50;
681
- if (walkExplicitlyCapped || walkExplicitlyScoped) {
682
- // ROUND-2 FIX (scoped-granularity guard): the unrestricted guard is skipped
683
- // for scoped/capped walks because a small *overall* result is expected. But
684
- // that skip was total — a scoped walk that aborts mid-enumeration (WASM
685
- // crash, transient FS error, an over-broad exclude) silently truncates the
686
- // IN-SCOPE slice, and the merge below treats every unwalked in-scope file as
687
- // a deletion → wipes it from index+snapshot. So for a purely SCOPED (uncapped)
688
- // walk we re-arm a guard against the IN-SCOPE subset: if the walk enumerated
689
- // far fewer in-scope files than the existing index held in that same scope,
690
- // AND those files are still on disk, the enumeration was truncated → reject
691
- // before any merge/save, leaving the old index+snapshot intact.
692
- //
693
- // Capped walks are intentionally EXEMPT: a cap means unseen ≠ deleted (the
694
- // merge preserves all unwalked files), so there is no truncation to detect —
695
- // nothing in-scope is dropped. A walk that is BOTH scoped and capped also
696
- // takes capped semantics (preserve everything unwalked), so the same
697
- // exemption applies — no in-scope file can be lost.
698
- if (walkExplicitlyScoped && !walkExplicitlyCapped && existing) {
699
- const includePaths = options.include_paths;
700
- const inScopeRel = (relPath) => includePaths.some((p) => relPath.startsWith(p)); // mirror walkDirectory
701
- const existingInScope = existing.files.filter((fe) => inScopeRel(fe.path));
702
- // All walked files are in scope by construction (walkDirectory honored
703
- // includePaths), so walkedInScope is simply the walk's file count.
704
- const walkedInScope = fileEntries.length;
705
- if (existingInScope.length > MIN_GUARD_FILES &&
706
- walkedInScope < existingInScope.length * DROP_THRESHOLD) {
707
- // Auto-heal analog (in-scope): the shrink may be a genuine mass deletion
708
- // within the scope, not a truncated walk. Sample the existing in-scope
709
- // paths on disk (mirrors isExistingIndexStale, but restricted to the
710
- // scope) — if most are gone, accept the merge.
711
- const inScopePaths = existingInScope.map((fe) => fe.path);
712
- const stride = Math.max(1, Math.floor(inScopePaths.length / STALE_SAMPLE_LIMIT));
713
- const sampled = [];
714
- for (let i = 0; i < inScopePaths.length && sampled.length < STALE_SAMPLE_LIMIT; i += stride) {
715
- const p = inScopePaths[i];
716
- if (p)
717
- sampled.push(p);
718
- }
719
- let missing = 0;
720
- await Promise.all(sampled.map(async (relPath) => {
721
- try {
722
- await stat(join(rootPath, relPath));
723
- }
724
- catch {
725
- missing++;
726
- }
727
- }));
728
- const mostGone = missing >= sampled.length * STALE_MISSING_FRACTION;
729
- if (mostGone) {
730
- console.error(`[codesift] Scoped sanity auto-heal for ${repoName}: walked ` +
731
- `${walkedInScope} of ${existingInScope.length} in-scope files but ` +
732
- `most sampled in-scope paths no longer exist on disk. Accepting ` +
733
- `scoped merge (legit in-scope mass deletion).`);
734
- }
735
- else {
736
- console.error(`[codesift] SCOPED SANITY CHECK FAILED for ${repoName}: scoped walk ` +
737
- `under-enumerated — walked ${walkedInScope} of ${existingInScope.length} ` +
738
- `in-scope files, which still exist on disk. Keeping old index.`);
739
- return {
740
- repo: repoName,
741
- root: rootPath,
742
- file_count: existing.file_count,
743
- symbol_count: existing.symbol_count,
744
- duration_ms: Date.now() - startTime,
745
- status: "rejected_partial",
746
- reason: `scoped walk under-enumerated: walked ${walkedInScope} of ${existingInScope.length} in-scope files (still on disk) — kept old index, nothing was re-registered`,
747
- hint: "If the in-scope shrink is expected (deleted files, new excludes), run invalidate_cache then index_folder to rebuild from scratch.",
748
- };
749
- }
750
- }
751
- }
752
- const detail = walkExplicitlyCapped
753
- ? `max_files=${maxFiles} hit (${files.length} files returned)`
754
- : `include_paths=[${options.include_paths.join(", ")}]`;
755
- console.error(`[codesift] sanity guard skipped: walk explicitly capped/scoped (${detail})`);
756
- }
757
- else if (existing && fileEntries.length < existing.file_count * DROP_THRESHOLD && existing.file_count > MIN_GUARD_FILES) {
758
- // The shrink can also mean the OLD index is the bogus one: an earlier
759
- // walker may have swept since-deleted trees (.worktrees/, vendored dirs),
760
- // permanently inflating the baseline so every honest reindex looks
761
- // truncated and gets rejected forever. Disambiguate by sampling the old
762
- // index's paths: if most of them no longer exist on disk, the old index
763
- // is stale dead weight — accept the new result instead of keeping it.
764
- if (await isExistingIndexStale(existing, rootPath)) {
765
- console.error(`[codesift] Sanity check auto-heal for ${repoName}: old index has ` +
766
- `${existing.file_count} files but most sampled paths no longer exist ` +
767
- `on disk. Accepting new index (${fileEntries.length} files).`);
768
- }
769
- else {
770
- console.error(`[codesift] SANITY CHECK FAILED for ${repoName}: ` +
771
- `new index has ${fileEntries.length} files vs ${existing.file_count} previously. ` +
772
- `Keeping old index. Use invalidate_cache + index_folder to force reindex.`);
773
- return {
774
- repo: repoName,
775
- root: rootPath,
776
- file_count: existing.file_count,
777
- symbol_count: existing.symbol_count,
778
- duration_ms: Date.now() - startTime,
779
- status: "rejected_partial",
780
- reason: `new walk found ${fileEntries.length} files, <50% of the ${existing.file_count} previously indexed — kept old index, nothing was re-registered`,
781
- hint: "If the shrink is expected (deleted trees, new excludes), run invalidate_cache then index_folder to rebuild from scratch.",
782
- };
783
- }
784
- }
785
- // ── MERGE-persist for scoped/capped walks (T7 correctness fix) ────────────
786
- // A scoped (include_paths) or capped (max_files-hit) walk only enumerated a
787
- // slice of the repo. Persisting that slice verbatim would delete every
788
- // out-of-scope file's symbols from index+snapshot. When an existing index is
789
- // present we instead MERGE: preserve out-of-scope existing entries/symbols/
790
- // shas and overlay the walk's results.
791
- //
792
- // - include_paths scoped (and NOT capped): "scope" = files whose relPath is
793
- // under any include root (mirror walkDirectory's relPath.startsWith(p)
794
- // test EXACTLY). Out-of-scope existing files are preserved verbatim;
795
- // in-scope existing files NOT in the walk set W are dropped (genuine
796
- // in-scope deletions — the walk fully enumerated the scope).
797
- // - capped (max_files hit): scope is UNDEFINED — the cap means an unseen
798
- // file is not necessarily deleted. Preserve ALL existing entries not in W,
799
- // overlay W. (If a capped walk also passed include_paths, the cap makes the
800
- // in-scope enumeration incomplete too, so we still only trust W and
801
- // preserve everything else — capped semantics win.)
802
- //
803
- // First run (no existing index) with a scoped/capped walk → save what we have
804
- // (current behavior, documented): there is nothing to preserve.
805
- let mergedSymbols = symbols;
806
- let mergedEntries = fileEntries;
807
- let mergedSnapshotFiles = newSnapshotFiles;
808
- if ((walkExplicitlyCapped || walkExplicitlyScoped) && existing) {
809
- const walkedPaths = new Set(fileEntries.map((fe) => fe.path));
810
- // A capped walk has undefined scope (unseen ≠ deleted), so it preserves
811
- // everything not walked. A purely scoped (uncapped) walk additionally drops
812
- // in-scope-but-unwalked files, since the walk fully enumerated the scope.
813
- const includePaths = options?.include_paths;
814
- const inScope = (relPath) => {
815
- if (walkExplicitlyCapped)
816
- return false; // cap → never treat as deletable
817
- if (!includePaths || includePaths.length === 0)
818
- return false;
819
- // Mirror walkDirectory's include-path filter exactly.
820
- return includePaths.some((p) => relPath.startsWith(p));
821
- };
822
- const preservedEntries = [];
823
- const preservedFilePaths = new Set();
824
- for (const fe of existing.files) {
825
- if (walkedPaths.has(fe.path))
826
- continue; // walk result wins for these
827
- if (inScope(fe.path))
828
- continue; // in-scope + not walked = deleted-in-scope
829
- preservedEntries.push(fe);
830
- preservedFilePaths.add(fe.path);
831
- }
832
- const preservedSymbols = existing.symbols.filter((s) => preservedFilePaths.has(s.file));
833
- mergedEntries = [...preservedEntries, ...fileEntries];
834
- mergedSymbols = [...preservedSymbols, ...symbols];
835
- // Snapshot: preserve out-of-scope shas, overlay walked ones.
836
- mergedSnapshotFiles = {};
837
- if (oldSnapshot) {
838
- for (const relPath of preservedFilePaths) {
839
- const sha = oldSnapshot.files[relPath];
840
- if (sha !== undefined)
841
- mergedSnapshotFiles[relPath] = sha;
842
- }
843
- }
844
- Object.assign(mergedSnapshotFiles, newSnapshotFiles);
845
- }
846
- // Build and cache BM25 index from the FINAL (possibly merged) symbol set.
847
- // Built here (not before the guard) so a rejected_partial early-return leaves
848
- // the previous in-memory BM25 index intact rather than swapping in a partial.
849
- const bm25 = buildBM25Index(mergedSymbols);
850
- bm25Indexes.set(repoName, bm25);
851
- // Resolve workspaces (Task 7) — runs before persistence so collectImportEdges
852
- // and other downstream consumers see the populated `workspaces` field.
853
- // Gated behind CODESIFT_DISABLE_MONOREPO=1 kill switch (spec D-FB).
854
- let workspaces;
855
- if (process.env.CODESIFT_DISABLE_MONOREPO !== "1") {
856
- try {
857
- const { resolveWorkspaces } = await import("../storage/workspace-resolver.js");
858
- const resolved = await resolveWorkspaces(rootPath);
859
- if (resolved)
860
- workspaces = resolved.workspaces;
861
- }
862
- catch {
863
- // Resolver should never throw, but guard belt-and-braces — flat-repo
864
- // mode is the safe fallback.
865
- }
866
- }
867
- // Build and save code index from the FINAL (possibly merged) sets.
868
- const codeIndex = {
869
- repo: repoName,
870
- root: rootPath,
871
- symbols: mergedSymbols,
872
- files: mergedEntries,
873
- created_at: Date.now(),
874
- updated_at: Date.now(),
875
- symbol_count: mergedSymbols.length,
876
- file_count: mergedEntries.length,
877
- extractor_version: { ...EXTRACTOR_VERSIONS },
878
- ...(workspaces ? { workspaces } : {}),
879
- };
880
- await saveIndex(indexPath, codeIndex);
881
- // Persist the hash snapshot AFTER the index lands (mirrors registerRepo
882
- // ordering) and only on the success path — the rejected_partial branch
883
- // returned earlier, leaving the previous snapshot intact. Non-fatal: the
884
- // snapshot is a reuse-optimization cache; a write failure just costs a full
885
- // re-parse next run, so we warn and continue.
886
- try {
887
- const newSnapshot = {
888
- version: HASH_SNAPSHOT_VERSION,
889
- repo: repoName,
890
- // CRITICAL-2 (created_at race): use the EXACT timestamp serialized into
891
- // the index, not a fresh Date.now(). A watcher's saveIncremental that
892
- // lands between saveIndex and this write would otherwise leave the
893
- // snapshot OLDER than created_at, blinding the staleness guard above. By
894
- // anchoring to codeIndex.updated_at, snapshot.created_at === the index's
895
- // updated_at on a fresh write, so any later incremental strictly advances
896
- // index.updated_at past it and the guard fires correctly.
897
- created_at: codeIndex.updated_at,
898
- files: mergedSnapshotFiles,
899
- };
900
- await saveHashSnapshot(snapshotPath, newSnapshot);
901
- }
902
- catch (err) {
903
- const msg = err instanceof Error ? err.message : String(err);
904
- console.warn(`[codesift] hash-snapshot save failed for ${repoName} (non-fatal): ${msg}`);
905
- }
906
- // Embed symbols and chunks in background (non-fatal, don't block MCP response)
907
- // Large repos (71K symbols) can take minutes — fire-and-forget to prevent timeout
908
- embedSymbols(mergedSymbols, indexPath, repoName, config)
909
- .then(() => embedChunks(mergedEntries, rootPath, repoName, indexPath, config, mergedSymbols))
910
- .catch((err) => {
911
- const msg = err instanceof Error ? err.message : String(err);
912
- console.error(`[codesift] Background embedding failed for ${repoName}: ${msg}`);
913
- });
914
- // Register in the global registry. If a stale entry exists with the same
915
- // root but a different name (e.g. `local/workspace` from before the git
916
- // origin auto-detect landed), drop it so `list_repos` doesn't show ghosts.
917
- const existingRepos = await listRegistryRepos(config.registryPath);
918
- for (const stale of existingRepos) {
919
- if (stale.root === rootPath && stale.name !== repoName) {
920
- await removeRepo(config.registryPath, stale.name);
921
- console.error(`[codesift] Migrated registry: ${stale.name} -> ${repoName} (same root)`);
922
- }
923
- }
924
- const meta = {
925
- name: repoName,
926
- root: rootPath,
927
- index_path: indexPath,
928
- symbol_count: mergedSymbols.length,
929
- file_count: mergedEntries.length,
930
- updated_at: Date.now(),
931
- };
932
- await registerRepo(config.registryPath, meta);
933
- // Capture git HEAD for auto-refresh tracking
934
- try {
935
- const head = execFileSync("git", ["rev-parse", "HEAD"], {
936
- cwd: rootPath, encoding: "utf-8", timeout: 5000,
937
- }).trim();
938
- await updateRepoMeta(config.registryPath, repoName, { last_git_commit: head });
939
- }
940
- catch {
941
- // Not a git repo — skip
942
- }
943
- // Start file watcher for incremental updates (unless disabled)
944
- if (options?.watch !== false) {
945
- await setupWatcher(rootPath, repoName, indexPath);
946
- }
947
- // Auto-enable framework-specific tool bundles (NestJS, etc.)
948
- // Lazy import to avoid circular dep: index-tools → register-tools → tool handlers → index-tools
949
- try {
950
- const { detectFrameworks } = await import("../utils/framework-detect.js");
951
- const { enableFrameworkToolBundle } = await import("../register-tools.js");
952
- const tempIndex = { root: rootPath, files: mergedEntries, symbols: mergedSymbols };
953
- const frameworks = detectFrameworks(tempIndex);
954
- for (const fw of frameworks) {
955
- const enabled = enableFrameworkToolBundle(fw);
956
- if (enabled.length > 0) {
957
- console.error(`[codesift] auto-enabled ${enabled.length} ${fw} tools for ${repoName}: ${enabled.join(", ")}`);
958
- }
959
- }
960
- }
961
- catch {
962
- // Non-fatal — framework auto-enable is a convenience feature
963
- }
964
- // Record completion timestamp so subsequent re-runs can short-circuit when
965
- // the watcher is keeping the index fresh.
966
- lastFullIndexAt.set(rootPath, Date.now());
967
- return {
968
- repo: repoName,
969
- root: rootPath,
970
- file_count: mergedEntries.length,
971
- symbol_count: mergedSymbols.length,
972
- duration_ms: Date.now() - startTime,
973
- };
974
- }
975
- /**
976
- * Clone a remote git repository and index it.
977
- * Clones into ~/.codesift/repos/{name}. If already cloned, pulls latest.
978
- */
16
+ export { indexFolder, resetIndexFolderRedundancyForTesting, indexFile, clearLastIndexedStateForTesting, ensureIndexFresh, resetFreshnessCache, listAllRepos, invalidateCache, getBM25Index, getCodeIndex, getEmbeddingCache, autoIndexCurrentRepo, _cachedEmbeddingReposForTesting, _embeddingLoadCountForTesting, _resetEmbeddingLoadCountForTesting, embedSymbols, drainLegacyHashQueue, ASTRO_LOCK_FILENAME, EXTRACTOR_VERSIONS_FILENAME, checkAstroExtractorVersion, };
979
17
  export async function indexRepo(url, options) {
980
18
  validateGitUrl(url);
981
19
  if (options?.branch) {
@@ -1051,383 +89,6 @@ export async function indexRepo(url, options) {
1051
89
  * Override via CODESIFT_MAX_WATCHERS env var. Set to 0 to disable watchers
1052
90
  * entirely (suitable for CI / batch index runs).
1053
91
  */
1054
- const DEFAULT_MAX_WATCHERS = 8;
1055
- function getMaxWatchers() {
1056
- const env = process.env.CODESIFT_MAX_WATCHERS;
1057
- if (env !== undefined) {
1058
- const n = Number.parseInt(env, 10);
1059
- if (Number.isFinite(n) && n >= 0)
1060
- return n;
1061
- }
1062
- return DEFAULT_MAX_WATCHERS;
1063
- }
1064
- // Insertion-ordered Map gives us free LRU semantics: re-inserting a key
1065
- // moves it to the end, so the first key is the least-recently set up.
1066
- const watcherInsertionOrder = new Set();
1067
- /**
1068
- * Replace or create a file watcher for incremental index updates.
1069
- *
1070
- * Enforces a max-active-watchers cap with LRU eviction so that bulk indexing
1071
- * of many repos in one session cannot exhaust the system file table. When the
1072
- * cap is exceeded the oldest watcher is closed; that repo's index becomes
1073
- * stale-on-disk until the next explicit `index_folder` or `index_file`.
1074
- */
1075
- async function setupWatcher(rootPath, repoName, indexPath) {
1076
- const existingWatcher = activeWatchers.get(repoName);
1077
- if (existingWatcher) {
1078
- await stopWatcher(existingWatcher);
1079
- watcherInsertionOrder.delete(repoName);
1080
- }
1081
- // Evict oldest watchers until we fit under the cap (with room for the new one)
1082
- const maxWatchers = getMaxWatchers();
1083
- if (maxWatchers === 0) {
1084
- // Caller of indexFolder can also opt out via watch:false; this env is the
1085
- // global kill-switch (e.g. for CI bulk-index jobs).
1086
- return;
1087
- }
1088
- while (watcherInsertionOrder.size >= maxWatchers) {
1089
- const oldest = watcherInsertionOrder.values().next().value;
1090
- if (oldest === undefined)
1091
- break;
1092
- const oldWatcher = activeWatchers.get(oldest);
1093
- if (oldWatcher) {
1094
- await stopWatcher(oldWatcher).catch(() => { });
1095
- activeWatchers.delete(oldest);
1096
- }
1097
- watcherInsertionOrder.delete(oldest);
1098
- console.error(`[codesift] watcher cap reached (${maxWatchers}); evicted oldest watcher: ${oldest}`);
1099
- }
1100
- const watcher = await startWatcher(rootPath, (changedFile) => {
1101
- handleFileChange(rootPath, repoName, indexPath, changedFile).catch((err) => {
1102
- const message = err instanceof Error ? err.message : String(err);
1103
- console.error(`[codesift] Watcher error for ${changedFile}: ${message}`);
1104
- });
1105
- }, (deletedFile) => {
1106
- handleFileDelete(rootPath, repoName, indexPath, deletedFile).catch((err) => {
1107
- const message = err instanceof Error ? err.message : String(err);
1108
- console.error(`[codesift] Watcher delete error for ${deletedFile}: ${message}`);
1109
- });
1110
- });
1111
- activeWatchers.set(repoName, watcher);
1112
- watcherInsertionOrder.add(repoName);
1113
- }
1114
- /**
1115
- * Handle a file change event from the watcher.
1116
- * Re-parses the changed file and updates the index incrementally.
1117
- */
1118
- async function handleFileChange(repoRoot, repoName, indexPath, relativeFile) {
1119
- const fullPath = join(repoRoot, relativeFile);
1120
- // Invalidate cached findings so the next scan sees the updated file contents.
1121
- scanOnChanged(repoName, relativeFile);
1122
- // Invalidate negative evidence for this file's subtree
1123
- try {
1124
- const { invalidateNegativeEvidence } = await import("../storage/session-state.js");
1125
- invalidateNegativeEvidence(repoName, relativeFile);
1126
- }
1127
- catch {
1128
- // Best-effort — session-state may not be loaded
1129
- }
1130
- // Invalidate Hono model cache for this file (canonicalized absolute path)
1131
- try {
1132
- const { honoCache } = await import("../cache/hono-cache.js");
1133
- honoCache.invalidate(fullPath);
1134
- }
1135
- catch {
1136
- // Best-effort — hono-cache may not be loaded
1137
- }
1138
- const result = await parseOneFile(fullPath, repoRoot, repoName);
1139
- if (!result)
1140
- return;
1141
- await saveIncremental(indexPath, relativeFile, result.symbols, result.entry);
1142
- if (loadConfig().secretScanEnabled) {
1143
- try {
1144
- await scanFileForSecrets(fullPath, relativeFile, repoName, result.symbols);
1145
- }
1146
- catch (err) {
1147
- const message = err instanceof Error ? err.message : String(err);
1148
- console.warn(`[codesift] Secret scan failed for ${relativeFile}: ${message}`);
1149
- }
1150
- }
1151
- // Invalidate caches — lazy rebuild on next query via getBM25Index()
1152
- bm25Indexes.delete(repoName);
1153
- codeIndexes.delete(repoName);
1154
- embeddingCaches.delete(repoName);
1155
- }
1156
- /**
1157
- * Handle a file deletion event from the watcher.
1158
- * Removes all symbols for the deleted file from the index.
1159
- */
1160
- async function handleFileDelete(repoRoot, repoName, indexPath, relativeFile) {
1161
- await removeFileFromIndex(indexPath, relativeFile);
1162
- // Invalidate caches — lazy rebuild on next query via getBM25Index()
1163
- bm25Indexes.delete(repoName);
1164
- codeIndexes.delete(repoName);
1165
- embeddingCaches.delete(repoName);
1166
- scanOnDeleted(repoName, relativeFile);
1167
- // Invalidate Hono model cache
1168
- try {
1169
- const { honoCache } = await import("../cache/hono-cache.js");
1170
- honoCache.invalidate(join(repoRoot, relativeFile));
1171
- }
1172
- catch {
1173
- // Best-effort
1174
- }
1175
- }
1176
- export async function listAllRepos(options) {
1177
- const config = loadConfig();
1178
- let repos = await listRegistryRepos(config.registryPath);
1179
- // Filter by name substring (case-insensitive)
1180
- if (options?.name_contains) {
1181
- const filter = options.name_contains.toLowerCase();
1182
- repos = repos.filter((r) => r.name.toLowerCase().includes(filter));
1183
- }
1184
- if (options?.compact === false)
1185
- return repos;
1186
- // Default: ultra-compact — just repo names (agents only need the identifier)
1187
- return repos.map((r) => r.name);
1188
- }
1189
- export async function invalidateCache(repoName) {
1190
- const config = loadConfig();
1191
- const meta = await getRepo(config.registryPath, repoName);
1192
- if (!meta)
1193
- return false;
1194
- // Stop watcher
1195
- const watcher = activeWatchers.get(repoName);
1196
- if (watcher) {
1197
- await stopWatcher(watcher);
1198
- activeWatchers.delete(repoName);
1199
- }
1200
- // Remove in-memory caches
1201
- bm25Indexes.delete(repoName);
1202
- codeIndexes.delete(repoName);
1203
- embeddingCaches.delete(repoName);
1204
- // Delete index file + embedding files + chunk files
1205
- const embeddingPath = getEmbeddingPath(meta.index_path);
1206
- const embeddingMetaPath = getEmbeddingMetaPath(meta.index_path);
1207
- const chunkPath = getChunkPath(meta.index_path);
1208
- const chunkEmbeddingPath = getChunkEmbeddingPath(meta.index_path);
1209
- const graphStorePath = getGraphPath(meta.index_path);
1210
- const snapshotPath = getSnapshotPath(meta.index_path);
1211
- for (const fp of [meta.index_path, embeddingPath, embeddingMetaPath, chunkPath, chunkEmbeddingPath, graphStorePath, snapshotPath]) {
1212
- try {
1213
- await unlink(fp);
1214
- }
1215
- catch { /* File may not exist */ }
1216
- }
1217
- // Remove from registry
1218
- await removeRepo(config.registryPath, repoName);
1219
- return true;
1220
- }
1221
- /**
1222
- * In-process record of the last indexed state per absolute file path.
1223
- *
1224
- * Telemetry (30d, 2026-06): 750 consecutive duplicate index_file calls at
1225
- * avg 3.7s each (~47 min of agent wall-clock). Two causes: (1) duplicate
1226
- * hook registrations firing index_file twice per edit, and (2) a race where
1227
- * call N+1's on-disk mtime pre-check read the index before call N's
1228
- * serialized saveIncremental landed, forcing a full re-parse + full-index
1229
- * save. This map short-circuits both in-process in ~1ms (mtime first, then
1230
- * content hash for touch/no-op rewrites) without loading the on-disk index.
1231
- */
1232
- const lastIndexedState = new Map();
1233
- /** Test hook — clear the in-process last-indexed state. */
1234
- export function clearLastIndexedStateForTesting() {
1235
- lastIndexedState.clear();
1236
- }
1237
- /**
1238
- * Re-index a single file instantly. Finds the repo by matching the file
1239
- * path against indexed repo roots. Updates symbols, BM25 index, and
1240
- * invalidates embedding cache — no full repo walk needed.
1241
- */
1242
- export async function indexFile(filePath) {
1243
- const absPath = resolve(filePath);
1244
- const config = loadConfig();
1245
- const repos = await listRegistryRepos(config.registryPath);
1246
- // Find the most specific repo root that contains this file
1247
- const matchingRepo = repos
1248
- .filter((r) => absPath.startsWith(r.root + "/") || absPath === r.root)
1249
- .sort((a, b) => b.root.length - a.root.length)[0];
1250
- if (!matchingRepo) {
1251
- throw new Error(`No indexed repo contains "${absPath}". Run index_folder first.`);
1252
- }
1253
- const startTime = Date.now();
1254
- const relPath = relative(matchingRepo.root, absPath);
1255
- // If the changed file is a TS/JS config that drives path resolution, drop
1256
- // caches so incremental indexing picks up new `paths` / `extends`.
1257
- {
1258
- const cfg = basename(absPath).toLowerCase();
1259
- if ((cfg.startsWith("tsconfig") || cfg.startsWith("jsconfig")) &&
1260
- cfg.endsWith(".json")) {
1261
- clearTsconfigCache();
1262
- }
1263
- }
1264
- // In-process short-circuit: mtime, then content hash. Both avoid loading
1265
- // the on-disk index entirely (the expensive part on large repos).
1266
- const st = await stat(absPath);
1267
- const mem = lastIndexedState.get(absPath);
1268
- if (mem && Math.round(st.mtimeMs) === mem.mtimeMs) {
1269
- return {
1270
- repo: matchingRepo.name,
1271
- file: relPath,
1272
- symbol_count: mem.symbolCount,
1273
- duration_ms: Date.now() - startTime,
1274
- skipped: true,
1275
- };
1276
- }
1277
- const content = await readFile(absPath, "utf-8").catch(() => null);
1278
- const contentHash = content !== null ? createHash("sha1").update(content).digest("hex") : null;
1279
- if (mem && contentHash !== null && contentHash === mem.contentHash) {
1280
- // Touched / rewritten with identical content — refresh mtime, skip work.
1281
- mem.mtimeMs = Math.round(st.mtimeMs);
1282
- return {
1283
- repo: matchingRepo.name,
1284
- file: relPath,
1285
- symbol_count: mem.symbolCount,
1286
- duration_ms: Date.now() - startTime,
1287
- skipped: true,
1288
- };
1289
- }
1290
- // On-disk mtime check — first touch of this file in this process (CLI
1291
- // hook invocations, fresh server). Skips files unchanged since the last
1292
- // full index, and seeds the in-process state for subsequent calls.
1293
- if (!mem) {
1294
- const existing = await loadIndex(matchingRepo.index_path);
1295
- if (existing) {
1296
- const prevEntry = existing.files.find((f) => f.path === relPath);
1297
- if (prevEntry?.mtime_ms && Math.round(st.mtimeMs) === prevEntry.mtime_ms) {
1298
- if (contentHash !== null) {
1299
- lastIndexedState.set(absPath, {
1300
- mtimeMs: Math.round(st.mtimeMs),
1301
- contentHash,
1302
- symbolCount: prevEntry.symbol_count,
1303
- });
1304
- }
1305
- return {
1306
- repo: matchingRepo.name,
1307
- file: relPath,
1308
- symbol_count: prevEntry.symbol_count,
1309
- duration_ms: Date.now() - startTime,
1310
- skipped: true,
1311
- };
1312
- }
1313
- }
1314
- }
1315
- const result = await parseOneFile(absPath, matchingRepo.root, matchingRepo.name);
1316
- if (!result) {
1317
- throw new Error(`Failed to parse "${relPath}"`);
1318
- }
1319
- await saveIncremental(matchingRepo.index_path, relPath, result.symbols, result.entry);
1320
- if (contentHash !== null) {
1321
- lastIndexedState.set(absPath, {
1322
- mtimeMs: Math.round(st.mtimeMs),
1323
- contentHash,
1324
- symbolCount: result.symbols.length,
1325
- });
1326
- }
1327
- let secretFindingsCount = 0;
1328
- if (config.secretScanEnabled) {
1329
- try {
1330
- secretFindingsCount = (await scanFileForSecrets(absPath, relPath, matchingRepo.name, result.symbols)).length;
1331
- }
1332
- catch (err) {
1333
- const message = err instanceof Error ? err.message : String(err);
1334
- console.warn(`[codesift] Secret scan failed for ${relPath}: ${message}`);
1335
- }
1336
- }
1337
- // Invalidate caches — lazy rebuild on next query via getBM25Index()
1338
- bm25Indexes.delete(matchingRepo.name);
1339
- codeIndexes.delete(matchingRepo.name);
1340
- embeddingCaches.delete(matchingRepo.name);
1341
- let secretsWarning;
1342
- if (secretFindingsCount > 0) {
1343
- secretsWarning = `\u26A0 ${secretFindingsCount} potential secret(s) detected`;
1344
- }
1345
- return {
1346
- repo: matchingRepo.name,
1347
- file: relPath,
1348
- symbol_count: result.symbols.length,
1349
- duration_ms: Date.now() - startTime,
1350
- ...(secretsWarning ? { secrets_warning: secretsWarning } : {}),
1351
- };
1352
- }
1353
- // ---------------------------------------------------------------------------
1354
- // Git-based auto-refresh — transparent freshness check before index access
1355
- // ---------------------------------------------------------------------------
1356
- const freshnessChecked = new Map();
1357
- const FRESHNESS_INTERVAL_MS = 60_000;
1358
- const MAX_DIFF_FILES = 50;
1359
- /**
1360
- * Ensure the index for a repo is fresh relative to git HEAD.
1361
- * Throttled to once per minute per repo. Reindexes changed files if HEAD moved.
1362
- * No-op for non-git repos.
1363
- */
1364
- export async function ensureIndexFresh(repoName) {
1365
- const lastCheck = freshnessChecked.get(repoName);
1366
- if (lastCheck && Date.now() - lastCheck < FRESHNESS_INTERVAL_MS) {
1367
- return { status: "fresh" };
1368
- }
1369
- const config = loadConfig();
1370
- const meta = await getRepo(config.registryPath, repoName);
1371
- if (!meta)
1372
- return { status: "skipped" };
1373
- let currentCommit;
1374
- try {
1375
- currentCommit = execFileSync("git", ["rev-parse", "HEAD"], {
1376
- cwd: meta.root, encoding: "utf-8", timeout: 5000,
1377
- }).trim();
1378
- }
1379
- catch {
1380
- freshnessChecked.set(repoName, Date.now());
1381
- return { status: "skipped" };
1382
- }
1383
- if (meta.last_git_commit === currentCommit) {
1384
- freshnessChecked.set(repoName, Date.now());
1385
- return { status: "fresh" };
1386
- }
1387
- // HEAD moved — find changed files
1388
- let changedFiles = [];
1389
- if (meta.last_git_commit) {
1390
- try {
1391
- const diff = execFileSync("git", [
1392
- "diff", "--name-only", "--diff-filter=ACMR",
1393
- `${meta.last_git_commit}..${currentCommit}`,
1394
- ], {
1395
- cwd: meta.root, encoding: "utf-8", timeout: 10_000,
1396
- });
1397
- changedFiles = diff.trim().split("\n").filter(Boolean);
1398
- }
1399
- catch {
1400
- // Stored commit gone (rebase/squash) — will do full incremental
1401
- changedFiles = [];
1402
- }
1403
- }
1404
- if (changedFiles.length > 0 && changedFiles.length <= MAX_DIFF_FILES) {
1405
- for (const file of changedFiles) {
1406
- try {
1407
- await indexFile(join(meta.root, file));
1408
- }
1409
- catch {
1410
- // File deleted or unparseable — skip
1411
- }
1412
- }
1413
- }
1414
- else if (changedFiles.length > MAX_DIFF_FILES || !meta.last_git_commit) {
1415
- await indexFolder(meta.root, { incremental: true, watch: false });
1416
- }
1417
- await updateRepoMeta(config.registryPath, repoName, {
1418
- last_git_commit: currentCommit,
1419
- updated_at: Date.now(),
1420
- });
1421
- bm25Indexes.delete(repoName);
1422
- codeIndexes.delete(repoName);
1423
- embeddingCaches.delete(repoName);
1424
- freshnessChecked.set(repoName, Date.now());
1425
- return { status: "refreshed", files_updated: changedFiles.length };
1426
- }
1427
- /** Reset freshness throttle cache. Exported for testing. */
1428
- export function resetFreshnessCache() {
1429
- freshnessChecked.clear();
1430
- }
1431
92
  /** Stop every active watcher and clear the in-memory index caches. Exported
1432
93
  * for testing — afterAll teardown of integration tests that index temp dirs
1433
94
  * must call this before `rm -rf`-ing the temp dir, otherwise the chokidar
@@ -1440,329 +101,6 @@ export async function stopAllWatchersForTesting() {
1440
101
  bm25Indexes.clear();
1441
102
  codeIndexes.clear();
1442
103
  embeddingCaches.clear();
1443
- freshnessChecked.clear();
1444
- }
1445
- // ---------------------------------------------------------------------------
1446
- // Index access — with auto-refresh
1447
- // ---------------------------------------------------------------------------
1448
- /**
1449
- * Get the in-memory BM25 index for a repo.
1450
- * Loads from disk if not cached. Auto-refreshes if git HEAD moved.
1451
- */
1452
- export async function getBM25Index(repoName) {
1453
- await ensureIndexFresh(repoName);
1454
- const cached = bm25Indexes.get(repoName);
1455
- if (cached)
1456
- return cached;
1457
- const config = loadConfig();
1458
- const meta = await getRepo(config.registryPath, repoName);
1459
- if (!meta)
1460
- return null;
1461
- const index = await loadIndex(meta.index_path);
1462
- if (!index)
1463
- return null;
1464
- const bm25 = buildBM25Index(index.symbols);
1465
- bm25Indexes.set(repoName, bm25);
1466
- return bm25;
1467
- }
1468
- /**
1469
- * Get the code index for a repo from disk.
1470
- * Starts watcher if not running (lazy start after server restart).
1471
- */
1472
- /**
1473
- * Get the code index for a repo from disk. Auto-refreshes if git HEAD moved.
1474
- */
1475
- export async function getCodeIndex(repoName, options) {
1476
- const config = loadConfig();
1477
- const resolved = await resolveRegisteredRepoMeta(config.registryPath, repoName);
1478
- if (!resolved)
1479
- return null;
1480
- const { resolvedName, meta } = resolved;
1481
- if (!options?.skipFreshness) {
1482
- await ensureIndexFresh(resolvedName);
1483
- }
1484
- const cached = codeIndexes.get(resolvedName);
1485
- if (cached)
1486
- return cached;
1487
- const result = await loadIndexOrStale(meta.index_path, { ...EXTRACTOR_VERSIONS });
1488
- if (!result)
1489
- return null;
1490
- if (result.status === "stale") {
1491
- const extra = result.mismatch_detail ? ` — ${result.mismatch_detail}` : "";
1492
- console.warn(`[codesift] stale index for ${resolvedName}: extractor_version_mismatch ` +
1493
- `(${result.language} expected ${result.expected_version}, got ${result.actual_version})${extra}. ` +
1494
- `Run index_folder to refresh.`);
1495
- return null;
1496
- }
1497
- codeIndexes.set(resolvedName, result.index);
1498
- return result.index;
1499
- }
1500
- /**
1501
- * Walk up from dir until a .git directory is found. Returns the git root or null.
1502
- */
1503
- async function findGitRoot(dir) {
1504
- let current = resolve(dir);
1505
- while (true) {
1506
- try {
1507
- await stat(join(current, ".git"));
1508
- return current;
1509
- }
1510
- catch {
1511
- const parent = dirname(current);
1512
- if (parent === current)
1513
- return null;
1514
- current = parent;
1515
- }
1516
- }
1517
- }
1518
- /**
1519
- * Called at server startup. If the CWD is inside a git repo that isn't indexed yet,
1520
- * index it automatically in the background so tools work without manual setup.
1521
- */
1522
- export async function autoIndexCurrentRepo(cwd) {
1523
- const gitRoot = await findGitRoot(cwd);
1524
- if (!gitRoot)
1525
- return;
1526
- const repoName = getRepoName(gitRoot);
1527
- const config = loadConfig();
1528
- const existing = await getRepo(config.registryPath, repoName);
1529
- if (existing)
1530
- return;
1531
- console.error(`[codesift] Auto-indexing ${repoName} (first use)...`);
1532
- await indexFolder(gitRoot);
1533
- console.error(`[codesift] Auto-index complete: ${repoName}`);
1534
- }
1535
- /** True when embeddings are disabled entirely (low-RAM / lite mode). */
1536
- function embeddingsDisabled() {
1537
- const v = process.env["CODESIFT_DISABLE_LOCAL_EMBEDDINGS"];
1538
- return v === "1" || v === "true";
1539
- }
1540
- /** Resident-embedding RAM budget in MB (default 1024). 0/invalid → default. */
1541
- function embeddingMemBudgetBytes() {
1542
- const raw = process.env["CODESIFT_MAX_EMBEDDING_MEM_MB"];
1543
- const n = raw ? parseInt(raw, 10) : NaN;
1544
- return (Number.isNaN(n) || n <= 0 ? 1024 : n) * 1024 * 1024;
1545
- }
1546
- function embeddingMapBytes(m) {
1547
- let b = 0;
1548
- for (const v of m.values())
1549
- b += v.byteLength;
1550
- return b;
1551
- }
1552
- /**
1553
- * Evict least-recently-used repo embeddings while total resident bytes exceed
1554
- * the budget. `embeddingCaches` insertion order is the LRU order (getter
1555
- * re-inserts on hit). `pinned` (the repo being served right now) is never
1556
- * evicted mid-query. Bytes are summed from the live maps (source of truth) so
1557
- * the many `.delete` call sites can't drift an accounting counter.
1558
- */
1559
- function evictEmbeddingCachesOverBudget(pinned) {
1560
- const budget = embeddingMemBudgetBytes();
1561
- const sizes = new Map();
1562
- let total = 0;
1563
- for (const [k, m] of embeddingCaches) {
1564
- const b = embeddingMapBytes(m);
1565
- sizes.set(k, b);
1566
- total += b;
1567
- }
1568
- if (total <= budget)
1569
- return;
1570
- for (const k of [...embeddingCaches.keys()]) {
1571
- if (total <= budget)
1572
- break;
1573
- if (k === pinned)
1574
- continue;
1575
- embeddingCaches.delete(k);
1576
- total -= sizes.get(k) ?? 0;
1577
- }
1578
- }
1579
- /** Test-only: repo names currently resident in the embedding cache (LRU order, oldest first). */
1580
- export function _cachedEmbeddingReposForTesting() {
1581
- return [...embeddingCaches.keys()];
1582
- }
1583
- /**
1584
- * In-flight embedding loads, keyed by repo. Two MCP sessions (e.g. two editor
1585
- * windows on one `codesift serve` daemon) that first-access the same repo
1586
- * concurrently must trigger ONE disk load, not one per session — otherwise a
1587
- * GB-scale load runs N times in parallel. Concurrent callers await the same
1588
- * promise; the entry clears once the load settles.
1589
- */
1590
- const embeddingLoadsInFlight = new Map();
1591
- /** Count of actual disk loads (test-only) — proves load-once across sessions. */
1592
- let embeddingLoadCount = 0;
1593
- export function _embeddingLoadCountForTesting() {
1594
- return embeddingLoadCount;
1595
- }
1596
- export function _resetEmbeddingLoadCountForTesting() {
1597
- embeddingLoadCount = 0;
1598
- }
1599
- /**
1600
- * Get the in-memory embedding cache for a repo.
1601
- * Loads from disk if not cached. Returns null if no embeddings file exists,
1602
- * or if embeddings are disabled (lite mode). Bounds resident RAM via LRU, and
1603
- * dedupes concurrent first-access so the load runs exactly once per repo.
1604
- */
1605
- export async function getEmbeddingCache(repoName) {
1606
- // Lite mode: never hold embeddings in RAM (semantic falls back to BM25).
1607
- if (embeddingsDisabled())
1608
- return null;
1609
- const cached = embeddingCaches.get(repoName);
1610
- if (cached) {
1611
- // LRU touch: move to most-recently-used end.
1612
- embeddingCaches.delete(repoName);
1613
- embeddingCaches.set(repoName, cached);
1614
- return cached;
1615
- }
1616
- // Coalesce concurrent first-access onto one load.
1617
- const inFlight = embeddingLoadsInFlight.get(repoName);
1618
- if (inFlight)
1619
- return inFlight;
1620
- const loadPromise = (async () => {
1621
- const config = loadConfig();
1622
- const meta = await getRepo(config.registryPath, repoName);
1623
- if (!meta)
1624
- return null;
1625
- const embeddingPath = getEmbeddingPath(meta.index_path);
1626
- embeddingLoadCount++;
1627
- const embeddings = await loadEmbeddings(embeddingPath);
1628
- if (embeddings.size === 0)
1629
- return null;
1630
- // Pin-on-access: this repo is the one being served, so eviction never drops
1631
- // it out from under the load/query that just requested it.
1632
- embeddingCaches.set(repoName, embeddings);
1633
- evictEmbeddingCachesOverBudget(repoName);
1634
- return embeddings;
1635
- })();
1636
- embeddingLoadsInFlight.set(repoName, loadPromise);
1637
- try {
1638
- return await loadPromise;
1639
- }
1640
- finally {
1641
- embeddingLoadsInFlight.delete(repoName);
1642
- }
1643
- }
1644
- // ---------------------------------------------------------------------------
1645
- // Astro extractor version check + lockfile re-index
1646
- // ---------------------------------------------------------------------------
1647
- export const ASTRO_LOCK_FILENAME = "astro-reindex.lock";
1648
- export const EXTRACTOR_VERSIONS_FILENAME = "extractor-versions.json";
1649
- const LOCK_STALE_MS = 60_000; // 60 seconds
1650
- /**
1651
- * Check if the stored astro extractor version matches the current one.
1652
- * If not, re-extract all .astro files with lockfile protection.
1653
- *
1654
- * @param dataDir The data directory (e.g., ~/.codesift or a test tmpdir)
1655
- * @param repoRoot The repo root path (for locating .astro files)
1656
- * @param astroFiles Relative paths to .astro files in the repo
1657
- */
1658
- export async function checkAstroExtractorVersion(dataDir, repoRoot, astroFiles) {
1659
- // Read stored version snapshot
1660
- const versionsPath = join(dataDir, EXTRACTOR_VERSIONS_FILENAME);
1661
- let storedVersions = {};
1662
- try {
1663
- const raw = await readFile(versionsPath, "utf-8");
1664
- storedVersions = JSON.parse(raw);
1665
- }
1666
- catch {
1667
- // File doesn't exist or is invalid — treat as version mismatch
1668
- }
1669
- // Check if astro version matches
1670
- if (storedVersions.astro === EXTRACTOR_VERSIONS.astro) {
1671
- return { reindexed: false, reason: "astro extractor up to date" };
1672
- }
1673
- if (astroFiles.length === 0) {
1674
- // No astro files to re-extract — just update the version snapshot
1675
- await writeVersionSnapshot(dataDir, storedVersions);
1676
- return { reindexed: false, reason: "no astro files to re-extract" };
1677
- }
1678
- // Acquire lockfile
1679
- const lockPath = join(dataDir, ASTRO_LOCK_FILENAME);
1680
- if (!acquireLock(lockPath)) {
1681
- return { reindexed: false, reason: "astro re-index in progress (locked by another process)" };
1682
- }
1683
- try {
1684
- // Re-extract all .astro files
1685
- let count = 0;
1686
- for (const relPath of astroFiles) {
1687
- const absPath = join(repoRoot, relPath);
1688
- try {
1689
- const result = await parseOneFile(absPath, repoRoot, "");
1690
- if (result) {
1691
- count++;
1692
- if (count % 100 === 0) {
1693
- console.error(`[codesift] Astro re-index progress: ${count}/${astroFiles.length} files`);
1694
- }
1695
- }
1696
- }
1697
- catch {
1698
- // File may have been deleted or is unparseable
1699
- }
1700
- }
1701
- // Write version snapshot atomically
1702
- await writeVersionSnapshot(dataDir, storedVersions);
1703
- return {
1704
- reindexed: true,
1705
- files_reindexed: count,
1706
- reason: `re-extracted ${count} astro files (version ${storedVersions.astro ?? "none"} → ${EXTRACTOR_VERSIONS.astro})`,
1707
- };
1708
- }
1709
- finally {
1710
- // Release lockfile
1711
- try {
1712
- unlinkSync(lockPath);
1713
- }
1714
- catch {
1715
- // Lock may have been cleaned up already
1716
- }
1717
- }
1718
- }
1719
- /**
1720
- * Acquire an exclusive lockfile. Returns true if lock was acquired.
1721
- * If lockfile exists but is stale (mtime > 60s), deletes it and retries once.
1722
- */
1723
- function acquireLock(lockPath) {
1724
- try {
1725
- const fd = openSync(lockPath, "wx");
1726
- closeSync(fd);
1727
- return true;
1728
- }
1729
- catch (err) {
1730
- if (err.code !== "EEXIST") {
1731
- return false;
1732
- }
1733
- // Lock exists — check if stale
1734
- try {
1735
- const lockStat = statSync(lockPath);
1736
- const age = Date.now() - lockStat.mtimeMs;
1737
- if (age > LOCK_STALE_MS) {
1738
- // Stale lock — delete and retry once
1739
- unlinkSync(lockPath);
1740
- try {
1741
- const fd = openSync(lockPath, "wx");
1742
- closeSync(fd);
1743
- return true;
1744
- }
1745
- catch {
1746
- return false;
1747
- }
1748
- }
1749
- }
1750
- catch {
1751
- // stat failed — lock was just removed by another process
1752
- return false;
1753
- }
1754
- return false;
1755
- }
1756
- }
1757
- /**
1758
- * Atomically write the extractor versions snapshot.
1759
- * Uses write-to-tmp + rename for crash safety.
1760
- */
1761
- async function writeVersionSnapshot(dataDir, existingVersions) {
1762
- const versionsPath = join(dataDir, EXTRACTOR_VERSIONS_FILENAME);
1763
- const tmpPath = `${versionsPath}.tmp.${Date.now()}`;
1764
- const snapshot = { ...existingVersions, astro: EXTRACTOR_VERSIONS.astro };
1765
- writeFileSync(tmpPath, JSON.stringify(snapshot), "utf-8");
1766
- renameSync(tmpPath, versionsPath);
104
+ resetFreshnessCache();
1767
105
  }
1768
106
  //# sourceMappingURL=index-tools.js.map