seer-mcp 0.1.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 (371) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/LICENSE +176 -0
  3. package/README.md +272 -0
  4. package/README_dev.md +199 -0
  5. package/dist/bundle/ci.d.ts +47 -0
  6. package/dist/bundle/ci.d.ts.map +1 -0
  7. package/dist/bundle/ci.js +113 -0
  8. package/dist/bundle/ci.js.map +1 -0
  9. package/dist/bundle/contract.d.ts +111 -0
  10. package/dist/bundle/contract.d.ts.map +1 -0
  11. package/dist/bundle/contract.js +352 -0
  12. package/dist/bundle/contract.js.map +1 -0
  13. package/dist/bundle/export.d.ts +36 -0
  14. package/dist/bundle/export.d.ts.map +1 -0
  15. package/dist/bundle/export.js +152 -0
  16. package/dist/bundle/export.js.map +1 -0
  17. package/dist/bundle/external.d.ts +66 -0
  18. package/dist/bundle/external.d.ts.map +1 -0
  19. package/dist/bundle/external.js +238 -0
  20. package/dist/bundle/external.js.map +1 -0
  21. package/dist/bundle/format.d.ts +94 -0
  22. package/dist/bundle/format.d.ts.map +1 -0
  23. package/dist/bundle/format.js +42 -0
  24. package/dist/bundle/format.js.map +1 -0
  25. package/dist/bundle/import.d.ts +49 -0
  26. package/dist/bundle/import.d.ts.map +1 -0
  27. package/dist/bundle/import.js +116 -0
  28. package/dist/bundle/import.js.map +1 -0
  29. package/dist/cli/index.d.ts +3 -0
  30. package/dist/cli/index.d.ts.map +1 -0
  31. package/dist/cli/index.js +1402 -0
  32. package/dist/cli/index.js.map +1 -0
  33. package/dist/cli/init.d.ts +48 -0
  34. package/dist/cli/init.d.ts.map +1 -0
  35. package/dist/cli/init.js +284 -0
  36. package/dist/cli/init.js.map +1 -0
  37. package/dist/db/schema.d.ts +3 -0
  38. package/dist/db/schema.d.ts.map +1 -0
  39. package/dist/db/schema.js +616 -0
  40. package/dist/db/schema.js.map +1 -0
  41. package/dist/db/store.d.ts +1011 -0
  42. package/dist/db/store.d.ts.map +1 -0
  43. package/dist/db/store.js +3888 -0
  44. package/dist/db/store.js.map +1 -0
  45. package/dist/graph/pagerank.d.ts +9 -0
  46. package/dist/graph/pagerank.d.ts.map +1 -0
  47. package/dist/graph/pagerank.js +47 -0
  48. package/dist/graph/pagerank.js.map +1 -0
  49. package/dist/indexer/architecture.d.ts +72 -0
  50. package/dist/indexer/architecture.d.ts.map +1 -0
  51. package/dist/indexer/architecture.js +112 -0
  52. package/dist/indexer/architecture.js.map +1 -0
  53. package/dist/indexer/behavior.d.ts +75 -0
  54. package/dist/indexer/behavior.d.ts.map +1 -0
  55. package/dist/indexer/behavior.js +395 -0
  56. package/dist/indexer/behavior.js.map +1 -0
  57. package/dist/indexer/boundaries.d.ts +60 -0
  58. package/dist/indexer/boundaries.d.ts.map +1 -0
  59. package/dist/indexer/boundaries.js +366 -0
  60. package/dist/indexer/boundaries.js.map +1 -0
  61. package/dist/indexer/churn.d.ts +15 -0
  62. package/dist/indexer/churn.d.ts.map +1 -0
  63. package/dist/indexer/churn.js +49 -0
  64. package/dist/indexer/churn.js.map +1 -0
  65. package/dist/indexer/classify.d.ts +9 -0
  66. package/dist/indexer/classify.d.ts.map +1 -0
  67. package/dist/indexer/classify.js +90 -0
  68. package/dist/indexer/classify.js.map +1 -0
  69. package/dist/indexer/context.d.ts +176 -0
  70. package/dist/indexer/context.d.ts.map +1 -0
  71. package/dist/indexer/context.js +193 -0
  72. package/dist/indexer/context.js.map +1 -0
  73. package/dist/indexer/continuity.d.ts +67 -0
  74. package/dist/indexer/continuity.d.ts.map +1 -0
  75. package/dist/indexer/continuity.js +288 -0
  76. package/dist/indexer/continuity.js.map +1 -0
  77. package/dist/indexer/detectchanges.d.ts +32 -0
  78. package/dist/indexer/detectchanges.d.ts.map +1 -0
  79. package/dist/indexer/detectchanges.js +74 -0
  80. package/dist/indexer/detectchanges.js.map +1 -0
  81. package/dist/indexer/discovery.d.ts +37 -0
  82. package/dist/indexer/discovery.d.ts.map +1 -0
  83. package/dist/indexer/discovery.js +136 -0
  84. package/dist/indexer/discovery.js.map +1 -0
  85. package/dist/indexer/externaldeps.d.ts +18 -0
  86. package/dist/indexer/externaldeps.d.ts.map +1 -0
  87. package/dist/indexer/externaldeps.js +288 -0
  88. package/dist/indexer/externaldeps.js.map +1 -0
  89. package/dist/indexer/freshness.d.ts +48 -0
  90. package/dist/indexer/freshness.d.ts.map +1 -0
  91. package/dist/indexer/freshness.js +128 -0
  92. package/dist/indexer/freshness.js.map +1 -0
  93. package/dist/indexer/git.d.ts +144 -0
  94. package/dist/indexer/git.d.ts.map +1 -0
  95. package/dist/indexer/git.js +444 -0
  96. package/dist/indexer/git.js.map +1 -0
  97. package/dist/indexer/index.d.ts +145 -0
  98. package/dist/indexer/index.d.ts.map +1 -0
  99. package/dist/indexer/index.js +930 -0
  100. package/dist/indexer/index.js.map +1 -0
  101. package/dist/indexer/modules.d.ts +62 -0
  102. package/dist/indexer/modules.d.ts.map +1 -0
  103. package/dist/indexer/modules.js +293 -0
  104. package/dist/indexer/modules.js.map +1 -0
  105. package/dist/indexer/preflight.d.ts +154 -0
  106. package/dist/indexer/preflight.d.ts.map +1 -0
  107. package/dist/indexer/preflight.js +399 -0
  108. package/dist/indexer/preflight.js.map +1 -0
  109. package/dist/indexer/protoScanner.d.ts +34 -0
  110. package/dist/indexer/protoScanner.d.ts.map +1 -0
  111. package/dist/indexer/protoScanner.js +133 -0
  112. package/dist/indexer/protoScanner.js.map +1 -0
  113. package/dist/indexer/risk.d.ts +115 -0
  114. package/dist/indexer/risk.d.ts.map +1 -0
  115. package/dist/indexer/risk.js +194 -0
  116. package/dist/indexer/risk.js.map +1 -0
  117. package/dist/indexer/serviceHostScanner.d.ts +25 -0
  118. package/dist/indexer/serviceHostScanner.d.ts.map +1 -0
  119. package/dist/indexer/serviceHostScanner.js +95 -0
  120. package/dist/indexer/serviceHostScanner.js.map +1 -0
  121. package/dist/indexer/serviceLinks.d.ts +105 -0
  122. package/dist/indexer/serviceLinks.d.ts.map +1 -0
  123. package/dist/indexer/serviceLinks.js +509 -0
  124. package/dist/indexer/serviceLinks.js.map +1 -0
  125. package/dist/indexer/shapehash.d.ts +98 -0
  126. package/dist/indexer/shapehash.d.ts.map +1 -0
  127. package/dist/indexer/shapehash.js +354 -0
  128. package/dist/indexer/shapehash.js.map +1 -0
  129. package/dist/indexer/skeleton.d.ts +15 -0
  130. package/dist/indexer/skeleton.d.ts.map +1 -0
  131. package/dist/indexer/skeleton.js +136 -0
  132. package/dist/indexer/skeleton.js.map +1 -0
  133. package/dist/indexer/symbolhistory.d.ts +41 -0
  134. package/dist/indexer/symbolhistory.d.ts.map +1 -0
  135. package/dist/indexer/symbolhistory.js +124 -0
  136. package/dist/indexer/symbolhistory.js.map +1 -0
  137. package/dist/indexer/watcher.d.ts +68 -0
  138. package/dist/indexer/watcher.d.ts.map +1 -0
  139. package/dist/indexer/watcher.js +179 -0
  140. package/dist/indexer/watcher.js.map +1 -0
  141. package/dist/mcp/server.d.ts +80 -0
  142. package/dist/mcp/server.d.ts.map +1 -0
  143. package/dist/mcp/server.js +1610 -0
  144. package/dist/mcp/server.js.map +1 -0
  145. package/dist/parser/index.d.ts +8 -0
  146. package/dist/parser/index.d.ts.map +1 -0
  147. package/dist/parser/index.js +33 -0
  148. package/dist/parser/index.js.map +1 -0
  149. package/dist/parser/languages/cpp.d.ts +3 -0
  150. package/dist/parser/languages/cpp.d.ts.map +1 -0
  151. package/dist/parser/languages/cpp.js +350 -0
  152. package/dist/parser/languages/cpp.js.map +1 -0
  153. package/dist/parser/languages/csharp.d.ts +3 -0
  154. package/dist/parser/languages/csharp.d.ts.map +1 -0
  155. package/dist/parser/languages/csharp.js +239 -0
  156. package/dist/parser/languages/csharp.js.map +1 -0
  157. package/dist/parser/languages/go.d.ts +3 -0
  158. package/dist/parser/languages/go.d.ts.map +1 -0
  159. package/dist/parser/languages/go.js +259 -0
  160. package/dist/parser/languages/go.js.map +1 -0
  161. package/dist/parser/languages/java.d.ts +3 -0
  162. package/dist/parser/languages/java.d.ts.map +1 -0
  163. package/dist/parser/languages/java.js +391 -0
  164. package/dist/parser/languages/java.js.map +1 -0
  165. package/dist/parser/languages/python.d.ts +3 -0
  166. package/dist/parser/languages/python.d.ts.map +1 -0
  167. package/dist/parser/languages/python.js +396 -0
  168. package/dist/parser/languages/python.js.map +1 -0
  169. package/dist/parser/languages/rust.d.ts +3 -0
  170. package/dist/parser/languages/rust.d.ts.map +1 -0
  171. package/dist/parser/languages/rust.js +159 -0
  172. package/dist/parser/languages/rust.js.map +1 -0
  173. package/dist/parser/languages/typescript.d.ts +3 -0
  174. package/dist/parser/languages/typescript.d.ts.map +1 -0
  175. package/dist/parser/languages/typescript.js +1442 -0
  176. package/dist/parser/languages/typescript.js.map +1 -0
  177. package/dist/parser/parserContext.d.ts +77 -0
  178. package/dist/parser/parserContext.d.ts.map +1 -0
  179. package/dist/parser/parserContext.js +354 -0
  180. package/dist/parser/parserContext.js.map +1 -0
  181. package/dist/parser/walker.d.ts +81 -0
  182. package/dist/parser/walker.d.ts.map +1 -0
  183. package/dist/parser/walker.js +217 -0
  184. package/dist/parser/walker.js.map +1 -0
  185. package/dist/parser/worker.d.ts +66 -0
  186. package/dist/parser/worker.d.ts.map +1 -0
  187. package/dist/parser/worker.js +129 -0
  188. package/dist/parser/worker.js.map +1 -0
  189. package/dist/parser/workerpool.d.ts +107 -0
  190. package/dist/parser/workerpool.d.ts.map +1 -0
  191. package/dist/parser/workerpool.js +383 -0
  192. package/dist/parser/workerpool.js.map +1 -0
  193. package/dist/scip/format.d.ts +87 -0
  194. package/dist/scip/format.d.ts.map +1 -0
  195. package/dist/scip/format.js +31 -0
  196. package/dist/scip/format.js.map +1 -0
  197. package/dist/scip/import.d.ts +37 -0
  198. package/dist/scip/import.d.ts.map +1 -0
  199. package/dist/scip/import.js +180 -0
  200. package/dist/scip/import.js.map +1 -0
  201. package/dist/types.d.ts +392 -0
  202. package/dist/types.d.ts.map +1 -0
  203. package/dist/types.js +4 -0
  204. package/dist/types.js.map +1 -0
  205. package/docs/architecture.md +105 -0
  206. package/docs/benchmarks/methodology.md +134 -0
  207. package/docs/benchmarks/raw-results.md +71 -0
  208. package/docs/benchmarks.md +74 -0
  209. package/docs/cli.md +148 -0
  210. package/docs/examples/behavior-tests.md +70 -0
  211. package/docs/examples/change-history.md +85 -0
  212. package/docs/examples/pre-edit-context.md +81 -0
  213. package/docs/examples/service-links.md +88 -0
  214. package/docs/examples.md +80 -0
  215. package/docs/faq.md +70 -0
  216. package/docs/internals.md +104 -0
  217. package/docs/languages.md +70 -0
  218. package/docs/limits.md +52 -0
  219. package/docs/mcp.md +199 -0
  220. package/docs/quickstart.md +119 -0
  221. package/docs/testing.md +123 -0
  222. package/docs/tools.md +115 -0
  223. package/package.json +52 -0
  224. package/research-codebase.md +578 -0
  225. package/seer-cli-docs.md +326 -0
  226. package/seer-master-guide.md +246 -0
  227. package/src/bundle/ci.ts +141 -0
  228. package/src/bundle/contract.ts +387 -0
  229. package/src/bundle/export.ts +175 -0
  230. package/src/bundle/external.ts +285 -0
  231. package/src/bundle/format.ts +92 -0
  232. package/src/bundle/import.ts +157 -0
  233. package/src/cli/index.ts +1249 -0
  234. package/src/cli/init.ts +389 -0
  235. package/src/db/schema.ts +614 -0
  236. package/src/db/store.ts +4306 -0
  237. package/src/graph/pagerank.ts +53 -0
  238. package/src/indexer/architecture.ts +148 -0
  239. package/src/indexer/behavior.ts +466 -0
  240. package/src/indexer/boundaries.ts +374 -0
  241. package/src/indexer/churn.ts +58 -0
  242. package/src/indexer/classify.ts +96 -0
  243. package/src/indexer/context.ts +340 -0
  244. package/src/indexer/continuity.ts +322 -0
  245. package/src/indexer/detectchanges.ts +94 -0
  246. package/src/indexer/discovery.ts +176 -0
  247. package/src/indexer/externaldeps.ts +243 -0
  248. package/src/indexer/freshness.ts +166 -0
  249. package/src/indexer/git.ts +453 -0
  250. package/src/indexer/index.ts +1092 -0
  251. package/src/indexer/modules.ts +358 -0
  252. package/src/indexer/preflight.ts +548 -0
  253. package/src/indexer/protoScanner.ts +147 -0
  254. package/src/indexer/risk.ts +304 -0
  255. package/src/indexer/serviceHostScanner.ts +92 -0
  256. package/src/indexer/serviceLinks.ts +543 -0
  257. package/src/indexer/shapehash.ts +370 -0
  258. package/src/indexer/skeleton.ts +169 -0
  259. package/src/indexer/symbolhistory.ts +172 -0
  260. package/src/indexer/watcher.ts +206 -0
  261. package/src/mcp/server.ts +1659 -0
  262. package/src/parser/index.ts +37 -0
  263. package/src/parser/languages/cpp.ts +361 -0
  264. package/src/parser/languages/csharp.ts +235 -0
  265. package/src/parser/languages/go.ts +259 -0
  266. package/src/parser/languages/java.ts +382 -0
  267. package/src/parser/languages/python.ts +370 -0
  268. package/src/parser/languages/rust.ts +164 -0
  269. package/src/parser/languages/typescript.ts +1435 -0
  270. package/src/parser/parserContext.ts +392 -0
  271. package/src/parser/walker.ts +306 -0
  272. package/src/parser/worker.ts +181 -0
  273. package/src/parser/workerpool.ts +448 -0
  274. package/src/scip/format.ts +83 -0
  275. package/src/scip/import.ts +216 -0
  276. package/src/types.ts +457 -0
  277. package/tests/benchmark-service-links.ts +244 -0
  278. package/tests/bug-regressions.ts +626 -0
  279. package/tests/filters.ts +264 -0
  280. package/tests/fixtures/Counter.tsx +38 -0
  281. package/tests/fixtures/caller.ts +7 -0
  282. package/tests/fixtures/collisions.ts +23 -0
  283. package/tests/fixtures/local_helper.ts +5 -0
  284. package/tests/fixtures/overloads.java +17 -0
  285. package/tests/fixtures/remote_helper.ts +4 -0
  286. package/tests/fixtures/sample.c +15 -0
  287. package/tests/fixtures/sample.cpp +47 -0
  288. package/tests/fixtures/sample.cs +62 -0
  289. package/tests/fixtures/sample.go +68 -0
  290. package/tests/fixtures/sample.h +30 -0
  291. package/tests/fixtures/sample.java +85 -0
  292. package/tests/fixtures/sample.py +46 -0
  293. package/tests/fixtures/sample.rs +78 -0
  294. package/tests/fixtures/sample.ts +76 -0
  295. package/tests/fixtures-service/HttpClients.cs +30 -0
  296. package/tests/fixtures-service/HttpClients.java +24 -0
  297. package/tests/fixtures-service/billing.ts +15 -0
  298. package/tests/fixtures-service/docker-compose.yml +15 -0
  299. package/tests/fixtures-service/gateway.ts +10 -0
  300. package/tests/fixtures-service/get_user.ts +11 -0
  301. package/tests/fixtures-service/graphql_client.ts +63 -0
  302. package/tests/fixtures-service/graphql_server.ts +30 -0
  303. package/tests/fixtures-service/grpc_client.go +30 -0
  304. package/tests/fixtures-service/http_clients.go +23 -0
  305. package/tests/fixtures-service/http_clients.py +38 -0
  306. package/tests/fixtures-service/http_clients.ts +49 -0
  307. package/tests/fixtures-service/k8s/payment-service.yaml +22 -0
  308. package/tests/fixtures-service/k8s_calls.ts +20 -0
  309. package/tests/fixtures-service/messaging.ts +87 -0
  310. package/tests/fixtures-service/trpc_client.ts +39 -0
  311. package/tests/fixtures-service/trpc_server.ts +39 -0
  312. package/tests/fixtures-service/user_service.proto +33 -0
  313. package/tests/fixtures-trackcd/Cargo.toml +11 -0
  314. package/tests/fixtures-trackcd/SpringController.java +36 -0
  315. package/tests/fixtures-trackcd/auth_service.ts +19 -0
  316. package/tests/fixtures-trackcd/complex_module.py +50 -0
  317. package/tests/fixtures-trackcd/express_app.js +30 -0
  318. package/tests/fixtures-trackcd/fastapi_app.py +49 -0
  319. package/tests/fixtures-trackcd/fastify_object_routes.js +32 -0
  320. package/tests/fixtures-trackcd/go.mod +8 -0
  321. package/tests/fixtures-trackcd/package.json +15 -0
  322. package/tests/fixtures-trackcd/requirements.txt +4 -0
  323. package/tests/fixtures-trackcd/tests/auth_service.test.ts +13 -0
  324. package/tests/fixtures-tracke/auth/AuthService.ts +23 -0
  325. package/tests/fixtures-tracke/auth/crypto.ts +7 -0
  326. package/tests/fixtures-tracke/billing/Billing.ts +20 -0
  327. package/tests/fixtures-tracke/billing/Invoice.ts +10 -0
  328. package/tests/fixtures-tracke/billing/server.ts +17 -0
  329. package/tests/fixtures-tracke/package.json +7 -0
  330. package/tests/fixtures-tracke/tests/auth.test.ts +23 -0
  331. package/tests/fixtures-tracke/tests/billing.test.ts +14 -0
  332. package/tests/fixtures-trackf/package.json +5 -0
  333. package/tests/fixtures-trackf/src/auth.ts +26 -0
  334. package/tests/fixtures-trackf/src/handlers.ts +35 -0
  335. package/tests/fixtures-tracki/billing/routes.ts +12 -0
  336. package/tests/fixtures-tracki/gateway/client.ts +13 -0
  337. package/tests/git-features.ts +267 -0
  338. package/tests/init.ts +141 -0
  339. package/tests/mcp-jit.ts +130 -0
  340. package/tests/mcp-smoke.ts +191 -0
  341. package/tests/mcp-trackcd.ts +169 -0
  342. package/tests/mcp-tracke.ts +229 -0
  343. package/tests/mcp-trackf.ts +330 -0
  344. package/tests/mcp-trackg.ts +219 -0
  345. package/tests/mcp-tracki.ts +174 -0
  346. package/tests/mcp-watcher.ts +126 -0
  347. package/tests/optspec.ts +194 -0
  348. package/tests/parallel-index.ts +333 -0
  349. package/tests/parallel-read.ts +125 -0
  350. package/tests/parallel-recovery.ts +241 -0
  351. package/tests/perf-callers.ts +145 -0
  352. package/tests/query-parity.ts +184 -0
  353. package/tests/query-perf.ts +55 -0
  354. package/tests/scale-parallel-parity.ts +225 -0
  355. package/tests/scale-test.ts +523 -0
  356. package/tests/smoke.ts +396 -0
  357. package/tests/trackcd.ts +325 -0
  358. package/tests/tracke-collisions.ts +255 -0
  359. package/tests/tracke.ts +314 -0
  360. package/tests/trackf-bugs.ts +406 -0
  361. package/tests/trackf.ts +390 -0
  362. package/tests/trackg.ts +1372 -0
  363. package/tests/tracki-boundaries.ts +202 -0
  364. package/tests/tracki-continuity.ts +253 -0
  365. package/tests/tracki-contract-diff.ts +249 -0
  366. package/tests/tracki-external-bundles.ts +341 -0
  367. package/tests/tracki-preflight.ts +251 -0
  368. package/tests/verify-roles.ts +51 -0
  369. package/tests/worker-parity.ts +286 -0
  370. package/tests/worker-pool.ts +262 -0
  371. package/tsconfig.json +20 -0
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.extractExternalDependencies = extractExternalDependencies;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const fast_glob_1 = __importDefault(require("fast-glob"));
10
+ /**
11
+ * Walk the repo for known package manifests and emit one row per declared
12
+ * dependency. Idempotent: clears `external_dependencies` and re-inserts every
13
+ * call, so deletions in package.json are reflected on the next index.
14
+ *
15
+ * Supported ecosystems:
16
+ * npm package.json / package-lock.json / pnpm-lock.yaml (deps only)
17
+ * cargo Cargo.toml (Cargo.lock not parsed — duplicates would be noisy)
18
+ * pypi requirements.txt, pyproject.toml (PEP 621 [project.dependencies])
19
+ * go go.mod
20
+ *
21
+ * Manifest discovery uses fast-glob with the same ignores as the rest of the
22
+ * indexer (no node_modules, no vendor) so monorepos can be picked up from
23
+ * `packages/foo/package.json`.
24
+ */
25
+ async function extractExternalDependencies(repoRoot, store) {
26
+ const abs = path_1.default.resolve(repoRoot);
27
+ const manifestPatterns = [
28
+ 'package.json',
29
+ '**/package.json',
30
+ 'Cargo.toml',
31
+ '**/Cargo.toml',
32
+ 'pyproject.toml',
33
+ '**/pyproject.toml',
34
+ 'requirements*.txt',
35
+ '**/requirements*.txt',
36
+ 'go.mod',
37
+ '**/go.mod',
38
+ ];
39
+ const ignored = [
40
+ 'node_modules/**', '**/node_modules/**',
41
+ 'vendor/**', '**/vendor/**', 'vendored/**', '**/vendored/**',
42
+ 'third_party/**', '**/third_party/**', 'thirdparty/**', '**/thirdparty/**',
43
+ 'target/**', '**/target/**',
44
+ 'dist/**', '**/dist/**',
45
+ '.git/**',
46
+ ];
47
+ const matches = await (0, fast_glob_1.default)(manifestPatterns, {
48
+ cwd: abs, ignore: ignored, onlyFiles: true, followSymbolicLinks: false, dot: false,
49
+ unique: true,
50
+ });
51
+ store.clearExternalDeps();
52
+ let inserted = 0;
53
+ for (const rel of matches) {
54
+ const filePath = path_1.default.join(abs, rel);
55
+ let content;
56
+ try {
57
+ content = fs_1.default.readFileSync(filePath, 'utf8');
58
+ }
59
+ catch {
60
+ continue;
61
+ }
62
+ if (rel.endsWith('package.json') || rel === 'package.json') {
63
+ inserted += parsePackageJson(content, rel, store);
64
+ }
65
+ else if (rel.endsWith('Cargo.toml') || rel === 'Cargo.toml') {
66
+ inserted += parseCargoToml(content, rel, store);
67
+ }
68
+ else if (rel.endsWith('pyproject.toml') || rel === 'pyproject.toml') {
69
+ inserted += parsePyproject(content, rel, store);
70
+ }
71
+ else if (rel.endsWith('.txt')) {
72
+ inserted += parseRequirementsTxt(content, rel, store);
73
+ }
74
+ else if (rel.endsWith('go.mod') || rel === 'go.mod') {
75
+ inserted += parseGoMod(content, rel, store);
76
+ }
77
+ }
78
+ return inserted;
79
+ }
80
+ function parsePackageJson(content, manifestPath, store) {
81
+ let json;
82
+ try {
83
+ json = JSON.parse(content);
84
+ }
85
+ catch {
86
+ return 0;
87
+ }
88
+ if (!json || typeof json !== 'object')
89
+ return 0;
90
+ let count = 0;
91
+ const groups = [
92
+ [json.dependencies, 0],
93
+ [json.devDependencies, 1],
94
+ [json.peerDependencies, 0],
95
+ [json.optionalDependencies, 0],
96
+ ];
97
+ for (const [group, isDev] of groups) {
98
+ if (!group || typeof group !== 'object')
99
+ continue;
100
+ for (const [name, version] of Object.entries(group)) {
101
+ if (!name)
102
+ continue;
103
+ store.insertExternalDep('npm', name, typeof version === 'string' ? version : null, manifestPath, isDev);
104
+ count++;
105
+ }
106
+ }
107
+ return count;
108
+ }
109
+ function parseCargoToml(content, manifestPath, store) {
110
+ // Lightweight TOML parser for [dependencies] / [dev-dependencies] sections.
111
+ // We intentionally don't pull in a full TOML lib — Cargo manifests are
112
+ // well-formed enough that a section-aware line walk suffices.
113
+ let count = 0;
114
+ let section = '';
115
+ for (const rawLine of content.split('\n')) {
116
+ const line = rawLine.replace(/#.*$/, '').trim();
117
+ if (!line)
118
+ continue;
119
+ const sectionMatch = line.match(/^\[(.+?)\]$/);
120
+ if (sectionMatch) {
121
+ section = sectionMatch[1].trim();
122
+ continue;
123
+ }
124
+ const inDeps = section === 'dependencies' || section === 'dev-dependencies' || section === 'build-dependencies';
125
+ if (!inDeps)
126
+ continue;
127
+ const eq = line.indexOf('=');
128
+ if (eq < 0)
129
+ continue;
130
+ const name = line.slice(0, eq).trim();
131
+ const rest = line.slice(eq + 1).trim();
132
+ if (!name || /[\[{]/.test(name))
133
+ continue;
134
+ let version = null;
135
+ const strMatch = rest.match(/^"([^"]+)"/);
136
+ if (strMatch)
137
+ version = strMatch[1];
138
+ else {
139
+ const inlineVer = rest.match(/version\s*=\s*"([^"]+)"/);
140
+ if (inlineVer)
141
+ version = inlineVer[1];
142
+ }
143
+ const isDev = section === 'dev-dependencies' ? 1 : 0;
144
+ store.insertExternalDep('cargo', name, version, manifestPath, isDev);
145
+ count++;
146
+ }
147
+ return count;
148
+ }
149
+ function parsePyproject(content, manifestPath, store) {
150
+ // [project] dependencies / optional-dependencies — Poetry uses
151
+ // [tool.poetry.dependencies] in addition. We handle both.
152
+ let count = 0;
153
+ let section = '';
154
+ let inList = false;
155
+ let buf = [];
156
+ const flushList = (isDev) => {
157
+ for (const item of buf) {
158
+ const m = item.match(/^"([^"]+)"|^'([^']+)'/);
159
+ if (!m)
160
+ continue;
161
+ const spec = (m[1] ?? m[2] ?? '').trim();
162
+ if (!spec)
163
+ continue;
164
+ // Strip extras / version: "package[extras]>=1.2.3"
165
+ const nameMatch = spec.match(/^([A-Za-z0-9_.\-]+)/);
166
+ if (!nameMatch)
167
+ continue;
168
+ const name = nameMatch[1];
169
+ const versionMatch = spec.slice(nameMatch[0].length).match(/[<>=~!^].+/);
170
+ const version = versionMatch ? versionMatch[0].trim() : null;
171
+ store.insertExternalDep('pypi', name, version, manifestPath, isDev);
172
+ count++;
173
+ }
174
+ buf = [];
175
+ };
176
+ const lines = content.split('\n');
177
+ for (let i = 0; i < lines.length; i++) {
178
+ const raw = lines[i];
179
+ const line = raw.replace(/#.*$/, '').trim();
180
+ const sectionMatch = line.match(/^\[(.+?)\]$/);
181
+ if (sectionMatch) {
182
+ if (inList) {
183
+ flushList(section.includes('dev') ? 1 : 0);
184
+ inList = false;
185
+ }
186
+ section = sectionMatch[1].trim();
187
+ continue;
188
+ }
189
+ if (section === 'project' || section === 'tool.poetry.dependencies' || section === 'tool.poetry.dev-dependencies') {
190
+ // [project] dependencies = ["pkg>=1.0", ...]
191
+ if (section === 'project' && /^dependencies\s*=\s*\[/.test(line)) {
192
+ inList = true;
193
+ const after = line.replace(/^dependencies\s*=\s*\[/, '');
194
+ if (after.includes(']')) {
195
+ for (const item of after.replace(/\].*$/, '').split(','))
196
+ buf.push(item.trim());
197
+ flushList(0);
198
+ inList = false;
199
+ }
200
+ else {
201
+ buf.push(after);
202
+ }
203
+ continue;
204
+ }
205
+ if (inList) {
206
+ if (line.includes(']')) {
207
+ for (const item of line.replace(/\].*$/, '').split(','))
208
+ if (item.trim())
209
+ buf.push(item.trim());
210
+ flushList(0);
211
+ inList = false;
212
+ }
213
+ else {
214
+ for (const item of line.split(','))
215
+ if (item.trim())
216
+ buf.push(item.trim());
217
+ }
218
+ continue;
219
+ }
220
+ if (section.startsWith('tool.poetry') && /^[A-Za-z0-9_.\-]+\s*=/.test(line)) {
221
+ const eq = line.indexOf('=');
222
+ const name = line.slice(0, eq).trim();
223
+ const rest = line.slice(eq + 1).trim();
224
+ const verMatch = rest.match(/^"([^"]+)"/);
225
+ const version = verMatch ? verMatch[1] : null;
226
+ const isDev = section.includes('dev') ? 1 : 0;
227
+ store.insertExternalDep('pypi', name, version, manifestPath, isDev);
228
+ count++;
229
+ }
230
+ }
231
+ }
232
+ if (inList)
233
+ flushList(section.includes('dev') ? 1 : 0);
234
+ return count;
235
+ }
236
+ function parseRequirementsTxt(content, manifestPath, store) {
237
+ let count = 0;
238
+ const isDev = /dev|test/i.test(manifestPath) ? 1 : 0;
239
+ for (const raw of content.split('\n')) {
240
+ const line = raw.replace(/#.*$/, '').trim();
241
+ if (!line || line.startsWith('-'))
242
+ continue;
243
+ const m = line.match(/^([A-Za-z0-9_.\-]+)/);
244
+ if (!m)
245
+ continue;
246
+ const name = m[1];
247
+ const rest = line.slice(m[0].length);
248
+ const ver = rest.match(/[<>=~!^].+/);
249
+ store.insertExternalDep('pypi', name, ver ? ver[0].trim() : null, manifestPath, isDev);
250
+ count++;
251
+ }
252
+ return count;
253
+ }
254
+ function parseGoMod(content, manifestPath, store) {
255
+ let count = 0;
256
+ let inRequire = false;
257
+ for (const raw of content.split('\n')) {
258
+ const line = raw.replace(/\/\/.*$/, '').trim();
259
+ if (!line)
260
+ continue;
261
+ if (line.startsWith('require (')) {
262
+ inRequire = true;
263
+ continue;
264
+ }
265
+ if (line === ')') {
266
+ inRequire = false;
267
+ continue;
268
+ }
269
+ if (line.startsWith('require ')) {
270
+ // single-line: `require mod v1.2.3`
271
+ const parts = line.slice('require '.length).trim().split(/\s+/);
272
+ if (parts.length >= 2) {
273
+ store.insertExternalDep('go', parts[0], parts[1], manifestPath, 0);
274
+ count++;
275
+ }
276
+ continue;
277
+ }
278
+ if (inRequire) {
279
+ const parts = line.split(/\s+/);
280
+ if (parts.length >= 2 && !/^\/\//.test(parts[0])) {
281
+ store.insertExternalDep('go', parts[0], parts[1], manifestPath, 0);
282
+ count++;
283
+ }
284
+ }
285
+ }
286
+ return count;
287
+ }
288
+ //# sourceMappingURL=externaldeps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"externaldeps.js","sourceRoot":"","sources":["../../src/indexer/externaldeps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { Indexer } from './index.js';
2
+ import { Store } from '../db/store.js';
3
+ /**
4
+ * Quick freshness check + targeted re-index for MCP/CLI queries.
5
+ *
6
+ * Design contract: the watcher (when running) keeps the index warm by marking
7
+ * files dirty in the background. JIT sync runs before every query as the
8
+ * correctness layer — it does the actual reindex of dirty files so a query
9
+ * returning right now reflects the current workspace state.
10
+ *
11
+ * Implementation: discover the workspace, compare on-disk content hashes
12
+ * against what the DB says, and only reindex files whose hash changed.
13
+ * Unchanged files are skipped entirely; we don't touch the parser for them.
14
+ *
15
+ * The intentional bias here is correctness over latency: we re-discover the
16
+ * full workspace each time so newly-added or newly-renamed files are not
17
+ * missed. For very large repos this is still cheap (a glob + dir walk
18
+ * over 10-100k files is sub-second) compared to a single tree-sitter parse,
19
+ * and you only do it once per JIT call.
20
+ */
21
+ export interface FreshnessReport {
22
+ /** Files where the on-disk hash differed from the DB. Reindexed. */
23
+ dirtyReindexed: number;
24
+ /** Files that vanished from disk since the last index. Pruned. */
25
+ removed: number;
26
+ /** Files newly seen this run (not in the DB yet). Indexed. */
27
+ added: number;
28
+ /** Total wall time in ms. */
29
+ elapsedMs: number;
30
+ }
31
+ /**
32
+ * Inspect a workspace for changes since the last index, then reindex only
33
+ * the files that need it. Designed to run before every MCP query.
34
+ *
35
+ * @param store a writable Store (NOT readonly — we may need to mutate)
36
+ * @param indexer an Indexer over the same store
37
+ * @param repoRoot the workspace path used at index time
38
+ * @param options.maxDirty cap reindex work per call. When the dirty set is
39
+ * larger than this, we still run a full `indexer.indexDirectory()` because
40
+ * a partial JIT pass would leave the index inconsistent (resolveEdges
41
+ * needs the full graph). Defaults to 200 — small enough to keep the
42
+ * "type a few characters and ask" workflow snappy.
43
+ */
44
+ export declare function jitSync(store: Store, indexer: Indexer, repoRoot: string, options?: {
45
+ maxDirty?: number;
46
+ verbose?: boolean;
47
+ }): Promise<FreshnessReport>;
48
+ //# sourceMappingURL=freshness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freshness.d.ts","sourceRoot":"","sources":["../../src/indexer/freshness.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GACrD,OAAO,CAAC,eAAe,CAAC,CA2F1B"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.jitSync = jitSync;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const discovery_js_1 = require("./discovery.js");
11
+ /**
12
+ * Cheap content hash matching what the indexer uses internally. Kept here as
13
+ * a duplicate (not exported from indexer/index.ts) because the indexer's
14
+ * version is in the hot loop and we don't want to widen its export surface.
15
+ */
16
+ function sha256Short(content) {
17
+ return crypto_1.default.createHash('sha256').update(content, 'utf8').digest('hex').slice(0, 16);
18
+ }
19
+ /**
20
+ * Inspect a workspace for changes since the last index, then reindex only
21
+ * the files that need it. Designed to run before every MCP query.
22
+ *
23
+ * @param store a writable Store (NOT readonly — we may need to mutate)
24
+ * @param indexer an Indexer over the same store
25
+ * @param repoRoot the workspace path used at index time
26
+ * @param options.maxDirty cap reindex work per call. When the dirty set is
27
+ * larger than this, we still run a full `indexer.indexDirectory()` because
28
+ * a partial JIT pass would leave the index inconsistent (resolveEdges
29
+ * needs the full graph). Defaults to 200 — small enough to keep the
30
+ * "type a few characters and ask" workflow snappy.
31
+ */
32
+ async function jitSync(store, indexer, repoRoot, options = {}) {
33
+ const start = Date.now();
34
+ const maxDirty = options.maxDirty ?? 200;
35
+ const absRoot = path_1.default.resolve(repoRoot);
36
+ // 1. Snapshot what the DB knows.
37
+ const dbFiles = store.listFiles();
38
+ const dbByPath = new Map(dbFiles.map(f => [normalizeForCompare(f.path), f]));
39
+ // 2. Walk the workspace and find candidate files. discoverFiles() applies
40
+ // the same ignore rules the indexer uses, so freshness can't be
41
+ // misled by build artifacts or `vendor/` entries.
42
+ const discovered = await (0, discovery_js_1.discoverFiles)(absRoot);
43
+ const discoveredByPath = new Map();
44
+ for (const d of discovered) {
45
+ discoveredByPath.set(normalizeForCompare(d.absolutePath), d.relativePath);
46
+ }
47
+ // 3. Identify added / removed / candidate-dirty files.
48
+ const added = [];
49
+ const removed = [];
50
+ const candidateDirty = [];
51
+ for (const f of dbFiles) {
52
+ const key = normalizeForCompare(f.path);
53
+ if (!discoveredByPath.has(key)) {
54
+ removed.push(f.id);
55
+ continue;
56
+ }
57
+ candidateDirty.push(f);
58
+ }
59
+ for (const [key, _rel] of discoveredByPath) {
60
+ if (!dbByPath.has(key))
61
+ added.push(key);
62
+ }
63
+ // 4. Hash each candidate. Same trade-off as the indexer: read everything
64
+ // we'd parse anyway, but if the hash matches we never spend time on
65
+ // the parser. We stop early as soon as we cross `maxDirty` so a giant
66
+ // change like a git checkout falls back to a full reindex.
67
+ const dirty = [];
68
+ for (const f of candidateDirty) {
69
+ if (dirty.length + added.length >= maxDirty)
70
+ break;
71
+ let content;
72
+ try {
73
+ content = await fs_1.default.promises.readFile(f.path, 'utf8');
74
+ }
75
+ catch {
76
+ // File became unreadable mid-check (rename, permission flip). Treat
77
+ // as removed so the next pass cleans it up.
78
+ removed.push(f.id);
79
+ continue;
80
+ }
81
+ const hash = sha256Short(content);
82
+ if (hash !== f.hash)
83
+ dirty.push(f.path);
84
+ }
85
+ const fullReindexNeeded = dirty.length + added.length >= maxDirty || removed.length > 0;
86
+ if (dirty.length === 0 && added.length === 0 && removed.length === 0) {
87
+ return { dirtyReindexed: 0, removed: 0, added: 0, elapsedMs: Date.now() - start };
88
+ }
89
+ if (fullReindexNeeded) {
90
+ // Cheaper to invoke the full pipeline than to surgically remove files
91
+ // and reconcile edge graphs. The indexer's cache means unchanged files
92
+ // are still skipped at parse time, so this is O(dirty + added + |touched|)
93
+ // not O(|workspace|).
94
+ // JIT pins parallel:false. The dirty set is small (≤ maxDirty=200) and
95
+ // worker spawn cost dominates the wins at this scale; serial is the
96
+ // right default for the snappy "edit + ask" loop. MCP servers that want
97
+ // parallel JIT can override later via an option.
98
+ const result = await indexer.indexDirectory(absRoot, { quiet: !options.verbose, parallel: false });
99
+ return {
100
+ dirtyReindexed: dirty.length,
101
+ removed: removed.length,
102
+ added: added.length,
103
+ elapsedMs: Date.now() - start + (result.elapsedMs ?? 0),
104
+ };
105
+ }
106
+ // Targeted JIT path: dirty/added files only, no full re-discovery. Reuse
107
+ // the indexer's machinery by calling indexDirectory — its cache skips
108
+ // unchanged files. This is dominated by the discovery walk we already did,
109
+ // so the marginal cost is small.
110
+ await indexer.indexDirectory(absRoot, { quiet: !options.verbose, parallel: false });
111
+ return {
112
+ dirtyReindexed: dirty.length,
113
+ removed: removed.length,
114
+ added: added.length,
115
+ elapsedMs: Date.now() - start,
116
+ };
117
+ }
118
+ /**
119
+ * Normalize a path for comparison across the OS-specific quirks we hit on
120
+ * Windows. We index with backslashes; discovery resolves through `path.join`
121
+ * which also produces backslashes. Read-only callers might pass a slash-form
122
+ * path through the MCP layer; lowercase folds Windows case-insensitivity.
123
+ */
124
+ function normalizeForCompare(p) {
125
+ const norm = p.replace(/\\/g, '/');
126
+ return process.platform === 'win32' ? norm.toLowerCase() : norm;
127
+ }
128
+ //# sourceMappingURL=freshness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freshness.js","sourceRoot":"","sources":["../../src/indexer/freshness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Thin async wrapper around `git` so the rest of the indexer doesn't deal
3
+ * with child_process directly. All commands run with `cwd = repoRoot`.
4
+ *
5
+ * Errors are surfaced as `null` returns (not throws) so a non-git workspace
6
+ * silently no-ops. Callers should check the return value.
7
+ */
8
+ export declare function isGitRepo(repoRoot: string): boolean;
9
+ export declare function gitHeadSha(repoRoot: string): string | null;
10
+ export declare function gitRemoteUrl(repoRoot: string, remote?: string): string | null;
11
+ export interface FileChurnStats {
12
+ commitCount: number;
13
+ lastCommitSha: string | null;
14
+ lastCommitAt: number | null;
15
+ topAuthor: string | null;
16
+ secondAuthor: string | null;
17
+ }
18
+ /**
19
+ * Collect file-level churn stats by streaming `git log` once and bucketing
20
+ * per file. Uses `--follow` per-file would be ~slow on big repos, so we use
21
+ * a single `git log --name-only` pass and aggregate in JS. The trade-off is
22
+ * that renames lose their pre-rename history; callers documenting that fact
23
+ * matches the master guide's "honest about rename limits" stance.
24
+ */
25
+ export declare function collectFileChurn(repoRoot: string, filesAbs: Iterable<string>): Promise<Map<string, FileChurnStats>>;
26
+ export interface CommitMeta {
27
+ sha: string;
28
+ authorName: string | null;
29
+ authorEmail: string | null;
30
+ committedAt: number;
31
+ message: string;
32
+ /**
33
+ * The path the file had AT THIS COMMIT (forward-slash, repo-relative).
34
+ * Resolved from `git log --follow --name-status` so commits prior to a
35
+ * rename can still be looked up by the historical path. Null if the path
36
+ * couldn't be determined from log output (in which case callers should
37
+ * fall back to the current path).
38
+ */
39
+ pathAtCommit: string | null;
40
+ }
41
+ /**
42
+ * `git log` commits that touched a single file, newest first. Each commit
43
+ * includes its author info and full message. Used by the symbol-history pass.
44
+ *
45
+ * `--name-status` is added on top of `--follow` so we get a per-commit path —
46
+ * critical for the rename case: the historical commits touched the OLD path,
47
+ * but our usual `git show <sha> -- <currentPath>` would look at the wrong
48
+ * path and return empty hunks. With pathAtCommit threaded through to
49
+ * fileDiffInfo(), pre-rename history is preserved.
50
+ *
51
+ * Parser shape: we ask git for a per-commit header line prefixed `__C__`
52
+ * (sha, author, email, ISO date — all NUL-free fields tab-separated), then
53
+ * the commit body (terminated by a unique end marker `__BODY_END__`), then
54
+ * the name-status lines that git appends after each commit. The name-status
55
+ * block has one path entry per commit relative to this file's --follow chain:
56
+ * either `M\tpath`, `A\tpath`, `D\tpath`, or `R<score>\toldPath\tnewPath`.
57
+ *
58
+ * Using a custom body terminator (instead of git's default blank-line
59
+ * separator) lets us handle commit messages that themselves contain blank
60
+ * lines or `__C__` literals without re-introducing the old `__C__ff8` bug.
61
+ */
62
+ export declare function commitsForFile(repoRoot: string, filePath: string, options?: {
63
+ limit?: number;
64
+ since?: number;
65
+ }): Promise<CommitMeta[]>;
66
+ /**
67
+ * Walk the line stream from `git log --follow --name-status` (with the
68
+ * `__C__` header / `__BODY_END__` body terminator format above) and emit
69
+ * one CommitMeta per `__C__` header. Exposed only for tests; the live
70
+ * pipeline goes through commitsForFile().
71
+ */
72
+ export declare function parseFollowLog(buf: string): CommitMeta[];
73
+ export interface DiffHunk {
74
+ oldStart: number;
75
+ oldLines: number;
76
+ newStart: number;
77
+ newLines: number;
78
+ }
79
+ export interface FileDiffInfo {
80
+ hunks: DiffHunk[];
81
+ /**
82
+ * True when the commit created the file (or — symmetrically — deleted it).
83
+ * In that case the diff has `--- /dev/null` (added) or `+++ /dev/null`
84
+ * (deleted) and EVERY symbol currently in the file should be attributed,
85
+ * because the file's current shape didn't exist before.
86
+ */
87
+ isFileAddition: boolean;
88
+ }
89
+ /**
90
+ * Diff hunks for a file changed by a single commit. `git show -U0 <sha>`
91
+ * handles the root commit transparently (no parent → diff against the empty
92
+ * tree), so the caller doesn't need to pass parentSha. `parentSha` is kept
93
+ * for compatibility but ignored.
94
+ */
95
+ export declare function fileDiffHunks(repoRoot: string, _parentSha: string | null, sha: string, filePath: string): Promise<DiffHunk[]>;
96
+ /** Like fileDiffHunks but returns extra metadata used for "this commit
97
+ * created the file → match every symbol" heuristic.
98
+ *
99
+ * `filePath` may be either an absolute path or a repo-relative one. When the
100
+ * file was renamed across history, callers should pass the PATH-AT-COMMIT
101
+ * (resolved from `git log --follow --name-status`) so `git show` looks at
102
+ * the right side of the rename — passing the current path would return
103
+ * empty hunks for pre-rename commits and silently lose history.
104
+ */
105
+ export declare function fileDiffInfo(repoRoot: string, sha: string, filePath: string): Promise<FileDiffInfo>;
106
+ /**
107
+ * Diff numstat for one commit: returns added/removed line counts per file
108
+ * (or aggregated when filePath is given).
109
+ */
110
+ export declare function commitNumstat(repoRoot: string, sha: string, filePath?: string): Promise<{
111
+ added: number;
112
+ removed: number;
113
+ }>;
114
+ /**
115
+ * git diff name-only between two refs. Defaults to HEAD vs the working
116
+ * tree (uncommitted changes) — used by `detect_changes`. Returns absolute
117
+ * paths (after path.resolve(repoRoot, rel)).
118
+ */
119
+ export declare function gitChangedFiles(repoRoot: string, fromRef?: string, toRef?: string): string[];
120
+ /**
121
+ * git diff -U0 hunks for one file between two refs (or working tree if refs
122
+ * omitted). Returns parsed hunk headers (line ranges in the new file) so
123
+ * `detect_changes` can compute which symbols overlap.
124
+ */
125
+ export declare function fileDiffHunksSync(repoRoot: string, filePath: string, fromRef?: string, toRef?: string): DiffHunk[];
126
+ /**
127
+ * Extract GitHub-style PR numbers from a commit message. We accept the
128
+ * common conventions:
129
+ * "Merge pull request #1234 from ..."
130
+ * "Fix something (#1234)"
131
+ * "#1234"
132
+ * "PR #1234"
133
+ *
134
+ * Returns the first matched PR number, or null.
135
+ */
136
+ export declare function extractPrNumber(message: string): number | null;
137
+ /**
138
+ * If `remoteUrl` is a GitHub URL (HTTPS or SSH), return the matching
139
+ * `https://github.com/<owner>/<repo>/pull/<n>` URL for a PR number.
140
+ * Returns null for non-GitHub remotes so we don't fabricate links to
141
+ * GitLab/Bitbucket/etc.
142
+ */
143
+ export declare function githubPrUrl(remoteUrl: string | null, prNumber: number): string | null;
144
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/indexer/git.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM1D;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,MAAM,GAAG,IAAI,CAM/E;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAsFtC;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBvB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CAsDxD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB;;;;;OAKG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GACzE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAC9C,OAAO,CAAC,YAAY,CAAC,CA0BvB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAC/C,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB7C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAS5F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GACnE,QAAQ,EAAE,CAsBZ;AAOD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOrF"}