gitnexus 1.6.9 → 1.6.10-aptos.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 (539) hide show
  1. package/README.md +211 -53
  2. package/dist/_shared/graph/types.d.ts +67 -3
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/index.js.map +1 -1
  7. package/dist/_shared/integrations/resilient-fetch.d.ts +3 -1
  8. package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
  9. package/dist/_shared/integrations/resilient-fetch.js +4 -3
  10. package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
  11. package/dist/_shared/language-detection.d.ts.map +1 -1
  12. package/dist/_shared/language-detection.js +2 -0
  13. package/dist/_shared/language-detection.js.map +1 -1
  14. package/dist/_shared/languages.d.ts +2 -0
  15. package/dist/_shared/languages.d.ts.map +1 -1
  16. package/dist/_shared/languages.js +2 -0
  17. package/dist/_shared/languages.js.map +1 -1
  18. package/dist/_shared/lbug/schema-constants.d.ts +2 -2
  19. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  20. package/dist/_shared/lbug/schema-constants.js +8 -0
  21. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  22. package/dist/_shared/pipeline.d.ts +1 -1
  23. package/dist/_shared/pipeline.d.ts.map +1 -1
  24. package/dist/_shared/scope-resolution/callable-flow-site.d.ts +110 -0
  25. package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
  26. package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
  27. package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
  28. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +1 -1
  29. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
  30. package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -1
  31. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  32. package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
  33. package/dist/_shared/scope-resolution/language-classification.js +1 -0
  34. package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
  35. package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
  36. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
  37. package/dist/_shared/scope-resolution/reference-site.d.ts +9 -1
  38. package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
  39. package/dist/_shared/scope-resolution/types.d.ts +20 -3
  40. package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
  41. package/dist/cli/ai-context.d.ts +1 -1
  42. package/dist/cli/ai-context.js +25 -44
  43. package/dist/cli/analyze.d.ts +5 -2
  44. package/dist/cli/analyze.js +197 -11
  45. package/dist/cli/clean.js +17 -3
  46. package/dist/cli/cli-message.d.ts +1 -1
  47. package/dist/cli/doctor.d.ts +18 -0
  48. package/dist/cli/doctor.js +96 -5
  49. package/dist/cli/editor-targets.d.ts +17 -2
  50. package/dist/cli/editor-targets.js +44 -0
  51. package/dist/cli/embeddings.d.ts +12 -0
  52. package/dist/cli/embeddings.js +49 -0
  53. package/dist/cli/eval-server.d.ts +23 -1
  54. package/dist/cli/eval-server.js +126 -8
  55. package/dist/cli/help-i18n.js +6 -0
  56. package/dist/cli/i18n/en.d.ts +18 -8
  57. package/dist/cli/i18n/en.js +18 -8
  58. package/dist/cli/i18n/resources.d.ts +28 -8
  59. package/dist/cli/i18n/zh-CN.d.ts +10 -0
  60. package/dist/cli/i18n/zh-CN.js +18 -8
  61. package/dist/cli/index.js +21 -7
  62. package/dist/cli/lazy-action.d.ts +7 -0
  63. package/dist/cli/lazy-action.js +27 -0
  64. package/dist/cli/mcp.js +6 -3
  65. package/dist/cli/move-availability.d.ts +5 -0
  66. package/dist/cli/move-availability.js +11 -0
  67. package/dist/cli/setup.d.ts +8 -0
  68. package/dist/cli/setup.js +230 -32
  69. package/dist/cli/skill-gen.js +38 -18
  70. package/dist/cli/standard-skills.d.ts +76 -0
  71. package/dist/cli/standard-skills.js +45 -0
  72. package/dist/cli/status.d.ts +4 -1
  73. package/dist/cli/status.js +57 -4
  74. package/dist/cli/tool.js +11 -0
  75. package/dist/cli/uninstall.js +77 -18
  76. package/dist/cli/wiki.d.ts +1 -0
  77. package/dist/cli/wiki.js +7 -1
  78. package/dist/config/ignore-service.d.ts +2 -0
  79. package/dist/config/ignore-service.js +27 -0
  80. package/dist/core/analysis-features.d.ts +21 -0
  81. package/dist/core/analysis-features.js +59 -0
  82. package/dist/core/analyzer-identity.d.ts +74 -0
  83. package/dist/core/analyzer-identity.js +1820 -0
  84. package/dist/core/augmentation/engine.js +13 -8
  85. package/dist/core/embeddings/embedder.d.ts +3 -2
  86. package/dist/core/embeddings/embedder.js +24 -7
  87. package/dist/core/embeddings/embedding-identity.d.ts +11 -0
  88. package/dist/core/embeddings/embedding-identity.js +24 -0
  89. package/dist/core/embeddings/embedding-pipeline.d.ts +36 -1
  90. package/dist/core/embeddings/embedding-pipeline.js +100 -9
  91. package/dist/core/embeddings/http-client.d.ts +33 -3
  92. package/dist/core/embeddings/http-client.js +237 -25
  93. package/dist/core/embeddings/node-module-compat.d.ts +25 -0
  94. package/dist/core/embeddings/node-module-compat.js +25 -0
  95. package/dist/core/embeddings/onnxruntime-common-resolver.js +8 -5
  96. package/dist/core/embeddings/onnxruntime-node-resolver.js +33 -7
  97. package/dist/core/embeddings/runtime-install.d.ts +119 -0
  98. package/dist/core/embeddings/runtime-install.js +372 -0
  99. package/dist/core/embeddings/runtime-support.d.ts +48 -17
  100. package/dist/core/embeddings/runtime-support.js +96 -0
  101. package/dist/core/git-staleness.js +1 -1
  102. package/dist/core/group/bridge-db.js +2 -0
  103. package/dist/core/group/extractors/http-patterns/python.js +246 -108
  104. package/dist/core/group/extractors/manifest-extractor.js +4 -0
  105. package/dist/core/incremental/escalation-gate.d.ts +38 -0
  106. package/dist/core/incremental/escalation-gate.js +48 -0
  107. package/dist/core/incremental/shadow-candidates.d.ts +3 -3
  108. package/dist/core/incremental/shadow-candidates.js +3 -3
  109. package/dist/core/incremental/subgraph-extract.d.ts +2 -2
  110. package/dist/core/incremental/subgraph-extract.js +2 -2
  111. package/dist/core/index-freshness.d.ts +5 -0
  112. package/dist/core/index-freshness.js +13 -0
  113. package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
  114. package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
  115. package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
  116. package/dist/core/ingestion/cobol-processor.js +27 -26
  117. package/dist/core/ingestion/community-processor.d.ts +51 -1
  118. package/dist/core/ingestion/community-processor.js +323 -64
  119. package/dist/core/ingestion/emit-references.js +7 -2
  120. package/dist/core/ingestion/filesystem-walker.js +4 -0
  121. package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +3 -0
  122. package/dist/core/ingestion/frameworks/spring/analysis-features.js +7 -0
  123. package/dist/core/ingestion/frameworks/spring/bean-candidates.d.ts +30 -0
  124. package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
  125. package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
  126. package/dist/core/ingestion/frameworks/spring/bean-catalog.js +26 -0
  127. package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +24 -0
  128. package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
  129. package/dist/core/ingestion/languages/c/captures.js +56 -0
  130. package/dist/core/ingestion/languages/c/query.js +17 -0
  131. package/dist/core/ingestion/languages/c/scope-resolver.js +6 -0
  132. package/dist/core/ingestion/languages/cobol/captures.js +93 -0
  133. package/dist/core/ingestion/languages/cobol/scope-resolver.js +7 -0
  134. package/dist/core/ingestion/languages/cpp/captures.js +365 -75
  135. package/dist/core/ingestion/languages/cpp/scope-resolver.js +14 -0
  136. package/dist/core/ingestion/languages/csharp/captures.js +25 -0
  137. package/dist/core/ingestion/languages/dart/captures.js +90 -2
  138. package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
  139. package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
  140. package/dist/core/ingestion/languages/dart.js +2 -0
  141. package/dist/core/ingestion/languages/go/captures.js +34 -0
  142. package/dist/core/ingestion/languages/index.d.ts +1 -0
  143. package/dist/core/ingestion/languages/index.js +2 -0
  144. package/dist/core/ingestion/languages/java/analysis-features.d.ts +3 -0
  145. package/dist/core/ingestion/languages/java/analysis-features.js +13 -0
  146. package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +22 -0
  147. package/dist/core/ingestion/languages/java/capture-side-channel.js +58 -0
  148. package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
  149. package/dist/core/ingestion/languages/java/captures.js +193 -17
  150. package/dist/core/ingestion/languages/java/package-facts.d.ts +5 -0
  151. package/dist/core/ingestion/languages/java/package-facts.js +9 -0
  152. package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
  153. package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
  154. package/dist/core/ingestion/languages/java/query.js +23 -0
  155. package/dist/core/ingestion/languages/java/scope-resolver.js +23 -0
  156. package/dist/core/ingestion/languages/java/spring-bean-metadata.d.ts +2 -0
  157. package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -0
  158. package/dist/core/ingestion/languages/java/spring-config-bindings.d.ts +23 -0
  159. package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
  160. package/dist/core/ingestion/languages/java.js +3 -0
  161. package/dist/core/ingestion/languages/javascript/captures.js +16 -0
  162. package/dist/core/ingestion/languages/javascript/query.js +21 -0
  163. package/dist/core/ingestion/languages/jvm/package-facts.d.ts +35 -0
  164. package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
  165. package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
  166. package/dist/core/ingestion/languages/jvm/package-siblings.js +129 -0
  167. package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +17 -3
  168. package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +42 -8
  169. package/dist/core/ingestion/languages/kotlin/captures.js +59 -0
  170. package/dist/core/ingestion/languages/kotlin/package-facts.d.ts +5 -0
  171. package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
  172. package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
  173. package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
  174. package/dist/core/ingestion/languages/kotlin/query.js +19 -0
  175. package/dist/core/ingestion/languages/kotlin/scope-resolver.js +9 -1
  176. package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.d.ts +2 -0
  177. package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -0
  178. package/dist/core/ingestion/languages/kotlin.js +5 -6
  179. package/dist/core/ingestion/languages/move.d.ts +1 -0
  180. package/dist/core/ingestion/languages/move.js +27 -0
  181. package/dist/core/ingestion/languages/php/captures.js +40 -0
  182. package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
  183. package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
  184. package/dist/core/ingestion/languages/php/import-target.js +110 -2
  185. package/dist/core/ingestion/languages/php/interpret.js +10 -0
  186. package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
  187. package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
  188. package/dist/core/ingestion/languages/python/captures.js +24 -5
  189. package/dist/core/ingestion/languages/python/interpret.js +4 -0
  190. package/dist/core/ingestion/languages/python/receiver-binding.d.ts +15 -2
  191. package/dist/core/ingestion/languages/python/receiver-binding.js +96 -2
  192. package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
  193. package/dist/core/ingestion/languages/python/simple-hooks.js +15 -5
  194. package/dist/core/ingestion/languages/ruby/captures.js +42 -0
  195. package/dist/core/ingestion/languages/rust/captures.js +13 -0
  196. package/dist/core/ingestion/languages/rust/interpret.js +18 -0
  197. package/dist/core/ingestion/languages/rust/query.js +9 -0
  198. package/dist/core/ingestion/languages/rust/range-binding.js +6 -2
  199. package/dist/core/ingestion/languages/swift/captures.js +12 -0
  200. package/dist/core/ingestion/languages/typescript/captures.js +21 -0
  201. package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
  202. package/dist/core/ingestion/languages/typescript/query.js +37 -0
  203. package/dist/core/ingestion/markdown-processor.js +3 -2
  204. package/dist/core/ingestion/model/registration-table.js +1 -0
  205. package/dist/core/ingestion/parsing-processor.d.ts +3 -1
  206. package/dist/core/ingestion/parsing-processor.js +36 -1
  207. package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
  208. package/dist/core/ingestion/pipeline-phases/index.js +2 -0
  209. package/dist/core/ingestion/pipeline-phases/parse-impl.js +56 -2
  210. package/dist/core/ingestion/pipeline-phases/parse.d.ts +0 -2
  211. package/dist/core/ingestion/pipeline-phases/parse.js +12 -3
  212. package/dist/core/ingestion/pipeline-phases/processes.d.ts +8 -0
  213. package/dist/core/ingestion/pipeline-phases/processes.js +11 -1
  214. package/dist/core/ingestion/pipeline-phases/spring-config.d.ts +37 -0
  215. package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
  216. package/dist/core/ingestion/pipeline-phases/standalone-ingest.d.ts +10 -0
  217. package/dist/core/ingestion/pipeline-phases/standalone-ingest.js +6 -0
  218. package/dist/core/ingestion/pipeline.d.ts +4 -2
  219. package/dist/core/ingestion/pipeline.js +5 -2
  220. package/dist/core/ingestion/resolve-references.js +12 -0
  221. package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
  222. package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
  223. package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
  224. package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
  225. package/dist/core/ingestion/scope-extractor.js +306 -43
  226. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +71 -2
  227. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
  228. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
  229. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +3 -1
  230. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +6 -0
  231. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +1 -0
  232. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +4 -1
  233. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +7 -2
  234. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +47 -0
  235. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1138 -0
  236. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +16 -4
  237. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +97 -1
  238. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +60 -0
  239. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +111 -0
  240. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +4 -3
  241. package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +5 -0
  242. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +25 -38
  243. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +6 -0
  244. package/dist/core/ingestion/scope-resolution/pipeline/run.js +147 -35
  245. package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
  246. package/dist/core/ingestion/scope-resolution/scope/walkers.js +73 -44
  247. package/dist/core/ingestion/taint/typescript-model.js +34 -2
  248. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  249. package/dist/core/ingestion/tree-sitter-queries.js +23 -2
  250. package/dist/core/ingestion/type-extractors/jvm.js +17 -2
  251. package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -0
  252. package/dist/core/ingestion/utils/ast-helpers.js +153 -2
  253. package/dist/core/ingestion/utils/callable-flow-captures.d.ts +94 -0
  254. package/dist/core/ingestion/utils/callable-flow-captures.js +878 -0
  255. package/dist/core/ingestion/utils/line-base.d.ts +20 -0
  256. package/dist/core/ingestion/utils/line-base.js +20 -0
  257. package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
  258. package/dist/core/ingestion/utils/symbol-labels.js +45 -0
  259. package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
  260. package/dist/core/ingestion/workers/parse-worker.js +40 -5
  261. package/dist/core/ingestion/workers/result-merge.js +4 -0
  262. package/dist/core/ingestion/workers/worker-pool.d.ts +28 -0
  263. package/dist/core/ingestion/workers/worker-pool.js +128 -28
  264. package/dist/core/lbug/csv-generator.d.ts +15 -0
  265. package/dist/core/lbug/csv-generator.js +124 -27
  266. package/dist/core/lbug/cypher-escape.d.ts +20 -0
  267. package/dist/core/lbug/cypher-escape.js +20 -0
  268. package/dist/core/lbug/extension-load-error.d.ts +67 -0
  269. package/dist/core/lbug/extension-load-error.js +326 -0
  270. package/dist/core/lbug/extension-loader.d.ts +17 -2
  271. package/dist/core/lbug/extension-loader.js +38 -13
  272. package/dist/core/lbug/lbug-adapter.d.ts +203 -2
  273. package/dist/core/lbug/lbug-adapter.js +527 -86
  274. package/dist/core/lbug/lbug-config.d.ts +56 -2
  275. package/dist/core/lbug/lbug-config.js +267 -7
  276. package/dist/core/lbug/move-columns.d.ts +7 -0
  277. package/dist/core/lbug/move-columns.js +86 -0
  278. package/dist/core/lbug/native-check.d.ts +40 -0
  279. package/dist/core/lbug/native-check.js +90 -0
  280. package/dist/core/lbug/node-table-layout.d.ts +29 -0
  281. package/dist/core/lbug/node-table-layout.js +119 -0
  282. package/dist/core/lbug/pool-adapter.d.ts +23 -1
  283. package/dist/core/lbug/pool-adapter.js +115 -8
  284. package/dist/core/lbug/schema.d.ts +4 -3
  285. package/dist/core/lbug/schema.js +16 -16
  286. package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
  287. package/dist/core/lbug/sidecar-recovery.js +418 -16
  288. package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
  289. package/dist/core/move/artifact-download.d.ts +19 -0
  290. package/dist/core/move/artifact-download.js +179 -0
  291. package/dist/core/move/compiler-facts.d.ts +120 -0
  292. package/dist/core/move/compiler-facts.js +9 -0
  293. package/dist/core/move/consistency.d.ts +28 -0
  294. package/dist/core/move/consistency.js +98 -0
  295. package/dist/core/move/constants.d.ts +98 -0
  296. package/dist/core/move/constants.js +136 -0
  297. package/dist/core/move/discovery.d.ts +10 -0
  298. package/dist/core/move/discovery.js +22 -0
  299. package/dist/core/move/entry-points.d.ts +14 -0
  300. package/dist/core/move/entry-points.js +40 -0
  301. package/dist/core/move/facts-mapper.d.ts +75 -0
  302. package/dist/core/move/facts-mapper.js +534 -0
  303. package/dist/core/move/install-lock.d.ts +14 -0
  304. package/dist/core/move/install-lock.js +102 -0
  305. package/dist/core/move/install.d.ts +39 -0
  306. package/dist/core/move/install.js +391 -0
  307. package/dist/core/move/mcp-client.d.ts +115 -0
  308. package/dist/core/move/mcp-client.js +436 -0
  309. package/dist/core/move/move-ingest.d.ts +49 -0
  310. package/dist/core/move/move-ingest.js +320 -0
  311. package/dist/core/move/provision.d.ts +19 -0
  312. package/dist/core/move/provision.js +91 -0
  313. package/dist/core/move/release.d.ts +6 -0
  314. package/dist/core/move/release.js +10 -0
  315. package/dist/core/move/symbol-id.d.ts +35 -0
  316. package/dist/core/move/symbol-id.js +65 -0
  317. package/dist/core/move/type-parser.d.ts +11 -0
  318. package/dist/core/move/type-parser.js +38 -0
  319. package/dist/core/platform/capabilities.d.ts +0 -1
  320. package/dist/core/platform/capabilities.js +39 -8
  321. package/dist/core/run-analyze.d.ts +3 -3
  322. package/dist/core/run-analyze.js +1001 -184
  323. package/dist/core/search/fts-indexes.d.ts +31 -0
  324. package/dist/core/search/fts-indexes.js +73 -0
  325. package/dist/core/search/fts-schema.js +2 -0
  326. package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
  327. package/dist/core/tree-sitter/safe-parse.js +21 -7
  328. package/dist/core/wiki/graph-queries.js +6 -5
  329. package/dist/core/wiki/llm-client.d.ts +8 -2
  330. package/dist/core/wiki/llm-client.js +41 -5
  331. package/dist/mcp/core/embedder.js +16 -2
  332. package/dist/mcp/http-transport.d.ts +5 -0
  333. package/dist/mcp/http-transport.js +19 -5
  334. package/dist/mcp/local/bean-metadata.d.ts +2 -0
  335. package/dist/mcp/local/bean-metadata.js +25 -0
  336. package/dist/mcp/local/line-display.d.ts +22 -0
  337. package/dist/mcp/local/line-display.js +3 -0
  338. package/dist/mcp/local/local-backend.d.ts +19 -1
  339. package/dist/mcp/local/local-backend.js +402 -155
  340. package/dist/mcp/local/pdg-impact.d.ts +5 -3
  341. package/dist/mcp/local/pdg-impact.js +5 -2
  342. package/dist/mcp/output-budget.d.ts +5 -0
  343. package/dist/mcp/output-budget.js +52 -0
  344. package/dist/mcp/read-only-policy.d.ts +12 -0
  345. package/dist/mcp/read-only-policy.js +102 -0
  346. package/dist/mcp/repository-policy.d.ts +34 -0
  347. package/dist/mcp/repository-policy.js +328 -0
  348. package/dist/mcp/resources.js +32 -5
  349. package/dist/mcp/server.d.ts +5 -2
  350. package/dist/mcp/server.js +29 -9
  351. package/dist/mcp/tools.d.ts +0 -8
  352. package/dist/mcp/tools.js +102 -5
  353. package/dist/server/analyze-job.d.ts +3 -0
  354. package/dist/server/analyze-job.js +17 -0
  355. package/dist/server/analyze-launch.d.ts +6 -0
  356. package/dist/server/analyze-launch.js +82 -6
  357. package/dist/server/analyze-worker-core.d.ts +2 -1
  358. package/dist/server/analyze-worker-core.js +5 -2
  359. package/dist/server/analyze-worker.js +29 -6
  360. package/dist/server/api.d.ts +30 -0
  361. package/dist/server/api.js +120 -34
  362. package/dist/server/mcp-http.d.ts +1 -1
  363. package/dist/server/mcp-http.js +4 -2
  364. package/dist/server/upload-ingest.js +2 -1
  365. package/dist/server/validation.js +2 -1
  366. package/dist/storage/git.d.ts +31 -0
  367. package/dist/storage/git.js +111 -1
  368. package/dist/storage/parse-cache.js +7 -1
  369. package/dist/storage/parsedfile-store.d.ts +8 -0
  370. package/dist/storage/parsedfile-store.js +165 -1
  371. package/dist/storage/repo-manager.d.ts +194 -2
  372. package/dist/storage/repo-manager.js +56 -1
  373. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
  374. package/hooks/claude/gitnexus-hook.cjs +59 -9
  375. package/hooks/claude/pre-tool-use.sh +0 -0
  376. package/hooks/claude/session-start.sh +0 -0
  377. package/package.json +21 -15
  378. package/scripts/cross-platform-tests.ts +56 -0
  379. package/scripts/ensure-fts.ts +43 -0
  380. package/scripts/install-duckdb-extension.mjs +85 -24
  381. package/scripts/run-cross-platform.ts +61 -6
  382. package/scripts/shard-arg.ts +30 -0
  383. package/scripts/sync-plugin-manifests.mjs +192 -0
  384. package/skills/gitnexus-lfg/README.md +55 -0
  385. package/skills/gitnexus-lfg/SKILL.md +86 -0
  386. package/skills/gitnexus-plan/README.md +142 -0
  387. package/skills/gitnexus-plan/SKILL.md +348 -0
  388. package/skills/gitnexus-plan/references/context-ledger.md +137 -0
  389. package/skills/gitnexus-plan/references/context-pack.md +126 -0
  390. package/skills/gitnexus-plan/references/evidence-provenance.md +272 -0
  391. package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
  392. package/skills/gitnexus-plan/references/plan-template.md +201 -0
  393. package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2084 -0
  394. package/skills/gitnexus-review/SKILL.md +273 -0
  395. package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
  396. package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
  397. package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
  398. package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
  399. package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
  400. package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
  401. package/skills/gitnexus-work/README.md +71 -0
  402. package/skills/gitnexus-work/SKILL.md +269 -0
  403. package/skills/gitnexus-work/references/evidence-provenance.md +272 -0
  404. package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2084 -0
  405. package/web/assets/ProcessFlowModal-B_bfBySy.js +22 -0
  406. package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
  407. package/web/assets/agent-Bqxn-abU.js +626 -0
  408. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
  409. package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +36 -0
  410. package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-DBefcjof.js} +7 -7
  411. package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-EjWnjEJl.js} +6 -6
  412. package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +4 -0
  413. package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
  414. package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
  415. package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
  416. package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
  417. package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +124 -0
  418. package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
  419. package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +10 -0
  420. package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
  421. package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
  422. package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
  423. package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-Ckl3_KkO.js} +13 -13
  424. package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
  425. package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-BZeP-55u.js} +17 -17
  426. package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
  427. package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
  428. package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-C162wE5z.js} +5 -5
  429. package/web/assets/chunk-LII3EMHJ-BL6lKJ_P.js +1 -0
  430. package/web/assets/chunk-LRIF4GLE-n59lhprL.js +1 -0
  431. package/web/assets/chunk-QA3QBVWF-DVXPOIxe.js +2 -0
  432. package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
  433. package/web/assets/chunk-RG4AUYOV-ZNgyLFq6.js +206 -0
  434. package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
  435. package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
  436. package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +1 -0
  437. package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
  438. package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
  439. package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +1 -0
  440. package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +2 -0
  441. package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
  442. package/web/assets/chunk-ZXARS5L4-C3v-4Fsw.js +1 -0
  443. package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +1 -0
  444. package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +1 -0
  445. package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
  446. package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +4 -0
  447. package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +43 -0
  448. package/web/assets/diagram-GF46GFSD-B2atbzmU.js +24 -0
  449. package/web/assets/diagram-HNR7UZ2L-DVRltWbL.js +3 -0
  450. package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +24 -0
  451. package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +10 -0
  452. package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +85 -0
  453. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
  454. package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +162 -0
  455. package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +292 -0
  456. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
  457. package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +106 -0
  458. package/web/assets/index-CX_fADmQ.css +2 -0
  459. package/web/assets/index-D1Z3dGGz.js +575 -0
  460. package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
  461. package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +2 -0
  462. package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js} +6 -6
  463. package/web/assets/journeyDiagram-M6C3CM3L-C6wjooas.js +139 -0
  464. package/web/assets/kanban-definition-75IXJCU3-5_UVY79g.js +89 -0
  465. package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
  466. package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-8xDLzk2e.js} +29 -29
  467. package/web/assets/node-Ct_zna8U.js +8 -0
  468. package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
  469. package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
  470. package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +30 -0
  471. package/web/assets/preload-helper-Czpn1I53.js +1 -0
  472. package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-DR54jOeR.js} +6 -6
  473. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
  474. package/web/assets/requirementDiagram-JXO7QTGE-PEkg7sKC.js +84 -0
  475. package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  476. package/web/assets/sankeyDiagram-URQDO5SZ-DDWEtjcs.js +40 -0
  477. package/web/assets/sdk-CzHHH8tD.js +37 -0
  478. package/web/assets/sequenceDiagram-VS2MUI6T-Bv-uwANx.js +162 -0
  479. package/web/assets/src-JV30wyV8.js +1 -0
  480. package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +1 -0
  481. package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +1 -0
  482. package/web/assets/timeline-definition-O6YCAMPW-Qmsuo7qS.js +120 -0
  483. package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
  484. package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
  485. package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +34 -0
  486. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
  487. package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +78 -0
  488. package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-CoZ_Tits.js} +6 -6
  489. package/web/index.html +18 -10
  490. package/skills/gitnexus-pr-review.md +0 -163
  491. package/web/assets/agent-Dli_x7bU.js +0 -660
  492. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
  493. package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
  494. package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
  495. package/web/assets/chunk-67TQ5CYL-4sNPJU1q.js +0 -124
  496. package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
  497. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
  498. package/web/assets/chunk-LII3EMHJ-D-jm-dLa.js +0 -1
  499. package/web/assets/chunk-QA3QBVWF-BgRW3SXd.js +0 -2
  500. package/web/assets/chunk-RG4AUYOV-CqWzWsV3.js +0 -206
  501. package/web/assets/chunk-T2UQINTJ-DSBqkzH7.js +0 -1
  502. package/web/assets/chunk-UY5QBCOK-DyF0vyGd.js +0 -1
  503. package/web/assets/chunk-ZXARS5L4-CxN8oiwI.js +0 -1
  504. package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
  505. package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
  506. package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
  507. package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
  508. package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
  509. package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
  510. package/web/assets/diagram-HNR7UZ2L-DFCfd5LI.js +0 -3
  511. package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
  512. package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
  513. package/web/assets/erDiagram-L5TCEMPS-8X1y6R4Y.js +0 -85
  514. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
  515. package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
  516. package/web/assets/ganttDiagram-JCBTUEKG-D3iL2Aet.js +0 -292
  517. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
  518. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
  519. package/web/assets/index-KctnI3Vq.js +0 -635
  520. package/web/assets/index-_lgn7hs5.css +0 -2
  521. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
  522. package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
  523. package/web/assets/journeyDiagram-M6C3CM3L-CvArszLo.js +0 -139
  524. package/web/assets/kanban-definition-75IXJCU3-CpfVLLf9.js +0 -89
  525. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
  526. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
  527. package/web/assets/pieDiagram-CU6KROY3-s27EFWgP.js +0 -30
  528. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
  529. package/web/assets/requirementDiagram-JXO7QTGE-CWhqInuf.js +0 -84
  530. package/web/assets/sankeyDiagram-URQDO5SZ-1qEjlFIB.js +0 -40
  531. package/web/assets/sequenceDiagram-VS2MUI6T-RyTlZ5cR.js +0 -162
  532. package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
  533. package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
  534. package/web/assets/timeline-definition-O6YCAMPW-DrrqLYAf.js +0 -120
  535. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
  536. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
  537. package/web/assets/vennDiagram-MWXL3ELB-B0RkWAim.js +0 -34
  538. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
  539. package/web/assets/wardleyDiagram-CUQ6CDDI-boUxiQ5F.js +0 -78
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Convert a 1-based source line number to the 0-based convention used by
3
+ * GraphNode `startLine`/`endLine`.
4
+ *
5
+ * The graph layer stores line numbers 0-based (tree-sitter `startPosition.row`),
6
+ * and this is load-bearing: the taint/PDG/CFG join and the MCP consumers all add
7
+ * `+ 1` to recover 1-based (see `summary-harvest-driver.ts` — "Function/Method
8
+ * node startLine is 0-based"). Most emitters get 0-based for free from
9
+ * tree-sitter. The exceptions are the regex-based COBOL/JCL processors (their
10
+ * parsers use `lineNum = i + 1`) and the scope-capture path (`Capture` ranges
11
+ * are 1-based per RFC §2.1). Those must convert to 0-based when they build a
12
+ * graph node, or the exact-content slice in `csv-generator.ts` drops the
13
+ * symbol's declaration line (#2379) and reported line numbers are off (#2377).
14
+ *
15
+ * Apply this ONLY at the graph-node `startLine:`/`endLine:` assignment. The
16
+ * parser-internal 1-based values (`.line`, `prog.startLine`) stay 1-based —
17
+ * they feed `L${line}` node/edge IDs and line-range containment checks that
18
+ * must not shift. The clamp guards degenerate inputs (line 0 / empty files).
19
+ */
20
+ export declare const toZeroBasedLine: (oneBasedLine: number) => number;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Convert a 1-based source line number to the 0-based convention used by
3
+ * GraphNode `startLine`/`endLine`.
4
+ *
5
+ * The graph layer stores line numbers 0-based (tree-sitter `startPosition.row`),
6
+ * and this is load-bearing: the taint/PDG/CFG join and the MCP consumers all add
7
+ * `+ 1` to recover 1-based (see `summary-harvest-driver.ts` — "Function/Method
8
+ * node startLine is 0-based"). Most emitters get 0-based for free from
9
+ * tree-sitter. The exceptions are the regex-based COBOL/JCL processors (their
10
+ * parsers use `lineNum = i + 1`) and the scope-capture path (`Capture` ranges
11
+ * are 1-based per RFC §2.1). Those must convert to 0-based when they build a
12
+ * graph node, or the exact-content slice in `csv-generator.ts` drops the
13
+ * symbol's declaration line (#2379) and reported line numbers are off (#2377).
14
+ *
15
+ * Apply this ONLY at the graph-node `startLine:`/`endLine:` assignment. The
16
+ * parser-internal 1-based values (`.line`, `prog.startLine`) stay 1-based —
17
+ * they feed `L${line}` node/edge IDs and line-range containment checks that
18
+ * must not shift. The clamp guards degenerate inputs (line 0 / empty files).
19
+ */
20
+ export const toZeroBasedLine = (oneBasedLine) => Math.max(0, oneBasedLine - 1);
@@ -0,0 +1,21 @@
1
+ import type { NodeLabel } from '../../../_shared/index.js';
2
+ /**
3
+ * Graph-node labels that represent a resolvable code symbol — a definition with
4
+ * its own source span (function, type, member, module-like container).
5
+ *
6
+ * These get EXACT source-span content in the FTS index: `csv-generator.ts`
7
+ * slices exactly `[startLine, endLine]` for them (no ±2 padding), while every
8
+ * other label keeps the context window. That exactness depends on the 0-based
9
+ * `startLine`/`endLine` invariant enforced by `line-base.ts` — the slice is only
10
+ * correct because all emitters store 0-based lines. Keep the two together.
11
+ *
12
+ * Single source of truth so the set can't silently drift the way the inline copy
13
+ * did in #2379.
14
+ *
15
+ * NOTE: `group/extractors/manifest-extractor.ts`'s `CUSTOM_CONTRACT_RESOLVE_QUERY`
16
+ * carries a near-identical hand-list that is intentionally a SUBSET — it excludes
17
+ * `Namespace`, `Variable`, `Module`. Unifying the two needs a contract-resolution
18
+ * behavior check (would widen which nodes resolve as contract symbols), so it is
19
+ * deliberately left separate for now.
20
+ */
21
+ export declare const SYMBOL_NODE_LABELS: ReadonlySet<NodeLabel>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Graph-node labels that represent a resolvable code symbol — a definition with
3
+ * its own source span (function, type, member, module-like container).
4
+ *
5
+ * These get EXACT source-span content in the FTS index: `csv-generator.ts`
6
+ * slices exactly `[startLine, endLine]` for them (no ±2 padding), while every
7
+ * other label keeps the context window. That exactness depends on the 0-based
8
+ * `startLine`/`endLine` invariant enforced by `line-base.ts` — the slice is only
9
+ * correct because all emitters store 0-based lines. Keep the two together.
10
+ *
11
+ * Single source of truth so the set can't silently drift the way the inline copy
12
+ * did in #2379.
13
+ *
14
+ * NOTE: `group/extractors/manifest-extractor.ts`'s `CUSTOM_CONTRACT_RESOLVE_QUERY`
15
+ * carries a near-identical hand-list that is intentionally a SUBSET — it excludes
16
+ * `Namespace`, `Variable`, `Module`. Unifying the two needs a contract-resolution
17
+ * behavior check (would widen which nodes resolve as contract symbols), so it is
18
+ * deliberately left separate for now.
19
+ */
20
+ export const SYMBOL_NODE_LABELS = new Set([
21
+ 'Function',
22
+ 'Method',
23
+ 'Class',
24
+ 'Interface',
25
+ 'CodeElement',
26
+ 'Struct',
27
+ 'Enum',
28
+ 'Macro',
29
+ 'Typedef',
30
+ 'Union',
31
+ 'Namespace',
32
+ 'Trait',
33
+ 'Impl',
34
+ 'TypeAlias',
35
+ 'Const',
36
+ 'Static',
37
+ 'Variable',
38
+ 'Property',
39
+ 'Record',
40
+ 'Delegate',
41
+ 'Annotation',
42
+ 'Constructor',
43
+ 'Template',
44
+ 'Module',
45
+ ]);
@@ -113,6 +113,21 @@ export interface ExtractedDecoratorRoute {
113
113
  * participate in `include_router(prefix=...)` joining.
114
114
  */
115
115
  decoratorReceiver?: string;
116
+ /**
117
+ * Raw text of a non-literal decorator path argument (`#2391`), e.g.
118
+ * `API_V1_WIDGETS_GET` or `API_V1 + "/widgets"`. Present only when the
119
+ * decorator's first argument was NOT a string literal, in which case
120
+ * `routePath` is empty and parse-impl resolves the constant cross-file (or
121
+ * drops the route on failure). Absent for ordinary string-literal routes.
122
+ */
123
+ routePathExpr?: string;
124
+ /**
125
+ * Parsed operand list for {@link routePathExpr} — an identifier reference or a
126
+ * `+`-concatenation, in the {@link Operand} shape the constant resolver folds.
127
+ * `undefined` when the expression was not a foldable string form (e.g. an
128
+ * attribute access), in which case the route is dropped at resolution.
129
+ */
130
+ routePathOperands?: Operand[];
116
131
  /**
117
132
  * FastAPI `app.include_router(prefix='/x')` prefix that applies to
118
133
  * this route. Filled by parse-impl after cross-file aggregation; the
@@ -131,6 +146,17 @@ export interface ExtractedDecoratorRoute {
131
146
  */
132
147
  handlerName?: string;
133
148
  }
149
+ /**
150
+ * One Python file's module-level string constants (#2391), used by parse-impl to
151
+ * resolve non-literal decorator route paths cross-file. `constants` is the
152
+ * `Map`-based {@link ModuleConstants} shape — it survives the worker
153
+ * `postMessage` boundary (structured clone) and the parse cache
154
+ * (`mapReplacer`/`mapReviver`) without conversion.
155
+ */
156
+ export interface ExtractedModuleConstants {
157
+ filePath: string;
158
+ constants: ModuleConstants;
159
+ }
134
160
  export interface ExtractedToolDef {
135
161
  filePath: string;
136
162
  toolName: string;
@@ -211,6 +237,13 @@ export interface ParseWorkerResult {
211
237
  * predate the field; consumers must guard with `if (… ?? [])`).
212
238
  */
213
239
  routerModuleAliases?: ExtractedRouterModuleAlias[];
240
+ /**
241
+ * Per-file Python module-level string constants (#2391). parse-impl aggregates
242
+ * these into a repo-wide, file-path-keyed map and resolves each decorator
243
+ * route's non-literal path expression against it. Optional for cache backward
244
+ * compatibility (older entries predate the field; consumers guard with `?? []`).
245
+ */
246
+ moduleConstants?: ExtractedModuleConstants[];
214
247
  toolDefs: ExtractedToolDef[];
215
248
  ormQueries: ExtractedORMQuery[];
216
249
  constructorBindings: FileConstructorBindings[];
@@ -256,3 +289,4 @@ export interface ParseWorkerInput {
256
289
  * Appends results to the provided array (avoids allocation when no matches).
257
290
  */
258
291
  export declare function extractORMQueries(filePath: string, content: string, out: ExtractedORMQuery[]): void;
292
+ import { type ModuleConstants, type Operand } from '../route-extractors/python-const-resolver.js';
@@ -751,6 +751,7 @@ export function extractORMQueries(filePath, content, out) {
751
751
  // per file; this module does not re-export it. Downstream consumers
752
752
  // import the function and its types directly from `route-extractors/`.
753
753
  import { extractFastAPIRouterBindings } from '../route-extractors/fastapi-router-bindings.js';
754
+ import { extractPythonModuleConstants, parseConstOperands, } from '../route-extractors/python-const-resolver.js';
754
755
  /**
755
756
  * Report a non-fatal worker issue to the pool over IPC so a caught error is not
756
757
  * invisible to the operator (#2264). The pool logs it on the main thread AND
@@ -813,7 +814,7 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
813
814
  try {
814
815
  tree = parseSourceSafe(parser, parseContent, undefined, {
815
816
  bufferSize: getTreeSitterBufferSize(parseContent),
816
- });
817
+ }, file.path);
817
818
  }
818
819
  catch (err) {
819
820
  reportWarning(`Failed to parse file ${file.path}: ${err instanceof Error ? err.message : String(err)}`);
@@ -986,6 +987,12 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
986
987
  if (captureMap['decorator'] && captureMap['decorator.name']) {
987
988
  const decoratorName = captureMap['decorator.name'].text;
988
989
  const decoratorArg = captureMap['decorator.arg']?.text;
990
+ // #2391: the first positional arg captured as either a string node
991
+ // (`arg_str`, present even for the empty-string literal `""` which has no
992
+ // `string_content`) or a non-literal expression (`arg_expr`: an
993
+ // identifier or a `+`-concatenation).
994
+ const decoratorArgStr = captureMap['decorator.arg_str'];
995
+ const decoratorArgExpr = captureMap['decorator.arg_expr'];
989
996
  const decoratorReceiver = captureMap['decorator.receiver']?.text;
990
997
  const decoratorNode = captureMap['decorator'];
991
998
  // Store by the decorator's end line — the definition follows immediately after
@@ -994,19 +1001,39 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
994
1001
  arg: decoratorArg,
995
1002
  });
996
1003
  if (ROUTE_DECORATOR_NAMES.has(decoratorName)) {
997
- const routePath = decoratorArg || '';
998
1004
  const method = decoratorName.replace('Mapping', '').toUpperCase();
999
1005
  const httpMethod = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'].includes(method)
1000
1006
  ? method
1001
1007
  : 'GET';
1002
- result.decoratorRoutes.push({
1008
+ const base = {
1003
1009
  filePath: file.path,
1004
- routePath,
1005
1010
  httpMethod,
1006
1011
  decoratorName,
1007
1012
  lineNumber: decoratorNode.startPosition.row + lineOffset,
1008
1013
  ...(decoratorReceiver ? { decoratorReceiver } : {}),
1009
- });
1014
+ };
1015
+ if (decoratorArgStr) {
1016
+ // String-literal path (the fast path, unchanged). Empty-string
1017
+ // literal `""` has no `string_content` → `decoratorArg` undefined →
1018
+ // routePath '' (a valid path under an APIRouter prefix).
1019
+ result.decoratorRoutes.push({ ...base, routePath: decoratorArg ?? '' });
1020
+ }
1021
+ else if (decoratorArgExpr) {
1022
+ // #2391 non-literal path (imported/composed constant). Emit the raw
1023
+ // expression + its operands for cross-file resolution in parse-impl;
1024
+ // `routePath` stays empty until resolved (or the route is dropped).
1025
+ const operands = decoratorArgExpr.type === 'identifier'
1026
+ ? [{ kind: 'ref', name: decoratorArgExpr.text }]
1027
+ : parseConstOperands(decoratorArgExpr);
1028
+ result.decoratorRoutes.push({
1029
+ ...base,
1030
+ routePath: '',
1031
+ routePathExpr: decoratorArgExpr.text,
1032
+ ...(operands ? { routePathOperands: operands } : {}),
1033
+ });
1034
+ }
1035
+ // Otherwise the first arg is absent or an unsupported shape
1036
+ // (attribute access, call, …) → skip; never a phantom `POST /`.
1010
1037
  }
1011
1038
  // MCP/RPC tool detection: @mcp.tool(), @app.tool(), @server.tool()
1012
1039
  if (decoratorName === 'tool') {
@@ -1839,6 +1866,14 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
1839
1866
  // came from a `@router.<verb>` decorator. Python-only.
1840
1867
  if (language === SupportedLanguages.Python) {
1841
1868
  extractFastAPIRouterBindings(file.path, parseContent, result.routerIncludes, result.routerImports, (result.routerModuleAliases ??= []), (result.routerConstructorPrefixes ??= []));
1869
+ // #2391: harvest module-level string constants + from-imports so parse-impl
1870
+ // can resolve non-literal decorator route paths cross-file. Only emit for
1871
+ // files that carry something resolvable (a constant definition or an import
1872
+ // binding) to keep the aggregate bounded on large repos.
1873
+ const constants = extractPythonModuleConstants(tree);
1874
+ if (constants.literals.size > 0 || constants.exprs.size > 0 || constants.imports.size > 0) {
1875
+ (result.moduleConstants ??= []).push({ filePath: file.path, constants });
1876
+ }
1842
1877
  }
1843
1878
  // Language-specific decorator route extraction via provider hook.
1844
1879
  // The provider's extractDecoratorRoutes walks the AST for framework-specific
@@ -32,6 +32,10 @@ export const mergeResult = (target, src) => {
32
32
  target.routerModuleAliases ??= [];
33
33
  appendAll(target.routerModuleAliases, src.routerModuleAliases);
34
34
  }
35
+ if (src.moduleConstants) {
36
+ target.moduleConstants ??= [];
37
+ appendAll(target.moduleConstants, src.moduleConstants);
38
+ }
35
39
  if (src.springTypes) {
36
40
  target.springTypes ??= [];
37
41
  appendAll(target.springTypes, src.springTypes);
@@ -99,6 +99,19 @@ export interface WorkerPoolOptions {
99
99
  * created. Default `Math.max(3, poolSize)`.
100
100
  */
101
101
  consecutiveFailureThreshold?: number;
102
+ /**
103
+ * Startup budget in milliseconds for a replacement worker to emit the
104
+ * `{type:'ready'}` handshake before the pool treats it as a startup
105
+ * crash (see {@link waitForWorkerReady}). Default 5000; also overridable
106
+ * via `GITNEXUS_WORKER_READY_TIMEOUT_MS`, mirroring
107
+ * `GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS`. On a slow or heavily loaded
108
+ * host, a full pool of workers cold-starting concurrently can
109
+ * legitimately need more than 5s to load the native grammar bindings —
110
+ * without the override every slot times out and the pool misclassifies
111
+ * the slow start as a deterministic startup crash-loop, aborting the
112
+ * whole analyze.
113
+ */
114
+ workerReadyTimeoutMs?: number;
102
115
  /**
103
116
  * Test-only injection point for the Worker constructor. When provided,
104
117
  * the pool uses this factory instead of `new Worker(workerUrl)`. Production
@@ -135,6 +148,19 @@ export interface WorkerPoolOptions {
135
148
  pdg?: boolean;
136
149
  /** Per-function source-line cap for worker-side CFG construction (0 ⇒ no cap). */
137
150
  pdgMaxFunctionLines?: number;
151
+ /**
152
+ * Max wall time `terminate()` waits for a retired worker that has NOT yet
153
+ * reached a JS-visible safe point before giving up on terminating it
154
+ * (#2432). Terminating a worker thread that is inside an N-API call aborts
155
+ * the whole process (`Napi::Error` → `std::terminate` → SIGABRT) — and the
156
+ * same abort fires at plain process exit, so the drain is what makes
157
+ * shutdown safe. On expiry the worker is left running (unref'd, with its
158
+ * at-safe-point terminate listener still armed) and a diagnostic is logged.
159
+ * Default 30000ms — above the C++ capture budget
160
+ * (`GITNEXUS_CPP_CAPTURE_BUDGET_MS`, 20000ms) so the drain converges for
161
+ * the known pathological class. 0 ⇒ no wait (test hook).
162
+ */
163
+ shutdownDrainMs?: number;
138
164
  }
139
165
  export declare class WorkerPoolDispatchError extends Error {
140
166
  /**
@@ -193,6 +219,8 @@ interface ResolvedWorkerPoolOptions {
193
219
  maxRespawnsPerSlot: number;
194
220
  maxCumulativeTimeoutMs: number;
195
221
  consecutiveFailureThreshold: number;
222
+ shutdownDrainMs: number;
223
+ workerReadyTimeoutMs: number;
196
224
  }
197
225
  export declare function resolveWorkerPoolOptions(options?: WorkerPoolOptions, poolSize?: number): ResolvedWorkerPoolOptions;
198
226
  /**
@@ -116,17 +116,7 @@ const DEFAULT_TIMEOUT_BACKOFF_FACTOR = 2;
116
116
  const DEFAULT_MAX_RESPAWNS_PER_SLOT = 3;
117
117
  const DEFAULT_MAX_CUMULATIVE_TIMEOUT_FACTOR = 5;
118
118
  const DEFAULT_CONSECUTIVE_FAILURE_THRESHOLD_FLOOR = 3;
119
- /**
120
- * Bounded wait for a replacement worker to emit the `{type:'ready'}`
121
- * handshake from `parse-worker.ts`. Trusting Node's `online` event alone
122
- * lets a worker that crashes during top-of-script init slip past pool
123
- * startup — the pool only notices on the first dispatch's idle timeout
124
- * (default 30s). 5 seconds is a generous budget for parser + grammar
125
- * imports; if the worker hasn't reported ready by then, it's almost
126
- * certainly stuck or crashed and the pool should surface the failure
127
- * fast rather than wait out the dispatch idle timeout.
128
- */
129
- const WORKER_READY_TIMEOUT_MS = 5_000;
119
+ const DEFAULT_WORKER_READY_TIMEOUT_MS = 5_000;
130
120
  /**
131
121
  * Default upper bound on auto-resolved pool size. Past 16 workers the
132
122
  * dominant cost shifts from worker-side parsing to main-thread merge /
@@ -231,6 +221,8 @@ function nonNegativeInteger(value) {
231
221
  ? Math.floor(parsed)
232
222
  : undefined;
233
223
  }
224
+ /** See {@link WorkerPoolOptions.shutdownDrainMs}. */
225
+ const DEFAULT_SHUTDOWN_DRAIN_MS = 30_000;
234
226
  export function resolveWorkerPoolOptions(options = {}, poolSize) {
235
227
  const subBatchIdleTimeoutMs = positiveInteger(options.subBatchIdleTimeoutMs) ??
236
228
  positiveInteger(process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS) ??
@@ -252,6 +244,12 @@ export function resolveWorkerPoolOptions(options = {}, poolSize) {
252
244
  consecutiveFailureThreshold: positiveInteger(options.consecutiveFailureThreshold) ??
253
245
  positiveInteger(process.env.GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD) ??
254
246
  Math.max(DEFAULT_CONSECUTIVE_FAILURE_THRESHOLD_FLOOR, poolSize ?? 0),
247
+ shutdownDrainMs: nonNegativeInteger(options.shutdownDrainMs) ??
248
+ nonNegativeInteger(process.env.GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS) ??
249
+ DEFAULT_SHUTDOWN_DRAIN_MS,
250
+ workerReadyTimeoutMs: positiveInteger(options.workerReadyTimeoutMs) ??
251
+ positiveInteger(process.env.GITNEXUS_WORKER_READY_TIMEOUT_MS) ??
252
+ DEFAULT_WORKER_READY_TIMEOUT_MS,
255
253
  };
256
254
  }
257
255
  /**
@@ -347,6 +345,27 @@ function captureWorkerStderr(worker) {
347
345
  // A stderr stream error must never crash the pool.
348
346
  stream.on('error', () => undefined);
349
347
  }
348
+ /**
349
+ * Forward a worker's piped stdout to the parent process's stdout, so worker
350
+ * logs stay visible now that the production factory spawns with
351
+ * `{ stdout: true }`. Workers with INHERITED stdout have been observed to
352
+ * crash silently during top-of-script init (exit code 1, nothing on stderr,
353
+ * roughly half of a concurrently spawned pool) on macOS 26.5 under both
354
+ * Node 22 and 26; piping stdout eliminates the crash entirely. Piping also
355
+ * matches the existing stderr handling, so worker output no longer races the
356
+ * parent's raw fd. No-op when the worker has no `stdout` stream (test
357
+ * factories).
358
+ */
359
+ function forwardWorkerStdout(worker) {
360
+ const stream = worker.stdout;
361
+ if (!stream)
362
+ return;
363
+ stream.on('data', (chunk) => {
364
+ process.stdout.write(chunk);
365
+ });
366
+ // A stdout stream error must never crash the pool.
367
+ stream.on('error', () => undefined);
368
+ }
350
369
  /** Captured stderr tail for a worker, trimmed; '' when nothing was captured. */
351
370
  function workerStderrTail(worker) {
352
371
  return workerStderrTails.get(worker)?.text.trim() ?? '';
@@ -383,13 +402,14 @@ function workerErrorReason(workerIndex, message, stack) {
383
402
  * (parser/grammar import failure, missing native binding) slip past
384
403
  * pool startup. The pool then only noticed the dead replacement on the
385
404
  * first dispatch's idle timeout (default 30s) — a long stall masking
386
- * an actual crash. This handshake bounds the wait at
387
- * {@link WORKER_READY_TIMEOUT_MS} and surfaces init failures as
388
- * `error` / `exit` / `messageerror` events directly. `messageerror` is
389
- * wired the same way: a V8 deserialization failure during startup is
390
- * treated as worker death and rejects the readiness promise.
405
+ * an actual crash. This handshake bounds the wait at `readyTimeoutMs`
406
+ * (see {@link WorkerPoolOptions.workerReadyTimeoutMs}) and surfaces init
407
+ * failures as `error` / `exit` / `messageerror` events directly.
408
+ * `messageerror` is wired the same way: a V8 deserialization failure
409
+ * during startup is treated as worker death and rejects the readiness
410
+ * promise.
391
411
  */
392
- function waitForWorkerReady(worker) {
412
+ function waitForWorkerReady(worker, readyTimeoutMs) {
393
413
  return new Promise((resolve, reject) => {
394
414
  const cleanup = () => {
395
415
  clearTimeout(timer);
@@ -427,8 +447,8 @@ function waitForWorkerReady(worker) {
427
447
  // access can fire from the listeners.
428
448
  const timer = setTimeout(() => {
429
449
  cleanup();
430
- reject(new Error(withStderr(worker, `Replacement worker did not report ready within ${WORKER_READY_TIMEOUT_MS}ms — likely crashed during top-of-script init`)));
431
- }, WORKER_READY_TIMEOUT_MS);
450
+ reject(new Error(withStderr(worker, `Replacement worker did not report ready within ${readyTimeoutMs}ms — likely crashed during top-of-script init (slow host? raise GITNEXUS_WORKER_READY_TIMEOUT_MS)`)));
451
+ }, readyTimeoutMs);
432
452
  worker.on('message', onMessage);
433
453
  worker.once('error', onError);
434
454
  worker.once('exit', onExit);
@@ -558,6 +578,10 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
558
578
  : undefined;
559
579
  const spawnWorker = options?.workerFactory ??
560
580
  ((url) => new Worker(url, {
581
+ // Piped (not inherited) stdio: stderr for crash capture (#1741),
582
+ // stdout because inherited stdout triggers silent startup crashes on
583
+ // some hosts (see forwardWorkerStdout).
584
+ stdout: true,
561
585
  stderr: true,
562
586
  workerData: workerStoreData,
563
587
  // The CFG visitors build per-function control-flow graphs by RECURSIVE
@@ -571,10 +595,11 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
571
595
  // try/catch) and only that function's PDG is skipped, never a crash.
572
596
  resourceLimits: { stackSizeMb: 16 },
573
597
  }));
574
- /** Spawn + wire stderr capture in one step (used by all spawn sites). */
598
+ /** Spawn + wire stdio capture/forwarding in one step (used by all spawn sites). */
575
599
  const spawnAndCapture = (url) => {
576
600
  const worker = spawnWorker(url);
577
601
  captureWorkerStderr(worker);
602
+ forwardWorkerStdout(worker);
578
603
  return worker;
579
604
  };
580
605
  const workers = new Array(size);
@@ -608,13 +633,50 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
608
633
  // Set by `terminate()` (below). Also read by the self-healing startup loop so
609
634
  // a terminate during startup aborts pending backoff/retries (#1741).
610
635
  let terminated = false;
636
+ /** Resolves `true` when `promise` settles within `ms`, else `false`. The
637
+ * timer is unref'd so an expiring drain never holds the process open. */
638
+ const settledWithin = (promise, ms) => {
639
+ if (ms <= 0)
640
+ return Promise.resolve(false);
641
+ return new Promise((resolve) => {
642
+ const timer = setTimeout(() => resolve(false), ms);
643
+ timer.unref?.();
644
+ void promise.then(() => {
645
+ clearTimeout(timer);
646
+ resolve(true);
647
+ });
648
+ });
649
+ };
611
650
  const terminateTrackedWorkers = async (liveWorkers) => {
612
651
  const retired = Array.from(retiredWorkers);
613
652
  await Promise.all([
614
653
  ...liveWorkers.map((worker) => worker?.terminate().catch(() => undefined)),
615
- ...retired.map((record) => record.terminate()),
654
+ ...retired.map(async (record) => {
655
+ // #2432: a retired worker that has not reached a JS-visible safe
656
+ // point may be inside an N-API call — terminating it aborts the
657
+ // WHOLE process (`Napi::Error` → std::terminate → SIGABRT). Drain:
658
+ // wait (bounded) for its safe point; on expiry leave it running —
659
+ // it is unref'd and its at-safe-point terminate listener stays
660
+ // armed — and log which file wedged it.
661
+ if (!record.safeToTerminate) {
662
+ const drained = await settledWithin(record.safePoint, poolOptions.shutdownDrainMs);
663
+ if (!drained) {
664
+ logger.warn({
665
+ workerIndex: record.workerIndex,
666
+ reason: record.reason,
667
+ drainMs: poolOptions.shutdownDrainMs,
668
+ }, `Worker ${record.workerIndex} is still inside native code after the ` +
669
+ `${poolOptions.shutdownDrainMs}ms shutdown drain; leaving it un-terminated ` +
670
+ `to avoid a native abort (#2432). It will be terminated at its next safe point.`);
671
+ return;
672
+ }
673
+ }
674
+ await record.terminate();
675
+ }),
616
676
  ]);
617
- retiredWorkers.clear();
677
+ // Undrained records stay tracked so a repeated shutdown call can retry
678
+ // their (now possibly safe) terminate; record.terminate() removes each
679
+ // drained record via its cleanup.
618
680
  };
619
681
  for (let i = 0; i < size; i++) {
620
682
  workers[i] = spawnAndCapture(workerUrl);
@@ -665,7 +727,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
665
727
  if (!worker)
666
728
  return; // terminated mid-startup
667
729
  try {
668
- await waitForWorkerReady(worker);
730
+ await waitForWorkerReady(worker, poolOptions.workerReadyTimeoutMs);
669
731
  anyWorkerReachedReady = true;
670
732
  return; // ready — slot stays in activeSlots
671
733
  }
@@ -709,7 +771,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
709
771
  const initialReadyGate = Promise.allSettled(workers.map((_, i) => bringSlotReady(i))).then(() => undefined);
710
772
  const dispatch = async (items, onProgress, chunkHash) => {
711
773
  // Await the initial-spawn readiness gate (F13). On first dispatch
712
- // this blocks for up to WORKER_READY_TIMEOUT_MS while every initial
774
+ // this blocks for up to poolOptions.workerReadyTimeoutMs while every initial
713
775
  // worker's `{type:'ready'}` handshake is checked; on subsequent
714
776
  // dispatches the promise is already settled and resolves
715
777
  // synchronously. Slots whose initial worker crashed in top-of-
@@ -788,6 +850,18 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
788
850
  const retireWorkerAfterTimeout = (worker, workerIndex, reason) => {
789
851
  let cleaned = false;
790
852
  let terminateStarted = false;
853
+ let resolveSafePoint;
854
+ const safePoint = new Promise((resolve) => {
855
+ resolveSafePoint = resolve;
856
+ });
857
+ // A message/messageerror proves the worker is executing JS again; an
858
+ // exit/error means the thread is gone. Either way `worker.terminate()`
859
+ // can no longer land mid-N-API call (#2432), so shutdown's drain may
860
+ // stop waiting.
861
+ function markSafeToTerminate() {
862
+ record.safeToTerminate = true;
863
+ resolveSafePoint();
864
+ }
791
865
  function cleanupRetired() {
792
866
  if (cleaned)
793
867
  return;
@@ -806,6 +880,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
806
880
  await worker.terminate().catch(() => undefined);
807
881
  }
808
882
  function terminateWhenBackInJs() {
883
+ markSafeToTerminate();
809
884
  void terminateRetired();
810
885
  }
811
886
  function onRetiredMessage(raw) {
@@ -816,8 +891,14 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
816
891
  terminateWhenBackInJs();
817
892
  }
818
893
  }
819
- const onRetiredError = () => cleanupRetired();
820
- const onRetiredExit = () => cleanupRetired();
894
+ const onRetiredError = () => {
895
+ markSafeToTerminate();
896
+ cleanupRetired();
897
+ };
898
+ const onRetiredExit = () => {
899
+ markSafeToTerminate();
900
+ cleanupRetired();
901
+ };
821
902
  const onRetiredMessageError = () => terminateWhenBackInJs();
822
903
  const record = {
823
904
  worker,
@@ -825,6 +906,8 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
825
906
  reason,
826
907
  cleanup: cleanupRetired,
827
908
  terminate: terminateRetired,
909
+ safeToTerminate: false,
910
+ safePoint,
828
911
  };
829
912
  retiredWorkers.add(record);
830
913
  worker.on('message', onRetiredMessage);
@@ -851,7 +934,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
851
934
  return false;
852
935
  const replacement = spawnAndCapture(workerUrl);
853
936
  try {
854
- await waitForWorkerReady(replacement);
937
+ await waitForWorkerReady(replacement, poolOptions.workerReadyTimeoutMs);
855
938
  }
856
939
  catch (err) {
857
940
  await replacement.terminate().catch(() => undefined);
@@ -890,8 +973,25 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
890
973
  const liveWorkers = workers.slice();
891
974
  for (let i = 0; i < workers.length; i++)
892
975
  workers[i] = undefined;
976
+ // #2432: a live worker with a job in flight may be inside an N-API
977
+ // call — direct terminate risks the same native abort as the retired
978
+ // case. Route busy workers through the retire path (terminate at
979
+ // their next JS-visible safe point); idle workers are parked in the
980
+ // JS event loop and terminate safely right away.
981
+ const idleWorkers = [];
982
+ for (let i = 0; i < liveWorkers.length; i++) {
983
+ const worker = liveWorkers[i];
984
+ if (worker === undefined)
985
+ continue;
986
+ if (busySlots.has(i)) {
987
+ retireWorkerAfterTimeout(worker, i, 'circuit breaker tripped with job in flight');
988
+ }
989
+ else {
990
+ idleWorkers.push(worker);
991
+ }
992
+ }
893
993
  activeSlots.clear();
894
- void terminateTrackedWorkers(liveWorkers);
994
+ void terminateTrackedWorkers(idleWorkers);
895
995
  };
896
996
  const maybeDone = () => {
897
997
  if (stopped)
@@ -14,6 +14,7 @@
14
14
  import type { GraphNode, GraphRelationship } from '../../_shared/index.js';
15
15
  import { KnowledgeGraph } from '../graph/types.js';
16
16
  import { NodeTableName } from './schema.js';
17
+ import { type LayoutTableName } from './node-table-layout.js';
17
18
  /**
18
19
  * Flush buffered rows to disk once the buffered chunk reaches this many bytes.
19
20
  * Byte-bounded rather than row-count-bounded: row size ranges from a few dozen
@@ -49,6 +50,14 @@ export declare const shouldFlushCSVBuffer: (byteCount: number) => boolean;
49
50
  export declare const sanitizeUTF8: (str: string) => string;
50
51
  export declare const escapeCSVField: (value: string | number | undefined | null) => string;
51
52
  export declare const escapeCSVNumber: (value: number | undefined | null, defaultValue?: number) => string;
53
+ /**
54
+ * LadybugDB STRING[] literal inside a quoted CSV field. Elements containing a
55
+ * list metacharacter (' , [ ]) are single-quoted so comma-bearing types like
56
+ * `Table<address, u64>` survive as one element. LadybugDB keeps the quotes on
57
+ * read, so user-facing columns must strip them (see moveResources fieldList).
58
+ */
59
+ export declare const escapeCSVStringArray: (value: unknown) => string;
60
+ export declare const escapeCSVBoolean: (value: unknown) => string;
52
61
  export declare const isBinaryContent: (content: string) => boolean;
53
62
  /**
54
63
  * Flatten newlines and tabs to single spaces for FTS-indexed text columns
@@ -77,6 +86,12 @@ export declare const isBinaryContent: (content: string) => boolean;
77
86
  * otherwise fail to match whitespace-normalized indexed content.
78
87
  */
79
88
  export declare const normalizeFtsText: (text: string) => string;
89
+ /**
90
+ * Encode a row from the same ordered layout that owns its DDL, CSV header,
91
+ * and COPY column list. These tables are shared across languages, so missing
92
+ * optional properties deliberately serialize to typed defaults.
93
+ */
94
+ export declare const buildLayoutNodeRow: (table: LayoutTableName, node: GraphNode, content: string) => string;
80
95
  /** Canonical relationship CSV header — shared by the emit pass and the
81
96
  * `splitRelCsvByLabelPair` differential oracle. */
82
97
  export declare const REL_CSV_HEADER = "from,to,type,confidence,reason,step";