@wirecat/cli-core 0.495.0 → 0.496.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 +31 -0
- package/dist/cli/messenger/conversation-answers.d.ts +1 -1
- package/dist/cli/messenger/message-answers.d.ts +1 -1
- package/dist/cli/messenger/message-writes.d.ts +2 -2
- package/dist/cli/messenger/search-answers.js +2 -2
- package/dist/cli/messenger/search-command.js +4 -2
- package/dist/entities/conversation-results.d.ts +2 -2
- package/dist/entities/evidence.d.ts +8 -8
- package/dist/entities/index.d.ts +19 -19
- package/dist/entities/listener.d.ts +4 -4
- package/dist/entities/message-context.d.ts +3 -3
- package/dist/entities/message-write.d.ts +4 -4
- package/dist/entities/message.d.ts +2 -2
- package/dist/entities/message.js +2 -2
- package/dist/entities/store-records.d.ts +1 -1
- package/dist/services/document-source.d.ts +2 -3
- package/dist/services/document-source.js +2 -7
- package/dist/services/messages-discovery.js +7 -2
- package/dist/services/notes-search.d.ts +13 -3
- package/dist/services/notes-search.js +93 -19
- package/dist/store/sqlite/note-search.d.ts +5 -0
- package/dist/store/sqlite/note-search.js +11 -2
- package/package.json +1 -1
- package/parity.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,37 @@ shape of this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.496.0 — 31.10.2026
|
|
11
|
+
|
|
12
|
+
### Changed — may break callers
|
|
13
|
+
|
|
14
|
+
- **A discovery follow-up carries an `excerpt` of up to 240 characters, as the hit itself, instead of its whole
|
|
15
|
+
`text`.** On a real archive one follow-up (a pasted long write-up) added 7 KB to a five-hit answer, a sixth of it.
|
|
16
|
+
`items[].follow_ups[].text` is now `items[].follow_ups[].excerpt`; `messages context <ref>` shows the whole message.
|
|
17
|
+
The terminal output is unchanged.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Discovery search keeps the colons of a quoted timestamp in a date filter.** 0.492.0 turned a colon between digits
|
|
22
|
+
into a space so that "22:00" in a question would not fail, but it also did so inside quotes, and
|
|
23
|
+
`date:["2026-08-21T21:30:00Z" TO "…"]` failed with `query.invalid-date` under `discover`. Quoted text is now left as is.
|
|
24
|
+
- **`search notes`, the notes of `search all` and drive's `search` keep the query's fields for hits found by
|
|
25
|
+
meaning.** `date:today` or `tag:work` without `--exact` returned about 20 notes that matched neither: the meaning
|
|
26
|
+
half embedded the whole query, fields included, and checked only `--filter`. Now only the query's words and phrases
|
|
27
|
+
are searched by meaning, and every field and every excluded word (`-draft`) holds for every hit; a field joined to
|
|
28
|
+
the words by `OR` narrows nothing. A query of fields alone is not searched by meaning and lists the matching notes,
|
|
29
|
+
newest first. `--filter` also checks every meaning candidate: before, it kept only the newest 500 notes it matched,
|
|
30
|
+
so an older note found by meaning was dropped.
|
|
31
|
+
- **A Drive document's `date:` and its shown `updated_at` are one time.** `date:` read when the store's copy changed,
|
|
32
|
+
while the hit showed the document's edit time on Drive, so of 20 hits for `date>=30d` 16 showed an older date. Both
|
|
33
|
+
are now the edit time on Drive when the store has it, and the store's copy otherwise, as `context` evidence already
|
|
34
|
+
reads it. `date:` on a Drive document therefore matches by its edit time, and the time is always written as
|
|
35
|
+
`2026-01-01T00:00:00.000Z`, as every other time is, where a front-matter time was shown as written.
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- **`NoteQuery.refs` checks a list of notes against a query, and `NoteHit.at` is the time `date:` read.**
|
|
40
|
+
|
|
10
41
|
## 0.495.0 — 31.10.2026
|
|
11
42
|
|
|
12
43
|
### Changed — may break callers
|
|
@@ -80,7 +80,7 @@ export declare const conversationShown: (account: AccountKey, { summary, message
|
|
|
80
80
|
chat_title: string | null;
|
|
81
81
|
timestamp: string;
|
|
82
82
|
sender_name: string | null;
|
|
83
|
-
|
|
83
|
+
excerpt: string;
|
|
84
84
|
}[] | undefined;
|
|
85
85
|
outgoing: boolean | null;
|
|
86
86
|
attachments: {
|
|
@@ -57,7 +57,7 @@ export declare const threadAnswer: ({ items, ...thread }: ThreadContext, reader:
|
|
|
57
57
|
chat_title: string | null;
|
|
58
58
|
timestamp: string;
|
|
59
59
|
sender_name: string | null;
|
|
60
|
-
|
|
60
|
+
excerpt: string;
|
|
61
61
|
}[] | undefined;
|
|
62
62
|
outgoing: boolean | null;
|
|
63
63
|
attachments: {
|
|
@@ -61,7 +61,7 @@ export declare const writtenAnswer: ({ operationId, sendId, message, messages, s
|
|
|
61
61
|
chat_title: string | null;
|
|
62
62
|
timestamp: string;
|
|
63
63
|
sender_name: string | null;
|
|
64
|
-
|
|
64
|
+
excerpt: string;
|
|
65
65
|
}[] | undefined;
|
|
66
66
|
outgoing: boolean | null;
|
|
67
67
|
attachments: {
|
|
@@ -280,7 +280,7 @@ export declare const writtenAnswer: ({ operationId, sendId, message, messages, s
|
|
|
280
280
|
chat_title: string | null;
|
|
281
281
|
timestamp: string;
|
|
282
282
|
sender_name: string | null;
|
|
283
|
-
|
|
283
|
+
excerpt: string;
|
|
284
284
|
}[] | undefined;
|
|
285
285
|
outgoing: boolean | null;
|
|
286
286
|
attachments: {
|
|
@@ -20,7 +20,7 @@ const MESSAGE_HIT_UNTRUSTED = [
|
|
|
20
20
|
"context.text",
|
|
21
21
|
"follow_ups.chat_title",
|
|
22
22
|
"follow_ups.sender_name",
|
|
23
|
-
"follow_ups.
|
|
23
|
+
"follow_ups.excerpt",
|
|
24
24
|
];
|
|
25
25
|
const MAIL_HIT_UNTRUSTED = [
|
|
26
26
|
"email.subject",
|
|
@@ -81,7 +81,7 @@ export const messageHitItem = (hit, query = "") => {
|
|
|
81
81
|
chat_title: one.chatTitle ?? null,
|
|
82
82
|
timestamp: one.timestamp,
|
|
83
83
|
sender_name: one.senderName,
|
|
84
|
-
|
|
84
|
+
excerpt: excerpt(one.text, query),
|
|
85
85
|
})),
|
|
86
86
|
untrusted: hit.email ? [...MESSAGE_HIT_UNTRUSTED, ...MAIL_HIT_UNTRUSTED] : MESSAGE_HIT_UNTRUSTED,
|
|
87
87
|
});
|
|
@@ -107,11 +107,13 @@ const notesCommand = (messenger) => annotate(new Command("notes"), { effects: LO
|
|
|
107
107
|
"text model, by meaning; each hit says which found it and what it links to")
|
|
108
108
|
.argument("<query...>", 'strict Lucene query: words, "phrases", AND/OR/NOT, tag:, source:internal (written in memo) or source:file ' +
|
|
109
109
|
"(from a notes folder) and date ranges")
|
|
110
|
-
.addHelpText("after", "
|
|
110
|
+
.addHelpText("after", "Fields in the query or in --filter (tag:, date:, source:…) hold for every hit, found by words or by meaning; " +
|
|
111
|
+
"only the words are searched by meaning, and a query of fields alone lists the matching notes, newest first — " +
|
|
112
|
+
"'budget tag:work', 'date:today'. updated_at is the time date: reads: a Drive document's edit time. " +
|
|
111
113
|
"--json: the list is items; each note's reference is ref.")
|
|
112
114
|
.option("--source <accounts>", "only these notes accounts, separated by commas: notes:internal for notes written in memo, notes:<folder id> " +
|
|
113
115
|
"as a hit shows it, notes, documents or group:<name>")
|
|
114
|
-
.option("--filter <query>", "a query every hit must also match
|
|
116
|
+
.option("--filter <query>", "a query every hit must also match, found by words or by meaning")
|
|
115
117
|
.option("--limit <n>", "how many", positiveCount("--limit"))
|
|
116
118
|
.option("--page <n>", "which page, starting at 1", positiveCount("--page"))
|
|
117
119
|
.option("--exact", "words as written only; meaning is not searched")
|
|
@@ -56,7 +56,7 @@ export declare const conversationDetails: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
56
56
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
57
57
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
58
58
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
59
|
-
readonly
|
|
59
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
60
60
|
}, undefined>, undefined>, undefined>;
|
|
61
61
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
62
62
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -273,7 +273,7 @@ export declare const conversationDetails: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
273
273
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
274
274
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
275
275
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
276
|
-
readonly
|
|
276
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
277
277
|
}, undefined>, undefined>, undefined>;
|
|
278
278
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
279
279
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -47,7 +47,7 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
47
47
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
48
48
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
49
49
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
50
|
-
readonly
|
|
50
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
51
51
|
}, undefined>, undefined>, undefined>;
|
|
52
52
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
53
53
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -264,7 +264,7 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
264
264
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
265
265
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
266
266
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
267
|
-
readonly
|
|
267
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
268
268
|
}, undefined>, undefined>, undefined>;
|
|
269
269
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
270
270
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -519,7 +519,7 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
519
519
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
520
520
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
521
521
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
522
|
-
readonly
|
|
522
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
523
523
|
}, undefined>, undefined>, undefined>;
|
|
524
524
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
525
525
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -736,7 +736,7 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
736
736
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
737
737
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
738
738
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
739
|
-
readonly
|
|
739
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
740
740
|
}, undefined>, undefined>, undefined>;
|
|
741
741
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
742
742
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1027,7 +1027,7 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1027
1027
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1028
1028
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1029
1029
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1030
|
-
readonly
|
|
1030
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1031
1031
|
}, undefined>, undefined>, undefined>;
|
|
1032
1032
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1033
1033
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1244,7 +1244,7 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1244
1244
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1245
1245
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1246
1246
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1247
|
-
readonly
|
|
1247
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1248
1248
|
}, undefined>, undefined>, undefined>;
|
|
1249
1249
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1250
1250
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1499,7 +1499,7 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1499
1499
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1500
1500
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1501
1501
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1502
|
-
readonly
|
|
1502
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1503
1503
|
}, undefined>, undefined>, undefined>;
|
|
1504
1504
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1505
1505
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1716,7 +1716,7 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1716
1716
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1717
1717
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1718
1718
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1719
|
-
readonly
|
|
1719
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1720
1720
|
}, undefined>, undefined>, undefined>;
|
|
1721
1721
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1722
1722
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
package/dist/entities/index.d.ts
CHANGED
|
@@ -270,7 +270,7 @@ export declare const ENTITIES: {
|
|
|
270
270
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
271
271
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
272
272
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
273
|
-
readonly
|
|
273
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
274
274
|
}, undefined>, undefined>, undefined>;
|
|
275
275
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
276
276
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -487,7 +487,7 @@ export declare const ENTITIES: {
|
|
|
487
487
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
488
488
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
489
489
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
490
|
-
readonly
|
|
490
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
491
491
|
}, undefined>, undefined>, undefined>;
|
|
492
492
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
493
493
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -709,7 +709,7 @@ export declare const ENTITIES: {
|
|
|
709
709
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
710
710
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
711
711
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
712
|
-
readonly
|
|
712
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
713
713
|
}, undefined>, undefined>, undefined>;
|
|
714
714
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
715
715
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1192,7 +1192,7 @@ export declare const ENTITIES: {
|
|
|
1192
1192
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1193
1193
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1194
1194
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1195
|
-
readonly
|
|
1195
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1196
1196
|
}, undefined>, undefined>, undefined>;
|
|
1197
1197
|
readonly email: v.OptionalSchema<v.StrictObjectSchema<{
|
|
1198
1198
|
readonly subject: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
@@ -1279,7 +1279,7 @@ export declare const ENTITIES: {
|
|
|
1279
1279
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1280
1280
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1281
1281
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1282
|
-
readonly
|
|
1282
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1283
1283
|
}, undefined>, undefined>, undefined>;
|
|
1284
1284
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1285
1285
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1496,7 +1496,7 @@ export declare const ENTITIES: {
|
|
|
1496
1496
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1497
1497
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1498
1498
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1499
|
-
readonly
|
|
1499
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1500
1500
|
}, undefined>, undefined>, undefined>;
|
|
1501
1501
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1502
1502
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1944,7 +1944,7 @@ export declare const ENTITIES: {
|
|
|
1944
1944
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1945
1945
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1946
1946
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1947
|
-
readonly
|
|
1947
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1948
1948
|
}, undefined>, undefined>, undefined>;
|
|
1949
1949
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1950
1950
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -2161,7 +2161,7 @@ export declare const ENTITIES: {
|
|
|
2161
2161
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
2162
2162
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
2163
2163
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
2164
|
-
readonly
|
|
2164
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
2165
2165
|
}, undefined>, undefined>, undefined>;
|
|
2166
2166
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
2167
2167
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -2382,7 +2382,7 @@ export declare const ENTITIES: {
|
|
|
2382
2382
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
2383
2383
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
2384
2384
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
2385
|
-
readonly
|
|
2385
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
2386
2386
|
}, undefined>, undefined>, undefined>;
|
|
2387
2387
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
2388
2388
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -2599,7 +2599,7 @@ export declare const ENTITIES: {
|
|
|
2599
2599
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
2600
2600
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
2601
2601
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
2602
|
-
readonly
|
|
2602
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
2603
2603
|
}, undefined>, undefined>, undefined>;
|
|
2604
2604
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
2605
2605
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -6854,7 +6854,7 @@ export declare const ENTITIES: {
|
|
|
6854
6854
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
6855
6855
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
6856
6856
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
6857
|
-
readonly
|
|
6857
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
6858
6858
|
}, undefined>, undefined>, undefined>;
|
|
6859
6859
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
6860
6860
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -7071,7 +7071,7 @@ export declare const ENTITIES: {
|
|
|
7071
7071
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
7072
7072
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
7073
7073
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
7074
|
-
readonly
|
|
7074
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
7075
7075
|
}, undefined>, undefined>, undefined>;
|
|
7076
7076
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
7077
7077
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -7531,7 +7531,7 @@ export declare const ENTITIES: {
|
|
|
7531
7531
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
7532
7532
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
7533
7533
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
7534
|
-
readonly
|
|
7534
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
7535
7535
|
}, undefined>, undefined>, undefined>;
|
|
7536
7536
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
7537
7537
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -8039,7 +8039,7 @@ export declare const ENTITIES: {
|
|
|
8039
8039
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8040
8040
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
8041
8041
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8042
|
-
readonly
|
|
8042
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
8043
8043
|
}, undefined>, undefined>, undefined>;
|
|
8044
8044
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
8045
8045
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -8723,7 +8723,7 @@ export declare const ENTITIES: {
|
|
|
8723
8723
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8724
8724
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
8725
8725
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8726
|
-
readonly
|
|
8726
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
8727
8727
|
}, undefined>, undefined>, undefined>;
|
|
8728
8728
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
8729
8729
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -10394,7 +10394,7 @@ export declare const ENTITIES: {
|
|
|
10394
10394
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10395
10395
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
10396
10396
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10397
|
-
readonly
|
|
10397
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
10398
10398
|
}, undefined>, undefined>, undefined>;
|
|
10399
10399
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
10400
10400
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -10611,7 +10611,7 @@ export declare const ENTITIES: {
|
|
|
10611
10611
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10612
10612
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
10613
10613
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10614
|
-
readonly
|
|
10614
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
10615
10615
|
}, undefined>, undefined>, undefined>;
|
|
10616
10616
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
10617
10617
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -10866,7 +10866,7 @@ export declare const ENTITIES: {
|
|
|
10866
10866
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10867
10867
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
10868
10868
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10869
|
-
readonly
|
|
10869
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
10870
10870
|
}, undefined>, undefined>, undefined>;
|
|
10871
10871
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
10872
10872
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -11083,7 +11083,7 @@ export declare const ENTITIES: {
|
|
|
11083
11083
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
11084
11084
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
11085
11085
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
11086
|
-
readonly
|
|
11086
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
11087
11087
|
}, undefined>, undefined>, undefined>;
|
|
11088
11088
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
11089
11089
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -46,7 +46,7 @@ export declare const watchedMessage: v.StrictObjectSchema<{
|
|
|
46
46
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
47
47
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
48
48
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
49
|
-
readonly
|
|
49
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
50
50
|
}, undefined>, undefined>, undefined>;
|
|
51
51
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
52
52
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -555,7 +555,7 @@ export declare const messageEvent: v.VariantSchema<"event", [v.StrictObjectSchem
|
|
|
555
555
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
556
556
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
557
557
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
558
|
-
readonly
|
|
558
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
559
559
|
}, undefined>, undefined>, undefined>;
|
|
560
560
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
561
561
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1171,7 +1171,7 @@ export declare const watchItem: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1171
1171
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1172
1172
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1173
1173
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1174
|
-
readonly
|
|
1174
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1175
1175
|
}, undefined>, undefined>, undefined>;
|
|
1176
1176
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1177
1177
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1679,7 +1679,7 @@ export declare const watchItem: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1679
1679
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1680
1680
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
1681
1681
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1682
|
-
readonly
|
|
1682
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
1683
1683
|
}, undefined>, undefined>, undefined>;
|
|
1684
1684
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1685
1685
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -51,7 +51,7 @@ export declare const messageThread: v.StrictObjectSchema<{
|
|
|
51
51
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
52
52
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
53
53
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
54
|
-
readonly
|
|
54
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
55
55
|
}, undefined>, undefined>, undefined>;
|
|
56
56
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
57
57
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -292,7 +292,7 @@ export declare const messageContext: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
292
292
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
293
293
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
294
294
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
295
|
-
readonly
|
|
295
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
296
296
|
}, undefined>, undefined>, undefined>;
|
|
297
297
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
298
298
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -514,7 +514,7 @@ export declare const messageContext: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
514
514
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
515
515
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
516
516
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
517
|
-
readonly
|
|
517
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
518
518
|
}, undefined>, undefined>, undefined>;
|
|
519
519
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
520
520
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -47,7 +47,7 @@ export declare const messageWrite: v.StrictObjectSchema<{
|
|
|
47
47
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
48
48
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
49
49
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
50
|
-
readonly
|
|
50
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
51
51
|
}, undefined>, undefined>, undefined>;
|
|
52
52
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
53
53
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -265,7 +265,7 @@ export declare const messageWrite: v.StrictObjectSchema<{
|
|
|
265
265
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
266
266
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
267
267
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
268
|
-
readonly
|
|
268
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
269
269
|
}, undefined>, undefined>, undefined>;
|
|
270
270
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
271
271
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -491,7 +491,7 @@ export declare const messageSend: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
491
491
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
492
492
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
493
493
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
494
|
-
readonly
|
|
494
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
495
495
|
}, undefined>, undefined>, undefined>;
|
|
496
496
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
497
497
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -709,7 +709,7 @@ export declare const messageSend: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
709
709
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
710
710
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
711
711
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
712
|
-
readonly
|
|
712
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
713
713
|
}, undefined>, undefined>, undefined>;
|
|
714
714
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
715
715
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -57,14 +57,14 @@ export declare const message: v.StrictObjectSchema<{
|
|
|
57
57
|
}, undefined>, undefined>, undefined>;
|
|
58
58
|
/**
|
|
59
59
|
* A discovery hit's later messages, from any chat the search reads, that share a rare word with it, latest first:
|
|
60
|
-
* one may change or cancel what the hit says.
|
|
60
|
+
* one may change or cancel what the hit says. An excerpt, as the hit's own: `messages context <ref>` has the whole text.
|
|
61
61
|
*/
|
|
62
62
|
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
63
63
|
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
64
64
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
65
65
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
66
66
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
67
|
-
readonly
|
|
67
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
68
68
|
}, undefined>, undefined>, undefined>;
|
|
69
69
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
70
70
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
package/dist/entities/message.js
CHANGED
|
@@ -61,14 +61,14 @@ export const message = v.strictObject({
|
|
|
61
61
|
context: v.optional(v.array(v.strictObject({ ref: reference, timestamp: time, sender_name: v.nullable(text), text }))),
|
|
62
62
|
/**
|
|
63
63
|
* A discovery hit's later messages, from any chat the search reads, that share a rare word with it, latest first:
|
|
64
|
-
* one may change or cancel what the hit says.
|
|
64
|
+
* one may change or cancel what the hit says. An excerpt, as the hit's own: `messages context <ref>` has the whole text.
|
|
65
65
|
*/
|
|
66
66
|
follow_ups: v.optional(v.array(v.strictObject({
|
|
67
67
|
ref: reference,
|
|
68
68
|
chat_title: v.nullable(text),
|
|
69
69
|
timestamp: time,
|
|
70
70
|
sender_name: v.nullable(text),
|
|
71
|
-
text,
|
|
71
|
+
excerpt: text,
|
|
72
72
|
}))),
|
|
73
73
|
outgoing: v.nullable(v.boolean()),
|
|
74
74
|
attachments: v.array(attachment),
|
|
@@ -70,7 +70,7 @@ export declare const storeExport: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
70
70
|
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
71
71
|
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
72
72
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
73
|
-
readonly
|
|
73
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
74
74
|
}, undefined>, undefined>, undefined>;
|
|
75
75
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
76
76
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { Profiles } from "../search/account-list.js";
|
|
2
2
|
import type { Note, StoredAccount, StoredFile } from "../store/index.js";
|
|
3
3
|
/**
|
|
4
|
-
* Where a hit came from. The document's preferred file says it: its account's provider
|
|
4
|
+
* Where a hit came from. The document's preferred file says it: its account's provider and its link.
|
|
5
5
|
* A Drive document under a notes folder (before version 31 moves it) is still known by its front matter.
|
|
6
|
-
*
|
|
6
|
+
* The hit's time is the store search's: the one `date:` reads.
|
|
7
7
|
*/
|
|
8
8
|
export declare const documentSource: (note: Note, accounts: readonly StoredAccount[], profiles: Profiles, file?: StoredFile) => {
|
|
9
9
|
kind: "document" | "note";
|
|
10
10
|
provider: string;
|
|
11
11
|
account: string;
|
|
12
12
|
url?: string | undefined;
|
|
13
|
-
updated_at: string;
|
|
14
13
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isFolderProvider, kindIn } from "../domain/providers.js";
|
|
2
2
|
/**
|
|
3
|
-
* Where a hit came from. The document's preferred file says it: its account's provider
|
|
3
|
+
* Where a hit came from. The document's preferred file says it: its account's provider and its link.
|
|
4
4
|
* A Drive document under a notes folder (before version 31 moves it) is still known by its front matter.
|
|
5
|
-
*
|
|
5
|
+
* The hit's time is the store search's: the one `date:` reads.
|
|
6
6
|
*/
|
|
7
7
|
export const documentSource = (note, accounts, profiles, file) => {
|
|
8
8
|
const metadata = note.frontMatter;
|
|
@@ -16,15 +16,10 @@ export const documentSource = (note, accounts, profiles, file) => {
|
|
|
16
16
|
(isFolderProvider(key.provider) && key.account === account.name))
|
|
17
17
|
: undefined;
|
|
18
18
|
const url = file?.url ?? (remote && typeof metadata?.sourceUrl === "string" ? metadata.sourceUrl : undefined);
|
|
19
|
-
const modified = file?.externalUpdatedAt ??
|
|
20
|
-
(remote && typeof metadata?.modifiedAt === "string" && Number.isFinite(Date.parse(metadata.modifiedAt))
|
|
21
|
-
? metadata.modifiedAt
|
|
22
|
-
: undefined);
|
|
23
19
|
return {
|
|
24
20
|
kind: remote ? "document" : "note",
|
|
25
21
|
provider: profile ? profile.command : "notes",
|
|
26
22
|
account: profile?.name ?? note.folderId ?? "internal",
|
|
27
23
|
...(remote && url !== undefined ? { url } : {}),
|
|
28
|
-
updated_at: remote && modified !== undefined ? modified : note.updatedAt,
|
|
29
24
|
};
|
|
30
25
|
};
|
|
@@ -31,10 +31,15 @@ const FOLLOW_UP_CANDIDATES = 20;
|
|
|
31
31
|
export const searchDiscovery = async (store, account, asked, messenger = {}, meaning, rerank) => {
|
|
32
32
|
// A question's own "?" would parse as a one-character wildcard and send it to strict search (BUG-395); the
|
|
33
33
|
// colon of a time or ratio ("22:00", "1:1") would parse as a field and fail the whole search, and escaped it is
|
|
34
|
-
// syntax again, so it splits the numbers (BUG-450).
|
|
34
|
+
// syntax again, so it splits the numbers (BUG-450). A quoted timestamp keeps its colons (BUG-458).
|
|
35
35
|
const request = asked.ast !== undefined || asked.exact || !asked.text
|
|
36
36
|
? asked
|
|
37
|
-
: {
|
|
37
|
+
: {
|
|
38
|
+
...asked,
|
|
39
|
+
text: asked.text
|
|
40
|
+
.replace(/(?<=\p{L})\?(?=\s|$)/gu, "")
|
|
41
|
+
.replace(/"(?:[^"\\]|\\.)*"|(?<=\d):(?=\d)/gu, (found) => (found === ":" ? " " : found)),
|
|
42
|
+
};
|
|
38
43
|
const original = await prepareLucene(store, account, request, messenger);
|
|
39
44
|
const text = request.text ?? "";
|
|
40
45
|
const plan = planQuestion(text, request.ast !== undefined || !!request.exact || !!request.newest);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type QueryNode } from "@wirecat/cli-base/query";
|
|
1
2
|
import { type Embedder, type WarmEmbedders } from "../embeddings/embed.js";
|
|
2
3
|
import { type TextModel } from "../embeddings/models.js";
|
|
3
4
|
import type { PictureEmbedder } from "../images/picture/embedder.js";
|
|
@@ -90,7 +91,7 @@ export interface FoundNote {
|
|
|
90
91
|
/** The note's path inside its folder; `null` for a note written in memo. */
|
|
91
92
|
path: string | null;
|
|
92
93
|
title: string | null;
|
|
93
|
-
/**
|
|
94
|
+
/** The time `date:` reads: a Drive document's edit time when the store has one, else when the store's copy changed. */
|
|
94
95
|
updated_at: string;
|
|
95
96
|
/** The first line holding a word of the query. */
|
|
96
97
|
excerpt: string;
|
|
@@ -135,7 +136,7 @@ export interface NotesQuery {
|
|
|
135
136
|
limit?: number;
|
|
136
137
|
offset?: number;
|
|
137
138
|
tag?: string;
|
|
138
|
-
/** A query in the same language that every hit must also match
|
|
139
|
+
/** A query in the same language that every hit must also match, as the query's own fields are. */
|
|
139
140
|
filter?: string;
|
|
140
141
|
folderIds?: string[];
|
|
141
142
|
/** With `folderIds`, the notes written in memo too: one ranked list, so `offset` pages it. */
|
|
@@ -164,9 +165,18 @@ export declare const noteSourceOfQuery: (query: string) => {
|
|
|
164
165
|
source?: Note["source"];
|
|
165
166
|
rest: string;
|
|
166
167
|
};
|
|
168
|
+
/**
|
|
169
|
+
* What a note found by meaning must still match: the query with each word it asks for taken as matched, since the
|
|
170
|
+
* meaning half stands in for those. Words it excludes, and every other field, stay. `undefined` when nothing but
|
|
171
|
+
* wanted words is left, so any note found by meaning fits.
|
|
172
|
+
*/
|
|
173
|
+
export declare const fieldsOfQuery: (root: QueryNode) => QueryNode | undefined;
|
|
174
|
+
/** The words and phrases the query asks for, for the meaning half to embed; none it excludes, no field. */
|
|
175
|
+
export declare const meaningWords: (root: QueryNode) => string;
|
|
167
176
|
/**
|
|
168
177
|
* `search notes`: words and stems, and meaning when the local model is there, merged by reciprocal rank;
|
|
169
|
-
* each hit says which half found it, and the answer lists what the notes found link to.
|
|
178
|
+
* each hit says which half found it, and the answer lists what the notes found link to. Every field of the query and
|
|
179
|
+
* of `filter` holds for every hit, found by words or by meaning; a query of fields alone is not searched by meaning.
|
|
170
180
|
*/
|
|
171
181
|
export declare const searchNotes: (store: MessageStore, query: string, { limit, offset, tag, filter: expression, folderIds, withInternal, source: given, exact, timezone, env, command, embedders, pictures: withPictures, pictureLimit, pictureEmbedder, }?: NotesQuery) => Promise<NotesFound>;
|
|
172
182
|
/** What `notes:internal` and `notes:<folder id>` ask of the store: one query, so a page of it is one page. */
|
|
@@ -19,8 +19,10 @@ import { listContextOf } from "./search-kind.js";
|
|
|
19
19
|
* Text in the query language messages use, parsed for a store search: `date:` read in `timezone`, and the store's
|
|
20
20
|
* stemmer when a word is stemmed.
|
|
21
21
|
*/
|
|
22
|
-
export const storeQuery = async (store, text, { exact, timezone } = {}) =>
|
|
23
|
-
|
|
22
|
+
export const storeQuery = async (store, text, { exact, timezone } = {}) => resolvedQuery(store, parsedQuery(text, exact), timezone);
|
|
23
|
+
const parsedQuery = (text, exact) => validateFields(parseLucene(text, { ...SEARCH_QUERY, defaultField: exact ? "exact" : "text" })).root;
|
|
24
|
+
const resolvedQuery = async (store, root, timezone) => {
|
|
25
|
+
const ast = { root };
|
|
24
26
|
const zone = timezoneOf(timezone);
|
|
25
27
|
const resolve = (node) => {
|
|
26
28
|
if (node.kind === "boolean")
|
|
@@ -145,8 +147,6 @@ const MAX_LINE = 200;
|
|
|
145
147
|
const MAX_NOTES_OFFSET = 1000;
|
|
146
148
|
/** How deep each half is read before the two are merged. */
|
|
147
149
|
const CANDIDATES = 50;
|
|
148
|
-
/** What a filter may narrow the meaning half to; past this the filter is applied to words only. */
|
|
149
|
-
const FILTERED = 500;
|
|
150
150
|
/** Reciprocal rank fusion's usual constant, as conversations use. */
|
|
151
151
|
export const RRF_K = 60;
|
|
152
152
|
const firstLine = (text, query) => {
|
|
@@ -225,17 +225,88 @@ export const noteSourceOfQuery = (query) => {
|
|
|
225
225
|
}
|
|
226
226
|
return { source, rest };
|
|
227
227
|
};
|
|
228
|
+
const WORD_FIELDS = new Set(["text", "exact"]);
|
|
229
|
+
/**
|
|
230
|
+
* What a note found by meaning must still match: the query with each word it asks for taken as matched, since the
|
|
231
|
+
* meaning half stands in for those. Words it excludes, and every other field, stay. `undefined` when nothing but
|
|
232
|
+
* wanted words is left, so any note found by meaning fits.
|
|
233
|
+
*/
|
|
234
|
+
export const fieldsOfQuery = (root) => {
|
|
235
|
+
let narrows = false;
|
|
236
|
+
const kept = (node) => {
|
|
237
|
+
if (node.kind === "boolean")
|
|
238
|
+
return {
|
|
239
|
+
...node,
|
|
240
|
+
clauses: node.clauses.map(({ occur, node }) => {
|
|
241
|
+
if (occur !== "must_not")
|
|
242
|
+
return { occur, node: kept(node) };
|
|
243
|
+
narrows = true;
|
|
244
|
+
return { occur, node };
|
|
245
|
+
}),
|
|
246
|
+
};
|
|
247
|
+
if (!WORD_FIELDS.has(node.field)) {
|
|
248
|
+
narrows = true;
|
|
249
|
+
return node;
|
|
250
|
+
}
|
|
251
|
+
// `in:notes` holds for every note and document; an empty clause list would match nothing.
|
|
252
|
+
return { kind: "predicate", field: "in", operator: "term", value: "notes", span: node.span };
|
|
253
|
+
};
|
|
254
|
+
const fields = kept(root);
|
|
255
|
+
return narrows ? fields : undefined;
|
|
256
|
+
};
|
|
257
|
+
/** The words and phrases the query asks for, for the meaning half to embed; none it excludes, no field. */
|
|
258
|
+
export const meaningWords = (root) => {
|
|
259
|
+
const wanted = (node) => node.kind === "boolean"
|
|
260
|
+
? node.clauses.flatMap(({ occur, node }) => (occur === "must_not" ? [] : wanted(node)))
|
|
261
|
+
: WORD_FIELDS.has(node.field) && (node.operator === "term" || node.operator === "phrase")
|
|
262
|
+
? [node.value]
|
|
263
|
+
: [];
|
|
264
|
+
return wanted(root).join(" ").trim();
|
|
265
|
+
};
|
|
266
|
+
const allOf = (nodes) => nodes.length <= 1
|
|
267
|
+
? nodes[0]
|
|
268
|
+
: {
|
|
269
|
+
kind: "boolean",
|
|
270
|
+
clauses: nodes.map((node) => ({ occur: "must", node })),
|
|
271
|
+
span: { start: 0, end: 0 },
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* The notes of `refs` that match `root`, in the order of `refs`, each with the time `date:` read. One store query over
|
|
275
|
+
* just those notes, so a filter that matches thousands of notes still checks every candidate.
|
|
276
|
+
*/
|
|
277
|
+
const matching = async (store, refs, root, scope) => {
|
|
278
|
+
if (refs.length === 0)
|
|
279
|
+
return new Map();
|
|
280
|
+
const resolved = await resolvedQuery(store, root ?? { kind: "predicate", field: "in", operator: "term", value: "notes", span: { start: 0, end: 0 } }, scope.timezone);
|
|
281
|
+
const found = await store.notes.search({
|
|
282
|
+
root: resolved.root,
|
|
283
|
+
refs,
|
|
284
|
+
limit: refs.length,
|
|
285
|
+
...(scope.folderIds ? { folderIds: scope.folderIds } : {}),
|
|
286
|
+
...(scope.withInternal ? { withInternal: true } : {}),
|
|
287
|
+
...(scope.source ? { source: scope.source } : {}),
|
|
288
|
+
...(resolved.stemmer ? { stemmer: resolved.stemmer } : {}),
|
|
289
|
+
});
|
|
290
|
+
return new Map(found.items.map(({ ref, note, at }) => [ref, { note, at }]));
|
|
291
|
+
};
|
|
228
292
|
/**
|
|
229
293
|
* `search notes`: words and stems, and meaning when the local model is there, merged by reciprocal rank;
|
|
230
|
-
* each hit says which half found it, and the answer lists what the notes found link to.
|
|
294
|
+
* each hit says which half found it, and the answer lists what the notes found link to. Every field of the query and
|
|
295
|
+
* of `filter` holds for every hit, found by words or by meaning; a query of fields alone is not searched by meaning.
|
|
231
296
|
*/
|
|
232
297
|
export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, filter: expression, folderIds, withInternal, source: given, exact = false, timezone, env, command, embedders, pictures: withPictures = false, pictureLimit = 5, pictureEmbedder, } = {}) => {
|
|
233
298
|
const typed = noteSourceOfQuery(query);
|
|
234
299
|
const source = given ?? typed.source;
|
|
235
|
-
const
|
|
300
|
+
const rest = typed.source !== undefined && typed.source === source ? typed.rest : query;
|
|
236
301
|
const label = tag === undefined ? undefined : normalizeTag(tag);
|
|
237
302
|
const filter = [expression ? `(${expression})` : "", label === undefined ? "" : `tag:${label}`].filter(Boolean).join(" AND ") ||
|
|
238
303
|
undefined;
|
|
304
|
+
const parsed = query.trim() ? parsedQuery(query, exact) : undefined;
|
|
305
|
+
const words = parsed === undefined ? "" : meaningWords(parsed);
|
|
306
|
+
const narrowing = allOf([
|
|
307
|
+
...(parsed === undefined ? [] : [fieldsOfQuery(parsed)].filter((node) => node !== undefined)),
|
|
308
|
+
...(filter === undefined ? [] : [parsedQuery(filter)]),
|
|
309
|
+
]);
|
|
239
310
|
const text = [query.trim() ? `(${query})` : "", filter ?? ""].filter(Boolean).join(" AND ");
|
|
240
311
|
const window = offset + limit;
|
|
241
312
|
const scope = {
|
|
@@ -248,7 +319,7 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
248
319
|
let meaning;
|
|
249
320
|
if (exact)
|
|
250
321
|
meaningSkipped = "--exact searches words as written";
|
|
251
|
-
else if (words
|
|
322
|
+
else if (words) {
|
|
252
323
|
try {
|
|
253
324
|
const nearest = await nearestNotes(store, words, {
|
|
254
325
|
limit: Math.max(window, CANDIDATES),
|
|
@@ -259,13 +330,11 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
259
330
|
...(withInternal ? { withInternal: true } : {}),
|
|
260
331
|
...(source === undefined ? {} : { source }),
|
|
261
332
|
});
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
meaning = nearest.filter(({ ref }) => refs.has(ref));
|
|
268
|
-
}
|
|
333
|
+
const allowed = await matching(store, nearest.map(({ ref }) => ref), narrowing, scope);
|
|
334
|
+
meaning = nearest.flatMap(({ ref }) => {
|
|
335
|
+
const found = allowed.get(ref);
|
|
336
|
+
return found ? [{ ref, ...found }] : [];
|
|
337
|
+
});
|
|
269
338
|
}
|
|
270
339
|
catch (error) {
|
|
271
340
|
if (!(error instanceof CliError && error.code === "not_found"))
|
|
@@ -273,7 +342,7 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
273
342
|
meaningSkipped = error.message;
|
|
274
343
|
}
|
|
275
344
|
}
|
|
276
|
-
const titleWords = plainQueryWords(
|
|
345
|
+
const titleWords = plainQueryWords(rest);
|
|
277
346
|
const titled = titleWords === undefined
|
|
278
347
|
? { items: [], hasMore: false }
|
|
279
348
|
: await searchNotesQuery(store, {
|
|
@@ -292,10 +361,10 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
292
361
|
...scope,
|
|
293
362
|
});
|
|
294
363
|
const ranked = new Map();
|
|
295
|
-
const add = (list, by) => list.forEach(({ ref, note }, rank) => {
|
|
364
|
+
const add = (list, by) => list.forEach(({ ref, note, at }, rank) => {
|
|
296
365
|
if (tierRefs.has(ref))
|
|
297
366
|
return;
|
|
298
|
-
const held = ranked.get(ref) ?? { note, score: 0, foundBy: [] };
|
|
367
|
+
const held = ranked.get(ref) ?? { note, at, score: 0, foundBy: [] };
|
|
299
368
|
held.score += 1 / (RRF_K + rank + 1);
|
|
300
369
|
held.foundBy.push(by);
|
|
301
370
|
ranked.set(ref, held);
|
|
@@ -304,7 +373,7 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
304
373
|
if (meaning !== undefined)
|
|
305
374
|
add(meaning, "meaning");
|
|
306
375
|
const ordered = [
|
|
307
|
-
...tier.map(({ ref, note }) => [ref, { note, score: 0, foundBy: ["title"] }]),
|
|
376
|
+
...tier.map(({ ref, note, at }) => [ref, { note, at, score: 0, foundBy: ["title"] }]),
|
|
308
377
|
...[...ranked.entries()].sort(([, a], [, b]) => b.score - a.score),
|
|
309
378
|
];
|
|
310
379
|
const page = slice ? ordered : ordered.slice(offset, window);
|
|
@@ -313,7 +382,7 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
313
382
|
const counts = new Map();
|
|
314
383
|
const accounts = await store.accounts.storedAccounts();
|
|
315
384
|
const profiles = await store.accounts.profiles();
|
|
316
|
-
for (const [ref, { note, foundBy }] of page) {
|
|
385
|
+
for (const [ref, { note, at, foundBy }] of page) {
|
|
317
386
|
const links = (await store.notes.links({ from: ref })).map(({ to, targetText, kind, anchor }) => ({
|
|
318
387
|
to,
|
|
319
388
|
target_text: targetText,
|
|
@@ -327,6 +396,7 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
327
396
|
path: note.path,
|
|
328
397
|
title: note.title,
|
|
329
398
|
...documentSource(note, accounts, profiles, note.source === "file" ? (await store.files.ofDocument(note.ref))[0] : undefined),
|
|
399
|
+
updated_at: at,
|
|
330
400
|
excerpt: firstLine(note.text, words),
|
|
331
401
|
links,
|
|
332
402
|
found_by: foundBy,
|
|
@@ -360,6 +430,10 @@ export const searchNotes = async (store, query, { limit = 20, offset = 0, tag, f
|
|
|
360
430
|
embedder: pictureEmbedder,
|
|
361
431
|
})
|
|
362
432
|
: {};
|
|
433
|
+
if (lane.pictures && narrowing !== undefined) {
|
|
434
|
+
const allowed = await matching(store, lane.pictures.map(({ ref }) => ref), narrowing, scope);
|
|
435
|
+
lane.pictures = lane.pictures.filter(({ ref }) => allowed.has(ref));
|
|
436
|
+
}
|
|
363
437
|
return {
|
|
364
438
|
query,
|
|
365
439
|
...(label === undefined ? {} : { tag: label }),
|
|
@@ -13,6 +13,8 @@ export interface NoteQuery {
|
|
|
13
13
|
/** With `folderIds`, the notes written in memo too, in the same ranked list. */
|
|
14
14
|
withInternal?: boolean;
|
|
15
15
|
source?: Note["source"];
|
|
16
|
+
/** Only these notes (`document:<id>`, `note:<id>`): checks a list found another way against the query. */
|
|
17
|
+
refs?: string[];
|
|
16
18
|
/** Newest first instead of best first. */
|
|
17
19
|
newest?: boolean;
|
|
18
20
|
/** The store's stemmer, set when a leaf is stemmed. */
|
|
@@ -26,6 +28,8 @@ export interface NoteHit {
|
|
|
26
28
|
relevance: number | null;
|
|
27
29
|
/** Whether the note holds the exact forms, when the search was stemmed. */
|
|
28
30
|
exact?: boolean;
|
|
31
|
+
/** The time `date:` read: a Drive document's edit time when the store has one, else when the store's copy changed. */
|
|
32
|
+
at: string;
|
|
29
33
|
}
|
|
30
34
|
/** The fields a note has. A message-only field (`from:`, `chat:`, …) is refused rather than matching nothing. */
|
|
31
35
|
export declare const NOTE_FIELDS: readonly ["text", "exact", "body", "tag", "date", "in", "has", "title", "site", "lang", "author", "keyword", "source"];
|
|
@@ -68,6 +72,7 @@ export interface CorpusRow {
|
|
|
68
72
|
/** What one corpus is searched by; `accountIds` narrows a corpus that has accounts. */
|
|
69
73
|
export type CorpusQuery = Pick<NoteQuery, "root" | "limit" | "offset" | "newest" | "stemmer" | "signal"> & {
|
|
70
74
|
accountIds?: string[];
|
|
75
|
+
ids?: number[];
|
|
71
76
|
};
|
|
72
77
|
/** Notes matching a parsed query, by the same language as messages: files and written notes, merged. */
|
|
73
78
|
export declare const searchNotes: (context: StoreContext, query: NoteQuery) => {
|
|
@@ -4,6 +4,7 @@ import { compileAutomaton, foldRegex, wildcardPattern, } from "../../search/luce
|
|
|
4
4
|
import { isStemmed } from "../../search/lucene/resolved.js";
|
|
5
5
|
import { exhausted, QUERY_LIMITS, searchError } from "../../search/lucene/types.js";
|
|
6
6
|
import { normalize } from "../normalize.js";
|
|
7
|
+
import { contextDocumentTime } from "./context-document-source.js";
|
|
7
8
|
import { documentPicturesOver } from "./document-pictures.js";
|
|
8
9
|
import { linkKind } from "./link-kinds.js";
|
|
9
10
|
import { prefixOf } from "./lucene.js";
|
|
@@ -42,7 +43,7 @@ const CORPORA = [
|
|
|
42
43
|
type: "document",
|
|
43
44
|
noun: "note",
|
|
44
45
|
fields: NOTE_FIELDS,
|
|
45
|
-
view:
|
|
46
|
+
view: `(SELECT n.id, n.account_id AS folder_id, n.external_id AS path, n.title, coalesce(n.body, '') AS text, n.metadata, ${contextDocumentTime} AS at, n.deleted_at FROM documents n)`,
|
|
46
47
|
words: "document_words",
|
|
47
48
|
stems: "document_stems",
|
|
48
49
|
live: "coalesce(json_extract(n.metadata, '$.catalog.active'), 1)=1",
|
|
@@ -67,7 +68,13 @@ export const searchNotes = (context, query) => {
|
|
|
67
68
|
const offset = query.offset ?? 0;
|
|
68
69
|
const chosen = CORPORA.filter(({ type }) => (query.source === undefined || (query.source === "file") === (type === "document")) &&
|
|
69
70
|
(!query.folderIds?.length || query.withInternal === true || type === "document"));
|
|
70
|
-
const
|
|
71
|
+
const idsOf = (type) => query.refs?.flatMap((ref) => (ref.startsWith(`${type}:`) ? [Number(ref.slice(type.length + 1))] : []));
|
|
72
|
+
const rows = chosen.flatMap((corpus) => {
|
|
73
|
+
const ids = idsOf(corpus.type);
|
|
74
|
+
if (ids?.length === 0)
|
|
75
|
+
return [];
|
|
76
|
+
return searchCorpus(context, { ...query, ...(query.folderIds ? { accountIds: query.folderIds } : {}), ...(ids ? { ids } : {}) }, corpus);
|
|
77
|
+
});
|
|
71
78
|
const exactFirst = rows.some((row) => row.exact !== undefined);
|
|
72
79
|
rows.sort((a, b) => query.newest
|
|
73
80
|
? (b.at ?? 0) - (a.at ?? 0) || a.id - b.id
|
|
@@ -89,6 +96,7 @@ export const searchNotes = (context, query) => {
|
|
|
89
96
|
note,
|
|
90
97
|
relevance: row.relevance,
|
|
91
98
|
...(row.exact === undefined ? {} : { exact: row.exact }),
|
|
99
|
+
at: new Date(row.at ?? 0).toISOString(),
|
|
92
100
|
};
|
|
93
101
|
}),
|
|
94
102
|
hasMore: rows.length > offset + query.limit,
|
|
@@ -247,6 +255,7 @@ export const searchCorpus = (context, query, corpus) => {
|
|
|
247
255
|
bound("n.deleted_at IS NULL"),
|
|
248
256
|
...(corpus.live ? [bound(corpus.live)] : []),
|
|
249
257
|
...(query.accountIds?.length && corpus.inAccounts ? [corpus.inAccounts(JSON.stringify(query.accountIds))] : []),
|
|
258
|
+
...(query.ids ? [bound("n.id IN (SELECT value FROM json_each(?))", JSON.stringify(query.ids))] : []),
|
|
250
259
|
], "AND");
|
|
251
260
|
const where = combine([scope, expression], "AND");
|
|
252
261
|
const ranking = query.newest ? undefined : required(query.root, stemmed ? "stems" : "fts");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.496.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|
package/parity.json
CHANGED
|
@@ -387,7 +387,7 @@
|
|
|
387
387
|
"--filter": {
|
|
388
388
|
"value": "query",
|
|
389
389
|
"meaning": "Strict Lucene filter: any message in the conversation must match; the meaning query stays unchanged",
|
|
390
|
-
"note": "search notes uses it for a query every note must also match,
|
|
390
|
+
"note": "search notes uses it for a query every note must also match, found by words or by meaning"
|
|
391
391
|
},
|
|
392
392
|
"--find-by-phone": {
|
|
393
393
|
"value": "<who>",
|