@wirecat/cli-core 0.549.0 → 0.551.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +223 -22
- package/THIRD_PARTY_NOTICES +41 -0
- package/dist/calendar/ics.d.ts +1 -1
- package/dist/calendar/ics.js +5 -2
- package/dist/calendar/windows-zones.generated.d.ts +1 -0
- package/dist/calendar/windows-zones.generated.js +146 -0
- package/dist/cli/compact.js +2 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/meeting-findings-input.js +4 -3
- package/dist/cli/messenger/backfill-command.js +28 -1
- package/dist/cli/messenger/context.js +1 -0
- package/dist/cli/messenger/history-gaps.js +4 -4
- package/dist/cli/messenger/mcp-command.js +1 -0
- package/dist/cli/messenger/messages-delete-command.js +7 -8
- package/dist/cli/messenger/projects-command.js +47 -2
- package/dist/cli/payment-query.d.ts +8 -0
- package/dist/cli/payment-query.js +27 -0
- package/dist/cli/project-status-rows.d.ts +8 -0
- package/dist/cli/project-status-rows.js +102 -0
- package/dist/cli/project-status.d.ts +132 -0
- package/dist/cli/project-status.js +248 -0
- package/dist/cli/steps.js +4 -1
- package/dist/domain/knowledge.d.ts +1 -1
- package/dist/domain/knowledge.js +1 -1
- package/dist/domain/status-words.d.ts +3 -0
- package/dist/domain/status-words.js +44 -0
- package/dist/entities/fact.d.ts +12 -1
- package/dist/entities/fact.js +13 -0
- package/dist/entities/index.d.ts +18 -2
- package/dist/entities/meeting-findings.d.ts +1 -1
- package/dist/entities/message-transfer.d.ts +16 -0
- package/dist/entities/message-transfer.js +6 -0
- package/dist/errors/reasons.js +1 -0
- package/dist/mail/partial.d.ts +9 -3
- package/dist/mail/partial.js +35 -10
- package/dist/mail/source.d.ts +7 -1
- package/dist/mail/sync.js +1 -1
- package/dist/mcp/app-server.js +1 -0
- package/dist/mcp/http/oauth.d.ts +2 -1
- package/dist/mcp/http/oauth.js +2 -2
- package/dist/mcp/http/serve.d.ts +2 -0
- package/dist/mcp/http/serve.js +2 -1
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/surface.js +1 -1
- package/dist/meetings/findings-rules.d.ts +14 -3
- package/dist/meetings/findings-rules.js +16 -2
- package/dist/meetings/index.d.ts +3 -2
- package/dist/meetings/index.js +2 -1
- package/dist/meetings/meeting-context.d.ts +2 -3
- package/dist/meetings/meeting-context.js +3 -4
- package/dist/meetings/payment.d.ts +27 -0
- package/dist/meetings/payment.js +81 -0
- package/dist/services/archive.d.ts +13 -0
- package/dist/services/archive.js +56 -5
- package/dist/services/deps.d.ts +3 -0
- package/dist/services/history-limits.d.ts +2 -0
- package/dist/services/index.d.ts +4 -1
- package/dist/services/index.js +4 -1
- package/dist/services/job-query.d.ts +5 -2
- package/dist/services/job-query.js +5 -2
- package/dist/services/link-scorers/alias-hits.d.ts +7 -0
- package/dist/services/link-scorers/alias-hits.js +54 -0
- package/dist/services/link-scorers/chat-senders.d.ts +6 -0
- package/dist/services/link-scorers/chat-senders.js +56 -0
- package/dist/services/link-scorers/chat-title.d.ts +6 -0
- package/dist/services/link-scorers/chat-title.js +44 -0
- package/dist/services/link-scorers/email-domain.d.ts +6 -0
- package/dist/services/link-scorers/email-domain.js +64 -0
- package/dist/services/link-scorers/index.d.ts +9 -0
- package/dist/services/link-scorers/index.js +8 -0
- package/dist/services/link-scorers/mail-thread.d.ts +3 -0
- package/dist/services/link-scorers/mail-thread.js +74 -0
- package/dist/services/link-scorers/member-chats.d.ts +3 -0
- package/dist/services/link-scorers/member-chats.js +40 -0
- package/dist/services/link-scorers/member-dialog.d.ts +3 -0
- package/dist/services/link-scorers/member-dialog.js +34 -0
- package/dist/services/link-scorers/scan.d.ts +41 -0
- package/dist/services/link-scorers/scan.js +244 -0
- package/dist/services/link-scorers/shared.d.ts +26 -0
- package/dist/services/link-scorers/shared.js +48 -0
- package/dist/services/link-scorers/types.d.ts +77 -0
- package/dist/services/link-scorers/types.js +1 -0
- package/dist/services/project-status/index.d.ts +71 -0
- package/dist/services/project-status/index.js +196 -0
- package/dist/services/project-status/items.d.ts +10 -0
- package/dist/services/project-status/items.js +23 -0
- package/dist/services/project-status/signals/amounts.d.ts +20 -0
- package/dist/services/project-status/signals/amounts.js +91 -0
- package/dist/services/project-status/signals/children.d.ts +13 -0
- package/dist/services/project-status/signals/children.js +28 -0
- package/dist/services/project-status/signals/coverage.d.ts +13 -0
- package/dist/services/project-status/signals/coverage.js +30 -0
- package/dist/services/project-status/signals/index.d.ts +3 -0
- package/dist/services/project-status/signals/index.js +21 -0
- package/dist/services/project-status/signals/last-message.d.ts +4 -0
- package/dist/services/project-status/signals/last-message.js +22 -0
- package/dist/services/project-status/signals/payments.d.ts +9 -0
- package/dist/services/project-status/signals/payments.js +24 -0
- package/dist/services/project-status/signals/promises.d.ts +17 -0
- package/dist/services/project-status/signals/promises.js +109 -0
- package/dist/services/project-status/signals/questions.d.ts +8 -0
- package/dist/services/project-status/signals/questions.js +38 -0
- package/dist/services/project-status/signals/reply-next.d.ts +19 -0
- package/dist/services/project-status/signals/reply-next.js +75 -0
- package/dist/services/project-status/signals/topics.d.ts +10 -0
- package/dist/services/project-status/signals/topics.js +50 -0
- package/dist/services/project-status/types.d.ts +84 -0
- package/dist/services/project-status/types.js +1 -0
- package/dist/services/proposals/index.d.ts +1 -0
- package/dist/services/proposals/index.js +1 -0
- package/dist/services/proposals/kinds/findings.d.ts +3 -0
- package/dist/services/proposals/kinds/findings.js +8 -1
- package/dist/store/decisions.d.ts +5 -1
- package/dist/store/decisions.js +5 -1
- package/dist/store/evidence-findings.js +1 -0
- package/dist/store/index.d.ts +2 -1
- package/dist/store/index.js +1 -0
- package/dist/store/project-transfer/request.d.ts +1 -1
- package/dist/store/project-transfer/schema.d.ts +2 -2
- package/dist/store/project-transfer/snapshot-model.d.ts +2 -2
- package/dist/store/sqlite/email-locations.d.ts +22 -1
- package/dist/store/sqlite/email-locations.js +29 -2
- package/dist/store/sqlite/emails.d.ts +3 -7
- package/dist/store/sqlite/emails.js +4 -2
- package/dist/store/sqlite/evidence-findings.js +5 -1
- package/dist/store/sqlite/facts.d.ts +13 -0
- package/dist/store/sqlite/facts.js +64 -6
- package/dist/store/sqlite/findings-core.js +14 -1
- package/dist/store/sqlite/knowledge.d.ts +16 -2
- package/dist/store/sqlite/knowledge.js +1 -0
- package/dist/store/sqlite/project-transfer/snapshot.d.ts +1 -1
- package/dist/store/sqlite/relation-proposals.d.ts +29 -2
- package/dist/store/sqlite/relation-proposals.js +75 -4
- package/dist/store/store.d.ts +1 -0
- package/package.json +3 -3
- package/parity.json +11 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { snakeKeys } from "./envelope.js";
|
|
3
|
+
import { heldPhrase } from "./messenger/search-answers.js";
|
|
4
|
+
import { STATUS_SIGNAL_ROWS } from "./project-status-rows.js";
|
|
5
|
+
const day = (at) => new Date(at).toISOString().slice(0, 10);
|
|
6
|
+
const listKey = (signal) => signal.replaceAll("-", "_");
|
|
7
|
+
const SECTIONS = {
|
|
8
|
+
signals: "status.signal",
|
|
9
|
+
money: "status.money",
|
|
10
|
+
chats: "status.chat",
|
|
11
|
+
out_of_scope: "status.out-of-scope",
|
|
12
|
+
failed: "status.failed",
|
|
13
|
+
};
|
|
14
|
+
/** The `project_status` answer drawn by `--compact`: each signal's list with that signal's row. */
|
|
15
|
+
export const projectStatusRow = (signals) => ({
|
|
16
|
+
columns: [],
|
|
17
|
+
sections: {
|
|
18
|
+
...SECTIONS,
|
|
19
|
+
...Object.fromEntries(signals.map(({ id }) => [listKey(id), `status.${id}`])),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
const statusItem = v.looseObject({
|
|
23
|
+
signal: v.string(),
|
|
24
|
+
ref: v.nullable(v.string()),
|
|
25
|
+
chat: v.nullable(v.string()),
|
|
26
|
+
chat_title: v.nullable(v.string()),
|
|
27
|
+
at: v.nullable(v.string()),
|
|
28
|
+
who: v.nullable(v.strictObject({ ref: v.nullable(v.string()), name: v.nullable(v.string()), owner: v.boolean() })),
|
|
29
|
+
evidence: v.array(v.strictObject({ ref: v.string(), fingerprint: v.nullable(v.string()) })),
|
|
30
|
+
basis: v.picklist(["store", "fact", "task", "pattern"]),
|
|
31
|
+
data: v.record(v.string(), v.unknown()),
|
|
32
|
+
});
|
|
33
|
+
/** Where a project stands: per chat signals, open money, and what was left out. Empty lists are left out. */
|
|
34
|
+
export const projectStatusSchema = v.looseObject({
|
|
35
|
+
project: v.string(),
|
|
36
|
+
key: v.nullable(v.string()),
|
|
37
|
+
name: v.string(),
|
|
38
|
+
window: v.strictObject({ since: v.string(), until: v.string() }),
|
|
39
|
+
signals: v.array(v.strictObject({ id: v.string(), version: v.number() })),
|
|
40
|
+
money: v.array(v.strictObject({ direction: v.string(), currency: v.nullable(v.string()), amount: v.string(), rows: v.number() })),
|
|
41
|
+
chats: v.array(v.strictObject({
|
|
42
|
+
chat: v.string(),
|
|
43
|
+
title: v.nullable(v.string()),
|
|
44
|
+
kind: v.string(),
|
|
45
|
+
role: v.nullable(v.string()),
|
|
46
|
+
purpose: v.string(),
|
|
47
|
+
project: v.string(),
|
|
48
|
+
coverage: v.string(),
|
|
49
|
+
attention: v.number(),
|
|
50
|
+
why: v.nullable(v.string()),
|
|
51
|
+
})),
|
|
52
|
+
out_of_scope: v.optional(v.array(v.strictObject({ chat: v.string(), reason: v.string(), purpose: v.optional(v.string()) }))),
|
|
53
|
+
failed: v.optional(v.array(v.strictObject({ signal: v.string(), why: v.string() }))),
|
|
54
|
+
...Object.fromEntries(Object.keys(STATUS_SIGNAL_ROWS).map((name) => [listKey(name.slice(7)), v.optional(v.array(statusItem))])),
|
|
55
|
+
});
|
|
56
|
+
const coverageOf = (found, chat) => found.items.find((one) => one.signal === "coverage" && one.chat === chat)?.data;
|
|
57
|
+
const partial = (found, chat) => {
|
|
58
|
+
const held = coverageOf(found, chat.ref);
|
|
59
|
+
return held ? held.state !== "complete" && held.beforeHeld : chat.coverage.completeness.state !== "complete";
|
|
60
|
+
};
|
|
61
|
+
const readFrom = (found, chat) => {
|
|
62
|
+
const reply = found.items.find((one) => one.signal === "reply-next" && one.chat === chat)?.data;
|
|
63
|
+
const money = found.items
|
|
64
|
+
.filter((one) => one.signal === "amounts" && one.chat === chat && one.data.state === "open")
|
|
65
|
+
.map((one) => one.data.since)
|
|
66
|
+
.sort()[0];
|
|
67
|
+
return day([money, reply?.waitingSince, found.window.since].find((one) => typeof one === "string"));
|
|
68
|
+
};
|
|
69
|
+
/** At most two: the chats `attention` weighs highest, a chat held in part synced first. */
|
|
70
|
+
const nextOf = (found, hints) => {
|
|
71
|
+
const byRef = new Map(found.chats.map((chat) => [chat.ref, chat]));
|
|
72
|
+
const top = found.attention.slice(0, 2).flatMap((one) => {
|
|
73
|
+
const chat = byRef.get(one.chat);
|
|
74
|
+
return chat ? [{ chat, why: one.why }] : [];
|
|
75
|
+
});
|
|
76
|
+
const because = (step, why) => (step ? [{ ...step, why }] : []);
|
|
77
|
+
const syncs = top.flatMap(({ chat, why }) => partial(found, chat) ? because(hints.sync(chat, day(found.window.since)), why) : []);
|
|
78
|
+
const reads = top.flatMap(({ chat, why }) => partial(found, chat) ? [] : because(hints.read(chat, readFrom(found, chat.ref)), why));
|
|
79
|
+
return [...syncs, ...reads].slice(0, 2);
|
|
80
|
+
};
|
|
81
|
+
const missingOf = (found) => {
|
|
82
|
+
const held = found.chats.filter((chat) => partial(found, chat));
|
|
83
|
+
const [first] = held;
|
|
84
|
+
return [
|
|
85
|
+
...(first
|
|
86
|
+
? [
|
|
87
|
+
{
|
|
88
|
+
field: "history",
|
|
89
|
+
why: `${held.length} of ${found.chats.length} chats hold only part of the window; ` +
|
|
90
|
+
`the first is ${heldPhrase(first.coverage)}`,
|
|
91
|
+
step: "messages.sync",
|
|
92
|
+
},
|
|
93
|
+
]
|
|
94
|
+
: []),
|
|
95
|
+
...(found.outOfScope.length
|
|
96
|
+
? [
|
|
97
|
+
{
|
|
98
|
+
field: "chats",
|
|
99
|
+
why: `${found.outOfScope.length} linked chats were not read here (${[
|
|
100
|
+
...new Set(found.outOfScope.map((one) => one.reason)),
|
|
101
|
+
].join(", ")}); memo projects status reads every account`,
|
|
102
|
+
},
|
|
103
|
+
]
|
|
104
|
+
: []),
|
|
105
|
+
...found.failed.map((one) => ({ field: `signal:${one.signal}`, why: one.why })),
|
|
106
|
+
];
|
|
107
|
+
};
|
|
108
|
+
const withPlace = (found, hints) => {
|
|
109
|
+
const titles = new Map(found.chats.map((chat) => [chat.ref, chat.title]));
|
|
110
|
+
const sync = (one) => {
|
|
111
|
+
const chat = found.chats.find((each) => each.ref === one.chat);
|
|
112
|
+
const step = chat && partial(found, chat) ? hints.sync(chat, day(found.window.since)) : null;
|
|
113
|
+
return step ? hints.line(step) : null;
|
|
114
|
+
};
|
|
115
|
+
return (one) => ({
|
|
116
|
+
...one,
|
|
117
|
+
ref: one.evidence[0]?.ref ?? one.chat,
|
|
118
|
+
chatTitle: one.chat === null ? null : (titles.get(one.chat) ?? null),
|
|
119
|
+
...(one.signal === "coverage" ? { syncCommand: sync(one) } : {}),
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
/** The answer of `projects status`: the item, two steps at most, what is missing, and the window. */
|
|
123
|
+
export const projectStatusAnswer = (found, hints) => {
|
|
124
|
+
const weights = new Map(found.attention.map((one) => [one.chat, one]));
|
|
125
|
+
const place = withPlace(found, hints);
|
|
126
|
+
const lists = Object.fromEntries(found.signals.flatMap(({ id }) => {
|
|
127
|
+
const items = found.items.filter((one) => one.signal === id).map(place);
|
|
128
|
+
return items.length ? [[listKey(id), items]] : [];
|
|
129
|
+
}));
|
|
130
|
+
const item = snakeKeys({
|
|
131
|
+
project: found.project.ref,
|
|
132
|
+
key: found.project.key,
|
|
133
|
+
name: found.project.name,
|
|
134
|
+
window: found.window,
|
|
135
|
+
signals: found.signals,
|
|
136
|
+
money: found.money.open,
|
|
137
|
+
chats: found.chats.map((chat) => ({
|
|
138
|
+
chat: chat.ref,
|
|
139
|
+
title: chat.title,
|
|
140
|
+
kind: chat.kind,
|
|
141
|
+
role: chat.role,
|
|
142
|
+
purpose: chat.purpose,
|
|
143
|
+
project: chat.project,
|
|
144
|
+
coverage: chat.coverage.completeness.state,
|
|
145
|
+
attention: weights.get(chat.ref)?.weight ?? 0,
|
|
146
|
+
why: weights.get(chat.ref)?.why ?? null,
|
|
147
|
+
})),
|
|
148
|
+
...(found.outOfScope.length ? { outOfScope: found.outOfScope } : {}),
|
|
149
|
+
...(found.failed.length ? { failed: found.failed } : {}),
|
|
150
|
+
...lists,
|
|
151
|
+
});
|
|
152
|
+
const missing = missingOf(found);
|
|
153
|
+
const complete = found.failed.length === 0 && !found.chats.some((chat) => partial(found, chat));
|
|
154
|
+
return {
|
|
155
|
+
item,
|
|
156
|
+
next: nextOf(found, hints),
|
|
157
|
+
missing,
|
|
158
|
+
meta: { window: found.window, complete, ...(found.accounts.length ? { accounts: found.accounts } : {}) },
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
const NEXT_WORDS = { owner: "YOU", them: "them", nobody: "nobody" };
|
|
162
|
+
const chatLine = (found, chat) => {
|
|
163
|
+
const of = (signal) => found.items.filter((one) => one.signal === signal && one.chat === chat.ref);
|
|
164
|
+
const [last] = of("last-message");
|
|
165
|
+
const reply = of("reply-next")[0]?.data;
|
|
166
|
+
const head = [
|
|
167
|
+
`${chat.title ?? chat.ref} (${[chat.role ?? "no role", chat.kind].join(", ")})`,
|
|
168
|
+
last
|
|
169
|
+
? `last ${day(last.at)} ${last.who?.owner ? "you" : (last.who?.name ?? "them")}`
|
|
170
|
+
: "nothing in the window",
|
|
171
|
+
...(reply
|
|
172
|
+
? [
|
|
173
|
+
`next: ${reply.next === "named" ? `${reply.addressed?.name ?? "someone"} (named)` : NEXT_WORDS[reply.next]}` +
|
|
174
|
+
(reply.waitingSince ? ` since ${day(reply.waitingSince)}` : ""),
|
|
175
|
+
]
|
|
176
|
+
: []),
|
|
177
|
+
...(partial(found, chat) ? [heldPhrase(chat.coverage)] : []),
|
|
178
|
+
].join(" · ");
|
|
179
|
+
const open = [];
|
|
180
|
+
const asked = of("questions").map((one) => one.data);
|
|
181
|
+
const yours = asked.filter((one) => one.side === "yours").length;
|
|
182
|
+
const theirs = asked.length - yours;
|
|
183
|
+
if (theirs)
|
|
184
|
+
open.push(`${theirs} question${theirs === 1 ? "" : "s"} to you unanswered`);
|
|
185
|
+
if (yours)
|
|
186
|
+
open.push(`${yours} question${yours === 1 ? "" : "s"} of yours unanswered`);
|
|
187
|
+
for (const topic of of("topics")) {
|
|
188
|
+
const data = topic.data;
|
|
189
|
+
if (data.silentSince)
|
|
190
|
+
open.push(`"${data.query}" quiet on their side since ${day(data.silentSince)}`);
|
|
191
|
+
}
|
|
192
|
+
const promised = of("promises").length;
|
|
193
|
+
if (promised)
|
|
194
|
+
open.push(`${promised} promise${promised === 1 ? "" : "s"}`);
|
|
195
|
+
return [` ${head}`, ...(open.length ? [` open: ${open.join(" · ")}`] : [])];
|
|
196
|
+
};
|
|
197
|
+
const moneyLine = (one, titles) => {
|
|
198
|
+
const data = one.data;
|
|
199
|
+
const asks = data.asks > 1 && data.lastAsked ? ` (asked ${data.asks}×, last ${day(data.lastAsked)})` : "";
|
|
200
|
+
const where = one.chat === null ? "" : ` · ${titles.get(one.chat) ?? one.chat}`;
|
|
201
|
+
const words = data.direction.replace("_", " ");
|
|
202
|
+
const sum = `${data.amount} ${data.currency ?? "?"} ${data.state} since ${day(data.since)}`;
|
|
203
|
+
return ` ${words.padEnd(7)} ${sum}${asks}${where} · ${one.evidence[0]?.ref ?? ""} [${one.basis}]`;
|
|
204
|
+
};
|
|
205
|
+
/** The human form: header, money, a line per chat with what is open, then the steps. */
|
|
206
|
+
export const projectStatusText = (found, hints) => {
|
|
207
|
+
const titles = new Map(found.chats.map((chat) => [chat.ref, chat.title]));
|
|
208
|
+
const { next } = projectStatusAnswer(found, hints);
|
|
209
|
+
const money = found.items.filter((one) => one.signal === "amounts" && one.data.state !== "mentioned");
|
|
210
|
+
const payments = found.items.filter((one) => one.signal === "payments");
|
|
211
|
+
const children = found.items.filter((one) => one.signal === "children");
|
|
212
|
+
const key = found.project.key ? `${found.project.key} · ` : "";
|
|
213
|
+
const lines = [
|
|
214
|
+
`${key}${found.project.name} · ${found.chats.length} linked chats in ${found.accounts.length} accounts, ` +
|
|
215
|
+
`${day(found.window.since)} to ${day(found.window.until)}`,
|
|
216
|
+
];
|
|
217
|
+
if (money.length || payments.length) {
|
|
218
|
+
lines.push("Money");
|
|
219
|
+
for (const one of money)
|
|
220
|
+
lines.push(moneyLine(one, titles));
|
|
221
|
+
for (const one of payments) {
|
|
222
|
+
const data = one.data;
|
|
223
|
+
lines.push(` payment ${data.title} · ${one.evidence[0]?.ref ?? ""} [${data.status}]`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (found.chats.length)
|
|
227
|
+
lines.push("Chats");
|
|
228
|
+
for (const chat of found.chats)
|
|
229
|
+
for (const line of chatLine(found, chat))
|
|
230
|
+
lines.push(line);
|
|
231
|
+
if (children.length)
|
|
232
|
+
lines.push("Children");
|
|
233
|
+
for (const one of children) {
|
|
234
|
+
const data = one.data;
|
|
235
|
+
const cut = one.data.cut;
|
|
236
|
+
lines.push(` ${cut ? `${data.child} not read (${cut})` : `${data.key ?? data.child} · ${data.name} · ${data.chats} chats`}`);
|
|
237
|
+
}
|
|
238
|
+
if (found.outOfScope.length)
|
|
239
|
+
lines.push(`Not read here: ${found.outOfScope.map((one) => `${one.chat} (${one.reason})`).join(", ")}`);
|
|
240
|
+
for (const one of found.failed)
|
|
241
|
+
lines.push(`Signal ${one.signal} failed: ${one.why}`);
|
|
242
|
+
if (next.length)
|
|
243
|
+
lines.push("Next");
|
|
244
|
+
next.forEach((step, index) => {
|
|
245
|
+
lines.push(` ${index + 1}. ${hints.line(step)}`);
|
|
246
|
+
});
|
|
247
|
+
return lines.join("\n");
|
|
248
|
+
};
|
package/dist/cli/steps.js
CHANGED
|
@@ -48,7 +48,10 @@ export const STEPS = defineSteps([
|
|
|
48
48
|
{
|
|
49
49
|
id: "messages.list",
|
|
50
50
|
command: "messages list",
|
|
51
|
-
args: [
|
|
51
|
+
args: [
|
|
52
|
+
{ name: "chat", required: true },
|
|
53
|
+
{ name: "query", required: false },
|
|
54
|
+
],
|
|
52
55
|
why: "only the newest were read here; this reads the chat itself",
|
|
53
56
|
},
|
|
54
57
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { FACT_TYPES } from "../meetings/index.js";
|
|
2
2
|
export declare const FACT_STATUSES: readonly ["proposed", "accepted", "superseded", "reversed", "rejected"];
|
|
3
3
|
export declare const MEMORY_KINDS: readonly ["summary", "digest", "preference"];
|
|
4
4
|
export declare const MEMORY_STATUSES: readonly ["proposed", "confirmed", "stale", "superseded"];
|
package/dist/domain/knowledge.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TASK_KINDS } from "../tasks/index.js";
|
|
2
|
-
export
|
|
2
|
+
export { FACT_TYPES } from "../meetings/index.js";
|
|
3
3
|
export const FACT_STATUSES = ["proposed", "accepted", "superseded", "reversed", "rejected"];
|
|
4
4
|
export const MEMORY_KINDS = ["summary", "digest", "preference"];
|
|
5
5
|
export const MEMORY_STATUSES = ["proposed", "confirmed", "stale", "superseded"];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Word patterns for project status, ru/en/es, matched on the text as written (case folded here). A stem cannot tell
|
|
3
|
+
* `оплатил` from `оплати`, so the past forms a money stem shares with a request are listed whole: a message with one
|
|
4
|
+
* of them reads as "done", whatever stems it also hits.
|
|
5
|
+
*/
|
|
6
|
+
const words = (forms) => new RegExp(`(?<![\\p{L}\\p{N}])(?:${forms.join("|")})(?![\\p{L}\\p{N}])`, "iu");
|
|
7
|
+
export const MONEY_DONE_FORMS = words([
|
|
8
|
+
"оплатил[аи]?",
|
|
9
|
+
"заплатил[аи]?",
|
|
10
|
+
"перевел[аи]?",
|
|
11
|
+
"перевёл",
|
|
12
|
+
"отправил[аи]?",
|
|
13
|
+
"оплачено",
|
|
14
|
+
"переведено",
|
|
15
|
+
"paid",
|
|
16
|
+
"transferred",
|
|
17
|
+
"pagué",
|
|
18
|
+
"pagado",
|
|
19
|
+
"transferí",
|
|
20
|
+
]);
|
|
21
|
+
/** First person future: "I'll send", "сделаю", "lo envío". Labelled a guess wherever it is shown. */
|
|
22
|
+
export const PROMISE_FORMS = words([
|
|
23
|
+
"сделаю",
|
|
24
|
+
"пришлю",
|
|
25
|
+
"отправлю",
|
|
26
|
+
"подготовлю",
|
|
27
|
+
"проверю",
|
|
28
|
+
"напишу",
|
|
29
|
+
"позвоню",
|
|
30
|
+
"скину",
|
|
31
|
+
"вышлю",
|
|
32
|
+
"оплачу",
|
|
33
|
+
"будет готов[аоы]?",
|
|
34
|
+
"i'?ll (?:send|do|check|call|write|pay|prepare|share|fix)",
|
|
35
|
+
"i will (?:send|do|check|call|write|pay|prepare|share|fix)",
|
|
36
|
+
"will be ready",
|
|
37
|
+
"lo envío",
|
|
38
|
+
"te envío",
|
|
39
|
+
"enviaré",
|
|
40
|
+
"haré",
|
|
41
|
+
"mandaré",
|
|
42
|
+
"te llamo",
|
|
43
|
+
"estará listo",
|
|
44
|
+
]);
|
package/dist/entities/fact.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as v from "valibot";
|
|
|
2
2
|
export declare const fact: v.StrictObjectSchema<{
|
|
3
3
|
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
4
4
|
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
5
|
-
readonly kind: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise"], undefined>;
|
|
5
|
+
readonly kind: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise", "payment"], undefined>;
|
|
6
6
|
readonly text: v.StringSchema<undefined>;
|
|
7
7
|
readonly status: v.PicklistSchema<readonly ["proposed", "accepted", "superseded", "reversed", "rejected"], undefined>;
|
|
8
8
|
readonly project: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
@@ -29,6 +29,17 @@ export declare const fact: v.StrictObjectSchema<{
|
|
|
29
29
|
/** Who recorded it: the owner, or an agent whose fact waits as proposed. */
|
|
30
30
|
readonly origin: v.PicklistSchema<["owner", "agent"], undefined>;
|
|
31
31
|
readonly evidence: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
32
|
+
/** A `payment` fact's fields. */
|
|
33
|
+
readonly payment: v.OptionalSchema<v.NullableSchema<v.StrictObjectSchema<{
|
|
34
|
+
readonly amount: v.StringSchema<undefined>;
|
|
35
|
+
readonly currency: v.StringSchema<undefined>;
|
|
36
|
+
readonly direction: v.PicklistSchema<readonly ["to_us", "from_us"], undefined>;
|
|
37
|
+
readonly counterparty: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
38
|
+
readonly counterparty_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
39
|
+
readonly due_at: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
40
|
+
readonly state: v.PicklistSchema<readonly ["expected", "paid", "cancelled"], undefined>;
|
|
41
|
+
readonly item: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
42
|
+
}, undefined>, undefined>, undefined>;
|
|
32
43
|
/** With `--sources`: each piece of evidence read back. */
|
|
33
44
|
readonly sources: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
34
45
|
readonly ref: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
package/dist/entities/fact.js
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
import { FACT_STATUSES, FACT_TYPES, MEMORY_SCOPES } from "../domain/knowledge.js";
|
|
3
|
+
import { PAYMENT_DIRECTIONS, PAYMENT_STATES } from "../meetings/index.js";
|
|
3
4
|
import { author, evidenceSource, id, reference, text, time } from "./fields.js";
|
|
5
|
+
const payment = v.strictObject({
|
|
6
|
+
amount: text,
|
|
7
|
+
currency: text,
|
|
8
|
+
direction: v.picklist(PAYMENT_DIRECTIONS),
|
|
9
|
+
counterparty: v.nullable(reference),
|
|
10
|
+
counterparty_name: v.nullable(text),
|
|
11
|
+
due_at: v.nullable(text),
|
|
12
|
+
state: v.picklist(PAYMENT_STATES),
|
|
13
|
+
item: v.nullable(text),
|
|
14
|
+
});
|
|
4
15
|
export const fact = v.strictObject({
|
|
5
16
|
ref: reference,
|
|
6
17
|
id,
|
|
@@ -24,6 +35,8 @@ export const fact = v.strictObject({
|
|
|
24
35
|
/** Who recorded it: the owner, or an agent whose fact waits as proposed. */
|
|
25
36
|
origin: v.picklist(["owner", "agent"]),
|
|
26
37
|
evidence: v.array(reference),
|
|
38
|
+
/** A `payment` fact's fields. */
|
|
39
|
+
payment: v.optional(v.nullable(payment)),
|
|
27
40
|
/** With `--sources`: each piece of evidence read back. */
|
|
28
41
|
sources: v.optional(v.array(evidenceSource)),
|
|
29
42
|
created_at: time,
|
package/dist/entities/index.d.ts
CHANGED
|
@@ -1099,6 +1099,7 @@ export declare const ENTITIES: {
|
|
|
1099
1099
|
readonly reached_since: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
1100
1100
|
readonly reached_last: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
1101
1101
|
readonly stopped: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
1102
|
+
readonly limited: v.OptionalSchema<v.PicklistSchema<["group_too_large", "older_than_window"], undefined>, undefined>;
|
|
1102
1103
|
readonly tasks: v.OptionalSchema<v.StrictObjectSchema<{
|
|
1103
1104
|
readonly added: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
1104
1105
|
readonly closed: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -1145,6 +1146,11 @@ export declare const ENTITIES: {
|
|
|
1145
1146
|
readonly retryable: v.BooleanSchema<undefined>;
|
|
1146
1147
|
readonly retry_after_ms: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1147
1148
|
}, v.UnknownSchema, undefined>, undefined>;
|
|
1149
|
+
readonly limited: v.OptionalSchema<v.PicklistSchema<["group_too_large", "older_than_window"], undefined>, undefined>;
|
|
1150
|
+
}, undefined>, undefined>;
|
|
1151
|
+
readonly limited: v.OptionalSchema<v.StrictObjectSchema<{
|
|
1152
|
+
readonly group_too_large: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
1153
|
+
readonly older_than_window: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
1148
1154
|
}, undefined>, undefined>;
|
|
1149
1155
|
readonly tasks: v.OptionalSchema<v.StrictObjectSchema<{
|
|
1150
1156
|
readonly added: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -5448,7 +5454,7 @@ export declare const ENTITIES: {
|
|
|
5448
5454
|
readonly fact: v.StrictObjectSchema<{
|
|
5449
5455
|
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
5450
5456
|
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
5451
|
-
readonly kind: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise"], undefined>;
|
|
5457
|
+
readonly kind: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise", "payment"], undefined>;
|
|
5452
5458
|
readonly text: v.StringSchema<undefined>;
|
|
5453
5459
|
readonly status: v.PicklistSchema<readonly ["proposed", "accepted", "superseded", "reversed", "rejected"], undefined>;
|
|
5454
5460
|
readonly project: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
@@ -5471,6 +5477,16 @@ export declare const ENTITIES: {
|
|
|
5471
5477
|
readonly scope: v.NullableSchema<v.PicklistSchema<readonly ["personal", "work"], undefined>, undefined>;
|
|
5472
5478
|
readonly origin: v.PicklistSchema<["owner", "agent"], undefined>;
|
|
5473
5479
|
readonly evidence: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
5480
|
+
readonly payment: v.OptionalSchema<v.NullableSchema<v.StrictObjectSchema<{
|
|
5481
|
+
readonly amount: v.StringSchema<undefined>;
|
|
5482
|
+
readonly currency: v.StringSchema<undefined>;
|
|
5483
|
+
readonly direction: v.PicklistSchema<readonly ["to_us", "from_us"], undefined>;
|
|
5484
|
+
readonly counterparty: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
5485
|
+
readonly counterparty_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
5486
|
+
readonly due_at: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
5487
|
+
readonly state: v.PicklistSchema<readonly ["expected", "paid", "cancelled"], undefined>;
|
|
5488
|
+
readonly item: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
5489
|
+
}, undefined>, undefined>, undefined>;
|
|
5474
5490
|
readonly sources: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
5475
5491
|
readonly ref: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
5476
5492
|
readonly kind: v.StringSchema<undefined>;
|
|
@@ -6257,7 +6273,7 @@ export declare const ENTITIES: {
|
|
|
6257
6273
|
readonly fingerprint: v.StringSchema<undefined>;
|
|
6258
6274
|
}, undefined>, undefined>;
|
|
6259
6275
|
readonly kind: v.LiteralSchema<"fact", undefined>;
|
|
6260
|
-
readonly type: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise"], undefined>;
|
|
6276
|
+
readonly type: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise", "payment"], undefined>;
|
|
6261
6277
|
readonly statement: v.StringSchema<undefined>;
|
|
6262
6278
|
}, undefined>, v.StrictObjectSchema<{
|
|
6263
6279
|
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
@@ -17,7 +17,7 @@ export declare const meetingFindings: v.StrictObjectSchema<{
|
|
|
17
17
|
readonly fingerprint: v.StringSchema<undefined>;
|
|
18
18
|
}, undefined>, undefined>;
|
|
19
19
|
readonly kind: v.LiteralSchema<"fact", undefined>;
|
|
20
|
-
readonly type: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise"], undefined>;
|
|
20
|
+
readonly type: v.PicklistSchema<readonly ["fact", "statement", "question", "decision", "promise", "payment"], undefined>;
|
|
21
21
|
readonly statement: v.StringSchema<undefined>;
|
|
22
22
|
}, undefined>, v.StrictObjectSchema<{
|
|
23
23
|
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
@@ -202,6 +202,8 @@ export declare const messageSyncChat: v.StrictObjectSchema<{
|
|
|
202
202
|
readonly reached_since: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
203
203
|
readonly reached_last: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
204
204
|
readonly stopped: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
205
|
+
/** The history limits stopped the read: a group too large to read, or the window's start reached. */
|
|
206
|
+
readonly limited: v.OptionalSchema<v.PicklistSchema<["group_too_large", "older_than_window"], undefined>, undefined>;
|
|
205
207
|
readonly tasks: v.OptionalSchema<v.StrictObjectSchema<{
|
|
206
208
|
readonly added: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
207
209
|
readonly closed: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -250,6 +252,12 @@ export declare const messageSyncAll: v.StrictObjectSchema<{
|
|
|
250
252
|
readonly retryable: v.BooleanSchema<undefined>;
|
|
251
253
|
readonly retry_after_ms: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
252
254
|
}, v.UnknownSchema, undefined>, undefined>;
|
|
255
|
+
readonly limited: v.OptionalSchema<v.PicklistSchema<["group_too_large", "older_than_window"], undefined>, undefined>;
|
|
256
|
+
}, undefined>, undefined>;
|
|
257
|
+
/** How many chats the history limits left unread (big groups) or read only to the window's start. */
|
|
258
|
+
readonly limited: v.OptionalSchema<v.StrictObjectSchema<{
|
|
259
|
+
readonly group_too_large: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
260
|
+
readonly older_than_window: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
253
261
|
}, undefined>, undefined>;
|
|
254
262
|
readonly tasks: v.OptionalSchema<v.StrictObjectSchema<{
|
|
255
263
|
readonly added: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -328,6 +336,8 @@ export declare const messageSync: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
328
336
|
readonly reached_since: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
329
337
|
readonly reached_last: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
330
338
|
readonly stopped: v.OptionalSchema<v.LiteralSchema<true, undefined>, undefined>;
|
|
339
|
+
/** The history limits stopped the read: a group too large to read, or the window's start reached. */
|
|
340
|
+
readonly limited: v.OptionalSchema<v.PicklistSchema<["group_too_large", "older_than_window"], undefined>, undefined>;
|
|
331
341
|
readonly tasks: v.OptionalSchema<v.StrictObjectSchema<{
|
|
332
342
|
readonly added: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
333
343
|
readonly closed: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -375,6 +385,12 @@ export declare const messageSync: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
375
385
|
readonly retryable: v.BooleanSchema<undefined>;
|
|
376
386
|
readonly retry_after_ms: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
377
387
|
}, v.UnknownSchema, undefined>, undefined>;
|
|
388
|
+
readonly limited: v.OptionalSchema<v.PicklistSchema<["group_too_large", "older_than_window"], undefined>, undefined>;
|
|
389
|
+
}, undefined>, undefined>;
|
|
390
|
+
/** How many chats the history limits left unread (big groups) or read only to the window's start. */
|
|
391
|
+
readonly limited: v.OptionalSchema<v.StrictObjectSchema<{
|
|
392
|
+
readonly group_too_large: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
393
|
+
readonly older_than_window: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
378
394
|
}, undefined>, undefined>;
|
|
379
395
|
readonly tasks: v.OptionalSchema<v.StrictObjectSchema<{
|
|
380
396
|
readonly added: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -46,6 +46,7 @@ const tasks = v.optional(v.strictObject({
|
|
|
46
46
|
held: v.optional(count),
|
|
47
47
|
held_chats: v.optional(count),
|
|
48
48
|
}));
|
|
49
|
+
const historyLimited = v.picklist(["group_too_large", "older_than_window"]);
|
|
49
50
|
export const messageSyncChat = v.strictObject({
|
|
50
51
|
issue: v.optional(actionableError),
|
|
51
52
|
resume: v.optional(v.strictObject({ before: v.optional(text) })),
|
|
@@ -59,6 +60,8 @@ export const messageSyncChat = v.strictObject({
|
|
|
59
60
|
reached_since: v.optional(v.literal(true)),
|
|
60
61
|
reached_last: v.optional(v.literal(true)),
|
|
61
62
|
stopped: v.optional(v.literal(true)),
|
|
63
|
+
/** The history limits stopped the read: a group too large to read, or the window's start reached. */
|
|
64
|
+
limited: v.optional(historyLimited),
|
|
62
65
|
tasks,
|
|
63
66
|
/** `--full-history`: the chat's pushed history is now kept in full; `false` when the store does not know the chat. */
|
|
64
67
|
history_included: v.optional(v.boolean()),
|
|
@@ -78,7 +81,10 @@ export const messageSyncAll = v.strictObject({
|
|
|
78
81
|
stopped: v.optional(v.literal(true)),
|
|
79
82
|
error: v.optional(text),
|
|
80
83
|
issue: v.optional(actionableError),
|
|
84
|
+
limited: v.optional(historyLimited),
|
|
81
85
|
})),
|
|
86
|
+
/** How many chats the history limits left unread (big groups) or read only to the window's start. */
|
|
87
|
+
limited: v.optional(v.strictObject({ group_too_large: count, older_than_window: count })),
|
|
82
88
|
tasks,
|
|
83
89
|
});
|
|
84
90
|
export const messageSyncStarted = v.strictObject({ job: id, pid: count, chat: text, log: text });
|
package/dist/errors/reasons.js
CHANGED
|
@@ -50,6 +50,7 @@ const OTHERS = [
|
|
|
50
50
|
validation("extraction.text-too-long", "the text is too long for memory extraction"),
|
|
51
51
|
validation("file.locked", "another process holds the file's lock"),
|
|
52
52
|
["mail.source-failed", "provider_error", "the mail server refused or did not complete a request"],
|
|
53
|
+
["mail.search-refused", "provider_error", "the mail server refused to search a folder"],
|
|
53
54
|
["mirror.partial", "provider_error", "some mirrored files were not synced"],
|
|
54
55
|
["profile.wrong-account", "authentication_error", "the signed-in source account does not match this profile"],
|
|
55
56
|
validation("push.too-many-files", "the folder holds more files than one push takes"),
|
package/dist/mail/partial.d.ts
CHANGED
|
@@ -6,16 +6,22 @@ import type { MailSource } from "./source.js";
|
|
|
6
6
|
export declare const PARTIAL = "partial";
|
|
7
7
|
/** How many partial emails one sync reads whole at most; the rest wait for the next run. */
|
|
8
8
|
export declare const PARTIAL_PER_RUN = 100;
|
|
9
|
+
/** Failed reads after which a partial email is given up on (`partial.stuck`) and stays as it is. */
|
|
10
|
+
export declare const PARTIAL_TRIES = 3;
|
|
9
11
|
export interface PartialOutcome {
|
|
10
12
|
/** Read whole this run, the mark cleared. */
|
|
11
13
|
completed: number;
|
|
12
|
-
/** Still partial after this run. */
|
|
14
|
+
/** Still partial after this run, tried again by the next. */
|
|
13
15
|
left: number;
|
|
16
|
+
/** Given up on: the server no longer gives this email at its stored place. They stay readable as they are. */
|
|
17
|
+
stuck: number;
|
|
14
18
|
}
|
|
15
19
|
/**
|
|
16
20
|
* Reads whole the emails a server search stored from their first bytes, so the archive holds their attachments too.
|
|
17
|
-
* Sync never reads stored mail again, so without this step a partial email would stay partial.
|
|
18
|
-
*
|
|
21
|
+
* Sync never reads stored mail again, so without this step a partial email would stay partial. A source with `find`
|
|
22
|
+
* finds them by id; elsewhere they are read at their newest stored location under its UIDVALIDITY, trusted only when
|
|
23
|
+
* `identify` gives the stored id for the bytes read there. Each failed read is counted, and after `PARTIAL_TRIES`, or
|
|
24
|
+
* at once when the place holds another message, the email is left partial for good.
|
|
19
25
|
*/
|
|
20
26
|
export declare const completePartial: ({ store, source, accountId, address, folders, maxBodyChars, maxAttachmentChars, loadEngine, now, take, signal, }: {
|
|
21
27
|
store: MessageStore;
|