@backbencher/brain 0.0.0-stage → 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 (319) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/EMBEDDINGS.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +415 -2
  5. package/bin/bb +13 -0
  6. package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
  7. package/dist/brain-index-health-KY7K552E.js +17 -0
  8. package/dist/brain-relationship-enrichment-QH7OOHUF.js +558 -0
  9. package/dist/brain.sql-EIM4WS4D.js +29 -0
  10. package/dist/chunk-2BSKD7O3.js +40 -0
  11. package/dist/chunk-2DE27DVC.js +1314 -0
  12. package/dist/chunk-2RRBMNBQ.js +322 -0
  13. package/dist/chunk-2RTN2DFU.js +711 -0
  14. package/dist/chunk-2WXYNLBA.js +29 -0
  15. package/dist/chunk-3CTFIJJB.js +17 -0
  16. package/dist/chunk-3LFTSMIV.js +174 -0
  17. package/dist/chunk-47HKX4AJ.js +930 -0
  18. package/dist/chunk-4H22TLOT.js +543 -0
  19. package/dist/chunk-5SD45FLC.js +818 -0
  20. package/dist/chunk-66A5ZFYA.js +1758 -0
  21. package/dist/chunk-6AIRWAO2.js +247 -0
  22. package/dist/chunk-6WNGD3NN.js +196 -0
  23. package/dist/chunk-7AN7U5IZ.js +371 -0
  24. package/dist/chunk-BHB7BYYI.js +626 -0
  25. package/dist/chunk-BQ3OVQ3P.js +125 -0
  26. package/dist/chunk-CW4XXSNN.js +1479 -0
  27. package/dist/chunk-D2Q4Y47A.js +53 -0
  28. package/dist/chunk-DIYAGQJL.js +34 -0
  29. package/dist/chunk-DYM4FQEE.js +90 -0
  30. package/dist/chunk-EWMWK7WN.js +75 -0
  31. package/dist/chunk-FVVQTSIM.js +3427 -0
  32. package/dist/chunk-FWSL4VG6.js +1290 -0
  33. package/dist/chunk-GBI7V7KY.js +69 -0
  34. package/dist/chunk-GEFFO6O2.js +152 -0
  35. package/dist/chunk-HOWAQXJO.js +236 -0
  36. package/dist/chunk-HQSPJDHI.js +613 -0
  37. package/dist/chunk-IFZNR5UJ.js +2863 -0
  38. package/dist/chunk-J4PMBXQQ.js +336 -0
  39. package/dist/chunk-KAET47ZL.js +125 -0
  40. package/dist/chunk-KCDECRJY.js +440 -0
  41. package/dist/chunk-KLK3PBTO.js +1119 -0
  42. package/dist/chunk-L5TDYKYK.js +76 -0
  43. package/dist/chunk-MLKGABMK.js +9 -0
  44. package/dist/chunk-OWISBAOF.js +61 -0
  45. package/dist/chunk-PJTNGD3Z.js +6924 -0
  46. package/dist/chunk-QLK6ED4Q.js +235 -0
  47. package/dist/chunk-R2GW4F6R.js +19 -0
  48. package/dist/chunk-RCMTFSEF.js +87 -0
  49. package/dist/chunk-RH7KC5HU.js +12050 -0
  50. package/dist/chunk-RM3PY6TG.js +376 -0
  51. package/dist/chunk-ROMM6KMC.js +433 -0
  52. package/dist/chunk-SK6YVHFZ.js +211 -0
  53. package/dist/chunk-SM7RFQRO.js +214 -0
  54. package/dist/chunk-UFE77L67.js +782 -0
  55. package/dist/chunk-UGR4QIGS.js +67 -0
  56. package/dist/chunk-UUNHHX4M.js +13 -0
  57. package/dist/chunk-V44PGPA6.js +2104 -0
  58. package/dist/chunk-VL52PL2T.js +71 -0
  59. package/dist/chunk-VURYFIHW.js +201 -0
  60. package/dist/chunk-XJKJYIPP.js +7436 -0
  61. package/dist/chunk-YI6FF2ZR.js +340 -0
  62. package/dist/cli/index.js +37 -0
  63. package/dist/config-HZAAYDP3.js +10 -0
  64. package/dist/content-search-642F7E5V.js +593 -0
  65. package/dist/database-TCTZDLE5.js +9 -0
  66. package/dist/doctor-GXCKSJOX.js +395 -0
  67. package/dist/edit-engine-KM7MPFEC.js +51 -0
  68. package/dist/engine-42TZFNIZ.js +11 -0
  69. package/dist/engine-LO6L4JLQ.js +18 -0
  70. package/dist/fingerprint-XDXFRWO6.js +33 -0
  71. package/dist/framework-intelligence-DWFCKV44.js +860 -0
  72. package/dist/freshness-3K6VU5OT.js +174 -0
  73. package/dist/graph-engine-PL5YA7BA.js +21 -0
  74. package/dist/graph_request-MM4REP6H.js +350 -0
  75. package/dist/impact_request-WDE47IZ5.js +68 -0
  76. package/dist/index-space-IUUN5WYV.js +15 -0
  77. package/dist/index-status-6BD7UBHR.js +34 -0
  78. package/dist/index.js +159 -0
  79. package/dist/instance-FO6QZRLH.js +19 -0
  80. package/dist/language-detection-DFCAU5DZ.js +11 -0
  81. package/dist/lsp/server.js +4301 -0
  82. package/dist/mcp/server.js +132 -0
  83. package/dist/onboard-DIQZV2NW.js +161 -0
  84. package/dist/override-companion-pass-XR7MHTP7.js +117 -0
  85. package/dist/parallel-indexer-4PW3AFXP.js +88 -0
  86. package/dist/pool-worker.js +1153 -0
  87. package/dist/project-health-ZS5TS2Z6.js +94 -0
  88. package/dist/project-index-5SDPHITE.js +57 -0
  89. package/dist/project-registry-DGZBIZS7.js +355 -0
  90. package/dist/real-bash-analyzer-SXSV67E2.js +2201 -0
  91. package/dist/real-c-analyzer-SY7FTZ6W.js +5942 -0
  92. package/dist/real-clean-analyzer-IGDHHLZK.js +3470 -0
  93. package/dist/real-clojure-analyzer-4OH7IWLB.js +2818 -0
  94. package/dist/real-cpp-analyzer-7LTDRJRJ.js +4101 -0
  95. package/dist/real-csharp-analyzer-KICU3TLH.js +3298 -0
  96. package/dist/real-css-analyzer-HPU277Q6.js +15 -0
  97. package/dist/real-dart-analyzer-7LZ5LCMW.js +3944 -0
  98. package/dist/real-elixir-analyzer-BE3MEVZO.js +2192 -0
  99. package/dist/real-erlang-analyzer-BZMAKYBK.js +1731 -0
  100. package/dist/real-fsharp-analyzer-5QLTOV3E.js +2390 -0
  101. package/dist/real-go-analyzer-POD7MZQR.js +4126 -0
  102. package/dist/real-graphql-analyzer-MAQRZ6QW.js +1442 -0
  103. package/dist/real-groovy-analyzer-MEWSUPMJ.js +2285 -0
  104. package/dist/real-haskell-analyzer-I5L2GR3Y.js +2533 -0
  105. package/dist/real-hcl-analyzer-DBOPXSWJ.js +725 -0
  106. package/dist/real-html-analyzer-O63XZLZD.js +1759 -0
  107. package/dist/real-java-analyzer-CHCW3EKA.js +4677 -0
  108. package/dist/real-javascript-analyzer-QAAJQYZE.js +14 -0
  109. package/dist/real-json-analyzer-UGBR7YQN.js +1640 -0
  110. package/dist/real-julia-analyzer-35Q4GHOZ.js +2085 -0
  111. package/dist/real-kotlin-analyzer-GRAYCWW2.js +3956 -0
  112. package/dist/real-lua-analyzer-5BAPDZDF.js +1957 -0
  113. package/dist/real-makefile-analyzer-YJKAHNAS.js +920 -0
  114. package/dist/real-markdown-analyzer-UKUQZO4F.js +1215 -0
  115. package/dist/real-matlab-analyzer-FVIKQZKG.js +480 -0
  116. package/dist/real-nim-analyzer-M7FAIABG.js +3603 -0
  117. package/dist/real-objective-c-analyzer-XMYQIGQI.js +1518 -0
  118. package/dist/real-perl-analyzer-ZLY6M2DZ.js +1865 -0
  119. package/dist/real-php-analyzer-KI2ZAM7X.js +9368 -0
  120. package/dist/real-powershell-analyzer-B3T5ZP6U.js +2915 -0
  121. package/dist/real-protobuf-analyzer-23OZ75XV.js +867 -0
  122. package/dist/real-python-analyzer-I4TIUB6D.js +4880 -0
  123. package/dist/real-r-analyzer-FJZJXXS6.js +2596 -0
  124. package/dist/real-ruby-analyzer-M3UFIVTQ.js +2429 -0
  125. package/dist/real-rust-analyzer-LVSONPAN.js +3359 -0
  126. package/dist/real-scala-analyzer-CWPI33Q2.js +3293 -0
  127. package/dist/real-scss-analyzer-TGRJQ7TH.js +1515 -0
  128. package/dist/real-solidity-analyzer-4P2VBVWA.js +2608 -0
  129. package/dist/real-sql-analyzer-J7DYZOZR.js +3840 -0
  130. package/dist/real-svelte-analyzer-NHEN2SX5.js +2532 -0
  131. package/dist/real-swift-analyzer-2NSYULWI.js +2311 -0
  132. package/dist/real-toml-analyzer-L3C66L7Q.js +929 -0
  133. package/dist/real-typescript-analyzer-FTC6ETRQ.js +14 -0
  134. package/dist/real-vb-analyzer-ORY7LAQS.js +3145 -0
  135. package/dist/real-vba-analyzer-JH2TTUFI.js +466 -0
  136. package/dist/real-vue-analyzer-OO4FUGBV.js +2680 -0
  137. package/dist/real-xml-analyzer-6CQVR477.js +2405 -0
  138. package/dist/real-yaml-analyzer-J6MQG3YX.js +3528 -0
  139. package/dist/real-zig-analyzer-EFKCPJNU.js +2430 -0
  140. package/dist/regex-search-OPTLKUN5.js +239 -0
  141. package/dist/rules-I453JTRC.js +152 -0
  142. package/dist/scoped-path-MJYWJZQX.js +11 -0
  143. package/dist/setup-show-Y5GB5KXA.js +15 -0
  144. package/dist/setup-wizard-G5YYR5T6.js +24 -0
  145. package/dist/symbol-search-KB4MU4SI.js +16 -0
  146. package/dist/taint-YOTN5X55.js +202 -0
  147. package/dist/taint-analyzer-N7YLZU3N.js +163 -0
  148. package/dist/tool-handlers-G4NAGJIH.js +72 -0
  149. package/dist/tool-registry-BPEJNSZG.js +17 -0
  150. package/dist/tool-validation-RF675A3C.js +32 -0
  151. package/dist/type-inference-4Y7WTMFE.js +13 -0
  152. package/dist/vector-binary-LMY4QGAN.js +19 -0
  153. package/dist/version-LXGNFO37.js +9 -0
  154. package/dist/wasm-NMWO3WXY.js +16 -0
  155. package/docs/EMBEDDINGS.md +132 -0
  156. package/docs/README.md +178 -0
  157. package/docs/data/m10-baseline.json +602 -0
  158. package/docs/data/m10-benchmark-baseline.json +57 -0
  159. package/docs/data/m10-benchmark-last-run.json +127 -0
  160. package/docs/data/m10-final-audit.json +215 -0
  161. package/docs/data/m12-final-audit.json +138 -0
  162. package/docs/data/m12-surface-matrix.json +50 -0
  163. package/docs/data/public-tools.json +1902 -0
  164. package/docs/indexing/DEAD-ASSETS.md +88 -0
  165. package/docs/indexing/INDEXER-REVIEW.md +634 -0
  166. package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
  167. package/docs/indexing/README.md +427 -0
  168. package/docs/indexing/discovery-matrix.md +41 -0
  169. package/docs/indexing/embeddings.md +325 -0
  170. package/docs/indexing/environment-variables.md +77 -0
  171. package/docs/indexing/performance.md +323 -0
  172. package/docs/indexing/resume.md +345 -0
  173. package/docs/indexing/troubleshooting.md +391 -0
  174. package/docs/man/bb.1 +190 -0
  175. package/docs/tools/bb_analyze.md +147 -0
  176. package/docs/tools/bb_annotate.md +110 -0
  177. package/docs/tools/bb_annotations.md +106 -0
  178. package/docs/tools/bb_ask.md +101 -0
  179. package/docs/tools/bb_cross_language.md +103 -0
  180. package/docs/tools/bb_doc.md +169 -0
  181. package/docs/tools/bb_edit.md +185 -0
  182. package/docs/tools/bb_graph.md +169 -0
  183. package/docs/tools/bb_health.md +156 -0
  184. package/docs/tools/bb_impact.md +117 -0
  185. package/docs/tools/bb_index.md +108 -0
  186. package/docs/tools/bb_migrate.md +135 -0
  187. package/docs/tools/bb_patterns.md +140 -0
  188. package/docs/tools/bb_search.md +150 -0
  189. package/docs/tools/bb_security.md +100 -0
  190. package/docs/tools/bb_visualize.md +184 -0
  191. package/grammars/README.md +57 -0
  192. package/grammars/THIRD-PARTY-NOTICES.md +50 -0
  193. package/grammars/tree-sitter-c/LICENSE +21 -0
  194. package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
  195. package/grammars/tree-sitter-cpp/LICENSE +21 -0
  196. package/grammars/tree-sitter-csharp/LICENSE +21 -0
  197. package/grammars/tree-sitter-css/LICENSE +21 -0
  198. package/grammars/tree-sitter-css/README.md +21 -0
  199. package/grammars/tree-sitter-dart/LICENSE +20 -0
  200. package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
  201. package/grammars/tree-sitter-dart-upstream/README.md +18 -0
  202. package/grammars/tree-sitter-elixir/LICENSE +176 -0
  203. package/grammars/tree-sitter-elixir/README.md +11 -0
  204. package/grammars/tree-sitter-fsharp/LICENSE +21 -0
  205. package/grammars/tree-sitter-fsharp/README.md +45 -0
  206. package/grammars/tree-sitter-graphql/LICENSE +21 -0
  207. package/grammars/tree-sitter-graphql/README.md +106 -0
  208. package/grammars/tree-sitter-groovy/LICENSE +21 -0
  209. package/grammars/tree-sitter-groovy/README.md +4 -0
  210. package/grammars/tree-sitter-haskell/LICENSE +21 -0
  211. package/grammars/tree-sitter-haskell/README.md +394 -0
  212. package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
  213. package/grammars/tree-sitter-hcl/LICENSE +201 -0
  214. package/grammars/tree-sitter-hcl/README.md +39 -0
  215. package/grammars/tree-sitter-html/LICENSE +21 -0
  216. package/grammars/tree-sitter-html/README.md +21 -0
  217. package/grammars/tree-sitter-julia/LICENSE +21 -0
  218. package/grammars/tree-sitter-julia/README.md +24 -0
  219. package/grammars/tree-sitter-kotlin/LICENSE +9 -0
  220. package/grammars/tree-sitter-lua/LICENSE.md +21 -0
  221. package/grammars/tree-sitter-lua/README.md +29 -0
  222. package/grammars/tree-sitter-make/LICENSE +21 -0
  223. package/grammars/tree-sitter-matlab/LICENSE +19 -0
  224. package/grammars/tree-sitter-matlab/README.md +99 -0
  225. package/grammars/tree-sitter-nim/LICENSE +373 -0
  226. package/grammars/tree-sitter-nim/README.md +46 -0
  227. package/grammars/tree-sitter-objc/LICENSE +21 -0
  228. package/grammars/tree-sitter-objc/README.md +20 -0
  229. package/grammars/tree-sitter-perl/LICENSE +7 -0
  230. package/grammars/tree-sitter-perl/README.md +100 -0
  231. package/grammars/tree-sitter-powershell/LICENSE +21 -0
  232. package/grammars/tree-sitter-powershell/README.md +7 -0
  233. package/grammars/tree-sitter-proto/LICENSE +21 -0
  234. package/grammars/tree-sitter-proto/README.md +105 -0
  235. package/grammars/tree-sitter-r/LICENSE +9 -0
  236. package/grammars/tree-sitter-r/README.md +66 -0
  237. package/grammars/tree-sitter-ruby/LICENSE +22 -0
  238. package/grammars/tree-sitter-scss/LICENSE +21 -0
  239. package/grammars/tree-sitter-scss/README.md +17 -0
  240. package/grammars/tree-sitter-solidity/LICENSE +7 -0
  241. package/grammars/tree-sitter-sql/LICENSE +21 -0
  242. package/grammars/tree-sitter-typescript/LICENSE +21 -0
  243. package/grammars/tree-sitter-vba/LICENSE +21 -0
  244. package/grammars/tree-sitter-vba/README.md +738 -0
  245. package/grammars/tree-sitter-vbnet/LICENSE +21 -0
  246. package/grammars/tree-sitter-vbnet/README.md +322 -0
  247. package/grammars/tree-sitter-xml/LICENSE +19 -0
  248. package/grammars/tree-sitter-yaml/LICENSE +20 -0
  249. package/grammars/tree-sitter-yaml/README.md +21 -0
  250. package/package.json +184 -4
  251. package/wasm/dart.wasm +0 -0
  252. package/wasm/tree-sitter-bash.wasm +0 -0
  253. package/wasm/tree-sitter-c.wasm +0 -0
  254. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  255. package/wasm/tree-sitter-clean.wasm +0 -0
  256. package/wasm/tree-sitter-clojure.wasm +0 -0
  257. package/wasm/tree-sitter-core_schema.wasm +0 -0
  258. package/wasm/tree-sitter-cpp.wasm +0 -0
  259. package/wasm/tree-sitter-css.wasm +0 -0
  260. package/wasm/tree-sitter-dart.wasm +0 -0
  261. package/wasm/tree-sitter-elisp.wasm +0 -0
  262. package/wasm/tree-sitter-elixir.wasm +0 -0
  263. package/wasm/tree-sitter-elm.wasm +0 -0
  264. package/wasm/tree-sitter-embedded_template.wasm +0 -0
  265. package/wasm/tree-sitter-erlang.wasm +0 -0
  266. package/wasm/tree-sitter-fsharp.wasm +0 -0
  267. package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
  268. package/wasm/tree-sitter-go.wasm +0 -0
  269. package/wasm/tree-sitter-graphql.wasm +0 -0
  270. package/wasm/tree-sitter-groovy.wasm +0 -0
  271. package/wasm/tree-sitter-haskell.wasm +0 -0
  272. package/wasm/tree-sitter-hcl.wasm +0 -0
  273. package/wasm/tree-sitter-html.wasm +0 -0
  274. package/wasm/tree-sitter-java.wasm +0 -0
  275. package/wasm/tree-sitter-javascript.wasm +0 -0
  276. package/wasm/tree-sitter-json.wasm +0 -0
  277. package/wasm/tree-sitter-json_schema.wasm +0 -0
  278. package/wasm/tree-sitter-julia.wasm +0 -0
  279. package/wasm/tree-sitter-kotlin.wasm +0 -0
  280. package/wasm/tree-sitter-lua.wasm +0 -0
  281. package/wasm/tree-sitter-make.wasm +0 -0
  282. package/wasm/tree-sitter-markdown.wasm +0 -0
  283. package/wasm/tree-sitter-markdown_inline.wasm +0 -0
  284. package/wasm/tree-sitter-matlab.wasm +0 -0
  285. package/wasm/tree-sitter-nim.wasm +0 -0
  286. package/wasm/tree-sitter-objc.wasm +0 -0
  287. package/wasm/tree-sitter-ocaml.wasm +0 -0
  288. package/wasm/tree-sitter-perl.wasm +0 -0
  289. package/wasm/tree-sitter-php.wasm +0 -0
  290. package/wasm/tree-sitter-php_only.wasm +0 -0
  291. package/wasm/tree-sitter-powershell.wasm +0 -0
  292. package/wasm/tree-sitter-protobuf.wasm +0 -0
  293. package/wasm/tree-sitter-python.wasm +0 -0
  294. package/wasm/tree-sitter-ql.wasm +0 -0
  295. package/wasm/tree-sitter-r.wasm +0 -0
  296. package/wasm/tree-sitter-rescript.wasm +0 -0
  297. package/wasm/tree-sitter-ruby.wasm +0 -0
  298. package/wasm/tree-sitter-rust.wasm +0 -0
  299. package/wasm/tree-sitter-scala.wasm +0 -0
  300. package/wasm/tree-sitter-scss.wasm +0 -0
  301. package/wasm/tree-sitter-solidity.wasm +0 -0
  302. package/wasm/tree-sitter-sql.wasm +0 -0
  303. package/wasm/tree-sitter-svelte.wasm +0 -0
  304. package/wasm/tree-sitter-swift.wasm +0 -0
  305. package/wasm/tree-sitter-systemrdl.wasm +0 -0
  306. package/wasm/tree-sitter-terraform.wasm +0 -0
  307. package/wasm/tree-sitter-tlaplus.wasm +0 -0
  308. package/wasm/tree-sitter-toml.wasm +0 -0
  309. package/wasm/tree-sitter-tsx.wasm +0 -0
  310. package/wasm/tree-sitter-typescript.wasm +0 -0
  311. package/wasm/tree-sitter-vba.wasm +0 -0
  312. package/wasm/tree-sitter-vbnet.wasm +0 -0
  313. package/wasm/tree-sitter-vue.wasm +0 -0
  314. package/wasm/tree-sitter-xml.wasm +0 -0
  315. package/wasm/tree-sitter-yaml.wasm +0 -0
  316. package/wasm/tree-sitter-zig.wasm +0 -0
  317. package/wasm/tree-sitter.wasm +0 -0
  318. package/wasm/tsx.wasm +0 -0
  319. package/wasm/typescript.wasm +0 -0
@@ -0,0 +1,543 @@
1
+ // src/ast/pool-diagnostics.ts
2
+ import { fork as forkChild, spawnSync } from "child_process";
3
+ import { existsSync } from "fs";
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+ var WORKER_ENTRY_RELATIVE = path.join("src", "ast", "pool-worker.ts");
7
+ var DEFAULT_WORKER_STARTUP_TIMEOUT_MS = 3e4;
8
+ var DISABLED_VALUES = /* @__PURE__ */ new Set(["0", "false", "off", "no", "none"]);
9
+ function poolStartupTimeoutMs(env = process.env) {
10
+ const raw = env.BB_WORKER_STARTUP_TIMEOUT_MS;
11
+ if (raw === void 0 || raw === "") return DEFAULT_WORKER_STARTUP_TIMEOUT_MS;
12
+ const n = Number(raw);
13
+ if (!Number.isFinite(n) || n <= 0) return DEFAULT_WORKER_STARTUP_TIMEOUT_MS;
14
+ return n;
15
+ }
16
+ function npmInstallFix(what) {
17
+ return [
18
+ `Install ${what}: \`npm install --include=dev\` in the bb checkout
19
+ tsx is a DEV dependency. A production install (\`npm ci --omit=dev\`, NODE_ENV=production,
20
+ a slim CI image) removes it, and the pool then fails exactly like this \u2014 silently,
21
+ because nothing on the path from "tsx is gone" to "workers don't start" said so.`,
22
+ "Or run the published build, which needs no tsx at all: `npm i -g @backbencher/brain`"
23
+ ];
24
+ }
25
+ function reinstallFix() {
26
+ return [
27
+ "Reinstall dependencies: `rm -rf node_modules && npm install --include=dev`\nIf that still fails the checkout is incomplete \u2014 `git status` should be clean and\n`src/ast/pool-worker.ts` must exist."
28
+ ];
29
+ }
30
+ function inProcessOptOut() {
31
+ return "Or stay in-process (same index, slower): `BB_POOL_WORKER=0 bb index .`";
32
+ }
33
+ function remediationFor(reason, detail) {
34
+ const workerCommand = `BB_POOL_WORKER=1 ${[detail.workerPath, ...detail.workerArgs ?? []].filter(Boolean).join(" ")}`;
35
+ switch (reason) {
36
+ case "pool-disabled-by-env":
37
+ return [
38
+ "The pool is off by request, not by failure.\nUnset it to get parallel indexing back: `unset BB_POOL_WORKER`"
39
+ ];
40
+ case "runtime-unsupported":
41
+ return [
42
+ `bb is running under \`${detail.execPath}\`, which is neither Node nor Bun.
43
+ Run it with Node >= 18 (\`node --version\`) or with Bun. The worker is forked with
44
+ the SAME executable as the parent, so an unrecognised runtime cannot load one:
45
+ answering "I don't know" costs an in-process index, guessing costs that plus a
46
+ failure that explains nothing.`
47
+ ];
48
+ case "worker-entry-missing":
49
+ return [
50
+ `Compiled worker entry \`${detail.workerPath}\` does not exist \u2014 a partial build, or an
51
+ install whose \`files\` list dropped dist/.`,
52
+ ...reinstallFix()
53
+ ];
54
+ case "tsx-missing":
55
+ return [...npmInstallFix("tsx, the TypeScript loader the dev worker needs"), inProcessOptOut()];
56
+ case "tsx-not-runnable":
57
+ return [
58
+ `\`${detail.workerPath}\` exists but cannot be executed.
59
+ \`chmod +x node_modules/.bin/tsx\`
60
+ or reinstall: \`rm -rf node_modules && npm install --include=dev\``,
61
+ inProcessOptOut()
62
+ ];
63
+ case "worker-load-crash":
64
+ return [
65
+ // The classified cause leads when stderr gave one. "Rebuild the native
66
+ // module" and "install tsx" are OPPOSITE fixes, and guessing between
67
+ // them from a truncated stack would be worse than reporting what the
68
+ // child actually printed.
69
+ ...detail.causeRemediation ?? [],
70
+ detail.stderrTail ? `The worker's own words:
71
+ \`\`\`
72
+ ${detail.stderrTail}
73
+ \`\`\`` : "It printed nothing to stderr, so the cause is unknown.",
74
+ detail.cause ? null : `Or run the worker by hand to see for yourself:
75
+ \`${workerCommand}\``,
76
+ inProcessOptOut()
77
+ ].filter((x) => x !== null);
78
+ case "worker-exited-silently":
79
+ return [
80
+ 'The worker exited cleanly WITHOUT sending `ready` \u2014 it never entered worker mode.\nMost often `BB_POOL_WORKER` is not "1" in the child environment: an exported\n`BB_POOL_WORKER=0` reads like a supported "don\'t use the pool" switch, and the\nonly consequence was that every forked worker left instantly.\nUnset it (`unset BB_POOL_WORKER`), or set it to 0 deliberately to index in-process.'
81
+ ];
82
+ case "worker-exit-nonzero":
83
+ return [
84
+ `Worker exited with code ${detail.exitCode}${detail.signal ? ` (signal ${detail.signal})` : ""} before it was ready.`,
85
+ detail.stderrTail ? `Its last words:
86
+ \`\`\`
87
+ ${detail.stderrTail}
88
+ \`\`\`` : "It printed nothing to stderr.",
89
+ ...detail.causeRemediation ?? [],
90
+ `Or re-run with the worker's own logging:
91
+ \`BB_LOG_LEVEL=debug bb index --force .\``,
92
+ inProcessOptOut()
93
+ ];
94
+ case "worker-startup-timeout":
95
+ return [
96
+ `The worker stayed alive but sent no \`ready\` within ${detail.timeoutMs}ms.
97
+ It is loading slowly, or it is hung.`,
98
+ "Raise the watchdog on a slow machine or a cold cache:\n `BB_WORKER_STARTUP_TIMEOUT_MS=120000 bb index .`",
99
+ `Or watch it start by hand:
100
+ \`${workerCommand}\``,
101
+ inProcessOptOut()
102
+ ];
103
+ case "worker-selftest-unsupported":
104
+ return [
105
+ "The installed worker did not answer bb's startup self-test, so bb cannot prove it\nstarts. That is expected for a build older than the self-test; it is NOT a failure\nof the pool.",
106
+ "Rebuild to get a verifiable worker: `npm run build` (and `npm install --include=dev`\nif you are running from source, where tsx is required)."
107
+ ];
108
+ case "fork-unavailable":
109
+ return [
110
+ "The operating system refused to fork a worker process.\nCheck for a sandbox ceiling (`ulimit -u`, a container pids limit) and for free\nfile descriptors (`ulimit -n`).",
111
+ inProcessOptOut()
112
+ ];
113
+ }
114
+ }
115
+ function fail(reason, message, detail) {
116
+ return { ok: false, reason, message, remediation: remediationFor(reason, detail), detail };
117
+ }
118
+ function findOnPath(name, env, exists) {
119
+ for (const dir of (env.PATH || "").split(path.delimiter)) {
120
+ if (!dir) continue;
121
+ const candidate = path.join(dir, name);
122
+ try {
123
+ if (exists(candidate)) return candidate;
124
+ } catch {
125
+ }
126
+ }
127
+ return null;
128
+ }
129
+ var MAX_ROOT_WALK = 6;
130
+ function findPackageRoot(fromDir, exists = existsSync) {
131
+ let dir = path.resolve(fromDir);
132
+ for (let i = 0; i <= MAX_ROOT_WALK; i++) {
133
+ try {
134
+ if (exists(path.join(dir, "package.json"))) return dir;
135
+ } catch {
136
+ }
137
+ const parent = path.dirname(dir);
138
+ if (parent === dir) return null;
139
+ dir = parent;
140
+ }
141
+ return null;
142
+ }
143
+ function looksLikeNode(execPath) {
144
+ const base = execPath.split(/[\\/]/).pop().toLowerCase().replace(/\.(exe|cmd|bat)$/, "");
145
+ return /^node(js)?\d*(\.\d+)*$/.test(base);
146
+ }
147
+ function looksLikeBun(execPath) {
148
+ return execPath.split(/[\\/]/).pop().toLowerCase().includes("bun");
149
+ }
150
+ function resolvePoolWorkerForkSafe(deps = {}) {
151
+ const env = deps.env ?? process.env;
152
+ const execPath = deps.execPath ?? process.execPath;
153
+ const exists = deps.exists ?? existsSync;
154
+ const moduleDir = deps.moduleDir ?? path.dirname(fileURLToPath(import.meta.url));
155
+ const baseDetail = {
156
+ execPath,
157
+ nodeVersion: deps.version ?? process.version,
158
+ moduleDir
159
+ };
160
+ const requested = (env.BB_POOL_WORKER ?? "").trim().toLowerCase();
161
+ if (DISABLED_VALUES.has(requested)) {
162
+ return fail(
163
+ "pool-disabled-by-env",
164
+ `pool disabled by BB_POOL_WORKER=${env.BB_POOL_WORKER} (in-process indexing will be used)`,
165
+ { ...baseDetail, workerArgs: [env.BB_POOL_WORKER ?? ""] }
166
+ );
167
+ }
168
+ const walked = findPackageRoot(moduleDir, exists);
169
+ const projectRoot = walked ?? path.resolve(moduleDir, "../..");
170
+ const isCompiled = (moduleDir.endsWith(`${path.sep}dist`) || moduleDir.includes(`${path.sep}dist${path.sep}`)) && !moduleDir.includes(`${path.sep}src${path.sep}`);
171
+ if (isCompiled) {
172
+ const candidates = [];
173
+ let dir = moduleDir;
174
+ for (let i = 0; i <= MAX_ROOT_WALK; i++) {
175
+ candidates.push(path.join(dir, "pool-worker.js"));
176
+ const parent = path.dirname(dir);
177
+ if (parent === dir) break;
178
+ dir = parent;
179
+ }
180
+ if (walked) candidates.push(path.join(walked, "dist", "pool-worker.js"));
181
+ const workerPath = candidates.find((p) => exists(p));
182
+ if (!workerPath) {
183
+ return fail("worker-entry-missing", `compiled worker entry is missing (tried ${candidates.length} locations)`, {
184
+ ...baseDetail,
185
+ projectRoot,
186
+ workerPath: candidates[0],
187
+ searchedPaths: candidates
188
+ });
189
+ }
190
+ return { ok: true, workerPath, workerArgs: [], source: "compiled-dist", projectRoot };
191
+ }
192
+ const workerEntry = path.join(projectRoot, WORKER_ENTRY_RELATIVE);
193
+ if (looksLikeNode(execPath)) {
194
+ const localTsx = path.join(projectRoot, "node_modules", ".bin", "tsx");
195
+ const localTsxExists = exists(localTsx);
196
+ const tsxPath = localTsxExists ? localTsx : findOnPath("tsx", env, exists);
197
+ if (!tsxPath) {
198
+ return fail(
199
+ "tsx-missing",
200
+ `tsx not found: no \`tsx\` in ${localTsx} and none on PATH \u2014 the dev worker cannot be started`,
201
+ {
202
+ ...baseDetail,
203
+ projectRoot,
204
+ workerPath: workerEntry,
205
+ searchedPaths: [localTsx, "$PATH"],
206
+ errorMessage: exists(localTsx) ? "tsx present on PATH but unusable" : void 0
207
+ }
208
+ );
209
+ }
210
+ return {
211
+ ok: true,
212
+ workerPath: tsxPath,
213
+ workerArgs: [workerEntry],
214
+ source: localTsxExists ? "tsx-local" : "tsx-path",
215
+ projectRoot
216
+ };
217
+ }
218
+ if (looksLikeBun(execPath)) {
219
+ return { ok: true, workerPath: workerEntry, workerArgs: [], source: "bun-native", projectRoot };
220
+ }
221
+ return fail(
222
+ "runtime-unsupported",
223
+ `cannot fork a worker under \`${execPath}\`: expected a Node or a Bun executable`,
224
+ { ...baseDetail, projectRoot, workerPath: workerEntry, searchedPaths: [localTsxPath(projectRoot)] }
225
+ );
226
+ }
227
+ function localTsxPath(projectRoot) {
228
+ return path.join(projectRoot, "node_modules", ".bin", "tsx");
229
+ }
230
+ function explainWorkerStderr(stderr) {
231
+ const s = stderr || "";
232
+ const rebuildNative = [
233
+ "The native module was built for a different Node ABI or platform. Rebuild it here:",
234
+ " `npm rebuild better-sqlite3 --build-from-source`",
235
+ "or reinstall from scratch: `rm -rf node_modules && npm install --include=dev`"
236
+ ];
237
+ if (/NODE_MODULE_VERSION|was compiled against a different Node\.js version/i.test(s)) {
238
+ return {
239
+ cause: "native-abi-mismatch",
240
+ summary: "a native module was compiled against a different Node.js version",
241
+ remediation: rebuildNative
242
+ };
243
+ }
244
+ if (/ERR_DLOPEN_FAILED|invalid ELF header|wrong architecture|mach-o file, but this architecture|is not a valid Win32 application/i.test(s)) {
245
+ return {
246
+ cause: "native-platform-mismatch",
247
+ summary: "a native module was built for another platform or architecture",
248
+ remediation: [
249
+ "This node_modules came from another machine/container. Reinstall here:",
250
+ " `rm -rf node_modules && npm install --include=dev`"
251
+ ]
252
+ };
253
+ }
254
+ if (/ERR_MODULE_NOT_FOUND|Cannot find module|Cannot find package '|Failed to resolve module|Cannot find module '\.\//i.test(s)) {
255
+ return {
256
+ cause: "missing-module",
257
+ summary: "a module in the worker's import graph is not installed",
258
+ remediation: [
259
+ "The worker entry exists but one of its imports does not \u2014 a partial install.",
260
+ " `rm -rf node_modules && npm install --include=dev`"
261
+ ]
262
+ };
263
+ }
264
+ if (/SyntaxError: Unexpected token|Cannot use import statement outside a module|Unexpected token 'export'|unknown file extension \.ts/i.test(s)) {
265
+ return {
266
+ cause: "typescript-source-run-as-js",
267
+ summary: "TypeScript source was executed by a runtime that cannot load it (tsx did not apply)",
268
+ remediation: [
269
+ "tsx resolved but did not run: the `tsx` on PATH is a shim or a different tool.",
270
+ "Prefer the local one: `npm install --include=dev` (creates node_modules/.bin/tsx)",
271
+ "Or run the compiled build, which needs no loader: `npm run build && node dist/cli/index.js index .`"
272
+ ]
273
+ };
274
+ }
275
+ if (/EACCES|Permission denied/i.test(s)) {
276
+ return {
277
+ cause: "permission-denied",
278
+ summary: "the resolved worker/tsx file is not executable",
279
+ remediation: [
280
+ "`chmod +x node_modules/.bin/tsx`",
281
+ "or reinstall: `rm -rf node_modules && npm install --include=dev`"
282
+ ]
283
+ };
284
+ }
285
+ if (/ENOMEM|Reached heap limit|heap out of memory|Allocation failed - JavaScript/i.test(s)) {
286
+ return {
287
+ cause: "out-of-memory",
288
+ summary: "the worker ran out of memory during startup",
289
+ remediation: [
290
+ "Raise the heap the worker is allowed: `NODE_OPTIONS=--max-old-space-size=4096`",
291
+ "Fewer workers also helps: lower bb's concurrency or run with fewer cores visible."
292
+ ]
293
+ };
294
+ }
295
+ if (/ERR_OSSL_EVP_UNSUPPORTED|error:0308010C:digital envelope routines::unsupported|digital envelope routines/i.test(s)) {
296
+ return {
297
+ cause: "openssl-legacy-provider",
298
+ summary: "an OpenSSL 3 / legacy digest incompatibility (old dependency on a modern Node)",
299
+ remediation: [
300
+ "Update the offending dependency, or run bb on Node 18 LTS where it still works.",
301
+ "For webpack-era tools only: `NODE_OPTIONS=--openssl-legacy-provider`"
302
+ ]
303
+ };
304
+ }
305
+ if (/tsx|ts-node|esbuild/i.test(s) && /throw|error/i.test(s)) {
306
+ return {
307
+ cause: "tsx-loader-crash",
308
+ summary: "the tsx loader itself failed while starting the worker",
309
+ remediation: [
310
+ "tsx is installed but broken. Reinstall it:",
311
+ " `npm install --include=dev tsx`",
312
+ "Check the loader version: `node_modules/.bin/tsx --version`"
313
+ ]
314
+ };
315
+ }
316
+ return {
317
+ cause: "unclassified",
318
+ summary: "the worker failed to start for an unrecognised reason",
319
+ remediation: [
320
+ "Re-run with the child's own output:",
321
+ " `BB_LOG_LEVEL=debug BB_POOL_WORKER=1 node_modules/.bin/tsx src/ast/pool-worker.ts`",
322
+ "and report the stack above if it persists."
323
+ ]
324
+ };
325
+ }
326
+ var CAPTURE_TAIL_BYTES = 8 * 1024;
327
+ var DEFAULT_CAPTURE_LINES = 20;
328
+ var SELFTEST_ENV = "BB_POOL_WORKER_SELFTEST";
329
+ var SELFTEST_MARKER = "[BB-WORKER-SELFTEST]";
330
+ function probePoolWorkerSync(resolution, opts = {}) {
331
+ if (!resolution.ok) return resolution;
332
+ const env = opts.env ?? process.env;
333
+ const timeoutMs = opts.timeoutMs ?? 3e4;
334
+ const startedAt = Date.now();
335
+ let res;
336
+ try {
337
+ res = spawnSync(
338
+ process.execPath,
339
+ [resolution.workerPath, ...resolution.workerArgs],
340
+ {
341
+ env: { ...env, [SELFTEST_ENV]: "1" },
342
+ encoding: "utf8",
343
+ timeout: timeoutMs,
344
+ killSignal: "SIGKILL",
345
+ maxBuffer: 4 * 1024 * 1024,
346
+ windowsHide: true
347
+ }
348
+ );
349
+ } catch (e) {
350
+ return fail("fork-unavailable", `could not start a worker self-test: ${e?.message ?? String(e)}`, {
351
+ workerPath: resolution.workerPath,
352
+ workerArgs: resolution.workerArgs,
353
+ errorMessage: String(e?.message ?? e)
354
+ });
355
+ }
356
+ const ms = Date.now() - startedAt;
357
+ const stdout = typeof res.stdout === "string" ? res.stdout : "";
358
+ const stderr = typeof res.stderr === "string" ? res.stderr : "";
359
+ const stderrTail = stderr.split("\n").map((l) => l.trimEnd()).filter((l) => l.trim().length > 0).slice(-DEFAULT_CAPTURE_LINES).join("\n");
360
+ if (res.error && res.error.code === "ETIMEDOUT") {
361
+ const explained2 = stderrTail ? explainWorkerStderr(stderrTail) : null;
362
+ const attributed2 = explained2 && explained2.cause !== "unclassified" ? explained2 : null;
363
+ return fail(
364
+ attributed2 ? "worker-load-crash" : "worker-startup-timeout",
365
+ attributed2 ? `worker self-test did not finish: ${attributed2.summary}` : `worker self-test did not finish within ${timeoutMs}ms`,
366
+ {
367
+ workerPath: resolution.workerPath,
368
+ workerArgs: resolution.workerArgs,
369
+ timeoutMs,
370
+ stderrTail: stderrTail || void 0,
371
+ ...attributed2 ? { cause: attributed2.cause, causeRemediation: attributed2.remediation } : {}
372
+ }
373
+ );
374
+ }
375
+ const markerLine = stdout.split("\n").find((l) => l.startsWith(SELFTEST_MARKER));
376
+ if (markerLine) {
377
+ let report = null;
378
+ try {
379
+ report = JSON.parse(markerLine.slice(SELFTEST_MARKER.length).trim());
380
+ } catch {
381
+ report = null;
382
+ }
383
+ if (report) {
384
+ return { ...resolution, ms, report, stderrTail };
385
+ }
386
+ }
387
+ if (res.status === 0 && !stderrTail) {
388
+ return fail(
389
+ "worker-selftest-unsupported",
390
+ "the installed worker did not run bb's startup self-test (it predates it)",
391
+ { workerPath: resolution.workerPath, workerArgs: resolution.workerArgs, exitCode: 0 }
392
+ );
393
+ }
394
+ const explained = stderrTail ? explainWorkerStderr(stderrTail) : null;
395
+ const attributed = explained && explained.cause !== "unclassified" ? explained : null;
396
+ return fail(
397
+ attributed ? "worker-load-crash" : "worker-exit-nonzero",
398
+ attributed ? `the worker failed to start: ${attributed.summary}` : `the worker exited with code ${res.status ?? "null"} before reporting a startup result`,
399
+ {
400
+ workerPath: resolution.workerPath,
401
+ workerArgs: resolution.workerArgs,
402
+ exitCode: res.status ?? null,
403
+ signal: res.signal ?? null,
404
+ stderrTail: stderrTail || void 0,
405
+ ...attributed ? { cause: attributed.cause, causeRemediation: attributed.remediation } : {}
406
+ }
407
+ );
408
+ }
409
+ function poolFailureLine(f) {
410
+ const first = (f.remediation[0] ?? "").split("\n")[0];
411
+ return `worker pool unavailable [${f.reason}]: ${f.message} \u2014 fix: ${first}`;
412
+ }
413
+ function renderPoolDiagnosis(r) {
414
+ if (r.ok) {
415
+ return `worker pool available: fork ${r.workerPath}${r.workerArgs.length ? " " + r.workerArgs.join(" ") : ""} (via ${r.source})`;
416
+ }
417
+ const lines = [];
418
+ lines.push(`worker pool unavailable [${r.reason}]: ${r.message}`);
419
+ const d = r.detail;
420
+ const evidence = [];
421
+ if (d.execPath) evidence.push(`runtime: ${d.execPath}${d.nodeVersion ? ` (${d.nodeVersion})` : ""}`);
422
+ if (d.projectRoot) evidence.push(`root: ${d.projectRoot}`);
423
+ if (d.searchedPaths?.length) evidence.push(`looked in: ${d.searchedPaths.join(", ")}`);
424
+ if (d.workerPath) evidence.push(`worker: ${d.workerPath}${d.workerArgs?.length ? " " + d.workerArgs.join(" ") : ""}`);
425
+ if (d.exitCode !== void 0) evidence.push(`exit: code=${d.exitCode}${d.signal ? ` signal=${d.signal}` : ""}`);
426
+ if (d.timeoutMs !== void 0) evidence.push(`timeout: ${d.timeoutMs}ms`);
427
+ if (evidence.length) lines.push(" " + evidence.join("\n "));
428
+ lines.push(" fix:");
429
+ r.remediation.forEach((fix, i) => {
430
+ const [first, ...rest] = fix.split("\n");
431
+ lines.push(` ${i + 1}. ${first.trim()}`);
432
+ for (const cont of rest) lines.push(cont.trim() ? ` ${cont.trim()}` : "");
433
+ });
434
+ return lines.join("\n");
435
+ }
436
+ function diagnosePoolStartupSync(opts = {}) {
437
+ const env = opts.env ?? process.env;
438
+ const findings = [];
439
+ let resolution;
440
+ try {
441
+ resolution = resolvePoolWorkerForkSafe({ moduleDir: opts.moduleDir, env });
442
+ } catch (e) {
443
+ const message = String(e?.message ?? e);
444
+ return {
445
+ status: "unavailable",
446
+ resolution: {
447
+ ok: false,
448
+ reason: "fork-unavailable",
449
+ message: `the pool resolver itself failed: ${message}`,
450
+ remediation: ["This is a bug in bb. Re-run with BB_LOG_LEVEL=debug and report it."],
451
+ detail: { errorMessage: message }
452
+ },
453
+ findings: [
454
+ {
455
+ id: "pool-resolver-crashed",
456
+ severity: "fail",
457
+ message: `the pool resolver threw: ${message}`,
458
+ fix: "This is a bug in bb \u2014 please report it with the message above."
459
+ }
460
+ ]
461
+ };
462
+ }
463
+ if (!resolution.ok) {
464
+ const disabled = resolution.reason === "pool-disabled-by-env";
465
+ findings.push({
466
+ id: `pool-${resolution.reason}`,
467
+ severity: disabled ? "info" : "fail",
468
+ message: renderPoolDiagnosis(resolution),
469
+ fix: resolution.remediation[0]
470
+ });
471
+ return { status: disabled ? "disabled" : "unavailable", resolution, findings };
472
+ }
473
+ const target = resolution.source === "compiled-dist" ? `the compiled worker (${resolution.workerPath})` : `tsx + TypeScript source (${resolution.workerPath} ${resolution.workerArgs.join(" ")})`;
474
+ findings.push({
475
+ id: "pool-target",
476
+ severity: "info",
477
+ message: `Pool workers fork ${target}
478
+ runtime: ${process.execPath} (${process.version})
479
+ root: ${resolution.projectRoot}`
480
+ });
481
+ if (opts.probe === false) return { status: "ok", resolution, findings };
482
+ let probe;
483
+ try {
484
+ probe = probePoolWorkerSync(resolution, { env, timeoutMs: opts.timeoutMs });
485
+ } catch (e) {
486
+ findings.push({
487
+ id: "pool-selftest-crashed",
488
+ severity: "warn",
489
+ message: `the worker self-test could not be run: ${String(e?.message ?? e)}`,
490
+ fix: "Re-run with BB_LOG_LEVEL=debug; if this repeats it is a bug in bb."
491
+ });
492
+ return { status: "ok", resolution, findings };
493
+ }
494
+ if (!probe.ok) {
495
+ const unverifiable = probe.reason === "worker-selftest-unsupported";
496
+ findings.push({
497
+ id: `pool-${probe.reason}`,
498
+ severity: unverifiable ? "warn" : "fail",
499
+ message: renderPoolDiagnosis(probe),
500
+ fix: probe.remediation[0]
501
+ });
502
+ return { status: unverifiable ? "ok" : "unavailable", resolution, probe, findings };
503
+ }
504
+ const r = probe.report;
505
+ if (r.engine === "unavailable") {
506
+ findings.push({
507
+ id: "pool-engine-unavailable",
508
+ severity: "warn",
509
+ message: `Pool workers START, but the AST engine did not load, so every file is parsed by regex
510
+ extraction instead of its grammar. Indexing succeeds and returns FEWER symbols than a
511
+ healthy run \u2014 which reads as "bb works" and is not.
512
+ worker said: ${r.diagnostics.join(" | ") || "(no detail)"}`,
513
+ fix: "npm rebuild --build-from-source && rm -rf node_modules && npm install --include=dev"
514
+ });
515
+ }
516
+ if (r.wasm === "unavailable") {
517
+ findings.push({
518
+ id: "pool-wasm-unavailable",
519
+ severity: "warn",
520
+ message: `Pool workers START, but the tree-sitter wasm registry did not load. Grammar-based
521
+ parsing is unavailable; files still index through the regex fallback.
522
+ worker said: ${r.diagnostics.join(" | ") || "(no detail)"}`,
523
+ fix: "Check the grammars shipped with your install: `ls wasm | head`"
524
+ });
525
+ }
526
+ if (r.engine === "ok" && r.wasm === "ok") {
527
+ findings.push({
528
+ id: "pool-verified",
529
+ severity: "info",
530
+ message: `A pool worker started and loaded the engine and the grammars in ${probe.ms}ms (pid ${r.pid}, ${r.node}).`
531
+ });
532
+ }
533
+ const status = r.engine === "ok" && r.wasm === "ok" ? "ok" : "degraded";
534
+ return { status, resolution, probe, findings };
535
+ }
536
+
537
+ export {
538
+ poolStartupTimeoutMs,
539
+ findPackageRoot,
540
+ resolvePoolWorkerForkSafe,
541
+ poolFailureLine,
542
+ diagnosePoolStartupSync
543
+ };