gitnexus 1.6.10-rc.2 → 1.6.10-rc.21

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 (219) hide show
  1. package/README.md +56 -12
  2. package/dist/cli/analyze.js +166 -5
  3. package/dist/cli/clean.js +17 -3
  4. package/dist/cli/cli-message.d.ts +1 -1
  5. package/dist/cli/doctor.d.ts +18 -0
  6. package/dist/cli/doctor.js +76 -3
  7. package/dist/cli/embeddings.d.ts +12 -0
  8. package/dist/cli/embeddings.js +49 -0
  9. package/dist/cli/help-i18n.js +4 -0
  10. package/dist/cli/i18n/en.d.ts +10 -5
  11. package/dist/cli/i18n/en.js +10 -5
  12. package/dist/cli/i18n/resources.d.ts +15 -5
  13. package/dist/cli/i18n/zh-CN.d.ts +5 -0
  14. package/dist/cli/i18n/zh-CN.js +10 -5
  15. package/dist/cli/index.js +12 -1
  16. package/dist/core/augmentation/engine.js +4 -3
  17. package/dist/core/embeddings/embedder.js +16 -2
  18. package/dist/core/embeddings/embedding-pipeline.d.ts +20 -0
  19. package/dist/core/embeddings/embedding-pipeline.js +10 -2
  20. package/dist/core/embeddings/http-client.d.ts +28 -1
  21. package/dist/core/embeddings/http-client.js +107 -15
  22. package/dist/core/embeddings/node-module-compat.d.ts +23 -0
  23. package/dist/core/embeddings/node-module-compat.js +23 -0
  24. package/dist/core/embeddings/onnxruntime-common-resolver.js +6 -3
  25. package/dist/core/embeddings/onnxruntime-node-resolver.js +31 -5
  26. package/dist/core/embeddings/runtime-install.d.ts +119 -0
  27. package/dist/core/embeddings/runtime-install.js +372 -0
  28. package/dist/core/embeddings/runtime-support.d.ts +48 -17
  29. package/dist/core/embeddings/runtime-support.js +96 -0
  30. package/dist/core/group/extractors/http-patterns/python.js +246 -108
  31. package/dist/core/group/extractors/manifest-extractor.js +4 -0
  32. package/dist/core/incremental/escalation-gate.d.ts +38 -0
  33. package/dist/core/incremental/escalation-gate.js +48 -0
  34. package/dist/core/incremental/shadow-candidates.d.ts +3 -3
  35. package/dist/core/incremental/shadow-candidates.js +3 -3
  36. package/dist/core/incremental/subgraph-extract.d.ts +2 -2
  37. package/dist/core/incremental/subgraph-extract.js +2 -2
  38. package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
  39. package/dist/core/ingestion/cobol-processor.js +27 -26
  40. package/dist/core/ingestion/community-processor.d.ts +51 -1
  41. package/dist/core/ingestion/community-processor.js +316 -63
  42. package/dist/core/ingestion/emit-references.js +3 -2
  43. package/dist/core/ingestion/languages/cpp/captures.js +157 -74
  44. package/dist/core/ingestion/markdown-processor.js +3 -2
  45. package/dist/core/ingestion/parsing-processor.d.ts +3 -1
  46. package/dist/core/ingestion/parsing-processor.js +4 -0
  47. package/dist/core/ingestion/pipeline-phases/parse-impl.js +42 -0
  48. package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
  49. package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
  50. package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
  51. package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
  52. package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -1
  53. package/dist/core/ingestion/tree-sitter-queries.js +12 -1
  54. package/dist/core/ingestion/utils/line-base.d.ts +20 -0
  55. package/dist/core/ingestion/utils/line-base.js +20 -0
  56. package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
  57. package/dist/core/ingestion/utils/symbol-labels.js +45 -0
  58. package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
  59. package/dist/core/ingestion/workers/parse-worker.js +40 -5
  60. package/dist/core/ingestion/workers/result-merge.js +4 -0
  61. package/dist/core/ingestion/workers/worker-pool.d.ts +14 -0
  62. package/dist/core/ingestion/workers/worker-pool.js +85 -5
  63. package/dist/core/lbug/csv-generator.js +8 -2
  64. package/dist/core/lbug/cypher-escape.d.ts +20 -0
  65. package/dist/core/lbug/cypher-escape.js +20 -0
  66. package/dist/core/lbug/extension-load-error.d.ts +67 -0
  67. package/dist/core/lbug/extension-load-error.js +320 -0
  68. package/dist/core/lbug/extension-loader.d.ts +17 -2
  69. package/dist/core/lbug/extension-loader.js +38 -13
  70. package/dist/core/lbug/lbug-adapter.d.ts +147 -1
  71. package/dist/core/lbug/lbug-adapter.js +390 -70
  72. package/dist/core/lbug/lbug-config.d.ts +28 -0
  73. package/dist/core/lbug/lbug-config.js +114 -4
  74. package/dist/core/lbug/native-check.d.ts +22 -0
  75. package/dist/core/lbug/native-check.js +66 -0
  76. package/dist/core/lbug/pool-adapter.js +10 -1
  77. package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
  78. package/dist/core/lbug/sidecar-recovery.js +418 -16
  79. package/dist/core/platform/capabilities.js +27 -1
  80. package/dist/core/run-analyze.js +470 -108
  81. package/dist/core/search/fts-indexes.d.ts +7 -0
  82. package/dist/core/search/fts-indexes.js +37 -0
  83. package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
  84. package/dist/core/tree-sitter/safe-parse.js +21 -7
  85. package/dist/core/wiki/graph-queries.js +6 -5
  86. package/dist/mcp/core/embedder.js +16 -2
  87. package/dist/mcp/local/line-display.d.ts +22 -0
  88. package/dist/mcp/local/line-display.js +3 -0
  89. package/dist/mcp/local/local-backend.d.ts +14 -0
  90. package/dist/mcp/local/local-backend.js +63 -19
  91. package/dist/mcp/local/pdg-impact.d.ts +5 -3
  92. package/dist/mcp/local/pdg-impact.js +5 -2
  93. package/dist/mcp/resources.js +1 -0
  94. package/dist/mcp/tools.js +1 -1
  95. package/dist/server/analyze-launch.d.ts +6 -0
  96. package/dist/server/analyze-launch.js +82 -6
  97. package/dist/server/api.d.ts +30 -0
  98. package/dist/server/api.js +63 -21
  99. package/dist/storage/parse-cache.js +1 -1
  100. package/dist/storage/repo-manager.d.ts +65 -1
  101. package/dist/storage/repo-manager.js +18 -1
  102. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
  103. package/hooks/claude/gitnexus-hook.cjs +59 -9
  104. package/package.json +5 -3
  105. package/scripts/cross-platform-tests.ts +43 -0
  106. package/scripts/ensure-fts.ts +32 -0
  107. package/scripts/install-duckdb-extension.mjs +85 -24
  108. package/scripts/run-cross-platform.ts +46 -6
  109. package/scripts/shard-arg.ts +30 -0
  110. package/web/assets/ProcessFlowModal-Dna7GkwO.js +22 -0
  111. package/web/assets/{agent-Dli_x7bU.js → agent-DNYDy-KA.js} +49 -49
  112. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
  113. package/web/assets/architectureDiagram-UL44E2DR-BU5ZRITg.js +36 -0
  114. package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-Dut1BpTV.js} +2 -2
  115. package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-DOXVs7-C.js} +2 -2
  116. package/web/assets/chunk-2T2R6R2M-pkw2oXHH.js +4 -0
  117. package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
  118. package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
  119. package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
  120. package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
  121. package/web/assets/{chunk-67TQ5CYL-4sNPJU1q.js → chunk-67TQ5CYL-zxhDWgyF.js} +3 -3
  122. package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
  123. package/web/assets/chunk-7J6CGLKN-AmkN8jJN.js +10 -0
  124. package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
  125. package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
  126. package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
  127. package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-D9BM9HWZ.js} +1 -1
  128. package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
  129. package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-tD2F6wxK.js} +1 -1
  130. package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
  131. package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
  132. package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-Ba9JK-6F.js} +2 -2
  133. package/web/assets/{chunk-LII3EMHJ-D-jm-dLa.js → chunk-LII3EMHJ-EGx-eBIu.js} +1 -1
  134. package/web/assets/chunk-LRIF4GLE-C3_PqUBq.js +1 -0
  135. package/web/assets/{chunk-QA3QBVWF-BgRW3SXd.js → chunk-QA3QBVWF-D4cSJBf6.js} +1 -1
  136. package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
  137. package/web/assets/{chunk-RG4AUYOV-CqWzWsV3.js → chunk-RG4AUYOV-OqBBMwuQ.js} +4 -4
  138. package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
  139. package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
  140. package/web/assets/{chunk-T2UQINTJ-DSBqkzH7.js → chunk-T2UQINTJ-BJusEiGe.js} +1 -1
  141. package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
  142. package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
  143. package/web/assets/{chunk-UY5QBCOK-DyF0vyGd.js → chunk-UY5QBCOK-BCpUlARQ.js} +1 -1
  144. package/web/assets/chunk-VU6ZFW4Y-BeXVk45_.js +2 -0
  145. package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
  146. package/web/assets/{chunk-ZXARS5L4-CxN8oiwI.js → chunk-ZXARS5L4-BI_qR2Nm.js} +1 -1
  147. package/web/assets/classDiagram-KGZ6W3CR-D9zSIg0x.js +1 -0
  148. package/web/assets/classDiagram-v2-72OJOZXJ-D9zSIg0x.js +1 -0
  149. package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
  150. package/web/assets/dagre-ND4H6XIP-CpcV5kbl.js +4 -0
  151. package/web/assets/diagram-3NCE3AQN-6SMxBRpj.js +43 -0
  152. package/web/assets/diagram-GF46GFSD-BZEdNcRZ.js +24 -0
  153. package/web/assets/{diagram-HNR7UZ2L-DFCfd5LI.js → diagram-HNR7UZ2L-DxKW2a2Y.js} +2 -2
  154. package/web/assets/diagram-QXG6HAR7-HfTHcXX_.js +24 -0
  155. package/web/assets/diagram-WEQXMOUZ-CyijUS8r.js +10 -0
  156. package/web/assets/{erDiagram-L5TCEMPS-8X1y6R4Y.js → erDiagram-L5TCEMPS-D0fvpWEX.js} +3 -3
  157. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
  158. package/web/assets/flowDiagram-H6V6AXG4-Bvr9bbhk.js +162 -0
  159. package/web/assets/{ganttDiagram-JCBTUEKG-D3iL2Aet.js → ganttDiagram-JCBTUEKG-TzODrLzv.js} +2 -2
  160. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
  161. package/web/assets/gitGraphDiagram-S2ZK5IYY-ONQSwJIY.js +106 -0
  162. package/web/assets/index-B4eB4dNZ.js +575 -0
  163. package/web/assets/index-CX_fADmQ.css +2 -0
  164. package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
  165. package/web/assets/infoDiagram-3YFTVSEB-DIPVUIQ6.js +2 -0
  166. package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-BLjivjXL.js} +3 -3
  167. package/web/assets/{journeyDiagram-M6C3CM3L-CvArszLo.js → journeyDiagram-M6C3CM3L-Cetgs3NH.js} +3 -3
  168. package/web/assets/{kanban-definition-75IXJCU3-CpfVLLf9.js → kanban-definition-75IXJCU3-DMlCaIpf.js} +5 -5
  169. package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
  170. package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-B4GbXQBc.js} +3 -3
  171. package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
  172. package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
  173. package/web/assets/{pieDiagram-CU6KROY3-s27EFWgP.js → pieDiagram-CU6KROY3-D3YC_xyg.js} +2 -2
  174. package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-B1TQnlm0.js} +2 -2
  175. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
  176. package/web/assets/{requirementDiagram-JXO7QTGE-CWhqInuf.js → requirementDiagram-JXO7QTGE-f8wczLQf.js} +3 -3
  177. package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  178. package/web/assets/{sankeyDiagram-URQDO5SZ-1qEjlFIB.js → sankeyDiagram-URQDO5SZ-BTxzG5j0.js} +2 -2
  179. package/web/assets/{sequenceDiagram-VS2MUI6T-RyTlZ5cR.js → sequenceDiagram-VS2MUI6T-DuamM-IR.js} +5 -5
  180. package/web/assets/src-BNCXICdA.js +1 -0
  181. package/web/assets/stateDiagram-7D4R322I-Ch2pEUcw.js +1 -0
  182. package/web/assets/stateDiagram-v2-36443NZ5-7ANuoZLL.js +1 -0
  183. package/web/assets/{timeline-definition-O6YCAMPW-DrrqLYAf.js → timeline-definition-O6YCAMPW-07BR8R8G.js} +3 -3
  184. package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
  185. package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
  186. package/web/assets/{vennDiagram-MWXL3ELB-B0RkWAim.js → vennDiagram-MWXL3ELB-BQX2ossk.js} +4 -4
  187. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
  188. package/web/assets/{wardleyDiagram-CUQ6CDDI-boUxiQ5F.js → wardleyDiagram-CUQ6CDDI-CGIJBBiK.js} +3 -3
  189. package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-B3HNMuWp.js} +4 -4
  190. package/web/index.html +17 -10
  191. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
  192. package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
  193. package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
  194. package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
  195. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
  196. package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
  197. package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
  198. package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
  199. package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
  200. package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
  201. package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
  202. package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
  203. package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
  204. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
  205. package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
  206. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
  207. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
  208. package/web/assets/index-KctnI3Vq.js +0 -635
  209. package/web/assets/index-_lgn7hs5.css +0 -2
  210. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
  211. package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
  212. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
  213. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
  214. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
  215. package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
  216. package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
  217. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
  218. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
  219. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
@@ -62,6 +62,31 @@ export declare function isWalCorruptionError(err: unknown): boolean;
62
62
  * back to the permissive matcher.
63
63
  */
64
64
  export declare const isLbugCheckpointIoError: (err: unknown) => boolean;
65
+ /**
66
+ * True when `err` looks like the LadybugDB buffer manager failing to release
67
+ * frame memory — the failure mode of a 4 KiB page-size assumption on a
68
+ * 16 KiB/64 KiB-page kernel (#1231). Deliberately does NOT match the
69
+ * generic "buffer pool is full" exhaustion error, which is a sizing
70
+ * problem, not a page-size one.
71
+ */
72
+ export declare const isLbugPageSizeFrameError: (err: unknown) => boolean;
73
+ /**
74
+ * True when the given `@ladybugdb/core` version contains the runtime
75
+ * OS-page-size detection introduced in 0.18.0 (see the matcher comment
76
+ * above). Unknown/unparseable versions return false so callers err on the
77
+ * side of showing the upgrade hint.
78
+ */
79
+ export declare const isPageSizeAwareLadybug: (version: string | undefined) => boolean;
80
+ /**
81
+ * OS memory page size in bytes, or `undefined` when it cannot be determined
82
+ * (Windows, missing getconf, sandboxed exec). Node exposes no page-size API,
83
+ * so this shells out to POSIX `getconf PAGE_SIZE` — same execFileSync shape
84
+ * as the Windows 8.3 short-path probe above, but with a tighter timeout and
85
+ * an explicit killSignal (see the options comment below).
86
+ */
87
+ export declare const getOsPageSize: () => number | undefined;
88
+ /** Exported only for unit tests — clears the getconf probe cache. */
89
+ export declare const _resetOsPageSizeCacheForTest: () => void;
65
90
  type LbugModule = typeof lbug;
66
91
  export interface LbugDatabaseOptions {
67
92
  readOnly?: boolean;
@@ -108,6 +133,8 @@ export type DeleteAllErrorClass = 'benign-missing-table' | 'rethrow';
108
133
  */
109
134
  export declare const classifyDeleteAllError: (err: unknown) => DeleteAllErrorClass;
110
135
  export declare function createLbugDatabase(lbugModule: LbugModule, databasePath: string, options?: LbugDatabaseOptions): lbug.Database;
136
+ export declare const HANDLE_RELEASE_PROBE_ATTEMPTS = 5;
137
+ export declare const HANDLE_RELEASE_PROBE_DELAY_MS = 50;
111
138
  /**
112
139
  * Marker symbol attached to lock errors after `openWithLockRetry` exhausts
113
140
  * its budget. `withLbugDb`'s outer query-time retry consults this so it
@@ -121,6 +148,7 @@ export declare const LBUG_OPEN_RETRY_EXHAUSTED: unique symbol;
121
148
  export declare const isOpenRetryExhausted: (err: unknown) => boolean;
122
149
  /** Exported only for direct unit testing — production callers use `openWithLockRetry`. */
123
150
  export declare const _isTestFixturePathForTest: (dbPath: string) => boolean;
151
+ export declare const sleep: (ms: number) => Promise<void>;
124
152
  export declare function openLbugConnection(lbugModule: LbugModule, databasePath: string, options?: LbugDatabaseOptions): Promise<LbugConnectionHandle>;
125
153
  export declare function closeLbugConnection(handle: LbugConnectionHandle): Promise<void>;
126
154
  /**
@@ -337,6 +337,106 @@ export const isLbugCheckpointIoError = (err) => {
337
337
  return true;
338
338
  return LBUG_CHECKPOINT_PERMISSIVE_RE.test(msg);
339
339
  };
340
+ // ─── Ladybug non-4K page-size frame-release matcher (#1231) ─────────────────
341
+ //
342
+ // LadybugDB <= 0.17.x hardcoded a 4 KiB OS-page assumption in its buffer
343
+ // manager: evicting a frame released physical memory with
344
+ // `madvise(frame, frameSize, MADV_DONTNEED)` on 4 KiB-aligned frame
345
+ // addresses (verified by disassembling `VMRegion::releaseFrame` in
346
+ // @ladybugdb/core-linux-arm64 0.17.1 — `mov w2, #0x4` = MADV_DONTNEED,
347
+ // throw on non-zero return). On kernels with 16 KiB pages (Raspberry Pi 5
348
+ // default 2712 kernel, Asahi Linux) or 64 KiB pages (some enterprise arm64
349
+ // distros), madvise rejects addresses that are not multiples of the real
350
+ // page size with EINVAL, surfacing as:
351
+ // "Buffer manager exception: Releasing physical memory associated with a
352
+ // frame failed with error code -1: Invalid argument."
353
+ // which aborts `gitnexus analyze` mid-COPY.
354
+ //
355
+ // @ladybugdb/core 0.18.0 rewrote the release path with runtime OS-page-size
356
+ // detection and discard-granule-aligned madvise (new binary strings:
357
+ // "Failed to detect the operating system page size.", "Unsupported page
358
+ // size combination: frame size {}, discard granule size {}, frame group
359
+ // size {}."), so upgrading is the fix. The residual 0.18.0 guard
360
+ // ("Unsupported page size combination") is matched here too so exotic
361
+ // configurations receive the same actionable guidance instead of a raw
362
+ // native message.
363
+ const LBUG_FRAME_RELEASE_RE = /releasing physical memory associated with a frame failed/i;
364
+ const LBUG_PAGE_COMBO_RE = /unsupported page size combination/i;
365
+ /**
366
+ * True when `err` looks like the LadybugDB buffer manager failing to release
367
+ * frame memory — the failure mode of a 4 KiB page-size assumption on a
368
+ * 16 KiB/64 KiB-page kernel (#1231). Deliberately does NOT match the
369
+ * generic "buffer pool is full" exhaustion error, which is a sizing
370
+ * problem, not a page-size one.
371
+ */
372
+ export const isLbugPageSizeFrameError = (err) => {
373
+ if (!err)
374
+ return false;
375
+ const msg = err instanceof Error ? err.message : String(err);
376
+ return LBUG_FRAME_RELEASE_RE.test(msg) || LBUG_PAGE_COMBO_RE.test(msg);
377
+ };
378
+ /**
379
+ * True when the given `@ladybugdb/core` version contains the runtime
380
+ * OS-page-size detection introduced in 0.18.0 (see the matcher comment
381
+ * above). Unknown/unparseable versions return false so callers err on the
382
+ * side of showing the upgrade hint.
383
+ */
384
+ export const isPageSizeAwareLadybug = (version) => {
385
+ if (!version)
386
+ return false;
387
+ const m = /^(\d+)\.(\d+)/.exec(version.trim());
388
+ if (!m)
389
+ return false;
390
+ const major = Number(m[1]);
391
+ const minor = Number(m[2]);
392
+ return major > 0 || minor >= 18;
393
+ };
394
+ // `undefined` = not probed yet; `null` = probed and unavailable. Cached
395
+ // because analyze error paths and doctor may both ask, and getconf forks.
396
+ let cachedOsPageSize;
397
+ /**
398
+ * OS memory page size in bytes, or `undefined` when it cannot be determined
399
+ * (Windows, missing getconf, sandboxed exec). Node exposes no page-size API,
400
+ * so this shells out to POSIX `getconf PAGE_SIZE` — same execFileSync shape
401
+ * as the Windows 8.3 short-path probe above, but with a tighter timeout and
402
+ * an explicit killSignal (see the options comment below).
403
+ */
404
+ export const getOsPageSize = () => {
405
+ if (cachedOsPageSize !== undefined)
406
+ return cachedOsPageSize ?? undefined;
407
+ if (process.platform === 'win32') {
408
+ // Windows allocation granularity is not what madvise alignment is about;
409
+ // the #1231 failure mode is POSIX-only.
410
+ cachedOsPageSize = null;
411
+ return undefined;
412
+ }
413
+ try {
414
+ // killSignal SIGKILL (first use in this repo): the default SIGTERM is
415
+ // catchable, so a signal-trapping child held the "5s" timeout for 9s in
416
+ // review reproduction — SIGKILL makes the timeout real for everything
417
+ // except a child stuck in uninterruptible I/O (D state). 2000ms, not
418
+ // 5000: doctor runs this probe on its happy path and real getconf
419
+ // answers in ~2ms, but keep margin for loaded Pi-class hardware — a
420
+ // too-tight ceiling would silently drop the very #1231 diagnostics this
421
+ // probe exists to provide (the catch caches the failure). (#2424 review)
422
+ const out = execFileSync('getconf', ['PAGE_SIZE'], {
423
+ encoding: 'utf-8',
424
+ timeout: 2000,
425
+ killSignal: 'SIGKILL',
426
+ stdio: ['ignore', 'pipe', 'pipe'],
427
+ });
428
+ const parsed = Number(out.trim());
429
+ cachedOsPageSize = Number.isInteger(parsed) && parsed > 0 ? parsed : null;
430
+ }
431
+ catch {
432
+ cachedOsPageSize = null;
433
+ }
434
+ return cachedOsPageSize ?? undefined;
435
+ };
436
+ /** Exported only for unit tests — clears the getconf probe cache. */
437
+ export const _resetOsPageSizeCacheForTest = () => {
438
+ cachedOsPageSize = undefined;
439
+ };
340
440
  /**
341
441
  * Return true when the error message indicates that a LadybugDB write
342
442
  * transaction could not proceed due to lock contention — either a file
@@ -411,7 +511,10 @@ export function createLbugDatabase(lbugModule, databasePath, options = {}) {
411
511
  // 1. OPEN_LOCK_RETRY_ATTEMPTS / OPEN_LOCK_RETRY_DELAY_MS (this file)
412
512
  // → `new lbug.Database()` constructor lock failures
413
513
  // 2. HANDLE_RELEASE_PROBE_ATTEMPTS / HANDLE_RELEASE_PROBE_DELAY_MS (this file)
414
- // → post-close fs.open probe to absorb Windows handle-release lag
514
+ // → post-close fs.open probe to absorb Windows handle-release lag; also
515
+ // the shared budget for wipeLbugDbFiles' ENOENT-verified removal
516
+ // (lbug-adapter.ts) and the dirty-recovery sidecar park's
517
+ // rename/rm retries (sidecar-recovery.ts) — same lock class
415
518
  // 3. DB_LOCK_RETRY_ATTEMPTS / DB_LOCK_RETRY_DELAY_MS (lbug-adapter.ts withLbugDb)
416
519
  // → query-time busy/lock retry around already-open connections
417
520
  //
@@ -429,8 +532,13 @@ export function createLbugDatabase(lbugModule, databasePath, options = {}) {
429
532
  // matches on is unchanged.)
430
533
  const OPEN_LOCK_RETRY_ATTEMPTS = 5;
431
534
  const OPEN_LOCK_RETRY_DELAY_MS = 100;
432
- const HANDLE_RELEASE_PROBE_ATTEMPTS = 5;
433
- const HANDLE_RELEASE_PROBE_DELAY_MS = 50;
535
+ // Exported (this shipping review, FIX 1/2): the dirty-recovery sidecar park
536
+ // (sidecar-recovery.ts) and the ENOENT-verified wipe (lbug-adapter.ts
537
+ // wipeLbugDbFiles) retry the SAME Windows handle-release/AV lock class, and
538
+ // their previous private mirror constants were documentation-coupled copies
539
+ // that could drift from this tuning-knob registry silently.
540
+ export const HANDLE_RELEASE_PROBE_ATTEMPTS = 5;
541
+ export const HANDLE_RELEASE_PROBE_DELAY_MS = 50;
434
542
  const HANDLE_RELEASE_LOCK_CODES = new Set(['EBUSY', 'EPERM', 'EACCES']);
435
543
  /**
436
544
  * Test-fixture directory prefixes recognized by `isTestFixturePath`.
@@ -492,7 +600,9 @@ const isTestFixturePath = (dbPath) => {
492
600
  };
493
601
  /** Exported only for direct unit testing — production callers use `openWithLockRetry`. */
494
602
  export const _isTestFixturePathForTest = isTestFixturePath;
495
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
603
+ // Exported alongside HANDLE_RELEASE_PROBE_* (this shipping review, FIX 1/2)
604
+ // so the consumers of the shared retry budget do not each grow a private copy.
605
+ export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
496
606
  /**
497
607
  * Attempt to remove stale `.wal` / `.lock` sidecars that a previous aborted
498
608
  * test run may have left behind. Best-effort: ENOENT is normal, anything
@@ -4,3 +4,25 @@ export interface NativeCheckResult {
4
4
  message?: string;
5
5
  }
6
6
  export declare function checkLbugNative(overridePkgDir?: string): NativeCheckResult;
7
+ export interface FtsProbeResult {
8
+ loaded: boolean;
9
+ /** Collapsed LadybugDB error when `loaded` is false. */
10
+ reason?: string;
11
+ }
12
+ /**
13
+ * Live-probe `LOAD EXTENSION fts` on a throwaway in-memory database.
14
+ *
15
+ * `doctor` used to print the static platform capability, which contradicted
16
+ * analyze whenever the extension file was missing or unloadable (#2374).
17
+ * LOAD never touches the network, so the probe is safe offline, and it
18
+ * surfaces LadybugDB's real error — which distinguishes a missing extension
19
+ * file from a present-but-broken one (wrong platform, truncated download).
20
+ * Dynamic import so doctor still runs when the native module itself is broken.
21
+ *
22
+ * Bounded by `timeoutMs`: an unresponsive extension file (e.g. on a hung
23
+ * network home dir) must never freeze `doctor` — the tool the degradation
24
+ * warnings send users to. `Promise.race` lets doctor report and move on; it
25
+ * cannot cancel an in-flight native call, so a future thread-blocking case
26
+ * would need an out-of-process probe.
27
+ */
28
+ export declare function probeFtsExtensionLoad(timeoutMs?: number): Promise<FtsProbeResult>;
@@ -81,3 +81,69 @@ export function checkLbugNative(overridePkgDir) {
81
81
  }
82
82
  return { ok: true, binaryPath };
83
83
  }
84
+ const DEFAULT_FTS_PROBE_TIMEOUT_MS = 10_000;
85
+ /** Close each result, swallowing close-time errors so a successful LOAD is not
86
+ * misreported as a failure (native-check keeps no static lbug dependency, so it
87
+ * cannot reuse the adapter's closeQueryResults — that would eagerly load the
88
+ * module and defeat the dynamic import below). */
89
+ const closeProbeResults = (result) => {
90
+ for (const r of Array.isArray(result) ? result : [result]) {
91
+ try {
92
+ r?.close?.();
93
+ }
94
+ catch {
95
+ // ignore — a close failure must not flip a successful LOAD to failed
96
+ }
97
+ }
98
+ };
99
+ /**
100
+ * Live-probe `LOAD EXTENSION fts` on a throwaway in-memory database.
101
+ *
102
+ * `doctor` used to print the static platform capability, which contradicted
103
+ * analyze whenever the extension file was missing or unloadable (#2374).
104
+ * LOAD never touches the network, so the probe is safe offline, and it
105
+ * surfaces LadybugDB's real error — which distinguishes a missing extension
106
+ * file from a present-but-broken one (wrong platform, truncated download).
107
+ * Dynamic import so doctor still runs when the native module itself is broken.
108
+ *
109
+ * Bounded by `timeoutMs`: an unresponsive extension file (e.g. on a hung
110
+ * network home dir) must never freeze `doctor` — the tool the degradation
111
+ * warnings send users to. `Promise.race` lets doctor report and move on; it
112
+ * cannot cancel an in-flight native call, so a future thread-blocking case
113
+ * would need an out-of-process probe.
114
+ */
115
+ export async function probeFtsExtensionLoad(timeoutMs = DEFAULT_FTS_PROBE_TIMEOUT_MS) {
116
+ let timer;
117
+ const timeout = new Promise((resolve) => {
118
+ timer = setTimeout(() => resolve({
119
+ loaded: false,
120
+ reason: 'probe timed out — extension file or filesystem unresponsive',
121
+ }), timeoutMs);
122
+ });
123
+ const probe = (async () => {
124
+ try {
125
+ const { default: lbug } = await import('@ladybugdb/core');
126
+ const db = new lbug.Database(':memory:');
127
+ // Nested finallys so `db` is closed even if the Connection ctor throws.
128
+ try {
129
+ const conn = new lbug.Connection(db);
130
+ try {
131
+ const result = await conn.query('LOAD EXTENSION fts');
132
+ closeProbeResults(result);
133
+ return { loaded: true };
134
+ }
135
+ finally {
136
+ await conn.close().catch(() => { });
137
+ }
138
+ }
139
+ finally {
140
+ await db.close().catch(() => { });
141
+ }
142
+ }
143
+ catch (err) {
144
+ const message = err instanceof Error ? err.message : String(err);
145
+ return { loaded: false, reason: message.replace(/\s+/g, ' ').trim() };
146
+ }
147
+ })();
148
+ return await Promise.race([probe, timeout]).finally(() => clearTimeout(timer));
149
+ }
@@ -19,7 +19,7 @@ import lbug from '@ladybugdb/core';
19
19
  import { isReadOnlyDbError, loadFTSExtension } from './lbug-adapter.js';
20
20
  import { closeQueryResults } from './query-result-utils.js';
21
21
  import { createLbugDatabase, isWalCorruptionError, toNativeSafePath, WAL_RECOVERY_SUGGESTION, } from './lbug-config.js';
22
- import { isMissingFsError, isMissingShadowSidecarError, isReadOnlyShadowReplayError, preflightLbugSidecars, quarantineWalForMissingShadow, renameFailureMessage, statIfExists, } from './sidecar-recovery.js';
22
+ import { guardWalQuarantine, isMissingFsError, isMissingShadowSidecarError, isReadOnlyShadowReplayError, preflightLbugSidecars, quarantineWalForMissingShadow, renameFailureMessage, statIfExists, } from './sidecar-recovery.js';
23
23
  const pool = new Map();
24
24
  const poolCloseListeners = new Set();
25
25
  /**
@@ -349,6 +349,12 @@ const poolSidecarLogger = {
349
349
  * See plan: docs/plans/2026-05-21-001-fix-pr-1747-quarantine-enoent-and-large-wal-plan.md (U2)
350
350
  */
351
351
  async function tryQuarantineForMissingShadow(dbPath, opts) {
352
+ // Refuse (throw) before renaming a live WAL when the shadow is present on
353
+ // disk or the orphan WAL is too large — parity with the serve path's
354
+ // refuseLargeWalQuarantine (issue #2382 review, Finding B). Kept OUTSIDE the
355
+ // try so the actionable recovery message propagates to the MCP caller rather
356
+ // than being re-wrapped as a rename failure.
357
+ await guardWalQuarantine(dbPath, opts.reason, opts.err, poolSidecarLogger);
352
358
  try {
353
359
  const quarantinePath = await quarantineWalForMissingShadow(dbPath, {
354
360
  logger: poolSidecarLogger,
@@ -396,6 +402,7 @@ async function replayShadowPagesWithWritableOpen(dbPath) {
396
402
  if (isMissingShadowSidecarError(err)) {
397
403
  await tryQuarantineForMissingShadow(dbPath, {
398
404
  reason: 'pool writable replay recovery',
405
+ err,
399
406
  });
400
407
  return;
401
408
  }
@@ -429,6 +436,7 @@ async function openReadOnlyDatabase(dbPath) {
429
436
  db = undefined;
430
437
  await tryQuarantineForMissingShadow(dbPath, {
431
438
  reason: 'pool read-only recovery',
439
+ err,
432
440
  });
433
441
  await preflightLbugSidecars(dbPath, {
434
442
  mode: 'read-only',
@@ -559,6 +567,7 @@ async function doInitLbug(repoId, dbPath) {
559
567
  }
560
568
  }
561
569
  if (lastError.message.startsWith('LadybugDB checkpoint sidecar is missing') ||
570
+ lastError.message.startsWith('LadybugDB checkpoint sidecar is present but unreachable') ||
562
571
  lastError.message.startsWith('GitNexus could not move the LadybugDB WAL sidecar') ||
563
572
  isMissingShadowSidecarError(lastError)) {
564
573
  throw lastError;
@@ -32,7 +32,31 @@ export declare const statIfExists: (filePath: string) => Promise<{
32
32
  export declare const isMissingShadowSidecarError: (err: unknown) => boolean;
33
33
  export declare const isReadOnlyShadowReplayError: (err: unknown) => boolean;
34
34
  export declare const shadowSidecarRecoveryMessage: (dbPath: string, err: unknown) => string;
35
+ /**
36
+ * Actionable message for the case where LadybugDB reports a "missing shadow"
37
+ * but `inspectLbugSidecars` finds the `.shadow` PRESENT on disk — the open
38
+ * failed on path reachability or a lock, not a genuinely-missing sidecar (issue
39
+ * #2382 review, S2). Unlike `shadowSidecarRecoveryMessage` it does NOT tell the
40
+ * operator to rebuild the index (the remedy is fixing the lock/path). Keeps the
41
+ * `Original error:` tail so downstream `isMissingShadowSidecarError` recognition
42
+ * still matches the wrapped error.
43
+ */
44
+ export declare const presentShadowUnreachableMessage: (dbPath: string, err: unknown) => string;
35
45
  export declare const isPermissionRenameError: (err: unknown) => boolean;
46
+ /**
47
+ * Canonical remediation guidance for the LadybugDB file-lock class
48
+ * (EBUSY/EPERM/EACCES — an MCP/serve process holding the index, or an
49
+ * antivirus scan). One exported producer (this shipping review, FIX 7):
50
+ * the dirty-recovery park warning below, `LbugWipeError`'s message builder
51
+ * (lbug-adapter.ts) and {@link renameFailureMessage} previously carried
52
+ * three divergent hand-written copies of the same advice.
53
+ *
54
+ * `rerun` names the command to retry once the lock clears — the analyze
55
+ * wipe/park surfaces re-run the analyze; the read-path quarantine surface
56
+ * re-runs whatever command failed. No trailing period: callers own the
57
+ * sentence end.
58
+ */
59
+ export declare const lbugLockRemediation: (rerun?: string) => string;
36
60
  /**
37
61
  * Classify a failure surfaced by quarantine rename into an actionable user-facing
38
62
  * message.
@@ -50,6 +74,28 @@ export declare const isPermissionRenameError: (err: unknown) => boolean;
50
74
  */
51
75
  export declare const renameFailureMessage: (dbPath: string, err: unknown) => string;
52
76
  export declare function inspectLbugSidecars(dbPath: string): Promise<LbugSidecarState>;
77
+ /**
78
+ * Reject the WAL-quarantine path when discarding the WAL would be unsafe or
79
+ * wrong. Shared by every reactive missing-shadow recovery consumer — serve (via
80
+ * lbug-adapter's `refuseLargeWalQuarantine`) and the MCP/wiki/augmentation pool
81
+ * (via pool-adapter's `tryQuarantineForMissingShadow`) — so the quarantine
82
+ * safety policy has a single source of truth (issue #2382 review, Finding B).
83
+ *
84
+ * 1. `wal-with-shadow` — the `.shadow` sidecar is PRESENT on disk. A
85
+ * "missing shadow" error alongside a present shadow means the open failed
86
+ * on path reachability or a lock (the #1811 non-ASCII path-garble on
87
+ * Windows), not a genuinely-missing shadow; quarantining would move a live
88
+ * WAL sitting next to its shadow — data loss.
89
+ * 2. `orphan-wal` — the orphan WAL is too large to safely discard
90
+ * (>TINY_ORPHAN_WAL_BYTES); preserve the uncheckpointed pages for explicit
91
+ * operator recovery.
92
+ *
93
+ * Throws `shadowSidecarRecoveryMessage` in either case. Returns silently only
94
+ * when the shadow is absent AND the WAL is absent or tiny — the states where
95
+ * the existing recovery path is safe to proceed. `mode` is a label used only in
96
+ * the warning text (e.g. 'read-only', 'writable', 'pool read-only recovery').
97
+ */
98
+ export declare const guardWalQuarantine: (dbPath: string, mode: string, triggeringErr: unknown, logger: SidecarRecoveryLogger) => Promise<void>;
53
99
  export declare function quarantineWalForMissingShadow(dbPath: string, options: {
54
100
  logger: SidecarRecoveryLogger;
55
101
  level?: 'debug' | 'info' | 'warn';
@@ -63,6 +109,132 @@ export declare function preflightLbugSidecars(dbPath: string, options: {
63
109
  export declare function finalizeLbugSidecarsAfterClose(dbPath: string, options: {
64
110
  logger: SidecarRecoveryLogger;
65
111
  }): Promise<void>;
112
+ /**
113
+ * Move the WAL/shadow sidecars aside before a dirty-flag recovery rebuild
114
+ * (#2409 defect 2).
115
+ *
116
+ * When `incrementalInProgress` forces a full rebuild, the previous run
117
+ * died mid-writeback — its WAL can be poisoned in a way that natively
118
+ * kills the process on replay. The recovery run used to open the DB
119
+ * BEFORE the rebuild wipe (the embedding-cache preservation open), replay
120
+ * the poisoned WAL, and die on the spot — so recovery never happened and
121
+ * only a manual rename-aside of the index dir escaped the loop. The
122
+ * rebuild discards every pending WAL byte anyway (the DB files are wiped),
123
+ * so parking the sidecars first costs nothing and makes every subsequent
124
+ * open replay-free.
125
+ *
126
+ * Renamed when possible, so the bytes stay available for post-mortem
127
+ * debugging — and, like {@link quarantineWalForMissingShadow}'s quarantine
128
+ * files, the parked copies are surfaced and removable by
129
+ * `gitnexus clean --lbug-sidecars` (tri-review 4669518496 P2-7; before
130
+ * that, this comment claimed a "same philosophy" parity while the
131
+ * dirty-recovery files were invisible to every cleanup surface). Real
132
+ * lifecycle: the destinations are FIXED names — no timestamp, see
133
+ * {@link listParkedDirtyRecoverySidecars} — so each new crash overwrites
134
+ * the previous parked copy, capping accumulation at one file per sidecar;
135
+ * remove them via `clean --lbug-sidecars` or manually once their
136
+ * post-mortem value has passed.
137
+ *
138
+ * Escalation ladder per suffix (this shipping review, FIX 1 — replacing
139
+ * the drop-shape design, whose park had ZERO retry while the wipe path
140
+ * retried the very same lock class):
141
+ *
142
+ * 1. `rename(from, to)` retried over the shared handle-release budget
143
+ * (HANDLE_RELEASE_PROBE_ATTEMPTS × linear HANDLE_RELEASE_PROBE_DELAY_MS,
144
+ * lbug-config.ts) — a transient AV/handle-lag EBUSY must not cost the
145
+ * run anything.
146
+ * 2. Structural confirm probe: a bare "does `to` exist?" check cannot
147
+ * discriminate a Windows rename-onto-existing collision from a locked
148
+ * source that happens to have a leftover parked copy. Renaming the
149
+ * source to the collision-free `${to}.next` can — success proves the
150
+ * failure was the collision, so the stale copy is replaced (newest
151
+ * forensics win). The crash window between the `rm(to)` and the final
152
+ * promote rename strands the bytes at `.next` — acceptable: `.next`
153
+ * residues are enumerated by the dirty-recovery lister and removed by
154
+ * `clean --lbug-sidecars` (FIX 5). Never pre-delete the previous
155
+ * crash's parked copy on the bet that a rename will then succeed
156
+ * (tri-review 4669518496 P2-3: the old rm-first shape destroyed the
157
+ * prior forensics exactly when the source was locked and nothing
158
+ * replaced them).
159
+ * 3. rm-fallback: the source itself is locked for RENAME, but Windows
160
+ * lets some holders' files be unlink-marked — retry
161
+ * `rm(from, {force:true})` over the same budget and require the file
162
+ * verifiably GONE. Success eliminates the replay risk at the cost of
163
+ * the post-mortem forensics (logged exactly so).
164
+ * 4. Report in `failed` with the corrected lock guidance — the caller
165
+ * must abort (run-analyze throws a LbugWipeError in seconds instead
166
+ * of running the whole pipeline and dying at the wipe on the same
167
+ * handle).
168
+ *
169
+ * Per-suffix isolation: a `.wal` failure never skips the `.shadow`
170
+ * attempt.
171
+ *
172
+ * INVARIANT: after this function returns, either no original sidecar
173
+ * remains adjacent to the DB — every entry is in `moved` or `removed`, so
174
+ * every subsequent open this run performs is replay-free — or the entry is
175
+ * in `failed` and the caller MUST abort before any DB open.
176
+ *
177
+ * @returns `moved` — destination paths now holding the parked bytes;
178
+ * `removed` — source sidecars whose bytes are GONE (forensics lost, replay
179
+ * risk eliminated); `failed` — source sidecars still in place: a
180
+ * possibly-poisoned sidecar sits next to the DB and any pre-wipe open
181
+ * would replay it and die (there is no "wipe it in place" fallback).
182
+ */
183
+ export declare function quarantineSidecarsForDirtyRecovery(dbPath: string, log: (message: string) => void): Promise<{
184
+ moved: string[];
185
+ removed: string[];
186
+ failed: string[];
187
+ }>;
66
188
  export declare function listQuarantinedMissingShadowWals(dbPath: string): Promise<string[]>;
189
+ /**
190
+ * Delete the missing-shadow WAL quarantines for `dbPath` and return the
191
+ * deleted paths. Locked files are skipped, not thrown (FIX 5) — user-facing
192
+ * surfaces should call {@link cleanParkedLbugSidecars}, which also REPORTS
193
+ * the skipped files.
194
+ */
67
195
  export declare function cleanQuarantinedMissingShadowWals(dbPath: string): Promise<string[]>;
196
+ /**
197
+ * List the `.dirty-recovery` sidecars parked beside `dbPath` by
198
+ * {@link quarantineSidecarsForDirtyRecovery}, so `gitnexus clean
199
+ * --lbug-sidecars` can surface them next to the missing-shadow quarantines
200
+ * (tri-review 4669518496 P2-7 — they were previously invisible to every
201
+ * cleanup surface). Only fixed names can exist (see
202
+ * {@link dirtyRecoveryParkedNames}: `<dbPath>.wal.dirty-recovery`,
203
+ * `<dbPath>.shadow.dirty-recovery`, and their `.next` probe residues from a
204
+ * double park failure — enumerated since FIX 5 of this shipping review; the
205
+ * docs used to say "remove manually" while no surface even listed them), so
206
+ * this stats them directly instead of prefix-scanning the directory the way
207
+ * the timestamped missing-shadow lister must.
208
+ *
209
+ * Returns existing parked files as sorted absolute paths. Branch-scoped
210
+ * index slots (`branches/<slug>/`) are outside `clean.ts`'s flat-path
211
+ * resolution — the same documented limitation as the missing-shadow pair.
212
+ */
213
+ export declare function listParkedDirtyRecoverySidecars(dbPath: string): Promise<string[]>;
214
+ /**
215
+ * Delete the `.dirty-recovery` parked sidecars for `dbPath` and return the
216
+ * deleted paths. Sibling of {@link cleanQuarantinedMissingShadowWals}; same
217
+ * skip-not-throw policy (FIX 5) — user-facing surfaces should call
218
+ * {@link cleanParkedLbugSidecars}, which also reports locked files.
219
+ */
220
+ export declare function cleanParkedDirtyRecoverySidecars(dbPath: string): Promise<string[]>;
221
+ /**
222
+ * Aggregate roster of every parked/quarantined sidecar family beside
223
+ * `dbPath` (this shipping review, FIX 5): the timestamped missing-shadow
224
+ * WAL quarantines plus the fixed-name dirty-recovery parks (`.next`
225
+ * residues included). Single roster authority for `clean --lbug-sidecars`
226
+ * — the command previously concatenated the families inline in two places,
227
+ * which is how the `.next` residue stayed invisible.
228
+ */
229
+ export declare function listParkedLbugSidecars(dbPath: string): Promise<string[]>;
230
+ /**
231
+ * Delete every file {@link listParkedLbugSidecars} enumerates. Per-file
232
+ * error policy via {@link unlinkParkedFiles}: ENOENT skipped silently,
233
+ * locked files collected into `failed` while the rest are still deleted —
234
+ * a locked parked file must not crash the whole clean mid-command.
235
+ */
236
+ export declare function cleanParkedLbugSidecars(dbPath: string): Promise<{
237
+ deleted: string[];
238
+ failed: string[];
239
+ }>;
68
240
  export declare const _resetSidecarRecoveryWarningsForTest: () => void;