@wirecat/bitrix24-cli 0.3.0 → 0.5.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 (255) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +84 -9
  3. package/dist/api-keys.d.ts +36 -9
  4. package/dist/api-keys.d.ts.map +1 -1
  5. package/dist/api-keys.js +139 -19
  6. package/dist/api-keys.js.map +1 -1
  7. package/dist/bin/b24.js +2 -2
  8. package/dist/bitrix/errors.js +1 -1
  9. package/dist/bitrix/errors.js.map +1 -1
  10. package/dist/bitrix/methods.d.ts.map +1 -1
  11. package/dist/bitrix/methods.js +7 -3
  12. package/dist/bitrix/methods.js.map +1 -1
  13. package/dist/bitrix/transport.d.ts +4 -7
  14. package/dist/bitrix/transport.d.ts.map +1 -1
  15. package/dist/bitrix/transport.js +29 -19
  16. package/dist/bitrix/transport.js.map +1 -1
  17. package/dist/body.d.ts +14 -0
  18. package/dist/body.d.ts.map +1 -0
  19. package/dist/body.js +44 -0
  20. package/dist/body.js.map +1 -0
  21. package/dist/bundle/{chunk-QIPTIUMJ.js → all-profiles-CANIDIDS.js} +12 -7
  22. package/dist/bundle/{anthropic-RHRAVHC2.js → anthropic-JUJB4DCF.js} +5 -5
  23. package/dist/bundle/{app-server-QIT6S7AZ.js → app-server-3V5Z4PTK.js} +68 -54
  24. package/dist/bundle/b24.js +18 -12
  25. package/dist/bundle/{bun-H6RSODZ3.js → bun-LKMV5TY7.js} +2 -2
  26. package/dist/bundle/{bun-sqlite-BO4LTQHX.js → bun-sqlite-S56EF74S.js} +3 -3
  27. package/dist/bundle/{chunk-D5S6QV6R.js → chunk-2I4KWS3H.js} +6 -6
  28. package/dist/bundle/chunk-36PO5NWY.js +147 -0
  29. package/dist/bundle/{chunk-ZIAQPTUS.js → chunk-42F7Q7V6.js} +3 -3
  30. package/dist/bundle/{chunk-6WY72XVQ.js → chunk-4D3K6GZW.js} +18 -4
  31. package/dist/bundle/chunk-5D4MJQ6X.js +22 -0
  32. package/dist/bundle/chunk-5JOPERVF.js +84 -0
  33. package/dist/bundle/chunk-6A4UPWDC.js +15 -0
  34. package/dist/bundle/{chunk-P33NDCDI.js → chunk-6MGWIZG4.js} +1 -1
  35. package/dist/bundle/{chunk-ZDQQCXFG.js → chunk-6YJTNZ7U.js} +13 -13
  36. package/dist/bundle/{chunk-MBDK4YXG.js → chunk-7FBFJ6B4.js} +4 -2
  37. package/dist/bundle/chunk-7VCMOTQP.js +55 -0
  38. package/dist/bundle/{chunk-P364PLIK.js → chunk-A5IMMGYU.js} +36 -34
  39. package/dist/bundle/{chunk-45AKJVKV.js → chunk-ASEHTBNK.js} +1 -1
  40. package/dist/bundle/{chunk-HGL63O5V.js → chunk-B6LPJYPQ.js} +2 -2
  41. package/dist/bundle/{chunk-LSPIOT6Z.js → chunk-BHEE2K6C.js} +7 -7
  42. package/dist/bundle/chunk-BYZQBE63.js +971 -0
  43. package/dist/bundle/{program-H3TGGRQ6.js → chunk-COKGNTDQ.js} +15761 -16685
  44. package/dist/bundle/{chunk-XJXONOB5.js → chunk-DVFYRQGE.js} +1 -1
  45. package/dist/bundle/{chunk-FLUEXJ4X.js → chunk-DVSIBZ3G.js} +1 -1
  46. package/dist/bundle/chunk-EJEIXC6Y.js +273 -0
  47. package/dist/bundle/chunk-EYTGCM44.js +130 -0
  48. package/dist/bundle/{chunk-IRV2PCQ2.js → chunk-EYYOKT23.js} +26 -26
  49. package/dist/bundle/{chunk-PH5FZX6E.js → chunk-FCWPIWSR.js} +2 -2
  50. package/dist/bundle/{chunk-YZ5LHE5Q.js → chunk-FSWRMQWX.js} +2 -2
  51. package/dist/bundle/{chunk-ADLS6FVG.js → chunk-FXBHOCJK.js} +1 -1
  52. package/dist/bundle/chunk-G5MW6RCM.js +723 -0
  53. package/dist/bundle/{chunk-VEWWAGTD.js → chunk-GLTKRLFT.js} +8 -8
  54. package/dist/bundle/chunk-GUUZQ7NE.js +581 -0
  55. package/dist/bundle/{chunk-QSNROIJL.js → chunk-H6RIPOOI.js} +42 -9
  56. package/dist/bundle/{chunk-H2ADPPSH.js → chunk-HGFNC4CR.js} +1819 -597
  57. package/dist/bundle/{chunk-7GRZAKBB.js → chunk-IERYD2N2.js} +6 -6
  58. package/dist/bundle/{chunk-N6FLBXZS.js → chunk-IGCLMEMB.js} +3 -3
  59. package/dist/bundle/{chunk-U5ACMCAQ.js → chunk-J7WCSZ2Q.js} +411 -919
  60. package/dist/bundle/{chunk-W5YAO5G5.js → chunk-JZYHQ4HB.js} +9 -4
  61. package/dist/bundle/{chunk-EVYSBZ3I.js → chunk-K4QM3X5F.js} +4 -4
  62. package/dist/bundle/{chunk-DTXERR44.js → chunk-KFSMY7SZ.js} +2 -2
  63. package/dist/bundle/{chunk-LRGYKOCP.js → chunk-KPEDH5T4.js} +1 -1
  64. package/dist/bundle/{chunk-XRFJWHY5.js → chunk-KUY7LII2.js} +4 -4
  65. package/dist/bundle/{chunk-QC53QBNC.js → chunk-LFXDHLFR.js} +3 -3
  66. package/dist/bundle/{chunk-CNNEA2M4.js → chunk-LGLT4JB6.js} +3 -3
  67. package/dist/bundle/{chunk-QGMDQ2PM.js → chunk-LM4OOBAW.js} +3 -3
  68. package/dist/bundle/chunk-M74BSKMA.js +234 -0
  69. package/dist/bundle/{chunk-2KCZ7BKW.js → chunk-MMMT6ORT.js} +11 -11
  70. package/dist/bundle/{chunk-WII44RXN.js → chunk-NGYD6QTE.js} +2 -2
  71. package/dist/bundle/{chunk-FOTREPNS.js → chunk-NO6QOPVT.js} +10 -19
  72. package/dist/bundle/chunk-O6XC7DZI.js +804 -0
  73. package/dist/bundle/chunk-OE3NFB53.js +64 -0
  74. package/dist/bundle/{chunk-XD4FRDSL.js → chunk-OUMFNB34.js} +13 -149
  75. package/dist/bundle/{chunk-ZGZT5S6B.js → chunk-P2RQTNVJ.js} +806 -850
  76. package/dist/bundle/{chunk-RRJNNPR4.js → chunk-PBIBGIZ7.js} +1 -1
  77. package/dist/bundle/{chunk-EXOOKUEA.js → chunk-Q6VQHTRW.js} +2 -2
  78. package/dist/bundle/{chunk-TE3FR6MI.js → chunk-QHBCNVUG.js} +5 -5
  79. package/dist/bundle/{chunk-SGRYYE4X.js → chunk-QNOXAQ6Y.js} +4 -4
  80. package/dist/bundle/{chunk-QQXH2OPB.js → chunk-R5F2O5GX.js} +15 -272
  81. package/dist/bundle/{chunk-SFRNX2TI.js → chunk-R5PBSKJL.js} +1 -1
  82. package/dist/bundle/{chunk-OTD2ZRXD.js → chunk-RS2BARUU.js} +4 -4
  83. package/dist/bundle/chunk-TG3DSPT5.js +14 -0
  84. package/dist/bundle/{chunk-BCF7P4FZ.js → chunk-U22JMKUO.js} +6 -125
  85. package/dist/bundle/chunk-U66Q5TVK.js +106 -0
  86. package/dist/bundle/{chunk-QMPN6WKD.js → chunk-UCHMQWON.js} +211 -89
  87. package/dist/bundle/{chunk-POC3V3AO.js → chunk-VMJS7FJZ.js} +526 -467
  88. package/dist/bundle/{chunk-FZL7F5NR.js → chunk-VMVAQHDC.js} +77 -615
  89. package/dist/bundle/{chunk-K3UIB6ZF.js → chunk-WWMCJFMT.js} +2 -2
  90. package/dist/bundle/{chunk-CXL33BFL.js → chunk-XTA5TN3H.js} +1 -1
  91. package/dist/bundle/{chunk-WTPMJYMD.js → chunk-XUHHBEA7.js} +652 -131
  92. package/dist/bundle/{chunk-WKRQ44EH.js → chunk-YDZHO4LT.js} +13 -13
  93. package/dist/bundle/{chunk-2SNUMZ7S.js → chunk-ZKINZFIT.js} +6 -6
  94. package/dist/bundle/{chunk-HAXNUIGQ.js → chunk-ZSQXSIFQ.js} +89 -39
  95. package/dist/bundle/{chunk-YYO7D2MO.js → chunk-ZZEHDIEG.js} +58 -54
  96. package/dist/bundle/command-contract-OQV6H7SR.js +36 -0
  97. package/dist/bundle/{decode-5ZPLTYV6.js → decode-QSTBX4MG.js} +3 -3
  98. package/dist/bundle/{echarts-J6LAPIX7.js → echarts-JZELFH2N.js} +2 -2
  99. package/dist/bundle/{embed-YG5LDHME.js → embed-4RIW2LVH.js} +4 -4
  100. package/dist/bundle/{embedder-7FNUA5OZ.js → embedder-SW7DTWSL.js} +7 -7
  101. package/dist/bundle/{first-run-JPZNWIJN.js → first-run-7AISOSOM.js} +8 -8
  102. package/dist/bundle/first-screen-NMHNFZ2B.js +34 -0
  103. package/dist/bundle/{instructions-AXWTQHMR.js → instructions-BZE5YUGG.js} +1 -1
  104. package/dist/bundle/{mcp-7F46P6AM.js → mcp-SDWHDJTY.js} +2 -2
  105. package/dist/bundle/{node-P4E63KXA.js → node-KM3CUABH.js} +9 -9
  106. package/dist/bundle/{node-CWKAIOEM.js → node-LTKZIO4U.js} +2 -2
  107. package/dist/bundle/{node-sqlite-LSEKVRDA.js → node-sqlite-HQ5PN2RH.js} +4 -4
  108. package/dist/bundle/{oauth-THYNLRLD.js → oauth-UH6FOZQL.js} +5 -5
  109. package/dist/bundle/{open-E47QYKFC.js → open-TSUP3XGL.js} +3 -3
  110. package/dist/bundle/{openai-EWSGC3BC.js → openai-GVEE52E3.js} +14 -14
  111. package/dist/bundle/{process-WKTEA3WE.js → process-AGXY76ZE.js} +1 -1
  112. package/dist/bundle/program-BI4A4HFJ.js +2247 -0
  113. package/dist/bundle/{prompt-CAQ7QR3U.js → prompt-NRSUY7FA.js} +3 -3
  114. package/dist/bundle/{recognize-6KGHNZC3.js → recognize-NPDPQ6PJ.js} +2 -2
  115. package/dist/bundle/{remote-3UO2WDC3.js → remote-HFASMVLB.js} +5 -5
  116. package/dist/bundle/{rerank-2JVDPZBX.js → rerank-TL6Z6F7K.js} +5 -5
  117. package/dist/bundle/{chunk-VL6SPMZV.js → serve-VB4DHDZQ.js} +8 -6
  118. package/dist/bundle/server-T5EDRPJI.js +68 -0
  119. package/dist/bundle/{chunk-ZEW4P6AH.js → server-Z6MW6C37.js} +50 -14
  120. package/dist/bundle/source-4IGO5J7E.js +237 -0
  121. package/dist/bundle/sqlite-runtime-YS4POY3W.js +17 -0
  122. package/dist/bundle/{state-7NH5G4XJ.js → state-ISZVVZGR.js} +4 -4
  123. package/dist/bundle/store-IZJBAKJV.js +58 -0
  124. package/dist/bundle/{store-7O4JQD2Z.js → store-L76MSQC3.js} +17 -12
  125. package/dist/bundle/store-PBTIB7BD.js +207 -0
  126. package/dist/bundle/store-maintenance-command-YFKII7TF.js +58 -0
  127. package/dist/bundle/writer-3O5EYMFE.js +214 -0
  128. package/dist/commands/api.d.ts.map +1 -1
  129. package/dist/commands/api.js +81 -30
  130. package/dist/commands/api.js.map +1 -1
  131. package/dist/commands/crm-shared.d.ts +4 -0
  132. package/dist/commands/crm-shared.d.ts.map +1 -0
  133. package/dist/commands/crm-shared.js +94 -0
  134. package/dist/commands/crm-shared.js.map +1 -0
  135. package/dist/commands/crm-writes.d.ts +0 -1
  136. package/dist/commands/crm-writes.d.ts.map +1 -1
  137. package/dist/commands/crm-writes.js +43 -88
  138. package/dist/commands/crm-writes.js.map +1 -1
  139. package/dist/commands/crm.d.ts.map +1 -1
  140. package/dist/commands/crm.js +30 -48
  141. package/dist/commands/crm.js.map +1 -1
  142. package/dist/commands/session.d.ts.map +1 -1
  143. package/dist/commands/session.js +1 -0
  144. package/dist/commands/session.js.map +1 -1
  145. package/dist/commands/write.d.ts +6 -6
  146. package/dist/commands/write.d.ts.map +1 -1
  147. package/dist/commands/write.js +11 -18
  148. package/dist/commands/write.js.map +1 -1
  149. package/dist/config.d.ts +0 -5
  150. package/dist/config.d.ts.map +1 -1
  151. package/dist/config.js +6 -8
  152. package/dist/config.js.map +1 -1
  153. package/dist/crm/capabilities.d.ts +7 -0
  154. package/dist/crm/capabilities.d.ts.map +1 -0
  155. package/dist/crm/capabilities.js +7 -0
  156. package/dist/crm/capabilities.js.map +1 -0
  157. package/dist/crm/conditions.d.ts +1 -1
  158. package/dist/crm/conditions.d.ts.map +1 -1
  159. package/dist/crm/conditions.js +4 -6
  160. package/dist/crm/conditions.js.map +1 -1
  161. package/dist/crm/custom-query.d.ts +19 -0
  162. package/dist/crm/custom-query.d.ts.map +1 -0
  163. package/dist/crm/custom-query.js +79 -0
  164. package/dist/crm/custom-query.js.map +1 -0
  165. package/dist/crm/deal.d.ts +4 -27
  166. package/dist/crm/deal.d.ts.map +1 -1
  167. package/dist/crm/deal.js +15 -48
  168. package/dist/crm/deal.js.map +1 -1
  169. package/dist/crm/fields.d.ts +20 -0
  170. package/dist/crm/fields.d.ts.map +1 -0
  171. package/dist/crm/fields.js +78 -0
  172. package/dist/crm/fields.js.map +1 -0
  173. package/dist/crm/items.d.ts +7 -1
  174. package/dist/crm/items.d.ts.map +1 -1
  175. package/dist/crm/items.js +21 -18
  176. package/dist/crm/items.js.map +1 -1
  177. package/dist/crm/lead.d.ts +5 -36
  178. package/dist/crm/lead.d.ts.map +1 -1
  179. package/dist/crm/lead.js +15 -61
  180. package/dist/crm/lead.js.map +1 -1
  181. package/dist/crm/organization.d.ts +1 -0
  182. package/dist/crm/organization.d.ts.map +1 -1
  183. package/dist/crm/person.d.ts +1 -0
  184. package/dist/crm/person.d.ts.map +1 -1
  185. package/dist/crm/pipelines.d.ts +5 -0
  186. package/dist/crm/pipelines.d.ts.map +1 -0
  187. package/dist/crm/pipelines.js +54 -0
  188. package/dist/crm/pipelines.js.map +1 -0
  189. package/dist/crm/product.d.ts.map +1 -1
  190. package/dist/crm/product.js +2 -2
  191. package/dist/crm/product.js.map +1 -1
  192. package/dist/crm/rest3-fields.d.ts +3 -0
  193. package/dist/crm/rest3-fields.d.ts.map +1 -0
  194. package/dist/crm/rest3-fields.js +38 -0
  195. package/dist/crm/rest3-fields.js.map +1 -0
  196. package/dist/crm/source.d.ts +15 -0
  197. package/dist/crm/source.d.ts.map +1 -0
  198. package/dist/crm/source.js +122 -0
  199. package/dist/crm/source.js.map +1 -0
  200. package/dist/crm/user.d.ts.map +1 -1
  201. package/dist/crm/user.js +2 -2
  202. package/dist/crm/user.js.map +1 -1
  203. package/dist/crm/values.d.ts +26 -5
  204. package/dist/crm/values.d.ts.map +1 -1
  205. package/dist/crm/values.js +40 -5
  206. package/dist/crm/values.js.map +1 -1
  207. package/dist/crm/writer.d.ts +9 -0
  208. package/dist/crm/writer.d.ts.map +1 -0
  209. package/dist/crm/writer.js +119 -0
  210. package/dist/crm/writer.js.map +1 -0
  211. package/dist/program.d.ts.map +1 -1
  212. package/dist/program.js +53 -5
  213. package/dist/program.js.map +1 -1
  214. package/dist/reasons.d.ts.map +1 -1
  215. package/dist/reasons.js +6 -1
  216. package/dist/reasons.js.map +1 -1
  217. package/dist/store.d.ts +15 -0
  218. package/dist/store.d.ts.map +1 -0
  219. package/dist/store.js +33 -0
  220. package/dist/store.js.map +1 -0
  221. package/dist/version.d.ts +1 -1
  222. package/dist/version.js +1 -1
  223. package/package.json +4 -6
  224. package/skills/bitrix24-cli/SKILL.md +16 -10
  225. package/dist/bundle/all-profiles-QJ444GSX.js +0 -24
  226. package/dist/bundle/chunk-XNHSPHUN.js +0 -48
  227. package/dist/bundle/command-contract-OKQOE6G4.js +0 -30
  228. package/dist/bundle/first-screen-VQM4MTS7.js +0 -28
  229. package/dist/bundle/mcp-5RSWNTHS.js +0 -160
  230. package/dist/bundle/mcp-J5R5A65I.js +0 -87
  231. package/dist/bundle/serve-ES7AG5IK.js +0 -19
  232. package/dist/bundle/server-5LE5LNUQ.js +0 -45
  233. package/dist/bundle/server-BU4VBM6S.js +0 -58
  234. package/dist/bundle/store-maintenance-command-UDVGEY2D.js +0 -47
  235. package/dist/commands/doctor.d.ts +0 -77
  236. package/dist/commands/doctor.d.ts.map +0 -1
  237. package/dist/commands/doctor.js +0 -74
  238. package/dist/commands/doctor.js.map +0 -1
  239. package/dist/commands/mcp.d.ts +0 -3
  240. package/dist/commands/mcp.d.ts.map +0 -1
  241. package/dist/commands/mcp.js +0 -97
  242. package/dist/commands/mcp.js.map +0 -1
  243. package/dist/crm/pipeline.d.ts +0 -17
  244. package/dist/crm/pipeline.d.ts.map +0 -1
  245. package/dist/crm/pipeline.js +0 -42
  246. package/dist/crm/pipeline.js.map +0 -1
  247. package/dist/crm/stage.d.ts +0 -20
  248. package/dist/crm/stage.d.ts.map +0 -1
  249. package/dist/crm/stage.js +0 -65
  250. package/dist/crm/stage.js.map +0 -1
  251. package/dist/mcp.d.ts +0 -29
  252. package/dist/mcp.d.ts.map +0 -1
  253. package/dist/mcp.js +0 -99
  254. package/dist/mcp.js.map +0 -1
  255. /package/dist/bundle/{chunk-4PDYYS5K.js → chunk-ZQ3GWKDQ.js} +0 -0
@@ -3,7 +3,7 @@ const require = __bundleRequire(import.meta.url);
3
3
  import {
4
4
  answerOf,
5
5
  messengerContext
6
- } from "./chunk-FZL7F5NR.js";
6
+ } from "./chunk-VMVAQHDC.js";
7
7
  import {
8
8
  FETCHING,
9
9
  RULES_VERSION,
@@ -11,7 +11,6 @@ import {
11
11
  capability,
12
12
  chatEventAnswer,
13
13
  memberAnswer,
14
- newSendId,
15
14
  onlineDeps,
16
15
  openRequestTask,
17
16
  patiently,
@@ -24,7 +23,19 @@ import {
24
23
  typedQuery,
25
24
  withQuery,
26
25
  withTimeLimit
27
- } from "./chunk-POC3V3AO.js";
26
+ } from "./chunk-VMJS7FJZ.js";
27
+ import {
28
+ newSendId
29
+ } from "./chunk-6A4UPWDC.js";
30
+ import {
31
+ checkedOptions,
32
+ range
33
+ } from "./chunk-FSWRMQWX.js";
34
+ import {
35
+ messagesFor,
36
+ systemFor,
37
+ validateImages
38
+ } from "./chunk-WWMCJFMT.js";
28
39
  import {
29
40
  Command,
30
41
  LOCAL_READ,
@@ -32,11 +43,8 @@ import {
32
43
  REMOTE_READ,
33
44
  REMOTE_WRITE,
34
45
  annotate,
35
- codeOf,
36
- currentRun,
37
46
  destroysNothing,
38
47
  endpoint,
39
- envName,
40
48
  environmentOf,
41
49
  itemOf,
42
50
  jsonlRecords,
@@ -52,45 +60,52 @@ import {
52
60
  snakeKeys,
53
61
  storeTable,
54
62
  withoutProviderRefs
55
- } from "./chunk-U5ACMCAQ.js";
63
+ } from "./chunk-J7WCSZ2Q.js";
64
+ import {
65
+ codeOf,
66
+ currentRun,
67
+ envName
68
+ } from "./chunk-G5MW6RCM.js";
56
69
  import {
57
70
  failureKey
58
- } from "./chunk-FOTREPNS.js";
71
+ } from "./chunk-5D4MJQ6X.js";
59
72
  import {
60
73
  holdLock,
61
74
  lockPath,
62
75
  releaseLock,
63
76
  servingProfiles,
64
77
  takeLock
65
- } from "./chunk-N6FLBXZS.js";
78
+ } from "./chunk-IGCLMEMB.js";
66
79
  import {
67
80
  holdersOf
68
- } from "./chunk-XJXONOB5.js";
69
- import {
70
- checkedOptions,
71
- range
72
- } from "./chunk-YZ5LHE5Q.js";
81
+ } from "./chunk-DVFYRQGE.js";
73
82
  import {
74
- messagesFor,
75
- systemFor,
76
- validateImages
77
- } from "./chunk-K3UIB6ZF.js";
83
+ QUICK_HEALTH_CHECKS,
84
+ explainDamage,
85
+ fts5Tables,
86
+ storeHealth
87
+ } from "./chunk-BYZQBE63.js";
78
88
  import {
79
89
  renderMessages
80
- } from "./chunk-PH5FZX6E.js";
90
+ } from "./chunk-FCWPIWSR.js";
81
91
  import {
82
92
  levelFor
83
- } from "./chunk-XD4FRDSL.js";
93
+ } from "./chunk-OUMFNB34.js";
84
94
  import {
85
95
  readSecret
86
- } from "./chunk-ZIAQPTUS.js";
96
+ } from "./chunk-42F7Q7V6.js";
87
97
  import {
98
+ CORPORA,
88
99
  MIGRATIONS,
100
+ drainCorpus,
101
+ drainMeetingIndex,
89
102
  drainNoteIndex,
90
103
  dropAllUnusedVectors,
91
104
  fileFacts,
92
105
  fillSearchIndex,
93
106
  fillStems,
107
+ fillTrigrams,
108
+ fillVectorIndexes,
94
109
  involvementStoreOver,
95
110
  migrate,
96
111
  noteIndexState,
@@ -99,10 +114,12 @@ import {
99
114
  orphanPointers,
100
115
  pendingNormalization,
101
116
  readStoreTables,
117
+ rebuildMentions,
102
118
  resetAttachmentWords,
103
119
  resetNoteIndex,
104
120
  resetSearchIndex,
105
121
  resetStems,
122
+ rollBack,
106
123
  rowCounts,
107
124
  searchIndexState,
108
125
  stemmerCache,
@@ -110,20 +127,20 @@ import {
110
127
  storeClients,
111
128
  storeContents,
112
129
  vectorIndexCounts
113
- } from "./chunk-H2ADPPSH.js";
130
+ } from "./chunk-HGFNC4CR.js";
114
131
  import {
115
132
  storePath
116
- } from "./chunk-DTXERR44.js";
133
+ } from "./chunk-KFSMY7SZ.js";
117
134
  import {
118
135
  formatLocator,
119
136
  parseLocator
120
- } from "./chunk-QQXH2OPB.js";
137
+ } from "./chunk-R5F2O5GX.js";
121
138
  import {
122
139
  queryFieldsOf
123
- } from "./chunk-ZGZT5S6B.js";
140
+ } from "./chunk-P2RQTNVJ.js";
124
141
  import {
125
142
  openCache
126
- } from "./chunk-D5S6QV6R.js";
143
+ } from "./chunk-2I4KWS3H.js";
127
144
  import {
128
145
  CliError,
129
146
  Credentials,
@@ -152,7 +169,7 @@ import {
152
169
  trim,
153
170
  union,
154
171
  writeSecurely
155
- } from "./chunk-IRV2PCQ2.js";
172
+ } from "./chunk-EYYOKT23.js";
156
173
  import {
157
174
  __commonJS,
158
175
  __name,
@@ -1806,7 +1823,7 @@ var require_liquid_node = __commonJS({
1806
1823
  return readFileAsync(filepath, "utf8");
1807
1824
  }
1808
1825
  __name(readFile, "readFile");
1809
- function existsSync8(filepath) {
1826
+ function existsSync10(filepath) {
1810
1827
  try {
1811
1828
  fs$1.statSync(filepath);
1812
1829
  return true;
@@ -1814,11 +1831,11 @@ var require_liquid_node = __commonJS({
1814
1831
  return false;
1815
1832
  }
1816
1833
  }
1817
- __name(existsSync8, "existsSync");
1818
- function readFileSync4(filepath) {
1834
+ __name(existsSync10, "existsSync");
1835
+ function readFileSync5(filepath) {
1819
1836
  return fs$1.readFileSync(filepath, "utf8");
1820
1837
  }
1821
- __name(readFileSync4, "readFileSync");
1838
+ __name(readFileSync5, "readFileSync");
1822
1839
  function resolve2(root, file2, ext) {
1823
1840
  if (!path.extname(file2))
1824
1841
  file2 += ext;
@@ -1832,10 +1849,10 @@ var require_liquid_node = __commonJS({
1832
1849
  }
1833
1850
  }
1834
1851
  __name(fallback, "fallback");
1835
- function dirname2(filepath) {
1852
+ function dirname3(filepath) {
1836
1853
  return path.dirname(filepath);
1837
1854
  }
1838
- __name(dirname2, "dirname");
1855
+ __name(dirname3, "dirname");
1839
1856
  var realpathAsync = promisify(fs$1.realpath);
1840
1857
  async function contains(root, file2) {
1841
1858
  try {
@@ -1863,11 +1880,11 @@ var require_liquid_node = __commonJS({
1863
1880
  __proto__: null,
1864
1881
  exists,
1865
1882
  readFile,
1866
- existsSync: existsSync8,
1867
- readFileSync: readFileSync4,
1883
+ existsSync: existsSync10,
1884
+ readFileSync: readFileSync5,
1868
1885
  resolve: resolve2,
1869
1886
  fallback,
1870
- dirname: dirname2,
1887
+ dirname: dirname3,
1871
1888
  contains,
1872
1889
  containsSync,
1873
1890
  sep: path.sep
@@ -3592,7 +3609,7 @@ var require_liquid_node = __commonJS({
3592
3609
  uri_escape,
3593
3610
  slugify
3594
3611
  });
3595
- var join4 = argumentsToValue(function(v, arg) {
3612
+ var join5 = argumentsToValue(function(v, arg) {
3596
3613
  const array2 = toArray(v);
3597
3614
  const sep = isNil(arg) ? " " : stringify(arg);
3598
3615
  let outputSize = sep.length * Math.max(array2.length - 1, 0);
@@ -3868,7 +3885,7 @@ var require_liquid_node = __commonJS({
3868
3885
  __name(sample, "sample");
3869
3886
  var arrayFilters = /* @__PURE__ */ Object.freeze({
3870
3887
  __proto__: null,
3871
- join: join4,
3888
+ join: join5,
3872
3889
  last,
3873
3890
  first,
3874
3891
  reverse,
@@ -4796,15 +4813,15 @@ var require_liquid_node = __commonJS({
4796
4813
  }
4797
4814
  *render(ctx, emitter) {
4798
4815
  const group = yield evalToken(this.group, ctx);
4799
- const fingerprint = `cycle:${group}:` + this.candidates.join(",");
4816
+ const fingerprint2 = `cycle:${group}:` + this.candidates.join(",");
4800
4817
  const groups = ctx.getRegister("cycle", {});
4801
- let idx = groups[fingerprint];
4818
+ let idx = groups[fingerprint2];
4802
4819
  if (idx === void 0) {
4803
- idx = groups[fingerprint] = 0;
4820
+ idx = groups[fingerprint2] = 0;
4804
4821
  }
4805
4822
  const candidate = this.candidates[idx];
4806
4823
  idx = (idx + 1) % this.candidates.length;
4807
- groups[fingerprint] = idx;
4824
+ groups[fingerprint2] = idx;
4808
4825
  return yield evalToken(candidate, ctx);
4809
4826
  }
4810
4827
  *arguments() {
@@ -5492,11 +5509,11 @@ var require_liquid_node = __commonJS({
5492
5509
  }
5493
5510
  });
5494
5511
 
5495
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
5496
- import { chmodSync, constants, copyFileSync, existsSync as existsSync7, mkdirSync, realpathSync, renameSync as renameSync2, rmSync as rmSync2, statfsSync, statSync as statSync3, writeFileSync } from "node:fs";
5497
- import { dirname, resolve } from "node:path";
5512
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
5513
+ import { chmodSync, constants, copyFileSync, existsSync as existsSync9, mkdirSync, realpathSync as realpathSync2, renameSync as renameSync3, rmSync as rmSync3, statfsSync as statfsSync2, statSync as statSync4, writeFileSync as writeFileSync2 } from "node:fs";
5514
+ import { dirname as dirname2, resolve } from "node:path";
5498
5515
 
5499
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sealed.js
5516
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/sealed.js
5500
5517
  import { createCipheriv, createDecipheriv, createHash, randomBytes, scrypt, timingSafeEqual } from "node:crypto";
5501
5518
  import { closeSync, createReadStream, createWriteStream, existsSync, openSync, readSync, renameSync, rmSync, statSync } from "node:fs";
5502
5519
  import { Transform } from "node:stream";
@@ -5603,7 +5620,7 @@ var unsealFile = /* @__PURE__ */ __name(async (from, to, password) => {
5603
5620
  renameSync(pending, to);
5604
5621
  }, "unsealFile");
5605
5622
 
5606
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/store/compatibility.js
5623
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/store/compatibility.js
5607
5624
  var SPEAKS = MIGRATIONS.at(-1)?.version ?? 0;
5608
5625
  var fileSchemaOf = /* @__PURE__ */ __name((database) => {
5609
5626
  const tracked = database.prepare("SELECT 1 FROM sqlite_master WHERE name = 'schema_migrations'").get();
@@ -5627,7 +5644,7 @@ var compatibilityOf = /* @__PURE__ */ __name((file2, migrations = MIGRATIONS) =>
5627
5644
  };
5628
5645
  }, "compatibilityOf");
5629
5646
 
5630
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/store/repair.js
5647
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/store/repair.js
5631
5648
  import { createHash as createHash2 } from "node:crypto";
5632
5649
  var COPY_MARK = "__repair_";
5633
5650
  var COPY_NAME = /__repair_[0-9a-f]{8}(_\d+)?$/;
@@ -5881,10 +5898,457 @@ var deleteCopy = /* @__PURE__ */ __name((database, name) => {
5881
5898
  return found;
5882
5899
  }, "deleteCopy");
5883
5900
 
5884
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/store-info.js
5885
- import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
5901
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/store-info.js
5902
+ import { existsSync as existsSync4, statSync as statSync3 } from "node:fs";
5903
+
5904
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/store-recover.js
5905
+ import { existsSync as existsSync3 } from "node:fs";
5906
+
5907
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/store/recover.js
5908
+ import { execFileSync, spawn } from "node:child_process";
5909
+ import { existsSync as existsSync2, readFileSync, realpathSync, renameSync as renameSync2, rmSync as rmSync2, statfsSync, statSync as statSync2, writeFileSync } from "node:fs";
5910
+ import { basename, dirname, join } from "node:path";
5911
+ import { Transform as Transform2 } from "node:stream";
5912
+ var SQLITE3_MINIMUM = [3, 43, 0];
5913
+ var STORE_PARTS = ["", "-wal", "-shm"];
5914
+ var INSERTED = /^INSERT OR IGNORE INTO '([^']+)'/;
5915
+ var LOST_AND_FOUND = "recover_lost_and_found";
5916
+ var recovers = /* @__PURE__ */ __name((program) => {
5917
+ try {
5918
+ execFileSync(program, [":memory:", ".recover"], { stdio: ["ignore", "ignore", "pipe"] });
5919
+ return true;
5920
+ } catch {
5921
+ return false;
5922
+ }
5923
+ }, "recovers");
5924
+ var sqlite3Program = /* @__PURE__ */ __name((program = "sqlite3") => {
5925
+ let version = null;
5926
+ try {
5927
+ version = execFileSync(program, ["--version"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).split(" ")[0] ?? null;
5928
+ } catch {
5929
+ return { program, version: null, usable: false };
5930
+ }
5931
+ const parts = (version ?? "").split(".").map(Number);
5932
+ const at = SQLITE3_MINIMUM.findIndex((wanted, i) => (parts[i] ?? 0) !== wanted);
5933
+ const recent = at === -1 || (parts[at] ?? 0) > (SQLITE3_MINIMUM[at] ?? 0);
5934
+ return { program, version, usable: recent && recovers(program) };
5935
+ }, "sqlite3Program");
5936
+ var activeTimers = /* @__PURE__ */ __name(() => {
5937
+ if (process.platform !== "linux")
5938
+ return void 0;
5939
+ try {
5940
+ return execFileSync("systemctl", ["--user", "list-timers", "--plain", "--no-legend"], {
5941
+ encoding: "utf8",
5942
+ stdio: ["ignore", "pipe", "ignore"]
5943
+ }).split("\n").map((line) => line.trim().split(/\s+/).at(-2) ?? "").filter((unit) => /^(memo|mail|tg|max|whatsapp|zoom|drive|gcal|wirecat)-.*\.timer$/.test(unit));
5944
+ } catch {
5945
+ return void 0;
5946
+ }
5947
+ }, "activeTimers");
5948
+ var storeHolders = /* @__PURE__ */ __name((path) => {
5949
+ const folder = realpathSync(dirname(path));
5950
+ const files = STORE_PARTS.map((suffix) => join(folder, `${basename(path)}${suffix}`));
5951
+ const wanted = process.platform === "linux" ? files.flatMap((file2) => [file2, `${file2} (deleted)`]) : files.filter(existsSync2);
5952
+ return holdersOf(wanted)?.map((pid) => {
5953
+ let name = "?";
5954
+ try {
5955
+ name = readFileSync(`/proc/${pid}/comm`, "utf8").trim();
5956
+ } catch {
5957
+ }
5958
+ return { pid, name };
5959
+ });
5960
+ }, "storeHolders");
5961
+ var tableRows = /* @__PURE__ */ __name((database) => {
5962
+ const indexes = fts5Tables(database).map((index) => index.name);
5963
+ const tables = database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND rootpage > 0 AND name NOT LIKE 'sqlite_%' AND name NOT LIKE 'vector_index_%' ORDER BY name").all().map((row) => String(row.name)).filter((name) => !indexes.some((index) => name.startsWith(`${index}_`)));
5964
+ return Object.fromEntries(tables.map((table) => {
5965
+ try {
5966
+ return [table, Number(database.prepare(`SELECT count(*) AS n FROM "${table}"`).get()?.n)];
5967
+ } catch {
5968
+ return [table, null];
5969
+ }
5970
+ }));
5971
+ }, "tableRows");
5972
+ var copyReadableRows = /* @__PURE__ */ __name((path, target, program = "sqlite3") => new Promise((resolve2, reject) => {
5973
+ const reader = spawn(program, ["-readonly", path, `.recover --ignore-freelist --lost-and-found ${LOST_AND_FOUND}`], {
5974
+ stdio: ["ignore", "pipe", "pipe"]
5975
+ });
5976
+ const writer = spawn(program, ["-cmd", ".dbconfig defensive off", target], { stdio: ["pipe", "ignore", "pipe"] });
5977
+ const errors = [];
5978
+ const collect = /* @__PURE__ */ __name((chunk) => {
5979
+ for (const line of chunk.toString("utf8").split("\n"))
5980
+ if (line && errors.length < 50)
5981
+ errors.push(line.slice(0, 300));
5982
+ }, "collect");
5983
+ reader.stderr.on("data", collect);
5984
+ writer.stderr.on("data", collect);
5985
+ const read = {};
5986
+ let rest = "";
5987
+ const counter = new Transform2({
5988
+ transform(chunk, _encoding, done) {
5989
+ const lines = (rest + chunk.toString("latin1")).split("\n");
5990
+ rest = lines.pop() ?? "";
5991
+ for (const line of lines) {
5992
+ const table = INSERTED.exec(line)?.[1];
5993
+ if (table)
5994
+ read[table] = (read[table] ?? 0) + 1;
5995
+ }
5996
+ done(null, chunk);
5997
+ }
5998
+ });
5999
+ reader.stdout.pipe(counter).pipe(writer.stdin);
6000
+ let exits = 0;
6001
+ let readerCode = null;
6002
+ const exited = /* @__PURE__ */ __name(() => {
6003
+ exits += 1;
6004
+ if (exits < 2)
6005
+ return;
6006
+ if (readerCode !== 0)
6007
+ reject(new CliError("validation_error", `sqlite3 could not read the store: ${errors.join("; ")}`));
6008
+ else
6009
+ resolve2({ errors, read });
6010
+ }, "exited");
6011
+ reader.on("error", reject);
6012
+ writer.on("error", reject);
6013
+ reader.on("close", (code) => {
6014
+ readerCode = code;
6015
+ exited();
6016
+ });
6017
+ writer.on("close", exited);
6018
+ }), "copyReadableRows");
6019
+ var FILLERS = {
6020
+ message_words: /* @__PURE__ */ __name((database, now) => {
6021
+ resetSearchIndex(database);
6022
+ fillSearchIndex(database, { now });
6023
+ }, "message_words"),
6024
+ message_stems: /* @__PURE__ */ __name((database, now) => {
6025
+ resetStems(database, { force: true, now });
6026
+ fillStems(database, { now });
6027
+ }, "message_stems"),
6028
+ attachment_words: /* @__PURE__ */ __name((database) => void resetAttachmentWords(database), "attachment_words"),
6029
+ attachment_name_words: /* @__PURE__ */ __name((database) => (
6030
+ // As migration 20 filled it: й and ё fold as the triggers fold them.
6031
+ database.exec("INSERT INTO attachment_name_words (rowid, name) SELECT id, replace(replace(replace(replace(name, '\u0439', '\u0438'), '\u0419', '\u0418'), '\u0451', '\u0435'), '\u0401', '\u0415') FROM attachments WHERE name IS NOT NULL")
6032
+ ), "attachment_name_words"),
6033
+ meeting_words: /* @__PURE__ */ __name((database) => {
6034
+ database.exec("INSERT OR IGNORE INTO meeting_index_pending (indexable_type, id) SELECT 'meeting_transcript_row', id FROM meeting_transcript_rows UNION ALL SELECT 'meeting_chat_message', id FROM meeting_chat_messages UNION ALL SELECT 'meeting_summary', id FROM meeting_summaries");
6035
+ drainMeetingIndex(database);
6036
+ }, "meeting_words"),
6037
+ // Built per account by the first search that needs them.
6038
+ meeting_stems: /* @__PURE__ */ __name((database) => database.exec("UPDATE search_index_state SET filled_through = 0, built_at = NULL WHERE name LIKE 'meeting_stems:%'"), "meeting_stems")
6039
+ };
6040
+ var CORPUS_TABLES = new Set(Object.values(CORPORA).flatMap((corpus) => [`${corpus.type}_words`, `${corpus.type}_stems`]));
6041
+ var TRIGRAMS = ["note_trigrams", "document_trigrams"];
6042
+ var rebuildDerived = /* @__PURE__ */ __name((database, { now = Date.now, note = /* @__PURE__ */ __name(() => {
6043
+ }, "note") } = {}) => {
6044
+ const lost = database.prepare("SELECT 1 FROM sqlite_master WHERE name = ?").get(LOST_AND_FOUND);
6045
+ const lostAndFound = lost ? Number(database.prepare(`SELECT count(*) AS n FROM ${LOST_AND_FOUND}`).get()?.n) : 0;
6046
+ if (lost)
6047
+ database.exec(`DROP TABLE ${LOST_AND_FOUND}`);
6048
+ const indexes = fts5Tables(database);
6049
+ for (const { name, sql } of indexes) {
6050
+ database.exec(`DROP TABLE "${name}"`);
6051
+ database.exec(sql);
6052
+ }
6053
+ const vectors = database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name GLOB 'vector_index_[0-9]*' AND sql LIKE 'CREATE VIRTUAL%'").all().map((row) => String(row.name));
6054
+ for (const table of vectors) {
6055
+ database.exec(`DROP TRIGGER IF EXISTS "${table}_redo"`);
6056
+ database.exec(`DROP TABLE "${table}"`);
6057
+ database.prepare("DELETE FROM vector_indexes WHERE id = ?").run(Number(table.replace("vector_index_", "")));
6058
+ }
6059
+ const unfilled = [];
6060
+ const stemmerFor = stemmerCache();
6061
+ for (const { name, external } of indexes) {
6062
+ note(`rebuilding ${name}`);
6063
+ if (external)
6064
+ database.exec(`INSERT INTO "${name}" ("${name}") VALUES ('rebuild')`);
6065
+ else if (FILLERS[name])
6066
+ FILLERS[name](database, now);
6067
+ else if (!CORPUS_TABLES.has(name) && !TRIGRAMS.includes(name))
6068
+ unfilled.push(name);
6069
+ }
6070
+ note("rebuilding the words of notes, documents, memories, mail, tasks, transcripts and events");
6071
+ resetNoteIndex(database);
6072
+ for (const corpus of Object.values(CORPORA))
6073
+ drainCorpus(database, corpus, stemmerFor);
6074
+ for (const name of TRIGRAMS) {
6075
+ const type = name.replace("_trigrams", "");
6076
+ database.prepare(`UPDATE search_index_state SET filled_through = 0, watermark = (SELECT coalesce(max(id), 0) FROM ${type}s) WHERE name = ?`).run(name);
6077
+ }
6078
+ fillTrigrams(database);
6079
+ note("finding mentions again");
6080
+ const mentions = rebuildMentions(database, { now: now() }).mentions;
6081
+ involvementStoreOver({ database, now }).rebuild();
6082
+ note("indexing the stored vectors");
6083
+ const vectorModels = fillVectorIndexes(database);
6084
+ const without = database.prepare("SELECT count(*) AS n FROM chunks k WHERE NOT EXISTS (SELECT 1 FROM embeddings v WHERE v.model = ? AND v.content_hash = k.content_hash)");
6085
+ const chunksWithoutVector = Object.fromEntries(database.prepare("SELECT model FROM vector_indexes ORDER BY model").all().map((row) => [String(row.model), Number(without.get(String(row.model))?.n)]));
6086
+ return {
6087
+ lostAndFound,
6088
+ searchIndexes: indexes.map((index) => index.name),
6089
+ unfilled,
6090
+ mentions,
6091
+ vectorModels,
6092
+ chunksWithoutVector
6093
+ };
6094
+ }, "rebuildDerived");
6095
+ var danglingRows = /* @__PURE__ */ __name((database) => database.prepare(`SELECT "table" AS child, parent, fkid, count(*) AS n FROM pragma_foreign_key_check GROUP BY 1, 2, 3 ORDER BY 4 DESC`).all().map((group) => {
6096
+ const child = String(group.child);
6097
+ const column = database.prepare(`SELECT "from" AS name FROM pragma_foreign_key_list(?) WHERE id = ? ORDER BY seq LIMIT 1`).get(child, Number(group.fkid))?.name;
6098
+ let missing = [];
6099
+ try {
6100
+ missing = database.prepare(`SELECT DISTINCT "${String(column)}" AS id FROM "${child}" WHERE rowid IN (SELECT rowid FROM pragma_foreign_key_check(?) WHERE fkid = ?) ORDER BY 1 LIMIT 20`).all(child, Number(group.fkid)).map((row) => typeof row.id === "number" ? row.id : String(row.id));
6101
+ } catch {
6102
+ }
6103
+ return { table: child, parent: String(group.parent), rows: Number(group.n), missing };
6104
+ }), "danglingRows");
6105
+ var mailToFetch = /* @__PURE__ */ __name((database) => {
6106
+ try {
6107
+ return database.prepare(`SELECT a.external_id AS account, count(DISTINCT l.email_id) AS n FROM email_locations l
6108
+ JOIN mailboxes b ON b.id = l.mailbox_id JOIN accounts a ON a.id = b.account_id
6109
+ WHERE NOT EXISTS (SELECT 1 FROM emails e WHERE e.id = l.email_id) GROUP BY a.id ORDER BY a.external_id`).all().map((row) => ({ account: String(row.account), emails: Number(row.n) }));
6110
+ } catch {
6111
+ return [];
6112
+ }
6113
+ }, "mailToFetch");
6114
+ var fingerprint = /* @__PURE__ */ __name((path) => ["", "-wal"].map((suffix) => {
6115
+ const stat = statSync2(`${path}${suffix}`, { throwIfNoEntry: false });
6116
+ return stat ? `${stat.size}:${stat.mtimeMs}` : "-";
6117
+ }).join("|"), "fingerprint");
6118
+ var refuseInUse = /* @__PURE__ */ __name((path) => {
6119
+ const holders = storeHolders(path);
6120
+ if (holders && holders.length > 0) {
6121
+ const timers = activeTimers() ?? [];
6122
+ throw new CliError("validation_error", `the store is open in ${holders.map(({ pid, name }) => `${name} (process ${pid})`).join(", ")} \u2014 stop it first` + (timers.length ? `, and the timers: systemctl --user stop ${timers.join(" ")}` : ""), { reason: "store.in-use" });
6123
+ }
6124
+ }, "refuseInUse");
6125
+ var recoverStore = /* @__PURE__ */ __name(async ({ path, command, version, sqlite3 = "sqlite3", now = Date.now, note = /* @__PURE__ */ __name(() => {
6126
+ }, "note"), copy }) => {
6127
+ const started = Date.now();
6128
+ if (!existsSync2(path))
6129
+ throw new CliError("not_found", `no store at ${path}`);
6130
+ const program = copy ? { program: sqlite3, version: "given", usable: true } : sqlite3Program(sqlite3);
6131
+ if (!program.usable) {
6132
+ throw new CliError("configuration_error", program.version ? `sqlite3 ${program.version} cannot recover: the recovery needs ${SQLITE3_MINIMUM.join(".")} or newer, built with .recover` : "the recovery needs the sqlite3 program with its .recover command: install it (apt install sqlite3, brew install sqlite)", { reason: "store.sqlite3-missing" });
6133
+ }
6134
+ refuseInUse(path);
6135
+ const bytes = STORE_PARTS.reduce((sum, suffix) => sum + (statSync2(`${path}${suffix}`, { throwIfNoEntry: false })?.size ?? 0), 0);
6136
+ const { bavail, bsize } = statfsSync(dirname(path));
6137
+ if (Number(bavail) * Number(bsize) < bytes * 1.2)
6138
+ throw new CliError("validation_error", `the recovery needs about ${Math.ceil(bytes * 1.2 / 1e9)} GB free beside the store`);
6139
+ const old = await openSqlite(path, { readOnly: true });
6140
+ let rowsBefore;
6141
+ try {
6142
+ rowsBefore = tableRows(old.database);
6143
+ } finally {
6144
+ old.database.close();
6145
+ }
6146
+ const before = fingerprint(path);
6147
+ const stamp = new Date(now()).toISOString().replace(/[:.]/g, "-");
6148
+ const target = `${path}.recovering-${stamp}`;
6149
+ writeFileSync(target, "", { flag: "wx", mode: 384 });
6150
+ const dropTarget = /* @__PURE__ */ __name(() => {
6151
+ for (const suffix of [...STORE_PARTS, "-journal"])
6152
+ rmSync2(`${target}${suffix}`, { force: true });
6153
+ }, "dropTarget");
6154
+ note(`copying the readable rows into ${target}`);
6155
+ let copied;
6156
+ let copyErrors;
6157
+ let read;
6158
+ let opened;
6159
+ try {
6160
+ ;
6161
+ ({ errors: copyErrors, read } = await (copy ?? ((from, to) => copyReadableRows(from, to, sqlite3)))(path, target));
6162
+ copied = Date.now();
6163
+ opened = await openSqlite(target);
6164
+ } catch (error) {
6165
+ dropTarget();
6166
+ throw error;
6167
+ }
6168
+ let rebuilt;
6169
+ let kept;
6170
+ let dangling;
6171
+ let fetch2;
6172
+ try {
6173
+ kept = tableRows(opened.database);
6174
+ migrate(opened.database, { command, ...version ? { version } : {} });
6175
+ rebuilt = rebuildDerived(opened.database, { now, note });
6176
+ note("looking for rows that point at rows that were lost");
6177
+ dangling = danglingRows(opened.database);
6178
+ fetch2 = mailToFetch(opened.database);
6179
+ opened.database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
6180
+ } catch (error) {
6181
+ opened.database.close();
6182
+ dropTarget();
6183
+ throw error;
6184
+ }
6185
+ opened.database.close();
6186
+ const rebuiltAt = Date.now();
6187
+ note("checking the recovered file");
6188
+ const health = await storeHealth(target, { deep: true });
6189
+ const checkedAt = Date.now();
6190
+ if (!health.ok) {
6191
+ throw new CliError("validation_error", `the recovered file did not pass its check, so the store was left as it was; the file is kept at ${target}`, { reason: "store.recovery-failed" });
6192
+ }
6193
+ refuseInUse(path);
6194
+ if (fingerprint(path) !== before) {
6195
+ throw new CliError("validation_error", `the store was written to during the recovery, so it was left as it was \u2014 stop every timer and run it again; ${target} can be deleted`, { reason: "store.changed-during-recovery" });
6196
+ }
6197
+ const keptAt = `${path}.before-recover-${stamp}`;
6198
+ for (const suffix of STORE_PARTS)
6199
+ if (existsSync2(`${path}${suffix}`))
6200
+ renameSync2(`${path}${suffix}`, `${keptAt}${suffix}`);
6201
+ for (const suffix of STORE_PARTS)
6202
+ if (existsSync2(`${target}${suffix}`))
6203
+ renameSync2(`${target}${suffix}`, `${path}${suffix}`);
6204
+ const lost = Object.entries(rowsBefore).map(([table, before2]) => ({ table, before: before2, read: read[table] ?? 0, kept: kept[table] ?? 0 })).filter(({ before: before2, read: read2, kept: kept2 }) => before2 === null || before2 > kept2 || read2 > kept2);
6205
+ const seconds = /* @__PURE__ */ __name((from, to) => Math.round((to - from) / 100) / 10, "seconds");
6206
+ return {
6207
+ path,
6208
+ keptAt,
6209
+ sqlite3: program.version,
6210
+ lost,
6211
+ dangling,
6212
+ mailToFetch: fetch2,
6213
+ rebuilt,
6214
+ copyErrors,
6215
+ health,
6216
+ seconds: {
6217
+ copy: seconds(started, copied),
6218
+ rebuild: seconds(copied, rebuiltAt),
6219
+ check: seconds(rebuiltAt, checkedAt),
6220
+ total: seconds(started, Date.now())
6221
+ }
6222
+ };
6223
+ }, "recoverStore");
6224
+
6225
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/store-recover.js
6226
+ var COUNTED = [
6227
+ "accounts",
6228
+ "chats",
6229
+ "messages",
6230
+ "attachments",
6231
+ "emails",
6232
+ "documents",
6233
+ "notes",
6234
+ "meetings",
6235
+ "chunks",
6236
+ "embeddings",
6237
+ "mentions"
6238
+ ];
6239
+ var stopTimers = /* @__PURE__ */ __name((timers) => `systemctl --user stop ${timers.join(" ")}`, "stopTimers");
6240
+ var storeRecoveryCheck = /* @__PURE__ */ __name(async (env, command) => {
6241
+ const path = storePath(env);
6242
+ if (!existsSync3(path))
6243
+ return { path, exists: false, ok: true, next: [] };
6244
+ const health = await storeHealth(path, { deep: true });
6245
+ let rows = {};
6246
+ try {
6247
+ const { database } = await openSqlite(path, { readOnly: true });
6248
+ try {
6249
+ const all = tableRows(database);
6250
+ rows = Object.fromEntries(COUNTED.filter((table) => table in all).map((table) => [table, all[table] ?? null]));
6251
+ } finally {
6252
+ database.close();
6253
+ }
6254
+ } catch {
6255
+ }
6256
+ const explanation = explainDamage(health, command);
6257
+ const inUse = storeHolders(path) ?? null;
6258
+ const timers = activeTimers() ?? null;
6259
+ const sqlite3 = sqlite3Program();
6260
+ const next = health.ok ? [] : [
6261
+ ...timers?.length ? [stopTimers(timers)] : [],
6262
+ ...(inUse ?? []).map(({ pid, name }) => `stop ${name} (process ${pid}): it has the store open`),
6263
+ ...sqlite3.usable ? [] : ["install sqlite3 3.43 or newer (apt install sqlite3, brew install sqlite)"],
6264
+ `${command} store recover run`
6265
+ ];
6266
+ return {
6267
+ path,
6268
+ exists: true,
6269
+ ok: health.ok,
6270
+ seconds: Math.round(health.ms / 100) / 10,
6271
+ problems: health.problems ?? 0,
6272
+ damagedTables: health.damagedTables ?? [],
6273
+ damagedSearchIndexes: (health.searchIndexes ?? []).filter((index) => !index.ok).map(({ name, error }) => ({ name, ...error ? { error } : {} })),
6274
+ rows,
6275
+ explanation,
6276
+ inUse,
6277
+ timers,
6278
+ sqlite3: { version: sqlite3.version, usable: sqlite3.usable },
6279
+ next
6280
+ };
6281
+ }, "storeRecoveryCheck");
6282
+ var storeRecoveryRun = /* @__PURE__ */ __name(async (env, { command, version, note, timers: scheduled = activeTimers, copy }) => {
6283
+ const timers = scheduled() ?? [];
6284
+ if (timers.length > 0)
6285
+ throw new CliError("validation_error", `stop the timers first, they open the store: ${stopTimers(timers)}`, {
6286
+ reason: "store.in-use"
6287
+ });
6288
+ const recovery = await recoverStore({
6289
+ path: storePath(env),
6290
+ command,
6291
+ ...version ? { version } : {},
6292
+ ...note ? { note } : {},
6293
+ ...copy ? { copy } : {}
6294
+ });
6295
+ const mail = recovery.mailToFetch.map(({ account, emails }) => `mail <profile of ${account}> sync --rescan # ${emails} emails`);
6296
+ const lostMail = recovery.lost.some(({ table }) => table === "emails") && mail.length === 0 ? ["mail <profile> sync --rescan # each mail profile"] : [];
6297
+ const { health, copyErrors, ...kept } = recovery;
6298
+ return {
6299
+ ...kept,
6300
+ copyErrors: copyErrors.length,
6301
+ checkedOk: health.ok,
6302
+ next: [...mail, ...lostMail, "systemctl --user start <the timers stopped before>"]
6303
+ };
6304
+ }, "storeRecoveryRun");
6305
+ var recoveryNotes = /* @__PURE__ */ __name((answer) => {
6306
+ if ("keptAt" in answer) {
6307
+ const lost = answer.lost.map(({ table, before, read, kept }) => `${table}: ${kept} kept of ${before ?? "an uncountable number"}${read > kept ? `, ${read - kept} read but unusable` : ""}`);
6308
+ return [
6309
+ `recovered in ${answer.seconds.total} s; the damaged file is kept at ${answer.keptAt}`,
6310
+ ...lost.length ? lost : ["no table lost a row"],
6311
+ ...answer.dangling.map(({ table, parent, rows }) => `${rows} rows of ${table} point at ${parent} rows the store does not hold`),
6312
+ ...answer.next.map((line) => `next: ${line}`)
6313
+ ];
6314
+ }
6315
+ if (!answer.exists)
6316
+ return ["no store yet"];
6317
+ if (answer.ok)
6318
+ return [`the store is healthy (checked every page and search index in ${answer.seconds} s)`];
6319
+ const why = answer.explanation;
6320
+ return [
6321
+ ...why ? [why.what, ...why.impact, why.externalUnaffected] : [],
6322
+ ...answer.next.map((line) => `next: ${line}`)
6323
+ ];
6324
+ }, "recoveryNotes");
6325
+ var storeRecoverCommand = /* @__PURE__ */ __name(({ command, version }) => {
6326
+ const recover = annotate(new Command("recover"), { effects: LOCAL_READ, examples: [`${command} store recover`] }).summary("what is damaged in the store and how to recover it").description("check every page and search index of the store, say what is damaged, what it means and the commands that recover it; changes nothing").action(async function() {
6327
+ const output = outputFor(this);
6328
+ const answer = await storeRecoveryCheck(environmentOf(this).env ?? process.env, command);
6329
+ renderAnswer(this, output, itemOf(snakeKeys(answer)));
6330
+ if (output.format === "pretty")
6331
+ for (const line of recoveryNotes(answer))
6332
+ output.renderer.note(line);
6333
+ });
6334
+ recover.addCommand(annotate(new Command("run"), { effects: LOCAL_WRITE, examples: [`${command} store recover run`] }).summary("rebuild a damaged store from every row it can read").description("copy every readable row into a new file with the sqlite3 program, rebuild the search indexes, mentions and vector index, check it, and put it in place of the store; the damaged file is kept beside it. Refuses while a WireCat timer or process has the store").action(async function() {
6335
+ const output = outputFor(this);
6336
+ const answer = await storeRecoveryRun(environmentOf(this).env ?? process.env, {
6337
+ command,
6338
+ ...version ? { version } : {},
6339
+ note: /* @__PURE__ */ __name((text) => output.renderer.note(text), "note")
6340
+ });
6341
+ renderAnswer(this, output, itemOf(snakeKeys(answer)));
6342
+ if (output.format === "pretty")
6343
+ for (const line of recoveryNotes(answer))
6344
+ output.renderer.note(line);
6345
+ }));
6346
+ return recover;
6347
+ }, "storeRecoverCommand");
6348
+
6349
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/store-info.js
5886
6350
  var pendingIfKnown = /* @__PURE__ */ __name((database) => database.prepare("SELECT 1 FROM pragma_table_info('messages') WHERE name = 'normalized_text'").get() ? pendingNormalization(database) : null, "pendingIfKnown");
5887
- var bytesOf = /* @__PURE__ */ __name((path) => existsSync2(path) ? statSync2(path).size : 0, "bytesOf");
6351
+ var bytesOf = /* @__PURE__ */ __name((path) => existsSync4(path) ? statSync3(path).size : 0, "bytesOf");
5888
6352
  var messageOf = /* @__PURE__ */ __name((error) => error instanceof Error ? error.message : String(error), "messageOf");
5889
6353
  var contentsOf = /* @__PURE__ */ __name((database, version, writable) => version > 0 && writable ? {
5890
6354
  rows: rowCounts(database),
@@ -5895,7 +6359,7 @@ var contentsOf = /* @__PURE__ */ __name((database, version, writable) => version
5895
6359
  } : { rows: {}, pendingNormalization: null, wordIndex: null, stemIndex: null }, "contentsOf");
5896
6360
  var storeInfo = /* @__PURE__ */ __name(async (env) => {
5897
6361
  const path = storePath(env);
5898
- if (!existsSync2(path))
6362
+ if (!existsSync4(path))
5899
6363
  return snakeKeys({ path, exists: false, schema: compatibilityOf(void 0) });
5900
6364
  let schema = compatibilityOf(void 0);
5901
6365
  try {
@@ -5928,7 +6392,7 @@ var storeInfoCommand = /* @__PURE__ */ __name(() => annotate(new Command("info")
5928
6392
  renderAnswer(this, outputFor(this), itemOf(answer));
5929
6393
  }), "storeInfoCommand");
5930
6394
 
5931
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/password.js
6395
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/password.js
5932
6396
  var ENCRYPT_OPTION = [
5933
6397
  "--encrypt",
5934
6398
  "compress and encrypt with a password, typed at a hidden prompt or piped on stdin; it is never kept \u2014 lose it and the file cannot be opened"
@@ -5947,9 +6411,9 @@ var passwordOf = /* @__PURE__ */ __name(async (command, { twice }) => {
5947
6411
  return password;
5948
6412
  }, "passwordOf");
5949
6413
 
5950
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/rules.js
5951
- import { existsSync as existsSync3, readFileSync } from "node:fs";
5952
- import { join } from "node:path";
6414
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/rules.js
6415
+ import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
6416
+ import { join as join2 } from "node:path";
5953
6417
  var REPLY_ACTIONS = ["reply", "task"];
5954
6418
  var REPLY_MODELS = ["fill-only", "may-reword"];
5955
6419
  var REPLY_KINDS = ["dialog", "group"];
@@ -6035,7 +6499,7 @@ var defaultRule = /* @__PURE__ */ __name((id) => ({
6035
6499
  reply: { template: "", asReply: true },
6036
6500
  limits: { perChat: "1/1d", perPerson: "1/1d" }
6037
6501
  }), "defaultRule");
6038
- var repliesPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies.json`), "repliesPathFor");
6502
+ var repliesPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join2(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies.json`), "repliesPathFor");
6039
6503
  var EVERYONE = { reply: "all", allow: { people: [], chats: [] }, deny: { people: [], chats: [] } };
6040
6504
  var outsideAudience = /* @__PURE__ */ __name((audience, person, chat) => {
6041
6505
  if (person !== null && audience.deny.people.includes(person))
@@ -6065,11 +6529,11 @@ var readReplies = /* @__PURE__ */ __name((path, provider) => {
6065
6529
  return parseReplies(readRepliesFile(path, provider), path, provider);
6066
6530
  }, "readReplies");
6067
6531
  var readRepliesFile = /* @__PURE__ */ __name((path, provider) => {
6068
- if (!existsSync3(path))
6532
+ if (!existsSync5(path))
6069
6533
  return { audience: structuredClone(EVERYONE), rules: [] };
6070
6534
  let parsed;
6071
6535
  try {
6072
- parsed = JSON.parse(readFileSync(path, "utf8"));
6536
+ parsed = JSON.parse(readFileSync2(path, "utf8"));
6073
6537
  } catch (error) {
6074
6538
  throw broken(path, error instanceof Error ? error.message : String(error));
6075
6539
  }
@@ -6118,9 +6582,9 @@ var problem = /* @__PURE__ */ __name((issue) => {
6118
6582
  }, "problem");
6119
6583
  var broken = /* @__PURE__ */ __name((path, why) => new CliError("configuration_error", `the reply rules ${path} cannot be read (${why}) \u2014 fix the file`), "broken");
6120
6584
 
6121
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/state.js
6122
- import { existsSync as existsSync4, readFileSync as readFileSync2 } from "node:fs";
6123
- import { join as join2 } from "node:path";
6585
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/state.js
6586
+ import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
6587
+ import { join as join3 } from "node:path";
6124
6588
  var ANSWERED_KEPT = 1e3;
6125
6589
  var times = record(string(), array(string()));
6126
6590
  var stateFile = object({
@@ -6132,13 +6596,13 @@ var stateFile = object({
6132
6596
  });
6133
6597
  var emptyState = /* @__PURE__ */ __name(() => ({ paused: false, answered: [], sent: {} }), "emptyState");
6134
6598
  var answeredKey = /* @__PURE__ */ __name((message) => `${message.chatId}:${message.id}`, "answeredKey");
6135
- var repliesStatePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join2(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, `${profile}.replies-state.json`), "repliesStatePathFor");
6599
+ var repliesStatePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join3(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, `${profile}.replies-state.json`), "repliesStatePathFor");
6136
6600
  var readRepliesState = /* @__PURE__ */ __name((path) => {
6137
- if (!existsSync4(path))
6601
+ if (!existsSync6(path))
6138
6602
  return emptyState();
6139
6603
  let parsed;
6140
6604
  try {
6141
- parsed = JSON.parse(readFileSync2(path, "utf8"));
6605
+ parsed = JSON.parse(readFileSync3(path, "utf8"));
6142
6606
  } catch (error) {
6143
6607
  throw broken2(path, error instanceof Error ? error.message : String(error));
6144
6608
  }
@@ -6171,7 +6635,7 @@ var recordReply = /* @__PURE__ */ __name((state, rule2, message, now) => {
6171
6635
  }, "recordReply");
6172
6636
  var broken2 = /* @__PURE__ */ __name((path, why) => new CliError("configuration_error", `the reply state ${path} cannot be read (${why}) \u2014 fix or move the file`), "broken");
6173
6637
 
6174
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/decide.js
6638
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/decide.js
6175
6639
  var skip = /* @__PURE__ */ __name((why) => ({ skip: why }), "skip");
6176
6640
  var decide = /* @__PURE__ */ __name((rule2, incoming, state, now) => {
6177
6641
  const { message, chat, owner, sender } = incoming;
@@ -6277,7 +6741,7 @@ var filled = /* @__PURE__ */ __name((template2, senderName) => {
6277
6741
  return template2.replaceAll("{firstName}", name.split(/\s+/)[0] ?? name).replaceAll("{name}", name);
6278
6742
  }, "filled");
6279
6743
 
6280
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/template.js
6744
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/template.js
6281
6745
  var import_liquidjs = __toESM(require_liquid_node(), 1);
6282
6746
  var TEMPLATE_LIMITS = {
6283
6747
  parse: 32768,
@@ -6437,7 +6901,7 @@ var renderReplyTemplate = /* @__PURE__ */ __name(async (reply, input) => {
6437
6901
  }
6438
6902
  }, "renderReplyTemplate");
6439
6903
 
6440
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/dry-run.js
6904
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/dry-run.js
6441
6905
  var DRY_RUN_DAYS = 7;
6442
6906
  var PAGE = 500;
6443
6907
  var dryRun = /* @__PURE__ */ __name(async (store, account, rules, { since, until = Date.now(), only, audience, render }) => {
@@ -6551,7 +7015,7 @@ var storedSince = /* @__PURE__ */ __name(async (store, account, chat, since) =>
6551
7015
  }
6552
7016
  }, "storedSince");
6553
7017
 
6554
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/embeddings/keys.js
7018
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/embeddings/keys.js
6555
7019
  var endpointKeyName = /* @__PURE__ */ __name((baseUrl) => {
6556
7020
  const host = new URL(baseUrl).host;
6557
7021
  return ["openai", "anthropic"].includes(host) ? `endpoint:${host}` : host;
@@ -6582,7 +7046,7 @@ var embeddingKeys = /* @__PURE__ */ __name((app, env = process.env, keyring) =>
6582
7046
  };
6583
7047
  }, "embeddingKeys");
6584
7048
 
6585
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/models/openai.js
7049
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/models/openai.js
6586
7050
  var options = strictObject({
6587
7051
  temperature: range(0, 2),
6588
7052
  top_p: range(0, 1),
@@ -6631,7 +7095,7 @@ var openai = {
6631
7095
  }), "complete")
6632
7096
  };
6633
7097
 
6634
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/models/index.js
7098
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/models/index.js
6635
7099
  var modelGateway = /* @__PURE__ */ __name((deps) => ({
6636
7100
  complete: /* @__PURE__ */ __name(async (request) => {
6637
7101
  if (deps.signal?.aborted)
@@ -6646,7 +7110,7 @@ var modelGateway = /* @__PURE__ */ __name((deps) => ({
6646
7110
  if (!adapter && target.provider === "openai")
6647
7111
  adapter = openai;
6648
7112
  if (!adapter && target.provider === "anthropic")
6649
- adapter = (await import("./anthropic-RHRAVHC2.js")).anthropic;
7113
+ adapter = (await import("./anthropic-JUJB4DCF.js")).anthropic;
6650
7114
  if (!adapter)
6651
7115
  throw new CliError("validation_error", `no model adapter for ${target.provider}`);
6652
7116
  if (request.images !== void 0 && adapter.images !== true)
@@ -6687,19 +7151,19 @@ var modelGateway = /* @__PURE__ */ __name((deps) => ({
6687
7151
  }, "complete")
6688
7152
  }), "modelGateway");
6689
7153
 
6690
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/consents.js
6691
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
6692
- import { join as join3 } from "node:path";
7154
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/consents.js
7155
+ import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
7156
+ import { join as join4 } from "node:path";
6693
7157
  var shape = strictObject({
6694
7158
  provider: nullable(pipe(string(), minLength(1))),
6695
7159
  deniedChats: array(pipe(string(), minLength(1)))
6696
7160
  });
6697
- var replyConsentPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join3(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies-consents.json`), "replyConsentPathFor");
7161
+ var replyConsentPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join4(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies-consents.json`), "replyConsentPathFor");
6698
7162
  var readReplyConsent = /* @__PURE__ */ __name((path) => {
6699
- if (!existsSync5(path))
7163
+ if (!existsSync7(path))
6700
7164
  return { provider: null, deniedChats: [] };
6701
7165
  try {
6702
- return parse(shape, JSON.parse(readFileSync3(path, "utf8")));
7166
+ return parse(shape, JSON.parse(readFileSync4(path, "utf8")));
6703
7167
  } catch {
6704
7168
  throw new CliError("configuration_error", "reply model consent is invalid; fix its file before granting consent");
6705
7169
  }
@@ -6712,7 +7176,7 @@ var mayModelReply = /* @__PURE__ */ __name((path, provider, chat) => {
6712
7176
  return consent.provider === provider && !consent.deniedChats.includes(chat);
6713
7177
  }, "mayModelReply");
6714
7178
 
6715
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/rendering.js
7179
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/rendering.js
6716
7180
  var replyRenderer = /* @__PURE__ */ __name((app, profile, settings, env, warn, options2 = {
6717
7181
  ai: true
6718
7182
  }) => async (rule2, message, chat, now) => {
@@ -6759,7 +7223,7 @@ var replyRenderer = /* @__PURE__ */ __name((app, profile, settings, env, warn, o
6759
7223
  return result2;
6760
7224
  }, "replyRenderer");
6761
7225
 
6762
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/replies/serve.js
7226
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/replies/serve.js
6763
7227
  var NOT_ALLOWED = "replies.send is not allow";
6764
7228
  var NO_RULES = "no rules";
6765
7229
  var ONLY_TASK = "opened a task, sent nothing";
@@ -6852,7 +7316,7 @@ var replyTo = /* @__PURE__ */ __name(async (deps, message) => {
6852
7316
  return { skip: why };
6853
7317
  }, "replyTo");
6854
7318
 
6855
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-catch-up.js
7319
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-catch-up.js
6856
7320
  var START_SYNC_DELAY_MS = 3e4;
6857
7321
  var START_SYNC_BUDGET_MS = 5 * 6e4;
6858
7322
  var START_SYNC_WINDOW_MS = 7 * 864e5;
@@ -6929,7 +7393,7 @@ var startSync = /* @__PURE__ */ __name(({ chats, newestHeld, fetch: fetch2, note
6929
7393
  };
6930
7394
  }, "startSync");
6931
7395
 
6932
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-members.js
7396
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-members.js
6933
7397
  var FIRST_FETCH_MS = 6e4;
6934
7398
  var DAY_MS = 864e5;
6935
7399
  var memberFetches = /* @__PURE__ */ __name(({ withStore, fetch: fetch2, warn, firstMs = FIRST_FETCH_MS, everyMs = DAY_MS }) => {
@@ -6983,7 +7447,7 @@ var memberFetches = /* @__PURE__ */ __name(({ withStore, fetch: fetch2, warn, fi
6983
7447
  };
6984
7448
  }, "memberFetches");
6985
7449
 
6986
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-notice.js
7450
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-notice.js
6987
7451
  var record2 = /* @__PURE__ */ __name((context, app, severity, attributes) => recordLogFor(context.streams.diagnostic, app, { command: currentRun().command || "serve" })[severity](attributes), "record");
6988
7452
  var noticeFor = /* @__PURE__ */ __name((context, app, severity = "warn") => ({ text, ...attributes }) => {
6989
7453
  if (context.format === "pretty") {
@@ -7016,7 +7480,7 @@ var recordDiagnostics = /* @__PURE__ */ __name((context, app) => {
7016
7480
  return context;
7017
7481
  }, "recordDiagnostics");
7018
7482
 
7019
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-stems.js
7483
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-stems.js
7020
7484
  var STEMS_EVERY_MS = 3e4;
7021
7485
  var STEMS_SLICE_MS = 2e3;
7022
7486
  var stemFills = /* @__PURE__ */ __name(({ withStore, warn, everyMs = STEMS_EVERY_MS, sliceMs = STEMS_SLICE_MS }) => {
@@ -7056,7 +7520,7 @@ var stemFills = /* @__PURE__ */ __name(({ withStore, warn, everyMs = STEMS_EVERY
7056
7520
  };
7057
7521
  }, "stemFills");
7058
7522
 
7059
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/message-items.js
7523
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/message-items.js
7060
7524
  var defined = /* @__PURE__ */ __name((value) => Object.fromEntries(Object.entries(value).filter(([, one]) => one !== void 0)), "defined");
7061
7525
  var attachmentItem = /* @__PURE__ */ __name((attachment) => defined({
7062
7526
  kind: attachment.kind,
@@ -7151,7 +7615,7 @@ var viewOf = /* @__PURE__ */ __name((context, messenger) => ({
7151
7615
  locale: messenger.app.locale
7152
7616
  }), "viewOf");
7153
7617
 
7154
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-answers.js
7618
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-answers.js
7155
7619
  var observed = /* @__PURE__ */ __name((value) => ({
7156
7620
  value: value.value,
7157
7621
  observed_at: value.observedAt,
@@ -7218,7 +7682,7 @@ var watchEventItem = /* @__PURE__ */ __name((value, account) => {
7218
7682
  }
7219
7683
  }, "watchEventItem");
7220
7684
 
7221
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-command.js
7685
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-command.js
7222
7686
  var watchCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("watch"), {
7223
7687
  output: { entity: "watch_item" },
7224
7688
  effects: REMOTE_READ,
@@ -7373,7 +7837,7 @@ var describe = /* @__PURE__ */ __name((event, render) => {
7373
7837
  }
7374
7838
  }, "describe");
7375
7839
 
7376
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-command.js
7840
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-command.js
7377
7841
  var serveCommand = /* @__PURE__ */ __name((messenger) => {
7378
7842
  const command = annotate(new Command("serve"), {
7379
7843
  output: { entity: "serve_summary" },
@@ -7637,8 +8101,8 @@ var tasking = /* @__PURE__ */ __name((context, warn) => {
7637
8101
  };
7638
8102
  }, "tasking");
7639
8103
 
7640
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/store-tables-command.js
7641
- import { existsSync as existsSync6 } from "node:fs";
8104
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/store-tables-command.js
8105
+ import { existsSync as existsSync8 } from "node:fs";
7642
8106
  var PATH = "store tables list";
7643
8107
  var STORE_TABLES_QUERY = {
7644
8108
  entity: "store_table",
@@ -7667,7 +8131,7 @@ var storeTablesCommand = /* @__PURE__ */ __name((messenger) => {
7667
8131
  const filter = filterOf(words);
7668
8132
  const { full } = this.optsWithGlobals();
7669
8133
  const path = storePath(environmentOf(this).env ?? process.env);
7670
- if (!existsSync6(path))
8134
+ if (!existsSync8(path))
7671
8135
  throw new CliError("not_found", `no store at ${path}`);
7672
8136
  const items = await readStoreTables(path, { filter, sizes: full === true });
7673
8137
  renderAnswer(this, outputFor(this), listOf(PATH, {
@@ -7680,7 +8144,7 @@ var storeTablesCommand = /* @__PURE__ */ __name((messenger) => {
7680
8144
  return tables;
7681
8145
  }, "storeTablesCommand");
7682
8146
 
7683
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
8147
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
7684
8148
  var SEARCH_INDEXES = ["messages_fts", "chats_fts", "identities_fts"];
7685
8149
  var WORD_INDEX = "message_words";
7686
8150
  var schemaOf = /* @__PURE__ */ __name((database) => {
@@ -7689,7 +8153,7 @@ var schemaOf = /* @__PURE__ */ __name((database) => {
7689
8153
  }, "schemaOf");
7690
8154
  var count2 = /* @__PURE__ */ __name((database, table) => Number(database.prepare(`SELECT count(*) AS n FROM ${table}`).get()?.n ?? 0), "count");
7691
8155
  var pendingIfKnown2 = /* @__PURE__ */ __name((database) => database.prepare("SELECT 1 FROM pragma_table_info('messages') WHERE name = 'normalized_text'").get() ? pendingNormalization(database) : null, "pendingIfKnown");
7692
- var bytesOf2 = /* @__PURE__ */ __name((path) => existsSync7(path) ? statSync3(path).size : 0, "bytesOf");
8156
+ var bytesOf2 = /* @__PURE__ */ __name((path) => existsSync9(path) ? statSync4(path).size : 0, "bytesOf");
7693
8157
  var reading = /* @__PURE__ */ __name(async (path, read) => {
7694
8158
  const database = await openCache(path);
7695
8159
  try {
@@ -7706,10 +8170,22 @@ var readingOnly = /* @__PURE__ */ __name(async (path, read) => {
7706
8170
  database.close();
7707
8171
  }
7708
8172
  }, "readingOnly");
7709
- var storeSummary = /* @__PURE__ */ __name(async (env) => {
8173
+ var storeSummary = /* @__PURE__ */ __name(async (env, { deep = false, command } = {}) => {
7710
8174
  const path = storePath(env);
7711
- if (!existsSync7(path))
8175
+ if (!existsSync9(path))
7712
8176
  return { path, exists: false };
8177
+ const checked = await storeHealth(path, { deep });
8178
+ const health = {
8179
+ checked: checked.checked,
8180
+ covers: deep ? "every page and every search index" : QUICK_HEALTH_CHECKS,
8181
+ ok: checked.ok,
8182
+ ms: checked.ms,
8183
+ ...checked.problems ? { problems: checked.problems } : {},
8184
+ ...checked.damagedTables?.length ? { damagedTables: checked.damagedTables } : {},
8185
+ ...checked.searchIndexes?.some((index) => !index.ok) ? { damagedSearchIndexes: checked.searchIndexes.filter((index) => !index.ok).map((index) => index.name) } : {}
8186
+ };
8187
+ const damage = command ? explainDamage(checked, command) : null;
8188
+ const healthOf = { health, ...damage ? { damage } : {} };
7713
8189
  try {
7714
8190
  return await reading(path, (database) => {
7715
8191
  const { version, writable } = schemaOf(database);
@@ -7719,11 +8195,12 @@ var storeSummary = /* @__PURE__ */ __name(async (env) => {
7719
8195
  schema: version,
7720
8196
  speaks: SPEAKS,
7721
8197
  writable,
7722
- ...version > 0 ? { chats: count2(database, "chats"), messages: count2(database, "messages") } : {}
8198
+ ...version > 0 ? { chats: count2(database, "chats"), messages: count2(database, "messages") } : {},
8199
+ ...healthOf
7723
8200
  };
7724
8201
  });
7725
8202
  } catch (error) {
7726
- return { path, exists: true, error: messageOf2(error) };
8203
+ return { path, exists: true, error: messageOf2(error), ...healthOf };
7727
8204
  }
7728
8205
  }, "storeSummary");
7729
8206
  var result = /* @__PURE__ */ __name((command, value, next = []) => renderAnswer(command, outputFor(command), itemOf(snakeKeys(value), { next })), "result");
@@ -7738,7 +8215,8 @@ var storeMaintenanceCommands = /* @__PURE__ */ __name((messenger) => [
7738
8215
  repairCommand(messenger),
7739
8216
  resetCommand(messenger),
7740
8217
  copiesCommand(),
7741
- storeTablesCommand(messenger)
8218
+ storeTablesCommand(messenger),
8219
+ storeRecoverCommand({ command: messenger.app.command, version: messenger.app.version })
7742
8220
  ], "storeMaintenanceCommands");
7743
8221
  var refuseWhileServing = /* @__PURE__ */ __name((command, messenger) => {
7744
8222
  const serving = servingProfiles(messenger.app, environmentOf(command).env ?? process.env);
@@ -7750,7 +8228,7 @@ var repairCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("
7750
8228
  const { renderer, format } = outputFor(this);
7751
8229
  const { dryRun: dryRun2 } = this.opts();
7752
8230
  const path = storePath(environmentOf(this).env ?? process.env);
7753
- if (!existsSync7(path)) {
8231
+ if (!existsSync9(path)) {
7754
8232
  result(this, { path, exists: false });
7755
8233
  return;
7756
8234
  }
@@ -7790,7 +8268,7 @@ var notesOf = /* @__PURE__ */ __name((report, command) => {
7790
8268
  }, "notesOf");
7791
8269
  var copiesCommand = /* @__PURE__ */ __name(() => new Command("copies").description("the tables `store repair` kept as copies").addCommand(annotate(new Command("delete"), { output: { entity: "store_copy_removal" }, effects: LOCAL_WRITE }).description("delete one copy `store repair` kept, named exactly; refuses any other table").argument("<name>", "the copy's name, as `store repair` printed it").action(async function(name) {
7792
8270
  const path = storePath(environmentOf(this).env ?? process.env);
7793
- if (!existsSync7(path))
8271
+ if (!existsSync9(path))
7794
8272
  throw new CliError("not_found", `no store at ${path}`);
7795
8273
  const deleted = await reading(path, (database) => deleteCopy(database, name));
7796
8274
  result(this, { path, deleted });
@@ -7798,7 +8276,7 @@ var copiesCommand = /* @__PURE__ */ __name(() => new Command("copies").descripti
7798
8276
  var checkCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("check"), { output: { entity: "store_check" }, effects: LOCAL_READ }).summary("check the local archive for problems").description("whether the store is healthy \u2014 integrity, search indexes, disk, and which chats are behind").action(async function() {
7799
8277
  const { renderer } = outputFor(this);
7800
8278
  const path = storePath(environmentOf(this).env ?? process.env);
7801
- if (!existsSync7(path)) {
8279
+ if (!existsSync9(path)) {
7802
8280
  result(this, { path, exists: false, ok: true });
7803
8281
  return;
7804
8282
  }
@@ -7861,7 +8339,7 @@ var inspect = /* @__PURE__ */ __name((path) => reading(path, (database) => {
7861
8339
  ...schema.version > 0 ? [["attachment_words", indexIntegrity(database, "attachment_words", 0)]] : []
7862
8340
  ]);
7863
8341
  const size = bytesOf2(path) + bytesOf2(`${path}-wal`);
7864
- const { bavail, bsize } = statfsSync(dirname(path));
8342
+ const { bavail, bsize } = statfsSync2(dirname2(path));
7865
8343
  const free = Number(bavail) * Number(bsize);
7866
8344
  const behind = schema.version > 0 ? chatsBehind(database) : [];
7867
8345
  const vectorIndexes = schema.version >= 34 ? vectorIndexCounts(database) : [];
@@ -7949,14 +8427,18 @@ var chatsBehind = /* @__PURE__ */ __name((database) => database.prepare(`SELECT
7949
8427
  var migrateCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("migrate"), { output: { entity: "store_migration" }, effects: LOCAL_WRITE }).summary("migrate an older local archive").description("bring the store up to this build's schema, then normalize, index and stem the messages and notes stored before it").action(async function() {
7950
8428
  const { renderer } = outputFor(this);
7951
8429
  const path = storePath(environmentOf(this).env ?? process.env);
7952
- if (!existsSync7(path)) {
8430
+ if (!existsSync9(path)) {
7953
8431
  result(this, { path, exists: false });
7954
8432
  renderer.note(`no store yet \u2014 the first \`${messenger.app.command}\` command that reads a chat creates it`);
7955
8433
  return;
7956
8434
  }
7957
8435
  const answer = await reading(path, (database) => {
7958
8436
  const from = schemaOf(database).version;
7959
- migrate(database, { command: messenger.app.command, version: messenger.app.version });
8437
+ migrate(database, {
8438
+ command: messenger.app.command,
8439
+ version: messenger.app.version,
8440
+ rollback: { store: path, warn: /* @__PURE__ */ __name((line) => renderer.warn(line), "warn") }
8441
+ });
7960
8442
  const { normalized, indexed, terms } = buildWordIndex(database, (note) => renderer.note(note));
7961
8443
  const stemmed = buildStems(database, (note) => renderer.note(note));
7962
8444
  const notes = buildNoteIndex(database, (note) => renderer.note(note));
@@ -8009,7 +8491,7 @@ var buildNoteIndex = /* @__PURE__ */ __name((database, note, { reset = false } =
8009
8491
  var reindexCommand = /* @__PURE__ */ __name((messenger) => destroysNothing(annotate(new Command("rebuild"), { output: { entity: "store_reindex" }, effects: LOCAL_WRITE })).summary("rebuild the local archive's search indexes").description("rebuild the word index, its typo vocabulary, the stems, the files' word index, the notes' indexes and who took part in what, from what is stored, and drop the vectors no stored text uses; loses nothing").action(async function() {
8010
8492
  const { renderer } = outputFor(this);
8011
8493
  const path = storePath(environmentOf(this).env ?? process.env);
8012
- if (!existsSync7(path)) {
8494
+ if (!existsSync9(path)) {
8013
8495
  result(this, { path, exists: false });
8014
8496
  return;
8015
8497
  }
@@ -8038,11 +8520,11 @@ var reindexCommand = /* @__PURE__ */ __name((messenger) => destroysNothing(annot
8038
8520
  result(this, answer);
8039
8521
  }), "reindexCommand");
8040
8522
  var vacuumInto = /* @__PURE__ */ __name(async (path, target) => {
8041
- writeFileSync(target, "", { flag: "wx", mode: 384 });
8523
+ writeFileSync2(target, "", { flag: "wx", mode: 384 });
8042
8524
  try {
8043
8525
  await reading(path, (database) => database.prepare("VACUUM INTO ?").run(target));
8044
8526
  } catch (error) {
8045
- rmSync2(target, { force: true });
8527
+ rmSync3(target, { force: true });
8046
8528
  throw error;
8047
8529
  }
8048
8530
  }, "vacuumInto");
@@ -8051,9 +8533,9 @@ var backupCommand = /* @__PURE__ */ __name(() => destroysNothing(annotate(new Co
8051
8533
  const { encrypt } = this.opts();
8052
8534
  const path = storePath(environmentOf(this).env ?? process.env);
8053
8535
  const target = resolve(file2);
8054
- if (!existsSync7(path))
8536
+ if (!existsSync9(path))
8055
8537
  throw new CliError("not_found", `no store at ${path} to back up`);
8056
- if (existsSync7(target))
8538
+ if (existsSync9(target))
8057
8539
  throw new CliError("validation_error", `${target} exists \u2014 a backup never overwrites a file`);
8058
8540
  const password = encrypt ? await passwordOf(this, { twice: true }) : void 0;
8059
8541
  const copyAt = password === void 0 ? target : `${path}.backup-${process.pid}`;
@@ -8075,67 +8557,69 @@ var backupCommand = /* @__PURE__ */ __name(() => destroysNothing(annotate(new Co
8075
8557
  });
8076
8558
  } catch (error) {
8077
8559
  if (password === void 0)
8078
- rmSync2(target, { force: true });
8560
+ rmSync3(target, { force: true });
8079
8561
  throw error;
8080
8562
  } finally {
8081
8563
  if (password !== void 0)
8082
- rmSync2(copyAt, { force: true });
8564
+ rmSync3(copyAt, { force: true });
8083
8565
  }
8084
8566
  }), "backupCommand");
8085
8567
  var decryptCommand = /* @__PURE__ */ __name(() => annotate(new Command("decrypt"), { output: { entity: "store_decrypt" }, effects: LOCAL_WRITE }).description("open a file written with --encrypt into a new file; asks for its password").argument("<file>", "a file `store backup --encrypt` or `store export --encrypt` wrote").requiredOption("--output <file>", "the new file, readable only by you").action(async function(file2) {
8086
8568
  const { output } = this.opts();
8087
8569
  const from = resolve(file2);
8088
8570
  const to = resolve(output);
8089
- if (!existsSync7(from))
8571
+ if (!existsSync9(from))
8090
8572
  throw new CliError("not_found", `no file at ${from}`);
8091
8573
  if (!isSealed(from))
8092
8574
  throw new CliError("validation_error", `${from} was not written with --encrypt`);
8093
- if (existsSync7(to))
8575
+ if (existsSync9(to))
8094
8576
  throw new CliError("validation_error", `${to} exists \u2014 never overwritten`);
8095
8577
  await unsealFile(from, to, await passwordOf(this, { twice: false }));
8096
8578
  result(this, { path: to, from, bytes: bytesOf2(to) });
8097
8579
  }), "decryptCommand");
8098
- var restoreCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("restore"), { output: { entity: "store_restore" }, effects: LOCAL_WRITE }).summary("restore a backup while keeping the current store").description("put a backup in place of the store; the store it replaces is kept beside it, never deleted").argument("<file>", "a file `store backup` wrote; one written with --encrypt asks for its password").action(async function(file2) {
8580
+ var restoreCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("restore"), { output: { entity: "store_restore" }, effects: LOCAL_WRITE }).summary("restore a backup and keep the current store, or roll back a breaking upgrade").description("put a backup in place of the store; the store it replaces is kept beside it, never deleted. Given a rollback copy (backups/<store>-rollback-schema-<version>-<time>.db, kept for a day before an upgrade older tools cannot open), put its tables back in the store and return it to that version instead").argument("<file>", "a file `store backup` wrote, or a rollback copy; one written with --encrypt asks for its password").action(async function(file2) {
8099
8581
  const path = storePath(environmentOf(this).env ?? process.env);
8100
8582
  const given = resolve(file2);
8101
- if (!existsSync7(given))
8583
+ if (!existsSync9(given))
8102
8584
  throw new CliError("not_found", `no file at ${given}`);
8103
8585
  refuseWhileServing(this, messenger);
8104
8586
  if (!isSealed(given))
8105
8587
  return restoreFrom(this, messenger, given, given);
8106
8588
  const opened = `${path}.unsealing-${process.pid}`;
8107
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
8589
+ mkdirSync(dirname2(path), { recursive: true, mode: 448 });
8108
8590
  try {
8109
8591
  await unsealFile(given, opened, await passwordOf(this, { twice: false }));
8110
8592
  await restoreFrom(this, messenger, opened, given);
8111
8593
  } finally {
8112
- rmSync2(opened, { force: true });
8594
+ rmSync3(opened, { force: true });
8113
8595
  }
8114
8596
  }), "restoreCommand");
8115
8597
  var restoreFrom = /* @__PURE__ */ __name(async (command, messenger, backup, given) => {
8116
8598
  const { renderer } = outputFor(command);
8117
8599
  const path = storePath(environmentOf(command).env ?? process.env);
8118
- if (existsSync7(path) && realpathSync(backup) === realpathSync(path)) {
8600
+ if (existsSync9(path) && realpathSync2(backup) === realpathSync2(path)) {
8119
8601
  throw new CliError("validation_error", `${backup} is the store itself`);
8120
8602
  }
8603
+ if (await isRollbackCopy(backup))
8604
+ return rollBackFrom(command, messenger, backup);
8121
8605
  const schema = await backupSchema(backup);
8122
8606
  const stamp = stampNow();
8123
- const kept = existsSync7(path) ? `${path}.before-restore-${stamp}` : null;
8607
+ const kept = existsSync9(path) ? `${path}.before-restore-${stamp}` : null;
8124
8608
  if (kept) {
8125
8609
  const waitMs = environmentOf(command).storeLockWaitMs;
8126
8610
  await quiesce(path, messenger, "restore", (message) => renderer.warn(message), waitMs);
8127
8611
  } else
8128
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
8612
+ mkdirSync(dirname2(path), { recursive: true, mode: 448 });
8129
8613
  const incoming = `${path}.restoring-${stamp}`;
8130
8614
  copyFileSync(backup, incoming, constants.COPYFILE_EXCL);
8131
8615
  chmodSync(incoming, 384);
8132
8616
  if (kept) {
8133
- renameSync2(path, kept);
8617
+ renameSync3(path, kept);
8134
8618
  for (const suffix of ["-wal", "-shm"])
8135
- if (existsSync7(`${path}${suffix}`))
8136
- renameSync2(`${path}${suffix}`, `${kept}${suffix}`);
8619
+ if (existsSync9(`${path}${suffix}`))
8620
+ renameSync3(`${path}${suffix}`, `${kept}${suffix}`);
8137
8621
  }
8138
- renameSync2(incoming, path);
8622
+ renameSync3(incoming, path);
8139
8623
  result(command, { path, restoredFrom: given, keptAt: kept, schema: schema.version });
8140
8624
  if (kept)
8141
8625
  renderer.note(`the store it replaced is kept at ${kept}`);
@@ -8144,6 +8628,43 @@ var restoreFrom = /* @__PURE__ */ __name(async (command, messenger, backup, give
8144
8628
  renderer.note(`the backup is behind this build; the next command migrates it \u2014 \`${lineOf(command, "store migrate")}\` now`);
8145
8629
  }
8146
8630
  }, "restoreFrom");
8631
+ var isRollbackCopy = /* @__PURE__ */ __name(async (file2) => {
8632
+ try {
8633
+ return await readingOnly(file2, (database) => database.prepare("SELECT 1 FROM sqlite_master WHERE name = 'rollback_meta'").get() !== void 0);
8634
+ } catch {
8635
+ return false;
8636
+ }
8637
+ }, "isRollbackCopy");
8638
+ var rollBackFrom = /* @__PURE__ */ __name(async (command, messenger, copy) => {
8639
+ const { renderer } = outputFor(command);
8640
+ const path = storePath(environmentOf(command).env ?? process.env);
8641
+ if (!existsSync9(path))
8642
+ throw new CliError("not_found", `no store at ${path} to roll back`);
8643
+ const waitMs = environmentOf(command).storeLockWaitMs;
8644
+ await quiesce(path, messenger, "restore", (message) => renderer.warn(message), waitMs);
8645
+ const { database } = await openSqlite(path);
8646
+ let rolled;
8647
+ try {
8648
+ rolled = rollBack(database, copy);
8649
+ } finally {
8650
+ database.close();
8651
+ }
8652
+ result(command, {
8653
+ path,
8654
+ restoredFrom: copy,
8655
+ rolledBack: true,
8656
+ schema: rolled.from,
8657
+ was: rolled.was,
8658
+ tables: rolled.restored,
8659
+ rebuilt: rolled.rebuilt,
8660
+ foreignKeyViolations: rolled.foreignKeyViolations
8661
+ });
8662
+ const taken = new Date(rolled.createdAt).toISOString();
8663
+ renderer.note(`the store is back at schema ${rolled.from}; ${rolled.tables.length > 0 ? rolled.tables.join(", ") : "no table"} hold what they held at ${taken}, and what was written to them since is not kept`);
8664
+ renderer.note("open it with the older tool and run its `store rebuild`: the search indexes are behind the tables");
8665
+ renderer.note(`a tool that speaks schema ${rolled.to} or later migrates it again on its next run`);
8666
+ renderer.note("restart every serve and mcp of either CLI that was running, so they read the restored store");
8667
+ }, "rollBackFrom");
8147
8668
  var backupSchema = /* @__PURE__ */ __name(async (backup) => {
8148
8669
  let read;
8149
8670
  try {
@@ -8167,7 +8688,7 @@ var backupSchema = /* @__PURE__ */ __name(async (backup) => {
8167
8688
  var STORE_LOCK_WAIT_MS = 1e3;
8168
8689
  var quiesce = /* @__PURE__ */ __name(async (path, messenger, then, warn, waitMs = STORE_LOCK_WAIT_MS) => {
8169
8690
  const { command } = messenger.app;
8170
- const files = [path, `${path}-wal`, `${path}-shm`].filter((file2) => existsSync7(file2)).map((file2) => realpathSync(file2));
8691
+ const files = [path, `${path}-wal`, `${path}-shm`].filter((file2) => existsSync9(file2)).map((file2) => realpathSync2(file2));
8171
8692
  const holders = holdersOf(files);
8172
8693
  if (holders === void 0) {
8173
8694
  warn(`this system cannot say which processes have the store open \u2014 restart every running serve and mcp after this`);
@@ -8193,7 +8714,7 @@ var resetCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("r
8193
8714
  const { command } = messenger.app;
8194
8715
  const env = environmentOf(this).env ?? process.env;
8195
8716
  const path = storePath(env);
8196
- if (!existsSync7(path)) {
8717
+ if (!existsSync9(path)) {
8197
8718
  result(this, { path, exists: false, reset: false });
8198
8719
  renderer.note(`no store at ${path} \u2014 nothing to reset; the first \`${command}\` command that reads a chat creates it`);
8199
8720
  return;
@@ -8229,17 +8750,17 @@ var resetCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("r
8229
8750
  });
8230
8751
  renderer.note(`backed the store up to ${backup}`);
8231
8752
  }
8232
- for (const suffix of STORE_PARTS)
8233
- rmSync2(`${path}${suffix}`, { force: true });
8753
+ for (const suffix of STORE_PARTS2)
8754
+ rmSync3(`${path}${suffix}`, { force: true });
8234
8755
  await (await openStore({ path, command })).close();
8235
8756
  const schema = await reading(path, (database) => schemaOf(database).version);
8236
8757
  result(this, { path, exists: true, reset: true, backup, backedUp, schema });
8237
8758
  renderer.note(backup ? `the store is empty at schema ${schema}; \`${command} store restore ${backup}\` puts the old one back once a build can read it` : `the store is empty at schema ${schema}; there is no backup`);
8238
8759
  }), "resetCommand");
8239
- var STORE_PARTS = ["", "-wal", "-shm"];
8760
+ var STORE_PARTS2 = ["", "-wal", "-shm"];
8240
8761
  var resetPreview = /* @__PURE__ */ __name(async (path, messenger, env, keep) => {
8241
- const files = STORE_PARTS.map((suffix) => `${path}${suffix}`).filter((file2) => existsSync7(file2));
8242
- const holders = holdersOf(files.map((file2) => realpathSync(file2)));
8762
+ const files = STORE_PARTS2.map((suffix) => `${path}${suffix}`).filter((file2) => existsSync9(file2));
8763
+ const holders = holdersOf(files.map((file2) => realpathSync2(file2)));
8243
8764
  const serving = servingProfiles(messenger.app, env).length > 0;
8244
8765
  const read = await readingOnly(path, (database) => ({
8245
8766
  schema: schemaOf(database).version,