@wirecat/cli-memo 0.131.46 → 0.131.48

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 (132) hide show
  1. package/dist/bin/memo.js +2 -2
  2. package/dist/bundle/{all-profiles-I2JBJDOR.js → all-profiles-5YVSKBEV.js} +9 -9
  3. package/dist/bundle/{anthropic-CARSCLDG.js → anthropic-BMK6F36V.js} +6 -6
  4. package/dist/bundle/{app-server-SAMZMY3C.js → app-server-PUBWKHUG.js} +48 -45
  5. package/dist/bundle/auto-FXCXORUF.js +86 -0
  6. package/dist/bundle/{bun-T6E2RGI5.js → bun-ZBM364I6.js} +2 -2
  7. package/dist/bundle/{bun-sqlite-WWDLRDBW.js → bun-sqlite-YLBILWBE.js} +5 -5
  8. package/dist/bundle/{chunk-PIHAI7NF.js → chunk-2O32QNK3.js} +7 -7
  9. package/dist/bundle/{chunk-HE535VWC.js → chunk-3A3KPJHP.js} +4 -4
  10. package/dist/bundle/{chunk-XB43J5VQ.js → chunk-3LA6OE35.js} +9 -9
  11. package/dist/bundle/{chunk-IQJQLLAV.js → chunk-4FDK7LVF.js} +7 -7
  12. package/dist/bundle/{chunk-3ZLDPPI4.js → chunk-5BDWOMH6.js} +6 -6
  13. package/dist/bundle/{chunk-IFGMJXND.js → chunk-66KZBRZN.js} +3 -3
  14. package/dist/bundle/{chunk-JY34MQW4.js → chunk-7RNHFNHX.js} +4 -4
  15. package/dist/bundle/{chunk-CWBRCYDY.js → chunk-ADV7DNGM.js} +5 -5
  16. package/dist/bundle/{chunk-YFZ45S6S.js → chunk-BRLVX4V6.js} +1 -1
  17. package/dist/bundle/{chunk-RZ54DSVU.js → chunk-BXTDAGM4.js} +2 -2
  18. package/dist/bundle/{chunk-NFSFUVP2.js → chunk-C3I6L7JZ.js} +6 -6
  19. package/dist/bundle/{chunk-6B75W6XW.js → chunk-C6UTJATA.js} +38 -14
  20. package/dist/bundle/{chunk-J6EUSJ3X.js → chunk-CSPAEYKK.js} +4 -4
  21. package/dist/bundle/{chunk-AXCYTZJD.js → chunk-DGLSE6XA.js} +6 -6
  22. package/dist/bundle/{chunk-CV5MM7HG.js → chunk-DHO2JWF7.js} +3 -3
  23. package/dist/bundle/{chunk-UT2K3TAH.js → chunk-DMI3SFLF.js} +2 -2
  24. package/dist/bundle/{chunk-2K7E5YOZ.js → chunk-DNZYXNMB.js} +4 -4
  25. package/dist/bundle/{chunk-BJSZECFV.js → chunk-DPQL5JK6.js} +2 -2
  26. package/dist/bundle/{chunk-UI4MKFTZ.js → chunk-E4YCKC3F.js} +12 -12
  27. package/dist/bundle/{chunk-SN63VOE6.js → chunk-EBNNONF5.js} +8 -8
  28. package/dist/bundle/{chunk-YPD27HJI.js → chunk-EGVRMA2C.js} +198 -81
  29. package/dist/bundle/{chunk-RF3R3W2I.js → chunk-EQ237UYC.js} +22 -22
  30. package/dist/bundle/{chunk-V7QNIJOE.js → chunk-F7S25YVA.js} +9 -9
  31. package/dist/bundle/{chunk-TOSRVNCY.js → chunk-FTRFN3MU.js} +8 -8
  32. package/dist/bundle/{chunk-VUSM6XFE.js → chunk-H4726KFZ.js} +1 -1
  33. package/dist/bundle/{chunk-PZQCIEMC.js → chunk-HE56X542.js} +1 -1
  34. package/dist/bundle/{chunk-QUUYSYCG.js → chunk-IGYOKYG7.js} +4 -4
  35. package/dist/bundle/{chunk-MKA3NOUU.js → chunk-IHFK634F.js} +8 -8
  36. package/dist/bundle/{chunk-IPNORZSF.js → chunk-IWEL7QCT.js} +11 -11
  37. package/dist/bundle/{chunk-KGVDWSGM.js → chunk-J737T3RM.js} +3 -3
  38. package/dist/bundle/{chunk-JX6JZTOI.js → chunk-KNUUZW42.js} +29 -29
  39. package/dist/bundle/{chunk-36DLHVMS.js → chunk-LDHFV34C.js} +2 -2
  40. package/dist/bundle/{chunk-7UNXTC2J.js → chunk-LDXCFBIC.js} +34 -34
  41. package/dist/bundle/{chunk-TU34HVOY.js → chunk-MIMLBSUQ.js} +2 -2
  42. package/dist/bundle/{chunk-UEMY6RSB.js → chunk-MKLDUZ7N.js} +2 -2
  43. package/dist/bundle/{chunk-F7XQEYF3.js → chunk-MN3SFFTU.js} +303 -280
  44. package/dist/bundle/{chunk-WXCRRP4B.js → chunk-NWRITJ7F.js} +2 -2
  45. package/dist/bundle/{chunk-2R2Z2VWL.js → chunk-O3ZOYXH3.js} +20 -20
  46. package/dist/bundle/{chunk-CID4MNRQ.js → chunk-P3ASN72F.js} +1 -1
  47. package/dist/bundle/{chunk-LOSAAPRY.js → chunk-PUZ2G2KS.js} +8 -8
  48. package/dist/bundle/{chunk-Y5CAKD4X.js → chunk-QOGYHU3Q.js} +4 -4
  49. package/dist/bundle/{chunk-AAKU7TGI.js → chunk-QTBFV5RL.js} +3 -3
  50. package/dist/bundle/{chunk-ZGQSWRCY.js → chunk-QUQJZSRF.js} +566 -351
  51. package/dist/bundle/{chunk-IEVJMRL2.js → chunk-RCEDN42Q.js} +1 -1
  52. package/dist/bundle/{chunk-ICF3LNBX.js → chunk-RSJJGXZP.js} +1 -1
  53. package/dist/bundle/{chunk-UYITVRUC.js → chunk-SGDTAVMU.js} +2 -2
  54. package/dist/bundle/{chunk-TFWTSBON.js → chunk-T56R3TF2.js} +664 -117
  55. package/dist/bundle/{chunk-37D3IHOG.js → chunk-TW643BIA.js} +99 -74
  56. package/dist/bundle/{chunk-5FBJQHCG.js → chunk-TYOZC3BU.js} +3 -3
  57. package/dist/bundle/{chunk-2FYCJ3KB.js → chunk-TZROQCQ5.js} +18 -4
  58. package/dist/bundle/{chunk-LTZHG4BX.js → chunk-U2EFWFDN.js} +10 -10
  59. package/dist/bundle/{chunk-VZRGIWJM.js → chunk-U64G664E.js} +6 -6
  60. package/dist/bundle/{chunk-HDNMDLWC.js → chunk-UHWQ2YXW.js} +1 -1
  61. package/dist/bundle/{chunk-ADBD5GOY.js → chunk-UK2MMZFW.js} +2 -2
  62. package/dist/bundle/{chunk-QR5HJROX.js → chunk-VICARVCN.js} +1 -1
  63. package/dist/bundle/{chunk-YBBCGTZO.js → chunk-VJJCF52V.js} +655 -403
  64. package/dist/bundle/{chunk-XFT24B7A.js → chunk-VOJU5FVA.js} +179 -159
  65. package/dist/bundle/{chunk-LER7G4XY.js → chunk-VW6BF6M7.js} +1 -1
  66. package/dist/bundle/{chunk-GPBUD6WS.js → chunk-X3KMQW2Z.js} +27 -25
  67. package/dist/bundle/{chunk-5FN27OVR.js → chunk-X7UITQ66.js} +5 -5
  68. package/dist/bundle/{chunk-VOUTO3WF.js → chunk-XR4N2MYB.js} +13 -13
  69. package/dist/bundle/{chunk-2MKPY6NU.js → chunk-YBN7UF2Y.js} +1 -1
  70. package/dist/bundle/{chunk-W2EY5PSH.js → chunk-YO7AUGUT.js} +2 -2
  71. package/dist/bundle/{chunk-HFQZYHLX.js → chunk-YZEIVLAG.js} +4 -4
  72. package/dist/bundle/command-contract-BRZAKY6L.js +32 -0
  73. package/dist/bundle/{decode-E3TI4HEU.js → decode-WW5ZMB5R.js} +5 -5
  74. package/dist/bundle/{dispatch-MLRETSNQ.js → dispatch-HCRXCPCF.js} +8 -8
  75. package/dist/bundle/{echarts-B46XTHOI.js → echarts-ODD3E2RQ.js} +2 -2
  76. package/dist/bundle/{embed-BIUMRFOQ.js → embed-3ETM2WYU.js} +6 -6
  77. package/dist/bundle/{embedder-IA3CG6LB.js → embedder-6YL3WFBR.js} +9 -9
  78. package/dist/bundle/{entry-E3QEAAYL.js → entry-F2UGXKZ3.js} +7 -7
  79. package/dist/bundle/{failure-UJBGB2GP.js → failure-G4DCTWFD.js} +2 -2
  80. package/dist/bundle/failure-X7CYCJWD.js +66 -0
  81. package/dist/bundle/{first-run-6UQRVGZ4.js → first-run-OHQHOP5U.js} +11 -11
  82. package/dist/bundle/first-screen-ULF26GYG.js +30 -0
  83. package/dist/bundle/{instructions-6AISOK6M.js → instructions-RS5VERM7.js} +1 -1
  84. package/dist/bundle/{mcp-YMXA6IH6.js → mcp-M4QN2E7R.js} +2 -2
  85. package/dist/bundle/mcp-TS2UAN5I.js +90 -0
  86. package/dist/bundle/memo.js +16 -16
  87. package/dist/bundle/{node-6GP2V36M.js → node-BU6NHYHF.js} +2 -2
  88. package/dist/bundle/{node-sqlite-2CC5J5RZ.js → node-sqlite-WAF44CWS.js} +6 -6
  89. package/dist/bundle/{oauth-VOOLTPGW.js → oauth-T7RCNIYO.js} +7 -7
  90. package/dist/bundle/{open-AGFSOJG6.js → open-QLX2IVTC.js} +5 -5
  91. package/dist/bundle/{openai-KPRA5NIB.js → openai-O25HCJEY.js} +10 -10
  92. package/dist/bundle/{process-J74KA6F3.js → process-SB2X3TKY.js} +1 -1
  93. package/dist/bundle/{program-VAYJBUPU.js → program-SDLIDODQ.js} +98 -68
  94. package/dist/bundle/{prompt-PDQD5OD5.js → prompt-OHVHUNV4.js} +5 -5
  95. package/dist/bundle/{recognize-QH6FBB2L.js → recognize-SESVG7O3.js} +4 -4
  96. package/dist/bundle/{remote-BREQR2BJ.js → remote-DNGLVDYJ.js} +7 -7
  97. package/dist/bundle/{rerank-HWNJXOHL.js → rerank-SF3OUPEB.js} +7 -7
  98. package/dist/bundle/{serve-A63VR5F4.js → serve-6RK7QFZ2.js} +9 -9
  99. package/dist/bundle/server-JKWE764O.js +61 -0
  100. package/dist/bundle/{server-6UZJQQ4E.js → server-N6PCX7K7.js} +57 -57
  101. package/dist/bundle/server-RKGTOY4D.js +48 -0
  102. package/dist/bundle/{state-GMJJEIPI.js → state-J6WLL4TQ.js} +6 -6
  103. package/dist/bundle/{store-HLK3ZQ7A.js → store-R2PHK3FR.js} +13 -13
  104. package/dist/bundle/store-maintenance-command-LRZ5R3UM.js +48 -0
  105. package/dist/bundle/update-RV2WSULI.js +69 -0
  106. package/dist/contract-overrides/doctor.d.ts.map +1 -1
  107. package/dist/contract-overrides/doctor.js +6 -0
  108. package/dist/contract-overrides/doctor.js.map +1 -1
  109. package/dist/doctor/command.d.ts +25 -2
  110. package/dist/doctor/command.d.ts.map +1 -1
  111. package/dist/doctor/command.js +13 -5
  112. package/dist/doctor/command.js.map +1 -1
  113. package/dist/examples.d.ts.map +1 -1
  114. package/dist/examples.js +2 -0
  115. package/dist/examples.js.map +1 -1
  116. package/dist/store/info-command.d.ts.map +1 -1
  117. package/dist/store/info-command.js +23 -1
  118. package/dist/store/info-command.js.map +1 -1
  119. package/dist/version.d.ts +1 -1
  120. package/dist/version.js +1 -1
  121. package/package.json +4 -4
  122. package/dist/bundle/auto-KD7L4X6G.js +0 -86
  123. package/dist/bundle/command-contract-B6MBG7GI.js +0 -32
  124. package/dist/bundle/failure-UKRO32A7.js +0 -66
  125. package/dist/bundle/first-screen-W3BPVWCT.js +0 -30
  126. package/dist/bundle/mcp-RX3COQPC.js +0 -90
  127. package/dist/bundle/server-3FKLHDFN.js +0 -48
  128. package/dist/bundle/server-XKZXPS7I.js +0 -61
  129. package/dist/bundle/store-maintenance-command-2WOANSCK.js +0 -48
  130. package/dist/bundle/update-GIAB6TXY.js +0 -69
  131. /package/dist/bundle/{chunk-AT5Y62SD.js → chunk-IO44XLFM.js} +0 -0
  132. /package/dist/bundle/{chunk-B6ZCQNF4.js → chunk-VOXIGICJ.js} +0 -0
@@ -3,13 +3,17 @@ const require = __bundleRequire(import.meta.url);
3
3
  import {
4
4
  answerOf,
5
5
  messengerContext
6
- } from "./chunk-RF3R3W2I.js";
6
+ } from "./chunk-EQ237UYC.js";
7
7
  import {
8
8
  FETCHING,
9
+ QUICK_HEALTH_CHECKS,
9
10
  RULES_VERSION,
10
11
  applyTaskRulesOnArrival,
11
12
  capability,
12
13
  chatEventAnswer,
14
+ explainDamage,
15
+ fts5Tables,
16
+ invalidJson,
13
17
  memberAnswer,
14
18
  newSendId,
15
19
  onlineDeps,
@@ -20,11 +24,12 @@ import {
20
24
  senderIsMe,
21
25
  serveRelay,
22
26
  servicesFor,
27
+ storeHealth,
23
28
  syncsOneChat,
24
29
  typedQuery,
25
30
  withQuery,
26
31
  withTimeLimit
27
- } from "./chunk-ZGQSWRCY.js";
32
+ } from "./chunk-QUQJZSRF.js";
28
33
  import {
29
34
  stringWidth,
30
35
  wrapAnsi
@@ -56,30 +61,35 @@ import {
56
61
  snakeKeys,
57
62
  storeTable,
58
63
  withoutProviderRefs
59
- } from "./chunk-XFT24B7A.js";
64
+ } from "./chunk-VOJU5FVA.js";
60
65
  import {
61
66
  failureKey
62
- } from "./chunk-V7QNIJOE.js";
67
+ } from "./chunk-F7S25YVA.js";
63
68
  import {
64
69
  envName
65
- } from "./chunk-UT2K3TAH.js";
70
+ } from "./chunk-DMI3SFLF.js";
66
71
  import {
67
72
  holdLock,
68
73
  lockPath,
69
74
  releaseLock,
70
75
  servingProfiles,
71
76
  takeLock
72
- } from "./chunk-5FBJQHCG.js";
77
+ } from "./chunk-TYOZC3BU.js";
73
78
  import {
74
79
  holdersOf
75
- } from "./chunk-VUSM6XFE.js";
80
+ } from "./chunk-H4726KFZ.js";
76
81
  import {
82
+ CORPORA,
77
83
  MIGRATIONS,
84
+ drainCorpus,
85
+ drainMeetingIndex,
78
86
  drainNoteIndex,
79
87
  dropAllUnusedVectors,
80
88
  fileFacts,
81
89
  fillSearchIndex,
82
90
  fillStems,
91
+ fillTrigrams,
92
+ fillVectorIndexes,
83
93
  formatLocator,
84
94
  involvementStoreOver,
85
95
  migrate,
@@ -90,6 +100,7 @@ import {
90
100
  parseLocator,
91
101
  pendingNormalization,
92
102
  readStoreTables,
103
+ rebuildMentions,
93
104
  resetAttachmentWords,
94
105
  resetNoteIndex,
95
106
  resetSearchIndex,
@@ -102,34 +113,34 @@ import {
102
113
  storeClients,
103
114
  storeContents,
104
115
  vectorIndexCounts
105
- } from "./chunk-YBBCGTZO.js";
116
+ } from "./chunk-VJJCF52V.js";
106
117
  import {
107
118
  queryFieldsOf
108
- } from "./chunk-37D3IHOG.js";
119
+ } from "./chunk-TW643BIA.js";
109
120
  import {
110
121
  readSecret
111
- } from "./chunk-KGVDWSGM.js";
122
+ } from "./chunk-J737T3RM.js";
112
123
  import {
113
124
  checkedOptions,
114
125
  range
115
- } from "./chunk-CV5MM7HG.js";
126
+ } from "./chunk-DHO2JWF7.js";
116
127
  import {
117
128
  messagesFor,
118
129
  systemFor,
119
130
  validateImages
120
- } from "./chunk-WXCRRP4B.js";
131
+ } from "./chunk-NWRITJ7F.js";
121
132
  import {
122
133
  storePath
123
- } from "./chunk-W2EY5PSH.js";
134
+ } from "./chunk-YO7AUGUT.js";
124
135
  import {
125
136
  openCache
126
- } from "./chunk-3ZLDPPI4.js";
137
+ } from "./chunk-5BDWOMH6.js";
127
138
  import {
128
139
  Credentials,
129
140
  pathsAreOverridden,
130
141
  resolvePaths,
131
142
  writeSecurely
132
- } from "./chunk-2R2Z2VWL.js";
143
+ } from "./chunk-O3ZOYXH3.js";
133
144
  import {
134
145
  array,
135
146
  boolean,
@@ -153,12 +164,12 @@ import {
153
164
  transform,
154
165
  trim,
155
166
  union
156
- } from "./chunk-SN63VOE6.js";
167
+ } from "./chunk-EBNNONF5.js";
157
168
  import {
158
169
  CliError,
159
170
  singleLine,
160
171
  visibleControls
161
- } from "./chunk-RZ54DSVU.js";
172
+ } from "./chunk-BXTDAGM4.js";
162
173
  import {
163
174
  __commonJS,
164
175
  __name,
@@ -1812,7 +1823,7 @@ var require_liquid_node = __commonJS({
1812
1823
  return readFileAsync(filepath, "utf8");
1813
1824
  }
1814
1825
  __name(readFile, "readFile");
1815
- function existsSync8(filepath) {
1826
+ function existsSync10(filepath) {
1816
1827
  try {
1817
1828
  fs$1.statSync(filepath);
1818
1829
  return true;
@@ -1820,11 +1831,11 @@ var require_liquid_node = __commonJS({
1820
1831
  return false;
1821
1832
  }
1822
1833
  }
1823
- __name(existsSync8, "existsSync");
1824
- function readFileSync4(filepath) {
1834
+ __name(existsSync10, "existsSync");
1835
+ function readFileSync5(filepath) {
1825
1836
  return fs$1.readFileSync(filepath, "utf8");
1826
1837
  }
1827
- __name(readFileSync4, "readFileSync");
1838
+ __name(readFileSync5, "readFileSync");
1828
1839
  function resolve2(root, file2, ext) {
1829
1840
  if (!path.extname(file2))
1830
1841
  file2 += ext;
@@ -1838,10 +1849,10 @@ var require_liquid_node = __commonJS({
1838
1849
  }
1839
1850
  }
1840
1851
  __name(fallback, "fallback");
1841
- function dirname2(filepath) {
1852
+ function dirname3(filepath) {
1842
1853
  return path.dirname(filepath);
1843
1854
  }
1844
- __name(dirname2, "dirname");
1855
+ __name(dirname3, "dirname");
1845
1856
  var realpathAsync = promisify(fs$1.realpath);
1846
1857
  async function contains(root, file2) {
1847
1858
  try {
@@ -1869,11 +1880,11 @@ var require_liquid_node = __commonJS({
1869
1880
  __proto__: null,
1870
1881
  exists,
1871
1882
  readFile,
1872
- existsSync: existsSync8,
1873
- readFileSync: readFileSync4,
1883
+ existsSync: existsSync10,
1884
+ readFileSync: readFileSync5,
1874
1885
  resolve: resolve2,
1875
1886
  fallback,
1876
- dirname: dirname2,
1887
+ dirname: dirname3,
1877
1888
  contains,
1878
1889
  containsSync,
1879
1890
  sep: path.sep
@@ -3598,7 +3609,7 @@ var require_liquid_node = __commonJS({
3598
3609
  uri_escape,
3599
3610
  slugify
3600
3611
  });
3601
- var join4 = argumentsToValue(function(v, arg) {
3612
+ var join5 = argumentsToValue(function(v, arg) {
3602
3613
  const array2 = toArray(v);
3603
3614
  const sep = isNil(arg) ? " " : stringify(arg);
3604
3615
  let outputSize = sep.length * Math.max(array2.length - 1, 0);
@@ -3874,7 +3885,7 @@ var require_liquid_node = __commonJS({
3874
3885
  __name(sample, "sample");
3875
3886
  var arrayFilters = /* @__PURE__ */ Object.freeze({
3876
3887
  __proto__: null,
3877
- join: join4,
3888
+ join: join5,
3878
3889
  last,
3879
3890
  first,
3880
3891
  reverse,
@@ -5498,11 +5509,11 @@ var require_liquid_node = __commonJS({
5498
5509
  }
5499
5510
  });
5500
5511
 
5501
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
5502
- import { chmodSync, constants, copyFileSync, existsSync as existsSync7, mkdirSync, realpathSync, renameSync as renameSync2, rmSync as rmSync2, statfsSync, statSync as statSync3, writeFileSync } from "node:fs";
5503
- import { dirname, resolve } from "node:path";
5512
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/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";
5504
5515
 
5505
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/sealed.js
5516
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/sealed.js
5506
5517
  import { createCipheriv, createDecipheriv, createHash, randomBytes, scrypt, timingSafeEqual } from "node:crypto";
5507
5518
  import { closeSync, createReadStream, createWriteStream, existsSync, openSync, readSync, renameSync, rmSync, statSync } from "node:fs";
5508
5519
  import { Transform } from "node:stream";
@@ -5609,7 +5620,7 @@ var unsealFile = /* @__PURE__ */ __name(async (from, to, password) => {
5609
5620
  renameSync(pending, to);
5610
5621
  }, "unsealFile");
5611
5622
 
5612
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/store/compatibility.js
5623
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/store/compatibility.js
5613
5624
  var SPEAKS = MIGRATIONS.at(-1)?.version ?? 0;
5614
5625
  var fileSchemaOf = /* @__PURE__ */ __name((database) => {
5615
5626
  const tracked = database.prepare("SELECT 1 FROM sqlite_master WHERE name = 'schema_migrations'").get();
@@ -5633,7 +5644,7 @@ var compatibilityOf = /* @__PURE__ */ __name((file2, migrations = MIGRATIONS) =>
5633
5644
  };
5634
5645
  }, "compatibilityOf");
5635
5646
 
5636
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/store/repair.js
5647
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/store/repair.js
5637
5648
  import { createHash as createHash2 } from "node:crypto";
5638
5649
  var COPY_MARK = "__repair_";
5639
5650
  var COPY_NAME = /__repair_[0-9a-f]{8}(_\d+)?$/;
@@ -5887,10 +5898,528 @@ var deleteCopy = /* @__PURE__ */ __name((database, name) => {
5887
5898
  return found;
5888
5899
  }, "deleteCopy");
5889
5900
 
5890
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/store-info.js
5891
- import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
5901
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/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.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/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.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/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 RECOVER_LOCK = ".recover-lock";
5915
+ var INSERTED = /^INSERT OR IGNORE INTO '([^']+)'/;
5916
+ var LOST_AND_FOUND = "recover_lost_and_found";
5917
+ var recovers = /* @__PURE__ */ __name((program) => {
5918
+ try {
5919
+ execFileSync(program, [":memory:", ".recover"], { stdio: ["ignore", "ignore", "pipe"] });
5920
+ return true;
5921
+ } catch {
5922
+ return false;
5923
+ }
5924
+ }, "recovers");
5925
+ var sqlite3Program = /* @__PURE__ */ __name((program = "sqlite3") => {
5926
+ let version = null;
5927
+ try {
5928
+ version = execFileSync(program, ["--version"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).split(" ")[0] ?? null;
5929
+ } catch {
5930
+ return { program, version: null, usable: false };
5931
+ }
5932
+ const parts2 = (version ?? "").split(".").map(Number);
5933
+ const at = SQLITE3_MINIMUM.findIndex((wanted, i) => (parts2[i] ?? 0) !== wanted);
5934
+ const recent = at === -1 || (parts2[at] ?? 0) > (SQLITE3_MINIMUM[at] ?? 0);
5935
+ return { program, version, usable: recent && recovers(program) };
5936
+ }, "sqlite3Program");
5937
+ var activeTimers = /* @__PURE__ */ __name(() => {
5938
+ if (process.platform !== "linux")
5939
+ return void 0;
5940
+ try {
5941
+ return execFileSync("systemctl", ["--user", "list-timers", "--plain", "--no-legend"], {
5942
+ encoding: "utf8",
5943
+ stdio: ["ignore", "pipe", "ignore"]
5944
+ }).split("\n").map((line) => line.trim().split(/\s+/).at(-2) ?? "").filter((unit) => /^(memo|mail|tg|max|whatsapp|zoom|drive|gcal|wirecat)-.*\.timer$/.test(unit));
5945
+ } catch {
5946
+ return void 0;
5947
+ }
5948
+ }, "activeTimers");
5949
+ var alive = /* @__PURE__ */ __name((pid) => {
5950
+ try {
5951
+ process.kill(pid, 0);
5952
+ return true;
5953
+ } catch (error) {
5954
+ return error.code === "EPERM";
5955
+ }
5956
+ }, "alive");
5957
+ var runningRecovery = /* @__PURE__ */ __name((path) => {
5958
+ let pid;
5959
+ try {
5960
+ pid = Number(readFileSync(`${path}${RECOVER_LOCK}`, "utf8").trim());
5961
+ } catch {
5962
+ return null;
5963
+ }
5964
+ return Number.isInteger(pid) && pid > 0 && alive(pid) ? pid : null;
5965
+ }, "runningRecovery");
5966
+ var takeRecoverLock = /* @__PURE__ */ __name((path) => {
5967
+ const lock = `${path}${RECOVER_LOCK}`;
5968
+ const take = /* @__PURE__ */ __name(() => writeFileSync(lock, String(process.pid), { flag: "wx", mode: 384 }), "take");
5969
+ try {
5970
+ take();
5971
+ } catch (error) {
5972
+ if (error.code !== "EEXIST")
5973
+ throw error;
5974
+ const pid = runningRecovery(path);
5975
+ if (pid === null) {
5976
+ rmSync2(lock, { force: true });
5977
+ take();
5978
+ } else {
5979
+ throw new CliError("validation_error", `the store is being recovered by process ${pid} \u2014 wait for it to finish`, {
5980
+ reason: "store.recovering"
5981
+ });
5982
+ }
5983
+ }
5984
+ return () => rmSync2(lock, { force: true });
5985
+ }, "takeRecoverLock");
5986
+ var storeHolders = /* @__PURE__ */ __name((path) => {
5987
+ const folder = realpathSync(dirname(path));
5988
+ const files = STORE_PARTS.map((suffix) => join(folder, `${basename(path)}${suffix}`));
5989
+ const wanted = process.platform === "linux" ? files.flatMap((file2) => [file2, `${file2} (deleted)`]) : files.filter(existsSync2);
5990
+ const recovering = runningRecovery(path);
5991
+ const pids = holdersOf(wanted);
5992
+ if (pids === void 0 && recovering === null)
5993
+ return void 0;
5994
+ const all = [
5995
+ .../* @__PURE__ */ new Set([...pids ?? [], ...recovering !== null && recovering !== process.pid ? [recovering] : []])
5996
+ ];
5997
+ return all.map((pid) => {
5998
+ let name = "?";
5999
+ try {
6000
+ name = readFileSync(`/proc/${pid}/comm`, "utf8").trim();
6001
+ } catch {
6002
+ }
6003
+ return { pid, name };
6004
+ });
6005
+ }, "storeHolders");
6006
+ var tableRows = /* @__PURE__ */ __name((database) => {
6007
+ const indexes = fts5Tables(database).map((index) => index.name);
6008
+ 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}_`)));
6009
+ return Object.fromEntries(tables.map((table) => {
6010
+ try {
6011
+ return [table, Number(database.prepare(`SELECT count(*) AS n FROM "${table}"`).get()?.n)];
6012
+ } catch {
6013
+ return [table, null];
6014
+ }
6015
+ }));
6016
+ }, "tableRows");
6017
+ var copyReadableRows = /* @__PURE__ */ __name((path, target, program = "sqlite3") => new Promise((resolve2, reject) => {
6018
+ const reader = spawn(program, ["-readonly", path, `.recover --ignore-freelist --lost-and-found ${LOST_AND_FOUND}`], {
6019
+ stdio: ["ignore", "pipe", "pipe"]
6020
+ });
6021
+ const writer = spawn(program, ["-cmd", ".dbconfig defensive off", target], { stdio: ["pipe", "ignore", "pipe"] });
6022
+ const errors = [];
6023
+ const collect = /* @__PURE__ */ __name((chunk) => {
6024
+ for (const line of chunk.toString("utf8").split("\n"))
6025
+ if (line && errors.length < 50)
6026
+ errors.push(line.slice(0, 300));
6027
+ }, "collect");
6028
+ reader.stderr.on("data", collect);
6029
+ writer.stderr.on("data", collect);
6030
+ const read = {};
6031
+ let rest = "";
6032
+ const counter = new Transform2({
6033
+ transform(chunk, _encoding, done) {
6034
+ const lines = (rest + chunk.toString("latin1")).split("\n");
6035
+ rest = lines.pop() ?? "";
6036
+ for (const line of lines) {
6037
+ const table = INSERTED.exec(line)?.[1];
6038
+ if (table)
6039
+ read[table] = (read[table] ?? 0) + 1;
6040
+ }
6041
+ done(null, chunk);
6042
+ }
6043
+ });
6044
+ reader.stdout.pipe(counter).pipe(writer.stdin);
6045
+ let exits = 0;
6046
+ let readerCode = null;
6047
+ const exited = /* @__PURE__ */ __name(() => {
6048
+ exits += 1;
6049
+ if (exits < 2)
6050
+ return;
6051
+ if (readerCode !== 0)
6052
+ reject(new CliError("validation_error", `sqlite3 could not read the store: ${errors.join("; ")}`));
6053
+ else
6054
+ resolve2({ errors, read });
6055
+ }, "exited");
6056
+ reader.on("error", reject);
6057
+ writer.on("error", reject);
6058
+ reader.on("close", (code) => {
6059
+ readerCode = code;
6060
+ exited();
6061
+ });
6062
+ writer.on("close", exited);
6063
+ }), "copyReadableRows");
6064
+ var FILLERS = {
6065
+ message_words: /* @__PURE__ */ __name((database, now) => {
6066
+ resetSearchIndex(database);
6067
+ fillSearchIndex(database, { now });
6068
+ }, "message_words"),
6069
+ message_stems: /* @__PURE__ */ __name((database, now) => {
6070
+ resetStems(database, { force: true, now });
6071
+ fillStems(database, { now });
6072
+ }, "message_stems"),
6073
+ attachment_words: /* @__PURE__ */ __name((database) => void resetAttachmentWords(database), "attachment_words"),
6074
+ attachment_name_words: /* @__PURE__ */ __name((database) => (
6075
+ // As migration 20 filled it: й and ё fold as the triggers fold them.
6076
+ 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")
6077
+ ), "attachment_name_words"),
6078
+ meeting_words: /* @__PURE__ */ __name((database) => {
6079
+ 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");
6080
+ drainMeetingIndex(database);
6081
+ }, "meeting_words"),
6082
+ // Built per account by the first search that needs them.
6083
+ 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")
6084
+ };
6085
+ var CORPUS_TABLES = new Set(Object.values(CORPORA).flatMap((corpus) => [`${corpus.type}_words`, `${corpus.type}_stems`]));
6086
+ var TRIGRAMS = ["note_trigrams", "document_trigrams"];
6087
+ var rebuildDerived = /* @__PURE__ */ __name((database, { now = Date.now, note = /* @__PURE__ */ __name(() => {
6088
+ }, "note") } = {}) => {
6089
+ const lost = database.prepare("SELECT 1 FROM sqlite_master WHERE name = ?").get(LOST_AND_FOUND);
6090
+ const lostAndFound = lost ? Number(database.prepare(`SELECT count(*) AS n FROM ${LOST_AND_FOUND}`).get()?.n) : 0;
6091
+ if (lost)
6092
+ database.exec(`DROP TABLE ${LOST_AND_FOUND}`);
6093
+ const indexes = fts5Tables(database);
6094
+ for (const { name, sql } of indexes) {
6095
+ database.exec(`DROP TABLE "${name}"`);
6096
+ database.exec(sql);
6097
+ }
6098
+ 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));
6099
+ for (const table of vectors) {
6100
+ database.exec(`DROP TRIGGER IF EXISTS "${table}_redo"`);
6101
+ database.exec(`DROP TABLE "${table}"`);
6102
+ database.prepare("DELETE FROM vector_indexes WHERE id = ?").run(Number(table.replace("vector_index_", "")));
6103
+ }
6104
+ const unfilled = [];
6105
+ const stemmerFor = stemmerCache();
6106
+ for (const { name, external } of indexes) {
6107
+ note(`rebuilding ${name}`);
6108
+ if (external)
6109
+ database.exec(`INSERT INTO "${name}" ("${name}") VALUES ('rebuild')`);
6110
+ else if (FILLERS[name])
6111
+ FILLERS[name](database, now);
6112
+ else if (!CORPUS_TABLES.has(name) && !TRIGRAMS.includes(name))
6113
+ unfilled.push(name);
6114
+ }
6115
+ note("rebuilding the words of notes, documents, memories, mail, tasks, transcripts and events");
6116
+ resetNoteIndex(database);
6117
+ for (const corpus of Object.values(CORPORA))
6118
+ drainCorpus(database, corpus, stemmerFor);
6119
+ for (const name of TRIGRAMS) {
6120
+ const type = name.replace("_trigrams", "");
6121
+ database.prepare(`UPDATE search_index_state SET filled_through = 0, watermark = (SELECT coalesce(max(id), 0) FROM ${type}s) WHERE name = ?`).run(name);
6122
+ }
6123
+ fillTrigrams(database);
6124
+ note("finding mentions again");
6125
+ const mentions = rebuildMentions(database, { now: now() }).mentions;
6126
+ involvementStoreOver({ database, now }).rebuild();
6127
+ note("indexing the stored vectors");
6128
+ const vectorModels = fillVectorIndexes(database);
6129
+ 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)");
6130
+ 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)]));
6131
+ return {
6132
+ lostAndFound,
6133
+ searchIndexes: indexes.map((index) => index.name),
6134
+ unfilled,
6135
+ mentions,
6136
+ vectorModels,
6137
+ chunksWithoutVector
6138
+ };
6139
+ }, "rebuildDerived");
6140
+ 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) => {
6141
+ const child = String(group.child);
6142
+ 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;
6143
+ let missing = [];
6144
+ try {
6145
+ 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));
6146
+ } catch {
6147
+ }
6148
+ return { table: child, parent: String(group.parent), rows: Number(group.n), missing };
6149
+ }), "danglingRows");
6150
+ var mailToFetch = /* @__PURE__ */ __name((database) => {
6151
+ try {
6152
+ return database.prepare(`SELECT a.external_id AS account, count(DISTINCT l.email_id) AS n FROM email_locations l
6153
+ JOIN mailboxes b ON b.id = l.mailbox_id JOIN accounts a ON a.id = b.account_id
6154
+ 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) }));
6155
+ } catch {
6156
+ return [];
6157
+ }
6158
+ }, "mailToFetch");
6159
+ var clearInvalidJson = /* @__PURE__ */ __name((database) => {
6160
+ const found = invalidJson(database);
6161
+ for (const { table, column, required } of found) {
6162
+ const invalid = `"${column}" IS NOT NULL AND NOT json_valid("${column}")`;
6163
+ database.exec(required ? `DELETE FROM "${table}" WHERE ${invalid}` : `UPDATE "${table}" SET "${column}" = NULL WHERE ${invalid}`);
6164
+ }
6165
+ return found;
6166
+ }, "clearInvalidJson");
6167
+ var refuseInUse = /* @__PURE__ */ __name((path) => {
6168
+ const holders = storeHolders(path);
6169
+ if (holders && holders.length > 0) {
6170
+ const timers = activeTimers() ?? [];
6171
+ 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" });
6172
+ }
6173
+ }, "refuseInUse");
6174
+ var recoverStore = /* @__PURE__ */ __name(async ({ path, command, version, sqlite3 = "sqlite3", now = Date.now, note = /* @__PURE__ */ __name(() => {
6175
+ }, "note"), copy }) => {
6176
+ const started = Date.now();
6177
+ if (!existsSync2(path))
6178
+ throw new CliError("not_found", `no store at ${path}`);
6179
+ const program = copy ? { program: sqlite3, version: "given", usable: true } : sqlite3Program(sqlite3);
6180
+ if (!program.usable) {
6181
+ 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" });
6182
+ }
6183
+ const releaseLock2 = takeRecoverLock(path);
6184
+ try {
6185
+ refuseInUse(path);
6186
+ const bytes = STORE_PARTS.reduce((sum, suffix) => sum + (statSync2(`${path}${suffix}`, { throwIfNoEntry: false })?.size ?? 0), 0);
6187
+ const { bavail, bsize } = statfsSync(dirname(path));
6188
+ if (Number(bavail) * Number(bsize) < bytes * 1.2)
6189
+ throw new CliError("validation_error", `the recovery needs about ${Math.ceil(bytes * 1.2 / 1e9)} GB free beside the store`);
6190
+ return await recoverLocked({ path, command, version, sqlite3, now, note, copy, started, program });
6191
+ } finally {
6192
+ releaseLock2();
6193
+ }
6194
+ }, "recoverStore");
6195
+ var recoverLocked = /* @__PURE__ */ __name(async ({ path, command, version, sqlite3, now, note, copy, started, program }) => {
6196
+ const watch = (await openSqlite(path, { readOnly: true })).database;
6197
+ let watching = true;
6198
+ const stopWatching = /* @__PURE__ */ __name(() => {
6199
+ if (watching)
6200
+ watch.close();
6201
+ watching = false;
6202
+ }, "stopWatching");
6203
+ try {
6204
+ const dataVersion = /* @__PURE__ */ __name(() => Number(watch.prepare("PRAGMA data_version").get()?.data_version), "dataVersion");
6205
+ const rowsBefore = tableRows(watch);
6206
+ const before = { data: dataVersion(), inode: statSync2(path).ino };
6207
+ const stamp = new Date(now()).toISOString().replace(/[:.]/g, "-");
6208
+ const target = `${path}.recovering-${stamp}`;
6209
+ writeFileSync(target, "", { flag: "wx", mode: 384 });
6210
+ const dropTarget = /* @__PURE__ */ __name(() => {
6211
+ for (const suffix of [...STORE_PARTS, "-journal"])
6212
+ rmSync2(`${target}${suffix}`, { force: true });
6213
+ }, "dropTarget");
6214
+ note(`copying the readable rows into ${target}`);
6215
+ let copied;
6216
+ let copyErrors;
6217
+ let read;
6218
+ let opened;
6219
+ try {
6220
+ ;
6221
+ ({ errors: copyErrors, read } = await (copy ?? ((from, to) => copyReadableRows(from, to, sqlite3)))(path, target));
6222
+ copied = Date.now();
6223
+ opened = await openSqlite(target);
6224
+ } catch (error) {
6225
+ dropTarget();
6226
+ throw error;
6227
+ }
6228
+ let rebuilt;
6229
+ let kept;
6230
+ let dangling;
6231
+ let json;
6232
+ let fetch2;
6233
+ try {
6234
+ kept = tableRows(opened.database);
6235
+ migrate(opened.database, { command, ...version ? { version } : {} });
6236
+ note("clearing values that are not valid JSON");
6237
+ json = clearInvalidJson(opened.database);
6238
+ rebuilt = rebuildDerived(opened.database, { now, note });
6239
+ note("looking for rows that point at rows that were lost");
6240
+ dangling = danglingRows(opened.database);
6241
+ fetch2 = mailToFetch(opened.database);
6242
+ opened.database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
6243
+ } catch (error) {
6244
+ opened.database.close();
6245
+ dropTarget();
6246
+ throw error;
6247
+ }
6248
+ opened.database.close();
6249
+ const rebuiltAt = Date.now();
6250
+ note("checking the recovered file");
6251
+ const health = await storeHealth(target, { deep: true });
6252
+ const checkedAt = Date.now();
6253
+ if (!health.ok) {
6254
+ 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" });
6255
+ }
6256
+ refuseInUse(path);
6257
+ const changed = dataVersion() !== before.data || statSync2(path, { throwIfNoEntry: false })?.ino !== before.inode;
6258
+ stopWatching();
6259
+ if (changed) {
6260
+ 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" });
6261
+ }
6262
+ const keptAt = `${path}.before-recover-${stamp}`;
6263
+ for (const suffix of STORE_PARTS)
6264
+ if (existsSync2(`${path}${suffix}`))
6265
+ renameSync2(`${path}${suffix}`, `${keptAt}${suffix}`);
6266
+ for (const suffix of STORE_PARTS)
6267
+ if (existsSync2(`${target}${suffix}`))
6268
+ renameSync2(`${target}${suffix}`, `${path}${suffix}`);
6269
+ 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);
6270
+ const seconds = /* @__PURE__ */ __name((from, to) => Math.round((to - from) / 100) / 10, "seconds");
6271
+ return {
6272
+ path,
6273
+ keptAt,
6274
+ sqlite3: program.version,
6275
+ lost,
6276
+ dangling,
6277
+ invalidJson: json,
6278
+ mailToFetch: fetch2,
6279
+ rebuilt,
6280
+ copyErrors,
6281
+ health,
6282
+ seconds: {
6283
+ copy: seconds(started, copied),
6284
+ rebuild: seconds(copied, rebuiltAt),
6285
+ check: seconds(rebuiltAt, checkedAt),
6286
+ total: seconds(started, Date.now())
6287
+ }
6288
+ };
6289
+ } finally {
6290
+ stopWatching();
6291
+ }
6292
+ }, "recoverLocked");
6293
+
6294
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/store-recover.js
6295
+ var COUNTED = [
6296
+ "accounts",
6297
+ "chats",
6298
+ "messages",
6299
+ "attachments",
6300
+ "emails",
6301
+ "documents",
6302
+ "notes",
6303
+ "meetings",
6304
+ "chunks",
6305
+ "embeddings",
6306
+ "mentions"
6307
+ ];
6308
+ var stopTimers = /* @__PURE__ */ __name((timers) => `systemctl --user stop ${timers.join(" ")}`, "stopTimers");
6309
+ var storeRecoveryCheck = /* @__PURE__ */ __name(async (env, command) => {
6310
+ const path = storePath(env);
6311
+ if (!existsSync3(path))
6312
+ return { path, exists: false, ok: true, next: [] };
6313
+ const health = await storeHealth(path, { deep: true });
6314
+ let rows = {};
6315
+ try {
6316
+ const { database } = await openSqlite(path, { readOnly: true });
6317
+ try {
6318
+ const all = tableRows(database);
6319
+ rows = Object.fromEntries(COUNTED.filter((table) => table in all).map((table) => [table, all[table] ?? null]));
6320
+ } finally {
6321
+ database.close();
6322
+ }
6323
+ } catch {
6324
+ }
6325
+ const explanation = explainDamage(health, command);
6326
+ const inUse = storeHolders(path) ?? null;
6327
+ const timers = activeTimers() ?? null;
6328
+ const sqlite3 = sqlite3Program();
6329
+ const next = health.ok ? [] : [
6330
+ ...timers?.length ? [stopTimers(timers)] : [],
6331
+ ...(inUse ?? []).map(({ pid, name }) => `stop ${name} (process ${pid}): it has the store open`),
6332
+ ...sqlite3.usable ? [] : ["install sqlite3 3.43 or newer (apt install sqlite3, brew install sqlite)"],
6333
+ `${command} store recover run`
6334
+ ];
6335
+ return {
6336
+ path,
6337
+ exists: true,
6338
+ ok: health.ok,
6339
+ seconds: Math.round(health.ms / 100) / 10,
6340
+ problems: health.problems ?? 0,
6341
+ damagedTables: health.damagedTables ?? [],
6342
+ damagedSearchIndexes: (health.searchIndexes ?? []).filter((index) => !index.ok).map(({ name, error }) => ({ name, ...error ? { error } : {} })),
6343
+ invalidJson: health.invalidJson ?? [],
6344
+ rows,
6345
+ explanation,
6346
+ inUse,
6347
+ timers,
6348
+ sqlite3: { version: sqlite3.version, usable: sqlite3.usable },
6349
+ next
6350
+ };
6351
+ }, "storeRecoveryCheck");
6352
+ var storeRecoveryRun = /* @__PURE__ */ __name(async (env, { command, version, note, timers: scheduled = activeTimers, copy }) => {
6353
+ const timers = scheduled() ?? [];
6354
+ if (timers.length > 0)
6355
+ throw new CliError("validation_error", `stop the timers first, they open the store: ${stopTimers(timers)}`, {
6356
+ reason: "store.in-use"
6357
+ });
6358
+ const recovery = await recoverStore({
6359
+ path: storePath(env),
6360
+ command,
6361
+ ...version ? { version } : {},
6362
+ ...note ? { note } : {},
6363
+ ...copy ? { copy } : {}
6364
+ });
6365
+ const mail = recovery.mailToFetch.map(({ account, emails }) => `mail <profile of ${account}> sync --rescan # ${emails} emails`);
6366
+ const lostMail = recovery.lost.some(({ table }) => table === "emails") && mail.length === 0 ? ["mail <profile> sync --rescan # each mail profile"] : [];
6367
+ const { health, copyErrors, ...kept } = recovery;
6368
+ return {
6369
+ ...kept,
6370
+ copyErrors: copyErrors.length,
6371
+ checkedOk: health.ok,
6372
+ next: [...mail, ...lostMail, "systemctl --user start <the timers stopped before>"]
6373
+ };
6374
+ }, "storeRecoveryRun");
6375
+ var recoveryNotes = /* @__PURE__ */ __name((answer) => {
6376
+ if ("keptAt" in answer) {
6377
+ const lost = answer.lost.map(({ table, before, read, kept }) => `${table}: ${kept} kept of ${before ?? "an uncountable number"}${read > kept ? `, ${read - kept} read but unusable` : ""}`);
6378
+ return [
6379
+ `recovered in ${answer.seconds.total} s; the damaged file is kept at ${answer.keptAt}`,
6380
+ ...lost.length ? lost : ["no table lost a row"],
6381
+ ...answer.dangling.map(({ table, parent, rows }) => `${rows} rows of ${table} point at ${parent} rows the store does not hold`),
6382
+ ...answer.invalidJson.map(({ table, column, rows, required }) => `${table}.${column}: ${rows} values were not valid JSON \u2014 ${required ? "those rows were dropped" : "set to empty"}`),
6383
+ ...answer.next.map((line) => `next: ${line}`)
6384
+ ];
6385
+ }
6386
+ if (!answer.exists)
6387
+ return ["no store yet"];
6388
+ if (answer.ok)
6389
+ return [`the store is healthy (checked every page and search index in ${answer.seconds} s)`];
6390
+ const why = answer.explanation;
6391
+ return [
6392
+ ...why ? [why.what, ...why.impact, why.externalUnaffected] : [],
6393
+ ...answer.next.map((line) => `next: ${line}`)
6394
+ ];
6395
+ }, "recoveryNotes");
6396
+ var storeRecoverCommand = /* @__PURE__ */ __name(({ command, version }) => {
6397
+ 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() {
6398
+ const output = outputFor(this);
6399
+ const answer = await storeRecoveryCheck(environmentOf(this).env ?? process.env, command);
6400
+ renderAnswer(this, output, itemOf(snakeKeys(answer)));
6401
+ if (output.format === "pretty")
6402
+ for (const line of recoveryNotes(answer))
6403
+ output.renderer.note(line);
6404
+ });
6405
+ 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() {
6406
+ const output = outputFor(this);
6407
+ const answer = await storeRecoveryRun(environmentOf(this).env ?? process.env, {
6408
+ command,
6409
+ ...version ? { version } : {},
6410
+ note: /* @__PURE__ */ __name((text) => output.renderer.note(text), "note")
6411
+ });
6412
+ renderAnswer(this, output, itemOf(snakeKeys(answer)));
6413
+ if (output.format === "pretty")
6414
+ for (const line of recoveryNotes(answer))
6415
+ output.renderer.note(line);
6416
+ }));
6417
+ return recover;
6418
+ }, "storeRecoverCommand");
6419
+
6420
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/store-info.js
5892
6421
  var pendingIfKnown = /* @__PURE__ */ __name((database) => database.prepare("SELECT 1 FROM pragma_table_info('messages') WHERE name = 'normalized_text'").get() ? pendingNormalization(database) : null, "pendingIfKnown");
5893
- var bytesOf = /* @__PURE__ */ __name((path) => existsSync2(path) ? statSync2(path).size : 0, "bytesOf");
6422
+ var bytesOf = /* @__PURE__ */ __name((path) => existsSync4(path) ? statSync3(path).size : 0, "bytesOf");
5894
6423
  var messageOf = /* @__PURE__ */ __name((error) => error instanceof Error ? error.message : String(error), "messageOf");
5895
6424
  var contentsOf = /* @__PURE__ */ __name((database, version, writable) => version > 0 && writable ? {
5896
6425
  rows: rowCounts(database),
@@ -5901,7 +6430,7 @@ var contentsOf = /* @__PURE__ */ __name((database, version, writable) => version
5901
6430
  } : { rows: {}, pendingNormalization: null, wordIndex: null, stemIndex: null }, "contentsOf");
5902
6431
  var storeInfo = /* @__PURE__ */ __name(async (env) => {
5903
6432
  const path = storePath(env);
5904
- if (!existsSync2(path))
6433
+ if (!existsSync4(path))
5905
6434
  return snakeKeys({ path, exists: false, schema: compatibilityOf(void 0) });
5906
6435
  let schema = compatibilityOf(void 0);
5907
6436
  try {
@@ -5934,7 +6463,7 @@ var storeInfoCommand = /* @__PURE__ */ __name(() => annotate(new Command("info")
5934
6463
  renderAnswer(this, outputFor(this), itemOf(answer));
5935
6464
  }), "storeInfoCommand");
5936
6465
 
5937
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/password.js
6466
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/password.js
5938
6467
  var ENCRYPT_OPTION = [
5939
6468
  "--encrypt",
5940
6469
  "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"
@@ -5953,9 +6482,9 @@ var passwordOf = /* @__PURE__ */ __name(async (command, { twice }) => {
5953
6482
  return password;
5954
6483
  }, "passwordOf");
5955
6484
 
5956
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/rules.js
5957
- import { existsSync as existsSync3, readFileSync } from "node:fs";
5958
- import { join } from "node:path";
6485
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/rules.js
6486
+ import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
6487
+ import { join as join2 } from "node:path";
5959
6488
  var REPLY_ACTIONS = ["reply", "task"];
5960
6489
  var REPLY_MODELS = ["fill-only", "may-reword"];
5961
6490
  var REPLY_KINDS = ["dialog", "group"];
@@ -6041,7 +6570,7 @@ var defaultRule = /* @__PURE__ */ __name((id) => ({
6041
6570
  reply: { template: "", asReply: true },
6042
6571
  limits: { perChat: "1/1d", perPerson: "1/1d" }
6043
6572
  }), "defaultRule");
6044
- var repliesPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies.json`), "repliesPathFor");
6573
+ var repliesPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join2(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies.json`), "repliesPathFor");
6045
6574
  var EVERYONE = { reply: "all", allow: { people: [], chats: [] }, deny: { people: [], chats: [] } };
6046
6575
  var outsideAudience = /* @__PURE__ */ __name((audience, person, chat) => {
6047
6576
  if (person !== null && audience.deny.people.includes(person))
@@ -6071,11 +6600,11 @@ var readReplies = /* @__PURE__ */ __name((path, provider) => {
6071
6600
  return parseReplies(readRepliesFile(path, provider), path, provider);
6072
6601
  }, "readReplies");
6073
6602
  var readRepliesFile = /* @__PURE__ */ __name((path, provider) => {
6074
- if (!existsSync3(path))
6603
+ if (!existsSync5(path))
6075
6604
  return { audience: structuredClone(EVERYONE), rules: [] };
6076
6605
  let parsed;
6077
6606
  try {
6078
- parsed = JSON.parse(readFileSync(path, "utf8"));
6607
+ parsed = JSON.parse(readFileSync2(path, "utf8"));
6079
6608
  } catch (error) {
6080
6609
  throw broken(path, error instanceof Error ? error.message : String(error));
6081
6610
  }
@@ -6124,9 +6653,9 @@ var problem = /* @__PURE__ */ __name((issue) => {
6124
6653
  }, "problem");
6125
6654
  var broken = /* @__PURE__ */ __name((path, why) => new CliError("configuration_error", `the reply rules ${path} cannot be read (${why}) \u2014 fix the file`), "broken");
6126
6655
 
6127
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/state.js
6128
- import { existsSync as existsSync4, readFileSync as readFileSync2 } from "node:fs";
6129
- import { join as join2 } from "node:path";
6656
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/state.js
6657
+ import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
6658
+ import { join as join3 } from "node:path";
6130
6659
  var ANSWERED_KEPT = 1e3;
6131
6660
  var times = record(string(), array(string()));
6132
6661
  var stateFile = object({
@@ -6138,13 +6667,13 @@ var stateFile = object({
6138
6667
  });
6139
6668
  var emptyState = /* @__PURE__ */ __name(() => ({ paused: false, answered: [], sent: {} }), "emptyState");
6140
6669
  var answeredKey = /* @__PURE__ */ __name((message) => `${message.chatId}:${message.id}`, "answeredKey");
6141
- var repliesStatePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join2(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, `${profile}.replies-state.json`), "repliesStatePathFor");
6670
+ var repliesStatePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join3(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, `${profile}.replies-state.json`), "repliesStatePathFor");
6142
6671
  var readRepliesState = /* @__PURE__ */ __name((path) => {
6143
- if (!existsSync4(path))
6672
+ if (!existsSync6(path))
6144
6673
  return emptyState();
6145
6674
  let parsed;
6146
6675
  try {
6147
- parsed = JSON.parse(readFileSync2(path, "utf8"));
6676
+ parsed = JSON.parse(readFileSync3(path, "utf8"));
6148
6677
  } catch (error) {
6149
6678
  throw broken2(path, error instanceof Error ? error.message : String(error));
6150
6679
  }
@@ -6177,7 +6706,7 @@ var recordReply = /* @__PURE__ */ __name((state, rule2, message, now) => {
6177
6706
  }, "recordReply");
6178
6707
  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");
6179
6708
 
6180
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/decide.js
6709
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/decide.js
6181
6710
  var skip = /* @__PURE__ */ __name((why) => ({ skip: why }), "skip");
6182
6711
  var decide = /* @__PURE__ */ __name((rule2, incoming, state, now) => {
6183
6712
  const { message, chat, owner, sender } = incoming;
@@ -6283,7 +6812,7 @@ var filled = /* @__PURE__ */ __name((template2, senderName) => {
6283
6812
  return template2.replaceAll("{firstName}", name.split(/\s+/)[0] ?? name).replaceAll("{name}", name);
6284
6813
  }, "filled");
6285
6814
 
6286
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/template.js
6815
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/template.js
6287
6816
  var import_liquidjs = __toESM(require_liquid_node(), 1);
6288
6817
  var TEMPLATE_LIMITS = {
6289
6818
  parse: 32768,
@@ -6443,7 +6972,7 @@ var renderReplyTemplate = /* @__PURE__ */ __name(async (reply, input) => {
6443
6972
  }
6444
6973
  }, "renderReplyTemplate");
6445
6974
 
6446
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/dry-run.js
6975
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/dry-run.js
6447
6976
  var DRY_RUN_DAYS = 7;
6448
6977
  var PAGE = 500;
6449
6978
  var dryRun = /* @__PURE__ */ __name(async (store, account, rules, { since, until = Date.now(), only, audience, render }) => {
@@ -6557,7 +7086,7 @@ var storedSince = /* @__PURE__ */ __name(async (store, account, chat, since) =>
6557
7086
  }
6558
7087
  }, "storedSince");
6559
7088
 
6560
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/embeddings/keys.js
7089
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/embeddings/keys.js
6561
7090
  var endpointKeyName = /* @__PURE__ */ __name((baseUrl) => {
6562
7091
  const host = new URL(baseUrl).host;
6563
7092
  return ["openai", "anthropic"].includes(host) ? `endpoint:${host}` : host;
@@ -6588,7 +7117,7 @@ var embeddingKeys = /* @__PURE__ */ __name((app, env = process.env, keyring) =>
6588
7117
  };
6589
7118
  }, "embeddingKeys");
6590
7119
 
6591
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/models/openai.js
7120
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/models/openai.js
6592
7121
  var options = strictObject({
6593
7122
  temperature: range(0, 2),
6594
7123
  top_p: range(0, 1),
@@ -6637,7 +7166,7 @@ var openai = {
6637
7166
  }), "complete")
6638
7167
  };
6639
7168
 
6640
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/models/index.js
7169
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/models/index.js
6641
7170
  var modelGateway = /* @__PURE__ */ __name((deps) => ({
6642
7171
  complete: /* @__PURE__ */ __name(async (request) => {
6643
7172
  if (deps.signal?.aborted)
@@ -6652,7 +7181,7 @@ var modelGateway = /* @__PURE__ */ __name((deps) => ({
6652
7181
  if (!adapter && target.provider === "openai")
6653
7182
  adapter = openai;
6654
7183
  if (!adapter && target.provider === "anthropic")
6655
- adapter = (await import("./anthropic-CARSCLDG.js")).anthropic;
7184
+ adapter = (await import("./anthropic-BMK6F36V.js")).anthropic;
6656
7185
  if (!adapter)
6657
7186
  throw new CliError("validation_error", `no model adapter for ${target.provider}`);
6658
7187
  if (request.images !== void 0 && adapter.images !== true)
@@ -6693,19 +7222,19 @@ var modelGateway = /* @__PURE__ */ __name((deps) => ({
6693
7222
  }, "complete")
6694
7223
  }), "modelGateway");
6695
7224
 
6696
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/consents.js
6697
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
6698
- import { join as join3 } from "node:path";
7225
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/consents.js
7226
+ import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
7227
+ import { join as join4 } from "node:path";
6699
7228
  var shape = strictObject({
6700
7229
  provider: nullable(pipe(string(), minLength(1))),
6701
7230
  deniedChats: array(pipe(string(), minLength(1)))
6702
7231
  });
6703
- var replyConsentPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join3(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies-consents.json`), "replyConsentPathFor");
7232
+ var replyConsentPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join4(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies-consents.json`), "replyConsentPathFor");
6704
7233
  var readReplyConsent = /* @__PURE__ */ __name((path) => {
6705
- if (!existsSync5(path))
7234
+ if (!existsSync7(path))
6706
7235
  return { provider: null, deniedChats: [] };
6707
7236
  try {
6708
- return parse(shape, JSON.parse(readFileSync3(path, "utf8")));
7237
+ return parse(shape, JSON.parse(readFileSync4(path, "utf8")));
6709
7238
  } catch {
6710
7239
  throw new CliError("configuration_error", "reply model consent is invalid; fix its file before granting consent");
6711
7240
  }
@@ -6718,7 +7247,7 @@ var mayModelReply = /* @__PURE__ */ __name((path, provider, chat) => {
6718
7247
  return consent.provider === provider && !consent.deniedChats.includes(chat);
6719
7248
  }, "mayModelReply");
6720
7249
 
6721
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/rendering.js
7250
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/rendering.js
6722
7251
  var replyRenderer = /* @__PURE__ */ __name((app, profile, settings, env, warn, options2 = {
6723
7252
  ai: true
6724
7253
  }) => async (rule2, message, chat, now) => {
@@ -6765,7 +7294,7 @@ var replyRenderer = /* @__PURE__ */ __name((app, profile, settings, env, warn, o
6765
7294
  return result2;
6766
7295
  }, "replyRenderer");
6767
7296
 
6768
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/replies/serve.js
7297
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/replies/serve.js
6769
7298
  var NOT_ALLOWED = "replies.send is not allow";
6770
7299
  var NO_RULES = "no rules";
6771
7300
  var ONLY_TASK = "opened a task, sent nothing";
@@ -6858,7 +7387,7 @@ var replyTo = /* @__PURE__ */ __name(async (deps, message) => {
6858
7387
  return { skip: why };
6859
7388
  }, "replyTo");
6860
7389
 
6861
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-catch-up.js
7390
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-catch-up.js
6862
7391
  var START_SYNC_DELAY_MS = 3e4;
6863
7392
  var START_SYNC_BUDGET_MS = 5 * 6e4;
6864
7393
  var START_SYNC_WINDOW_MS = 7 * 864e5;
@@ -6935,7 +7464,7 @@ var startSync = /* @__PURE__ */ __name(({ chats, newestHeld, fetch: fetch2, note
6935
7464
  };
6936
7465
  }, "startSync");
6937
7466
 
6938
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-members.js
7467
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-members.js
6939
7468
  var FIRST_FETCH_MS = 6e4;
6940
7469
  var DAY_MS = 864e5;
6941
7470
  var memberFetches = /* @__PURE__ */ __name(({ withStore, fetch: fetch2, warn, firstMs = FIRST_FETCH_MS, everyMs = DAY_MS }) => {
@@ -6989,7 +7518,7 @@ var memberFetches = /* @__PURE__ */ __name(({ withStore, fetch: fetch2, warn, fi
6989
7518
  };
6990
7519
  }, "memberFetches");
6991
7520
 
6992
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-notice.js
7521
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-notice.js
6993
7522
  var record2 = /* @__PURE__ */ __name((context, app, severity, attributes) => recordLogFor(context.streams.diagnostic, app, { command: currentRun().command || "serve" })[severity](attributes), "record");
6994
7523
  var noticeFor = /* @__PURE__ */ __name((context, app, severity = "warn") => ({ text, ...attributes }) => {
6995
7524
  if (context.format === "pretty") {
@@ -7022,7 +7551,7 @@ var recordDiagnostics = /* @__PURE__ */ __name((context, app) => {
7022
7551
  return context;
7023
7552
  }, "recordDiagnostics");
7024
7553
 
7025
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-stems.js
7554
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-stems.js
7026
7555
  var STEMS_EVERY_MS = 3e4;
7027
7556
  var STEMS_SLICE_MS = 2e3;
7028
7557
  var stemFills = /* @__PURE__ */ __name(({ withStore, warn, everyMs = STEMS_EVERY_MS, sliceMs = STEMS_SLICE_MS }) => {
@@ -7062,7 +7591,7 @@ var stemFills = /* @__PURE__ */ __name(({ withStore, warn, everyMs = STEMS_EVERY
7062
7591
  };
7063
7592
  }, "stemFills");
7064
7593
 
7065
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/render/messages.js
7594
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/render/messages.js
7066
7595
  import { styleText } from "node:util";
7067
7596
  var TIME_WIDTH = 8;
7068
7597
  var INDENT = " ".repeat(TIME_WIDTH + 2);
@@ -7238,7 +7767,7 @@ var editedAt = /* @__PURE__ */ __name((message, options2) => {
7238
7767
  return day(edited) === day(message.timestamp) ? time : `${day(edited)} ${time}`;
7239
7768
  }, "editedAt");
7240
7769
 
7241
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/message-items.js
7770
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/message-items.js
7242
7771
  var defined = /* @__PURE__ */ __name((value) => Object.fromEntries(Object.entries(value).filter(([, one]) => one !== void 0)), "defined");
7243
7772
  var attachmentItem = /* @__PURE__ */ __name((attachment) => defined({
7244
7773
  kind: attachment.kind,
@@ -7333,7 +7862,7 @@ var viewOf = /* @__PURE__ */ __name((context, messenger) => ({
7333
7862
  locale: messenger.app.locale
7334
7863
  }), "viewOf");
7335
7864
 
7336
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-answers.js
7865
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-answers.js
7337
7866
  var observed = /* @__PURE__ */ __name((value) => ({
7338
7867
  value: value.value,
7339
7868
  observed_at: value.observedAt,
@@ -7400,7 +7929,7 @@ var watchEventItem = /* @__PURE__ */ __name((value, account) => {
7400
7929
  }
7401
7930
  }, "watchEventItem");
7402
7931
 
7403
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-command.js
7932
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-command.js
7404
7933
  var watchCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("watch"), {
7405
7934
  output: { entity: "watch_item" },
7406
7935
  effects: REMOTE_READ,
@@ -7555,7 +8084,7 @@ var describe = /* @__PURE__ */ __name((event, render) => {
7555
8084
  }
7556
8085
  }, "describe");
7557
8086
 
7558
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-command.js
8087
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-command.js
7559
8088
  var serveCommand = /* @__PURE__ */ __name((messenger) => {
7560
8089
  const command = annotate(new Command("serve"), {
7561
8090
  output: { entity: "serve_summary" },
@@ -7819,8 +8348,8 @@ var tasking = /* @__PURE__ */ __name((context, warn) => {
7819
8348
  };
7820
8349
  }, "tasking");
7821
8350
 
7822
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/store-tables-command.js
7823
- import { existsSync as existsSync6 } from "node:fs";
8351
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/store-tables-command.js
8352
+ import { existsSync as existsSync8 } from "node:fs";
7824
8353
  var PATH = "store tables list";
7825
8354
  var STORE_TABLES_QUERY = {
7826
8355
  entity: "store_table",
@@ -7849,7 +8378,7 @@ var storeTablesCommand = /* @__PURE__ */ __name((messenger) => {
7849
8378
  const filter = filterOf(words);
7850
8379
  const { full } = this.optsWithGlobals();
7851
8380
  const path = storePath(environmentOf(this).env ?? process.env);
7852
- if (!existsSync6(path))
8381
+ if (!existsSync8(path))
7853
8382
  throw new CliError("not_found", `no store at ${path}`);
7854
8383
  const items = await readStoreTables(path, { filter, sizes: full === true });
7855
8384
  renderAnswer(this, outputFor(this), listOf(PATH, {
@@ -7862,7 +8391,7 @@ var storeTablesCommand = /* @__PURE__ */ __name((messenger) => {
7862
8391
  return tables;
7863
8392
  }, "storeTablesCommand");
7864
8393
 
7865
- // node_modules/.pnpm/@wirecat+cli-core@0.597.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_e61f089635abd97613f35385460a4858/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
8394
+ // node_modules/.pnpm/@wirecat+cli-core@0.602.0_@wirecat+cli-base@0.80.8_commander@15.0.0_esbuild@0.28.2_type_87bcf484fc0706f541e30693101b5a29/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
7866
8395
  var SEARCH_INDEXES = ["messages_fts", "chats_fts", "identities_fts"];
7867
8396
  var WORD_INDEX = "message_words";
7868
8397
  var schemaOf = /* @__PURE__ */ __name((database) => {
@@ -7871,7 +8400,7 @@ var schemaOf = /* @__PURE__ */ __name((database) => {
7871
8400
  }, "schemaOf");
7872
8401
  var count2 = /* @__PURE__ */ __name((database, table) => Number(database.prepare(`SELECT count(*) AS n FROM ${table}`).get()?.n ?? 0), "count");
7873
8402
  var pendingIfKnown2 = /* @__PURE__ */ __name((database) => database.prepare("SELECT 1 FROM pragma_table_info('messages') WHERE name = 'normalized_text'").get() ? pendingNormalization(database) : null, "pendingIfKnown");
7874
- var bytesOf2 = /* @__PURE__ */ __name((path) => existsSync7(path) ? statSync3(path).size : 0, "bytesOf");
8403
+ var bytesOf2 = /* @__PURE__ */ __name((path) => existsSync9(path) ? statSync4(path).size : 0, "bytesOf");
7875
8404
  var reading = /* @__PURE__ */ __name(async (path, read) => {
7876
8405
  const database = await openCache(path);
7877
8406
  try {
@@ -7888,10 +8417,23 @@ var readingOnly = /* @__PURE__ */ __name(async (path, read) => {
7888
8417
  database.close();
7889
8418
  }
7890
8419
  }, "readingOnly");
7891
- var storeSummary = /* @__PURE__ */ __name(async (env) => {
8420
+ var storeSummary = /* @__PURE__ */ __name(async (env, { deep = false, command } = {}) => {
7892
8421
  const path = storePath(env);
7893
- if (!existsSync7(path))
8422
+ if (!existsSync9(path))
7894
8423
  return { path, exists: false };
8424
+ const checked = await storeHealth(path, { deep });
8425
+ const health = {
8426
+ checked: checked.checked,
8427
+ covers: deep ? "every page and every search index" : QUICK_HEALTH_CHECKS,
8428
+ ok: checked.ok,
8429
+ ms: checked.ms,
8430
+ ...checked.problems ? { problems: checked.problems } : {},
8431
+ ...checked.damagedTables?.length ? { damagedTables: checked.damagedTables } : {},
8432
+ ...checked.invalidJson?.length ? { invalidJson: checked.invalidJson } : {},
8433
+ ...checked.searchIndexes?.some((index) => !index.ok) ? { damagedSearchIndexes: checked.searchIndexes.filter((index) => !index.ok).map((index) => index.name) } : {}
8434
+ };
8435
+ const damage = command ? explainDamage(checked, command) : null;
8436
+ const healthOf = { health, ...damage ? { damage } : {} };
7895
8437
  try {
7896
8438
  return await reading(path, (database) => {
7897
8439
  const { version, writable } = schemaOf(database);
@@ -7901,11 +8443,12 @@ var storeSummary = /* @__PURE__ */ __name(async (env) => {
7901
8443
  schema: version,
7902
8444
  speaks: SPEAKS,
7903
8445
  writable,
7904
- ...version > 0 ? { chats: count2(database, "chats"), messages: count2(database, "messages") } : {}
8446
+ ...version > 0 ? { chats: count2(database, "chats"), messages: count2(database, "messages") } : {},
8447
+ ...healthOf
7905
8448
  };
7906
8449
  });
7907
8450
  } catch (error) {
7908
- return { path, exists: true, error: messageOf2(error) };
8451
+ return { path, exists: true, error: messageOf2(error), ...healthOf };
7909
8452
  }
7910
8453
  }, "storeSummary");
7911
8454
  var result = /* @__PURE__ */ __name((command, value, next = []) => renderAnswer(command, outputFor(command), itemOf(snakeKeys(value), { next })), "result");
@@ -7920,7 +8463,8 @@ var storeMaintenanceCommands = /* @__PURE__ */ __name((messenger) => [
7920
8463
  repairCommand(messenger),
7921
8464
  resetCommand(messenger),
7922
8465
  copiesCommand(),
7923
- storeTablesCommand(messenger)
8466
+ storeTablesCommand(messenger),
8467
+ storeRecoverCommand({ command: messenger.app.command, version: messenger.app.version })
7924
8468
  ], "storeMaintenanceCommands");
7925
8469
  var refuseWhileServing = /* @__PURE__ */ __name((command, messenger) => {
7926
8470
  const serving = servingProfiles(messenger.app, environmentOf(command).env ?? process.env);
@@ -7932,7 +8476,7 @@ var repairCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("
7932
8476
  const { renderer, format } = outputFor(this);
7933
8477
  const { dryRun: dryRun2 } = this.opts();
7934
8478
  const path = storePath(environmentOf(this).env ?? process.env);
7935
- if (!existsSync7(path)) {
8479
+ if (!existsSync9(path)) {
7936
8480
  result(this, { path, exists: false });
7937
8481
  return;
7938
8482
  }
@@ -7972,7 +8516,7 @@ var notesOf = /* @__PURE__ */ __name((report, command) => {
7972
8516
  }, "notesOf");
7973
8517
  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) {
7974
8518
  const path = storePath(environmentOf(this).env ?? process.env);
7975
- if (!existsSync7(path))
8519
+ if (!existsSync9(path))
7976
8520
  throw new CliError("not_found", `no store at ${path}`);
7977
8521
  const deleted = await reading(path, (database) => deleteCopy(database, name));
7978
8522
  result(this, { path, deleted });
@@ -7980,7 +8524,7 @@ var copiesCommand = /* @__PURE__ */ __name(() => new Command("copies").descripti
7980
8524
  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() {
7981
8525
  const { renderer } = outputFor(this);
7982
8526
  const path = storePath(environmentOf(this).env ?? process.env);
7983
- if (!existsSync7(path)) {
8527
+ if (!existsSync9(path)) {
7984
8528
  result(this, { path, exists: false, ok: true });
7985
8529
  return;
7986
8530
  }
@@ -8043,7 +8587,7 @@ var inspect = /* @__PURE__ */ __name((path) => reading(path, (database) => {
8043
8587
  ...schema.version > 0 ? [["attachment_words", indexIntegrity(database, "attachment_words", 0)]] : []
8044
8588
  ]);
8045
8589
  const size = bytesOf2(path) + bytesOf2(`${path}-wal`);
8046
- const { bavail, bsize } = statfsSync(dirname(path));
8590
+ const { bavail, bsize } = statfsSync2(dirname2(path));
8047
8591
  const free = Number(bavail) * Number(bsize);
8048
8592
  const behind = schema.version > 0 ? chatsBehind(database) : [];
8049
8593
  const vectorIndexes = schema.version >= 34 ? vectorIndexCounts(database) : [];
@@ -8131,7 +8675,7 @@ var chatsBehind = /* @__PURE__ */ __name((database) => database.prepare(`SELECT
8131
8675
  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() {
8132
8676
  const { renderer } = outputFor(this);
8133
8677
  const path = storePath(environmentOf(this).env ?? process.env);
8134
- if (!existsSync7(path)) {
8678
+ if (!existsSync9(path)) {
8135
8679
  result(this, { path, exists: false });
8136
8680
  renderer.note(`no store yet \u2014 the first \`${messenger.app.command}\` command that reads a chat creates it`);
8137
8681
  return;
@@ -8195,7 +8739,7 @@ var buildNoteIndex = /* @__PURE__ */ __name((database, note, { reset = false } =
8195
8739
  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() {
8196
8740
  const { renderer } = outputFor(this);
8197
8741
  const path = storePath(environmentOf(this).env ?? process.env);
8198
- if (!existsSync7(path)) {
8742
+ if (!existsSync9(path)) {
8199
8743
  result(this, { path, exists: false });
8200
8744
  return;
8201
8745
  }
@@ -8224,11 +8768,11 @@ var reindexCommand = /* @__PURE__ */ __name((messenger) => destroysNothing(annot
8224
8768
  result(this, answer);
8225
8769
  }), "reindexCommand");
8226
8770
  var vacuumInto = /* @__PURE__ */ __name(async (path, target) => {
8227
- writeFileSync(target, "", { flag: "wx", mode: 384 });
8771
+ writeFileSync2(target, "", { flag: "wx", mode: 384 });
8228
8772
  try {
8229
8773
  await reading(path, (database) => database.prepare("VACUUM INTO ?").run(target));
8230
8774
  } catch (error) {
8231
- rmSync2(target, { force: true });
8775
+ rmSync3(target, { force: true });
8232
8776
  throw error;
8233
8777
  }
8234
8778
  }, "vacuumInto");
@@ -8237,9 +8781,9 @@ var backupCommand = /* @__PURE__ */ __name(() => destroysNothing(annotate(new Co
8237
8781
  const { encrypt } = this.opts();
8238
8782
  const path = storePath(environmentOf(this).env ?? process.env);
8239
8783
  const target = resolve(file2);
8240
- if (!existsSync7(path))
8784
+ if (!existsSync9(path))
8241
8785
  throw new CliError("not_found", `no store at ${path} to back up`);
8242
- if (existsSync7(target))
8786
+ if (existsSync9(target))
8243
8787
  throw new CliError("validation_error", `${target} exists \u2014 a backup never overwrites a file`);
8244
8788
  const password = encrypt ? await passwordOf(this, { twice: true }) : void 0;
8245
8789
  const copyAt = password === void 0 ? target : `${path}.backup-${process.pid}`;
@@ -8261,22 +8805,22 @@ var backupCommand = /* @__PURE__ */ __name(() => destroysNothing(annotate(new Co
8261
8805
  });
8262
8806
  } catch (error) {
8263
8807
  if (password === void 0)
8264
- rmSync2(target, { force: true });
8808
+ rmSync3(target, { force: true });
8265
8809
  throw error;
8266
8810
  } finally {
8267
8811
  if (password !== void 0)
8268
- rmSync2(copyAt, { force: true });
8812
+ rmSync3(copyAt, { force: true });
8269
8813
  }
8270
8814
  }), "backupCommand");
8271
8815
  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) {
8272
8816
  const { output } = this.opts();
8273
8817
  const from = resolve(file2);
8274
8818
  const to = resolve(output);
8275
- if (!existsSync7(from))
8819
+ if (!existsSync9(from))
8276
8820
  throw new CliError("not_found", `no file at ${from}`);
8277
8821
  if (!isSealed(from))
8278
8822
  throw new CliError("validation_error", `${from} was not written with --encrypt`);
8279
- if (existsSync7(to))
8823
+ if (existsSync9(to))
8280
8824
  throw new CliError("validation_error", `${to} exists \u2014 never overwritten`);
8281
8825
  await unsealFile(from, to, await passwordOf(this, { twice: false }));
8282
8826
  result(this, { path: to, from, bytes: bytesOf2(to) });
@@ -8284,46 +8828,46 @@ var decryptCommand = /* @__PURE__ */ __name(() => annotate(new Command("decrypt"
8284
8828
  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) {
8285
8829
  const path = storePath(environmentOf(this).env ?? process.env);
8286
8830
  const given = resolve(file2);
8287
- if (!existsSync7(given))
8831
+ if (!existsSync9(given))
8288
8832
  throw new CliError("not_found", `no file at ${given}`);
8289
8833
  refuseWhileServing(this, messenger);
8290
8834
  if (!isSealed(given))
8291
8835
  return restoreFrom(this, messenger, given, given);
8292
8836
  const opened = `${path}.unsealing-${process.pid}`;
8293
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
8837
+ mkdirSync(dirname2(path), { recursive: true, mode: 448 });
8294
8838
  try {
8295
8839
  await unsealFile(given, opened, await passwordOf(this, { twice: false }));
8296
8840
  await restoreFrom(this, messenger, opened, given);
8297
8841
  } finally {
8298
- rmSync2(opened, { force: true });
8842
+ rmSync3(opened, { force: true });
8299
8843
  }
8300
8844
  }), "restoreCommand");
8301
8845
  var restoreFrom = /* @__PURE__ */ __name(async (command, messenger, backup, given) => {
8302
8846
  const { renderer } = outputFor(command);
8303
8847
  const path = storePath(environmentOf(command).env ?? process.env);
8304
- if (existsSync7(path) && realpathSync(backup) === realpathSync(path)) {
8848
+ if (existsSync9(path) && realpathSync2(backup) === realpathSync2(path)) {
8305
8849
  throw new CliError("validation_error", `${backup} is the store itself`);
8306
8850
  }
8307
8851
  if (await isRollbackCopy(backup))
8308
8852
  return rollBackFrom(command, messenger, backup);
8309
8853
  const schema = await backupSchema(backup);
8310
8854
  const stamp = stampNow();
8311
- const kept = existsSync7(path) ? `${path}.before-restore-${stamp}` : null;
8855
+ const kept = existsSync9(path) ? `${path}.before-restore-${stamp}` : null;
8312
8856
  if (kept) {
8313
8857
  const waitMs = environmentOf(command).storeLockWaitMs;
8314
8858
  await quiesce(path, messenger, "restore", (message) => renderer.warn(message), waitMs);
8315
8859
  } else
8316
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
8860
+ mkdirSync(dirname2(path), { recursive: true, mode: 448 });
8317
8861
  const incoming = `${path}.restoring-${stamp}`;
8318
8862
  copyFileSync(backup, incoming, constants.COPYFILE_EXCL);
8319
8863
  chmodSync(incoming, 384);
8320
8864
  if (kept) {
8321
- renameSync2(path, kept);
8865
+ renameSync3(path, kept);
8322
8866
  for (const suffix of ["-wal", "-shm"])
8323
- if (existsSync7(`${path}${suffix}`))
8324
- renameSync2(`${path}${suffix}`, `${kept}${suffix}`);
8867
+ if (existsSync9(`${path}${suffix}`))
8868
+ renameSync3(`${path}${suffix}`, `${kept}${suffix}`);
8325
8869
  }
8326
- renameSync2(incoming, path);
8870
+ renameSync3(incoming, path);
8327
8871
  result(command, { path, restoredFrom: given, keptAt: kept, schema: schema.version });
8328
8872
  if (kept)
8329
8873
  renderer.note(`the store it replaced is kept at ${kept}`);
@@ -8342,7 +8886,7 @@ var isRollbackCopy = /* @__PURE__ */ __name(async (file2) => {
8342
8886
  var rollBackFrom = /* @__PURE__ */ __name(async (command, messenger, copy) => {
8343
8887
  const { renderer } = outputFor(command);
8344
8888
  const path = storePath(environmentOf(command).env ?? process.env);
8345
- if (!existsSync7(path))
8889
+ if (!existsSync9(path))
8346
8890
  throw new CliError("not_found", `no store at ${path} to roll back`);
8347
8891
  const waitMs = environmentOf(command).storeLockWaitMs;
8348
8892
  await quiesce(path, messenger, "restore", (message) => renderer.warn(message), waitMs);
@@ -8392,7 +8936,7 @@ var backupSchema = /* @__PURE__ */ __name(async (backup) => {
8392
8936
  var STORE_LOCK_WAIT_MS = 1e3;
8393
8937
  var quiesce = /* @__PURE__ */ __name(async (path, messenger, then, warn, waitMs = STORE_LOCK_WAIT_MS) => {
8394
8938
  const { command } = messenger.app;
8395
- const files = [path, `${path}-wal`, `${path}-shm`].filter((file2) => existsSync7(file2)).map((file2) => realpathSync(file2));
8939
+ const files = [path, `${path}-wal`, `${path}-shm`].filter((file2) => existsSync9(file2)).map((file2) => realpathSync2(file2));
8396
8940
  const holders = holdersOf(files);
8397
8941
  if (holders === void 0) {
8398
8942
  warn(`this system cannot say which processes have the store open \u2014 restart every running serve and mcp after this`);
@@ -8418,7 +8962,7 @@ var resetCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("r
8418
8962
  const { command } = messenger.app;
8419
8963
  const env = environmentOf(this).env ?? process.env;
8420
8964
  const path = storePath(env);
8421
- if (!existsSync7(path)) {
8965
+ if (!existsSync9(path)) {
8422
8966
  result(this, { path, exists: false, reset: false });
8423
8967
  renderer.note(`no store at ${path} \u2014 nothing to reset; the first \`${command}\` command that reads a chat creates it`);
8424
8968
  return;
@@ -8454,17 +8998,17 @@ var resetCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("r
8454
8998
  });
8455
8999
  renderer.note(`backed the store up to ${backup}`);
8456
9000
  }
8457
- for (const suffix of STORE_PARTS)
8458
- rmSync2(`${path}${suffix}`, { force: true });
9001
+ for (const suffix of STORE_PARTS2)
9002
+ rmSync3(`${path}${suffix}`, { force: true });
8459
9003
  await (await openStore({ path, command })).close();
8460
9004
  const schema = await reading(path, (database) => schemaOf(database).version);
8461
9005
  result(this, { path, exists: true, reset: true, backup, backedUp, schema });
8462
9006
  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`);
8463
9007
  }), "resetCommand");
8464
- var STORE_PARTS = ["", "-wal", "-shm"];
9008
+ var STORE_PARTS2 = ["", "-wal", "-shm"];
8465
9009
  var resetPreview = /* @__PURE__ */ __name(async (path, messenger, env, keep) => {
8466
- const files = STORE_PARTS.map((suffix) => `${path}${suffix}`).filter((file2) => existsSync7(file2));
8467
- const holders = holdersOf(files.map((file2) => realpathSync(file2)));
9010
+ const files = STORE_PARTS2.map((suffix) => `${path}${suffix}`).filter((file2) => existsSync9(file2));
9011
+ const holders = holdersOf(files.map((file2) => realpathSync2(file2)));
8468
9012
  const serving = servingProfiles(messenger.app, env).length > 0;
8469
9013
  const read = await readingOnly(path, (database) => ({
8470
9014
  schema: schemaOf(database).version,
@@ -8495,6 +9039,9 @@ export {
8495
9039
  checkFor,
8496
9040
  passes,
8497
9041
  seal,
9042
+ storeRecoveryCheck,
9043
+ storeRecoveryRun,
9044
+ recoveryNotes,
8498
9045
  storeInfo,
8499
9046
  ENCRYPT_OPTION,
8500
9047
  passwordOf,