kirograph 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/README.md +1171 -0
  2. package/dist/architecture/index.d.ts +11 -0
  3. package/dist/architecture/index.d.ts.map +1 -0
  4. package/dist/architecture/index.js +207 -0
  5. package/dist/architecture/index.js.map +7 -0
  6. package/dist/architecture/layers/csharp.d.ts +6 -0
  7. package/dist/architecture/layers/csharp.d.ts.map +1 -0
  8. package/dist/architecture/layers/csharp.js +100 -0
  9. package/dist/architecture/layers/csharp.js.map +7 -0
  10. package/dist/architecture/layers/elixir.js +116 -0
  11. package/dist/architecture/layers/elixir.js.map +7 -0
  12. package/dist/architecture/layers/go.d.ts +7 -0
  13. package/dist/architecture/layers/go.d.ts.map +1 -0
  14. package/dist/architecture/layers/go.js +117 -0
  15. package/dist/architecture/layers/go.js.map +7 -0
  16. package/dist/architecture/layers/index.d.ts +30 -0
  17. package/dist/architecture/layers/index.d.ts.map +1 -0
  18. package/dist/architecture/layers/index.js +100 -0
  19. package/dist/architecture/layers/index.js.map +7 -0
  20. package/dist/architecture/layers/java.d.ts +7 -0
  21. package/dist/architecture/layers/java.d.ts.map +1 -0
  22. package/dist/architecture/layers/java.js +119 -0
  23. package/dist/architecture/layers/java.js.map +7 -0
  24. package/dist/architecture/layers/python.d.ts +7 -0
  25. package/dist/architecture/layers/python.d.ts.map +1 -0
  26. package/dist/architecture/layers/python.js +111 -0
  27. package/dist/architecture/layers/python.js.map +7 -0
  28. package/dist/architecture/layers/ruby.d.ts +6 -0
  29. package/dist/architecture/layers/ruby.d.ts.map +1 -0
  30. package/dist/architecture/layers/ruby.js +95 -0
  31. package/dist/architecture/layers/ruby.js.map +7 -0
  32. package/dist/architecture/layers/rust.d.ts +6 -0
  33. package/dist/architecture/layers/rust.d.ts.map +1 -0
  34. package/dist/architecture/layers/rust.js +98 -0
  35. package/dist/architecture/layers/rust.js.map +7 -0
  36. package/dist/architecture/layers/types.d.ts +2 -0
  37. package/dist/architecture/layers/types.d.ts.map +1 -0
  38. package/dist/architecture/layers/types.js +17 -0
  39. package/dist/architecture/layers/types.js.map +7 -0
  40. package/dist/architecture/layers/typescript.d.ts +9 -0
  41. package/dist/architecture/layers/typescript.d.ts.map +1 -0
  42. package/dist/architecture/layers/typescript.js +143 -0
  43. package/dist/architecture/layers/typescript.js.map +7 -0
  44. package/dist/architecture/manifest/cargo.d.ts +3 -0
  45. package/dist/architecture/manifest/cargo.d.ts.map +1 -0
  46. package/dist/architecture/manifest/cargo.js +94 -0
  47. package/dist/architecture/manifest/cargo.js.map +7 -0
  48. package/dist/architecture/manifest/csproj.d.ts +3 -0
  49. package/dist/architecture/manifest/csproj.d.ts.map +1 -0
  50. package/dist/architecture/manifest/csproj.js +75 -0
  51. package/dist/architecture/manifest/csproj.js.map +7 -0
  52. package/dist/architecture/manifest/go.d.ts +3 -0
  53. package/dist/architecture/manifest/go.d.ts.map +1 -0
  54. package/dist/architecture/manifest/go.js +85 -0
  55. package/dist/architecture/manifest/go.js.map +7 -0
  56. package/dist/architecture/manifest/gradle.d.ts +3 -0
  57. package/dist/architecture/manifest/gradle.d.ts.map +1 -0
  58. package/dist/architecture/manifest/gradle.js +80 -0
  59. package/dist/architecture/manifest/gradle.js.map +7 -0
  60. package/dist/architecture/manifest/index.d.ts +12 -0
  61. package/dist/architecture/manifest/index.d.ts.map +1 -0
  62. package/dist/architecture/manifest/index.js +130 -0
  63. package/dist/architecture/manifest/index.js.map +7 -0
  64. package/dist/architecture/manifest/maven.d.ts +3 -0
  65. package/dist/architecture/manifest/maven.d.ts.map +1 -0
  66. package/dist/architecture/manifest/maven.js +76 -0
  67. package/dist/architecture/manifest/maven.js.map +7 -0
  68. package/dist/architecture/manifest/npm.d.ts +3 -0
  69. package/dist/architecture/manifest/npm.d.ts.map +1 -0
  70. package/dist/architecture/manifest/npm.js +103 -0
  71. package/dist/architecture/manifest/npm.js.map +7 -0
  72. package/dist/architecture/manifest/python.d.ts +3 -0
  73. package/dist/architecture/manifest/python.d.ts.map +1 -0
  74. package/dist/architecture/manifest/python.js +105 -0
  75. package/dist/architecture/manifest/python.js.map +7 -0
  76. package/dist/architecture/manifest/types.d.ts +2 -0
  77. package/dist/architecture/manifest/types.d.ts.map +1 -0
  78. package/dist/architecture/manifest/types.js +17 -0
  79. package/dist/architecture/manifest/types.js.map +7 -0
  80. package/dist/architecture/types.d.ts +91 -0
  81. package/dist/architecture/types.d.ts.map +1 -0
  82. package/dist/architecture/types.js +17 -0
  83. package/dist/architecture/types.js.map +7 -0
  84. package/dist/assets/logo.png +0 -0
  85. package/dist/banner.d.ts +6 -0
  86. package/dist/banner.d.ts.map +1 -0
  87. package/dist/banner.js +67 -0
  88. package/dist/banner.js.map +1 -0
  89. package/dist/bin/banner.d.ts +6 -0
  90. package/dist/bin/banner.d.ts.map +1 -0
  91. package/dist/bin/banner.js +88 -0
  92. package/dist/bin/banner.js.map +7 -0
  93. package/dist/bin/commands/affected.d.ts +3 -0
  94. package/dist/bin/commands/affected.d.ts.map +1 -0
  95. package/dist/bin/commands/affected.js +78 -0
  96. package/dist/bin/commands/affected.js.map +7 -0
  97. package/dist/bin/commands/architecture.d.ts +3 -0
  98. package/dist/bin/commands/architecture.d.ts.map +1 -0
  99. package/dist/bin/commands/architecture.js +125 -0
  100. package/dist/bin/commands/architecture.js.map +7 -0
  101. package/dist/bin/commands/caveman.js +136 -0
  102. package/dist/bin/commands/caveman.js.map +7 -0
  103. package/dist/bin/commands/context.d.ts +3 -0
  104. package/dist/bin/commands/context.d.ts.map +1 -0
  105. package/dist/bin/commands/context.js +81 -0
  106. package/dist/bin/commands/context.js.map +7 -0
  107. package/dist/bin/commands/coupling.d.ts +3 -0
  108. package/dist/bin/commands/coupling.d.ts.map +1 -0
  109. package/dist/bin/commands/coupling.js +164 -0
  110. package/dist/bin/commands/coupling.js.map +7 -0
  111. package/dist/bin/commands/dashboard.d.ts +3 -0
  112. package/dist/bin/commands/dashboard.d.ts.map +1 -0
  113. package/dist/bin/commands/dashboard.js +209 -0
  114. package/dist/bin/commands/dashboard.js.map +7 -0
  115. package/dist/bin/commands/dead-code.js +77 -0
  116. package/dist/bin/commands/dead-code.js.map +7 -0
  117. package/dist/bin/commands/export.js +2620 -0
  118. package/dist/bin/commands/export.js.map +7 -0
  119. package/dist/bin/commands/files.d.ts +3 -0
  120. package/dist/bin/commands/files.d.ts.map +1 -0
  121. package/dist/bin/commands/files.js +104 -0
  122. package/dist/bin/commands/files.js.map +7 -0
  123. package/dist/bin/commands/help.d.ts +4 -0
  124. package/dist/bin/commands/help.d.ts.map +1 -0
  125. package/dist/bin/commands/help.js +212 -0
  126. package/dist/bin/commands/help.js.map +7 -0
  127. package/dist/bin/commands/hotspots.js +77 -0
  128. package/dist/bin/commands/hotspots.js.map +7 -0
  129. package/dist/bin/commands/index.d.ts +3 -0
  130. package/dist/bin/commands/index.d.ts.map +1 -0
  131. package/dist/bin/commands/index.js +58 -0
  132. package/dist/bin/commands/index.js.map +7 -0
  133. package/dist/bin/commands/init.d.ts +3 -0
  134. package/dist/bin/commands/init.d.ts.map +1 -0
  135. package/dist/bin/commands/init.js +68 -0
  136. package/dist/bin/commands/init.js.map +7 -0
  137. package/dist/bin/commands/install.d.ts +3 -0
  138. package/dist/bin/commands/install.d.ts.map +1 -0
  139. package/dist/bin/commands/install.js +34 -0
  140. package/dist/bin/commands/install.js.map +7 -0
  141. package/dist/bin/commands/mark-dirty.d.ts +3 -0
  142. package/dist/bin/commands/mark-dirty.d.ts.map +1 -0
  143. package/dist/bin/commands/mark-dirty.js +51 -0
  144. package/dist/bin/commands/mark-dirty.js.map +7 -0
  145. package/dist/bin/commands/package.d.ts +3 -0
  146. package/dist/bin/commands/package.d.ts.map +1 -0
  147. package/dist/bin/commands/package.js +139 -0
  148. package/dist/bin/commands/package.js.map +7 -0
  149. package/dist/bin/commands/path.js +93 -0
  150. package/dist/bin/commands/path.js.map +7 -0
  151. package/dist/bin/commands/qdrant.d.ts +3 -0
  152. package/dist/bin/commands/qdrant.d.ts.map +1 -0
  153. package/dist/bin/commands/qdrant.js +159 -0
  154. package/dist/bin/commands/qdrant.js.map +1 -0
  155. package/dist/bin/commands/query.d.ts +3 -0
  156. package/dist/bin/commands/query.d.ts.map +1 -0
  157. package/dist/bin/commands/query.js +47 -0
  158. package/dist/bin/commands/query.js.map +7 -0
  159. package/dist/bin/commands/serve.d.ts +3 -0
  160. package/dist/bin/commands/serve.d.ts.map +1 -0
  161. package/dist/bin/commands/serve.js +59 -0
  162. package/dist/bin/commands/serve.js.map +7 -0
  163. package/dist/bin/commands/snapshot.js +122 -0
  164. package/dist/bin/commands/snapshot.js.map +7 -0
  165. package/dist/bin/commands/status.d.ts +3 -0
  166. package/dist/bin/commands/status.d.ts.map +1 -0
  167. package/dist/bin/commands/status.js +107 -0
  168. package/dist/bin/commands/status.js.map +7 -0
  169. package/dist/bin/commands/stop.d.ts +3 -0
  170. package/dist/bin/commands/stop.d.ts.map +1 -0
  171. package/dist/bin/commands/stop.js +81 -0
  172. package/dist/bin/commands/stop.js.map +1 -0
  173. package/dist/bin/commands/surprising.js +79 -0
  174. package/dist/bin/commands/surprising.js.map +7 -0
  175. package/dist/bin/commands/sync-if-dirty.d.ts +3 -0
  176. package/dist/bin/commands/sync-if-dirty.d.ts.map +1 -0
  177. package/dist/bin/commands/sync-if-dirty.js +67 -0
  178. package/dist/bin/commands/sync-if-dirty.js.map +7 -0
  179. package/dist/bin/commands/sync.d.ts +3 -0
  180. package/dist/bin/commands/sync.d.ts.map +1 -0
  181. package/dist/bin/commands/sync.js +81 -0
  182. package/dist/bin/commands/sync.js.map +7 -0
  183. package/dist/bin/commands/typesense.d.ts +3 -0
  184. package/dist/bin/commands/typesense.d.ts.map +1 -0
  185. package/dist/bin/commands/typesense.js +126 -0
  186. package/dist/bin/commands/typesense.js.map +1 -0
  187. package/dist/bin/commands/uninit.d.ts +4 -0
  188. package/dist/bin/commands/uninit.d.ts.map +1 -0
  189. package/dist/bin/commands/uninit.js +123 -0
  190. package/dist/bin/commands/uninit.js.map +7 -0
  191. package/dist/bin/commands/unlock.d.ts +3 -0
  192. package/dist/bin/commands/unlock.d.ts.map +1 -0
  193. package/dist/bin/commands/unlock.js +53 -0
  194. package/dist/bin/commands/unlock.js.map +7 -0
  195. package/dist/bin/commands/utils.d.ts +12 -0
  196. package/dist/bin/commands/utils.d.ts.map +1 -0
  197. package/dist/bin/commands/utils.js +56 -0
  198. package/dist/bin/commands/utils.js.map +7 -0
  199. package/dist/bin/installer/archive.js +230 -0
  200. package/dist/bin/installer/archive.js.map +7 -0
  201. package/dist/bin/installer/caveman.js +57 -0
  202. package/dist/bin/installer/caveman.js.map +7 -0
  203. package/dist/bin/installer/cli-agent.d.ts +15 -0
  204. package/dist/bin/installer/cli-agent.d.ts.map +1 -0
  205. package/dist/bin/installer/cli-agent.js +89 -0
  206. package/dist/bin/installer/cli-agent.js.map +7 -0
  207. package/dist/bin/installer/config-prompt.d.ts +13 -0
  208. package/dist/bin/installer/config-prompt.d.ts.map +1 -0
  209. package/dist/bin/installer/config-prompt.js +158 -0
  210. package/dist/bin/installer/config-prompt.js.map +7 -0
  211. package/dist/bin/installer/dashboard.d.ts +3 -0
  212. package/dist/bin/installer/dashboard.d.ts.map +1 -0
  213. package/dist/bin/installer/dashboard.js +149 -0
  214. package/dist/bin/installer/dashboard.js.map +7 -0
  215. package/dist/bin/installer/hooks.d.ts +5 -0
  216. package/dist/bin/installer/hooks.d.ts.map +1 -0
  217. package/dist/bin/installer/hooks.js +155 -0
  218. package/dist/bin/installer/hooks.js.map +7 -0
  219. package/dist/bin/installer/index.d.ts +11 -0
  220. package/dist/bin/installer/index.d.ts.map +1 -0
  221. package/dist/bin/installer/index.js +228 -0
  222. package/dist/bin/installer/index.js.map +7 -0
  223. package/dist/bin/installer/mcp.d.ts +5 -0
  224. package/dist/bin/installer/mcp.d.ts.map +1 -0
  225. package/dist/bin/installer/mcp.js +80 -0
  226. package/dist/bin/installer/mcp.js.map +7 -0
  227. package/dist/bin/installer/prompts.d.ts +28 -0
  228. package/dist/bin/installer/prompts.d.ts.map +1 -0
  229. package/dist/bin/installer/prompts.js +134 -0
  230. package/dist/bin/installer/prompts.js.map +7 -0
  231. package/dist/bin/installer/qdrant-dashboard.d.ts +4 -0
  232. package/dist/bin/installer/qdrant-dashboard.d.ts.map +1 -0
  233. package/dist/bin/installer/qdrant-dashboard.js +115 -0
  234. package/dist/bin/installer/qdrant-dashboard.js.map +7 -0
  235. package/dist/bin/installer/steering.d.ts +5 -0
  236. package/dist/bin/installer/steering.d.ts.map +1 -0
  237. package/dist/bin/installer/steering.js +283 -0
  238. package/dist/bin/installer/steering.js.map +7 -0
  239. package/dist/bin/kirograph.d.ts +6 -0
  240. package/dist/bin/kirograph.d.ts.map +1 -0
  241. package/dist/bin/kirograph.js +95 -0
  242. package/dist/bin/kirograph.js.map +7 -0
  243. package/dist/bin/progress.d.ts +14 -0
  244. package/dist/bin/progress.d.ts.map +1 -0
  245. package/dist/bin/progress.js +201 -0
  246. package/dist/bin/progress.js.map +7 -0
  247. package/dist/bin/ui.d.ts +11 -0
  248. package/dist/bin/ui.d.ts.map +1 -0
  249. package/dist/bin/ui.js +71 -0
  250. package/dist/bin/ui.js.map +7 -0
  251. package/dist/config.d.ts +48 -0
  252. package/dist/config.d.ts.map +1 -0
  253. package/dist/config.js +273 -0
  254. package/dist/config.js.map +7 -0
  255. package/dist/context/index.d.ts +61 -0
  256. package/dist/context/index.d.ts.map +1 -0
  257. package/dist/context/index.js +224 -0
  258. package/dist/context/index.js.map +7 -0
  259. package/dist/core/file-tree.d.ts +15 -0
  260. package/dist/core/file-tree.d.ts.map +1 -0
  261. package/dist/core/file-tree.js +69 -0
  262. package/dist/core/file-tree.js.map +7 -0
  263. package/dist/core/lock-manager.d.ts +20 -0
  264. package/dist/core/lock-manager.d.ts.map +1 -0
  265. package/dist/core/lock-manager.js +120 -0
  266. package/dist/core/lock-manager.js.map +7 -0
  267. package/dist/core/pipeline.d.ts +37 -0
  268. package/dist/core/pipeline.d.ts.map +1 -0
  269. package/dist/core/pipeline.js +375 -0
  270. package/dist/core/pipeline.js.map +7 -0
  271. package/dist/core/snapshot.js +141 -0
  272. package/dist/core/snapshot.js.map +7 -0
  273. package/dist/db/database.d.ts +133 -0
  274. package/dist/db/database.d.ts.map +1 -0
  275. package/dist/db/database.js +929 -0
  276. package/dist/db/database.js.map +7 -0
  277. package/dist/db/schema.sql +174 -0
  278. package/dist/errors.d.ts +49 -0
  279. package/dist/errors.d.ts.map +1 -0
  280. package/dist/errors.js +160 -0
  281. package/dist/errors.js.map +7 -0
  282. package/dist/extraction/extractor.d.ts +29 -0
  283. package/dist/extraction/extractor.d.ts.map +1 -0
  284. package/dist/extraction/extractor.js +764 -0
  285. package/dist/extraction/extractor.js.map +7 -0
  286. package/dist/extraction/grammars.d.ts +48 -0
  287. package/dist/extraction/grammars.d.ts.map +1 -0
  288. package/dist/extraction/grammars.js +166 -0
  289. package/dist/extraction/grammars.js.map +7 -0
  290. package/dist/extraction/languages.d.ts +9 -0
  291. package/dist/extraction/languages.d.ts.map +1 -0
  292. package/dist/extraction/languages.js +103 -0
  293. package/dist/extraction/languages.js.map +7 -0
  294. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  295. package/dist/frameworks/csharp.d.ts +8 -0
  296. package/dist/frameworks/csharp.d.ts.map +1 -0
  297. package/dist/frameworks/csharp.js +93 -0
  298. package/dist/frameworks/csharp.js.map +7 -0
  299. package/dist/frameworks/elixir.js +142 -0
  300. package/dist/frameworks/elixir.js.map +7 -0
  301. package/dist/frameworks/express.d.ts +8 -0
  302. package/dist/frameworks/express.d.ts.map +1 -0
  303. package/dist/frameworks/express.js +143 -0
  304. package/dist/frameworks/express.js.map +7 -0
  305. package/dist/frameworks/go.d.ts +8 -0
  306. package/dist/frameworks/go.d.ts.map +1 -0
  307. package/dist/frameworks/go.js +85 -0
  308. package/dist/frameworks/go.js.map +7 -0
  309. package/dist/frameworks/index.d.ts +30 -0
  310. package/dist/frameworks/index.d.ts.map +1 -0
  311. package/dist/frameworks/index.js +243 -0
  312. package/dist/frameworks/index.js.map +7 -0
  313. package/dist/frameworks/java.d.ts +8 -0
  314. package/dist/frameworks/java.d.ts.map +1 -0
  315. package/dist/frameworks/java.js +87 -0
  316. package/dist/frameworks/java.js.map +7 -0
  317. package/dist/frameworks/laravel.d.ts +9 -0
  318. package/dist/frameworks/laravel.d.ts.map +1 -0
  319. package/dist/frameworks/laravel.js +115 -0
  320. package/dist/frameworks/laravel.js.map +7 -0
  321. package/dist/frameworks/python.d.ts +10 -0
  322. package/dist/frameworks/python.d.ts.map +1 -0
  323. package/dist/frameworks/python.js +158 -0
  324. package/dist/frameworks/python.js.map +7 -0
  325. package/dist/frameworks/react.d.ts +9 -0
  326. package/dist/frameworks/react.d.ts.map +1 -0
  327. package/dist/frameworks/react.js +230 -0
  328. package/dist/frameworks/react.js.map +7 -0
  329. package/dist/frameworks/ruby.d.ts +8 -0
  330. package/dist/frameworks/ruby.d.ts.map +1 -0
  331. package/dist/frameworks/ruby.js +136 -0
  332. package/dist/frameworks/ruby.js.map +7 -0
  333. package/dist/frameworks/rust.d.ts +8 -0
  334. package/dist/frameworks/rust.d.ts.map +1 -0
  335. package/dist/frameworks/rust.js +82 -0
  336. package/dist/frameworks/rust.js.map +7 -0
  337. package/dist/frameworks/svelte.d.ts +8 -0
  338. package/dist/frameworks/svelte.d.ts.map +1 -0
  339. package/dist/frameworks/svelte.js +174 -0
  340. package/dist/frameworks/svelte.js.map +7 -0
  341. package/dist/frameworks/swift.d.ts +10 -0
  342. package/dist/frameworks/swift.d.ts.map +1 -0
  343. package/dist/frameworks/swift.js +151 -0
  344. package/dist/frameworks/swift.js.map +7 -0
  345. package/dist/frameworks/types.d.ts +37 -0
  346. package/dist/frameworks/types.d.ts.map +1 -0
  347. package/dist/frameworks/types.js +17 -0
  348. package/dist/frameworks/types.js.map +7 -0
  349. package/dist/graph/queries.d.ts +53 -0
  350. package/dist/graph/queries.d.ts.map +1 -0
  351. package/dist/graph/queries.js +224 -0
  352. package/dist/graph/queries.js.map +7 -0
  353. package/dist/graph/traversal.d.ts +35 -0
  354. package/dist/graph/traversal.d.ts.map +1 -0
  355. package/dist/graph/traversal.js +148 -0
  356. package/dist/graph/traversal.js.map +7 -0
  357. package/dist/index.d.ts +102 -0
  358. package/dist/index.d.ts.map +1 -0
  359. package/dist/index.js +303 -0
  360. package/dist/index.js.map +7 -0
  361. package/dist/installer/index.d.ts +10 -0
  362. package/dist/installer/index.d.ts.map +1 -0
  363. package/dist/installer/index.js +526 -0
  364. package/dist/installer/index.js.map +1 -0
  365. package/dist/mcp/server.d.ts +16 -0
  366. package/dist/mcp/server.d.ts.map +1 -0
  367. package/dist/mcp/server.js +116 -0
  368. package/dist/mcp/server.js.map +7 -0
  369. package/dist/mcp/tools.d.ts +37 -0
  370. package/dist/mcp/tools.d.ts.map +1 -0
  371. package/dist/mcp/tools.js +779 -0
  372. package/dist/mcp/tools.js.map +7 -0
  373. package/dist/mcp/transport.d.ts +29 -0
  374. package/dist/mcp/transport.d.ts.map +1 -0
  375. package/dist/mcp/transport.js +70 -0
  376. package/dist/mcp/transport.js.map +7 -0
  377. package/dist/resolution/index.d.ts +56 -0
  378. package/dist/resolution/index.d.ts.map +1 -0
  379. package/dist/resolution/index.js +384 -0
  380. package/dist/resolution/index.js.map +7 -0
  381. package/dist/resolution/name-matcher.d.ts +25 -0
  382. package/dist/resolution/name-matcher.d.ts.map +1 -0
  383. package/dist/resolution/name-matcher.js +60 -0
  384. package/dist/resolution/name-matcher.js.map +7 -0
  385. package/dist/scripts/postinstall.js +64 -0
  386. package/dist/search/query-utils.d.ts +21 -0
  387. package/dist/search/query-utils.d.ts.map +1 -0
  388. package/dist/search/query-utils.js +219 -0
  389. package/dist/search/query-utils.js.map +7 -0
  390. package/dist/search/searcher.d.ts +15 -0
  391. package/dist/search/searcher.d.ts.map +1 -0
  392. package/dist/search/searcher.js +49 -0
  393. package/dist/search/searcher.js.map +7 -0
  394. package/dist/sync/index.d.ts +33 -0
  395. package/dist/sync/index.d.ts.map +1 -0
  396. package/dist/sync/index.js +200 -0
  397. package/dist/sync/index.js.map +7 -0
  398. package/dist/types.d.ts +131 -0
  399. package/dist/types.d.ts.map +1 -0
  400. package/dist/types.js +37 -0
  401. package/dist/types.js.map +7 -0
  402. package/dist/utils.d.ts +52 -0
  403. package/dist/utils.d.ts.map +1 -0
  404. package/dist/utils.js +254 -0
  405. package/dist/utils.js.map +7 -0
  406. package/dist/vectors/index.d.ts +71 -0
  407. package/dist/vectors/index.d.ts.map +1 -0
  408. package/dist/vectors/index.js +480 -0
  409. package/dist/vectors/index.js.map +7 -0
  410. package/dist/vectors/lancedb-index.d.ts +50 -0
  411. package/dist/vectors/lancedb-index.d.ts.map +1 -0
  412. package/dist/vectors/lancedb-index.js +153 -0
  413. package/dist/vectors/lancedb-index.js.map +7 -0
  414. package/dist/vectors/orama-index.d.ts +54 -0
  415. package/dist/vectors/orama-index.d.ts.map +1 -0
  416. package/dist/vectors/orama-index.js +213 -0
  417. package/dist/vectors/orama-index.js.map +7 -0
  418. package/dist/vectors/pglite-index.d.ts +53 -0
  419. package/dist/vectors/pglite-index.d.ts.map +1 -0
  420. package/dist/vectors/pglite-index.js +194 -0
  421. package/dist/vectors/pglite-index.js.map +7 -0
  422. package/dist/vectors/qdrant-index.d.ts +70 -0
  423. package/dist/vectors/qdrant-index.d.ts.map +1 -0
  424. package/dist/vectors/qdrant-index.js +364 -0
  425. package/dist/vectors/qdrant-index.js.map +7 -0
  426. package/dist/vectors/typesense-index.d.ts +75 -0
  427. package/dist/vectors/typesense-index.d.ts.map +1 -0
  428. package/dist/vectors/typesense-index.js +453 -0
  429. package/dist/vectors/typesense-index.js.map +7 -0
  430. package/dist/vectors/vec-index.d.ts +52 -0
  431. package/dist/vectors/vec-index.d.ts.map +1 -0
  432. package/dist/vectors/vec-index.js +198 -0
  433. package/dist/vectors/vec-index.js.map +7 -0
  434. package/package.json +67 -0
@@ -0,0 +1,929 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var database_exports = {};
30
+ __export(database_exports, {
31
+ GraphDatabase: () => GraphDatabase
32
+ });
33
+ module.exports = __toCommonJS(database_exports);
34
+ var path = __toESM(require("path"));
35
+ var fs = __toESM(require("fs"));
36
+ const { Database } = require("node-sqlite3-wasm");
37
+ const CURRENT_SCHEMA_VERSION = 1;
38
+ class GraphDatabase {
39
+ constructor(projectRoot) {
40
+ this.projectRoot = projectRoot;
41
+ const dbDir = path.join(projectRoot, ".kirograph");
42
+ fs.mkdirSync(dbDir, { recursive: true });
43
+ const dbPath = path.join(dbDir, "kirograph.db");
44
+ const lockPath = path.join(dbDir, "kirograph.db.lock");
45
+ if (fs.existsSync(lockPath)) {
46
+ throw new Error(
47
+ `Database is locked by another process (${lockPath} exists).
48
+ Run: kirograph unlock
49
+ Or delete the lock manually: ${lockPath}`
50
+ );
51
+ }
52
+ this.db = new Database(dbPath);
53
+ this.db.exec(`
54
+ PRAGMA journal_mode=WAL;
55
+ PRAGMA foreign_keys=ON;
56
+ PRAGMA busy_timeout=120000;
57
+ PRAGMA synchronous=NORMAL;
58
+ PRAGMA cache_size=-64000;
59
+ PRAGMA temp_store=MEMORY;
60
+ PRAGMA mmap_size=268435456;
61
+ `);
62
+ this.applySchema();
63
+ }
64
+ applySchema() {
65
+ const schemaPath = path.join(__dirname, "../db/schema.sql");
66
+ const sql = fs.readFileSync(schemaPath, "utf8");
67
+ this.db.exec(sql);
68
+ this.runMigrations();
69
+ }
70
+ runMigrations() {
71
+ const versionRow = this.db.get("SELECT version FROM schema_versions ORDER BY version DESC LIMIT 1");
72
+ const currentVersion = versionRow ? versionRow.version : 0;
73
+ if (currentVersion < CURRENT_SCHEMA_VERSION) {
74
+ this.db.run(
75
+ "INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)",
76
+ [CURRENT_SCHEMA_VERSION, Date.now()]
77
+ );
78
+ }
79
+ try {
80
+ this.db.run("ALTER TABLE unresolved_refs ADD COLUMN attempted_strategies TEXT");
81
+ } catch {
82
+ }
83
+ }
84
+ // ── Files ──────────────────────────────────────────────────────────────────
85
+ upsertFile(record) {
86
+ this.db.run(
87
+ `INSERT OR REPLACE INTO files (path, content_hash, language, file_size, symbol_count, indexed_at)
88
+ VALUES (?, ?, ?, ?, ?, ?)`,
89
+ [record.path, record.contentHash, record.language, record.fileSize, record.symbolCount, record.indexedAt]
90
+ );
91
+ }
92
+ getFile(filePath) {
93
+ const row = this.db.get("SELECT * FROM files WHERE path = ?", [filePath]);
94
+ return row ? this.rowToFile(row) : null;
95
+ }
96
+ getAllFiles() {
97
+ return this.db.all("SELECT * FROM files").map(this.rowToFile);
98
+ }
99
+ deleteFile(filePath) {
100
+ this.db.run("DELETE FROM nodes WHERE file_path = ?", [filePath]);
101
+ this.db.run("DELETE FROM files WHERE path = ?", [filePath]);
102
+ }
103
+ rowToFile(row) {
104
+ return {
105
+ path: row.path,
106
+ contentHash: row.content_hash,
107
+ language: row.language,
108
+ fileSize: row.file_size,
109
+ symbolCount: row.symbol_count,
110
+ indexedAt: row.indexed_at
111
+ };
112
+ }
113
+ // ── Nodes ──────────────────────────────────────────────────────────────────
114
+ upsertNode(node) {
115
+ this.db.run(
116
+ `INSERT OR REPLACE INTO nodes
117
+ (id, kind, name, qualified_name, file_path, language,
118
+ start_line, end_line, start_column, end_column,
119
+ docstring, signature, visibility,
120
+ is_exported, is_async, is_static, is_abstract,
121
+ decorators, type_parameters, updated_at)
122
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
123
+ [
124
+ node.id,
125
+ node.kind,
126
+ node.name,
127
+ node.qualifiedName,
128
+ node.filePath,
129
+ node.language,
130
+ node.startLine,
131
+ node.endLine,
132
+ node.startColumn,
133
+ node.endColumn,
134
+ node.docstring ?? null,
135
+ node.signature ?? null,
136
+ node.visibility ?? null,
137
+ node.isExported ? 1 : 0,
138
+ node.isAsync ? 1 : 0,
139
+ node.isStatic ? 1 : 0,
140
+ node.isAbstract ? 1 : 0,
141
+ node.decorators ? JSON.stringify(node.decorators) : null,
142
+ node.typeParameters ? JSON.stringify(node.typeParameters) : null,
143
+ node.updatedAt
144
+ ]
145
+ );
146
+ this.db.run(
147
+ `INSERT OR REPLACE INTO nodes_fts (id, name, qualified_name, docstring, signature)
148
+ VALUES (?, ?, ?, ?, ?)`,
149
+ [node.id, node.name, node.qualifiedName, node.docstring ?? "", node.signature ?? ""]
150
+ );
151
+ }
152
+ getNode(id) {
153
+ const row = this.db.get("SELECT * FROM nodes WHERE id = ?", [id]);
154
+ return row ? this.rowToNode(row) : null;
155
+ }
156
+ getNodesByFile(filePath) {
157
+ return this.db.all("SELECT * FROM nodes WHERE file_path = ?", [filePath]).map(this.rowToNode);
158
+ }
159
+ getNodesByKind(kind) {
160
+ return this.db.all("SELECT * FROM nodes WHERE kind = ?", [kind]).map(this.rowToNode);
161
+ }
162
+ findNodesByExactName(name, kinds, limit = 20) {
163
+ if (kinds && kinds.length > 0) {
164
+ const placeholders = kinds.map(() => "?").join(",");
165
+ return this.db.all(
166
+ `SELECT * FROM nodes WHERE name = ? AND kind IN (${placeholders}) LIMIT ?`,
167
+ [name, ...kinds, limit]
168
+ ).map(this.rowToNode);
169
+ }
170
+ return this.db.all(
171
+ "SELECT * FROM nodes WHERE name = ? LIMIT ?",
172
+ [name, limit]
173
+ ).map(this.rowToNode);
174
+ }
175
+ searchNodes(query, opts = {}) {
176
+ const { kinds, languages, limit = 20 } = opts;
177
+ const safe = query.replace(/\b(AND|OR|NOT)\b/g, " ").replace(/['"*()?\-+^~:{}\\\.\/,]/g, " ").replace(/\s+/g, " ").trim();
178
+ if (!safe) return [];
179
+ const ftsQuery = safe + "*";
180
+ const safeLimit = Math.max(1, Math.floor(Number(limit)));
181
+ const conditions = [];
182
+ const params = [];
183
+ if (kinds && kinds.length > 0) {
184
+ conditions.push(`kind IN (${kinds.map(() => "?").join(",")})`);
185
+ params.push(...kinds);
186
+ }
187
+ if (languages && languages.length > 0) {
188
+ conditions.push(`language IN (${languages.map(() => "?").join(",")})`);
189
+ params.push(...languages);
190
+ }
191
+ const where = conditions.length > 0 ? `AND ${conditions.join(" AND ")}` : "";
192
+ return this.db.all(
193
+ `SELECT * FROM nodes
194
+ WHERE id IN (SELECT rowid FROM nodes_fts WHERE nodes_fts MATCH '${ftsQuery}')
195
+ ${where}
196
+ LIMIT ${safeLimit}`,
197
+ params
198
+ ).map(this.rowToNode);
199
+ }
200
+ searchNodesByName(name, opts = {}) {
201
+ const { kinds, languages, limit = 20 } = opts;
202
+ const pattern = `%${name}%`;
203
+ const conditions = ["name LIKE ?"];
204
+ const params = [pattern];
205
+ if (kinds && kinds.length > 0) {
206
+ conditions.push(`kind IN (${kinds.map(() => "?").join(",")})`);
207
+ params.push(...kinds);
208
+ }
209
+ if (languages && languages.length > 0) {
210
+ conditions.push(`language IN (${languages.map(() => "?").join(",")})`);
211
+ params.push(...languages);
212
+ }
213
+ params.push(limit);
214
+ return this.db.all(
215
+ `SELECT * FROM nodes WHERE ${conditions.join(" AND ")} LIMIT ?`,
216
+ params
217
+ ).map(this.rowToNode);
218
+ }
219
+ deleteNodesByFile(filePath) {
220
+ const ids = this.db.all("SELECT id FROM nodes WHERE file_path = ?", [filePath]).map((r) => r.id);
221
+ if (ids.length === 0) return;
222
+ const placeholders = ids.map(() => "?").join(",");
223
+ this.db.run(`DELETE FROM edges WHERE source IN (${placeholders}) OR target IN (${placeholders})`, [...ids, ...ids]);
224
+ this.db.run(`DELETE FROM nodes_fts WHERE id IN (${placeholders})`, ids);
225
+ this.db.run(`DELETE FROM nodes WHERE file_path = ?`, [filePath]);
226
+ }
227
+ rowToNode(row) {
228
+ return {
229
+ id: row.id,
230
+ kind: row.kind,
231
+ name: row.name,
232
+ qualifiedName: row.qualified_name,
233
+ filePath: row.file_path,
234
+ language: row.language,
235
+ startLine: row.start_line,
236
+ endLine: row.end_line,
237
+ startColumn: row.start_column,
238
+ endColumn: row.end_column,
239
+ docstring: row.docstring ?? void 0,
240
+ signature: row.signature ?? void 0,
241
+ visibility: row.visibility ?? void 0,
242
+ isExported: row.is_exported === 1,
243
+ isAsync: row.is_async === 1,
244
+ isStatic: row.is_static === 1,
245
+ isAbstract: row.is_abstract === 1,
246
+ decorators: row.decorators ? JSON.parse(row.decorators) : void 0,
247
+ typeParameters: row.type_parameters ? JSON.parse(row.type_parameters) : void 0,
248
+ updatedAt: row.updated_at
249
+ };
250
+ }
251
+ // ── Edges ──────────────────────────────────────────────────────────────────
252
+ insertEdge(edge) {
253
+ this.db.run(
254
+ `INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, column)
255
+ VALUES (?, ?, ?, ?, ?, ?)`,
256
+ [edge.source, edge.target, edge.kind, edge.metadata ? JSON.stringify(edge.metadata) : null, edge.line ?? null, edge.column ?? null]
257
+ );
258
+ }
259
+ getCallers(nodeId, limit = 30) {
260
+ return this.db.all(
261
+ `SELECT n.* FROM nodes n
262
+ JOIN edges e ON e.source = n.id
263
+ WHERE e.target = ? AND e.kind = 'calls'
264
+ LIMIT ?`,
265
+ [nodeId, limit]
266
+ ).map(this.rowToNode);
267
+ }
268
+ getCallees(nodeId, limit = 30) {
269
+ return this.db.all(
270
+ `SELECT n.* FROM nodes n
271
+ JOIN edges e ON e.target = n.id
272
+ WHERE e.source = ? AND e.kind = 'calls'
273
+ LIMIT ?`,
274
+ [nodeId, limit]
275
+ ).map(this.rowToNode);
276
+ }
277
+ getImpactRadius(nodeId, depth = 2) {
278
+ const visited = /* @__PURE__ */ new Set([nodeId]);
279
+ let frontier = [nodeId];
280
+ for (let d = 0; d < depth; d++) {
281
+ if (frontier.length === 0) break;
282
+ const placeholders2 = frontier.map(() => "?").join(",");
283
+ const rows = this.db.all(
284
+ `SELECT DISTINCT source FROM edges WHERE target IN (${placeholders2}) AND kind IN ('calls','imports')`,
285
+ frontier
286
+ );
287
+ frontier = [];
288
+ for (const row of rows) {
289
+ if (!visited.has(row.source)) {
290
+ visited.add(row.source);
291
+ frontier.push(row.source);
292
+ }
293
+ }
294
+ }
295
+ visited.delete(nodeId);
296
+ if (visited.size === 0) return [];
297
+ const ids = [...visited];
298
+ const placeholders = ids.map(() => "?").join(",");
299
+ return this.db.all(`SELECT * FROM nodes WHERE id IN (${placeholders})`, ids).map(this.rowToNode);
300
+ }
301
+ getEdgesForNodes(nodeIds) {
302
+ if (nodeIds.length === 0) return [];
303
+ const placeholders = nodeIds.map(() => "?").join(",");
304
+ return this.db.all(
305
+ `SELECT * FROM edges WHERE source IN (${placeholders}) OR target IN (${placeholders})`,
306
+ [...nodeIds, ...nodeIds]
307
+ ).map((row) => ({
308
+ source: row.source,
309
+ target: row.target,
310
+ kind: row.kind,
311
+ metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
312
+ line: row.line ?? void 0,
313
+ column: row.column ?? void 0
314
+ }));
315
+ }
316
+ /**
317
+ * Find files that import (depend on) the given file path.
318
+ * Used for affected-test traversal.
319
+ */
320
+ getDependentFiles(filePath) {
321
+ const targetNodes = this.db.all("SELECT id FROM nodes WHERE file_path = ?", [filePath]);
322
+ if (targetNodes.length === 0) return [];
323
+ const ids = targetNodes.map((r) => r.id);
324
+ const placeholders = ids.map(() => "?").join(",");
325
+ const rows = this.db.all(
326
+ `SELECT DISTINCT n.file_path FROM nodes n
327
+ JOIN edges e ON e.source = n.id
328
+ WHERE e.target IN (${placeholders}) AND e.kind IN ('calls','imports')
329
+ AND n.file_path != ?`,
330
+ [...ids, filePath]
331
+ );
332
+ return rows.map((r) => r.file_path);
333
+ }
334
+ // ── Unresolved References ──────────────────────────────────────────────────
335
+ insertUnresolvedRef(sourceId, refName, refKind, filePath, line, column) {
336
+ this.db.run(
337
+ `INSERT INTO unresolved_refs (source_id, ref_name, ref_kind, file_path, line, column)
338
+ VALUES (?, ?, ?, ?, ?, ?)`,
339
+ [sourceId, refName, refKind, filePath, line ?? null, column ?? null]
340
+ );
341
+ }
342
+ deleteUnresolvedRefsByFile(filePath) {
343
+ this.db.run("DELETE FROM unresolved_refs WHERE file_path = ?", [filePath]);
344
+ }
345
+ /**
346
+ * Resolve pending references:
347
+ * - refKind='function': 3-strategy name matching → 'calls' edge
348
+ * - refKind='import': path-based resolution → 'imports' edge
349
+ *
350
+ * Returns the number of edges successfully created.
351
+ */
352
+ resolveUnresolvedRefs() {
353
+ const refs = this.db.all("SELECT * FROM unresolved_refs");
354
+ let resolved = 0;
355
+ for (const ref of refs) {
356
+ const { id: refId, source_id: sourceId, ref_name: refName, ref_kind: refKind, file_path: filePath, line, column } = ref;
357
+ if (refKind === "function") {
358
+ let target = this.db.get("SELECT id FROM nodes WHERE name = ? LIMIT 1", [refName]);
359
+ if (!target) {
360
+ target = this.db.get(
361
+ `SELECT id FROM nodes WHERE qualified_name LIKE ? LIMIT 1`,
362
+ [`%::${refName}`]
363
+ );
364
+ }
365
+ if (!target) {
366
+ target = this.db.get(
367
+ "SELECT id FROM nodes WHERE lower(name) = lower(?) LIMIT 1",
368
+ [refName]
369
+ );
370
+ }
371
+ if (target) {
372
+ this.insertEdge({ source: sourceId, target: target.id, kind: "calls", line: line ?? void 0, column: column ?? void 0 });
373
+ this.db.run("DELETE FROM unresolved_refs WHERE id = ?", [refId]);
374
+ resolved++;
375
+ }
376
+ } else if (refKind === "import") {
377
+ const targetFileNode = this.resolveImportPath(refName, filePath);
378
+ if (targetFileNode) {
379
+ this.insertEdge({ source: sourceId, target: targetFileNode, kind: "imports", line: line ?? void 0, column: column ?? void 0 });
380
+ this.db.run("DELETE FROM unresolved_refs WHERE id = ?", [refId]);
381
+ resolved++;
382
+ }
383
+ }
384
+ }
385
+ return resolved;
386
+ }
387
+ /** @deprecated Use resolveUnresolvedRefs() */
388
+ resolveCallEdges() {
389
+ return this.resolveUnresolvedRefs();
390
+ }
391
+ /**
392
+ * Resolve a module import path to the ID of the first node in the target file.
393
+ * Returns null if no indexed file matches.
394
+ */
395
+ resolveImportPath(importPath, sourceFilePath) {
396
+ if (!importPath.startsWith(".")) return null;
397
+ const sourceDir = sourceFilePath.replace(/[^/]+$/, "");
398
+ const segments = (sourceDir + importPath).split("/");
399
+ const normalized = [];
400
+ for (const seg of segments) {
401
+ if (seg === "..") normalized.pop();
402
+ else if (seg !== ".") normalized.push(seg);
403
+ }
404
+ const basePath = normalized.join("/");
405
+ const candidates = [
406
+ basePath,
407
+ basePath + ".ts",
408
+ basePath + ".tsx",
409
+ basePath + ".js",
410
+ basePath + ".jsx",
411
+ basePath + "/index.ts",
412
+ basePath + "/index.tsx",
413
+ basePath + "/index.js"
414
+ ];
415
+ for (const candidate of candidates) {
416
+ const row = this.db.get("SELECT id FROM nodes WHERE file_path = ? LIMIT 1", [candidate]);
417
+ if (row) return row.id;
418
+ }
419
+ return null;
420
+ }
421
+ // ── Node Context & Metrics ─────────────────────────────────────────────────
422
+ getNodeContext(nodeId) {
423
+ const node = this.getNode(nodeId);
424
+ if (!node) return null;
425
+ const ancestors = this.db.all(
426
+ `SELECT n.* FROM nodes n
427
+ JOIN edges e ON e.target = n.id
428
+ WHERE e.source = ? AND e.kind = 'contains'`,
429
+ [nodeId]
430
+ ).map(this.rowToNode);
431
+ const children = this.db.all(
432
+ `SELECT n.* FROM nodes n
433
+ JOIN edges e ON e.source = n.id
434
+ WHERE e.target = n.id AND e.source = ? AND e.kind = 'contains'`,
435
+ [nodeId]
436
+ ).map(this.rowToNode);
437
+ const callers = this.getCallers(nodeId, 20);
438
+ const callees = this.getCallees(nodeId, 20);
439
+ return { node, ancestors, children, callers, callees };
440
+ }
441
+ getNodeMetrics(nodeId) {
442
+ const incomingEdgeCount = this.db.get("SELECT COUNT(*) as c FROM edges WHERE target = ?", [nodeId])?.c ?? 0;
443
+ const outgoingEdgeCount = this.db.get("SELECT COUNT(*) as c FROM edges WHERE source = ?", [nodeId])?.c ?? 0;
444
+ const callCount = this.db.get(`SELECT COUNT(*) as c FROM edges WHERE source = ? AND kind = 'calls'`, [nodeId])?.c ?? 0;
445
+ const callerCount = this.db.get(`SELECT COUNT(*) as c FROM edges WHERE target = ? AND kind = 'calls'`, [nodeId])?.c ?? 0;
446
+ const childCount = this.db.get(`SELECT COUNT(*) as c FROM edges WHERE source = ? AND kind = 'contains'`, [nodeId])?.c ?? 0;
447
+ return { incomingEdgeCount, outgoingEdgeCount, callCount, callerCount, childCount };
448
+ }
449
+ // ── Graph Analysis ─────────────────────────────────────────────────────────
450
+ /**
451
+ * Find symbols with no incoming edges (potential dead code).
452
+ * Excludes exported symbols since they may be consumed externally.
453
+ */
454
+ findDeadCode(limit = 50) {
455
+ return this.db.all(
456
+ `SELECT * FROM nodes
457
+ WHERE kind IN ('function','method','class')
458
+ AND is_exported = 0
459
+ AND id NOT IN (SELECT DISTINCT target FROM edges)
460
+ LIMIT ?`,
461
+ [limit]
462
+ ).map(this.rowToNode);
463
+ }
464
+ /**
465
+ * Find circular import dependencies using DFS over import edges.
466
+ * Returns arrays of file paths forming cycles.
467
+ */
468
+ findCircularDependencies() {
469
+ const rows = this.db.all(
470
+ `SELECT DISTINCT n1.file_path as src, n2.file_path as dst
471
+ FROM edges e
472
+ JOIN nodes n1 ON n1.id = e.source
473
+ JOIN nodes n2 ON n2.id = e.target
474
+ WHERE e.kind = 'imports' AND n1.file_path != n2.file_path`
475
+ );
476
+ const adj = /* @__PURE__ */ new Map();
477
+ for (const row of rows) {
478
+ if (!adj.has(row.src)) adj.set(row.src, /* @__PURE__ */ new Set());
479
+ adj.get(row.src).add(row.dst);
480
+ }
481
+ const cycles = [];
482
+ const visited = /* @__PURE__ */ new Set();
483
+ const pathSet = /* @__PURE__ */ new Set();
484
+ const pathArr = [];
485
+ function dfs(node) {
486
+ if (pathSet.has(node)) {
487
+ const cycleStart = pathArr.indexOf(node);
488
+ cycles.push(pathArr.slice(cycleStart).concat(node));
489
+ return;
490
+ }
491
+ if (visited.has(node)) return;
492
+ visited.add(node);
493
+ pathSet.add(node);
494
+ pathArr.push(node);
495
+ for (const neighbor of adj.get(node) ?? []) {
496
+ dfs(neighbor);
497
+ }
498
+ pathArr.pop();
499
+ pathSet.delete(node);
500
+ }
501
+ for (const node of adj.keys()) {
502
+ if (!visited.has(node)) dfs(node);
503
+ }
504
+ return cycles;
505
+ }
506
+ /**
507
+ * Find the shortest path between two nodes via directed BFS (outgoing edges only).
508
+ */
509
+ findPath(fromId, toId, maxDepth = 10) {
510
+ if (fromId === toId) {
511
+ const node = this.getNode(fromId);
512
+ return node ? [node] : [];
513
+ }
514
+ const prev = /* @__PURE__ */ new Map();
515
+ const queue = [fromId];
516
+ const visited = /* @__PURE__ */ new Set([fromId]);
517
+ let depth = 0;
518
+ outer: while (queue.length > 0 && depth < maxDepth) {
519
+ const levelSize = queue.length;
520
+ depth++;
521
+ for (let i = 0; i < levelSize; i++) {
522
+ const current = queue.shift();
523
+ const rows = this.db.all(
524
+ `SELECT DISTINCT target as next FROM edges WHERE source = ?`,
525
+ [current]
526
+ );
527
+ for (const row of rows) {
528
+ if (!visited.has(row.next)) {
529
+ visited.add(row.next);
530
+ prev.set(row.next, current);
531
+ if (row.next === toId) break outer;
532
+ queue.push(row.next);
533
+ }
534
+ }
535
+ }
536
+ }
537
+ if (!prev.has(toId)) return [];
538
+ const pathIds = [];
539
+ let cur = toId;
540
+ while (cur !== void 0) {
541
+ pathIds.unshift(cur);
542
+ cur = prev.get(cur);
543
+ }
544
+ const result = [];
545
+ for (const id of pathIds) {
546
+ const node = this.getNode(id);
547
+ if (node) result.push(node);
548
+ }
549
+ return result;
550
+ }
551
+ /**
552
+ * Traverse type hierarchy via 'extends' and 'implements' edges.
553
+ * direction 'up' = base types, 'down' = derived types, 'both' = all.
554
+ */
555
+ getTypeHierarchy(nodeId, direction = "both") {
556
+ const visited = /* @__PURE__ */ new Set([nodeId]);
557
+ const frontier = [nodeId];
558
+ const result = [];
559
+ while (frontier.length > 0) {
560
+ const current = frontier.shift();
561
+ let rows = [];
562
+ if (direction === "up" || direction === "both") {
563
+ const up = this.db.all(
564
+ `SELECT target as id FROM edges WHERE source = ? AND kind IN ('extends','implements')`,
565
+ [current]
566
+ );
567
+ rows = rows.concat(up);
568
+ }
569
+ if (direction === "down" || direction === "both") {
570
+ const down = this.db.all(
571
+ `SELECT source as id FROM edges WHERE target = ? AND kind IN ('extends','implements')`,
572
+ [current]
573
+ );
574
+ rows = rows.concat(down);
575
+ }
576
+ for (const row of rows) {
577
+ if (!visited.has(row.id)) {
578
+ visited.add(row.id);
579
+ frontier.push(row.id);
580
+ const node = this.getNode(row.id);
581
+ if (node) result.push(node);
582
+ }
583
+ }
584
+ }
585
+ return result;
586
+ }
587
+ // ── Stats ──────────────────────────────────────────────────────────────────
588
+ getEmbeddingCount() {
589
+ try {
590
+ const row = this.db.get("SELECT COUNT(*) as c FROM vectors");
591
+ return row ? row.c : 0;
592
+ } catch {
593
+ return 0;
594
+ }
595
+ }
596
+ storeEmbedding(nodeId, embedding, model) {
597
+ const buf = Buffer.from(embedding.buffer);
598
+ this.db.run(
599
+ `INSERT OR REPLACE INTO vectors (node_id, embedding, model, created_at) VALUES (?, ?, ?, ?)`,
600
+ [nodeId, buf, model, Date.now()]
601
+ );
602
+ }
603
+ getEmbeddedNodeIds() {
604
+ return this.db.all("SELECT node_id FROM vectors").map((r) => r.node_id);
605
+ }
606
+ getAllEmbeddings() {
607
+ const rows = this.db.all("SELECT node_id, embedding FROM vectors");
608
+ return rows.map((r) => ({
609
+ nodeId: r.node_id,
610
+ embedding: new Float32Array(
611
+ r.embedding.buffer,
612
+ r.embedding.byteOffset,
613
+ r.embedding.byteLength / 4
614
+ )
615
+ }));
616
+ }
617
+ getAllNodes() {
618
+ return this.db.all("SELECT * FROM nodes").map(this.rowToNode);
619
+ }
620
+ /**
621
+ * Returns embeddable nodes in pages for memory-efficient streaming.
622
+ * `kinds` filters by node kind (e.g. ['function','method','class']).
623
+ * Returns an empty array when offset >= total count.
624
+ */
625
+ getEmbeddableNodesPaged(kinds, limit, offset) {
626
+ if (kinds.length === 0) return [];
627
+ const placeholders = kinds.map(() => "?").join(",");
628
+ return this.db.all(
629
+ `SELECT * FROM nodes WHERE kind IN (${placeholders}) LIMIT ? OFFSET ?`,
630
+ [...kinds, limit, offset]
631
+ ).map(this.rowToNode);
632
+ }
633
+ /** Count of nodes whose kind is in the provided list. */
634
+ countEmbeddableNodes(kinds) {
635
+ if (kinds.length === 0) return 0;
636
+ const placeholders = kinds.map(() => "?").join(",");
637
+ const row = this.db.get(`SELECT COUNT(*) as c FROM nodes WHERE kind IN (${placeholders})`, kinds);
638
+ return row?.c ?? 0;
639
+ }
640
+ getAllEdges() {
641
+ return this.db.all("SELECT source, target, kind FROM edges").map((row) => ({
642
+ source: row.source,
643
+ target: row.target,
644
+ kind: row.kind
645
+ }));
646
+ }
647
+ /**
648
+ * Find the top-N most-connected nodes by total edge degree (in + out).
649
+ * Excludes 'contains' edges (structural nesting, not semantic connections).
650
+ */
651
+ findHotspots(limit = 20) {
652
+ const rows = this.db.all(
653
+ `SELECT n.*,
654
+ (SELECT COUNT(*) FROM edges WHERE target = n.id AND kind != 'contains') AS in_degree,
655
+ (SELECT COUNT(*) FROM edges WHERE source = n.id AND kind != 'contains') AS out_degree,
656
+ (SELECT COUNT(*) FROM edges WHERE (source = n.id OR target = n.id) AND kind != 'contains') AS degree
657
+ FROM nodes n
658
+ ORDER BY degree DESC
659
+ LIMIT ?`,
660
+ [limit]
661
+ );
662
+ return rows.map((row) => ({
663
+ ...this.rowToNode(row),
664
+ degree: row.degree,
665
+ inDegree: row.in_degree,
666
+ outDegree: row.out_degree
667
+ }));
668
+ }
669
+ /**
670
+ * Find surprising cross-file connections: direct edges between nodes in
671
+ * structurally distant files. Scored by path distance × edge-kind weight.
672
+ */
673
+ findSurprisingConnections(limit = 20) {
674
+ const KIND_WEIGHT = {
675
+ calls: 1,
676
+ references: 0.8,
677
+ type_of: 0.7,
678
+ returns: 0.6,
679
+ decorates: 0.6,
680
+ extends: 0.5,
681
+ implements: 0.5
682
+ };
683
+ const rows = this.db.all(
684
+ `SELECT e.source, e.target, e.kind,
685
+ ns.file_path AS source_file, nt.file_path AS target_file
686
+ FROM edges e
687
+ JOIN nodes ns ON ns.id = e.source
688
+ JOIN nodes nt ON nt.id = e.target
689
+ WHERE ns.file_path != nt.file_path
690
+ AND e.kind NOT IN ('contains', 'import', 'imports')
691
+ LIMIT 5000`
692
+ );
693
+ const scored = rows.map((row) => {
694
+ const srcDirs = row.source_file.split("/").slice(0, -1);
695
+ const tgtDirs = row.target_file.split("/").slice(0, -1);
696
+ let common = 0;
697
+ for (let i = 0; i < Math.min(srcDirs.length, tgtDirs.length); i++) {
698
+ if (srcDirs[i] === tgtDirs[i]) common++;
699
+ else break;
700
+ }
701
+ const maxDirs = Math.max(srcDirs.length, tgtDirs.length, 1);
702
+ const pathSimilarity = common / maxDirs;
703
+ const kindWeight = KIND_WEIGHT[row.kind] ?? 0.4;
704
+ return { ...row, score: (1 - pathSimilarity) * kindWeight };
705
+ });
706
+ scored.sort((a, b) => b.score - a.score);
707
+ const seen = /* @__PURE__ */ new Set();
708
+ const top = [];
709
+ for (const row of scored) {
710
+ const key = `${row.source}|${row.target}|${row.kind}`;
711
+ if (!seen.has(key)) {
712
+ seen.add(key);
713
+ top.push(row);
714
+ if (top.length >= limit) break;
715
+ }
716
+ }
717
+ const result = [];
718
+ for (const row of top) {
719
+ const src = this.getNode(row.source);
720
+ const tgt = this.getNode(row.target);
721
+ if (src && tgt) result.push({ source: src, target: tgt, kind: row.kind, score: row.score });
722
+ }
723
+ return result;
724
+ }
725
+ getStats() {
726
+ const files = this.db.get("SELECT COUNT(*) as c FROM files").c;
727
+ const nodes = this.db.get("SELECT COUNT(*) as c FROM nodes").c;
728
+ const edges = this.db.get("SELECT COUNT(*) as c FROM edges").c;
729
+ const kindRows = this.db.all("SELECT kind, COUNT(*) as c FROM nodes GROUP BY kind");
730
+ const nodesByKind = {};
731
+ for (const row of kindRows) nodesByKind[row.kind] = row.c;
732
+ const langRows = this.db.all("SELECT language, COUNT(*) as c FROM files GROUP BY language");
733
+ const filesByLanguage = {};
734
+ for (const row of langRows) filesByLanguage[row.language] = row.c;
735
+ const dbPath = path.join(this.projectRoot, ".kirograph", "kirograph.db");
736
+ let dbSizeBytes = 0;
737
+ try {
738
+ dbSizeBytes = fs.statSync(dbPath).size;
739
+ } catch {
740
+ }
741
+ const embeddingCount = this.getEmbeddingCount();
742
+ return { files, nodes, edges, nodesByKind, filesByLanguage, dbSizeBytes, embeddingCount, embeddingsEnabled: false, embeddingModel: "", useVecIndex: false, semanticEngine: "cosine", vecIndexCount: 0, engineFallback: null, embeddableNodeCount: 0, frameworks: [], architectureEnabled: false };
743
+ }
744
+ // ── Architecture ──────────────────────────────────────────────────────────
745
+ clearArchitecture() {
746
+ this.db.run("DELETE FROM arch_coupling");
747
+ this.db.run("DELETE FROM arch_layer_deps");
748
+ this.db.run("DELETE FROM arch_package_deps");
749
+ this.db.run("DELETE FROM arch_file_layers");
750
+ this.db.run("DELETE FROM arch_file_packages");
751
+ this.db.run("DELETE FROM arch_layers");
752
+ this.db.run("DELETE FROM arch_packages");
753
+ }
754
+ upsertArchPackage(pkg) {
755
+ this.db.run(
756
+ `INSERT OR REPLACE INTO arch_packages
757
+ (id, name, path, source, language, manifest_path, version, external_deps, metadata, updated_at)
758
+ VALUES (?,?,?,?,?,?,?,?,?,?)`,
759
+ [
760
+ pkg.id,
761
+ pkg.name,
762
+ pkg.path,
763
+ pkg.source,
764
+ pkg.language ?? null,
765
+ pkg.manifestPath ?? null,
766
+ pkg.version ?? null,
767
+ pkg.externalDeps ? JSON.stringify(pkg.externalDeps) : null,
768
+ pkg.metadata ? JSON.stringify(pkg.metadata) : null,
769
+ pkg.updatedAt
770
+ ]
771
+ );
772
+ }
773
+ upsertArchLayer(layer) {
774
+ this.db.run(
775
+ `INSERT OR REPLACE INTO arch_layers (id, name, source, patterns, metadata, updated_at)
776
+ VALUES (?,?,?,?,?,?)`,
777
+ [
778
+ layer.id,
779
+ layer.name,
780
+ layer.source,
781
+ JSON.stringify(layer.patterns),
782
+ layer.metadata ? JSON.stringify(layer.metadata) : null,
783
+ layer.updatedAt
784
+ ]
785
+ );
786
+ }
787
+ upsertArchFilePackage(filePath, packageId) {
788
+ this.db.run(
789
+ "INSERT OR IGNORE INTO arch_file_packages (file_path, package_id) VALUES (?,?)",
790
+ [filePath, packageId]
791
+ );
792
+ }
793
+ upsertArchFileLayer(filePath, layerId, confidence, matchedPattern) {
794
+ this.db.run(
795
+ `INSERT OR REPLACE INTO arch_file_layers (file_path, layer_id, confidence, matched_pattern)
796
+ VALUES (?,?,?,?)`,
797
+ [filePath, layerId, confidence, matchedPattern]
798
+ );
799
+ }
800
+ upsertArchPackageDep(sourcePkg, targetPkg, depCount, files) {
801
+ this.db.run(
802
+ `INSERT OR REPLACE INTO arch_package_deps (source_pkg, target_pkg, dep_count, files)
803
+ VALUES (?,?,?,?)`,
804
+ [sourcePkg, targetPkg, depCount, files ? JSON.stringify(files) : null]
805
+ );
806
+ }
807
+ upsertArchLayerDep(sourceLayer, targetLayer, depCount) {
808
+ this.db.run(
809
+ `INSERT OR REPLACE INTO arch_layer_deps (source_layer, target_layer, dep_count)
810
+ VALUES (?,?,?)`,
811
+ [sourceLayer, targetLayer, depCount]
812
+ );
813
+ }
814
+ upsertArchCoupling(coupling) {
815
+ this.db.run(
816
+ `INSERT OR REPLACE INTO arch_coupling (package_id, afferent, efferent, instability, updated_at)
817
+ VALUES (?,?,?,?,?)`,
818
+ [coupling.packageId, coupling.afferent, coupling.efferent, coupling.instability, coupling.updatedAt]
819
+ );
820
+ }
821
+ getArchPackages() {
822
+ return this.db.all("SELECT * FROM arch_packages").map((r) => ({
823
+ id: r.id,
824
+ name: r.name,
825
+ path: r.path,
826
+ source: r.source,
827
+ language: r.language ?? void 0,
828
+ manifestPath: r.manifest_path ?? void 0,
829
+ version: r.version ?? void 0,
830
+ externalDeps: r.external_deps ? JSON.parse(r.external_deps) : void 0,
831
+ metadata: r.metadata ? JSON.parse(r.metadata) : void 0,
832
+ updatedAt: r.updated_at
833
+ }));
834
+ }
835
+ getArchLayers() {
836
+ return this.db.all("SELECT * FROM arch_layers").map((r) => ({
837
+ id: r.id,
838
+ name: r.name,
839
+ source: r.source,
840
+ patterns: JSON.parse(r.patterns),
841
+ metadata: r.metadata ? JSON.parse(r.metadata) : void 0,
842
+ updatedAt: r.updated_at
843
+ }));
844
+ }
845
+ getArchPackageDeps() {
846
+ return this.db.all("SELECT * FROM arch_package_deps").map((r) => ({
847
+ sourcePkg: r.source_pkg,
848
+ targetPkg: r.target_pkg,
849
+ depCount: r.dep_count,
850
+ files: r.files ? JSON.parse(r.files) : void 0
851
+ }));
852
+ }
853
+ getArchLayerDeps() {
854
+ return this.db.all("SELECT * FROM arch_layer_deps").map((r) => ({
855
+ sourceLayer: r.source_layer,
856
+ targetLayer: r.target_layer,
857
+ depCount: r.dep_count
858
+ }));
859
+ }
860
+ getArchCoupling() {
861
+ return this.db.all("SELECT * FROM arch_coupling").map((r) => ({
862
+ packageId: r.package_id,
863
+ afferent: r.afferent,
864
+ efferent: r.efferent,
865
+ instability: r.instability,
866
+ updatedAt: r.updated_at
867
+ }));
868
+ }
869
+ getArchStats() {
870
+ return {
871
+ packages: this.db.get("SELECT COUNT(*) as c FROM arch_packages")?.c ?? 0,
872
+ layers: this.db.get("SELECT COUNT(*) as c FROM arch_layers")?.c ?? 0,
873
+ packageDeps: this.db.get("SELECT COUNT(*) as c FROM arch_package_deps")?.c ?? 0
874
+ };
875
+ }
876
+ /**
877
+ * Return file-to-file import relationships by joining edges + nodes.
878
+ * Used by ArchitectureAnalyzer to roll up package-level dependencies.
879
+ */
880
+ getFileImportPairs() {
881
+ return this.db.all(
882
+ `SELECT DISTINCT n1.file_path as source_file, n2.file_path as target_file
883
+ FROM edges e
884
+ JOIN nodes n1 ON n1.id = e.source
885
+ JOIN nodes n2 ON n2.id = e.target
886
+ WHERE e.kind = 'imports' AND n1.file_path != n2.file_path`
887
+ ).map((r) => ({ sourceFile: r.source_file, targetFile: r.target_file }));
888
+ }
889
+ getArchFilePackages() {
890
+ return this.db.all("SELECT file_path, package_id FROM arch_file_packages").map((r) => ({ filePath: r.file_path, packageId: r.package_id }));
891
+ }
892
+ getArchFileLayers() {
893
+ return this.db.all("SELECT file_path, layer_id, confidence, matched_pattern FROM arch_file_layers").map((r) => ({
894
+ filePath: r.file_path,
895
+ layerId: r.layer_id,
896
+ confidence: r.confidence,
897
+ matchedPattern: r.matched_pattern
898
+ }));
899
+ }
900
+ getArchitectureResult() {
901
+ return {
902
+ packages: this.getArchPackages(),
903
+ layers: this.getArchLayers(),
904
+ packageDeps: this.getArchPackageDeps(),
905
+ layerDeps: this.getArchLayerDeps(),
906
+ coupling: this.getArchCoupling()
907
+ };
908
+ }
909
+ // ── Transactions ──────────────────────────────────────────────────────────
910
+ transaction(fn) {
911
+ this.db.run("BEGIN");
912
+ try {
913
+ const result = fn();
914
+ this.db.run("COMMIT");
915
+ return result;
916
+ } catch (err) {
917
+ this.db.run("ROLLBACK");
918
+ throw err;
919
+ }
920
+ }
921
+ close() {
922
+ this.db.close();
923
+ }
924
+ }
925
+ // Annotate the CommonJS export names for ESM import in node:
926
+ 0 && (module.exports = {
927
+ GraphDatabase
928
+ });
929
+ //# sourceMappingURL=database.js.map