@wirecat/cli-core 0.491.0 → 0.493.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 +58 -0
- package/dist/cli/messenger/conversation-answers.d.ts +7 -0
- package/dist/cli/messenger/message-answers.d.ts +7 -0
- package/dist/cli/messenger/message-writes.d.ts +14 -0
- package/dist/cli/messenger/messages-command.js +13 -1
- package/dist/cli/messenger/messages-search-command.js +4 -1
- package/dist/cli/messenger/search-answers.d.ts +6 -2
- package/dist/cli/messenger/search-answers.js +60 -7
- package/dist/cli/messenger/tasks-command.js +15 -3
- package/dist/cli/steps.js +1 -0
- package/dist/entities/agenda.d.ts +42 -0
- package/dist/entities/agenda.js +10 -0
- package/dist/entities/conversation-results.d.ts +14 -0
- package/dist/entities/evidence.d.ts +56 -0
- package/dist/entities/index.d.ts +169 -0
- package/dist/entities/index.js +1 -0
- package/dist/entities/listener.d.ts +28 -0
- package/dist/entities/message-context.d.ts +21 -0
- package/dist/entities/message-write.d.ts +28 -0
- package/dist/entities/message.d.ts +11 -0
- package/dist/entities/message.js +11 -0
- package/dist/entities/store-records.d.ts +7 -0
- package/dist/services/agenda.d.ts +5 -0
- package/dist/services/agenda.js +25 -4
- package/dist/services/chat-coverage.d.ts +19 -0
- package/dist/services/chat-coverage.js +27 -0
- package/dist/services/messages-discovery.d.ts +6 -0
- package/dist/services/messages-discovery.js +50 -3
- package/dist/services/messages-search.d.ts +2 -0
- package/dist/services/messages.d.ts +2 -0
- package/dist/services/search-all.d.ts +3 -0
- package/dist/services/search-all.js +4 -0
- package/dist/store/messages.d.ts +9 -0
- package/dist/store/messages.js +2 -0
- package/dist/store/sqlite/follow-ups.d.ts +17 -0
- package/dist/store/sqlite/follow-ups.js +59 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,64 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
|
|
|
5
5
|
minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
|
|
6
6
|
shape of this file.
|
|
7
7
|
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
## 0.493.0 — 31.10.2026
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`chatCoverage(store, account, chatIds)` says what the store holds of each chat.** Per chat, in the order asked:
|
|
15
|
+
`completeness` (`complete`, `partial` or `unknown`, up to date, gaps, start reached, last fetch) and `held` (messages,
|
|
16
|
+
oldest, newest), never text. It reads only the chats named, so a store of thousands of chats costs what the ids cost.
|
|
17
|
+
`coverageGaps` also takes a list of these rows and answers `missing` (`field: "history"`) and `next`: for the first
|
|
18
|
+
incomplete chat, `messages sync <chat> --since-time <start of the window>` when the answer has a window, then
|
|
19
|
+
`messages sync <chat>`. The step `messages.sync` takes `since_time`.
|
|
20
|
+
- **`messages list --offline` says when the store holds only part of the chat.** A chat that is `partial` or was never
|
|
21
|
+
fetched gives `meta.complete: false`, exit code 0, `missing` and `next`, as an offline read of 262 of 777 messages
|
|
22
|
+
must not pass for the whole chat. Online reads are unchanged.
|
|
23
|
+
- **`tasks agenda` says how much of each listed chat the store holds.** Each row of `owed`, `waiting` and `unsynced` has
|
|
24
|
+
`completeness` and `held`; a chat held only in part is marked `[partial]` or `[never fetched]` in the text, with one
|
|
25
|
+
line above the lists. The answer then has `meta.complete: false`, `missing` and `next` (bounded sync over the
|
|
26
|
+
`--within` window, then the whole chat).
|
|
27
|
+
- **`search all` names the chat to sync** when the store holds the chats its messages were searched in only in part:
|
|
28
|
+
`missing` (`field: "coverage"`) and `next`, from the same coverage `search messages` reports. `SearchAllFound` gains
|
|
29
|
+
`coverage`.
|
|
30
|
+
|
|
31
|
+
### Changed — may break callers
|
|
32
|
+
|
|
33
|
+
- **`tasks agenda --json` rows gain `completeness` and `held`**, and the answer may carry `meta.complete: false` with
|
|
34
|
+
`missing` and `next`; a caller that stops on anything but `meta.complete: true` now sees a store that holds chats in
|
|
35
|
+
part as incomplete. `tasks agenda` is declared `partial`, so the exit code stays 0. `AgendaChat` gains `coverage`
|
|
36
|
+
and `Agenda` gains `since`.
|
|
37
|
+
- **`search messages`, `search mail` and `search all` answer `meta.complete: false` when a chat searched is partial or
|
|
38
|
+
never fetched**, where they kept `true` and put the gap only in `missing` and `next`. Exit code stays 0 (the commands
|
|
39
|
+
are declared `partial`). A caller that read `meta.complete` as "no source failed" must read `missing` for the reason.
|
|
40
|
+
- **`messages list --offline --json` may carry `meta.complete: false`, `missing` and `next`** for a chat held in part.
|
|
41
|
+
`messages list` is declared `partial`: the exit code stays 0.
|
|
42
|
+
|
|
43
|
+
## 0.492.0 — 31.10.2026
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **`search messages --discover` shows follow-ups: later messages that may cancel or change a hit.** Each of the
|
|
48
|
+
first five hits gets up to two later messages, from any chat the search reads and passing its filters, that
|
|
49
|
+
share a word of three letters or more whose stem at most three messages of the store hold; latest first, a
|
|
50
|
+
message already shown above is not repeated. `items[].follow_ups` in `--json` and MCP (`ref`, `chat_title`,
|
|
51
|
+
`timestamp`, `sender_name`, `text`, all untrusted), `later, shares a rare word` lines in the terminal, and the
|
|
52
|
+
SDK's `query.discovery.followUps` counts them. The counts come from the stem index through a temporary `fts5vocab`
|
|
53
|
+
table, so the store does not change; while the stems are being built there are no follow-ups. On a benchmark
|
|
54
|
+
split written by an agent that never saw the method, cancelled decisions in the first three went from 7 to 11
|
|
55
|
+
of 15 and no answer was lost
|
|
56
|
+
([evidence pipeline](https://github.com/WireCatLabs/cli-testing/tree/main/performance/search/evidence-pipeline)).
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- **`search messages --discover` no longer fails on a question with a time or a ratio.** "Do we meet until 22:00?"
|
|
61
|
+
or "a 1:1 with Anna" read the colon as a field filter and ended the whole search with `query.invalid-syntax`.
|
|
62
|
+
In a question, a colon between two digits now splits the numbers, as a space would. Explicit query syntax is
|
|
63
|
+
unchanged. A question with a bare number still runs as strict search until cli-core takes cli-base 0.66.1, where a
|
|
64
|
+
number counts as a word of the question.
|
|
65
|
+
|
|
8
66
|
## 0.491.0 — 31.10.2026
|
|
9
67
|
|
|
10
68
|
### Fixed
|
|
@@ -75,6 +75,13 @@ export declare const conversationShown: (account: AccountKey, { summary, message
|
|
|
75
75
|
sender_name: string | null;
|
|
76
76
|
text: string;
|
|
77
77
|
}[] | undefined;
|
|
78
|
+
follow_ups?: {
|
|
79
|
+
ref: string;
|
|
80
|
+
chat_title: string | null;
|
|
81
|
+
timestamp: string;
|
|
82
|
+
sender_name: string | null;
|
|
83
|
+
text: string;
|
|
84
|
+
}[] | undefined;
|
|
78
85
|
outgoing: boolean | null;
|
|
79
86
|
attachments: {
|
|
80
87
|
message?: string | undefined;
|
|
@@ -52,6 +52,13 @@ export declare const threadAnswer: ({ items, ...thread }: ThreadContext, reader:
|
|
|
52
52
|
sender_name: string | null;
|
|
53
53
|
text: string;
|
|
54
54
|
}[] | undefined;
|
|
55
|
+
follow_ups?: {
|
|
56
|
+
ref: string;
|
|
57
|
+
chat_title: string | null;
|
|
58
|
+
timestamp: string;
|
|
59
|
+
sender_name: string | null;
|
|
60
|
+
text: string;
|
|
61
|
+
}[] | undefined;
|
|
55
62
|
outgoing: boolean | null;
|
|
56
63
|
attachments: {
|
|
57
64
|
message?: string | undefined;
|
|
@@ -56,6 +56,13 @@ export declare const writtenAnswer: ({ operationId, sendId, message, messages, s
|
|
|
56
56
|
sender_name: string | null;
|
|
57
57
|
text: string;
|
|
58
58
|
}[] | undefined;
|
|
59
|
+
follow_ups?: {
|
|
60
|
+
ref: string;
|
|
61
|
+
chat_title: string | null;
|
|
62
|
+
timestamp: string;
|
|
63
|
+
sender_name: string | null;
|
|
64
|
+
text: string;
|
|
65
|
+
}[] | undefined;
|
|
59
66
|
outgoing: boolean | null;
|
|
60
67
|
attachments: {
|
|
61
68
|
message?: string | undefined;
|
|
@@ -268,6 +275,13 @@ export declare const writtenAnswer: ({ operationId, sendId, message, messages, s
|
|
|
268
275
|
sender_name: string | null;
|
|
269
276
|
text: string;
|
|
270
277
|
}[] | undefined;
|
|
278
|
+
follow_ups?: {
|
|
279
|
+
ref: string;
|
|
280
|
+
chat_title: string | null;
|
|
281
|
+
timestamp: string;
|
|
282
|
+
sender_name: string | null;
|
|
283
|
+
text: string;
|
|
284
|
+
}[] | undefined;
|
|
271
285
|
outgoing: boolean | null;
|
|
272
286
|
attachments: {
|
|
273
287
|
message?: string | undefined;
|
|
@@ -5,7 +5,9 @@ import { isLocator, parseLocator } from "../../domain/locator.js";
|
|
|
5
5
|
import { SAVE_HELP } from "../../meetings/index.js";
|
|
6
6
|
import { renderMessages } from "../../render/messages.js";
|
|
7
7
|
import { renderThreadLinks } from "../../render/thread-context.js";
|
|
8
|
+
import { chatCoverage } from "../../services/chat-coverage.js";
|
|
8
9
|
import { readMail } from "../../services/mail-search.js";
|
|
10
|
+
import { storedChatId } from "../../services/message-resolution.js";
|
|
9
11
|
import { modelWith, spoken } from "../../speech/hearing.js";
|
|
10
12
|
import { REMOTE_READ } from "../effects.js";
|
|
11
13
|
import { itemOf, listOf, renderAnswer } from "../envelope.js";
|
|
@@ -30,6 +32,7 @@ import { pinCommand, starCommands, unpinCommand } from "./messages-pin-command.j
|
|
|
30
32
|
import { pressCommand } from "./messages-press-command.js";
|
|
31
33
|
import { scheduledCommand } from "./messages-scheduled-command.js";
|
|
32
34
|
import { sendCommand } from "./messages-send-command.js";
|
|
35
|
+
import { coverageGaps } from "./search-answers.js";
|
|
33
36
|
import { threadOptions, threadRequest } from "./thread-options.js";
|
|
34
37
|
import { transcribeSubcommand } from "./transcribe-command.js";
|
|
35
38
|
/** `messages`: reading, and sending through the guard. A CLI may add its own subcommands. */
|
|
@@ -40,6 +43,7 @@ export const messagesCommand = (messenger) => {
|
|
|
40
43
|
const list = annotate(messages.command("list"), {
|
|
41
44
|
examples: [`${messenger.app.command} personal messages list "Book club" --limit 20`],
|
|
42
45
|
effects: REMOTE_READ,
|
|
46
|
+
partial: true,
|
|
43
47
|
})
|
|
44
48
|
.description("a chat's messages, oldest to newest")
|
|
45
49
|
.addHelpText("after", SAVE_HELP)
|
|
@@ -68,6 +72,12 @@ export const messagesCommand = (messenger) => {
|
|
|
68
72
|
const next = page.hasMore
|
|
69
73
|
? cursorOf(window, { first: page.items[0]?.id, last: page.items.at(-1)?.id })
|
|
70
74
|
: undefined;
|
|
75
|
+
// Offline, the store is the whole answer: say how much of the chat it holds. Online the messenger is read.
|
|
76
|
+
const gaps = context.settings.offline
|
|
77
|
+
? coverageGaps(await context.withStore(async (store, account) => chatCoverage(store, account, [
|
|
78
|
+
await storedChatId(messenger, chat, store, account, { includeLeft: true }),
|
|
79
|
+
])))
|
|
80
|
+
: { next: [], missing: [] };
|
|
71
81
|
renderAnswer(this, context, listOf("messages list", {
|
|
72
82
|
items: messageItems(heardItems(page.items, hearing), reader),
|
|
73
83
|
limit,
|
|
@@ -75,7 +85,9 @@ export const messagesCommand = (messenger) => {
|
|
|
75
85
|
paging: "cursor",
|
|
76
86
|
...(next === undefined ? {} : { cursor: next }),
|
|
77
87
|
args: { chat, ...(query.length > 0 ? { query: query.join(" ") } : {}) },
|
|
78
|
-
|
|
88
|
+
next: gaps.next,
|
|
89
|
+
missing: [...hearingMissing(hearing, transcribe === true), ...gaps.missing],
|
|
90
|
+
...(gaps.missing.length > 0 ? { meta: { complete: false } } : {}),
|
|
79
91
|
}), () => renderMessages(spokenItems(page.items, hearing), viewOf(context, messenger)));
|
|
80
92
|
});
|
|
81
93
|
annotate(list, { output: { entity: "message" }, query: history });
|
|
@@ -174,7 +174,10 @@ const searchAction = (messenger) => async function (given) {
|
|
|
174
174
|
const place = hit.matchedIn && hit.matchedIn !== "text" && "excerpt" in hit
|
|
175
175
|
? `\n found in the ${PLACES[hit.matchedIn]}: ${String(hit.excerpt)}`
|
|
176
176
|
: "";
|
|
177
|
-
|
|
177
|
+
const later = (hit.followUps ?? [])
|
|
178
|
+
.map((one) => `\n later, shares a rare word · ${one.chatTitle ?? one.chatId} ${one.locator}\n${renderMessages([one], options)}`)
|
|
179
|
+
.join("");
|
|
180
|
+
return `${spans ? `${at.provider} · ${title}` : title} ${hit.locator}\n${renderMessages(hit.thread?.items ?? hit.context ?? [hit], options)}${place}${later}${links ? `\n${links}` : ""}`;
|
|
178
181
|
})
|
|
179
182
|
.join("\n\n");
|
|
180
183
|
const elsewhere = [...new Set(hits.map(({ at }) => at.provider))].filter((one) => one !== messenger.provider);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Missing, NextStep } from "@wirecat/cli-base/standards";
|
|
2
2
|
import type { InferOutput } from "valibot";
|
|
3
3
|
import type { ENTITIES } from "../../entities/index.js";
|
|
4
|
+
import type { ChatCoverage } from "../../services/chat-coverage.js";
|
|
4
5
|
import type { FoundMessage, SearchFound } from "../../services/messages.js";
|
|
5
6
|
import type { MeaningSkipped } from "../../services/messages-discovery.js";
|
|
6
7
|
import type { FoundNote, NotesFoundOf } from "../../services/notes-search.js";
|
|
@@ -16,8 +17,11 @@ export type HitItem = InferOutput<(typeof ENTITIES)["hit"]>;
|
|
|
16
17
|
/** The page a `--page` asks for, as the offset the search services take. */
|
|
17
18
|
export declare const offsetOf: (page: number | undefined, limit: number) => number | undefined;
|
|
18
19
|
export declare const messageHitItem: (hit: FoundMessage, query?: string) => MessageHitItem;
|
|
19
|
-
/**
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* What the archive lacked for this answer, and the step that would fill it. From a search's coverage, or from the
|
|
22
|
+
* chats an answer is about (`since` is the start of the window it was asked for).
|
|
23
|
+
*/
|
|
24
|
+
export declare const coverageGaps: (found: Pick<SearchFound, "coverage" | "refreshed"> | ChatCoverage[], shown?: number, since?: string) => {
|
|
21
25
|
next: NextStep[];
|
|
22
26
|
missing: Missing[];
|
|
23
27
|
};
|
|
@@ -12,7 +12,16 @@ const defined = (value) => Object.fromEntries(Object.entries(value).filter(([, o
|
|
|
12
12
|
/** The page a `--page` asks for, as the offset the search services take. */
|
|
13
13
|
export const offsetOf = (page, limit) => page === undefined || page <= 1 ? undefined : (page - 1) * limit;
|
|
14
14
|
/** Who wrote it and what, the chat's title, the mail's headers: others write them; the owner's own messages too. */
|
|
15
|
-
const MESSAGE_HIT_UNTRUSTED = [
|
|
15
|
+
const MESSAGE_HIT_UNTRUSTED = [
|
|
16
|
+
"chat_title",
|
|
17
|
+
"sender_name",
|
|
18
|
+
"excerpt",
|
|
19
|
+
"context.sender_name",
|
|
20
|
+
"context.text",
|
|
21
|
+
"follow_ups.chat_title",
|
|
22
|
+
"follow_ups.sender_name",
|
|
23
|
+
"follow_ups.text",
|
|
24
|
+
];
|
|
16
25
|
const MAIL_HIT_UNTRUSTED = [
|
|
17
26
|
"email.subject",
|
|
18
27
|
"email.from.name",
|
|
@@ -67,20 +76,61 @@ export const messageHitItem = (hit, query = "") => {
|
|
|
67
76
|
sender_name: one.senderName,
|
|
68
77
|
text: one.text,
|
|
69
78
|
})),
|
|
79
|
+
follow_ups: hit.followUps?.map((one) => ({
|
|
80
|
+
ref: one.locator,
|
|
81
|
+
chat_title: one.chatTitle ?? null,
|
|
82
|
+
timestamp: one.timestamp,
|
|
83
|
+
sender_name: one.senderName,
|
|
84
|
+
text: one.text,
|
|
85
|
+
})),
|
|
70
86
|
untrusted: hit.email ? [...MESSAGE_HIT_UNTRUSTED, ...MAIL_HIT_UNTRUSTED] : MESSAGE_HIT_UNTRUSTED,
|
|
71
87
|
});
|
|
72
88
|
};
|
|
73
89
|
const accountName = ({ provider, account }) => `${provider}:${account}`;
|
|
74
90
|
/** A source left out is an issue by its code; the sentence saying why goes to a person as a note, never here. */
|
|
75
|
-
const metaOf = (accounts, skipped = []) => ({
|
|
91
|
+
const metaOf = (accounts, skipped = [], heldInPart = false) => ({
|
|
76
92
|
accounts: accounts.map(accountName),
|
|
77
|
-
complete: skipped.length === 0,
|
|
93
|
+
complete: skipped.length === 0 && !heldInPart,
|
|
78
94
|
...(skipped.length
|
|
79
95
|
? { issues: skipped.map(({ source, resource, code }) => ({ code, source: source ?? resource ?? "" })) }
|
|
80
96
|
: {}),
|
|
81
97
|
});
|
|
82
|
-
|
|
83
|
-
|
|
98
|
+
const day = (at) => at?.slice(0, 10) ?? "no date";
|
|
99
|
+
/**
|
|
100
|
+
* The steps for chats the store holds only in part. Bounded first, when the answer's window is known, then the whole
|
|
101
|
+
* chat; both name the first chat only, because a download is the owner's call. Counts and dates only, never text.
|
|
102
|
+
*/
|
|
103
|
+
const chatGaps = (rows, since) => {
|
|
104
|
+
const open = rows.filter(({ completeness }) => completeness.state !== "complete");
|
|
105
|
+
const [first] = open;
|
|
106
|
+
if (!first)
|
|
107
|
+
return { next: [], missing: [] };
|
|
108
|
+
const held = first.completeness.state === "unknown" ? "never fetched" : `held from ${day(first.held.oldestAt)} only`;
|
|
109
|
+
const steps = (args, why) => ({
|
|
110
|
+
...nextStep("messages.sync", { args: { chat: first.chatId, ...args } }),
|
|
111
|
+
why,
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
next: [
|
|
115
|
+
...(since === undefined ? [] : [steps({ since_time: since }, `${held}; this reads back to ${day(since)}`)]),
|
|
116
|
+
steps({}, "reads the chat back to its first message; a big group can take minutes"),
|
|
117
|
+
],
|
|
118
|
+
missing: [
|
|
119
|
+
{
|
|
120
|
+
field: "history",
|
|
121
|
+
why: `${open.length} of ${rows.length} chats hold only part of their history; the first is ${held}`,
|
|
122
|
+
step: "messages.sync",
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* What the archive lacked for this answer, and the step that would fill it. From a search's coverage, or from the
|
|
129
|
+
* chats an answer is about (`since` is the start of the window it was asked for).
|
|
130
|
+
*/
|
|
131
|
+
export const coverageGaps = (found, shown = 0, since) => {
|
|
132
|
+
if (Array.isArray(found))
|
|
133
|
+
return chatGaps(found, since);
|
|
84
134
|
const coverage = found.coverage;
|
|
85
135
|
const stale = found.refreshed?.complete === false;
|
|
86
136
|
if (!coverage?.next && !stale)
|
|
@@ -187,7 +237,7 @@ export const messagesAnswer = (command, found, { limit, page, again }, query = "
|
|
|
187
237
|
page: page ?? 1,
|
|
188
238
|
...(again ? { args: again } : {}),
|
|
189
239
|
...gapsOf(found),
|
|
190
|
-
meta: metaOf(accounts, found.skipped),
|
|
240
|
+
meta: metaOf(accounts, found.skipped, coverageGaps(found).missing.length > 0),
|
|
191
241
|
});
|
|
192
242
|
};
|
|
193
243
|
/**
|
|
@@ -256,6 +306,7 @@ export const allAnswer = (command, found, { limit, page, again }, exact = false)
|
|
|
256
306
|
const scan = found.meetings?.complete === false ? found.meetings : undefined;
|
|
257
307
|
const notes = meaningGap(found.notes?.meaningSkipped, exact);
|
|
258
308
|
const messages = messageMeaningGap(found.messages?.meaningSkipped, "found_by");
|
|
309
|
+
const archive = coverageGaps({ coverage: found.coverage }, found.items.length);
|
|
259
310
|
return listOf(command, {
|
|
260
311
|
items: found.items.map(allHitItem),
|
|
261
312
|
limit,
|
|
@@ -274,6 +325,7 @@ export const allAnswer = (command, found, { limit, page, again }, exact = false)
|
|
|
274
325
|
: []),
|
|
275
326
|
...notes.next,
|
|
276
327
|
...messages.next.filter((step) => !notes.next.some((asked) => JSON.stringify(asked) === JSON.stringify(step))),
|
|
328
|
+
...archive.next,
|
|
277
329
|
],
|
|
278
330
|
missing: [
|
|
279
331
|
...(scan
|
|
@@ -287,7 +339,8 @@ export const allAnswer = (command, found, { limit, page, again }, exact = false)
|
|
|
287
339
|
: []),
|
|
288
340
|
...notes.missing,
|
|
289
341
|
...messages.missing,
|
|
342
|
+
...archive.missing,
|
|
290
343
|
],
|
|
291
|
-
meta: metaOf(found.accounts, found.skipped),
|
|
344
|
+
meta: metaOf(found.accounts, found.skipped, archive.missing.length > 0),
|
|
292
345
|
});
|
|
293
346
|
};
|
|
@@ -15,6 +15,7 @@ import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
|
15
15
|
import { listQuery, pagedList, pageOf, queryTerms, typedQuery, withQuery } from "../list-query.js";
|
|
16
16
|
import { positiveCount } from "../paging.js";
|
|
17
17
|
import { messengerContext, refuseLocalWrite } from "./context.js";
|
|
18
|
+
import { coverageGaps } from "./search-answers.js";
|
|
18
19
|
import { refuseJsonl, taskStatsAnswer } from "./stats-answers.js";
|
|
19
20
|
const line = ({ id, key, state, kind, group, createdAt, message, note }) => [
|
|
20
21
|
key ?? id.slice(0, 8),
|
|
@@ -50,10 +51,16 @@ const applyText = (pass, yes, tool) => yes
|
|
|
50
51
|
...pass.tasks.map((task) => ` ${task.kind.padEnd(8)} ${(task.category ?? "—").padEnd(13)} ${task.source}`),
|
|
51
52
|
...(pass.tasks.length > 0 ? [` ${tool} tasks scan ${pass.chat} --yes opens them`] : []),
|
|
52
53
|
].join("\n");
|
|
54
|
+
const agendaChats = (agenda) => [...agenda.unsynced, ...agenda.owed, ...agenda.waiting];
|
|
55
|
+
const agendaGaps = (agenda) => coverageGaps(agendaChats(agenda).map(({ coverage }) => coverage), 0, agenda.since);
|
|
56
|
+
const STATE_MARK = { complete: "", partial: " [partial]", unknown: " [never fetched]" };
|
|
53
57
|
const agendaText = (agenda) => {
|
|
54
58
|
const chat = (one) => ` ${when(one.lastMessageAt)} ${one.title ?? one.chatId} ${one.lastMessage ?? one.chatId}` +
|
|
55
|
-
(one.openTasks.length > 0 ? ` (${one.openTasks.length} open)` : "")
|
|
59
|
+
(one.openTasks.length > 0 ? ` (${one.openTasks.length} open)` : "") +
|
|
60
|
+
STATE_MARK[one.coverage.completeness.state];
|
|
61
|
+
const [history] = agendaGaps(agenda).missing;
|
|
56
62
|
return [
|
|
63
|
+
...(history ? [`${history.why}: sync before trusting what is listed`] : []),
|
|
57
64
|
...(agenda.stale
|
|
58
65
|
? [`the store saved nothing since ${when(agenda.storedAt)}: sync before trusting quiet chats`]
|
|
59
66
|
: []),
|
|
@@ -356,7 +363,11 @@ export const tasksCommand = (messenger) => {
|
|
|
356
363
|
const unmerged = await context.withServices((services) => services.tasks.unmerge(dup, writerOf(this)));
|
|
357
364
|
renderAnswer(this, context, itemOf(snakeKeys(unmerged)), () => `${card(unmerged.task)}\n`);
|
|
358
365
|
});
|
|
359
|
-
withQuery(annotate(tasks.command("agenda"), {
|
|
366
|
+
withQuery(annotate(tasks.command("agenda"), {
|
|
367
|
+
effects: LOCAL_READ,
|
|
368
|
+
partial: true,
|
|
369
|
+
examples: [`${tool} personal tasks agenda`],
|
|
370
|
+
})
|
|
360
371
|
.summary("what needs a look today: tasks due, chats you owe or wait on, what you are owed")
|
|
361
372
|
.description("what needs a look today, from the local store and without message text: tasks overdue, due or to check, " +
|
|
362
373
|
"chats where you owe an answer, chats where you wait for one, open tasks someone else does"), AGENDA_QUERY)
|
|
@@ -377,7 +388,8 @@ export const tasksCommand = (messenger) => {
|
|
|
377
388
|
...(query ? { query } : {}),
|
|
378
389
|
holder: holderOf(this),
|
|
379
390
|
}));
|
|
380
|
-
|
|
391
|
+
const { next, missing } = agendaGaps(agenda);
|
|
392
|
+
renderAnswer(this, context, itemOf(agendaItem(agenda), { next, missing, ...(missing.length > 0 ? { meta: { complete: false } } : {}) }), () => `${agendaText(agenda)}\n`);
|
|
381
393
|
});
|
|
382
394
|
annotate(tasks.command("categories"), {
|
|
383
395
|
output: { entity: "task_categories" },
|
package/dist/cli/steps.js
CHANGED
|
@@ -14,6 +14,7 @@ export const STEPS = defineSteps([
|
|
|
14
14
|
args: [
|
|
15
15
|
{ name: "chat", required: false },
|
|
16
16
|
{ name: "all", required: false },
|
|
17
|
+
{ name: "since_time", required: false },
|
|
17
18
|
{ name: "background", required: false },
|
|
18
19
|
],
|
|
19
20
|
why: "the local copy is missing messages; syncing brings them in",
|
|
@@ -42,6 +42,20 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
42
42
|
readonly last_from_owner: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
43
43
|
/** Open tasks whose source is in this chat. */
|
|
44
44
|
readonly open_tasks: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
45
|
+
/** `unknown` means nothing ever fetched the chat's history; `partial` that the store holds only part of it. */
|
|
46
|
+
readonly completeness: v.StrictObjectSchema<{
|
|
47
|
+
readonly state: v.PicklistSchema<["complete", "partial", "unknown"], undefined>;
|
|
48
|
+
readonly up_to_date: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
49
|
+
readonly gaps: v.BooleanSchema<undefined>;
|
|
50
|
+
readonly reaches_start: v.BooleanSchema<undefined>;
|
|
51
|
+
readonly fetched_at: v.NullableSchema<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`">]>, undefined>;
|
|
52
|
+
}, undefined>;
|
|
53
|
+
/** What the store holds of the chat: the count and the span, never the text. */
|
|
54
|
+
readonly held: v.StrictObjectSchema<{
|
|
55
|
+
readonly messages: v.NumberSchema<undefined>;
|
|
56
|
+
readonly oldest_at: v.NullableSchema<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`">]>, undefined>;
|
|
57
|
+
readonly newest_at: v.NullableSchema<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`">]>, undefined>;
|
|
58
|
+
}, undefined>;
|
|
45
59
|
}, undefined>, undefined>;
|
|
46
60
|
/** The owner wrote last, and nobody answered. */
|
|
47
61
|
readonly waiting: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -55,6 +69,20 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
55
69
|
readonly last_from_owner: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
56
70
|
/** Open tasks whose source is in this chat. */
|
|
57
71
|
readonly open_tasks: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
72
|
+
/** `unknown` means nothing ever fetched the chat's history; `partial` that the store holds only part of it. */
|
|
73
|
+
readonly completeness: v.StrictObjectSchema<{
|
|
74
|
+
readonly state: v.PicklistSchema<["complete", "partial", "unknown"], undefined>;
|
|
75
|
+
readonly up_to_date: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
76
|
+
readonly gaps: v.BooleanSchema<undefined>;
|
|
77
|
+
readonly reaches_start: v.BooleanSchema<undefined>;
|
|
78
|
+
readonly fetched_at: v.NullableSchema<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`">]>, undefined>;
|
|
79
|
+
}, undefined>;
|
|
80
|
+
/** What the store holds of the chat: the count and the span, never the text. */
|
|
81
|
+
readonly held: v.StrictObjectSchema<{
|
|
82
|
+
readonly messages: v.NumberSchema<undefined>;
|
|
83
|
+
readonly oldest_at: v.NullableSchema<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`">]>, undefined>;
|
|
84
|
+
readonly newest_at: v.NullableSchema<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`">]>, undefined>;
|
|
85
|
+
}, undefined>;
|
|
58
86
|
}, undefined>, undefined>;
|
|
59
87
|
/** The chat list says these moved and their newest message is not stored: read them first. */
|
|
60
88
|
readonly unsynced: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -68,6 +96,20 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
68
96
|
readonly last_from_owner: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
69
97
|
/** Open tasks whose source is in this chat. */
|
|
70
98
|
readonly open_tasks: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
99
|
+
/** `unknown` means nothing ever fetched the chat's history; `partial` that the store holds only part of it. */
|
|
100
|
+
readonly completeness: v.StrictObjectSchema<{
|
|
101
|
+
readonly state: v.PicklistSchema<["complete", "partial", "unknown"], undefined>;
|
|
102
|
+
readonly up_to_date: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
103
|
+
readonly gaps: v.BooleanSchema<undefined>;
|
|
104
|
+
readonly reaches_start: v.BooleanSchema<undefined>;
|
|
105
|
+
readonly fetched_at: v.NullableSchema<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`">]>, undefined>;
|
|
106
|
+
}, undefined>;
|
|
107
|
+
/** What the store holds of the chat: the count and the span, never the text. */
|
|
108
|
+
readonly held: v.StrictObjectSchema<{
|
|
109
|
+
readonly messages: v.NumberSchema<undefined>;
|
|
110
|
+
readonly oldest_at: v.NullableSchema<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`">]>, undefined>;
|
|
111
|
+
readonly newest_at: v.NullableSchema<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`">]>, undefined>;
|
|
112
|
+
}, undefined>;
|
|
71
113
|
}, undefined>, undefined>;
|
|
72
114
|
/** Open tasks someone else does: what they owe the owner, oldest first. */
|
|
73
115
|
readonly assigned: v.ArraySchema<v.StrictObjectSchema<{
|
package/dist/entities/agenda.js
CHANGED
|
@@ -13,6 +13,16 @@ const agendaChat = v.strictObject({
|
|
|
13
13
|
last_from_owner: v.nullable(v.boolean()),
|
|
14
14
|
/** Open tasks whose source is in this chat. */
|
|
15
15
|
open_tasks: v.array(id),
|
|
16
|
+
/** `unknown` means nothing ever fetched the chat's history; `partial` that the store holds only part of it. */
|
|
17
|
+
completeness: v.strictObject({
|
|
18
|
+
state: v.picklist(["complete", "partial", "unknown"]),
|
|
19
|
+
up_to_date: v.nullable(v.boolean()),
|
|
20
|
+
gaps: v.boolean(),
|
|
21
|
+
reaches_start: v.boolean(),
|
|
22
|
+
fetched_at: v.nullable(time),
|
|
23
|
+
}),
|
|
24
|
+
/** What the store holds of the chat: the count and the span, never the text. */
|
|
25
|
+
held: v.strictObject({ messages: v.number(), oldest_at: v.nullable(time), newest_at: v.nullable(time) }),
|
|
16
26
|
});
|
|
17
27
|
/** What needs a look today, from the store alone and without one message's text. */
|
|
18
28
|
export const agenda = v.strictObject({
|
|
@@ -51,6 +51,13 @@ export declare const conversationDetails: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
51
51
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
52
52
|
readonly text: v.StringSchema<undefined>;
|
|
53
53
|
}, undefined>, undefined>, undefined>;
|
|
54
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
55
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
56
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
59
|
+
readonly text: v.StringSchema<undefined>;
|
|
60
|
+
}, undefined>, undefined>, undefined>;
|
|
54
61
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
55
62
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
56
63
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -261,6 +268,13 @@ export declare const conversationDetails: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
261
268
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
262
269
|
readonly text: v.StringSchema<undefined>;
|
|
263
270
|
}, undefined>, undefined>, undefined>;
|
|
271
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
272
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
273
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
276
|
+
readonly text: v.StringSchema<undefined>;
|
|
277
|
+
}, undefined>, undefined>, undefined>;
|
|
264
278
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
265
279
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
266
280
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -42,6 +42,13 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
42
42
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
43
43
|
readonly text: v.StringSchema<undefined>;
|
|
44
44
|
}, undefined>, undefined>, undefined>;
|
|
45
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
46
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
47
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
50
|
+
readonly text: v.StringSchema<undefined>;
|
|
51
|
+
}, undefined>, undefined>, undefined>;
|
|
45
52
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
46
53
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
47
54
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -252,6 +259,13 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
252
259
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
253
260
|
readonly text: v.StringSchema<undefined>;
|
|
254
261
|
}, undefined>, undefined>, undefined>;
|
|
262
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
263
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
264
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
267
|
+
readonly text: v.StringSchema<undefined>;
|
|
268
|
+
}, undefined>, undefined>, undefined>;
|
|
255
269
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
256
270
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
257
271
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -500,6 +514,13 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
500
514
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
501
515
|
readonly text: v.StringSchema<undefined>;
|
|
502
516
|
}, undefined>, undefined>, undefined>;
|
|
517
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
518
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
519
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
522
|
+
readonly text: v.StringSchema<undefined>;
|
|
523
|
+
}, undefined>, undefined>, undefined>;
|
|
503
524
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
504
525
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
505
526
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -710,6 +731,13 @@ export declare const contribution: v.StrictObjectSchema<{
|
|
|
710
731
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
711
732
|
readonly text: v.StringSchema<undefined>;
|
|
712
733
|
}, undefined>, undefined>, undefined>;
|
|
734
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
735
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
736
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
739
|
+
readonly text: v.StringSchema<undefined>;
|
|
740
|
+
}, undefined>, undefined>, undefined>;
|
|
713
741
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
714
742
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
715
743
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -994,6 +1022,13 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
994
1022
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
995
1023
|
readonly text: v.StringSchema<undefined>;
|
|
996
1024
|
}, undefined>, undefined>, undefined>;
|
|
1025
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
1026
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
1027
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1030
|
+
readonly text: v.StringSchema<undefined>;
|
|
1031
|
+
}, undefined>, undefined>, undefined>;
|
|
997
1032
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
998
1033
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
999
1034
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -1204,6 +1239,13 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1204
1239
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1205
1240
|
readonly text: v.StringSchema<undefined>;
|
|
1206
1241
|
}, undefined>, undefined>, undefined>;
|
|
1242
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
1243
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
1244
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1247
|
+
readonly text: v.StringSchema<undefined>;
|
|
1248
|
+
}, undefined>, undefined>, undefined>;
|
|
1207
1249
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1208
1250
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
1209
1251
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -1452,6 +1494,13 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1452
1494
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1453
1495
|
readonly text: v.StringSchema<undefined>;
|
|
1454
1496
|
}, undefined>, undefined>, undefined>;
|
|
1497
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
1498
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
1499
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1502
|
+
readonly text: v.StringSchema<undefined>;
|
|
1503
|
+
}, undefined>, undefined>, undefined>;
|
|
1455
1504
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1456
1505
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
1457
1506
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
@@ -1662,6 +1711,13 @@ export declare const evidence: v.UnionSchema<[v.StrictObjectSchema<{
|
|
|
1662
1711
|
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1663
1712
|
readonly text: v.StringSchema<undefined>;
|
|
1664
1713
|
}, undefined>, undefined>, undefined>;
|
|
1714
|
+
readonly follow_ups: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
1715
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
1716
|
+
readonly chat_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
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
|
+
readonly sender_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
1719
|
+
readonly text: v.StringSchema<undefined>;
|
|
1720
|
+
}, undefined>, undefined>, undefined>;
|
|
1665
1721
|
readonly outgoing: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
1666
1722
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
1667
1723
|
readonly message: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|