codesift-mcp 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. package/README.md +5 -1
  2. package/dist/cli/commands-admin.d.ts +18 -0
  3. package/dist/cli/commands-admin.d.ts.map +1 -0
  4. package/dist/cli/commands-admin.js +187 -0
  5. package/dist/cli/commands-admin.js.map +1 -0
  6. package/dist/cli/commands-daemon.d.ts +42 -0
  7. package/dist/cli/commands-daemon.d.ts.map +1 -0
  8. package/dist/cli/commands-daemon.js +163 -0
  9. package/dist/cli/commands-daemon.js.map +1 -0
  10. package/dist/cli/commands-index.d.ts +12 -0
  11. package/dist/cli/commands-index.d.ts.map +1 -0
  12. package/dist/cli/commands-index.js +133 -0
  13. package/dist/cli/commands-index.js.map +1 -0
  14. package/dist/cli/commands-maintenance.d.ts +12 -0
  15. package/dist/cli/commands-maintenance.d.ts.map +1 -0
  16. package/dist/cli/commands-maintenance.js +409 -0
  17. package/dist/cli/commands-maintenance.js.map +1 -0
  18. package/dist/cli/commands-query.d.ts +21 -0
  19. package/dist/cli/commands-query.d.ts.map +1 -0
  20. package/dist/cli/commands-query.js +270 -0
  21. package/dist/cli/commands-query.js.map +1 -0
  22. package/dist/cli/commands.d.ts +2 -36
  23. package/dist/cli/commands.d.ts.map +1 -1
  24. package/dist/cli/commands.js +8 -854
  25. package/dist/cli/commands.js.map +1 -1
  26. package/dist/cli/embed-child.js +13 -2
  27. package/dist/cli/embed-child.js.map +1 -1
  28. package/dist/cli/hooks/pre-tool-use.d.ts +1 -0
  29. package/dist/cli/hooks/pre-tool-use.d.ts.map +1 -1
  30. package/dist/cli/hooks/pre-tool-use.js +11 -2
  31. package/dist/cli/hooks/pre-tool-use.js.map +1 -1
  32. package/dist/config.d.ts +13 -0
  33. package/dist/config.d.ts.map +1 -1
  34. package/dist/config.js +21 -0
  35. package/dist/config.js.map +1 -1
  36. package/dist/formatters-core.d.ts +7 -0
  37. package/dist/formatters-core.d.ts.map +1 -1
  38. package/dist/formatters-core.js +14 -3
  39. package/dist/formatters-core.js.map +1 -1
  40. package/dist/instructions.d.ts +1 -1
  41. package/dist/instructions.d.ts.map +1 -1
  42. package/dist/instructions.js +5 -2
  43. package/dist/instructions.js.map +1 -1
  44. package/dist/parser/extractors/hono-inline-analyzer.js +2 -2
  45. package/dist/parser/extractors/hono-inline-analyzer.js.map +1 -1
  46. package/dist/parser/extractors/php-class-metadata.d.ts +10 -0
  47. package/dist/parser/extractors/php-class-metadata.d.ts.map +1 -0
  48. package/dist/parser/extractors/php-class-metadata.js +65 -0
  49. package/dist/parser/extractors/php-class-metadata.js.map +1 -0
  50. package/dist/parser/extractors/php-doc.d.ts +13 -0
  51. package/dist/parser/extractors/php-doc.d.ts.map +1 -0
  52. package/dist/parser/extractors/php-doc.js +39 -0
  53. package/dist/parser/extractors/php-doc.js.map +1 -0
  54. package/dist/parser/extractors/php-node-metadata.d.ts +26 -0
  55. package/dist/parser/extractors/php-node-metadata.d.ts.map +1 -0
  56. package/dist/parser/extractors/php-node-metadata.js +132 -0
  57. package/dist/parser/extractors/php-node-metadata.js.map +1 -0
  58. package/dist/parser/extractors/php-symbol-builders.d.ts +13 -0
  59. package/dist/parser/extractors/php-symbol-builders.d.ts.map +1 -0
  60. package/dist/parser/extractors/php-symbol-builders.js +58 -0
  61. package/dist/parser/extractors/php-symbol-builders.js.map +1 -0
  62. package/dist/parser/extractors/php-walker.d.ts +4 -0
  63. package/dist/parser/extractors/php-walker.d.ts.map +1 -0
  64. package/dist/parser/extractors/php-walker.js +238 -0
  65. package/dist/parser/extractors/php-walker.js.map +1 -0
  66. package/dist/parser/extractors/php.d.ts +2 -33
  67. package/dist/parser/extractors/php.d.ts.map +1 -1
  68. package/dist/parser/extractors/php.js +2 -747
  69. package/dist/parser/extractors/php.js.map +1 -1
  70. package/dist/register-tool-groups/core/search.d.ts.map +1 -1
  71. package/dist/register-tool-groups/core/search.js +14 -0
  72. package/dist/register-tool-groups/core/search.js.map +1 -1
  73. package/dist/register-tool-groups/core/symbols.d.ts.map +1 -1
  74. package/dist/register-tool-groups/core/symbols.js +50 -5
  75. package/dist/register-tool-groups/core/symbols.js.map +1 -1
  76. package/dist/register-tool-loaders.d.ts +11 -11
  77. package/dist/register-tool-loaders.d.ts.map +1 -1
  78. package/dist/register-tools/runtime.d.ts +11 -0
  79. package/dist/register-tools/runtime.d.ts.map +1 -1
  80. package/dist/register-tools/runtime.js +40 -0
  81. package/dist/register-tools/runtime.js.map +1 -1
  82. package/dist/register-tools.d.ts.map +1 -1
  83. package/dist/register-tools.js +5 -1
  84. package/dist/register-tools.js.map +1 -1
  85. package/dist/retrieval/semantic-handlers.d.ts.map +1 -1
  86. package/dist/retrieval/semantic-handlers.js +10 -3
  87. package/dist/retrieval/semantic-handlers.js.map +1 -1
  88. package/dist/search/semantic.d.ts +2 -0
  89. package/dist/search/semantic.d.ts.map +1 -1
  90. package/dist/search/semantic.js +41 -9
  91. package/dist/search/semantic.js.map +1 -1
  92. package/dist/server.d.ts.map +1 -1
  93. package/dist/server.js +54 -2
  94. package/dist/server.js.map +1 -1
  95. package/dist/storage/_shared.d.ts +21 -0
  96. package/dist/storage/_shared.d.ts.map +1 -1
  97. package/dist/storage/_shared.js +36 -0
  98. package/dist/storage/_shared.js.map +1 -1
  99. package/dist/storage/chunk-store.d.ts +14 -2
  100. package/dist/storage/chunk-store.d.ts.map +1 -1
  101. package/dist/storage/chunk-store.js +214 -34
  102. package/dist/storage/chunk-store.js.map +1 -1
  103. package/dist/storage/embedding-store.d.ts +0 -12
  104. package/dist/storage/embedding-store.d.ts.map +1 -1
  105. package/dist/storage/embedding-store.js +69 -9
  106. package/dist/storage/embedding-store.js.map +1 -1
  107. package/dist/storage/index-cache.d.ts +12 -0
  108. package/dist/storage/index-cache.d.ts.map +1 -0
  109. package/dist/storage/index-cache.js +89 -0
  110. package/dist/storage/index-cache.js.map +1 -0
  111. package/dist/storage/index-footprint.d.ts +12 -0
  112. package/dist/storage/index-footprint.d.ts.map +1 -0
  113. package/dist/storage/index-footprint.js +41 -0
  114. package/dist/storage/index-footprint.js.map +1 -0
  115. package/dist/storage/index-json-mutations.d.ts +11 -0
  116. package/dist/storage/index-json-mutations.d.ts.map +1 -0
  117. package/dist/storage/index-json-mutations.js +93 -0
  118. package/dist/storage/index-json-mutations.js.map +1 -0
  119. package/dist/storage/index-migration.d.ts +22 -0
  120. package/dist/storage/index-migration.d.ts.map +1 -0
  121. package/dist/storage/index-migration.js +80 -0
  122. package/dist/storage/index-migration.js.map +1 -0
  123. package/dist/storage/index-store.d.ts +26 -55
  124. package/dist/storage/index-store.d.ts.map +1 -1
  125. package/dist/storage/index-store.js +82 -350
  126. package/dist/storage/index-store.js.map +1 -1
  127. package/dist/storage/index-version.d.ts +39 -0
  128. package/dist/storage/index-version.d.ts.map +1 -0
  129. package/dist/storage/index-version.js +87 -0
  130. package/dist/storage/index-version.js.map +1 -0
  131. package/dist/storage/registry.d.ts +9 -1
  132. package/dist/storage/registry.d.ts.map +1 -1
  133. package/dist/storage/registry.js +233 -9
  134. package/dist/storage/registry.js.map +1 -1
  135. package/dist/storage/shared-embedding-cache.d.ts +23 -3
  136. package/dist/storage/shared-embedding-cache.d.ts.map +1 -1
  137. package/dist/storage/shared-embedding-cache.js +300 -45
  138. package/dist/storage/shared-embedding-cache.js.map +1 -1
  139. package/dist/storage/sqlite/accessors.d.ts +34 -0
  140. package/dist/storage/sqlite/accessors.d.ts.map +1 -0
  141. package/dist/storage/sqlite/accessors.js +178 -0
  142. package/dist/storage/sqlite/accessors.js.map +1 -0
  143. package/dist/storage/sqlite/connection.d.ts +43 -0
  144. package/dist/storage/sqlite/connection.d.ts.map +1 -0
  145. package/dist/storage/sqlite/connection.js +241 -0
  146. package/dist/storage/sqlite/connection.js.map +1 -0
  147. package/dist/storage/sqlite/errors.d.ts +38 -0
  148. package/dist/storage/sqlite/errors.d.ts.map +1 -0
  149. package/dist/storage/sqlite/errors.js +150 -0
  150. package/dist/storage/sqlite/errors.js.map +1 -0
  151. package/dist/storage/sqlite/index-io.d.ts +49 -0
  152. package/dist/storage/sqlite/index-io.d.ts.map +1 -0
  153. package/dist/storage/sqlite/index-io.js +268 -0
  154. package/dist/storage/sqlite/index-io.js.map +1 -0
  155. package/dist/storage/sqlite/meta.d.ts +41 -0
  156. package/dist/storage/sqlite/meta.d.ts.map +1 -0
  157. package/dist/storage/sqlite/meta.js +28 -0
  158. package/dist/storage/sqlite/meta.js.map +1 -0
  159. package/dist/storage/sqlite/rows.d.ts +64 -0
  160. package/dist/storage/sqlite/rows.d.ts.map +1 -0
  161. package/dist/storage/sqlite/rows.js +186 -0
  162. package/dist/storage/sqlite/rows.js.map +1 -0
  163. package/dist/storage/sqlite/runtime.d.ts +6 -0
  164. package/dist/storage/sqlite/runtime.d.ts.map +1 -0
  165. package/dist/storage/sqlite/runtime.js +31 -0
  166. package/dist/storage/sqlite/runtime.js.map +1 -0
  167. package/dist/storage/sqlite/schema.d.ts +34 -0
  168. package/dist/storage/sqlite/schema.d.ts.map +1 -0
  169. package/dist/storage/sqlite/schema.js +98 -0
  170. package/dist/storage/sqlite/schema.js.map +1 -0
  171. package/dist/storage/sqlite-index-store.d.ts +40 -80
  172. package/dist/storage/sqlite-index-store.d.ts.map +1 -1
  173. package/dist/storage/sqlite-index-store.js +32 -577
  174. package/dist/storage/sqlite-index-store.js.map +1 -1
  175. package/dist/storage/telemetry/config.d.ts.map +1 -1
  176. package/dist/storage/telemetry/config.js +15 -3
  177. package/dist/storage/telemetry/config.js.map +1 -1
  178. package/dist/storage/telemetry/payload.d.ts.map +1 -1
  179. package/dist/storage/telemetry/payload.js +4 -1
  180. package/dist/storage/telemetry/payload.js.map +1 -1
  181. package/dist/storage/telemetry/retro-aggregator.d.ts +48 -0
  182. package/dist/storage/telemetry/retro-aggregator.d.ts.map +1 -0
  183. package/dist/storage/telemetry/retro-aggregator.js +221 -0
  184. package/dist/storage/telemetry/retro-aggregator.js.map +1 -0
  185. package/dist/storage/telemetry/sanitizer.d.ts +46 -0
  186. package/dist/storage/telemetry/sanitizer.d.ts.map +1 -1
  187. package/dist/storage/telemetry/sanitizer.js +25 -0
  188. package/dist/storage/telemetry/sanitizer.js.map +1 -1
  189. package/dist/storage/telemetry/uploader.d.ts +3 -1
  190. package/dist/storage/telemetry/uploader.d.ts.map +1 -1
  191. package/dist/storage/telemetry/uploader.js +161 -18
  192. package/dist/storage/telemetry/uploader.js.map +1 -1
  193. package/dist/storage/workspace-resolver.js +1 -1
  194. package/dist/storage/workspace-resolver.js.map +1 -1
  195. package/dist/tools/cross-repo-contract-adapters.d.ts +39 -0
  196. package/dist/tools/cross-repo-contract-adapters.d.ts.map +1 -0
  197. package/dist/tools/cross-repo-contract-adapters.js +70 -0
  198. package/dist/tools/cross-repo-contract-adapters.js.map +1 -0
  199. package/dist/tools/cross-repo-contract-group.d.ts +17 -0
  200. package/dist/tools/cross-repo-contract-group.d.ts.map +1 -0
  201. package/dist/tools/cross-repo-contract-group.js +89 -0
  202. package/dist/tools/cross-repo-contract-group.js.map +1 -0
  203. package/dist/tools/cross-repo-contract-matcher.d.ts +24 -0
  204. package/dist/tools/cross-repo-contract-matcher.d.ts.map +1 -0
  205. package/dist/tools/cross-repo-contract-matcher.js +134 -0
  206. package/dist/tools/cross-repo-contract-matcher.js.map +1 -0
  207. package/dist/tools/cross-repo-contract-resolver.d.ts +9 -0
  208. package/dist/tools/cross-repo-contract-resolver.d.ts.map +1 -0
  209. package/dist/tools/cross-repo-contract-resolver.js +86 -0
  210. package/dist/tools/cross-repo-contract-resolver.js.map +1 -0
  211. package/dist/tools/cross-repo-contract-tools.d.ts +12 -135
  212. package/dist/tools/cross-repo-contract-tools.d.ts.map +1 -1
  213. package/dist/tools/cross-repo-contract-tools.js +8 -589
  214. package/dist/tools/cross-repo-contract-tools.js.map +1 -1
  215. package/dist/tools/cross-repo-contract-types.d.ts +30 -0
  216. package/dist/tools/cross-repo-contract-types.d.ts.map +1 -0
  217. package/dist/tools/cross-repo-contract-types.js +3 -0
  218. package/dist/tools/cross-repo-contract-types.js.map +1 -0
  219. package/dist/tools/cross-repo-outbound-calls.d.ts +28 -0
  220. package/dist/tools/cross-repo-outbound-calls.d.ts.map +1 -0
  221. package/dist/tools/cross-repo-outbound-calls.js +347 -0
  222. package/dist/tools/cross-repo-outbound-calls.js.map +1 -0
  223. package/dist/tools/cross-repo-outbound-lexer/call-detectors.d.ts.map +1 -1
  224. package/dist/tools/cross-repo-outbound-lexer/call-detectors.js +2 -0
  225. package/dist/tools/cross-repo-outbound-lexer/call-detectors.js.map +1 -1
  226. package/dist/tools/cross-repo-outbound-lexer/types.d.ts +2 -0
  227. package/dist/tools/cross-repo-outbound-lexer/types.d.ts.map +1 -1
  228. package/dist/tools/index-tools/file-indexer.js +3 -3
  229. package/dist/tools/index-tools/file-indexer.js.map +1 -1
  230. package/dist/tools/index-tools/folder-indexer.d.ts.map +1 -1
  231. package/dist/tools/index-tools/folder-indexer.js +51 -3
  232. package/dist/tools/index-tools/folder-indexer.js.map +1 -1
  233. package/dist/tools/index-tools/parse.d.ts +12 -3
  234. package/dist/tools/index-tools/parse.d.ts.map +1 -1
  235. package/dist/tools/index-tools/parse.js +33 -8
  236. package/dist/tools/index-tools/parse.js.map +1 -1
  237. package/dist/tools/index-tools/registry.d.ts +35 -0
  238. package/dist/tools/index-tools/registry.d.ts.map +1 -1
  239. package/dist/tools/index-tools/registry.js +167 -3
  240. package/dist/tools/index-tools/registry.js.map +1 -1
  241. package/dist/tools/index-tools/state.d.ts +31 -0
  242. package/dist/tools/index-tools/state.d.ts.map +1 -1
  243. package/dist/tools/index-tools/state.js +53 -0
  244. package/dist/tools/index-tools/state.js.map +1 -1
  245. package/dist/tools/index-tools/types.d.ts +9 -0
  246. package/dist/tools/index-tools/types.d.ts.map +1 -1
  247. package/dist/tools/index-tools/watcher.js +3 -3
  248. package/dist/tools/index-tools/watcher.js.map +1 -1
  249. package/dist/tools/index-tools/worktree-seed.d.ts +44 -0
  250. package/dist/tools/index-tools/worktree-seed.d.ts.map +1 -0
  251. package/dist/tools/index-tools/worktree-seed.js +302 -0
  252. package/dist/tools/index-tools/worktree-seed.js.map +1 -0
  253. package/dist/tools/index-tools.d.ts +2 -2
  254. package/dist/tools/index-tools.d.ts.map +1 -1
  255. package/dist/tools/index-tools.js +5 -3
  256. package/dist/tools/index-tools.js.map +1 -1
  257. package/dist/tools/nest-ext-tools/graphql.d.ts +17 -0
  258. package/dist/tools/nest-ext-tools/graphql.d.ts.map +1 -0
  259. package/dist/tools/nest-ext-tools/graphql.js +54 -0
  260. package/dist/tools/nest-ext-tools/graphql.js.map +1 -0
  261. package/dist/tools/nest-ext-tools/microservice.d.ts +17 -0
  262. package/dist/tools/nest-ext-tools/microservice.d.ts.map +1 -0
  263. package/dist/tools/nest-ext-tools/microservice.js +51 -0
  264. package/dist/tools/nest-ext-tools/microservice.js.map +1 -0
  265. package/dist/tools/nest-ext-tools/openapi.d.ts +81 -0
  266. package/dist/tools/nest-ext-tools/openapi.d.ts.map +1 -0
  267. package/dist/tools/nest-ext-tools/openapi.js +254 -0
  268. package/dist/tools/nest-ext-tools/openapi.js.map +1 -0
  269. package/dist/tools/nest-ext-tools/queue.d.ts +27 -0
  270. package/dist/tools/nest-ext-tools/queue.d.ts.map +1 -0
  271. package/dist/tools/nest-ext-tools/queue.js +95 -0
  272. package/dist/tools/nest-ext-tools/queue.js.map +1 -0
  273. package/dist/tools/nest-ext-tools/schedule.d.ts +19 -0
  274. package/dist/tools/nest-ext-tools/schedule.d.ts.map +1 -0
  275. package/dist/tools/nest-ext-tools/schedule.js +89 -0
  276. package/dist/tools/nest-ext-tools/schedule.js.map +1 -0
  277. package/dist/tools/nest-ext-tools/scope.d.ts +19 -0
  278. package/dist/tools/nest-ext-tools/scope.d.ts.map +1 -0
  279. package/dist/tools/nest-ext-tools/scope.js +151 -0
  280. package/dist/tools/nest-ext-tools/scope.js.map +1 -0
  281. package/dist/tools/nest-ext-tools/shared.d.ts +33 -0
  282. package/dist/tools/nest-ext-tools/shared.d.ts.map +1 -0
  283. package/dist/tools/nest-ext-tools/shared.js +279 -0
  284. package/dist/tools/nest-ext-tools/shared.js.map +1 -0
  285. package/dist/tools/nest-ext-tools/typeorm.d.ts +22 -0
  286. package/dist/tools/nest-ext-tools/typeorm.d.ts.map +1 -0
  287. package/dist/tools/nest-ext-tools/typeorm.js +59 -0
  288. package/dist/tools/nest-ext-tools/typeorm.js.map +1 -0
  289. package/dist/tools/nest-ext-tools/websocket.d.ts +21 -0
  290. package/dist/tools/nest-ext-tools/websocket.d.ts.map +1 -0
  291. package/dist/tools/nest-ext-tools/websocket.js +70 -0
  292. package/dist/tools/nest-ext-tools/websocket.js.map +1 -0
  293. package/dist/tools/nest-ext-tools.d.ts +10 -204
  294. package/dist/tools/nest-ext-tools.d.ts.map +1 -1
  295. package/dist/tools/nest-ext-tools.js +10 -749
  296. package/dist/tools/nest-ext-tools.js.map +1 -1
  297. package/dist/tools/perf-tools.js +2 -2
  298. package/dist/tools/plan-turn/stale-index.d.ts +32 -0
  299. package/dist/tools/plan-turn/stale-index.d.ts.map +1 -1
  300. package/dist/tools/plan-turn/stale-index.js +42 -5
  301. package/dist/tools/plan-turn/stale-index.js.map +1 -1
  302. package/dist/tools/python-audit/checks/dead-code.d.ts +1 -1
  303. package/dist/tools/python-audit/checks/dead-code.d.ts.map +1 -1
  304. package/dist/tools/python-constants/constant-match.d.ts +5 -0
  305. package/dist/tools/python-constants/constant-match.d.ts.map +1 -0
  306. package/dist/tools/python-constants/constant-match.js +24 -0
  307. package/dist/tools/python-constants/constant-match.js.map +1 -0
  308. package/dist/tools/python-constants/file-context.d.ts +5 -0
  309. package/dist/tools/python-constants/file-context.d.ts.map +1 -0
  310. package/dist/tools/python-constants/file-context.js +91 -0
  311. package/dist/tools/python-constants/file-context.js.map +1 -0
  312. package/dist/tools/python-constants/function-defaults.d.ts +5 -0
  313. package/dist/tools/python-constants/function-defaults.d.ts.map +1 -0
  314. package/dist/tools/python-constants/function-defaults.js +98 -0
  315. package/dist/tools/python-constants/function-defaults.js.map +1 -0
  316. package/dist/tools/python-constants/model.d.ts +78 -0
  317. package/dist/tools/python-constants/model.d.ts.map +1 -0
  318. package/dist/tools/python-constants/model.js +2 -0
  319. package/dist/tools/python-constants/model.js.map +1 -0
  320. package/dist/tools/python-constants/syntax.d.ts +22 -0
  321. package/dist/tools/python-constants/syntax.d.ts.map +1 -0
  322. package/dist/tools/python-constants/syntax.js +93 -0
  323. package/dist/tools/python-constants/syntax.js.map +1 -0
  324. package/dist/tools/python-constants/value-resolver.d.ts +6 -0
  325. package/dist/tools/python-constants/value-resolver.d.ts.map +1 -0
  326. package/dist/tools/python-constants/value-resolver.js +320 -0
  327. package/dist/tools/python-constants/value-resolver.js.map +1 -0
  328. package/dist/tools/python-constants-tools.d.ts +3 -45
  329. package/dist/tools/python-constants-tools.d.ts.map +1 -1
  330. package/dist/tools/python-constants-tools.js +2 -505
  331. package/dist/tools/python-constants-tools.js.map +1 -1
  332. package/dist/tools/route-tools/django.d.ts +8 -0
  333. package/dist/tools/route-tools/django.d.ts.map +1 -0
  334. package/dist/tools/route-tools/django.js +52 -0
  335. package/dist/tools/route-tools/django.js.map +1 -0
  336. package/dist/tools/route-tools/express.d.ts +5 -0
  337. package/dist/tools/route-tools/express.d.ts.map +1 -0
  338. package/dist/tools/route-tools/express.js +33 -0
  339. package/dist/tools/route-tools/express.js.map +1 -0
  340. package/dist/tools/route-tools/file-sources.d.ts +7 -0
  341. package/dist/tools/route-tools/file-sources.d.ts.map +1 -0
  342. package/dist/tools/route-tools/file-sources.js +15 -0
  343. package/dist/tools/route-tools/file-sources.js.map +1 -0
  344. package/dist/tools/route-tools/handler-discovery.d.ts +4 -0
  345. package/dist/tools/route-tools/handler-discovery.d.ts.map +1 -0
  346. package/dist/tools/route-tools/handler-discovery.js +38 -0
  347. package/dist/tools/route-tools/handler-discovery.js.map +1 -0
  348. package/dist/tools/route-tools/hono.d.ts +5 -0
  349. package/dist/tools/route-tools/hono.d.ts.map +1 -0
  350. package/dist/tools/route-tools/hono.js +61 -0
  351. package/dist/tools/route-tools/hono.js.map +1 -0
  352. package/dist/tools/route-tools/ktor.d.ts +5 -0
  353. package/dist/tools/route-tools/ktor.d.ts.map +1 -0
  354. package/dist/tools/route-tools/ktor.js +76 -0
  355. package/dist/tools/route-tools/ktor.js.map +1 -0
  356. package/dist/tools/route-tools/laravel.d.ts +5 -0
  357. package/dist/tools/route-tools/laravel.d.ts.map +1 -0
  358. package/dist/tools/route-tools/laravel.js +45 -0
  359. package/dist/tools/route-tools/laravel.js.map +1 -0
  360. package/dist/tools/route-tools/mermaid-call-chain.d.ts +3 -0
  361. package/dist/tools/route-tools/mermaid-call-chain.d.ts.map +1 -0
  362. package/dist/tools/route-tools/mermaid-call-chain.js +50 -0
  363. package/dist/tools/route-tools/mermaid-call-chain.js.map +1 -0
  364. package/dist/tools/route-tools/nest.d.ts +5 -0
  365. package/dist/tools/route-tools/nest.d.ts.map +1 -0
  366. package/dist/tools/route-tools/nest.js +75 -0
  367. package/dist/tools/route-tools/nest.js.map +1 -0
  368. package/dist/tools/route-tools/next-trace.d.ts +4 -0
  369. package/dist/tools/route-tools/next-trace.d.ts.map +1 -0
  370. package/dist/tools/route-tools/next-trace.js +48 -0
  371. package/dist/tools/route-tools/next-trace.js.map +1 -0
  372. package/dist/tools/route-tools/next.d.ts +7 -0
  373. package/dist/tools/route-tools/next.d.ts.map +1 -0
  374. package/dist/tools/route-tools/next.js +77 -0
  375. package/dist/tools/route-tools/next.js.map +1 -0
  376. package/dist/tools/route-tools/python-decorators.d.ts +7 -0
  377. package/dist/tools/route-tools/python-decorators.d.ts.map +1 -0
  378. package/dist/tools/route-tools/python-decorators.js +53 -0
  379. package/dist/tools/route-tools/python-decorators.js.map +1 -0
  380. package/dist/tools/route-tools/route-mermaid.d.ts +4 -0
  381. package/dist/tools/route-tools/route-mermaid.d.ts.map +1 -0
  382. package/dist/tools/route-tools/route-mermaid.js +53 -0
  383. package/dist/tools/route-tools/route-mermaid.js.map +1 -0
  384. package/dist/tools/route-tools/spring-kotlin.d.ts +5 -0
  385. package/dist/tools/route-tools/spring-kotlin.d.ts.map +1 -0
  386. package/dist/tools/route-tools/spring-kotlin.js +52 -0
  387. package/dist/tools/route-tools/spring-kotlin.js.map +1 -0
  388. package/dist/tools/route-tools/trace-analysis.d.ts +4 -0
  389. package/dist/tools/route-tools/trace-analysis.d.ts.map +1 -0
  390. package/dist/tools/route-tools/trace-analysis.js +37 -0
  391. package/dist/tools/route-tools/trace-analysis.js.map +1 -0
  392. package/dist/tools/route-tools/trace-route.d.ts +6 -0
  393. package/dist/tools/route-tools/trace-route.d.ts.map +1 -0
  394. package/dist/tools/route-tools/trace-route.js +53 -0
  395. package/dist/tools/route-tools/trace-route.js.map +1 -0
  396. package/dist/tools/route-tools/types.d.ts +35 -0
  397. package/dist/tools/route-tools/types.d.ts.map +1 -0
  398. package/dist/tools/route-tools/types.js +2 -0
  399. package/dist/tools/route-tools/types.js.map +1 -0
  400. package/dist/tools/route-tools/yii2.d.ts +5 -0
  401. package/dist/tools/route-tools/yii2.d.ts.map +1 -0
  402. package/dist/tools/route-tools/yii2.js +73 -0
  403. package/dist/tools/route-tools/yii2.js.map +1 -0
  404. package/dist/tools/route-tools.d.ts +7 -49
  405. package/dist/tools/route-tools.d.ts.map +1 -1
  406. package/dist/tools/route-tools.js +5 -978
  407. package/dist/tools/route-tools.js.map +1 -1
  408. package/dist/tools/search-tools/types.d.ts +20 -0
  409. package/dist/tools/search-tools/types.d.ts.map +1 -1
  410. package/dist/tools/search-tools/zero-hit.d.ts.map +1 -1
  411. package/dist/tools/search-tools/zero-hit.js +0 -0
  412. package/dist/tools/search-tools/zero-hit.js.map +1 -1
  413. package/dist/tools/status-tools.d.ts +10 -0
  414. package/dist/tools/status-tools.d.ts.map +1 -1
  415. package/dist/tools/status-tools.js +14 -4
  416. package/dist/tools/status-tools.js.map +1 -1
  417. package/dist/tools/symbol-analysis-tools.d.ts +81 -0
  418. package/dist/tools/symbol-analysis-tools.d.ts.map +1 -0
  419. package/dist/tools/symbol-analysis-tools.js +327 -0
  420. package/dist/tools/symbol-analysis-tools.js.map +1 -0
  421. package/dist/tools/symbol-context-tools.d.ts +68 -0
  422. package/dist/tools/symbol-context-tools.d.ts.map +1 -0
  423. package/dist/tools/symbol-context-tools.js +232 -0
  424. package/dist/tools/symbol-context-tools.js.map +1 -0
  425. package/dist/tools/symbol-lookup-tools.d.ts +77 -0
  426. package/dist/tools/symbol-lookup-tools.d.ts.map +1 -0
  427. package/dist/tools/symbol-lookup-tools.js +305 -0
  428. package/dist/tools/symbol-lookup-tools.js.map +1 -0
  429. package/dist/tools/symbol-reference-tools.d.ts +38 -0
  430. package/dist/tools/symbol-reference-tools.d.ts.map +1 -0
  431. package/dist/tools/symbol-reference-tools.js +253 -0
  432. package/dist/tools/symbol-reference-tools.js.map +1 -0
  433. package/dist/tools/symbol-tool-internals.d.ts +9 -0
  434. package/dist/tools/symbol-tool-internals.d.ts.map +1 -0
  435. package/dist/tools/symbol-tool-internals.js +47 -0
  436. package/dist/tools/symbol-tool-internals.js.map +1 -0
  437. package/dist/tools/symbol-tools.d.ts +11 -176
  438. package/dist/tools/symbol-tools.d.ts.map +1 -1
  439. package/dist/tools/symbol-tools.js +7 -975
  440. package/dist/tools/symbol-tools.js.map +1 -1
  441. package/dist/tools/taint/python-context.d.ts +10 -0
  442. package/dist/tools/taint/python-context.d.ts.map +1 -0
  443. package/dist/tools/taint/python-context.js +150 -0
  444. package/dist/tools/taint/python-context.js.map +1 -0
  445. package/dist/tools/taint/taint-analyzer.d.ts +2 -0
  446. package/dist/tools/taint/taint-analyzer.d.ts.map +1 -0
  447. package/dist/tools/taint/taint-analyzer.js +2 -0
  448. package/dist/tools/taint/taint-analyzer.js.map +1 -0
  449. package/dist/tools/taint/taint-expression.d.ts +18 -0
  450. package/dist/tools/taint/taint-expression.d.ts.map +1 -0
  451. package/dist/tools/taint/taint-expression.js +265 -0
  452. package/dist/tools/taint/taint-expression.js.map +1 -0
  453. package/dist/tools/taint/taint-flow.d.ts +10 -0
  454. package/dist/tools/taint/taint-flow.d.ts.map +1 -0
  455. package/dist/tools/taint/taint-flow.js +178 -0
  456. package/dist/tools/taint/taint-flow.js.map +1 -0
  457. package/dist/tools/taint/taint-model.d.ts +113 -0
  458. package/dist/tools/taint/taint-model.d.ts.map +1 -0
  459. package/dist/tools/taint/taint-model.js +277 -0
  460. package/dist/tools/taint/taint-model.js.map +1 -0
  461. package/dist/tools/taint-tools.d.ts +2 -34
  462. package/dist/tools/taint-tools.d.ts.map +1 -1
  463. package/dist/tools/taint-tools.js +2 -852
  464. package/dist/tools/taint-tools.js.map +1 -1
  465. package/dist/tools/typescript-constants/file-context.d.ts +7 -0
  466. package/dist/tools/typescript-constants/file-context.d.ts.map +1 -0
  467. package/dist/tools/typescript-constants/file-context.js +219 -0
  468. package/dist/tools/typescript-constants/file-context.js.map +1 -0
  469. package/dist/tools/typescript-constants/symbol-resolver.d.ts +7 -0
  470. package/dist/tools/typescript-constants/symbol-resolver.d.ts.map +1 -0
  471. package/dist/tools/typescript-constants/symbol-resolver.js +165 -0
  472. package/dist/tools/typescript-constants/symbol-resolver.js.map +1 -0
  473. package/dist/tools/typescript-constants/types.d.ts +44 -0
  474. package/dist/tools/typescript-constants/types.d.ts.map +1 -0
  475. package/dist/tools/typescript-constants/types.js +2 -0
  476. package/dist/tools/typescript-constants/types.js.map +1 -0
  477. package/dist/tools/typescript-constants/value-evaluator.d.ts +8 -0
  478. package/dist/tools/typescript-constants/value-evaluator.d.ts.map +1 -0
  479. package/dist/tools/typescript-constants/value-evaluator.js +404 -0
  480. package/dist/tools/typescript-constants/value-evaluator.js.map +1 -0
  481. package/dist/tools/typescript-constants-tools.d.ts.map +1 -1
  482. package/dist/tools/typescript-constants-tools.js +19 -709
  483. package/dist/tools/typescript-constants-tools.js.map +1 -1
  484. package/dist/types.d.ts +6 -0
  485. package/dist/types.d.ts.map +1 -1
  486. package/dist/utils/git-head.d.ts +12 -0
  487. package/dist/utils/git-head.d.ts.map +1 -1
  488. package/dist/utils/git-head.js +25 -0
  489. package/dist/utils/git-head.js.map +1 -1
  490. package/dist/utils/import-graph/collect.d.ts +5 -0
  491. package/dist/utils/import-graph/collect.d.ts.map +1 -0
  492. package/dist/utils/import-graph/collect.js +47 -0
  493. package/dist/utils/import-graph/collect.js.map +1 -0
  494. package/dist/utils/import-graph/edge-accumulator.d.ts +7 -0
  495. package/dist/utils/import-graph/edge-accumulator.d.ts.map +1 -0
  496. package/dist/utils/import-graph/edge-accumulator.js +47 -0
  497. package/dist/utils/import-graph/edge-accumulator.js.map +1 -0
  498. package/dist/utils/import-graph/language-imports.d.ts +6 -0
  499. package/dist/utils/import-graph/language-imports.d.ts.map +1 -0
  500. package/dist/utils/import-graph/language-imports.js +84 -0
  501. package/dist/utils/import-graph/language-imports.js.map +1 -0
  502. package/dist/utils/import-graph/metrics.d.ts +6 -0
  503. package/dist/utils/import-graph/metrics.d.ts.map +1 -0
  504. package/dist/utils/import-graph/metrics.js +51 -0
  505. package/dist/utils/import-graph/metrics.js.map +1 -0
  506. package/dist/utils/import-graph/path-map.d.ts +7 -0
  507. package/dist/utils/import-graph/path-map.d.ts.map +1 -0
  508. package/dist/utils/import-graph/path-map.js +56 -0
  509. package/dist/utils/import-graph/path-map.js.map +1 -0
  510. package/dist/utils/import-graph/python-php-edge-collectors.d.ts +5 -0
  511. package/dist/utils/import-graph/python-php-edge-collectors.d.ts.map +1 -0
  512. package/dist/utils/import-graph/python-php-edge-collectors.js +56 -0
  513. package/dist/utils/import-graph/python-php-edge-collectors.js.map +1 -0
  514. package/dist/utils/import-graph/source-edge-collector.d.ts +13 -0
  515. package/dist/utils/import-graph/source-edge-collector.d.ts.map +1 -0
  516. package/dist/utils/import-graph/source-edge-collector.js +42 -0
  517. package/dist/utils/import-graph/source-edge-collector.js.map +1 -0
  518. package/dist/utils/import-graph/source-imports.d.ts +5 -0
  519. package/dist/utils/import-graph/source-imports.d.ts.map +1 -0
  520. package/dist/utils/import-graph/source-imports.js +33 -0
  521. package/dist/utils/import-graph/source-imports.js.map +1 -0
  522. package/dist/utils/import-graph/types.d.ts +15 -0
  523. package/dist/utils/import-graph/types.d.ts.map +1 -0
  524. package/dist/utils/import-graph/types.js +2 -0
  525. package/dist/utils/import-graph/types.js.map +1 -0
  526. package/dist/utils/import-graph/typescript-edge-collector.d.ts +7 -0
  527. package/dist/utils/import-graph/typescript-edge-collector.d.ts.map +1 -0
  528. package/dist/utils/import-graph/typescript-edge-collector.js +58 -0
  529. package/dist/utils/import-graph/typescript-edge-collector.js.map +1 -0
  530. package/dist/utils/import-graph/workspace-alias.d.ts +7 -0
  531. package/dist/utils/import-graph/workspace-alias.d.ts.map +1 -0
  532. package/dist/utils/import-graph/workspace-alias.js +95 -0
  533. package/dist/utils/import-graph/workspace-alias.js.map +1 -0
  534. package/dist/utils/import-graph/workspace-entry.d.ts +3 -0
  535. package/dist/utils/import-graph/workspace-entry.d.ts.map +1 -0
  536. package/dist/utils/import-graph/workspace-entry.js +81 -0
  537. package/dist/utils/import-graph/workspace-entry.js.map +1 -0
  538. package/dist/utils/import-graph.d.ts +10 -94
  539. package/dist/utils/import-graph.d.ts.map +1 -1
  540. package/dist/utils/import-graph.js +6 -702
  541. package/dist/utils/import-graph.js.map +1 -1
  542. package/package.json +6 -4
  543. package/rules/codesift.md +11 -2
  544. package/rules/codesift.mdc +11 -2
  545. package/rules/codex.md +11 -2
  546. package/rules/gemini.md +11 -2
@@ -1,7 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
- import { existsSync, mkdirSync, appendFileSync, createReadStream } from "node:fs";
3
- import { createInterface } from "node:readline";
4
- import { homedir } from "node:os";
2
+ import { existsSync, mkdirSync, appendFileSync, statSync } from "node:fs";
3
+ import { open } from "node:fs/promises";
4
+ import { homedir, totalmem } from "node:os";
5
5
  import { join } from "node:path";
6
6
  /**
7
7
  * Embeddings keyed by CONTENT, shared across every repository.
@@ -13,26 +13,147 @@ import { join } from "node:path";
13
13
  * That is not a marginal cost here. A linked worktree is a separate repo to
14
14
  * CodeSift, and its files are usually IDENTICAL to the checkout it came from:
15
15
  * `backlog-wave-1-integration` had 1,799 files and differed from main by zero.
16
- * With 40 worktrees registered, the same text was embedded up to 40 times. Half
17
- * of the 2M symbols still queued for embedding are worktrees or temp dirs.
18
- *
19
- * Auto-indexing no longer creates those entries, but an EXPLICIT
20
- * `index_folder(path=<worktree>)` still should work — the H19 hint tells agents
21
- * to do exactly that when they are working in one. This makes that cheap
22
- * instead of forbidden: the second repo containing a given symbol pays a hash
23
- * lookup, not a model call.
24
- *
25
- * Format: ndjson, append-only, one `{k, v}` per line. Append-only because
26
- * concurrent writers are the norm (one process per agent window) and appending
27
- * a line is the only operation that is safe without a lock. Duplicate keys are
28
- * harmless — the last one read wins, and they carry the same value by
29
- * construction.
16
+ * With 40 worktrees registered, the same text was embedded up to 40 times.
17
+ *
18
+ * ---------------------------------------------------------------------------
19
+ * v2: fixed-width binary records. Why the format changed (measured 2026-08-09)
20
+ * ---------------------------------------------------------------------------
21
+ *
22
+ * v1 was ndjson, and it had three defects that together made it a wasted
23
+ * optimization — it held **4.56%** of the symbol corpus (36,420 of 798,638
24
+ * vectors) and had not grown since 2026-08-07 despite 35 live processes:
25
+ *
26
+ * 1. `appendSharedCache` accumulated the whole batch into ONE string
27
+ * (`payload += …`). At ~16,248 bytes per vector line that hits V8's hard
28
+ * `MAX_STRING_LENGTH` (536,870,888) at exactly **33,042 entries**, throwing
29
+ * `RangeError: Invalid string length` straight into a bare `catch {}`.
30
+ * 7 of 37 symbol files exceed that ceiling and they hold **64%** of the
31
+ * corpus, so the repos that would benefit most were the only ones that
32
+ * silently wrote nothing.
33
+ * 2. Every key was appended whether or not the file already had it: **11.3%**
34
+ * of lines were repeats.
35
+ * 3. Text encoding. A 768-dim float32 vector is 3,072 bytes; as JSON decimals
36
+ * it took 16,248. A float32 round-trip of the stored values is bit-exact on
37
+ * 1,300 sampled vectors, so this was pure waste, not precision.
38
+ *
39
+ * Fixing only (1) would have been worse than leaving it broken: the corpus at
40
+ * v1's density projects to **12.1 GB**, against **2.28 GB** at fixed-width
41
+ * float32. The V8 ceiling had been acting as an accidental circuit breaker.
42
+ *
43
+ * v2 record layout, little-endian throughout:
44
+ *
45
+ * [16 B key][2 B dim][4 B crc32 of the vector bytes][dim*4 B float32 vector]
46
+ *
47
+ * The checksum is not ceremony. Corruption injection against the first draft of this reader
48
+ * (2026-08-09) measured what a record without one costs: two flipped bytes inside a vector were
49
+ * served as a valid embedding — 1000 of 1000 records "read successfully", one of them silently
50
+ * wrong — and 99.417% of a 3,090-byte record was payload that nothing verified. A wrong vector is
51
+ * worse than a missing one: it produces a plausible similarity score instead of a cache miss.
52
+ *
53
+ * It also buys RESYNC. That same pass showed one implausible dim byte at record 10 cost 99% of the
54
+ * file, because the reader stopped rather than guess. With a checksum the reader can skip exactly
55
+ * one record and carry on, and be right about having skipped it.
56
+ *
57
+ * The key is `contentKey`'s 32 hex chars as raw bytes. `dim` is per record
58
+ * rather than in a header because two models with different dimensions can
59
+ * legitimately share this file; a header would force one file per model and a
60
+ * mismatch would be indistinguishable from corruption.
61
+ *
62
+ * Append-only is retained deliberately: concurrent writers are the norm (one
63
+ * process per agent window) and a single `appendFileSync` under `O_APPEND` is
64
+ * the only write that is safe without a lock. Writes are now CHUNKED to a fixed
65
+ * byte budget, on record boundaries, so no buffer approaches any engine limit
66
+ * and a partially-written chunk can never split a record.
67
+ *
68
+ * The file remains DERIVED and safe to delete at any time. That is what makes
69
+ * changing its format cheap: worst case the next index recomputes. There is no
70
+ * v1 migration for the same reason — the old file is simply ignored, and
71
+ * whoever wants the disk back deletes it.
72
+ */
73
+ /** Bump when the record layout changes in a way that invalidates old entries. */
74
+ const CACHE_VERSION = 2;
75
+ /** Bytes of key stored per record — `contentKey` is 32 hex chars = 16 bytes. */
76
+ const KEY_BYTES = 16;
77
+ /** key + dim + crc, before the vector payload. */
78
+ const HEADER_BYTES = KEY_BYTES + 2 + 4;
79
+ /**
80
+ * CRC-32 of the vector bytes.
81
+ *
82
+ * Not cryptographic and not meant to be: the threat is a torn write or a flipped bit, not an
83
+ * adversary. 4 bytes on a 3,090-byte record is 0.13% for the difference between "this vector is
84
+ * wrong" and "this vector is wrong and nobody can tell".
85
+ */
86
+ const CRC_TABLE = (() => {
87
+ const t = new Uint32Array(256);
88
+ for (let i = 0; i < 256; i++) {
89
+ let c = i;
90
+ for (let k = 0; k < 8; k++)
91
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
92
+ t[i] = c >>> 0;
93
+ }
94
+ return t;
95
+ })();
96
+ function crc32(buf, start, end) {
97
+ let c = 0xffffffff;
98
+ for (let i = start; i < end; i++)
99
+ c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
100
+ return (c ^ 0xffffffff) >>> 0;
101
+ }
102
+ /**
103
+ * Largest single `appendFileSync` payload.
104
+ *
105
+ * Bounded so no buffer can approach an engine limit as the corpus grows — the
106
+ * v1 bug was exactly an unbounded accumulator. 8 MiB is ~2,700 vectors at 768
107
+ * dims: few enough syscalls to be irrelevant, small enough that the ceiling is
108
+ * three orders of magnitude away.
109
+ */
110
+ const MAX_APPEND_BYTES = 8 * 1024 * 1024;
111
+ /** Sanity bound on a decoded dimension, so a corrupt byte cannot request a huge allocation. */
112
+ const MAX_DIM = 8192;
113
+ /**
114
+ * Ceiling on how much of the cache is held resident, in bytes of vector payload.
115
+ *
116
+ * This bound is not optional decoration. Until the writer was fixed, appends threw
117
+ * `RangeError` above ~33k entries into a bare catch, so the file was accidentally frozen at 4.56%
118
+ * of the corpus and nobody had to think about the read side. Fixing the writer — and adding chunk
119
+ * texts to the same cache — let it grow for real, and `loadSharedCache` materialises EVERY record
120
+ * into a `Map` that no budget governs: measured +1.17 GB RSS and a multi-second event-loop freeze
121
+ * in a long-lived MCP server, on a machine that routinely runs 24–37 codesift processes at once.
122
+ *
123
+ * Stopping early is the correct degradation for this structure. The cache is a write-side
124
+ * optimization whose only failure mode is a cache MISS, so a partially loaded one is still
125
+ * completely correct — it just recomputes more. That is the same contract as an unreadable file.
126
+ *
127
+ * Default is deliberately modest and scales with the machine, matching the embedding/index budgets
128
+ * (`CODESIFT_MAX_EMBEDDING_MEM_MB`, `CODESIFT_MAX_INDEX_CACHE_MB`). Override with
129
+ * `CODESIFT_MAX_SHARED_CACHE_MB`; `0` disables the shared cache read entirely.
30
130
  */
31
- /** Bump when the vector layout changes in a way that invalidates old entries. */
32
- const CACHE_VERSION = 1;
131
+ function sharedCacheBudgetBytes() {
132
+ const raw = process.env["CODESIFT_MAX_SHARED_CACHE_MB"];
133
+ if (raw !== undefined) {
134
+ const n = Number.parseInt(raw, 10);
135
+ if (Number.isFinite(n) && n >= 0)
136
+ return n * 1024 * 1024;
137
+ }
138
+ const totalGb = totalmem() / 1024 ** 3;
139
+ const mb = totalGb <= 16 ? 64 : totalGb <= 32 ? 128 : 256;
140
+ return mb * 1024 * 1024;
141
+ }
142
+ /**
143
+ * Basename of the cache file this build reads and writes.
144
+ *
145
+ * Exported so `prune` can reclaim SUPERSEDED versions without hard-coding a name
146
+ * that would drift on the next format bump: it deletes every `shared-embeddings.*`
147
+ * that is not this one. A format bump otherwise strands the old file forever —
148
+ * nothing opens it and nothing deletes it, because it has no hash prefix for the
149
+ * artifact sweep to match (1.05 GB measured after the v1→v2 bump).
150
+ */
151
+ export function currentSharedCacheFilename() {
152
+ return `shared-embeddings.v${CACHE_VERSION}.bin`;
153
+ }
33
154
  function cachePath() {
34
155
  const dataDir = process.env["CODESIFT_DATA_DIR"] ?? join(homedir(), ".codesift");
35
- return join(dataDir, `shared-embeddings.v${CACHE_VERSION}.ndjson`);
156
+ return join(dataDir, currentSharedCacheFilename());
36
157
  }
37
158
  /**
38
159
  * Key for a piece of text under a specific model.
@@ -51,46 +172,147 @@ export function contentKey(model, dimensions, text) {
51
172
  }
52
173
  let memory = null;
53
174
  let loadedFrom = null;
175
+ let warnedWriteFailure = false;
54
176
  /**
55
177
  * Read the cache into memory once per process.
56
178
  *
57
- * Missing file, unreadable line, malformed JSON: all skipped. A cache that
58
- * cannot be read must degrade into "compute it again", never into an error —
59
- * it is an optimization, and a broken one has to stay invisible.
179
+ * Missing file, truncated tail, impossible dimension: all skipped. A cache that
180
+ * cannot be read must degrade into "compute it again", never into an error — it
181
+ * is an optimization, and a broken one has to stay invisible.
182
+ *
183
+ * A torn final record is the expected failure, not an exotic one: a writer
184
+ * killed mid-append leaves one. Reading stops at the first record that does not
185
+ * fit in the remaining bytes and keeps everything before it.
60
186
  */
61
187
  export async function loadSharedCache() {
62
188
  const path = cachePath();
63
189
  if (memory && loadedFrom === path)
64
190
  return memory;
65
191
  const map = new Map();
66
- if (existsSync(path)) {
192
+ const budget = sharedCacheBudgetBytes();
193
+ if (budget > 0 && existsSync(path)) {
194
+ let handle;
195
+ let corrupt = 0;
196
+ let skippedTail = false;
197
+ let resident = 0;
198
+ let stoppedAtBudget = false;
67
199
  try {
68
- const rl = createInterface({ input: createReadStream(path, { encoding: "utf-8" }), crlfDelay: Infinity });
69
- for await (const line of rl) {
70
- if (!line)
71
- continue;
72
- try {
73
- const entry = JSON.parse(line);
74
- if (typeof entry.k === "string" && Array.isArray(entry.v)) {
75
- map.set(entry.k, new Float32Array(entry.v));
200
+ const size = statSync(path).size;
201
+ // Async open/read: this runs inside the long-lived MCP server, where the
202
+ // synchronous version blocked the event loop for seconds on a file that is
203
+ // now hundreds of megabytes. Nothing here needs to be synchronous — the
204
+ // function has always been async, it just was not using it.
205
+ handle = await open(path, "r");
206
+ // Read in slabs rather than one buffer: the file is expected to outgrow
207
+ // any single comfortable allocation, which is how v1 died.
208
+ const SLAB = 4 * 1024 * 1024;
209
+ let carry = Buffer.alloc(0);
210
+ let offset = 0;
211
+ while (offset < size) {
212
+ const want = Math.min(SLAB, size - offset);
213
+ const buf = Buffer.allocUnsafe(want);
214
+ const { bytesRead: got } = await handle.read(buf, 0, want, offset);
215
+ if (got <= 0)
216
+ break;
217
+ offset += got;
218
+ const data = carry.length > 0 ? Buffer.concat([carry, buf.subarray(0, got)]) : buf.subarray(0, got);
219
+ let p = 0;
220
+ for (;;) {
221
+ if (p + HEADER_BYTES > data.length)
222
+ break;
223
+ const dim = data.readUInt16LE(p + KEY_BYTES);
224
+ if (dim === 0 || dim > MAX_DIM) {
225
+ // Cannot know where the next record starts, so this is where reading ends. Say how much
226
+ // was kept: the first draft did this silently, and one bad byte at record 10 cost 99%
227
+ // of the file with no way to notice.
228
+ skippedTail = true;
229
+ p = data.length;
230
+ offset = size;
231
+ break;
76
232
  }
233
+ const total = HEADER_BYTES + dim * 4;
234
+ if (p + total > data.length)
235
+ break; // record spans the slab boundary
236
+ const want = data.readUInt32LE(p + KEY_BYTES + 2);
237
+ if (crc32(data, p + HEADER_BYTES, p + total) !== want) {
238
+ // The length is intact, so the NEXT record's offset is still known: skip exactly this
239
+ // one and keep going. Without the checksum this record would have been served as a
240
+ // valid vector — a wrong embedding produces a plausible score, not a cache miss.
241
+ corrupt++;
242
+ p += total;
243
+ continue;
244
+ }
245
+ if (resident + dim * 4 > budget) {
246
+ // Stop, do not evict. Entries are equally valuable here — there is no recency to
247
+ // exploit, since a key is looked up once per corpus pass — so the cheapest correct
248
+ // policy is to keep the prefix already paid for and let the rest be recomputed.
249
+ stoppedAtBudget = true;
250
+ offset = size;
251
+ break;
252
+ }
253
+ const key = data.subarray(p, p + KEY_BYTES).toString("hex");
254
+ const vec = new Float32Array(dim);
255
+ for (let i = 0; i < dim; i++)
256
+ vec[i] = data.readFloatLE(p + HEADER_BYTES + i * 4);
257
+ map.set(key, vec);
258
+ resident += dim * 4;
259
+ p += total;
77
260
  }
78
- catch {
79
- // Skip a malformed line rather than abandoning the whole cache.
80
- }
261
+ carry = p < data.length ? Buffer.from(data.subarray(p)) : Buffer.alloc(0);
262
+ if (carry.length > 0)
263
+ skippedTail = true;
81
264
  }
82
265
  }
83
266
  catch {
84
- // Unreadable file — behave as if empty.
267
+ // Unreadable — behave as if empty.
268
+ }
269
+ finally {
270
+ if (corrupt > 0 || skippedTail) {
271
+ console.error(`[codesift] shared embedding cache: kept ${map.size} vectors, dropped ${corrupt} failing ` +
272
+ `checksum${skippedTail ? " and stopped early at an unreadable record" : ""}. ` +
273
+ `It is derived — delete ${path} to rebuild.`);
274
+ }
275
+ if (stoppedAtBudget) {
276
+ console.error(`[codesift] shared embedding cache: loaded ${map.size} vectors ` +
277
+ `(${(resident / 1024 ** 2).toFixed(0)} MB), stopping at the ` +
278
+ `${(budget / 1024 ** 2).toFixed(0)} MB budget. The rest will be recomputed rather than ` +
279
+ `looked up. Raise CODESIFT_MAX_SHARED_CACHE_MB to trade memory for fewer model calls.`);
280
+ }
281
+ if (handle !== undefined) {
282
+ try {
283
+ await handle.close();
284
+ }
285
+ catch {
286
+ /* already gone */
287
+ }
288
+ }
85
289
  }
86
290
  }
87
291
  memory = map;
88
292
  loadedFrom = path;
89
293
  return map;
90
294
  }
295
+ function encodeRecord(key, vec) {
296
+ if (key.length !== KEY_BYTES * 2 || !/^[0-9a-f]+$/.test(key) ||
297
+ vec.length === 0 || vec.length > MAX_DIM)
298
+ return null;
299
+ const rec = Buffer.allocUnsafe(HEADER_BYTES + vec.length * 4);
300
+ rec.write(key, 0, KEY_BYTES, "hex");
301
+ rec.writeUInt16LE(vec.length, KEY_BYTES);
302
+ for (let i = 0; i < vec.length; i++)
303
+ rec.writeFloatLE(vec[i], HEADER_BYTES + i * 4);
304
+ rec.writeUInt32LE(crc32(rec, HEADER_BYTES, rec.length), KEY_BYTES + 2);
305
+ return rec;
306
+ }
91
307
  /**
92
308
  * Append new vectors. Both the file and the in-memory map are updated, so a
93
309
  * second repo indexed in the same process hits memory rather than disk.
310
+ *
311
+ * Entries already present are skipped: v1 appended unconditionally and 11.3% of
312
+ * its lines were repeats of a key it already held. Dedup happens against the
313
+ * in-memory map, so it is exact within a process and best-effort across them —
314
+ * which is the same guarantee append-only gave before, at a fraction of the
315
+ * bytes.
94
316
  */
95
317
  export function appendSharedCache(entries) {
96
318
  if (entries.length === 0)
@@ -98,23 +320,56 @@ export function appendSharedCache(entries) {
98
320
  const path = cachePath();
99
321
  try {
100
322
  mkdirSync(join(path, ".."), { recursive: true });
101
- let payload = "";
323
+ let batch = [];
324
+ let batchEntries = [];
325
+ const pendingKeys = new Set();
326
+ let batchBytes = 0;
327
+ const flush = () => {
328
+ if (batch.length === 0)
329
+ return;
330
+ // One append per chunk, always ending on a record boundary, so a
331
+ // concurrent writer can interleave BETWEEN records but never inside one.
332
+ appendFileSync(path, Buffer.concat(batch));
333
+ if (memory) {
334
+ for (const { key, vec } of batchEntries)
335
+ memory.set(key, vec);
336
+ }
337
+ batch = [];
338
+ batchEntries = [];
339
+ pendingKeys.clear();
340
+ batchBytes = 0;
341
+ };
102
342
  for (const { key, vec } of entries) {
103
- if (memory && !memory.has(key))
104
- memory.set(key, vec);
105
- payload += JSON.stringify({ k: key, v: Array.from(vec) }) + "\n";
343
+ const normalizedKey = key.toLowerCase();
344
+ if (memory?.has(normalizedKey) || pendingKeys.has(normalizedKey))
345
+ continue;
346
+ const rec = encodeRecord(normalizedKey, vec);
347
+ if (!rec)
348
+ continue;
349
+ if (batchBytes + rec.length > MAX_APPEND_BYTES)
350
+ flush();
351
+ batch.push(rec);
352
+ batchEntries.push({ key: normalizedKey, vec });
353
+ pendingKeys.add(normalizedKey);
354
+ batchBytes += rec.length;
106
355
  }
107
- // One append for the batch: fewer syscalls, and a single write is far less
108
- // likely to interleave with another process mid-line than many small ones.
109
- appendFileSync(path, payload, "utf-8");
356
+ flush();
110
357
  }
111
- catch {
112
- // A cache that cannot be written must not fail the indexing run.
358
+ catch (err) {
359
+ // A cache that cannot be written must not fail the indexing run — but v1's
360
+ // silence is how a total write failure went unnoticed for days while the
361
+ // cache held 4.56% of the corpus. Say it once per process.
362
+ if (!warnedWriteFailure) {
363
+ warnedWriteFailure = true;
364
+ console.error(`[codesift] shared embedding cache is not being written (${err.message}). ` +
365
+ `Indexing continues; embeddings will be recomputed per repo.`);
366
+ }
113
367
  }
114
368
  }
115
369
  /** Test-only: forget the in-memory copy so a fresh path is picked up. */
116
370
  export function _resetSharedCacheForTests() {
117
371
  memory = null;
118
372
  loadedFrom = null;
373
+ warnedWriteFailure = false;
119
374
  }
120
375
  //# sourceMappingURL=shared-embedding-cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-embedding-cache.js","sourceRoot":"","sources":["../../src/storage/shared-embedding-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared-embedding-cache.js","sourceRoot":"","sources":["../../src/storage/shared-embedding-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { CodeSymbol, FileEntry } from "../../types.js";
2
+ import { type IndexSummary } from "./meta.js";
3
+ /**
4
+ * One file's `mtime_ms`, without materialising the index.
5
+ *
6
+ * `file-indexer.ts` used to parse the whole blob for exactly this value and then
7
+ * `saveIncremental` parsed it a second time — two full parses of 262 MB to decide whether a
8
+ * 40-line file had changed.
9
+ */
10
+ export declare function getFileMtimeSqlite(dbPath: string, filePath: string): Promise<number | undefined>;
11
+ /**
12
+ * Read an index without constructing its symbols.
13
+ *
14
+ * Measured on the real tgm-survey-platform index (240,137 symbols): a full load costs ~1.0 s and
15
+ * 349 MB of resident heap, essentially all of it building symbol objects. Tools that never touch
16
+ * `index.symbols` — `index_status` is the clearest, it reports counts it reads from metadata — paid
17
+ * that in full for nothing.
18
+ */
19
+ export declare function loadIndexSummarySqlite(dbPath: string): Promise<IndexSummary | null>;
20
+ /** One file's `files[]` entry, without materialising the index. */
21
+ export declare function getFileEntrySqlite(dbPath: string, filePath: string): Promise<FileEntry | undefined>;
22
+ /** Replace one file's symbols (and optionally its files[] entry) in a single transaction. */
23
+ export declare function saveIncrementalSqlite(dbPath: string, updatedFile: string, newSymbols: CodeSymbol[], fileEntry?: FileEntry): Promise<void>;
24
+ /** Drop a deleted file's symbols and its files[] entry. */
25
+ export declare function removeFileFromIndexSqlite(dbPath: string, deletedFile: string): Promise<void>;
26
+ /** All symbols for one file — lets per-file tools skip the whole-index load. */
27
+ export declare function getSymbolsForFileSqlite(dbPath: string, filePath: string): Promise<CodeSymbol[]>;
28
+ /**
29
+ * Cross-process change counter. SQLite bumps `data_version` when *another* connection
30
+ * commits, which is the invalidation signal a plain JSON file never had — and the reason an
31
+ * in-memory index cache becomes safe here despite the hook writing from its own process.
32
+ */
33
+ export declare function getDataVersion(dbPath: string): Promise<number>;
34
+ //# sourceMappingURL=accessors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessors.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/accessors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAS5D,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAqC9D;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ7B;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAwDzF;AAED,mEAAmE;AACnE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAQhC;AAED,6FAA6F;AAC7F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EAAE,EACxB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,2DAA2D;AAC3D,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CAUvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpE"}
@@ -0,0 +1,178 @@
1
+ import { openIndexDb, openReadConnection, readMetaValue, rollbackQuietly, writeMetaValue, } from "./connection.js";
2
+ import { rethrowOperational } from "./errors.js";
3
+ import { readMetaExtras } from "./meta.js";
4
+ import { INSERT_FILE_SQL, INSERT_SYMBOL_SQL, fileEntryToRow, rowToFileEntry, rowToSymbol, symbolToRow, } from "./rows.js";
5
+ /**
6
+ * Narrow accessors — the reason this backend exists.
7
+ *
8
+ * Every function here answers a question WITHOUT materialising the index. Under the JSON backend
9
+ * each of these cost a full parse of the whole repo's symbols; that is the cost ADR-003 set out to
10
+ * remove and ADR-004 stage 2 is still working through call site by call site.
11
+ */
12
+ /**
13
+ * Run a read against an already-open index, classifying any storage fault it surfaces.
14
+ *
15
+ * `openIndexDb` classifies what fails at open time, but corruption and I/O faults frequently only
16
+ * surface on the first page actually touched — and these accessors are the fast paths precisely
17
+ * because they touch one row late rather than the whole table early. Without this, a caller using
18
+ * `isIndexStorageError` (rather than `classifyStorageError`) does not recognise the fault, and the
19
+ * read falls into the "unexpected error" branch that reports an unindexed repo.
20
+ */
21
+ function classifyingRead(dbPath, read) {
22
+ try {
23
+ return read();
24
+ }
25
+ catch (err) {
26
+ rethrowOperational(err, dbPath);
27
+ }
28
+ }
29
+ /**
30
+ * One file's `mtime_ms`, without materialising the index.
31
+ *
32
+ * `file-indexer.ts` used to parse the whole blob for exactly this value and then
33
+ * `saveIncremental` parsed it a second time — two full parses of 262 MB to decide whether a
34
+ * 40-line file had changed.
35
+ */
36
+ export async function getFileMtimeSqlite(dbPath, filePath) {
37
+ const db = await openIndexDb(dbPath);
38
+ return classifyingRead(dbPath, () => {
39
+ const row = db.prepare("SELECT mtime_ms FROM files WHERE path = ?").get(filePath);
40
+ return row?.mtime_ms ?? undefined;
41
+ });
42
+ }
43
+ /**
44
+ * Read an index without constructing its symbols.
45
+ *
46
+ * Measured on the real tgm-survey-platform index (240,137 symbols): a full load costs ~1.0 s and
47
+ * 349 MB of resident heap, essentially all of it building symbol objects. Tools that never touch
48
+ * `index.symbols` — `index_status` is the clearest, it reports counts it reads from metadata — paid
49
+ * that in full for nothing.
50
+ */
51
+ export async function loadIndexSummarySqlite(dbPath) {
52
+ await openIndexDb(dbPath);
53
+ let reader;
54
+ let out = null;
55
+ try {
56
+ // Same one-transaction rule as `loadIndexSqlite`: files and meta must describe one instant,
57
+ // or the summary reports a file list from one revision with counts from another.
58
+ // Bound to a `const` as well as to `reader`: the closure below outlives the narrowing of the
59
+ // `let`, so reading it through `reader` needed an `as` cast that asserted away an `undefined`
60
+ // the compiler was right to track. The local carries the non-optional type honestly.
61
+ const snapshot = await openReadConnection(dbPath);
62
+ reader = snapshot;
63
+ snapshot.exec("BEGIN");
64
+ try {
65
+ const meta = (key) => readMetaValue(snapshot, key);
66
+ const repo = meta("repo");
67
+ const root = meta("root");
68
+ if (repo === undefined || root === undefined) {
69
+ snapshot.exec("COMMIT");
70
+ return null; // genuinely empty — not a fault
71
+ }
72
+ // ORDER BY rowid, matching `readTablePaged`'s keyset walk. Without it the two SQLite read
73
+ // paths could hand back the same files in different orders, so a caller comparing a summary
74
+ // against a full load would see a difference that is not in the data.
75
+ const files = snapshot.prepare("SELECT * FROM files ORDER BY rowid").all().map(rowToFileEntry);
76
+ const counted = snapshot.prepare("SELECT COUNT(*) AS n FROM symbols").get();
77
+ const summary = {
78
+ repo,
79
+ root,
80
+ files,
81
+ created_at: Number(meta("created_at") ?? 0),
82
+ updated_at: Number(meta("updated_at") ?? 0),
83
+ symbol_count: Number(counted?.n ?? 0),
84
+ file_count: files.length,
85
+ };
86
+ Object.assign(summary, readMetaExtras(meta));
87
+ snapshot.exec("COMMIT");
88
+ out = summary;
89
+ }
90
+ catch (err) {
91
+ rollbackQuietly(snapshot);
92
+ throw err;
93
+ }
94
+ }
95
+ catch (err) {
96
+ rethrowOperational(err, dbPath);
97
+ }
98
+ finally {
99
+ try {
100
+ reader?.close();
101
+ }
102
+ catch { /* best-effort */ }
103
+ }
104
+ return out;
105
+ }
106
+ /** One file's `files[]` entry, without materialising the index. */
107
+ export async function getFileEntrySqlite(dbPath, filePath) {
108
+ const db = await openIndexDb(dbPath);
109
+ return classifyingRead(dbPath, () => {
110
+ const row = db.prepare("SELECT * FROM files WHERE path = ?").get(filePath);
111
+ return row ? rowToFileEntry(row) : undefined;
112
+ });
113
+ }
114
+ /** Replace one file's symbols (and optionally its files[] entry) in a single transaction. */
115
+ export async function saveIncrementalSqlite(dbPath, updatedFile, newSymbols, fileEntry) {
116
+ const db = await openIndexDb(dbPath);
117
+ if (readMetaValue(db, "repo") === undefined) {
118
+ throw new Error(`Cannot incrementally update: index not found at ${dbPath}`);
119
+ }
120
+ db.exec("BEGIN");
121
+ try {
122
+ db.prepare("DELETE FROM symbols WHERE file = ?").run(updatedFile);
123
+ const insSym = db.prepare(INSERT_SYMBOL_SQL);
124
+ for (const sym of newSymbols)
125
+ insSym.run(...symbolToRow(sym));
126
+ if (fileEntry)
127
+ db.prepare(INSERT_FILE_SQL).run(...fileEntryToRow(fileEntry));
128
+ writeMetaValue(db, "updated_at", String(Date.now()));
129
+ db.exec("COMMIT");
130
+ }
131
+ catch (err) {
132
+ rollbackQuietly(db);
133
+ rethrowOperational(err, dbPath);
134
+ }
135
+ }
136
+ /** Drop a deleted file's symbols and its files[] entry. */
137
+ export async function removeFileFromIndexSqlite(dbPath, deletedFile) {
138
+ const db = await openIndexDb(dbPath);
139
+ if (readMetaValue(db, "repo") === undefined)
140
+ return; // nothing to remove
141
+ db.exec("BEGIN");
142
+ try {
143
+ db.prepare("DELETE FROM symbols WHERE file = ?").run(deletedFile);
144
+ db.prepare("DELETE FROM files WHERE path = ?").run(deletedFile);
145
+ writeMetaValue(db, "updated_at", String(Date.now()));
146
+ db.exec("COMMIT");
147
+ }
148
+ catch (err) {
149
+ rollbackQuietly(db);
150
+ rethrowOperational(err, dbPath);
151
+ }
152
+ }
153
+ /** All symbols for one file — lets per-file tools skip the whole-index load. */
154
+ export async function getSymbolsForFileSqlite(dbPath, filePath) {
155
+ const db = await openIndexDb(dbPath);
156
+ return classifyingRead(dbPath, () => {
157
+ const repo = readMetaValue(db, "repo");
158
+ if (repo === undefined)
159
+ return [];
160
+ const rows = db
161
+ .prepare("SELECT * FROM symbols WHERE file = ?")
162
+ .all(filePath);
163
+ return rows.map((row) => rowToSymbol(row, repo));
164
+ });
165
+ }
166
+ /**
167
+ * Cross-process change counter. SQLite bumps `data_version` when *another* connection
168
+ * commits, which is the invalidation signal a plain JSON file never had — and the reason an
169
+ * in-memory index cache becomes safe here despite the hook writing from its own process.
170
+ */
171
+ export async function getDataVersion(dbPath) {
172
+ const db = await openIndexDb(dbPath);
173
+ return classifyingRead(dbPath, () => {
174
+ const row = db.prepare("PRAGMA data_version").get();
175
+ return row.data_version;
176
+ });
177
+ }
178
+ //# sourceMappingURL=accessors.js.map