@wirecat/cli-memo 0.131.45 → 0.131.47
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.
- package/dist/bin/memo.js +2 -2
- package/dist/bundle/{all-profiles-ZBASDAVU.js → all-profiles-75EGCXK3.js} +5 -5
- package/dist/bundle/{anthropic-3ZS3RCUH.js → anthropic-PTAYBCPR.js} +3 -3
- package/dist/bundle/{app-server-PQF22PMD.js → app-server-YSUBXGGB.js} +41 -38
- package/dist/bundle/auto-GB35FRTV.js +86 -0
- package/dist/bundle/{bun-3CGVV3V2.js → bun-3AIG5ML4.js} +2 -2
- package/dist/bundle/{bun-sqlite-D6T3ESTG.js → bun-sqlite-5FCGI6EO.js} +2 -2
- package/dist/bundle/{chunk-CAPDRDQU.js → chunk-25RDNYKZ.js} +5 -5
- package/dist/bundle/{chunk-L45FSDH3.js → chunk-32QM6X5H.js} +1 -1
- package/dist/bundle/{chunk-NB267XRJ.js → chunk-3HPFTKDH.js} +4 -4
- package/dist/bundle/{chunk-UP2K5XUA.js → chunk-4LWX2WOB.js} +3 -3
- package/dist/bundle/{chunk-TVZEELSS.js → chunk-5N6HWFXN.js} +508 -338
- package/dist/bundle/{chunk-SK3TPK5Y.js → chunk-6IVHND3S.js} +4 -4
- package/dist/bundle/{chunk-75EEQB2R.js → chunk-6QNPOBR5.js} +11 -11
- package/dist/bundle/{chunk-75RJJQ2Q.js → chunk-6TKWJKPS.js} +10 -10
- package/dist/bundle/{chunk-CH37NCAP.js → chunk-BNIWLVWG.js} +3 -3
- package/dist/bundle/{chunk-IQ2MW47B.js → chunk-CODD5SXC.js} +27 -27
- package/dist/bundle/{chunk-HAPE26JK.js → chunk-DDADFHR7.js} +12 -12
- package/dist/bundle/{chunk-CGJFYMVZ.js → chunk-DMTLG2GD.js} +7 -7
- package/dist/bundle/{chunk-GOJZ3FQY.js → chunk-DS4DOK75.js} +22 -21
- package/dist/bundle/{chunk-PMUAUR5S.js → chunk-DWBTCOF2.js} +4 -4
- package/dist/bundle/{chunk-5IYS3BWO.js → chunk-EFQCDCLY.js} +56 -56
- package/dist/bundle/{chunk-IYJGFBNN.js → chunk-ELKK5M66.js} +5 -5
- package/dist/bundle/{chunk-YDNM5KYV.js → chunk-EVZI54B5.js} +4 -4
- package/dist/bundle/{chunk-GTPWWGQI.js → chunk-F4HMPMET.js} +7 -7
- package/dist/bundle/{chunk-2OYB4PWV.js → chunk-FSAMZHIM.js} +5 -5
- package/dist/bundle/{chunk-G3FRUKAD.js → chunk-G3YSCD77.js} +182 -158
- package/dist/bundle/{chunk-NTFEJ52I.js → chunk-G4W42RGE.js} +1 -1
- package/dist/bundle/{chunk-7EA6M6RA.js → chunk-GA3KFYEZ.js} +4 -4
- package/dist/bundle/{chunk-CXRCADXS.js → chunk-GOFPCOEI.js} +9 -9
- package/dist/bundle/{chunk-65MK55RS.js → chunk-GQLSVXS2.js} +20 -20
- package/dist/bundle/{chunk-YWTWDX4F.js → chunk-HCZV537M.js} +1 -1
- package/dist/bundle/{chunk-OMBFF6Z6.js → chunk-HVTW2M6T.js} +1 -1
- package/dist/bundle/{chunk-EJ2PEYQU.js → chunk-HYEYRFWX.js} +1 -1
- package/dist/bundle/{chunk-AOSSO4YI.js → chunk-I2RDACUF.js} +6 -6
- package/dist/bundle/{chunk-KE3CYUON.js → chunk-ILK5BCBB.js} +1 -1
- package/dist/bundle/{chunk-U4J7TAOW.js → chunk-IPLPMD6H.js} +1 -1
- package/dist/bundle/{chunk-7WJEQ36E.js → chunk-IPMBB6W5.js} +2 -2
- package/dist/bundle/{chunk-ZJXAYYLF.js → chunk-J324GKJM.js} +1 -1
- package/dist/bundle/{chunk-PXSGUVZP.js → chunk-KLBZJZD2.js} +637 -119
- package/dist/bundle/{chunk-FMMIPFTU.js → chunk-KWM7HLAI.js} +4 -4
- package/dist/bundle/{chunk-CRLYBXV5.js → chunk-LE7NROV6.js} +43 -36
- package/dist/bundle/{chunk-25MS26SH.js → chunk-MCMEBL3C.js} +23 -10
- package/dist/bundle/{chunk-FRT7URL7.js → chunk-MMJDQQFX.js} +483 -282
- package/dist/bundle/{chunk-TKFG75MJ.js → chunk-MSBRZ5QD.js} +2 -2
- package/dist/bundle/{chunk-IJBJ47GI.js → chunk-N5QQFDNV.js} +2 -2
- package/dist/bundle/{chunk-B4PZQYGP.js → chunk-N63KZFH4.js} +8 -8
- package/dist/bundle/{chunk-NBA3GJBR.js → chunk-OSCRP52P.js} +805 -347
- package/dist/bundle/{chunk-GBRK3WXY.js → chunk-PGVADNDD.js} +2 -2
- package/dist/bundle/{chunk-HXCSD2XV.js → chunk-R44PUK7G.js} +1 -1
- package/dist/bundle/{chunk-F2VTAFIT.js → chunk-SYTYLLYO.js} +1 -1
- package/dist/bundle/{chunk-MKVUBQEG.js → chunk-U35N3EC7.js} +1 -1
- package/dist/bundle/{chunk-5ZHM6SZW.js → chunk-U75ANK5K.js} +1 -1
- package/dist/bundle/{chunk-7G7N3IUO.js → chunk-UE4GMPBY.js} +4 -2
- package/dist/bundle/{chunk-OTOKJAYR.js → chunk-UFVGAFID.js} +3 -3
- package/dist/bundle/{chunk-OT4CLMVF.js → chunk-V3B5COFP.js} +3 -3
- package/dist/bundle/{chunk-6NQTGFAL.js → chunk-V6OYLCCM.js} +2 -2
- package/dist/bundle/{chunk-IAPKZSC5.js → chunk-W2JVP7GK.js} +1 -1
- package/dist/bundle/{chunk-LL3Z6KA3.js → chunk-W3T45MMN.js} +5 -5
- package/dist/bundle/{chunk-EJ4X6XH2.js → chunk-XRRPQCTS.js} +1 -1
- package/dist/bundle/{chunk-G6TRTDHB.js → chunk-Y4ZXDJQF.js} +2 -2
- package/dist/bundle/{chunk-WGX73SAA.js → chunk-YMK35KVV.js} +2 -2
- package/dist/bundle/{chunk-7G63XPDR.js → chunk-ZKH6LC5P.js} +7 -7
- package/dist/bundle/{chunk-C6GSSMDG.js → chunk-ZLIARJU4.js} +1 -1
- package/dist/bundle/{command-contract-K3GJRRXT.js → command-contract-YYILWWYQ.js} +11 -11
- package/dist/bundle/{decode-TTMBMSGQ.js → decode-F2A2BLIA.js} +2 -2
- package/dist/bundle/{echarts-7XN2RLJT.js → echarts-JL55HJCM.js} +2 -2
- package/dist/bundle/{embed-UKTHDQH5.js → embed-74KVORNN.js} +3 -3
- package/dist/bundle/{embedder-SCKLAVKW.js → embedder-GACNPCZN.js} +6 -6
- package/dist/bundle/{entry-VQRYB2HE.js → entry-7FI2H4RQ.js} +4 -4
- package/dist/bundle/failure-AHPPXHAW.js +66 -0
- package/dist/bundle/{first-run-RL6ZRY3Y.js → first-run-D4VBIJ7H.js} +5 -5
- package/dist/bundle/{first-screen-CRURWNKP.js → first-screen-D7Q2U7VP.js} +12 -12
- package/dist/bundle/{instructions-KGU67SPR.js → instructions-QNPIVGKX.js} +1 -1
- package/dist/bundle/{mcp-CSN7BDNG.js → mcp-AFXHH33V.js} +35 -35
- package/dist/bundle/memo.js +6 -6
- package/dist/bundle/{node-S5LQLVMO.js → node-SPFML2D5.js} +2 -2
- package/dist/bundle/{node-sqlite-PFCIEDPX.js → node-sqlite-T3KILRCP.js} +3 -3
- package/dist/bundle/{oauth-KJOGYDPV.js → oauth-ZOGSHZF3.js} +4 -4
- package/dist/bundle/{open-TPBENKAD.js → open-XXFVCGCA.js} +2 -2
- package/dist/bundle/{openai-UOYTHO32.js → openai-JRHZLFKD.js} +7 -7
- package/dist/bundle/{process-JWKE7GPV.js → process-OGYYVVLG.js} +1 -1
- package/dist/bundle/{program-RJ6X4DXE.js → program-EFCQACPD.js} +138 -61
- package/dist/bundle/{prompt-5HQ3Z7ZS.js → prompt-53D5WVD3.js} +2 -2
- package/dist/bundle/{recognize-5ILXEPII.js → recognize-7GYZKJCD.js} +1 -1
- package/dist/bundle/{remote-WIN3HJII.js → remote-V5GUFZCG.js} +4 -4
- package/dist/bundle/{rerank-JKHDSEBI.js → rerank-FUNVBYFI.js} +4 -4
- package/dist/bundle/{serve-VMHFRDYH.js → serve-ZLUYFAXC.js} +6 -6
- package/dist/bundle/server-4OJC7ZWM.js +61 -0
- package/dist/bundle/server-CGUUZBLB.js +48 -0
- package/dist/bundle/{server-TKWVP4OJ.js → server-HJRMD3XD.js} +50 -50
- package/dist/bundle/{state-OWOLD7JI.js → state-4P7H6KBM.js} +3 -3
- package/dist/bundle/{store-6GFFSNRY.js → store-NILJK24C.js} +11 -9
- package/dist/bundle/store-maintenance-command-VP7CIBSS.js +48 -0
- package/dist/bundle/update-NPK4DT2E.js +69 -0
- package/dist/contract-overrides/doctor.d.ts.map +1 -1
- package/dist/contract-overrides/doctor.js +6 -0
- package/dist/contract-overrides/doctor.js.map +1 -1
- package/dist/doctor/command.d.ts +23 -2
- package/dist/doctor/command.d.ts.map +1 -1
- package/dist/doctor/command.js +13 -5
- package/dist/doctor/command.js.map +1 -1
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +2 -0
- package/dist/examples.js.map +1 -1
- package/dist/schedule/command.d.ts.map +1 -1
- package/dist/schedule/command.js +2 -0
- package/dist/schedule/command.js.map +1 -1
- package/dist/schedule/mail-triage-input.d.ts +24 -0
- package/dist/schedule/mail-triage-input.d.ts.map +1 -0
- package/dist/schedule/mail-triage-input.js +53 -0
- package/dist/schedule/mail-triage-input.js.map +1 -0
- package/dist/store/info-command.d.ts.map +1 -1
- package/dist/store/info-command.js +23 -1
- package/dist/store/info-command.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/skills/mail-triage/SKILL.md +25 -27
- package/dist/bundle/auto-NW7IP4ST.js +0 -86
- package/dist/bundle/failure-JHW2U2OF.js +0 -66
- package/dist/bundle/server-IBJ23GCB.js +0 -48
- package/dist/bundle/server-SNWCFMJN.js +0 -61
- package/dist/bundle/store-maintenance-command-7DMPWFT4.js +0 -48
- package/dist/bundle/update-KSB7VYAW.js +0 -69
- /package/dist/bundle/{chunk-DL5LDAOS.js → chunk-JPGEFBRW.js} +0 -0
|
@@ -3,13 +3,16 @@ const require = __bundleRequire(import.meta.url);
|
|
|
3
3
|
import {
|
|
4
4
|
answerOf,
|
|
5
5
|
messengerContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GQLSVXS2.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,
|
|
13
16
|
memberAnswer,
|
|
14
17
|
newSendId,
|
|
15
18
|
onlineDeps,
|
|
@@ -20,11 +23,12 @@ import {
|
|
|
20
23
|
senderIsMe,
|
|
21
24
|
serveRelay,
|
|
22
25
|
servicesFor,
|
|
26
|
+
storeHealth,
|
|
23
27
|
syncsOneChat,
|
|
24
28
|
typedQuery,
|
|
25
29
|
withQuery,
|
|
26
30
|
withTimeLimit
|
|
27
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-5N6HWFXN.js";
|
|
28
32
|
import {
|
|
29
33
|
stringWidth,
|
|
30
34
|
wrapAnsi
|
|
@@ -56,30 +60,35 @@ import {
|
|
|
56
60
|
snakeKeys,
|
|
57
61
|
storeTable,
|
|
58
62
|
withoutProviderRefs
|
|
59
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-G3YSCD77.js";
|
|
60
64
|
import {
|
|
61
65
|
failureKey
|
|
62
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-ZKH6LC5P.js";
|
|
63
67
|
import {
|
|
64
68
|
envName
|
|
65
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-SYTYLLYO.js";
|
|
66
70
|
import {
|
|
67
71
|
holdLock,
|
|
68
72
|
lockPath,
|
|
69
73
|
releaseLock,
|
|
70
74
|
servingProfiles,
|
|
71
75
|
takeLock
|
|
72
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-MSBRZ5QD.js";
|
|
73
77
|
import {
|
|
74
78
|
holdersOf
|
|
75
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-W2JVP7GK.js";
|
|
76
80
|
import {
|
|
81
|
+
CORPORA,
|
|
77
82
|
MIGRATIONS,
|
|
83
|
+
drainCorpus,
|
|
84
|
+
drainMeetingIndex,
|
|
78
85
|
drainNoteIndex,
|
|
79
86
|
dropAllUnusedVectors,
|
|
80
87
|
fileFacts,
|
|
81
88
|
fillSearchIndex,
|
|
82
89
|
fillStems,
|
|
90
|
+
fillTrigrams,
|
|
91
|
+
fillVectorIndexes,
|
|
83
92
|
formatLocator,
|
|
84
93
|
involvementStoreOver,
|
|
85
94
|
migrate,
|
|
@@ -90,10 +99,12 @@ import {
|
|
|
90
99
|
parseLocator,
|
|
91
100
|
pendingNormalization,
|
|
92
101
|
readStoreTables,
|
|
102
|
+
rebuildMentions,
|
|
93
103
|
resetAttachmentWords,
|
|
94
104
|
resetNoteIndex,
|
|
95
105
|
resetSearchIndex,
|
|
96
106
|
resetStems,
|
|
107
|
+
rollBack,
|
|
97
108
|
rowCounts,
|
|
98
109
|
searchIndexState,
|
|
99
110
|
stemmerCache,
|
|
@@ -101,28 +112,28 @@ import {
|
|
|
101
112
|
storeClients,
|
|
102
113
|
storeContents,
|
|
103
114
|
vectorIndexCounts
|
|
104
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-OSCRP52P.js";
|
|
105
116
|
import {
|
|
106
117
|
queryFieldsOf
|
|
107
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-EFQCDCLY.js";
|
|
108
119
|
import {
|
|
109
120
|
readSecret
|
|
110
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-V6OYLCCM.js";
|
|
111
122
|
import {
|
|
112
123
|
checkedOptions,
|
|
113
124
|
range
|
|
114
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-32QM6X5H.js";
|
|
115
126
|
import {
|
|
116
127
|
messagesFor,
|
|
117
128
|
systemFor,
|
|
118
129
|
validateImages
|
|
119
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-U35N3EC7.js";
|
|
120
131
|
import {
|
|
121
132
|
storePath
|
|
122
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-IPLPMD6H.js";
|
|
123
134
|
import {
|
|
124
135
|
openCache
|
|
125
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-25RDNYKZ.js";
|
|
126
137
|
import {
|
|
127
138
|
Credentials,
|
|
128
139
|
pathsAreOverridden,
|
|
@@ -1811,7 +1822,7 @@ var require_liquid_node = __commonJS({
|
|
|
1811
1822
|
return readFileAsync(filepath, "utf8");
|
|
1812
1823
|
}
|
|
1813
1824
|
__name(readFile, "readFile");
|
|
1814
|
-
function
|
|
1825
|
+
function existsSync10(filepath) {
|
|
1815
1826
|
try {
|
|
1816
1827
|
fs$1.statSync(filepath);
|
|
1817
1828
|
return true;
|
|
@@ -1819,11 +1830,11 @@ var require_liquid_node = __commonJS({
|
|
|
1819
1830
|
return false;
|
|
1820
1831
|
}
|
|
1821
1832
|
}
|
|
1822
|
-
__name(
|
|
1823
|
-
function
|
|
1833
|
+
__name(existsSync10, "existsSync");
|
|
1834
|
+
function readFileSync5(filepath) {
|
|
1824
1835
|
return fs$1.readFileSync(filepath, "utf8");
|
|
1825
1836
|
}
|
|
1826
|
-
__name(
|
|
1837
|
+
__name(readFileSync5, "readFileSync");
|
|
1827
1838
|
function resolve2(root, file2, ext) {
|
|
1828
1839
|
if (!path.extname(file2))
|
|
1829
1840
|
file2 += ext;
|
|
@@ -1837,10 +1848,10 @@ var require_liquid_node = __commonJS({
|
|
|
1837
1848
|
}
|
|
1838
1849
|
}
|
|
1839
1850
|
__name(fallback, "fallback");
|
|
1840
|
-
function
|
|
1851
|
+
function dirname3(filepath) {
|
|
1841
1852
|
return path.dirname(filepath);
|
|
1842
1853
|
}
|
|
1843
|
-
__name(
|
|
1854
|
+
__name(dirname3, "dirname");
|
|
1844
1855
|
var realpathAsync = promisify(fs$1.realpath);
|
|
1845
1856
|
async function contains(root, file2) {
|
|
1846
1857
|
try {
|
|
@@ -1868,11 +1879,11 @@ var require_liquid_node = __commonJS({
|
|
|
1868
1879
|
__proto__: null,
|
|
1869
1880
|
exists,
|
|
1870
1881
|
readFile,
|
|
1871
|
-
existsSync:
|
|
1872
|
-
readFileSync:
|
|
1882
|
+
existsSync: existsSync10,
|
|
1883
|
+
readFileSync: readFileSync5,
|
|
1873
1884
|
resolve: resolve2,
|
|
1874
1885
|
fallback,
|
|
1875
|
-
dirname:
|
|
1886
|
+
dirname: dirname3,
|
|
1876
1887
|
contains,
|
|
1877
1888
|
containsSync,
|
|
1878
1889
|
sep: path.sep
|
|
@@ -3597,7 +3608,7 @@ var require_liquid_node = __commonJS({
|
|
|
3597
3608
|
uri_escape,
|
|
3598
3609
|
slugify
|
|
3599
3610
|
});
|
|
3600
|
-
var
|
|
3611
|
+
var join5 = argumentsToValue(function(v, arg) {
|
|
3601
3612
|
const array2 = toArray(v);
|
|
3602
3613
|
const sep = isNil(arg) ? " " : stringify(arg);
|
|
3603
3614
|
let outputSize = sep.length * Math.max(array2.length - 1, 0);
|
|
@@ -3873,7 +3884,7 @@ var require_liquid_node = __commonJS({
|
|
|
3873
3884
|
__name(sample, "sample");
|
|
3874
3885
|
var arrayFilters = /* @__PURE__ */ Object.freeze({
|
|
3875
3886
|
__proto__: null,
|
|
3876
|
-
join:
|
|
3887
|
+
join: join5,
|
|
3877
3888
|
last,
|
|
3878
3889
|
first,
|
|
3879
3890
|
reverse,
|
|
@@ -4801,15 +4812,15 @@ var require_liquid_node = __commonJS({
|
|
|
4801
4812
|
}
|
|
4802
4813
|
*render(ctx, emitter) {
|
|
4803
4814
|
const group = yield evalToken(this.group, ctx);
|
|
4804
|
-
const
|
|
4815
|
+
const fingerprint2 = `cycle:${group}:` + this.candidates.join(",");
|
|
4805
4816
|
const groups = ctx.getRegister("cycle", {});
|
|
4806
|
-
let idx = groups[
|
|
4817
|
+
let idx = groups[fingerprint2];
|
|
4807
4818
|
if (idx === void 0) {
|
|
4808
|
-
idx = groups[
|
|
4819
|
+
idx = groups[fingerprint2] = 0;
|
|
4809
4820
|
}
|
|
4810
4821
|
const candidate = this.candidates[idx];
|
|
4811
4822
|
idx = (idx + 1) % this.candidates.length;
|
|
4812
|
-
groups[
|
|
4823
|
+
groups[fingerprint2] = idx;
|
|
4813
4824
|
return yield evalToken(candidate, ctx);
|
|
4814
4825
|
}
|
|
4815
4826
|
*arguments() {
|
|
@@ -5497,11 +5508,11 @@ var require_liquid_node = __commonJS({
|
|
|
5497
5508
|
}
|
|
5498
5509
|
});
|
|
5499
5510
|
|
|
5500
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5501
|
-
import { chmodSync, constants, copyFileSync, existsSync as
|
|
5502
|
-
import { dirname, resolve } from "node:path";
|
|
5511
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
|
|
5512
|
+
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";
|
|
5513
|
+
import { dirname as dirname2, resolve } from "node:path";
|
|
5503
5514
|
|
|
5504
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5515
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/sealed.js
|
|
5505
5516
|
import { createCipheriv, createDecipheriv, createHash, randomBytes, scrypt, timingSafeEqual } from "node:crypto";
|
|
5506
5517
|
import { closeSync, createReadStream, createWriteStream, existsSync, openSync, readSync, renameSync, rmSync, statSync } from "node:fs";
|
|
5507
5518
|
import { Transform } from "node:stream";
|
|
@@ -5608,7 +5619,7 @@ var unsealFile = /* @__PURE__ */ __name(async (from, to, password) => {
|
|
|
5608
5619
|
renameSync(pending, to);
|
|
5609
5620
|
}, "unsealFile");
|
|
5610
5621
|
|
|
5611
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5622
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/store/compatibility.js
|
|
5612
5623
|
var SPEAKS = MIGRATIONS.at(-1)?.version ?? 0;
|
|
5613
5624
|
var fileSchemaOf = /* @__PURE__ */ __name((database) => {
|
|
5614
5625
|
const tracked = database.prepare("SELECT 1 FROM sqlite_master WHERE name = 'schema_migrations'").get();
|
|
@@ -5632,7 +5643,7 @@ var compatibilityOf = /* @__PURE__ */ __name((file2, migrations = MIGRATIONS) =>
|
|
|
5632
5643
|
};
|
|
5633
5644
|
}, "compatibilityOf");
|
|
5634
5645
|
|
|
5635
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5646
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/store/repair.js
|
|
5636
5647
|
import { createHash as createHash2 } from "node:crypto";
|
|
5637
5648
|
var COPY_MARK = "__repair_";
|
|
5638
5649
|
var COPY_NAME = /__repair_[0-9a-f]{8}(_\d+)?$/;
|
|
@@ -5886,10 +5897,457 @@ var deleteCopy = /* @__PURE__ */ __name((database, name) => {
|
|
|
5886
5897
|
return found;
|
|
5887
5898
|
}, "deleteCopy");
|
|
5888
5899
|
|
|
5889
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5890
|
-
import { existsSync as
|
|
5900
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/store-info.js
|
|
5901
|
+
import { existsSync as existsSync4, statSync as statSync3 } from "node:fs";
|
|
5902
|
+
|
|
5903
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/store-recover.js
|
|
5904
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
5905
|
+
|
|
5906
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/store/recover.js
|
|
5907
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
5908
|
+
import { existsSync as existsSync2, readFileSync, realpathSync, renameSync as renameSync2, rmSync as rmSync2, statfsSync, statSync as statSync2, writeFileSync } from "node:fs";
|
|
5909
|
+
import { basename, dirname, join } from "node:path";
|
|
5910
|
+
import { Transform as Transform2 } from "node:stream";
|
|
5911
|
+
var SQLITE3_MINIMUM = [3, 43, 0];
|
|
5912
|
+
var STORE_PARTS = ["", "-wal", "-shm"];
|
|
5913
|
+
var INSERTED = /^INSERT OR IGNORE INTO '([^']+)'/;
|
|
5914
|
+
var LOST_AND_FOUND = "recover_lost_and_found";
|
|
5915
|
+
var recovers = /* @__PURE__ */ __name((program) => {
|
|
5916
|
+
try {
|
|
5917
|
+
execFileSync(program, [":memory:", ".recover"], { stdio: ["ignore", "ignore", "pipe"] });
|
|
5918
|
+
return true;
|
|
5919
|
+
} catch {
|
|
5920
|
+
return false;
|
|
5921
|
+
}
|
|
5922
|
+
}, "recovers");
|
|
5923
|
+
var sqlite3Program = /* @__PURE__ */ __name((program = "sqlite3") => {
|
|
5924
|
+
let version = null;
|
|
5925
|
+
try {
|
|
5926
|
+
version = execFileSync(program, ["--version"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).split(" ")[0] ?? null;
|
|
5927
|
+
} catch {
|
|
5928
|
+
return { program, version: null, usable: false };
|
|
5929
|
+
}
|
|
5930
|
+
const parts2 = (version ?? "").split(".").map(Number);
|
|
5931
|
+
const at = SQLITE3_MINIMUM.findIndex((wanted, i) => (parts2[i] ?? 0) !== wanted);
|
|
5932
|
+
const recent = at === -1 || (parts2[at] ?? 0) > (SQLITE3_MINIMUM[at] ?? 0);
|
|
5933
|
+
return { program, version, usable: recent && recovers(program) };
|
|
5934
|
+
}, "sqlite3Program");
|
|
5935
|
+
var activeTimers = /* @__PURE__ */ __name(() => {
|
|
5936
|
+
if (process.platform !== "linux")
|
|
5937
|
+
return void 0;
|
|
5938
|
+
try {
|
|
5939
|
+
return execFileSync("systemctl", ["--user", "list-timers", "--plain", "--no-legend"], {
|
|
5940
|
+
encoding: "utf8",
|
|
5941
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5942
|
+
}).split("\n").map((line) => line.trim().split(/\s+/).at(-2) ?? "").filter((unit) => /^(memo|mail|tg|max|whatsapp|zoom|drive|gcal|wirecat)-.*\.timer$/.test(unit));
|
|
5943
|
+
} catch {
|
|
5944
|
+
return void 0;
|
|
5945
|
+
}
|
|
5946
|
+
}, "activeTimers");
|
|
5947
|
+
var storeHolders = /* @__PURE__ */ __name((path) => {
|
|
5948
|
+
const folder = realpathSync(dirname(path));
|
|
5949
|
+
const files = STORE_PARTS.map((suffix) => join(folder, `${basename(path)}${suffix}`));
|
|
5950
|
+
const wanted = process.platform === "linux" ? files.flatMap((file2) => [file2, `${file2} (deleted)`]) : files.filter(existsSync2);
|
|
5951
|
+
return holdersOf(wanted)?.map((pid) => {
|
|
5952
|
+
let name = "?";
|
|
5953
|
+
try {
|
|
5954
|
+
name = readFileSync(`/proc/${pid}/comm`, "utf8").trim();
|
|
5955
|
+
} catch {
|
|
5956
|
+
}
|
|
5957
|
+
return { pid, name };
|
|
5958
|
+
});
|
|
5959
|
+
}, "storeHolders");
|
|
5960
|
+
var tableRows = /* @__PURE__ */ __name((database) => {
|
|
5961
|
+
const indexes = fts5Tables(database).map((index) => index.name);
|
|
5962
|
+
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}_`)));
|
|
5963
|
+
return Object.fromEntries(tables.map((table) => {
|
|
5964
|
+
try {
|
|
5965
|
+
return [table, Number(database.prepare(`SELECT count(*) AS n FROM "${table}"`).get()?.n)];
|
|
5966
|
+
} catch {
|
|
5967
|
+
return [table, null];
|
|
5968
|
+
}
|
|
5969
|
+
}));
|
|
5970
|
+
}, "tableRows");
|
|
5971
|
+
var copyReadableRows = /* @__PURE__ */ __name((path, target, program = "sqlite3") => new Promise((resolve2, reject) => {
|
|
5972
|
+
const reader = spawn(program, ["-readonly", path, `.recover --ignore-freelist --lost-and-found ${LOST_AND_FOUND}`], {
|
|
5973
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
5974
|
+
});
|
|
5975
|
+
const writer = spawn(program, ["-cmd", ".dbconfig defensive off", target], { stdio: ["pipe", "ignore", "pipe"] });
|
|
5976
|
+
const errors = [];
|
|
5977
|
+
const collect = /* @__PURE__ */ __name((chunk) => {
|
|
5978
|
+
for (const line of chunk.toString("utf8").split("\n"))
|
|
5979
|
+
if (line && errors.length < 50)
|
|
5980
|
+
errors.push(line.slice(0, 300));
|
|
5981
|
+
}, "collect");
|
|
5982
|
+
reader.stderr.on("data", collect);
|
|
5983
|
+
writer.stderr.on("data", collect);
|
|
5984
|
+
const read = {};
|
|
5985
|
+
let rest = "";
|
|
5986
|
+
const counter = new Transform2({
|
|
5987
|
+
transform(chunk, _encoding, done) {
|
|
5988
|
+
const lines = (rest + chunk.toString("latin1")).split("\n");
|
|
5989
|
+
rest = lines.pop() ?? "";
|
|
5990
|
+
for (const line of lines) {
|
|
5991
|
+
const table = INSERTED.exec(line)?.[1];
|
|
5992
|
+
if (table)
|
|
5993
|
+
read[table] = (read[table] ?? 0) + 1;
|
|
5994
|
+
}
|
|
5995
|
+
done(null, chunk);
|
|
5996
|
+
}
|
|
5997
|
+
});
|
|
5998
|
+
reader.stdout.pipe(counter).pipe(writer.stdin);
|
|
5999
|
+
let exits = 0;
|
|
6000
|
+
let readerCode = null;
|
|
6001
|
+
const exited = /* @__PURE__ */ __name(() => {
|
|
6002
|
+
exits += 1;
|
|
6003
|
+
if (exits < 2)
|
|
6004
|
+
return;
|
|
6005
|
+
if (readerCode !== 0)
|
|
6006
|
+
reject(new CliError("validation_error", `sqlite3 could not read the store: ${errors.join("; ")}`));
|
|
6007
|
+
else
|
|
6008
|
+
resolve2({ errors, read });
|
|
6009
|
+
}, "exited");
|
|
6010
|
+
reader.on("error", reject);
|
|
6011
|
+
writer.on("error", reject);
|
|
6012
|
+
reader.on("close", (code) => {
|
|
6013
|
+
readerCode = code;
|
|
6014
|
+
exited();
|
|
6015
|
+
});
|
|
6016
|
+
writer.on("close", exited);
|
|
6017
|
+
}), "copyReadableRows");
|
|
6018
|
+
var FILLERS = {
|
|
6019
|
+
message_words: /* @__PURE__ */ __name((database, now) => {
|
|
6020
|
+
resetSearchIndex(database);
|
|
6021
|
+
fillSearchIndex(database, { now });
|
|
6022
|
+
}, "message_words"),
|
|
6023
|
+
message_stems: /* @__PURE__ */ __name((database, now) => {
|
|
6024
|
+
resetStems(database, { force: true, now });
|
|
6025
|
+
fillStems(database, { now });
|
|
6026
|
+
}, "message_stems"),
|
|
6027
|
+
attachment_words: /* @__PURE__ */ __name((database) => void resetAttachmentWords(database), "attachment_words"),
|
|
6028
|
+
attachment_name_words: /* @__PURE__ */ __name((database) => (
|
|
6029
|
+
// As migration 20 filled it: й and ё fold as the triggers fold them.
|
|
6030
|
+
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")
|
|
6031
|
+
), "attachment_name_words"),
|
|
6032
|
+
meeting_words: /* @__PURE__ */ __name((database) => {
|
|
6033
|
+
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");
|
|
6034
|
+
drainMeetingIndex(database);
|
|
6035
|
+
}, "meeting_words"),
|
|
6036
|
+
// Built per account by the first search that needs them.
|
|
6037
|
+
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")
|
|
6038
|
+
};
|
|
6039
|
+
var CORPUS_TABLES = new Set(Object.values(CORPORA).flatMap((corpus) => [`${corpus.type}_words`, `${corpus.type}_stems`]));
|
|
6040
|
+
var TRIGRAMS = ["note_trigrams", "document_trigrams"];
|
|
6041
|
+
var rebuildDerived = /* @__PURE__ */ __name((database, { now = Date.now, note = /* @__PURE__ */ __name(() => {
|
|
6042
|
+
}, "note") } = {}) => {
|
|
6043
|
+
const lost = database.prepare("SELECT 1 FROM sqlite_master WHERE name = ?").get(LOST_AND_FOUND);
|
|
6044
|
+
const lostAndFound = lost ? Number(database.prepare(`SELECT count(*) AS n FROM ${LOST_AND_FOUND}`).get()?.n) : 0;
|
|
6045
|
+
if (lost)
|
|
6046
|
+
database.exec(`DROP TABLE ${LOST_AND_FOUND}`);
|
|
6047
|
+
const indexes = fts5Tables(database);
|
|
6048
|
+
for (const { name, sql } of indexes) {
|
|
6049
|
+
database.exec(`DROP TABLE "${name}"`);
|
|
6050
|
+
database.exec(sql);
|
|
6051
|
+
}
|
|
6052
|
+
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));
|
|
6053
|
+
for (const table of vectors) {
|
|
6054
|
+
database.exec(`DROP TRIGGER IF EXISTS "${table}_redo"`);
|
|
6055
|
+
database.exec(`DROP TABLE "${table}"`);
|
|
6056
|
+
database.prepare("DELETE FROM vector_indexes WHERE id = ?").run(Number(table.replace("vector_index_", "")));
|
|
6057
|
+
}
|
|
6058
|
+
const unfilled = [];
|
|
6059
|
+
const stemmerFor = stemmerCache();
|
|
6060
|
+
for (const { name, external } of indexes) {
|
|
6061
|
+
note(`rebuilding ${name}`);
|
|
6062
|
+
if (external)
|
|
6063
|
+
database.exec(`INSERT INTO "${name}" ("${name}") VALUES ('rebuild')`);
|
|
6064
|
+
else if (FILLERS[name])
|
|
6065
|
+
FILLERS[name](database, now);
|
|
6066
|
+
else if (!CORPUS_TABLES.has(name) && !TRIGRAMS.includes(name))
|
|
6067
|
+
unfilled.push(name);
|
|
6068
|
+
}
|
|
6069
|
+
note("rebuilding the words of notes, documents, memories, mail, tasks, transcripts and events");
|
|
6070
|
+
resetNoteIndex(database);
|
|
6071
|
+
for (const corpus of Object.values(CORPORA))
|
|
6072
|
+
drainCorpus(database, corpus, stemmerFor);
|
|
6073
|
+
for (const name of TRIGRAMS) {
|
|
6074
|
+
const type = name.replace("_trigrams", "");
|
|
6075
|
+
database.prepare(`UPDATE search_index_state SET filled_through = 0, watermark = (SELECT coalesce(max(id), 0) FROM ${type}s) WHERE name = ?`).run(name);
|
|
6076
|
+
}
|
|
6077
|
+
fillTrigrams(database);
|
|
6078
|
+
note("finding mentions again");
|
|
6079
|
+
const mentions = rebuildMentions(database, { now: now() }).mentions;
|
|
6080
|
+
involvementStoreOver({ database, now }).rebuild();
|
|
6081
|
+
note("indexing the stored vectors");
|
|
6082
|
+
const vectorModels = fillVectorIndexes(database);
|
|
6083
|
+
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)");
|
|
6084
|
+
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)]));
|
|
6085
|
+
return {
|
|
6086
|
+
lostAndFound,
|
|
6087
|
+
searchIndexes: indexes.map((index) => index.name),
|
|
6088
|
+
unfilled,
|
|
6089
|
+
mentions,
|
|
6090
|
+
vectorModels,
|
|
6091
|
+
chunksWithoutVector
|
|
6092
|
+
};
|
|
6093
|
+
}, "rebuildDerived");
|
|
6094
|
+
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) => {
|
|
6095
|
+
const child = String(group.child);
|
|
6096
|
+
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;
|
|
6097
|
+
let missing = [];
|
|
6098
|
+
try {
|
|
6099
|
+
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));
|
|
6100
|
+
} catch {
|
|
6101
|
+
}
|
|
6102
|
+
return { table: child, parent: String(group.parent), rows: Number(group.n), missing };
|
|
6103
|
+
}), "danglingRows");
|
|
6104
|
+
var mailToFetch = /* @__PURE__ */ __name((database) => {
|
|
6105
|
+
try {
|
|
6106
|
+
return database.prepare(`SELECT a.external_id AS account, count(DISTINCT l.email_id) AS n FROM email_locations l
|
|
6107
|
+
JOIN mailboxes b ON b.id = l.mailbox_id JOIN accounts a ON a.id = b.account_id
|
|
6108
|
+
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) }));
|
|
6109
|
+
} catch {
|
|
6110
|
+
return [];
|
|
6111
|
+
}
|
|
6112
|
+
}, "mailToFetch");
|
|
6113
|
+
var fingerprint = /* @__PURE__ */ __name((path) => ["", "-wal"].map((suffix) => {
|
|
6114
|
+
const stat = statSync2(`${path}${suffix}`, { throwIfNoEntry: false });
|
|
6115
|
+
return stat ? `${stat.size}:${stat.mtimeMs}` : "-";
|
|
6116
|
+
}).join("|"), "fingerprint");
|
|
6117
|
+
var refuseInUse = /* @__PURE__ */ __name((path) => {
|
|
6118
|
+
const holders = storeHolders(path);
|
|
6119
|
+
if (holders && holders.length > 0) {
|
|
6120
|
+
const timers = activeTimers() ?? [];
|
|
6121
|
+
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" });
|
|
6122
|
+
}
|
|
6123
|
+
}, "refuseInUse");
|
|
6124
|
+
var recoverStore = /* @__PURE__ */ __name(async ({ path, command, version, sqlite3 = "sqlite3", now = Date.now, note = /* @__PURE__ */ __name(() => {
|
|
6125
|
+
}, "note"), copy }) => {
|
|
6126
|
+
const started = Date.now();
|
|
6127
|
+
if (!existsSync2(path))
|
|
6128
|
+
throw new CliError("not_found", `no store at ${path}`);
|
|
6129
|
+
const program = copy ? { program: sqlite3, version: "given", usable: true } : sqlite3Program(sqlite3);
|
|
6130
|
+
if (!program.usable) {
|
|
6131
|
+
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" });
|
|
6132
|
+
}
|
|
6133
|
+
refuseInUse(path);
|
|
6134
|
+
const bytes = STORE_PARTS.reduce((sum, suffix) => sum + (statSync2(`${path}${suffix}`, { throwIfNoEntry: false })?.size ?? 0), 0);
|
|
6135
|
+
const { bavail, bsize } = statfsSync(dirname(path));
|
|
6136
|
+
if (Number(bavail) * Number(bsize) < bytes * 1.2)
|
|
6137
|
+
throw new CliError("validation_error", `the recovery needs about ${Math.ceil(bytes * 1.2 / 1e9)} GB free beside the store`);
|
|
6138
|
+
const old = await openSqlite(path, { readOnly: true });
|
|
6139
|
+
let rowsBefore;
|
|
6140
|
+
try {
|
|
6141
|
+
rowsBefore = tableRows(old.database);
|
|
6142
|
+
} finally {
|
|
6143
|
+
old.database.close();
|
|
6144
|
+
}
|
|
6145
|
+
const before = fingerprint(path);
|
|
6146
|
+
const stamp = new Date(now()).toISOString().replace(/[:.]/g, "-");
|
|
6147
|
+
const target = `${path}.recovering-${stamp}`;
|
|
6148
|
+
writeFileSync(target, "", { flag: "wx", mode: 384 });
|
|
6149
|
+
const dropTarget = /* @__PURE__ */ __name(() => {
|
|
6150
|
+
for (const suffix of [...STORE_PARTS, "-journal"])
|
|
6151
|
+
rmSync2(`${target}${suffix}`, { force: true });
|
|
6152
|
+
}, "dropTarget");
|
|
6153
|
+
note(`copying the readable rows into ${target}`);
|
|
6154
|
+
let copied;
|
|
6155
|
+
let copyErrors;
|
|
6156
|
+
let read;
|
|
6157
|
+
let opened;
|
|
6158
|
+
try {
|
|
6159
|
+
;
|
|
6160
|
+
({ errors: copyErrors, read } = await (copy ?? ((from, to) => copyReadableRows(from, to, sqlite3)))(path, target));
|
|
6161
|
+
copied = Date.now();
|
|
6162
|
+
opened = await openSqlite(target);
|
|
6163
|
+
} catch (error) {
|
|
6164
|
+
dropTarget();
|
|
6165
|
+
throw error;
|
|
6166
|
+
}
|
|
6167
|
+
let rebuilt;
|
|
6168
|
+
let kept;
|
|
6169
|
+
let dangling;
|
|
6170
|
+
let fetch2;
|
|
6171
|
+
try {
|
|
6172
|
+
kept = tableRows(opened.database);
|
|
6173
|
+
migrate(opened.database, { command, ...version ? { version } : {} });
|
|
6174
|
+
rebuilt = rebuildDerived(opened.database, { now, note });
|
|
6175
|
+
note("looking for rows that point at rows that were lost");
|
|
6176
|
+
dangling = danglingRows(opened.database);
|
|
6177
|
+
fetch2 = mailToFetch(opened.database);
|
|
6178
|
+
opened.database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
6179
|
+
} catch (error) {
|
|
6180
|
+
opened.database.close();
|
|
6181
|
+
dropTarget();
|
|
6182
|
+
throw error;
|
|
6183
|
+
}
|
|
6184
|
+
opened.database.close();
|
|
6185
|
+
const rebuiltAt = Date.now();
|
|
6186
|
+
note("checking the recovered file");
|
|
6187
|
+
const health = await storeHealth(target, { deep: true });
|
|
6188
|
+
const checkedAt = Date.now();
|
|
6189
|
+
if (!health.ok) {
|
|
6190
|
+
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" });
|
|
6191
|
+
}
|
|
6192
|
+
refuseInUse(path);
|
|
6193
|
+
if (fingerprint(path) !== before) {
|
|
6194
|
+
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" });
|
|
6195
|
+
}
|
|
6196
|
+
const keptAt = `${path}.before-recover-${stamp}`;
|
|
6197
|
+
for (const suffix of STORE_PARTS)
|
|
6198
|
+
if (existsSync2(`${path}${suffix}`))
|
|
6199
|
+
renameSync2(`${path}${suffix}`, `${keptAt}${suffix}`);
|
|
6200
|
+
for (const suffix of STORE_PARTS)
|
|
6201
|
+
if (existsSync2(`${target}${suffix}`))
|
|
6202
|
+
renameSync2(`${target}${suffix}`, `${path}${suffix}`);
|
|
6203
|
+
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);
|
|
6204
|
+
const seconds = /* @__PURE__ */ __name((from, to) => Math.round((to - from) / 100) / 10, "seconds");
|
|
6205
|
+
return {
|
|
6206
|
+
path,
|
|
6207
|
+
keptAt,
|
|
6208
|
+
sqlite3: program.version,
|
|
6209
|
+
lost,
|
|
6210
|
+
dangling,
|
|
6211
|
+
mailToFetch: fetch2,
|
|
6212
|
+
rebuilt,
|
|
6213
|
+
copyErrors,
|
|
6214
|
+
health,
|
|
6215
|
+
seconds: {
|
|
6216
|
+
copy: seconds(started, copied),
|
|
6217
|
+
rebuild: seconds(copied, rebuiltAt),
|
|
6218
|
+
check: seconds(rebuiltAt, checkedAt),
|
|
6219
|
+
total: seconds(started, Date.now())
|
|
6220
|
+
}
|
|
6221
|
+
};
|
|
6222
|
+
}, "recoverStore");
|
|
6223
|
+
|
|
6224
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/store-recover.js
|
|
6225
|
+
var COUNTED = [
|
|
6226
|
+
"accounts",
|
|
6227
|
+
"chats",
|
|
6228
|
+
"messages",
|
|
6229
|
+
"attachments",
|
|
6230
|
+
"emails",
|
|
6231
|
+
"documents",
|
|
6232
|
+
"notes",
|
|
6233
|
+
"meetings",
|
|
6234
|
+
"chunks",
|
|
6235
|
+
"embeddings",
|
|
6236
|
+
"mentions"
|
|
6237
|
+
];
|
|
6238
|
+
var stopTimers = /* @__PURE__ */ __name((timers) => `systemctl --user stop ${timers.join(" ")}`, "stopTimers");
|
|
6239
|
+
var storeRecoveryCheck = /* @__PURE__ */ __name(async (env, command) => {
|
|
6240
|
+
const path = storePath(env);
|
|
6241
|
+
if (!existsSync3(path))
|
|
6242
|
+
return { path, exists: false, ok: true, next: [] };
|
|
6243
|
+
const health = await storeHealth(path, { deep: true });
|
|
6244
|
+
let rows = {};
|
|
6245
|
+
try {
|
|
6246
|
+
const { database } = await openSqlite(path, { readOnly: true });
|
|
6247
|
+
try {
|
|
6248
|
+
const all = tableRows(database);
|
|
6249
|
+
rows = Object.fromEntries(COUNTED.filter((table) => table in all).map((table) => [table, all[table] ?? null]));
|
|
6250
|
+
} finally {
|
|
6251
|
+
database.close();
|
|
6252
|
+
}
|
|
6253
|
+
} catch {
|
|
6254
|
+
}
|
|
6255
|
+
const explanation = explainDamage(health, command);
|
|
6256
|
+
const inUse = storeHolders(path) ?? null;
|
|
6257
|
+
const timers = activeTimers() ?? null;
|
|
6258
|
+
const sqlite3 = sqlite3Program();
|
|
6259
|
+
const next = health.ok ? [] : [
|
|
6260
|
+
...timers?.length ? [stopTimers(timers)] : [],
|
|
6261
|
+
...(inUse ?? []).map(({ pid, name }) => `stop ${name} (process ${pid}): it has the store open`),
|
|
6262
|
+
...sqlite3.usable ? [] : ["install sqlite3 3.43 or newer (apt install sqlite3, brew install sqlite)"],
|
|
6263
|
+
`${command} store recover run`
|
|
6264
|
+
];
|
|
6265
|
+
return {
|
|
6266
|
+
path,
|
|
6267
|
+
exists: true,
|
|
6268
|
+
ok: health.ok,
|
|
6269
|
+
seconds: Math.round(health.ms / 100) / 10,
|
|
6270
|
+
problems: health.problems ?? 0,
|
|
6271
|
+
damagedTables: health.damagedTables ?? [],
|
|
6272
|
+
damagedSearchIndexes: (health.searchIndexes ?? []).filter((index) => !index.ok).map(({ name, error }) => ({ name, ...error ? { error } : {} })),
|
|
6273
|
+
rows,
|
|
6274
|
+
explanation,
|
|
6275
|
+
inUse,
|
|
6276
|
+
timers,
|
|
6277
|
+
sqlite3: { version: sqlite3.version, usable: sqlite3.usable },
|
|
6278
|
+
next
|
|
6279
|
+
};
|
|
6280
|
+
}, "storeRecoveryCheck");
|
|
6281
|
+
var storeRecoveryRun = /* @__PURE__ */ __name(async (env, { command, version, note, timers: scheduled = activeTimers, copy }) => {
|
|
6282
|
+
const timers = scheduled() ?? [];
|
|
6283
|
+
if (timers.length > 0)
|
|
6284
|
+
throw new CliError("validation_error", `stop the timers first, they open the store: ${stopTimers(timers)}`, {
|
|
6285
|
+
reason: "store.in-use"
|
|
6286
|
+
});
|
|
6287
|
+
const recovery = await recoverStore({
|
|
6288
|
+
path: storePath(env),
|
|
6289
|
+
command,
|
|
6290
|
+
...version ? { version } : {},
|
|
6291
|
+
...note ? { note } : {},
|
|
6292
|
+
...copy ? { copy } : {}
|
|
6293
|
+
});
|
|
6294
|
+
const mail = recovery.mailToFetch.map(({ account, emails }) => `mail <profile of ${account}> sync --rescan # ${emails} emails`);
|
|
6295
|
+
const lostMail = recovery.lost.some(({ table }) => table === "emails") && mail.length === 0 ? ["mail <profile> sync --rescan # each mail profile"] : [];
|
|
6296
|
+
const { health, copyErrors, ...kept } = recovery;
|
|
6297
|
+
return {
|
|
6298
|
+
...kept,
|
|
6299
|
+
copyErrors: copyErrors.length,
|
|
6300
|
+
checkedOk: health.ok,
|
|
6301
|
+
next: [...mail, ...lostMail, "systemctl --user start <the timers stopped before>"]
|
|
6302
|
+
};
|
|
6303
|
+
}, "storeRecoveryRun");
|
|
6304
|
+
var recoveryNotes = /* @__PURE__ */ __name((answer) => {
|
|
6305
|
+
if ("keptAt" in answer) {
|
|
6306
|
+
const lost = answer.lost.map(({ table, before, read, kept }) => `${table}: ${kept} kept of ${before ?? "an uncountable number"}${read > kept ? `, ${read - kept} read but unusable` : ""}`);
|
|
6307
|
+
return [
|
|
6308
|
+
`recovered in ${answer.seconds.total} s; the damaged file is kept at ${answer.keptAt}`,
|
|
6309
|
+
...lost.length ? lost : ["no table lost a row"],
|
|
6310
|
+
...answer.dangling.map(({ table, parent, rows }) => `${rows} rows of ${table} point at ${parent} rows the store does not hold`),
|
|
6311
|
+
...answer.next.map((line) => `next: ${line}`)
|
|
6312
|
+
];
|
|
6313
|
+
}
|
|
6314
|
+
if (!answer.exists)
|
|
6315
|
+
return ["no store yet"];
|
|
6316
|
+
if (answer.ok)
|
|
6317
|
+
return [`the store is healthy (checked every page and search index in ${answer.seconds} s)`];
|
|
6318
|
+
const why = answer.explanation;
|
|
6319
|
+
return [
|
|
6320
|
+
...why ? [why.what, ...why.impact, why.externalUnaffected] : [],
|
|
6321
|
+
...answer.next.map((line) => `next: ${line}`)
|
|
6322
|
+
];
|
|
6323
|
+
}, "recoveryNotes");
|
|
6324
|
+
var storeRecoverCommand = /* @__PURE__ */ __name(({ command, version }) => {
|
|
6325
|
+
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() {
|
|
6326
|
+
const output = outputFor(this);
|
|
6327
|
+
const answer = await storeRecoveryCheck(environmentOf(this).env ?? process.env, command);
|
|
6328
|
+
renderAnswer(this, output, itemOf(snakeKeys(answer)));
|
|
6329
|
+
if (output.format === "pretty")
|
|
6330
|
+
for (const line of recoveryNotes(answer))
|
|
6331
|
+
output.renderer.note(line);
|
|
6332
|
+
});
|
|
6333
|
+
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() {
|
|
6334
|
+
const output = outputFor(this);
|
|
6335
|
+
const answer = await storeRecoveryRun(environmentOf(this).env ?? process.env, {
|
|
6336
|
+
command,
|
|
6337
|
+
...version ? { version } : {},
|
|
6338
|
+
note: /* @__PURE__ */ __name((text) => output.renderer.note(text), "note")
|
|
6339
|
+
});
|
|
6340
|
+
renderAnswer(this, output, itemOf(snakeKeys(answer)));
|
|
6341
|
+
if (output.format === "pretty")
|
|
6342
|
+
for (const line of recoveryNotes(answer))
|
|
6343
|
+
output.renderer.note(line);
|
|
6344
|
+
}));
|
|
6345
|
+
return recover;
|
|
6346
|
+
}, "storeRecoverCommand");
|
|
6347
|
+
|
|
6348
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/store-info.js
|
|
5891
6349
|
var pendingIfKnown = /* @__PURE__ */ __name((database) => database.prepare("SELECT 1 FROM pragma_table_info('messages') WHERE name = 'normalized_text'").get() ? pendingNormalization(database) : null, "pendingIfKnown");
|
|
5892
|
-
var bytesOf = /* @__PURE__ */ __name((path) =>
|
|
6350
|
+
var bytesOf = /* @__PURE__ */ __name((path) => existsSync4(path) ? statSync3(path).size : 0, "bytesOf");
|
|
5893
6351
|
var messageOf = /* @__PURE__ */ __name((error) => error instanceof Error ? error.message : String(error), "messageOf");
|
|
5894
6352
|
var contentsOf = /* @__PURE__ */ __name((database, version, writable) => version > 0 && writable ? {
|
|
5895
6353
|
rows: rowCounts(database),
|
|
@@ -5900,7 +6358,7 @@ var contentsOf = /* @__PURE__ */ __name((database, version, writable) => version
|
|
|
5900
6358
|
} : { rows: {}, pendingNormalization: null, wordIndex: null, stemIndex: null }, "contentsOf");
|
|
5901
6359
|
var storeInfo = /* @__PURE__ */ __name(async (env) => {
|
|
5902
6360
|
const path = storePath(env);
|
|
5903
|
-
if (!
|
|
6361
|
+
if (!existsSync4(path))
|
|
5904
6362
|
return snakeKeys({ path, exists: false, schema: compatibilityOf(void 0) });
|
|
5905
6363
|
let schema = compatibilityOf(void 0);
|
|
5906
6364
|
try {
|
|
@@ -5933,7 +6391,7 @@ var storeInfoCommand = /* @__PURE__ */ __name(() => annotate(new Command("info")
|
|
|
5933
6391
|
renderAnswer(this, outputFor(this), itemOf(answer));
|
|
5934
6392
|
}), "storeInfoCommand");
|
|
5935
6393
|
|
|
5936
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
6394
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/password.js
|
|
5937
6395
|
var ENCRYPT_OPTION = [
|
|
5938
6396
|
"--encrypt",
|
|
5939
6397
|
"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"
|
|
@@ -5952,9 +6410,9 @@ var passwordOf = /* @__PURE__ */ __name(async (command, { twice }) => {
|
|
|
5952
6410
|
return password;
|
|
5953
6411
|
}, "passwordOf");
|
|
5954
6412
|
|
|
5955
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5956
|
-
import { existsSync as
|
|
5957
|
-
import { join } from "node:path";
|
|
6413
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/rules.js
|
|
6414
|
+
import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
|
|
6415
|
+
import { join as join2 } from "node:path";
|
|
5958
6416
|
var REPLY_ACTIONS = ["reply", "task"];
|
|
5959
6417
|
var REPLY_MODELS = ["fill-only", "may-reword"];
|
|
5960
6418
|
var REPLY_KINDS = ["dialog", "group"];
|
|
@@ -6040,7 +6498,7 @@ var defaultRule = /* @__PURE__ */ __name((id) => ({
|
|
|
6040
6498
|
reply: { template: "", asReply: true },
|
|
6041
6499
|
limits: { perChat: "1/1d", perPerson: "1/1d" }
|
|
6042
6500
|
}), "defaultRule");
|
|
6043
|
-
var repliesPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) =>
|
|
6501
|
+
var repliesPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join2(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies.json`), "repliesPathFor");
|
|
6044
6502
|
var EVERYONE = { reply: "all", allow: { people: [], chats: [] }, deny: { people: [], chats: [] } };
|
|
6045
6503
|
var outsideAudience = /* @__PURE__ */ __name((audience, person, chat) => {
|
|
6046
6504
|
if (person !== null && audience.deny.people.includes(person))
|
|
@@ -6070,11 +6528,11 @@ var readReplies = /* @__PURE__ */ __name((path, provider) => {
|
|
|
6070
6528
|
return parseReplies(readRepliesFile(path, provider), path, provider);
|
|
6071
6529
|
}, "readReplies");
|
|
6072
6530
|
var readRepliesFile = /* @__PURE__ */ __name((path, provider) => {
|
|
6073
|
-
if (!
|
|
6531
|
+
if (!existsSync5(path))
|
|
6074
6532
|
return { audience: structuredClone(EVERYONE), rules: [] };
|
|
6075
6533
|
let parsed;
|
|
6076
6534
|
try {
|
|
6077
|
-
parsed = JSON.parse(
|
|
6535
|
+
parsed = JSON.parse(readFileSync2(path, "utf8"));
|
|
6078
6536
|
} catch (error) {
|
|
6079
6537
|
throw broken(path, error instanceof Error ? error.message : String(error));
|
|
6080
6538
|
}
|
|
@@ -6123,9 +6581,9 @@ var problem = /* @__PURE__ */ __name((issue) => {
|
|
|
6123
6581
|
}, "problem");
|
|
6124
6582
|
var broken = /* @__PURE__ */ __name((path, why) => new CliError("configuration_error", `the reply rules ${path} cannot be read (${why}) \u2014 fix the file`), "broken");
|
|
6125
6583
|
|
|
6126
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
6127
|
-
import { existsSync as
|
|
6128
|
-
import { join as
|
|
6584
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/state.js
|
|
6585
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
|
|
6586
|
+
import { join as join3 } from "node:path";
|
|
6129
6587
|
var ANSWERED_KEPT = 1e3;
|
|
6130
6588
|
var times = record(string(), array(string()));
|
|
6131
6589
|
var stateFile = object({
|
|
@@ -6137,13 +6595,13 @@ var stateFile = object({
|
|
|
6137
6595
|
});
|
|
6138
6596
|
var emptyState = /* @__PURE__ */ __name(() => ({ paused: false, answered: [], sent: {} }), "emptyState");
|
|
6139
6597
|
var answeredKey = /* @__PURE__ */ __name((message) => `${message.chatId}:${message.id}`, "answeredKey");
|
|
6140
|
-
var repliesStatePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) =>
|
|
6598
|
+
var repliesStatePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join3(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, `${profile}.replies-state.json`), "repliesStatePathFor");
|
|
6141
6599
|
var readRepliesState = /* @__PURE__ */ __name((path) => {
|
|
6142
|
-
if (!
|
|
6600
|
+
if (!existsSync6(path))
|
|
6143
6601
|
return emptyState();
|
|
6144
6602
|
let parsed;
|
|
6145
6603
|
try {
|
|
6146
|
-
parsed = JSON.parse(
|
|
6604
|
+
parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
6147
6605
|
} catch (error) {
|
|
6148
6606
|
throw broken2(path, error instanceof Error ? error.message : String(error));
|
|
6149
6607
|
}
|
|
@@ -6176,7 +6634,7 @@ var recordReply = /* @__PURE__ */ __name((state, rule2, message, now) => {
|
|
|
6176
6634
|
}, "recordReply");
|
|
6177
6635
|
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");
|
|
6178
6636
|
|
|
6179
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
6637
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/decide.js
|
|
6180
6638
|
var skip = /* @__PURE__ */ __name((why) => ({ skip: why }), "skip");
|
|
6181
6639
|
var decide = /* @__PURE__ */ __name((rule2, incoming, state, now) => {
|
|
6182
6640
|
const { message, chat, owner, sender } = incoming;
|
|
@@ -6282,7 +6740,7 @@ var filled = /* @__PURE__ */ __name((template2, senderName) => {
|
|
|
6282
6740
|
return template2.replaceAll("{firstName}", name.split(/\s+/)[0] ?? name).replaceAll("{name}", name);
|
|
6283
6741
|
}, "filled");
|
|
6284
6742
|
|
|
6285
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
6743
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/template.js
|
|
6286
6744
|
var import_liquidjs = __toESM(require_liquid_node(), 1);
|
|
6287
6745
|
var TEMPLATE_LIMITS = {
|
|
6288
6746
|
parse: 32768,
|
|
@@ -6442,7 +6900,7 @@ var renderReplyTemplate = /* @__PURE__ */ __name(async (reply, input) => {
|
|
|
6442
6900
|
}
|
|
6443
6901
|
}, "renderReplyTemplate");
|
|
6444
6902
|
|
|
6445
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
6903
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/dry-run.js
|
|
6446
6904
|
var DRY_RUN_DAYS = 7;
|
|
6447
6905
|
var PAGE = 500;
|
|
6448
6906
|
var dryRun = /* @__PURE__ */ __name(async (store, account, rules, { since, until = Date.now(), only, audience, render }) => {
|
|
@@ -6556,7 +7014,7 @@ var storedSince = /* @__PURE__ */ __name(async (store, account, chat, since) =>
|
|
|
6556
7014
|
}
|
|
6557
7015
|
}, "storedSince");
|
|
6558
7016
|
|
|
6559
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7017
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/embeddings/keys.js
|
|
6560
7018
|
var endpointKeyName = /* @__PURE__ */ __name((baseUrl) => {
|
|
6561
7019
|
const host = new URL(baseUrl).host;
|
|
6562
7020
|
return ["openai", "anthropic"].includes(host) ? `endpoint:${host}` : host;
|
|
@@ -6587,7 +7045,7 @@ var embeddingKeys = /* @__PURE__ */ __name((app, env = process.env, keyring) =>
|
|
|
6587
7045
|
};
|
|
6588
7046
|
}, "embeddingKeys");
|
|
6589
7047
|
|
|
6590
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7048
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/models/openai.js
|
|
6591
7049
|
var options = strictObject({
|
|
6592
7050
|
temperature: range(0, 2),
|
|
6593
7051
|
top_p: range(0, 1),
|
|
@@ -6636,7 +7094,7 @@ var openai = {
|
|
|
6636
7094
|
}), "complete")
|
|
6637
7095
|
};
|
|
6638
7096
|
|
|
6639
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7097
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/models/index.js
|
|
6640
7098
|
var modelGateway = /* @__PURE__ */ __name((deps) => ({
|
|
6641
7099
|
complete: /* @__PURE__ */ __name(async (request) => {
|
|
6642
7100
|
if (deps.signal?.aborted)
|
|
@@ -6651,7 +7109,7 @@ var modelGateway = /* @__PURE__ */ __name((deps) => ({
|
|
|
6651
7109
|
if (!adapter && target.provider === "openai")
|
|
6652
7110
|
adapter = openai;
|
|
6653
7111
|
if (!adapter && target.provider === "anthropic")
|
|
6654
|
-
adapter = (await import("./anthropic-
|
|
7112
|
+
adapter = (await import("./anthropic-PTAYBCPR.js")).anthropic;
|
|
6655
7113
|
if (!adapter)
|
|
6656
7114
|
throw new CliError("validation_error", `no model adapter for ${target.provider}`);
|
|
6657
7115
|
if (request.images !== void 0 && adapter.images !== true)
|
|
@@ -6692,19 +7150,19 @@ var modelGateway = /* @__PURE__ */ __name((deps) => ({
|
|
|
6692
7150
|
}, "complete")
|
|
6693
7151
|
}), "modelGateway");
|
|
6694
7152
|
|
|
6695
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
6696
|
-
import { existsSync as
|
|
6697
|
-
import { join as
|
|
7153
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/consents.js
|
|
7154
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
7155
|
+
import { join as join4 } from "node:path";
|
|
6698
7156
|
var shape = strictObject({
|
|
6699
7157
|
provider: nullable(pipe(string(), minLength(1))),
|
|
6700
7158
|
deniedChats: array(pipe(string(), minLength(1)))
|
|
6701
7159
|
});
|
|
6702
|
-
var replyConsentPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) =>
|
|
7160
|
+
var replyConsentPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join4(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).config, `${profile}.replies-consents.json`), "replyConsentPathFor");
|
|
6703
7161
|
var readReplyConsent = /* @__PURE__ */ __name((path) => {
|
|
6704
|
-
if (!
|
|
7162
|
+
if (!existsSync7(path))
|
|
6705
7163
|
return { provider: null, deniedChats: [] };
|
|
6706
7164
|
try {
|
|
6707
|
-
return parse(shape, JSON.parse(
|
|
7165
|
+
return parse(shape, JSON.parse(readFileSync4(path, "utf8")));
|
|
6708
7166
|
} catch {
|
|
6709
7167
|
throw new CliError("configuration_error", "reply model consent is invalid; fix its file before granting consent");
|
|
6710
7168
|
}
|
|
@@ -6717,7 +7175,7 @@ var mayModelReply = /* @__PURE__ */ __name((path, provider, chat) => {
|
|
|
6717
7175
|
return consent.provider === provider && !consent.deniedChats.includes(chat);
|
|
6718
7176
|
}, "mayModelReply");
|
|
6719
7177
|
|
|
6720
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7178
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/rendering.js
|
|
6721
7179
|
var replyRenderer = /* @__PURE__ */ __name((app, profile, settings, env, warn, options2 = {
|
|
6722
7180
|
ai: true
|
|
6723
7181
|
}) => async (rule2, message, chat, now) => {
|
|
@@ -6764,7 +7222,7 @@ var replyRenderer = /* @__PURE__ */ __name((app, profile, settings, env, warn, o
|
|
|
6764
7222
|
return result2;
|
|
6765
7223
|
}, "replyRenderer");
|
|
6766
7224
|
|
|
6767
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7225
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/replies/serve.js
|
|
6768
7226
|
var NOT_ALLOWED = "replies.send is not allow";
|
|
6769
7227
|
var NO_RULES = "no rules";
|
|
6770
7228
|
var ONLY_TASK = "opened a task, sent nothing";
|
|
@@ -6857,7 +7315,7 @@ var replyTo = /* @__PURE__ */ __name(async (deps, message) => {
|
|
|
6857
7315
|
return { skip: why };
|
|
6858
7316
|
}, "replyTo");
|
|
6859
7317
|
|
|
6860
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7318
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-catch-up.js
|
|
6861
7319
|
var START_SYNC_DELAY_MS = 3e4;
|
|
6862
7320
|
var START_SYNC_BUDGET_MS = 5 * 6e4;
|
|
6863
7321
|
var START_SYNC_WINDOW_MS = 7 * 864e5;
|
|
@@ -6934,7 +7392,7 @@ var startSync = /* @__PURE__ */ __name(({ chats, newestHeld, fetch: fetch2, note
|
|
|
6934
7392
|
};
|
|
6935
7393
|
}, "startSync");
|
|
6936
7394
|
|
|
6937
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7395
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-members.js
|
|
6938
7396
|
var FIRST_FETCH_MS = 6e4;
|
|
6939
7397
|
var DAY_MS = 864e5;
|
|
6940
7398
|
var memberFetches = /* @__PURE__ */ __name(({ withStore, fetch: fetch2, warn, firstMs = FIRST_FETCH_MS, everyMs = DAY_MS }) => {
|
|
@@ -6988,7 +7446,7 @@ var memberFetches = /* @__PURE__ */ __name(({ withStore, fetch: fetch2, warn, fi
|
|
|
6988
7446
|
};
|
|
6989
7447
|
}, "memberFetches");
|
|
6990
7448
|
|
|
6991
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7449
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-notice.js
|
|
6992
7450
|
var record2 = /* @__PURE__ */ __name((context, app, severity, attributes) => recordLogFor(context.streams.diagnostic, app, { command: currentRun().command || "serve" })[severity](attributes), "record");
|
|
6993
7451
|
var noticeFor = /* @__PURE__ */ __name((context, app, severity = "warn") => ({ text, ...attributes }) => {
|
|
6994
7452
|
if (context.format === "pretty") {
|
|
@@ -7021,7 +7479,7 @@ var recordDiagnostics = /* @__PURE__ */ __name((context, app) => {
|
|
|
7021
7479
|
return context;
|
|
7022
7480
|
}, "recordDiagnostics");
|
|
7023
7481
|
|
|
7024
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7482
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-stems.js
|
|
7025
7483
|
var STEMS_EVERY_MS = 3e4;
|
|
7026
7484
|
var STEMS_SLICE_MS = 2e3;
|
|
7027
7485
|
var stemFills = /* @__PURE__ */ __name(({ withStore, warn, everyMs = STEMS_EVERY_MS, sliceMs = STEMS_SLICE_MS }) => {
|
|
@@ -7061,7 +7519,7 @@ var stemFills = /* @__PURE__ */ __name(({ withStore, warn, everyMs = STEMS_EVERY
|
|
|
7061
7519
|
};
|
|
7062
7520
|
}, "stemFills");
|
|
7063
7521
|
|
|
7064
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7522
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/render/messages.js
|
|
7065
7523
|
import { styleText } from "node:util";
|
|
7066
7524
|
var TIME_WIDTH = 8;
|
|
7067
7525
|
var INDENT = " ".repeat(TIME_WIDTH + 2);
|
|
@@ -7237,7 +7695,7 @@ var editedAt = /* @__PURE__ */ __name((message, options2) => {
|
|
|
7237
7695
|
return day(edited) === day(message.timestamp) ? time : `${day(edited)} ${time}`;
|
|
7238
7696
|
}, "editedAt");
|
|
7239
7697
|
|
|
7240
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7698
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/message-items.js
|
|
7241
7699
|
var defined = /* @__PURE__ */ __name((value) => Object.fromEntries(Object.entries(value).filter(([, one]) => one !== void 0)), "defined");
|
|
7242
7700
|
var attachmentItem = /* @__PURE__ */ __name((attachment) => defined({
|
|
7243
7701
|
kind: attachment.kind,
|
|
@@ -7332,7 +7790,7 @@ var viewOf = /* @__PURE__ */ __name((context, messenger) => ({
|
|
|
7332
7790
|
locale: messenger.app.locale
|
|
7333
7791
|
}), "viewOf");
|
|
7334
7792
|
|
|
7335
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7793
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-answers.js
|
|
7336
7794
|
var observed = /* @__PURE__ */ __name((value) => ({
|
|
7337
7795
|
value: value.value,
|
|
7338
7796
|
observed_at: value.observedAt,
|
|
@@ -7399,7 +7857,7 @@ var watchEventItem = /* @__PURE__ */ __name((value, account) => {
|
|
|
7399
7857
|
}
|
|
7400
7858
|
}, "watchEventItem");
|
|
7401
7859
|
|
|
7402
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7860
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/watch-command.js
|
|
7403
7861
|
var watchCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("watch"), {
|
|
7404
7862
|
output: { entity: "watch_item" },
|
|
7405
7863
|
effects: REMOTE_READ,
|
|
@@ -7554,7 +8012,7 @@ var describe = /* @__PURE__ */ __name((event, render) => {
|
|
|
7554
8012
|
}
|
|
7555
8013
|
}, "describe");
|
|
7556
8014
|
|
|
7557
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
8015
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/serve-command.js
|
|
7558
8016
|
var serveCommand = /* @__PURE__ */ __name((messenger) => {
|
|
7559
8017
|
const command = annotate(new Command("serve"), {
|
|
7560
8018
|
output: { entity: "serve_summary" },
|
|
@@ -7818,8 +8276,8 @@ var tasking = /* @__PURE__ */ __name((context, warn) => {
|
|
|
7818
8276
|
};
|
|
7819
8277
|
}, "tasking");
|
|
7820
8278
|
|
|
7821
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
7822
|
-
import { existsSync as
|
|
8279
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/store-tables-command.js
|
|
8280
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
7823
8281
|
var PATH = "store tables list";
|
|
7824
8282
|
var STORE_TABLES_QUERY = {
|
|
7825
8283
|
entity: "store_table",
|
|
@@ -7848,7 +8306,7 @@ var storeTablesCommand = /* @__PURE__ */ __name((messenger) => {
|
|
|
7848
8306
|
const filter = filterOf(words);
|
|
7849
8307
|
const { full } = this.optsWithGlobals();
|
|
7850
8308
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
7851
|
-
if (!
|
|
8309
|
+
if (!existsSync8(path))
|
|
7852
8310
|
throw new CliError("not_found", `no store at ${path}`);
|
|
7853
8311
|
const items = await readStoreTables(path, { filter, sizes: full === true });
|
|
7854
8312
|
renderAnswer(this, outputFor(this), listOf(PATH, {
|
|
@@ -7861,7 +8319,7 @@ var storeTablesCommand = /* @__PURE__ */ __name((messenger) => {
|
|
|
7861
8319
|
return tables;
|
|
7862
8320
|
}, "storeTablesCommand");
|
|
7863
8321
|
|
|
7864
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
8322
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.599.0_@wirecat+cli-base@0.78.0_commander@15.0.0_esbuild@0.28.2_type_9abdd607bcc42461f37eac6c77838a67/node_modules/@wirecat/cli-core/dist/cli/messenger/store-maintenance-command.js
|
|
7865
8323
|
var SEARCH_INDEXES = ["messages_fts", "chats_fts", "identities_fts"];
|
|
7866
8324
|
var WORD_INDEX = "message_words";
|
|
7867
8325
|
var schemaOf = /* @__PURE__ */ __name((database) => {
|
|
@@ -7870,7 +8328,7 @@ var schemaOf = /* @__PURE__ */ __name((database) => {
|
|
|
7870
8328
|
}, "schemaOf");
|
|
7871
8329
|
var count2 = /* @__PURE__ */ __name((database, table) => Number(database.prepare(`SELECT count(*) AS n FROM ${table}`).get()?.n ?? 0), "count");
|
|
7872
8330
|
var pendingIfKnown2 = /* @__PURE__ */ __name((database) => database.prepare("SELECT 1 FROM pragma_table_info('messages') WHERE name = 'normalized_text'").get() ? pendingNormalization(database) : null, "pendingIfKnown");
|
|
7873
|
-
var bytesOf2 = /* @__PURE__ */ __name((path) =>
|
|
8331
|
+
var bytesOf2 = /* @__PURE__ */ __name((path) => existsSync9(path) ? statSync4(path).size : 0, "bytesOf");
|
|
7874
8332
|
var reading = /* @__PURE__ */ __name(async (path, read) => {
|
|
7875
8333
|
const database = await openCache(path);
|
|
7876
8334
|
try {
|
|
@@ -7887,10 +8345,22 @@ var readingOnly = /* @__PURE__ */ __name(async (path, read) => {
|
|
|
7887
8345
|
database.close();
|
|
7888
8346
|
}
|
|
7889
8347
|
}, "readingOnly");
|
|
7890
|
-
var storeSummary = /* @__PURE__ */ __name(async (env) => {
|
|
8348
|
+
var storeSummary = /* @__PURE__ */ __name(async (env, { deep = false, command } = {}) => {
|
|
7891
8349
|
const path = storePath(env);
|
|
7892
|
-
if (!
|
|
8350
|
+
if (!existsSync9(path))
|
|
7893
8351
|
return { path, exists: false };
|
|
8352
|
+
const checked = await storeHealth(path, { deep });
|
|
8353
|
+
const health = {
|
|
8354
|
+
checked: checked.checked,
|
|
8355
|
+
covers: deep ? "every page and every search index" : QUICK_HEALTH_CHECKS,
|
|
8356
|
+
ok: checked.ok,
|
|
8357
|
+
ms: checked.ms,
|
|
8358
|
+
...checked.problems ? { problems: checked.problems } : {},
|
|
8359
|
+
...checked.damagedTables?.length ? { damagedTables: checked.damagedTables } : {},
|
|
8360
|
+
...checked.searchIndexes?.some((index) => !index.ok) ? { damagedSearchIndexes: checked.searchIndexes.filter((index) => !index.ok).map((index) => index.name) } : {}
|
|
8361
|
+
};
|
|
8362
|
+
const damage = command ? explainDamage(checked, command) : null;
|
|
8363
|
+
const healthOf = { health, ...damage ? { damage } : {} };
|
|
7894
8364
|
try {
|
|
7895
8365
|
return await reading(path, (database) => {
|
|
7896
8366
|
const { version, writable } = schemaOf(database);
|
|
@@ -7900,11 +8370,12 @@ var storeSummary = /* @__PURE__ */ __name(async (env) => {
|
|
|
7900
8370
|
schema: version,
|
|
7901
8371
|
speaks: SPEAKS,
|
|
7902
8372
|
writable,
|
|
7903
|
-
...version > 0 ? { chats: count2(database, "chats"), messages: count2(database, "messages") } : {}
|
|
8373
|
+
...version > 0 ? { chats: count2(database, "chats"), messages: count2(database, "messages") } : {},
|
|
8374
|
+
...healthOf
|
|
7904
8375
|
};
|
|
7905
8376
|
});
|
|
7906
8377
|
} catch (error) {
|
|
7907
|
-
return { path, exists: true, error: messageOf2(error) };
|
|
8378
|
+
return { path, exists: true, error: messageOf2(error), ...healthOf };
|
|
7908
8379
|
}
|
|
7909
8380
|
}, "storeSummary");
|
|
7910
8381
|
var result = /* @__PURE__ */ __name((command, value, next = []) => renderAnswer(command, outputFor(command), itemOf(snakeKeys(value), { next })), "result");
|
|
@@ -7919,7 +8390,8 @@ var storeMaintenanceCommands = /* @__PURE__ */ __name((messenger) => [
|
|
|
7919
8390
|
repairCommand(messenger),
|
|
7920
8391
|
resetCommand(messenger),
|
|
7921
8392
|
copiesCommand(),
|
|
7922
|
-
storeTablesCommand(messenger)
|
|
8393
|
+
storeTablesCommand(messenger),
|
|
8394
|
+
storeRecoverCommand({ command: messenger.app.command, version: messenger.app.version })
|
|
7923
8395
|
], "storeMaintenanceCommands");
|
|
7924
8396
|
var refuseWhileServing = /* @__PURE__ */ __name((command, messenger) => {
|
|
7925
8397
|
const serving = servingProfiles(messenger.app, environmentOf(command).env ?? process.env);
|
|
@@ -7931,7 +8403,7 @@ var repairCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("
|
|
|
7931
8403
|
const { renderer, format } = outputFor(this);
|
|
7932
8404
|
const { dryRun: dryRun2 } = this.opts();
|
|
7933
8405
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
7934
|
-
if (!
|
|
8406
|
+
if (!existsSync9(path)) {
|
|
7935
8407
|
result(this, { path, exists: false });
|
|
7936
8408
|
return;
|
|
7937
8409
|
}
|
|
@@ -7971,7 +8443,7 @@ var notesOf = /* @__PURE__ */ __name((report, command) => {
|
|
|
7971
8443
|
}, "notesOf");
|
|
7972
8444
|
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) {
|
|
7973
8445
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
7974
|
-
if (!
|
|
8446
|
+
if (!existsSync9(path))
|
|
7975
8447
|
throw new CliError("not_found", `no store at ${path}`);
|
|
7976
8448
|
const deleted = await reading(path, (database) => deleteCopy(database, name));
|
|
7977
8449
|
result(this, { path, deleted });
|
|
@@ -7979,7 +8451,7 @@ var copiesCommand = /* @__PURE__ */ __name(() => new Command("copies").descripti
|
|
|
7979
8451
|
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() {
|
|
7980
8452
|
const { renderer } = outputFor(this);
|
|
7981
8453
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
7982
|
-
if (!
|
|
8454
|
+
if (!existsSync9(path)) {
|
|
7983
8455
|
result(this, { path, exists: false, ok: true });
|
|
7984
8456
|
return;
|
|
7985
8457
|
}
|
|
@@ -8042,7 +8514,7 @@ var inspect = /* @__PURE__ */ __name((path) => reading(path, (database) => {
|
|
|
8042
8514
|
...schema.version > 0 ? [["attachment_words", indexIntegrity(database, "attachment_words", 0)]] : []
|
|
8043
8515
|
]);
|
|
8044
8516
|
const size = bytesOf2(path) + bytesOf2(`${path}-wal`);
|
|
8045
|
-
const { bavail, bsize } =
|
|
8517
|
+
const { bavail, bsize } = statfsSync2(dirname2(path));
|
|
8046
8518
|
const free = Number(bavail) * Number(bsize);
|
|
8047
8519
|
const behind = schema.version > 0 ? chatsBehind(database) : [];
|
|
8048
8520
|
const vectorIndexes = schema.version >= 34 ? vectorIndexCounts(database) : [];
|
|
@@ -8130,14 +8602,18 @@ var chatsBehind = /* @__PURE__ */ __name((database) => database.prepare(`SELECT
|
|
|
8130
8602
|
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() {
|
|
8131
8603
|
const { renderer } = outputFor(this);
|
|
8132
8604
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
8133
|
-
if (!
|
|
8605
|
+
if (!existsSync9(path)) {
|
|
8134
8606
|
result(this, { path, exists: false });
|
|
8135
8607
|
renderer.note(`no store yet \u2014 the first \`${messenger.app.command}\` command that reads a chat creates it`);
|
|
8136
8608
|
return;
|
|
8137
8609
|
}
|
|
8138
8610
|
const answer = await reading(path, (database) => {
|
|
8139
8611
|
const from = schemaOf(database).version;
|
|
8140
|
-
migrate(database, {
|
|
8612
|
+
migrate(database, {
|
|
8613
|
+
command: messenger.app.command,
|
|
8614
|
+
version: messenger.app.version,
|
|
8615
|
+
rollback: { store: path, warn: /* @__PURE__ */ __name((line) => renderer.warn(line), "warn") }
|
|
8616
|
+
});
|
|
8141
8617
|
const { normalized, indexed, terms } = buildWordIndex(database, (note) => renderer.note(note));
|
|
8142
8618
|
const stemmed = buildStems(database, (note) => renderer.note(note));
|
|
8143
8619
|
const notes = buildNoteIndex(database, (note) => renderer.note(note));
|
|
@@ -8190,7 +8666,7 @@ var buildNoteIndex = /* @__PURE__ */ __name((database, note, { reset = false } =
|
|
|
8190
8666
|
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() {
|
|
8191
8667
|
const { renderer } = outputFor(this);
|
|
8192
8668
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
8193
|
-
if (!
|
|
8669
|
+
if (!existsSync9(path)) {
|
|
8194
8670
|
result(this, { path, exists: false });
|
|
8195
8671
|
return;
|
|
8196
8672
|
}
|
|
@@ -8219,11 +8695,11 @@ var reindexCommand = /* @__PURE__ */ __name((messenger) => destroysNothing(annot
|
|
|
8219
8695
|
result(this, answer);
|
|
8220
8696
|
}), "reindexCommand");
|
|
8221
8697
|
var vacuumInto = /* @__PURE__ */ __name(async (path, target) => {
|
|
8222
|
-
|
|
8698
|
+
writeFileSync2(target, "", { flag: "wx", mode: 384 });
|
|
8223
8699
|
try {
|
|
8224
8700
|
await reading(path, (database) => database.prepare("VACUUM INTO ?").run(target));
|
|
8225
8701
|
} catch (error) {
|
|
8226
|
-
|
|
8702
|
+
rmSync3(target, { force: true });
|
|
8227
8703
|
throw error;
|
|
8228
8704
|
}
|
|
8229
8705
|
}, "vacuumInto");
|
|
@@ -8232,9 +8708,9 @@ var backupCommand = /* @__PURE__ */ __name(() => destroysNothing(annotate(new Co
|
|
|
8232
8708
|
const { encrypt } = this.opts();
|
|
8233
8709
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
8234
8710
|
const target = resolve(file2);
|
|
8235
|
-
if (!
|
|
8711
|
+
if (!existsSync9(path))
|
|
8236
8712
|
throw new CliError("not_found", `no store at ${path} to back up`);
|
|
8237
|
-
if (
|
|
8713
|
+
if (existsSync9(target))
|
|
8238
8714
|
throw new CliError("validation_error", `${target} exists \u2014 a backup never overwrites a file`);
|
|
8239
8715
|
const password = encrypt ? await passwordOf(this, { twice: true }) : void 0;
|
|
8240
8716
|
const copyAt = password === void 0 ? target : `${path}.backup-${process.pid}`;
|
|
@@ -8256,67 +8732,69 @@ var backupCommand = /* @__PURE__ */ __name(() => destroysNothing(annotate(new Co
|
|
|
8256
8732
|
});
|
|
8257
8733
|
} catch (error) {
|
|
8258
8734
|
if (password === void 0)
|
|
8259
|
-
|
|
8735
|
+
rmSync3(target, { force: true });
|
|
8260
8736
|
throw error;
|
|
8261
8737
|
} finally {
|
|
8262
8738
|
if (password !== void 0)
|
|
8263
|
-
|
|
8739
|
+
rmSync3(copyAt, { force: true });
|
|
8264
8740
|
}
|
|
8265
8741
|
}), "backupCommand");
|
|
8266
8742
|
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) {
|
|
8267
8743
|
const { output } = this.opts();
|
|
8268
8744
|
const from = resolve(file2);
|
|
8269
8745
|
const to = resolve(output);
|
|
8270
|
-
if (!
|
|
8746
|
+
if (!existsSync9(from))
|
|
8271
8747
|
throw new CliError("not_found", `no file at ${from}`);
|
|
8272
8748
|
if (!isSealed(from))
|
|
8273
8749
|
throw new CliError("validation_error", `${from} was not written with --encrypt`);
|
|
8274
|
-
if (
|
|
8750
|
+
if (existsSync9(to))
|
|
8275
8751
|
throw new CliError("validation_error", `${to} exists \u2014 never overwritten`);
|
|
8276
8752
|
await unsealFile(from, to, await passwordOf(this, { twice: false }));
|
|
8277
8753
|
result(this, { path: to, from, bytes: bytesOf2(to) });
|
|
8278
8754
|
}), "decryptCommand");
|
|
8279
|
-
var restoreCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("restore"), { output: { entity: "store_restore" }, effects: LOCAL_WRITE }).summary("restore a backup
|
|
8755
|
+
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) {
|
|
8280
8756
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
8281
8757
|
const given = resolve(file2);
|
|
8282
|
-
if (!
|
|
8758
|
+
if (!existsSync9(given))
|
|
8283
8759
|
throw new CliError("not_found", `no file at ${given}`);
|
|
8284
8760
|
refuseWhileServing(this, messenger);
|
|
8285
8761
|
if (!isSealed(given))
|
|
8286
8762
|
return restoreFrom(this, messenger, given, given);
|
|
8287
8763
|
const opened = `${path}.unsealing-${process.pid}`;
|
|
8288
|
-
mkdirSync(
|
|
8764
|
+
mkdirSync(dirname2(path), { recursive: true, mode: 448 });
|
|
8289
8765
|
try {
|
|
8290
8766
|
await unsealFile(given, opened, await passwordOf(this, { twice: false }));
|
|
8291
8767
|
await restoreFrom(this, messenger, opened, given);
|
|
8292
8768
|
} finally {
|
|
8293
|
-
|
|
8769
|
+
rmSync3(opened, { force: true });
|
|
8294
8770
|
}
|
|
8295
8771
|
}), "restoreCommand");
|
|
8296
8772
|
var restoreFrom = /* @__PURE__ */ __name(async (command, messenger, backup, given) => {
|
|
8297
8773
|
const { renderer } = outputFor(command);
|
|
8298
8774
|
const path = storePath(environmentOf(command).env ?? process.env);
|
|
8299
|
-
if (
|
|
8775
|
+
if (existsSync9(path) && realpathSync2(backup) === realpathSync2(path)) {
|
|
8300
8776
|
throw new CliError("validation_error", `${backup} is the store itself`);
|
|
8301
8777
|
}
|
|
8778
|
+
if (await isRollbackCopy(backup))
|
|
8779
|
+
return rollBackFrom(command, messenger, backup);
|
|
8302
8780
|
const schema = await backupSchema(backup);
|
|
8303
8781
|
const stamp = stampNow();
|
|
8304
|
-
const kept =
|
|
8782
|
+
const kept = existsSync9(path) ? `${path}.before-restore-${stamp}` : null;
|
|
8305
8783
|
if (kept) {
|
|
8306
8784
|
const waitMs = environmentOf(command).storeLockWaitMs;
|
|
8307
8785
|
await quiesce(path, messenger, "restore", (message) => renderer.warn(message), waitMs);
|
|
8308
8786
|
} else
|
|
8309
|
-
mkdirSync(
|
|
8787
|
+
mkdirSync(dirname2(path), { recursive: true, mode: 448 });
|
|
8310
8788
|
const incoming = `${path}.restoring-${stamp}`;
|
|
8311
8789
|
copyFileSync(backup, incoming, constants.COPYFILE_EXCL);
|
|
8312
8790
|
chmodSync(incoming, 384);
|
|
8313
8791
|
if (kept) {
|
|
8314
|
-
|
|
8792
|
+
renameSync3(path, kept);
|
|
8315
8793
|
for (const suffix of ["-wal", "-shm"])
|
|
8316
|
-
if (
|
|
8317
|
-
|
|
8794
|
+
if (existsSync9(`${path}${suffix}`))
|
|
8795
|
+
renameSync3(`${path}${suffix}`, `${kept}${suffix}`);
|
|
8318
8796
|
}
|
|
8319
|
-
|
|
8797
|
+
renameSync3(incoming, path);
|
|
8320
8798
|
result(command, { path, restoredFrom: given, keptAt: kept, schema: schema.version });
|
|
8321
8799
|
if (kept)
|
|
8322
8800
|
renderer.note(`the store it replaced is kept at ${kept}`);
|
|
@@ -8325,6 +8803,43 @@ var restoreFrom = /* @__PURE__ */ __name(async (command, messenger, backup, give
|
|
|
8325
8803
|
renderer.note(`the backup is behind this build; the next command migrates it \u2014 \`${lineOf(command, "store migrate")}\` now`);
|
|
8326
8804
|
}
|
|
8327
8805
|
}, "restoreFrom");
|
|
8806
|
+
var isRollbackCopy = /* @__PURE__ */ __name(async (file2) => {
|
|
8807
|
+
try {
|
|
8808
|
+
return await readingOnly(file2, (database) => database.prepare("SELECT 1 FROM sqlite_master WHERE name = 'rollback_meta'").get() !== void 0);
|
|
8809
|
+
} catch {
|
|
8810
|
+
return false;
|
|
8811
|
+
}
|
|
8812
|
+
}, "isRollbackCopy");
|
|
8813
|
+
var rollBackFrom = /* @__PURE__ */ __name(async (command, messenger, copy) => {
|
|
8814
|
+
const { renderer } = outputFor(command);
|
|
8815
|
+
const path = storePath(environmentOf(command).env ?? process.env);
|
|
8816
|
+
if (!existsSync9(path))
|
|
8817
|
+
throw new CliError("not_found", `no store at ${path} to roll back`);
|
|
8818
|
+
const waitMs = environmentOf(command).storeLockWaitMs;
|
|
8819
|
+
await quiesce(path, messenger, "restore", (message) => renderer.warn(message), waitMs);
|
|
8820
|
+
const { database } = await openSqlite(path);
|
|
8821
|
+
let rolled;
|
|
8822
|
+
try {
|
|
8823
|
+
rolled = rollBack(database, copy);
|
|
8824
|
+
} finally {
|
|
8825
|
+
database.close();
|
|
8826
|
+
}
|
|
8827
|
+
result(command, {
|
|
8828
|
+
path,
|
|
8829
|
+
restoredFrom: copy,
|
|
8830
|
+
rolledBack: true,
|
|
8831
|
+
schema: rolled.from,
|
|
8832
|
+
was: rolled.was,
|
|
8833
|
+
tables: rolled.restored,
|
|
8834
|
+
rebuilt: rolled.rebuilt,
|
|
8835
|
+
foreignKeyViolations: rolled.foreignKeyViolations
|
|
8836
|
+
});
|
|
8837
|
+
const taken = new Date(rolled.createdAt).toISOString();
|
|
8838
|
+
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`);
|
|
8839
|
+
renderer.note("open it with the older tool and run its `store rebuild`: the search indexes are behind the tables");
|
|
8840
|
+
renderer.note(`a tool that speaks schema ${rolled.to} or later migrates it again on its next run`);
|
|
8841
|
+
renderer.note("restart every serve and mcp of either CLI that was running, so they read the restored store");
|
|
8842
|
+
}, "rollBackFrom");
|
|
8328
8843
|
var backupSchema = /* @__PURE__ */ __name(async (backup) => {
|
|
8329
8844
|
let read;
|
|
8330
8845
|
try {
|
|
@@ -8348,7 +8863,7 @@ var backupSchema = /* @__PURE__ */ __name(async (backup) => {
|
|
|
8348
8863
|
var STORE_LOCK_WAIT_MS = 1e3;
|
|
8349
8864
|
var quiesce = /* @__PURE__ */ __name(async (path, messenger, then, warn, waitMs = STORE_LOCK_WAIT_MS) => {
|
|
8350
8865
|
const { command } = messenger.app;
|
|
8351
|
-
const files = [path, `${path}-wal`, `${path}-shm`].filter((file2) =>
|
|
8866
|
+
const files = [path, `${path}-wal`, `${path}-shm`].filter((file2) => existsSync9(file2)).map((file2) => realpathSync2(file2));
|
|
8352
8867
|
const holders = holdersOf(files);
|
|
8353
8868
|
if (holders === void 0) {
|
|
8354
8869
|
warn(`this system cannot say which processes have the store open \u2014 restart every running serve and mcp after this`);
|
|
@@ -8374,7 +8889,7 @@ var resetCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("r
|
|
|
8374
8889
|
const { command } = messenger.app;
|
|
8375
8890
|
const env = environmentOf(this).env ?? process.env;
|
|
8376
8891
|
const path = storePath(env);
|
|
8377
|
-
if (!
|
|
8892
|
+
if (!existsSync9(path)) {
|
|
8378
8893
|
result(this, { path, exists: false, reset: false });
|
|
8379
8894
|
renderer.note(`no store at ${path} \u2014 nothing to reset; the first \`${command}\` command that reads a chat creates it`);
|
|
8380
8895
|
return;
|
|
@@ -8410,17 +8925,17 @@ var resetCommand = /* @__PURE__ */ __name((messenger) => annotate(new Command("r
|
|
|
8410
8925
|
});
|
|
8411
8926
|
renderer.note(`backed the store up to ${backup}`);
|
|
8412
8927
|
}
|
|
8413
|
-
for (const suffix of
|
|
8414
|
-
|
|
8928
|
+
for (const suffix of STORE_PARTS2)
|
|
8929
|
+
rmSync3(`${path}${suffix}`, { force: true });
|
|
8415
8930
|
await (await openStore({ path, command })).close();
|
|
8416
8931
|
const schema = await reading(path, (database) => schemaOf(database).version);
|
|
8417
8932
|
result(this, { path, exists: true, reset: true, backup, backedUp, schema });
|
|
8418
8933
|
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`);
|
|
8419
8934
|
}), "resetCommand");
|
|
8420
|
-
var
|
|
8935
|
+
var STORE_PARTS2 = ["", "-wal", "-shm"];
|
|
8421
8936
|
var resetPreview = /* @__PURE__ */ __name(async (path, messenger, env, keep) => {
|
|
8422
|
-
const files =
|
|
8423
|
-
const holders = holdersOf(files.map((file2) =>
|
|
8937
|
+
const files = STORE_PARTS2.map((suffix) => `${path}${suffix}`).filter((file2) => existsSync9(file2));
|
|
8938
|
+
const holders = holdersOf(files.map((file2) => realpathSync2(file2)));
|
|
8424
8939
|
const serving = servingProfiles(messenger.app, env).length > 0;
|
|
8425
8940
|
const read = await readingOnly(path, (database) => ({
|
|
8426
8941
|
schema: schemaOf(database).version,
|
|
@@ -8451,6 +8966,9 @@ export {
|
|
|
8451
8966
|
checkFor,
|
|
8452
8967
|
passes,
|
|
8453
8968
|
seal,
|
|
8969
|
+
storeRecoveryCheck,
|
|
8970
|
+
storeRecoveryRun,
|
|
8971
|
+
recoveryNotes,
|
|
8454
8972
|
storeInfo,
|
|
8455
8973
|
ENCRYPT_OPTION,
|
|
8456
8974
|
passwordOf,
|