@wirecat/cli-core 0.573.0 → 0.575.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 +26 -0
- package/dist/botcheck/registries.js +10 -7
- package/dist/calendar/feeds.js +7 -3
- package/dist/calendar/mcp/index.d.ts +12 -12
- package/dist/cli/findings-input.js +6 -0
- package/dist/cli/messenger/serve-catch-up.js +3 -2
- package/dist/domain/orders.d.ts +19 -0
- package/dist/domain/orders.js +12 -0
- package/dist/domain/ref-summaries.js +1 -0
- package/dist/domain/references.d.ts +1 -1
- package/dist/domain/references.js +1 -0
- package/dist/entities/index.d.ts +75 -0
- package/dist/entities/mail-findings.d.ts +75 -0
- package/dist/entities/mail-findings.js +62 -0
- package/dist/errors/reasons.js +5 -0
- package/dist/http/time-limit.d.ts +11 -0
- package/dist/http/time-limit.js +20 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mail/findings.d.ts +73 -1
- package/dist/mail/findings.js +164 -1
- package/dist/models/openai.js +4 -3
- package/dist/oauth/requests.js +10 -6
- package/dist/services/proposals/kinds/mail-findings.js +9 -0
- package/dist/services/proposals/kinds/orders.d.ts +4 -0
- package/dist/services/proposals/kinds/orders.js +32 -0
- package/dist/services/proposals/registry.js +2 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/store/sqlite/entity-types.d.ts +1 -0
- package/dist/store/sqlite/entity-types.js +1 -0
- package/dist/store/sqlite/finance.d.ts +40 -2
- package/dist/store/sqlite/finance.js +48 -42
- package/dist/store/sqlite/knowledge.js +2 -1
- package/dist/store/sqlite/mail-findings.js +81 -1
- package/dist/store/sqlite/manifest.js +2 -0
- package/dist/store/sqlite/migrations.generated.js +20 -0
- package/dist/store/sqlite/orders.d.ts +84 -0
- package/dist/store/sqlite/orders.js +186 -0
- package/dist/store/sqlite/ref-summaries.js +10 -0
- package/dist/store/sqlite/schema.d.ts +440 -0
- package/dist/store/sqlite/schema.js +38 -0
- package/dist/store/sqlite/things.js +1 -0
- package/dist/store/store.d.ts +3 -0
- package/dist/store/store.js +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ shape of this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.575.0 — 05.11.2026
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Orders in the store (store version 50).** `store.orders` keeps what the owner, his business or a client ordered:
|
|
15
|
+
for whom (`customer`, the owner when left out) and why (`purpose`: `personal`, `business`, `client`, `other`), the
|
|
16
|
+
shop as its mail names it with an optional `supplier` reference, the shop's number, amount and currency, the status
|
|
17
|
+
(`placed`, `shipped`, `delivered`, `cancelled`, `returned`), the order and delivery days, and links to an invoice and
|
|
18
|
+
a payment. The owner's entry is confirmed at once; an agent's is an `order` proposal (`order:<id>`) only the owner
|
|
19
|
+
decides. One shop's number is stored once (`order.duplicate`), and only the owner moves an order's status on.
|
|
20
|
+
- **Mail findings take invoices, payments and orders.** A `mail_findings` batch now takes the kinds `invoice`,
|
|
21
|
+
`payment`, `order` and `order_update` (a later mail's status for a stored order, found by `supplier_name` and
|
|
22
|
+
`number`). Staging checks each the way `store.finance` and `store.orders` check the owner's own entry and refuses
|
|
23
|
+
the batch with that reason; nothing is written until the owner accepts, which records the confirmed row with the
|
|
24
|
+
cited mail as its evidence. The agent still only proposes.
|
|
25
|
+
|
|
26
|
+
## 0.574.0 — 05.11.2026
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **A finished request no longer keeps the command in memory until its time limit ends.** The limit was a timer that
|
|
31
|
+
ran to the end even after the answer came, and it held everything the command had loaded; tg-cli and max-cli
|
|
32
|
+
already fixed the same thing in their own requests, and tg ran out of memory on macOS before that. This covers the
|
|
33
|
+
OAuth token and revoke requests, the OpenAI model request, the bot-registry checks, calendar feeds and serve's
|
|
34
|
+
catch-up on start. `timeLimit` and `withTimeLimit` (`src/http/time-limit.ts`) are the stoppable limit now.
|
|
35
|
+
|
|
10
36
|
## 0.573.0 — 05.11.2026
|
|
11
37
|
|
|
12
38
|
### Added
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withTimeLimit } from "../http/time-limit.js";
|
|
1
2
|
/** Where each one is documented, for the help text and the MCP description. */
|
|
2
3
|
export const REGISTRIES = {
|
|
3
4
|
cas: { title: "Combot Anti-Spam (CAS)", docs: "https://cas.chat/api" },
|
|
@@ -12,17 +13,19 @@ const TIMEOUT_MS = 10_000;
|
|
|
12
13
|
export const askRegistries = async (id, options = {}) => Promise.all([askCas(id, options), askLols(id, options)]);
|
|
13
14
|
const getJson = async (url, headers, { fetch: fetchFn = fetch, timeoutMs = TIMEOUT_MS }) => {
|
|
14
15
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const { status, text } = await withTimeLimit(timeoutMs, async (signal) => {
|
|
17
|
+
const response = await fetchFn(url, {
|
|
18
|
+
headers: { accept: "application/json", ...headers },
|
|
19
|
+
signal,
|
|
20
|
+
redirect: "error",
|
|
21
|
+
});
|
|
22
|
+
return { status: response.status, text: await response.text() };
|
|
19
23
|
});
|
|
20
|
-
const text = await response.text();
|
|
21
24
|
try {
|
|
22
|
-
return { status
|
|
25
|
+
return { status, body: JSON.parse(text) };
|
|
23
26
|
}
|
|
24
27
|
catch {
|
|
25
|
-
return { failed: `answered ${
|
|
28
|
+
return { failed: `answered ${status} with something that is not JSON` };
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
catch (error) {
|
package/dist/calendar/feeds.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
2
2
|
import { CliError, isCliError } from "@wirecat/cli-base";
|
|
3
3
|
import { zonedMoment } from "@wirecat/cli-base/query";
|
|
4
4
|
import { runBudget } from "../background/budget.js";
|
|
5
|
+
import { timeLimit } from "../http/time-limit.js";
|
|
5
6
|
import { calendarText, joinUrlWithoutQuery } from "../meetings/index.js";
|
|
6
7
|
import { expandSeries, unexpandable } from "./expand.js";
|
|
7
8
|
import { readIcs } from "./ics.js";
|
|
@@ -72,8 +73,8 @@ export const fetchFeedIfChanged = async (address, options) => {
|
|
|
72
73
|
...(since?.lastModified ? { "if-modified-since": since.lastModified } : {}),
|
|
73
74
|
};
|
|
74
75
|
const run = options.fetch ?? fetch;
|
|
75
|
-
const timeout =
|
|
76
|
-
const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
|
|
76
|
+
const timeout = timeLimit(limits.timeoutMs);
|
|
77
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeout.signal]) : timeout.signal;
|
|
77
78
|
let url = feedAddress(address);
|
|
78
79
|
try {
|
|
79
80
|
for (let hop = 0;; hop++) {
|
|
@@ -122,7 +123,7 @@ export const fetchFeedIfChanged = async (address, options) => {
|
|
|
122
123
|
throw error;
|
|
123
124
|
if (options.signal?.aborted)
|
|
124
125
|
throw new CliError("cancelled", `reading ${name} was cancelled`);
|
|
125
|
-
if (timeout.aborted)
|
|
126
|
+
if (timeout.signal.aborted)
|
|
126
127
|
throw new CliError("timeout", `${name} did not answer within ${Math.round(limits.timeoutMs / 1000)} s`, {
|
|
127
128
|
reason: "feed.timeout",
|
|
128
129
|
retryable: true,
|
|
@@ -134,6 +135,9 @@ export const fetchFeedIfChanged = async (address, options) => {
|
|
|
134
135
|
retryable: true,
|
|
135
136
|
});
|
|
136
137
|
}
|
|
138
|
+
finally {
|
|
139
|
+
timeout.clear();
|
|
140
|
+
}
|
|
137
141
|
};
|
|
138
142
|
const SPAN = { start: 0, end: 0 };
|
|
139
143
|
const firstLink = (text) => text?.match(/https?:\/\/[^\s<>"')\]]+/iu)?.[0];
|
|
@@ -10,13 +10,13 @@ export declare const calendarTools: ({
|
|
|
10
10
|
inputSchema: {
|
|
11
11
|
type: string;
|
|
12
12
|
properties: {
|
|
13
|
+
limit?: undefined;
|
|
13
14
|
account_id: {
|
|
14
15
|
type: string;
|
|
15
16
|
minimum: number;
|
|
16
17
|
};
|
|
17
18
|
query?: undefined;
|
|
18
19
|
timezone?: undefined;
|
|
19
|
-
limit?: undefined;
|
|
20
20
|
page?: undefined;
|
|
21
21
|
event?: undefined;
|
|
22
22
|
} | {
|
|
@@ -45,9 +45,9 @@ export declare const calendarTools: ({
|
|
|
45
45
|
};
|
|
46
46
|
event?: undefined;
|
|
47
47
|
} | {
|
|
48
|
+
limit?: undefined;
|
|
48
49
|
query?: undefined;
|
|
49
50
|
timezone?: undefined;
|
|
50
|
-
limit?: undefined;
|
|
51
51
|
page?: undefined;
|
|
52
52
|
event: {
|
|
53
53
|
type: string;
|
|
@@ -58,9 +58,9 @@ export declare const calendarTools: ({
|
|
|
58
58
|
minimum: number;
|
|
59
59
|
};
|
|
60
60
|
} | {
|
|
61
|
+
limit?: undefined;
|
|
61
62
|
query?: undefined;
|
|
62
63
|
timezone?: undefined;
|
|
63
|
-
limit?: undefined;
|
|
64
64
|
page?: undefined;
|
|
65
65
|
event?: undefined;
|
|
66
66
|
account_id?: undefined;
|
|
@@ -80,13 +80,13 @@ export declare const calendarTools: ({
|
|
|
80
80
|
inputSchema: {
|
|
81
81
|
type: string;
|
|
82
82
|
properties: {
|
|
83
|
+
limit?: undefined;
|
|
83
84
|
account_id: {
|
|
84
85
|
type: string;
|
|
85
86
|
minimum: number;
|
|
86
87
|
};
|
|
87
88
|
query?: undefined;
|
|
88
89
|
timezone?: undefined;
|
|
89
|
-
limit?: undefined;
|
|
90
90
|
page?: undefined;
|
|
91
91
|
event?: undefined;
|
|
92
92
|
} | {
|
|
@@ -115,9 +115,9 @@ export declare const calendarTools: ({
|
|
|
115
115
|
};
|
|
116
116
|
event?: undefined;
|
|
117
117
|
} | {
|
|
118
|
+
limit?: undefined;
|
|
118
119
|
query?: undefined;
|
|
119
120
|
timezone?: undefined;
|
|
120
|
-
limit?: undefined;
|
|
121
121
|
page?: undefined;
|
|
122
122
|
event: {
|
|
123
123
|
type: string;
|
|
@@ -128,9 +128,9 @@ export declare const calendarTools: ({
|
|
|
128
128
|
minimum: number;
|
|
129
129
|
};
|
|
130
130
|
} | {
|
|
131
|
+
limit?: undefined;
|
|
131
132
|
query?: undefined;
|
|
132
133
|
timezone?: undefined;
|
|
133
|
-
limit?: undefined;
|
|
134
134
|
page?: undefined;
|
|
135
135
|
event?: undefined;
|
|
136
136
|
account_id?: undefined;
|
|
@@ -150,13 +150,13 @@ export declare const calendarTools: ({
|
|
|
150
150
|
inputSchema: {
|
|
151
151
|
type: string;
|
|
152
152
|
properties: {
|
|
153
|
+
limit?: undefined;
|
|
153
154
|
account_id: {
|
|
154
155
|
type: string;
|
|
155
156
|
minimum: number;
|
|
156
157
|
};
|
|
157
158
|
query?: undefined;
|
|
158
159
|
timezone?: undefined;
|
|
159
|
-
limit?: undefined;
|
|
160
160
|
page?: undefined;
|
|
161
161
|
event?: undefined;
|
|
162
162
|
} | {
|
|
@@ -185,9 +185,9 @@ export declare const calendarTools: ({
|
|
|
185
185
|
};
|
|
186
186
|
event?: undefined;
|
|
187
187
|
} | {
|
|
188
|
+
limit?: undefined;
|
|
188
189
|
query?: undefined;
|
|
189
190
|
timezone?: undefined;
|
|
190
|
-
limit?: undefined;
|
|
191
191
|
page?: undefined;
|
|
192
192
|
event: {
|
|
193
193
|
type: string;
|
|
@@ -198,9 +198,9 @@ export declare const calendarTools: ({
|
|
|
198
198
|
minimum: number;
|
|
199
199
|
};
|
|
200
200
|
} | {
|
|
201
|
+
limit?: undefined;
|
|
201
202
|
query?: undefined;
|
|
202
203
|
timezone?: undefined;
|
|
203
|
-
limit?: undefined;
|
|
204
204
|
page?: undefined;
|
|
205
205
|
event?: undefined;
|
|
206
206
|
account_id?: undefined;
|
|
@@ -220,13 +220,13 @@ export declare const calendarTools: ({
|
|
|
220
220
|
inputSchema: {
|
|
221
221
|
type: string;
|
|
222
222
|
properties: {
|
|
223
|
+
limit?: undefined;
|
|
223
224
|
account_id: {
|
|
224
225
|
type: string;
|
|
225
226
|
minimum: number;
|
|
226
227
|
};
|
|
227
228
|
query?: undefined;
|
|
228
229
|
timezone?: undefined;
|
|
229
|
-
limit?: undefined;
|
|
230
230
|
page?: undefined;
|
|
231
231
|
event?: undefined;
|
|
232
232
|
} | {
|
|
@@ -255,9 +255,9 @@ export declare const calendarTools: ({
|
|
|
255
255
|
};
|
|
256
256
|
event?: undefined;
|
|
257
257
|
} | {
|
|
258
|
+
limit?: undefined;
|
|
258
259
|
query?: undefined;
|
|
259
260
|
timezone?: undefined;
|
|
260
|
-
limit?: undefined;
|
|
261
261
|
page?: undefined;
|
|
262
262
|
event: {
|
|
263
263
|
type: string;
|
|
@@ -268,9 +268,9 @@ export declare const calendarTools: ({
|
|
|
268
268
|
minimum: number;
|
|
269
269
|
};
|
|
270
270
|
} | {
|
|
271
|
+
limit?: undefined;
|
|
271
272
|
query?: undefined;
|
|
272
273
|
timezone?: undefined;
|
|
273
|
-
limit?: undefined;
|
|
274
274
|
page?: undefined;
|
|
275
275
|
event?: undefined;
|
|
276
276
|
account_id?: undefined;
|
|
@@ -8,6 +8,12 @@ const keys = {
|
|
|
8
8
|
due_evidence: "dueEvidence",
|
|
9
9
|
assignee_evidence: "assigneeEvidence",
|
|
10
10
|
memory_kind: "memoryKind",
|
|
11
|
+
issue_date: "issueDate",
|
|
12
|
+
due_date: "dueDate",
|
|
13
|
+
unit_price: "unitPrice",
|
|
14
|
+
supplier_name: "supplierName",
|
|
15
|
+
order_date: "orderDate",
|
|
16
|
+
fulfilled_date: "fulfilledDate",
|
|
11
17
|
};
|
|
12
18
|
const parseFindingsJson = (text, label, validate) => {
|
|
13
19
|
if (Buffer.byteLength(text, "utf8") > 65536)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { failureKey } from "../../errors/failures.js";
|
|
2
|
+
import { withTimeLimit } from "../../http/time-limit.js";
|
|
2
3
|
/** The provider's own catch-up lands first; this pass then finds most chats already current. */
|
|
3
4
|
export const START_SYNC_DELAY_MS = 30_000;
|
|
4
5
|
export const START_SYNC_BUDGET_MS = 5 * 60_000;
|
|
@@ -19,8 +20,8 @@ export const startSync = ({ chats, newestHeld, fetch, note, warn, delayMs = STAR
|
|
|
19
20
|
let pass = Promise.resolve();
|
|
20
21
|
let started = false;
|
|
21
22
|
let done;
|
|
22
|
-
const run =
|
|
23
|
-
|
|
23
|
+
const run = () => withTimeLimit(budgetMs, (deadline) => catchUp(AbortSignal.any([controller.signal, deadline])));
|
|
24
|
+
const catchUp = async (stop) => {
|
|
24
25
|
const floor = now() - windowMs;
|
|
25
26
|
const moved = [];
|
|
26
27
|
for (const chat of await chats(stop)) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FinanceReview } from "./finance.js";
|
|
2
|
+
export declare const ORDER_STATUSES: readonly ["placed", "shipped", "delivered", "cancelled", "returned"];
|
|
3
|
+
/** Why it was ordered: for the owner himself, for his business, for a client, or anything else. */
|
|
4
|
+
export declare const ORDER_PURPOSES: readonly ["personal", "business", "client", "other"];
|
|
5
|
+
export type OrderStatus = (typeof ORDER_STATUSES)[number];
|
|
6
|
+
export type OrderPurpose = (typeof ORDER_PURPOSES)[number];
|
|
7
|
+
export interface OrderTitleFields {
|
|
8
|
+
id: number;
|
|
9
|
+
number: string | null;
|
|
10
|
+
supplierName: string;
|
|
11
|
+
total: number | null;
|
|
12
|
+
currency: string | null;
|
|
13
|
+
status: OrderStatus;
|
|
14
|
+
review: FinanceReview;
|
|
15
|
+
}
|
|
16
|
+
/** "12345 · Ozon, 2 499.00 RUB (shipped)": a ref summary's title, which `refLabel` prefixes. */
|
|
17
|
+
export declare const orderLine: (order: OrderTitleFields) => string;
|
|
18
|
+
/** "Order 12345 · Ozon, 2 499.00 RUB (shipped)". */
|
|
19
|
+
export declare const orderTitle: (order: OrderTitleFields) => string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { moneyLabel } from "./money.js";
|
|
2
|
+
export const ORDER_STATUSES = ["placed", "shipped", "delivered", "cancelled", "returned"];
|
|
3
|
+
/** Why it was ordered: for the owner himself, for his business, for a client, or anything else. */
|
|
4
|
+
export const ORDER_PURPOSES = ["personal", "business", "client", "other"];
|
|
5
|
+
/** "12345 · Ozon, 2 499.00 RUB (shipped)": a ref summary's title, which `refLabel` prefixes. */
|
|
6
|
+
export const orderLine = (order) => {
|
|
7
|
+
const money = order.total === null || order.currency === null ? "" : `, ${moneyLabel(order.total, order.currency)}`;
|
|
8
|
+
const notes = [order.status, order.review === "confirmed" ? null : order.review].filter(Boolean).join(", ");
|
|
9
|
+
return `${order.number ?? `#${order.id}`} · ${order.supplierName}${money} (${notes})`;
|
|
10
|
+
};
|
|
11
|
+
/** "Order 12345 · Ozon, 2 499.00 RUB (shipped)". */
|
|
12
|
+
export const orderTitle = (order) => `Order ${orderLine(order)}`;
|
|
@@ -33,7 +33,7 @@ export type Reference = {
|
|
|
33
33
|
* Things named by their store id (a task also by its key or the task package's id). `entity` is the name
|
|
34
34
|
* before organizations and projects: it still parses, so an old file's reference resolves as not found.
|
|
35
35
|
*/
|
|
36
|
-
export declare const SIMPLE_REFERENCES: readonly ["note", "document", "person", "organization", "project", "task", "memory", "fact", "bot", "event", "invoice", "payment", "entity"];
|
|
36
|
+
export declare const SIMPLE_REFERENCES: readonly ["note", "document", "person", "organization", "project", "task", "memory", "fact", "bot", "event", "invoice", "payment", "order", "entity"];
|
|
37
37
|
export type SimpleReference = (typeof SIMPLE_REFERENCES)[number];
|
|
38
38
|
export type RefKindName = Exclude<Reference["type"], "entity">;
|
|
39
39
|
export interface RefKindSpec<R extends Reference = Reference> {
|
package/dist/entities/index.d.ts
CHANGED
|
@@ -5966,6 +5966,81 @@ export declare const ENTITIES: {
|
|
|
5966
5966
|
readonly address: v.StringSchema<undefined>;
|
|
5967
5967
|
readonly name: v.StringSchema<undefined>;
|
|
5968
5968
|
readonly reason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5969
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
5970
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
5971
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
5972
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
5973
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
5974
|
+
}, undefined>, undefined>;
|
|
5975
|
+
readonly kind: v.LiteralSchema<"invoice", undefined>;
|
|
5976
|
+
readonly direction: v.PicklistSchema<readonly ["receivable", "payable"], undefined>;
|
|
5977
|
+
readonly counterparty: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
5978
|
+
readonly currency: v.StringSchema<undefined>;
|
|
5979
|
+
readonly lines: v.ArraySchema<v.StrictObjectSchema<{
|
|
5980
|
+
readonly description: v.StringSchema<undefined>;
|
|
5981
|
+
readonly quantity: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5982
|
+
readonly unit_price: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5983
|
+
readonly amount: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5984
|
+
}, undefined>, undefined>;
|
|
5985
|
+
readonly total: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5986
|
+
readonly number: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5987
|
+
readonly issue_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5988
|
+
readonly due_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
5989
|
+
readonly project: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
5990
|
+
readonly reason: v.StringSchema<undefined>;
|
|
5991
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
5992
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
5993
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
5994
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
5995
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
5996
|
+
}, undefined>, undefined>;
|
|
5997
|
+
readonly kind: v.LiteralSchema<"payment", undefined>;
|
|
5998
|
+
readonly direction: v.PicklistSchema<readonly ["in", "out"], undefined>;
|
|
5999
|
+
readonly payer: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6000
|
+
readonly payee: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6001
|
+
readonly amount: v.StringSchema<undefined>;
|
|
6002
|
+
readonly currency: v.StringSchema<undefined>;
|
|
6003
|
+
readonly date: v.StringSchema<undefined>;
|
|
6004
|
+
readonly reference: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6005
|
+
readonly allocations: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
6006
|
+
readonly invoice: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
6007
|
+
readonly amount: v.StringSchema<undefined>;
|
|
6008
|
+
}, undefined>, undefined>, undefined>;
|
|
6009
|
+
readonly project: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6010
|
+
readonly reason: v.StringSchema<undefined>;
|
|
6011
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
6012
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
6013
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
6014
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
6015
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
6016
|
+
}, undefined>, undefined>;
|
|
6017
|
+
readonly kind: v.LiteralSchema<"order", undefined>;
|
|
6018
|
+
readonly purpose: v.PicklistSchema<readonly ["personal", "business", "client", "other"], undefined>;
|
|
6019
|
+
readonly customer: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6020
|
+
readonly supplier: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6021
|
+
readonly supplier_name: v.StringSchema<undefined>;
|
|
6022
|
+
readonly number: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6023
|
+
readonly total: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6024
|
+
readonly currency: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6025
|
+
readonly status: v.OptionalSchema<v.PicklistSchema<readonly ["placed", "shipped", "delivered", "cancelled", "returned"], undefined>, undefined>;
|
|
6026
|
+
readonly order_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6027
|
+
readonly fulfilled_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6028
|
+
readonly invoice: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6029
|
+
readonly payment: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6030
|
+
readonly project: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
6031
|
+
readonly reason: v.StringSchema<undefined>;
|
|
6032
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
6033
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
6034
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
6035
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
6036
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
6037
|
+
}, undefined>, undefined>;
|
|
6038
|
+
readonly kind: v.LiteralSchema<"order_update", undefined>;
|
|
6039
|
+
readonly supplier_name: v.StringSchema<undefined>;
|
|
6040
|
+
readonly number: v.StringSchema<undefined>;
|
|
6041
|
+
readonly status: v.PicklistSchema<readonly ["placed", "shipped", "delivered", "cancelled", "returned"], undefined>;
|
|
6042
|
+
readonly date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6043
|
+
readonly reason: v.StringSchema<undefined>;
|
|
5969
6044
|
}, undefined>], undefined>, undefined>;
|
|
5970
6045
|
}, undefined>;
|
|
5971
6046
|
readonly fingerprint: v.StringSchema<undefined>;
|
|
@@ -81,6 +81,81 @@ export declare const mailFindings: v.StrictObjectSchema<{
|
|
|
81
81
|
readonly address: v.StringSchema<undefined>;
|
|
82
82
|
readonly name: v.StringSchema<undefined>;
|
|
83
83
|
readonly reason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
84
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
85
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
86
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
87
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
88
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
89
|
+
}, undefined>, undefined>;
|
|
90
|
+
readonly kind: v.LiteralSchema<"invoice", undefined>;
|
|
91
|
+
readonly direction: v.PicklistSchema<readonly ["receivable", "payable"], undefined>;
|
|
92
|
+
readonly counterparty: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
93
|
+
readonly currency: v.StringSchema<undefined>;
|
|
94
|
+
readonly lines: v.ArraySchema<v.StrictObjectSchema<{
|
|
95
|
+
readonly description: v.StringSchema<undefined>;
|
|
96
|
+
readonly quantity: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
97
|
+
readonly unit_price: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
98
|
+
readonly amount: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
99
|
+
}, undefined>, undefined>;
|
|
100
|
+
readonly total: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
101
|
+
readonly number: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
102
|
+
readonly issue_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
103
|
+
readonly due_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
104
|
+
readonly project: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
105
|
+
readonly reason: v.StringSchema<undefined>;
|
|
106
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
107
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
108
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
109
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
110
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
111
|
+
}, undefined>, undefined>;
|
|
112
|
+
readonly kind: v.LiteralSchema<"payment", undefined>;
|
|
113
|
+
readonly direction: v.PicklistSchema<readonly ["in", "out"], undefined>;
|
|
114
|
+
readonly payer: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
115
|
+
readonly payee: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
116
|
+
readonly amount: v.StringSchema<undefined>;
|
|
117
|
+
readonly currency: v.StringSchema<undefined>;
|
|
118
|
+
readonly date: v.StringSchema<undefined>;
|
|
119
|
+
readonly reference: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
120
|
+
readonly allocations: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
121
|
+
readonly invoice: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
122
|
+
readonly amount: v.StringSchema<undefined>;
|
|
123
|
+
}, undefined>, undefined>, undefined>;
|
|
124
|
+
readonly project: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
125
|
+
readonly reason: v.StringSchema<undefined>;
|
|
126
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
127
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
128
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
129
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
130
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
131
|
+
}, undefined>, undefined>;
|
|
132
|
+
readonly kind: v.LiteralSchema<"order", undefined>;
|
|
133
|
+
readonly purpose: v.PicklistSchema<readonly ["personal", "business", "client", "other"], undefined>;
|
|
134
|
+
readonly customer: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
135
|
+
readonly supplier: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
136
|
+
readonly supplier_name: v.StringSchema<undefined>;
|
|
137
|
+
readonly number: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
138
|
+
readonly total: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
139
|
+
readonly currency: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
140
|
+
readonly status: v.OptionalSchema<v.PicklistSchema<readonly ["placed", "shipped", "delivered", "cancelled", "returned"], undefined>, undefined>;
|
|
141
|
+
readonly order_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
142
|
+
readonly fulfilled_date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
143
|
+
readonly invoice: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
144
|
+
readonly payment: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
145
|
+
readonly project: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
146
|
+
readonly reason: v.StringSchema<undefined>;
|
|
147
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
148
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
149
|
+
readonly evidence: v.ArraySchema<v.StrictObjectSchema<{
|
|
150
|
+
readonly reference: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
151
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
152
|
+
}, undefined>, undefined>;
|
|
153
|
+
readonly kind: v.LiteralSchema<"order_update", undefined>;
|
|
154
|
+
readonly supplier_name: v.StringSchema<undefined>;
|
|
155
|
+
readonly number: v.StringSchema<undefined>;
|
|
156
|
+
readonly status: v.PicklistSchema<readonly ["placed", "shipped", "delivered", "cancelled", "returned"], undefined>;
|
|
157
|
+
readonly date: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
158
|
+
readonly reason: v.StringSchema<undefined>;
|
|
84
159
|
}, undefined>], undefined>, undefined>;
|
|
85
160
|
}, undefined>;
|
|
86
161
|
readonly fingerprint: v.StringSchema<undefined>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
|
+
import { INVOICE_DIRECTIONS, MONEY_DIRECTIONS } from "../domain/finance.js";
|
|
2
3
|
import { FACT_TYPES, MEMORY_KINDS, MEMORY_SCOPES, WORK_TASK_TYPES } from "../domain/knowledge.js";
|
|
4
|
+
import { ORDER_PURPOSES, ORDER_STATUSES } from "../domain/orders.js";
|
|
3
5
|
import { author, id, reference, text, time } from "./fields.js";
|
|
4
6
|
const evidence = v.strictObject({ reference, fingerprint: text });
|
|
5
7
|
const base = { id, evidence: v.array(evidence) };
|
|
@@ -45,6 +47,66 @@ const finding = v.variant("kind", [
|
|
|
45
47
|
}),
|
|
46
48
|
v.strictObject({ ...base, kind: v.literal("link"), from: reference, to: reference, reason: text }),
|
|
47
49
|
v.strictObject({ ...base, kind: v.literal("new_contact"), address: text, name: text, reason: v.optional(text) }),
|
|
50
|
+
v.strictObject({
|
|
51
|
+
...base,
|
|
52
|
+
kind: v.literal("invoice"),
|
|
53
|
+
direction: v.picklist(INVOICE_DIRECTIONS),
|
|
54
|
+
counterparty: reference,
|
|
55
|
+
currency: text,
|
|
56
|
+
lines: v.array(v.strictObject({
|
|
57
|
+
description: text,
|
|
58
|
+
quantity: v.optional(text),
|
|
59
|
+
unit_price: v.optional(text),
|
|
60
|
+
amount: v.optional(text),
|
|
61
|
+
})),
|
|
62
|
+
total: v.optional(text),
|
|
63
|
+
number: v.optional(text),
|
|
64
|
+
issue_date: v.optional(text),
|
|
65
|
+
due_date: v.optional(text),
|
|
66
|
+
project: v.optional(reference),
|
|
67
|
+
reason: text,
|
|
68
|
+
}),
|
|
69
|
+
v.strictObject({
|
|
70
|
+
...base,
|
|
71
|
+
kind: v.literal("payment"),
|
|
72
|
+
direction: v.picklist(MONEY_DIRECTIONS),
|
|
73
|
+
payer: v.optional(reference),
|
|
74
|
+
payee: v.optional(reference),
|
|
75
|
+
amount: text,
|
|
76
|
+
currency: text,
|
|
77
|
+
date: text,
|
|
78
|
+
reference: v.optional(text),
|
|
79
|
+
allocations: v.optional(v.array(v.strictObject({ invoice: reference, amount: text }))),
|
|
80
|
+
project: v.optional(reference),
|
|
81
|
+
reason: text,
|
|
82
|
+
}),
|
|
83
|
+
v.strictObject({
|
|
84
|
+
...base,
|
|
85
|
+
kind: v.literal("order"),
|
|
86
|
+
purpose: v.picklist(ORDER_PURPOSES),
|
|
87
|
+
customer: v.optional(reference),
|
|
88
|
+
supplier: v.optional(reference),
|
|
89
|
+
supplier_name: text,
|
|
90
|
+
number: v.optional(text),
|
|
91
|
+
total: v.optional(text),
|
|
92
|
+
currency: v.optional(text),
|
|
93
|
+
status: v.optional(v.picklist(ORDER_STATUSES)),
|
|
94
|
+
order_date: v.optional(text),
|
|
95
|
+
fulfilled_date: v.optional(text),
|
|
96
|
+
invoice: v.optional(reference),
|
|
97
|
+
payment: v.optional(reference),
|
|
98
|
+
project: v.optional(reference),
|
|
99
|
+
reason: text,
|
|
100
|
+
}),
|
|
101
|
+
v.strictObject({
|
|
102
|
+
...base,
|
|
103
|
+
kind: v.literal("order_update"),
|
|
104
|
+
supplier_name: text,
|
|
105
|
+
number: text,
|
|
106
|
+
status: v.picklist(ORDER_STATUSES),
|
|
107
|
+
date: v.optional(text),
|
|
108
|
+
reason: text,
|
|
109
|
+
}),
|
|
48
110
|
]);
|
|
49
111
|
const outcome = v.strictObject({
|
|
50
112
|
id,
|
package/dist/errors/reasons.js
CHANGED
|
@@ -197,6 +197,11 @@ const OTHERS = [
|
|
|
197
197
|
validation("money.amount", "the amount is not a decimal string in the currency's scale"),
|
|
198
198
|
validation("money.currency", "the currency is not one the store keeps money in"),
|
|
199
199
|
validation("money.quantity", "the quantity is not a decimal above 0"),
|
|
200
|
+
validation("order.duplicate", "the shop's order with this number is already stored; change its status instead"),
|
|
201
|
+
validation("order.field", "a field of the order is not valid"),
|
|
202
|
+
["order.not-found", "not_found", "no stored order of that shop has that number"],
|
|
203
|
+
validation("order.ref", "the reference names no order, or a shop's number names more than one"),
|
|
204
|
+
validation("order.status", "a rejected or deleted order's status does not change"),
|
|
200
205
|
["model.not-downloaded", "not_found", "the model is not downloaded on this machine"],
|
|
201
206
|
["person.no-owner", "not_found", "no person is marked as the owner in the store"],
|
|
202
207
|
["transcription.no-key", "authentication_error", "no OpenAI key is set for transcription"],
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TimeLimit {
|
|
2
|
+
signal: AbortSignal;
|
|
3
|
+
clear: () => void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A time limit that can be stopped. `AbortSignal.timeout` cannot: its timer runs to the deadline even after the
|
|
7
|
+
* request is done, and keeps the run's whole async context (everything the command loaded) alive until then.
|
|
8
|
+
*/
|
|
9
|
+
export declare const timeLimit: (ms: number) => TimeLimit;
|
|
10
|
+
/** Runs `run` under a time limit and stops the timer when it settles. Whatever `run` reads from the response belongs inside. */
|
|
11
|
+
export declare const withTimeLimit: <T>(ms: number, run: (deadline: AbortSignal) => Promise<T>) => Promise<T>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A time limit that can be stopped. `AbortSignal.timeout` cannot: its timer runs to the deadline even after the
|
|
3
|
+
* request is done, and keeps the run's whole async context (everything the command loaded) alive until then.
|
|
4
|
+
*/
|
|
5
|
+
export const timeLimit = (ms) => {
|
|
6
|
+
const controller = new AbortController();
|
|
7
|
+
const timer = setTimeout(() => controller.abort(new DOMException("The operation timed out.", "TimeoutError")), ms);
|
|
8
|
+
timer.unref();
|
|
9
|
+
return { signal: controller.signal, clear: () => clearTimeout(timer) };
|
|
10
|
+
};
|
|
11
|
+
/** Runs `run` under a time limit and stops the timer when it settles. Whatever `run` reads from the response belongs inside. */
|
|
12
|
+
export const withTimeLimit = async (ms, run) => {
|
|
13
|
+
const limit = timeLimit(ms);
|
|
14
|
+
try {
|
|
15
|
+
return await run(limit.signal);
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
limit.clear();
|
|
19
|
+
}
|
|
20
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { parseMarkdownSpans } from "./domain/markdown-spans.js";
|
|
|
9
9
|
export type { MessageLink, MessagePermalink } from "./domain/message-link.js";
|
|
10
10
|
export type * from "./domain/models.js";
|
|
11
11
|
export { CURRENCY_SCALES, currencyOf, type Money, minorUnits, moneyLabel, moneyOf, } from "./domain/money.js";
|
|
12
|
+
export { ORDER_PURPOSES, ORDER_STATUSES, type OrderPurpose, type OrderStatus, } from "./domain/orders.js";
|
|
12
13
|
export { countedPoll } from "./domain/polls.js";
|
|
13
14
|
export { FOLDER_PROVIDERS, isFolderProvider, isKind, KINDS, type Kind, kindIn, kindOf, PROVIDERS, type ProviderEntry, providerNamed, providers, UNKNOWN_PROVIDER, useProviders, } from "./domain/providers.js";
|
|
14
15
|
export type { RankingGraphEvidence, RankingGraphLink } from "./domain/rankings-graph.js";
|