@wirecat/cli-core 0.398.0 → 0.400.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 +106 -0
- package/dist/analysis/consents.d.ts +11 -6
- package/dist/analysis/consents.js +5 -2
- package/dist/cli/analysis-choice.d.ts +1 -0
- package/dist/cli/analysis-choice.js +3 -0
- package/dist/cli/bot/admins.js +14 -4
- package/dist/cli/bot/command.js +38 -16
- package/dist/cli/bot/examples.d.ts +3 -0
- package/dist/cli/bot/examples.js +2 -0
- package/dist/cli/bot/mcp.js +6 -2
- package/dist/cli/bot/messages.js +17 -6
- package/dist/cli/bot/moderation.js +16 -4
- package/dist/cli/bot/people.js +16 -4
- package/dist/cli/bot/setup.js +27 -8
- package/dist/cli/bot/watch.js +7 -1
- package/dist/cli/config-command.js +20 -1
- package/dist/cli/context.d.ts +2 -0
- package/dist/cli/context.js +1 -1
- package/dist/cli/effects.d.ts +4 -1
- package/dist/cli/effects.js +10 -2
- package/dist/cli/embedding-choice.d.ts +2 -1
- package/dist/cli/embedding-choice.js +4 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/json-fields.js +12 -1
- package/dist/cli/messenger/account-command.js +15 -6
- package/dist/cli/messenger/account-profile-query.d.ts +2 -0
- package/dist/cli/messenger/account-profile-query.js +13 -0
- package/dist/cli/messenger/account-sessions-command.js +1 -0
- package/dist/cli/messenger/admin-commands.js +30 -21
- package/dist/cli/messenger/admin-contacts-command.js +6 -3
- package/dist/cli/messenger/admin-folders-command.js +5 -5
- package/dist/cli/messenger/admin-moderation-command.js +4 -4
- package/dist/cli/messenger/admin-statistics-command.js +6 -14
- package/dist/cli/messenger/analysis-consents-query.d.ts +5 -0
- package/dist/cli/messenger/analysis-consents-query.js +20 -0
- package/dist/cli/messenger/archive-commands.js +3 -3
- package/dist/cli/messenger/attachments-command.js +3 -0
- package/dist/cli/messenger/backfill-command.js +5 -4
- package/dist/cli/messenger/catch-up-answers.d.ts +2 -1
- package/dist/cli/messenger/catch-up-answers.js +6 -2
- package/dist/cli/messenger/chat-queries.d.ts +1 -0
- package/dist/cli/messenger/chat-queries.js +12 -2
- package/dist/cli/messenger/chats-command.js +2 -2
- package/dist/cli/messenger/chats-documents-command.js +7 -5
- package/dist/cli/messenger/chats-members-command.js +7 -3
- package/dist/cli/messenger/chats-read-command.js +1 -1
- package/dist/cli/messenger/chats-stats-command.js +1 -1
- package/dist/cli/messenger/chats-tracking-command.js +14 -6
- package/dist/cli/messenger/contacts-command.js +11 -7
- package/dist/cli/messenger/context.d.ts +2 -0
- package/dist/cli/messenger/conversations-command.js +47 -29
- package/dist/cli/messenger/doctor-command.js +5 -1
- package/dist/cli/messenger/document-links-query.d.ts +2 -0
- package/dist/cli/messenger/document-links-query.js +9 -0
- package/dist/cli/messenger/download-command.js +1 -0
- package/dist/cli/messenger/flood-command.d.ts +2 -2
- package/dist/cli/messenger/flood-command.js +3 -3
- package/dist/cli/messenger/gaps-command.js +2 -2
- package/dist/cli/messenger/guard-commands.js +35 -13
- package/dist/cli/messenger/hearing-command.d.ts +1 -1
- package/dist/cli/messenger/hearing-command.js +1 -1
- package/dist/cli/messenger/images-command.js +1 -0
- package/dist/cli/messenger/inbox.js +6 -4
- package/dist/cli/messenger/media-archive-command.js +2 -0
- package/dist/cli/messenger/media-archive-move-command.js +1 -0
- package/dist/cli/messenger/media-archive-timer-command.js +1 -1
- package/dist/cli/messenger/mentions-command.js +15 -2
- package/dist/cli/messenger/messages-command.js +2 -0
- package/dist/cli/messenger/messages-delete-command.js +1 -0
- package/dist/cli/messenger/messages-edit-command.js +1 -0
- package/dist/cli/messenger/messages-evidence-command.js +3 -1
- package/dist/cli/messenger/messages-forward-command.js +1 -0
- package/dist/cli/messenger/messages-pin-command.js +3 -0
- package/dist/cli/messenger/messages-send-command.js +1 -0
- package/dist/cli/messenger/messages-stats-command.js +1 -1
- package/dist/cli/messenger/metadata-command.js +7 -2
- package/dist/cli/messenger/models-command.js +10 -2
- package/dist/cli/messenger/polls-command.js +4 -0
- package/dist/cli/messenger/private-people-command.js +8 -6
- package/dist/cli/messenger/rankings-command.js +6 -11
- package/dist/cli/messenger/reactions-command.js +2 -0
- package/dist/cli/messenger/recipients-query.d.ts +5 -0
- package/dist/cli/messenger/recipients-query.js +18 -0
- package/dist/cli/messenger/records-command.js +13 -6
- package/dist/cli/messenger/replies-edit-command.d.ts +1 -1
- package/dist/cli/messenger/replies-edit-command.js +13 -5
- package/dist/cli/messenger/retention-command.js +1 -1
- package/dist/cli/messenger/review.js +6 -4
- package/dist/cli/messenger/search-command.js +3 -1
- package/dist/cli/messenger/searches-command.js +6 -2
- package/dist/cli/messenger/sends-query.d.ts +5 -0
- package/dist/cli/messenger/sends-query.js +33 -0
- package/dist/cli/messenger/serve-command.js +1 -0
- package/dist/cli/messenger/serve-relay.d.ts +1 -0
- package/dist/cli/messenger/statistics-query.d.ts +14 -0
- package/dist/cli/messenger/statistics-query.js +143 -0
- package/dist/cli/messenger/stats-command.js +6 -6
- package/dist/cli/messenger/store-maintenance-command.d.ts +1 -1
- package/dist/cli/messenger/store-maintenance-command.js +10 -10
- package/dist/cli/messenger/tags-command.js +18 -6
- package/dist/cli/messenger/tasks-command.js +47 -8
- package/dist/cli/messenger/transcribe-command.js +2 -1
- package/dist/cli/messenger/watch-answers.d.ts +6 -0
- package/dist/cli/messenger/watch-answers.js +69 -0
- package/dist/cli/messenger/watch-command.d.ts +1 -1
- package/dist/cli/messenger/watch-command.js +56 -7
- package/dist/cli/program.js +5 -1
- package/dist/cli/runs/command.js +25 -38
- package/dist/cli/runs/query.d.ts +5 -0
- package/dist/cli/runs/query.js +32 -0
- package/dist/cli/runs/search-command.d.ts +4 -0
- package/dist/cli/runs/search-command.js +27 -0
- package/dist/cli/runs/search-query.d.ts +4 -0
- package/dist/cli/runs/search-query.js +50 -0
- package/dist/cli/runs/search.d.ts +2 -1
- package/dist/cli/runs/search.js +6 -6
- package/dist/domain/attachments.js +9 -1
- package/dist/domain/rankings-options.js +3 -3
- package/dist/entities/account-change.d.ts +89 -0
- package/dist/entities/account-change.js +20 -0
- package/dist/entities/account-profile.d.ts +7 -0
- package/dist/entities/account-profile.js +8 -0
- package/dist/entities/analysis-consent.d.ts +9 -0
- package/dist/entities/analysis-consent.js +4 -0
- package/dist/entities/attachment-results.d.ts +96 -0
- package/dist/entities/attachment-results.js +31 -0
- package/dist/entities/batch-result.d.ts +27 -0
- package/dist/entities/batch-result.js +18 -0
- package/dist/entities/chat-admin.d.ts +234 -0
- package/dist/entities/chat-admin.js +84 -0
- package/dist/entities/chat-change.d.ts +25 -0
- package/dist/entities/chat-change.js +11 -0
- package/dist/entities/chat-metadata.d.ts +34 -0
- package/dist/entities/chat-metadata.js +15 -0
- package/dist/entities/chat-moderation.d.ts +44 -0
- package/dist/entities/chat-moderation.js +37 -0
- package/dist/entities/chat-tracking.d.ts +26 -0
- package/dist/entities/chat-tracking.js +23 -0
- package/dist/entities/contact-activity.d.ts +52 -0
- package/dist/entities/contact-activity.js +42 -0
- package/dist/entities/contact-context.d.ts +1568 -0
- package/dist/entities/contact-context.js +191 -0
- package/dist/entities/contact-write.d.ts +22 -0
- package/dist/entities/contact-write.js +6 -0
- package/dist/entities/conversation-preparation.d.ts +63 -0
- package/dist/entities/conversation-preparation.js +23 -0
- package/dist/entities/conversation-results.d.ts +567 -0
- package/dist/entities/conversation-results.js +94 -0
- package/dist/entities/document-link.d.ts +13 -0
- package/dist/entities/document-link.js +11 -0
- package/dist/entities/extraction-report.d.ts +95 -0
- package/dist/entities/extraction-report.js +34 -0
- package/dist/entities/image-embedding.d.ts +9 -0
- package/dist/entities/image-embedding.js +10 -0
- package/dist/entities/index.d.ts +8006 -1928
- package/dist/entities/index.js +174 -3
- package/dist/entities/listener.d.ts +2150 -0
- package/dist/entities/listener.js +46 -0
- package/dist/entities/media-archive.d.ts +43 -0
- package/dist/entities/media-archive.js +32 -0
- package/dist/entities/meeting-task-proposal.d.ts +14 -0
- package/dist/entities/meeting-task-proposal.js +19 -0
- package/dist/entities/meeting.d.ts +1 -1
- package/dist/entities/meeting.js +1 -1
- package/dist/entities/mention.d.ts +63 -0
- package/dist/entities/mention.js +44 -0
- package/dist/entities/message-change.d.ts +19 -0
- package/dist/entities/message-change.js +6 -0
- package/dist/entities/message-context.d.ts +617 -0
- package/dist/entities/message-context.js +20 -0
- package/dist/entities/message-read.d.ts +73 -0
- package/dist/entities/message-read.js +58 -0
- package/dist/entities/message-transfer.d.ts +379 -0
- package/dist/entities/message-transfer.js +83 -0
- package/dist/entities/message-write.d.ts +191 -0
- package/dist/entities/message-write.js +8 -0
- package/dist/entities/model-key.d.ts +14 -0
- package/dist/entities/model-key.js +10 -0
- package/dist/entities/poll.d.ts +40 -0
- package/dist/entities/poll.js +16 -0
- package/dist/entities/private-contact.d.ts +10 -0
- package/dist/entities/private-contact.js +4 -0
- package/dist/entities/reaction-change.d.ts +7 -0
- package/dist/entities/reaction-change.js +8 -0
- package/dist/entities/recipient.d.ts +29 -0
- package/dist/entities/recipient.js +11 -0
- package/dist/entities/recorded-run.d.ts +103 -0
- package/dist/entities/recorded-run.js +44 -0
- package/dist/entities/saved-search.d.ts +4 -0
- package/dist/entities/saved-search.js +2 -0
- package/dist/entities/send-attempt.d.ts +31 -0
- package/dist/entities/send-attempt.js +29 -0
- package/dist/entities/store-maintenance.d.ts +319 -0
- package/dist/entities/store-maintenance.js +145 -0
- package/dist/entities/store-records.d.ts +442 -0
- package/dist/entities/store-records.js +99 -0
- package/dist/entities/tag-change.d.ts +74 -0
- package/dist/entities/tag-change.js +31 -0
- package/dist/entities/task-pair.d.ts +31 -0
- package/dist/entities/task-pair.js +23 -0
- package/dist/entities/task-results.d.ts +524 -0
- package/dist/entities/task-results.js +142 -0
- package/dist/errors/reasons.js +1 -0
- package/dist/mcp/agent.d.ts +3 -1
- package/dist/mcp/agent.js +9 -6
- package/dist/mcp/bot/server.d.ts +2 -0
- package/dist/mcp/bot/server.js +1 -0
- package/dist/mcp/prompts.js +8 -2
- package/dist/mcp/server.js +3 -1
- package/dist/mcp/tools/attachments.js +1 -0
- package/dist/meetings/cli/index.js +1 -1
- package/dist/meetings/cli/passage.js +1 -0
- package/dist/meetings/index.d.ts +2 -1
- package/dist/meetings/index.js +1 -0
- package/dist/meetings/links.d.ts +16 -0
- package/dist/meetings/mcp/index.d.ts +15 -15
- package/dist/meetings/read-answers.d.ts +167 -0
- package/dist/meetings/read-answers.js +183 -0
- package/dist/runs/run.d.ts +10 -2
- package/dist/runs/run.js +11 -3
- package/dist/sends/journal.d.ts +8 -1
- package/dist/sends/journal.js +9 -2
- package/dist/sends/permissions.d.ts +5 -1
- package/dist/sends/permissions.js +11 -1
- package/dist/sends/recipients.d.ts +8 -0
- package/dist/sends/recipients.js +9 -0
- package/dist/services/admin-statistics.js +3 -3
- package/dist/services/chat-documents.d.ts +1 -0
- package/dist/services/chat-documents.js +9 -3
- package/dist/services/chats.d.ts +1 -1
- package/dist/services/chats.js +5 -2
- package/dist/services/meeting-links.d.ts +2 -17
- package/dist/store/exports.d.ts +1 -1
- package/dist/store/exports.js +1 -1
- package/dist/store/messages.d.ts +3 -1
- package/dist/store/messages.js +2 -2
- package/dist/store/roster.d.ts +4 -1
- package/dist/store/roster.js +2 -2
- package/dist/store/sqlite/chats.d.ts +12 -0
- package/dist/store/sqlite/chats.js +1 -0
- package/dist/store/sqlite/document-links.d.ts +1 -1
- package/dist/store/sqlite/document-links.js +5 -5
- package/dist/store/sqlite/involvements.js +2 -1
- package/dist/store/sqlite/roster.d.ts +2 -1
- package/dist/store/sqlite/roster.js +3 -2
- package/package.json +3 -3
- package/parity.json +76 -108
|
@@ -4,21 +4,25 @@ import { Command } from "commander";
|
|
|
4
4
|
import { renderMessages } from "../../render/messages.js";
|
|
5
5
|
import { environmentOf } from "../context.js";
|
|
6
6
|
import { REMOTE_READ } from "../effects.js";
|
|
7
|
+
import { jsonlRecords, listOf } from "../envelope.js";
|
|
7
8
|
import { withoutProviderRefs } from "../provider-refs.js";
|
|
8
9
|
import { messengerContext } from "./context.js";
|
|
10
|
+
import { selfOf } from "./message-items.js";
|
|
11
|
+
import { watchEventItem, watchedMessageItem } from "./watch-answers.js";
|
|
9
12
|
/**
|
|
10
13
|
* New messages as they arrive, until Ctrl-C or `--timeout` — both a normal end, exit 0: listening
|
|
11
|
-
* for a minute is a complete answer.
|
|
14
|
+
* for a minute is a complete answer. Canonical item records and one end record with `--jsonl`; `--json` is refused,
|
|
12
15
|
* because a stream is not one value. Nothing is marked read.
|
|
13
16
|
*/
|
|
14
17
|
export const watchCommand = (messenger) => annotate(new Command("watch"), {
|
|
18
|
+
output: { entity: "watch_item" },
|
|
15
19
|
effects: REMOTE_READ,
|
|
16
20
|
lifetime: "persistent",
|
|
17
21
|
examples: [`${messenger.app.command} personal watch --jsonl --timeout 30s`],
|
|
18
22
|
})
|
|
19
23
|
.summary("stream new messages until interrupted or timed out")
|
|
20
24
|
.description("print new messages as they arrive, until Ctrl-C or --timeout (either ends it normally)")
|
|
21
|
-
.option("--events", "
|
|
25
|
+
.option("--events", "include changes and receipts; each item names its event")
|
|
22
26
|
.action(async function () {
|
|
23
27
|
const events = this.opts().events === true;
|
|
24
28
|
const context = messengerContext(this, messenger);
|
|
@@ -35,19 +39,59 @@ export const watchCommand = (messenger) => annotate(new Command("watch"), {
|
|
|
35
39
|
provider: messenger.provider,
|
|
36
40
|
locale: messenger.app.locale,
|
|
37
41
|
})}`;
|
|
38
|
-
//
|
|
39
|
-
// a line of another shape.
|
|
42
|
+
// Event-tagged payloads are opt-in; ordinary items remain message values.
|
|
40
43
|
const stop = new AbortController();
|
|
44
|
+
let connection;
|
|
45
|
+
let printed = 0;
|
|
46
|
+
const account = () => {
|
|
47
|
+
if (!connection)
|
|
48
|
+
throw new Error("watch has no connected account");
|
|
49
|
+
return selfOf(messenger, connection);
|
|
50
|
+
};
|
|
41
51
|
const print = (event) => {
|
|
42
52
|
if (stop.signal.aborted || (!events && event.event !== "message"))
|
|
43
53
|
return;
|
|
44
54
|
if (context.format === "jsonl") {
|
|
45
|
-
|
|
55
|
+
const data = events
|
|
56
|
+
? watchEventItem(event, account())
|
|
57
|
+
: event.event === "message"
|
|
58
|
+
? watchedMessageItem(event.message, account())
|
|
59
|
+
: undefined;
|
|
60
|
+
if (data === undefined)
|
|
61
|
+
return;
|
|
62
|
+
context.streams.data(JSON.stringify({ type: "item", data: withoutProviderRefs(data) }));
|
|
63
|
+
printed++;
|
|
46
64
|
}
|
|
47
65
|
else
|
|
48
66
|
context.streams.data(describe(event, render));
|
|
49
67
|
};
|
|
50
|
-
|
|
68
|
+
const finish = (complete, error) => {
|
|
69
|
+
if (context.format !== "jsonl" || environmentOf(this).commandSignal?.aborted)
|
|
70
|
+
return;
|
|
71
|
+
const issues = !complete && error instanceof CliError ? [{ code: error.code, source: "watch" }] : undefined;
|
|
72
|
+
for (const record of jsonlRecords(listOf("watch", {
|
|
73
|
+
items: [],
|
|
74
|
+
limit: Math.max(1, printed),
|
|
75
|
+
has_more: false,
|
|
76
|
+
paging: "cursor",
|
|
77
|
+
meta: { complete, ...(issues ? { issues } : {}) },
|
|
78
|
+
})))
|
|
79
|
+
context.streams.data(JSON.stringify(record));
|
|
80
|
+
};
|
|
81
|
+
try {
|
|
82
|
+
await listenUntilStopped(this, context, messenger, print, {
|
|
83
|
+
stop,
|
|
84
|
+
pipe: true,
|
|
85
|
+
connected: (open) => {
|
|
86
|
+
connection = open;
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
finish(false, error);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
finish(true);
|
|
51
95
|
});
|
|
52
96
|
/**
|
|
53
97
|
* Listens until Ctrl-C, SIGTERM, `--timeout` or — with `pipe` — a reader that has gone away.
|
|
@@ -55,7 +99,11 @@ export const watchCommand = (messenger) => annotate(new Command("watch"), {
|
|
|
55
99
|
* `feed` runs it beside `watch`, so what the messenger pushes reaches the store (`stored`).
|
|
56
100
|
*/
|
|
57
101
|
export const listenUntilStopped = async (command, context, messenger, onEvent, { stop, pipe = false, catchUp = false, onReady = () => context.renderer.note("listening — Ctrl-C to stop"), connected, }) => {
|
|
58
|
-
const
|
|
102
|
+
const environment = environmentOf(command);
|
|
103
|
+
const phase = environment.untilStopped?.();
|
|
104
|
+
const given = phase
|
|
105
|
+
? AbortSignal.any([phase, ...[environment.signal].filter((one) => one !== undefined)])
|
|
106
|
+
: environment.signal;
|
|
59
107
|
const end = () => stop.abort();
|
|
60
108
|
given?.addEventListener("abort", end, { once: true });
|
|
61
109
|
const signals = given ? [] : ["SIGINT", "SIGTERM"];
|
|
@@ -96,6 +144,7 @@ export const listenUntilStopped = async (command, context, messenger, onEvent, {
|
|
|
96
144
|
if (pipe && !given)
|
|
97
145
|
process.stdout.off("error", closed);
|
|
98
146
|
given?.removeEventListener("abort", end);
|
|
147
|
+
environment.endUntilStopped?.();
|
|
99
148
|
}
|
|
100
149
|
};
|
|
101
150
|
const describe = (event, render) => {
|
package/dist/cli/program.js
CHANGED
|
@@ -11,7 +11,7 @@ import { failureContext } from "../errors/reasons.js";
|
|
|
11
11
|
import { envName, readOnlyLockOf, readOnlyRefusal } from "../ports/app.js";
|
|
12
12
|
import { recorded, wasSettled } from "../runs/recording.js";
|
|
13
13
|
import { processRun, useAsProcessRun } from "../runs/scope.js";
|
|
14
|
-
import { keyForCommand } from "../sends/permissions.js";
|
|
14
|
+
import { AUTHORITY_KEY, keyForCommand } from "../sends/permissions.js";
|
|
15
15
|
import { logParsedArgv, logVersion } from "./argv-log.js";
|
|
16
16
|
import { commandPathOf } from "./command-contract.js";
|
|
17
17
|
import { outputFor, provide } from "./context.js";
|
|
@@ -254,6 +254,10 @@ const runOnce = async (argv, definition, options) => {
|
|
|
254
254
|
if (lock && changesAuthorityNow(action) && !flags.dryRun)
|
|
255
255
|
throw new CliError("permission_error", `this process is read-only (${lock}) — \`${command} ${path.join(" ")}\` changes what a later run may do; ` +
|
|
256
256
|
`run it without ${lock}`);
|
|
257
|
+
if (options.agent && options.agent.authority !== true && changesAuthorityNow(action))
|
|
258
|
+
throw new CliError("permission_error", `\`${command} ${path.join(" ")}\` changes what a later run may do, and this profile keeps that from agents ` +
|
|
259
|
+
`(${AUTHORITY_KEY}) — the owner turns it on in a terminal: ` +
|
|
260
|
+
`\`${command} <profile> config set${path[0] === "bot" ? " --bot" : ""} permissions.${AUTHORITY_KEY} allow\``, { permission: AUTHORITY_KEY, sent: false });
|
|
257
261
|
const { lifetime, cooperative: stopsAtItsPace } = metaOf(action);
|
|
258
262
|
const persistent = lifetime === "persistent";
|
|
259
263
|
listens = persistent;
|
package/dist/cli/runs/command.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
2
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
-
import { Command
|
|
3
|
+
import { Command } from "commander";
|
|
4
4
|
import { findRun, listRuns, readEvents, runsDirFor } from "../../runs/run.js";
|
|
5
5
|
import { environmentOf, outputFor } from "../context.js";
|
|
6
6
|
import { LOCAL_READ, NO_EFFECTS } from "../effects.js";
|
|
7
7
|
import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
8
|
+
import { typedQuery, withQuery } from "../list-query.js";
|
|
8
9
|
import { positiveCount } from "../paging.js";
|
|
9
10
|
import { lineOf } from "../steps.js";
|
|
10
|
-
import {
|
|
11
|
+
import { RUNS_QUERY, runListFilter } from "./query.js";
|
|
11
12
|
/** Reading the log is not itself worth recording, so **nothing here starts a run**. */
|
|
12
13
|
export const runsCommand = (app) => {
|
|
13
14
|
const command = new Command("runs").description("recorded runs — what this tool did, and when");
|
|
@@ -18,24 +19,35 @@ export const runsCommand = (app) => {
|
|
|
18
19
|
throw new CliError("not_found", `no recorded run "${id}" — \`${lineOf(from, "runs list")}\` shows them`);
|
|
19
20
|
return found;
|
|
20
21
|
};
|
|
21
|
-
annotate(command.command("list"), {
|
|
22
|
-
effects: LOCAL_READ,
|
|
22
|
+
withQuery(annotate(command.command("list"), {
|
|
23
23
|
examples: [`${app.command} runs list --limit 10`],
|
|
24
|
-
|
|
24
|
+
effects: LOCAL_READ,
|
|
25
|
+
}), RUNS_QUERY)
|
|
25
26
|
.description("recorded runs, newest first")
|
|
26
27
|
.option("--limit <n>", "how many to show", positiveCount("--limit"), 20)
|
|
27
28
|
.option("--page <n>", "which page, starting at 1", positiveCount("--page"), 1)
|
|
28
|
-
.action(function () {
|
|
29
|
+
.action(function (words) {
|
|
30
|
+
const filter = runListFilter(words);
|
|
29
31
|
const { limit, page } = this.opts();
|
|
30
32
|
const output = outputFor(this);
|
|
31
33
|
const { renderer } = output;
|
|
32
|
-
const runs = listRuns(dir(this), { atLeast: page * limit + 1 });
|
|
34
|
+
const runs = listRuns(dir(this), { atLeast: page * limit + 1, filter });
|
|
33
35
|
const shown = runs.slice((page - 1) * limit, page * limit);
|
|
34
|
-
renderAnswer(this, output, listOf("runs list", {
|
|
36
|
+
renderAnswer(this, output, listOf("runs list", {
|
|
37
|
+
items: shown.map(snakeKeys),
|
|
38
|
+
limit,
|
|
39
|
+
page,
|
|
40
|
+
has_more: runs.length > page * limit,
|
|
41
|
+
args: words.length ? { query: typedQuery(words) } : {},
|
|
42
|
+
}));
|
|
35
43
|
if (runs.length === 0)
|
|
36
44
|
renderer.note("nothing recorded — a run is kept with `--record`, or when it fails");
|
|
37
45
|
});
|
|
38
|
-
annotate(command.command("show"), {
|
|
46
|
+
annotate(command.command("show"), {
|
|
47
|
+
examples: [`${app.command} runs show run-101`],
|
|
48
|
+
effects: LOCAL_READ,
|
|
49
|
+
output: { entity: "run", view: "details" },
|
|
50
|
+
})
|
|
39
51
|
.argument("<run-id>", `an id from \`${app.command} runs list\``)
|
|
40
52
|
.description("one run: what it was, how it ended, and every event it logged")
|
|
41
53
|
.option("--problems", "only failed responses, warnings and crashes")
|
|
@@ -56,36 +68,11 @@ export const runsCommand = (app) => {
|
|
|
56
68
|
if (shown.length < events.length)
|
|
57
69
|
renderer.note(`${events.length - shown.length} other events — \`${lineOf(this, `runs show ${id}`)}\` shows them all`);
|
|
58
70
|
});
|
|
59
|
-
annotate(command.command("
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
annotate(command.command("path"), {
|
|
72
|
+
examples: [`${app.command} runs path run-101`],
|
|
73
|
+
effects: NO_EFFECTS,
|
|
74
|
+
output: { entity: "run_location" },
|
|
62
75
|
})
|
|
63
|
-
.description("search recorded diagnostic metadata and events; no message contents")
|
|
64
|
-
.argument("[query]", "case-insensitive literal diagnostic text")
|
|
65
|
-
.addOption(new Option("--status <status>", "run outcome").choices(["success", "failed", "partial", "running"]))
|
|
66
|
-
.option("--error-code <code>", "one stable error code")
|
|
67
|
-
.option("--operation <name>", "one operation, such as messages.download")
|
|
68
|
-
.option("--profile <name>", "one recorded profile")
|
|
69
|
-
.option("--since-time <time>", "runs starting on or after an ISO time or 2h / 1d ago")
|
|
70
|
-
.option("--limit <n>", "matches per page, at most 100", positiveCount("--limit"), 20)
|
|
71
|
-
.option("--page <n>", "result page", positiveCount("--page"), 1)
|
|
72
|
-
.action(function (query) {
|
|
73
|
-
const options = this.opts();
|
|
74
|
-
const found = searchRuns(dir(this), {
|
|
75
|
-
...options,
|
|
76
|
-
since: options.sinceTime,
|
|
77
|
-
...(query === undefined ? {} : { query }),
|
|
78
|
-
});
|
|
79
|
-
renderAnswer(this, outputFor(this), runsFound(found, {
|
|
80
|
-
query,
|
|
81
|
-
status: options.status,
|
|
82
|
-
error_code: options.errorCode,
|
|
83
|
-
operation: options.operation,
|
|
84
|
-
profile: options.profile,
|
|
85
|
-
since_time: options.sinceTime,
|
|
86
|
-
}));
|
|
87
|
-
});
|
|
88
|
-
annotate(command.command("path"), { effects: NO_EFFECTS, examples: [`${app.command} runs path run-101`] })
|
|
89
76
|
.argument("<run-id>", `an id from \`${app.command} runs list\``)
|
|
90
77
|
.description("the directory holding one run")
|
|
91
78
|
.action(function (id) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type QueryRegistry } from "@wirecat/cli-base/query";
|
|
2
|
+
import type { RunListFilter } from "../../runs/run.js";
|
|
3
|
+
import { type QueryWords } from "../list-query.js";
|
|
4
|
+
export declare const RUNS_QUERY: QueryRegistry;
|
|
5
|
+
export declare const runListFilter: (words: QueryWords) => RunListFilter;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { queryFieldsOf } from "@wirecat/cli-base/query";
|
|
2
|
+
import { recordedRun } from "../../entities/index.js";
|
|
3
|
+
import { queryTerms } from "../list-query.js";
|
|
4
|
+
export const RUNS_QUERY = {
|
|
5
|
+
entity: "run",
|
|
6
|
+
backend: "native",
|
|
7
|
+
fields: queryFieldsOf(recordedRun, {
|
|
8
|
+
native: ["run_id", "command", "profile", "status", "error_code"],
|
|
9
|
+
examples: {
|
|
10
|
+
command: 'command:"messages send"',
|
|
11
|
+
profile: "profile:work",
|
|
12
|
+
status: "status:failed",
|
|
13
|
+
error_code: "error_code:timeout",
|
|
14
|
+
},
|
|
15
|
+
}).map((field) => field.native
|
|
16
|
+
? {
|
|
17
|
+
...field,
|
|
18
|
+
operators: field.operators.filter((operator) => operator === "term" || operator === "phrase"),
|
|
19
|
+
}
|
|
20
|
+
: field),
|
|
21
|
+
};
|
|
22
|
+
export const runListFilter = (words) => {
|
|
23
|
+
const terms = queryTerms(words, RUNS_QUERY, "runs list");
|
|
24
|
+
const status = recordedRun.entries.status.options.find((value) => value === terms.get("status"));
|
|
25
|
+
return {
|
|
26
|
+
...(terms.has("run_id") ? { runId: terms.get("run_id") } : {}),
|
|
27
|
+
...(terms.has("command") ? { command: terms.get("command") } : {}),
|
|
28
|
+
...(terms.has("profile") ? { profile: terms.get("profile") } : {}),
|
|
29
|
+
...(status === undefined ? {} : { status }),
|
|
30
|
+
...(terms.has("error_code") ? { errorCode: terms.get("error_code") } : {}),
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { annotate } from "@wirecat/cli-base/commands";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { runsDirFor } from "../../runs/run.js";
|
|
4
|
+
import { environmentOf, outputFor } from "../context.js";
|
|
5
|
+
import { LOCAL_READ } from "../effects.js";
|
|
6
|
+
import { renderAnswer } from "../envelope.js";
|
|
7
|
+
import { typedQuery, withQuery } from "../list-query.js";
|
|
8
|
+
import { positiveCount } from "../paging.js";
|
|
9
|
+
import { runsFound, searchRuns } from "./search.js";
|
|
10
|
+
import { RUN_SEARCH_QUERY, runSearchFilter } from "./search-query.js";
|
|
11
|
+
/** Diagnostic files are independent of linked accounts and never start a recorded run themselves. */
|
|
12
|
+
export const runsSearchCommand = (app) => annotate(withQuery(new Command("runs")
|
|
13
|
+
.summary("search recorded diagnostic metadata and events")
|
|
14
|
+
.description("search recorded diagnostic metadata and events; literal words and field:value terms joined by AND; no message contents")
|
|
15
|
+
.option("--since-time <time>", "runs starting on or after an ISO time or 2h / 1d ago")
|
|
16
|
+
.option("--limit <n>", "matches per page, at most 100", positiveCount("--limit"), 20)
|
|
17
|
+
.option("--page <n>", "result page", positiveCount("--page"), 1), RUN_SEARCH_QUERY), {
|
|
18
|
+
effects: LOCAL_READ,
|
|
19
|
+
output: { entity: "run", view: "hit" },
|
|
20
|
+
examples: [`${app.command} search runs timeout status:failed --limit 10`],
|
|
21
|
+
}).action(function (words) {
|
|
22
|
+
const filter = runSearchFilter(words);
|
|
23
|
+
const options = this.opts();
|
|
24
|
+
const dir = runsDirFor(app, environmentOf(this).env ?? process.env);
|
|
25
|
+
const found = searchRuns(dir, { ...filter, ...options, since: options.sinceTime });
|
|
26
|
+
renderAnswer(this, outputFor(this), runsFound(found, { query: typedQuery(words), since_time: options.sinceTime }));
|
|
27
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type QueryWords } from "../list-query.js";
|
|
2
|
+
import type { RunSearch } from "./search.js";
|
|
3
|
+
export declare const RUN_SEARCH_QUERY: import("@wirecat/cli-base/query").QueryRegistry;
|
|
4
|
+
export declare const runSearchFilter: (words: QueryWords) => Pick<RunSearch, "terms" | "status" | "errorCode" | "operation" | "profile">;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { defineQuery, parseLucene, queryError, validateQuery } from "@wirecat/cli-base/query";
|
|
2
|
+
import { LIST_QUERY_GUIDE, termField, typedQuery } from "../list-query.js";
|
|
3
|
+
export const RUN_SEARCH_QUERY = defineQuery({
|
|
4
|
+
entity: "run",
|
|
5
|
+
backend: "native",
|
|
6
|
+
fields: [
|
|
7
|
+
termField("text", "kw", "text:timeout"),
|
|
8
|
+
termField("status", "enum", "status:failed", { values: ["success", "failed", "partial", "running"] }),
|
|
9
|
+
termField("error_code", "kw", "error_code:rate_limited"),
|
|
10
|
+
termField("operation", "kw", "operation:messages.download"),
|
|
11
|
+
termField("profile", "kw", "profile:work"),
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
export const runSearchFilter = (words) => {
|
|
15
|
+
const text = typedQuery(words).trim();
|
|
16
|
+
if (!text)
|
|
17
|
+
return {};
|
|
18
|
+
const context = { command: "search runs", guide: LIST_QUERY_GUIDE };
|
|
19
|
+
const ast = parseLucene(text, { defaultField: "text", ...context });
|
|
20
|
+
validateQuery(ast, RUN_SEARCH_QUERY, context);
|
|
21
|
+
const terms = [];
|
|
22
|
+
const fields = new Map();
|
|
23
|
+
const add = (node) => {
|
|
24
|
+
if (node.kind === "boolean") {
|
|
25
|
+
for (const clause of node.clauses) {
|
|
26
|
+
if (clause.occur !== "must")
|
|
27
|
+
queryError("query.unsupported-placement", clause.node.span, "run search takes terms joined by AND", context);
|
|
28
|
+
add(clause.node);
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (node.operator !== "term" && node.operator !== "phrase")
|
|
33
|
+
queryError("query.unsupported-placement", node.span, "run search takes literal words and field:value terms", context);
|
|
34
|
+
if (node.field === "text")
|
|
35
|
+
terms.push(node.value);
|
|
36
|
+
else {
|
|
37
|
+
if (fields.has(node.field))
|
|
38
|
+
queryError("query.unsupported-placement", node.span, `${node.field} only once here`, context);
|
|
39
|
+
fields.set(node.field, node.value);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
add(ast.root);
|
|
43
|
+
return {
|
|
44
|
+
...(terms.length ? { terms } : {}),
|
|
45
|
+
...(fields.has("status") ? { status: fields.get("status")?.toLowerCase() } : {}),
|
|
46
|
+
...(fields.has("error_code") ? { errorCode: fields.get("error_code") } : {}),
|
|
47
|
+
...(fields.has("operation") ? { operation: fields.get("operation") } : {}),
|
|
48
|
+
...(fields.has("profile") ? { profile: fields.get("profile") } : {}),
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export interface RunSearch {
|
|
2
2
|
query?: string;
|
|
3
|
+
terms?: readonly string[];
|
|
3
4
|
status?: "success" | "failed" | "partial" | "running";
|
|
4
5
|
errorCode?: string;
|
|
5
6
|
operation?: string;
|
|
@@ -8,7 +9,7 @@ export interface RunSearch {
|
|
|
8
9
|
limit?: number;
|
|
9
10
|
page?: number;
|
|
10
11
|
}
|
|
11
|
-
export declare const searchRuns: (dir: string, { query, status, errorCode, operation, profile, since, limit, page }?: RunSearch) => {
|
|
12
|
+
export declare const searchRuns: (dir: string, { query, terms, status, errorCode, operation, profile, since, limit, page }?: RunSearch) => {
|
|
12
13
|
items: {
|
|
13
14
|
runId: string;
|
|
14
15
|
command: string;
|
package/dist/cli/runs/search.js
CHANGED
|
@@ -32,14 +32,14 @@ const safeEvent = (event) => Object.fromEntries(FIELDS.flatMap((name) => {
|
|
|
32
32
|
}
|
|
33
33
|
return typeof value === "string" || typeof value === "number" ? [[name, value]] : [];
|
|
34
34
|
}));
|
|
35
|
-
export const searchRuns = (dir, { query = "", status, errorCode, operation, profile, since, limit = 20, page = 1 } = {}) => {
|
|
35
|
+
export const searchRuns = (dir, { query = "", terms = [], status, errorCode, operation, profile, since, limit = 20, page = 1 } = {}) => {
|
|
36
36
|
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100 || !Number.isSafeInteger(page) || page < 1)
|
|
37
37
|
throw new CliError("validation_error", "run search uses a limit from 1 to 100 and a positive page");
|
|
38
38
|
const window = dateWindow(since === undefined ? {} : { sinceTime: since });
|
|
39
39
|
const from = window.since;
|
|
40
40
|
if (from !== undefined && !Number.isFinite(from))
|
|
41
41
|
throw new CliError("validation_error", "--since-time must be a valid date or ISO timestamp");
|
|
42
|
-
const
|
|
42
|
+
const needles = [...(query ? [query] : []), ...terms].map((term) => term.toLowerCase());
|
|
43
43
|
const offset = (page - 1) * limit;
|
|
44
44
|
const matches = [];
|
|
45
45
|
for (const run of listRuns(dir, from === undefined ? {} : { since: from })) {
|
|
@@ -51,11 +51,11 @@ export const searchRuns = (dir, { query = "", status, errorCode, operation, prof
|
|
|
51
51
|
run.errorCode === errorCode ||
|
|
52
52
|
run.partial?.failures.some((failure) => failure.errorCode === errorCode)) &&
|
|
53
53
|
!operation &&
|
|
54
|
-
(
|
|
54
|
+
needles.every((needle) => JSON.stringify(run).toLowerCase().includes(needle));
|
|
55
55
|
// A finished run lists its operations and codes, so a run that cannot match is never opened.
|
|
56
56
|
// One still running, or killed, has no such list and is read.
|
|
57
57
|
const ruledOut = !metadataMatch &&
|
|
58
|
-
|
|
58
|
+
needles.length === 0 &&
|
|
59
59
|
((operation !== undefined && run.operations !== undefined && !run.operations.includes(operation)) ||
|
|
60
60
|
(errorCode !== undefined && run.codes !== undefined && !run.codes.includes(errorCode)));
|
|
61
61
|
if (ruledOut)
|
|
@@ -64,7 +64,7 @@ export const searchRuns = (dir, { query = "", status, errorCode, operation, prof
|
|
|
64
64
|
const events = found ? readEvents(found.dir).map(safeEvent) : [];
|
|
65
65
|
const filtered = events.filter((event) => (!errorCode || event.error_code === errorCode || event.code === errorCode) &&
|
|
66
66
|
(!operation || event.operation === operation) &&
|
|
67
|
-
(
|
|
67
|
+
needles.every((needle) => JSON.stringify(event).toLowerCase().includes(needle)));
|
|
68
68
|
if (!metadataMatch && filtered.length === 0)
|
|
69
69
|
continue;
|
|
70
70
|
const metadata = {
|
|
@@ -110,7 +110,7 @@ export const searchRuns = (dir, { query = "", status, errorCode, operation, prof
|
|
|
110
110
|
};
|
|
111
111
|
};
|
|
112
112
|
/** A page of `searchRuns` in the list envelope; `args` are the search's own, so `page.next` reruns it. */
|
|
113
|
-
export const runsFound = (found, args) => listOf("runs
|
|
113
|
+
export const runsFound = (found, args) => listOf("search runs", {
|
|
114
114
|
items: found.items.map(snakeKeys),
|
|
115
115
|
limit: found.limit,
|
|
116
116
|
has_more: found.hasMore,
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/** Attachments that are never a file, so their messages cost no download request. */
|
|
2
|
-
export const NOT_FILES = new Set([
|
|
2
|
+
export const NOT_FILES = new Set([
|
|
3
|
+
"webpage",
|
|
4
|
+
"share",
|
|
5
|
+
"poll",
|
|
6
|
+
"location",
|
|
7
|
+
"contact",
|
|
8
|
+
"control",
|
|
9
|
+
"inline_keyboard",
|
|
10
|
+
]);
|
|
3
11
|
/** The stored kinds `has:<kind>` matches: MAX stores a file as `file`, Telegram as `document`. */
|
|
4
12
|
export const storedKinds = (kind) => (kind === "file" ? ["file", "document"] : [kind]);
|
|
5
13
|
/**
|
|
@@ -33,11 +33,11 @@ export const rankingOptions = (target, input) => {
|
|
|
33
33
|
const { measure, score, weights: given, minMessages } = input;
|
|
34
34
|
const messageKind = input.messageKind ?? "all";
|
|
35
35
|
if (!["all", "posts", "comments"].includes(messageKind))
|
|
36
|
-
invalid("
|
|
36
|
+
invalid("message_kind takes all, posts or comments");
|
|
37
37
|
if (target === "messages" && minMessages !== undefined)
|
|
38
|
-
invalid("
|
|
38
|
+
invalid("min_messages applies to stats contacts top");
|
|
39
39
|
if (minMessages !== undefined && (!Number.isSafeInteger(minMessages) || minMessages < 1))
|
|
40
|
-
invalid("
|
|
40
|
+
invalid("min_messages takes a positive integer");
|
|
41
41
|
if (measure !== undefined && !measures.includes(measure))
|
|
42
42
|
invalid(`--measure takes ${measures.join(", ")}`);
|
|
43
43
|
if (measure !== undefined && (score !== undefined || given !== undefined))
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
export declare const accountChange: v.StrictObjectSchema<{
|
|
3
|
+
readonly operation_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
4
|
+
readonly account: Omit<v.StrictObjectSchema<{
|
|
5
|
+
readonly provider: v.StringSchema<undefined>;
|
|
6
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
7
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8
|
+
readonly username: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
9
|
+
readonly phone: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
10
|
+
readonly scope: v.OptionalSchema<v.PicklistSchema<["personal", "work"], undefined>, undefined>;
|
|
11
|
+
}, undefined>, "entries" | "~run" | "~standard" | "~types"> & {
|
|
12
|
+
readonly entries: Omit<{
|
|
13
|
+
readonly provider: v.StringSchema<undefined>;
|
|
14
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
15
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
16
|
+
readonly username: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
17
|
+
readonly phone: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
18
|
+
readonly scope: v.OptionalSchema<v.PicklistSchema<["personal", "work"], undefined>, undefined>;
|
|
19
|
+
}, "provider" | "scope">;
|
|
20
|
+
readonly "~standard": v.StandardProps<{
|
|
21
|
+
id: string;
|
|
22
|
+
name: string | null;
|
|
23
|
+
username: string | null;
|
|
24
|
+
phone?: string | null | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string | null;
|
|
28
|
+
username: string | null;
|
|
29
|
+
phone?: string | null | undefined;
|
|
30
|
+
}>;
|
|
31
|
+
readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
|
|
32
|
+
id: string;
|
|
33
|
+
name: string | null;
|
|
34
|
+
username: string | null;
|
|
35
|
+
phone?: string | null | undefined;
|
|
36
|
+
}, v.MinLengthIssue<string, 1> | v.StrictObjectIssue | v.StringIssue>;
|
|
37
|
+
readonly "~types"?: {
|
|
38
|
+
readonly input: {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string | null;
|
|
41
|
+
username: string | null;
|
|
42
|
+
phone?: string | null | undefined;
|
|
43
|
+
};
|
|
44
|
+
readonly output: {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string | null;
|
|
47
|
+
username: string | null;
|
|
48
|
+
phone?: string | null | undefined;
|
|
49
|
+
};
|
|
50
|
+
readonly issue: v.MinLengthIssue<string, 1> | v.StrictObjectIssue | v.StringIssue;
|
|
51
|
+
} | undefined;
|
|
52
|
+
};
|
|
53
|
+
}, undefined>;
|
|
54
|
+
export declare const endedAccountSessions: v.StrictObjectSchema<{
|
|
55
|
+
readonly operation_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
56
|
+
readonly sessions: v.ArraySchema<v.StrictObjectSchema<{
|
|
57
|
+
readonly current: v.BooleanSchema<undefined>;
|
|
58
|
+
readonly client: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
59
|
+
readonly device: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
60
|
+
readonly location: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
61
|
+
readonly last_active_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>;
|
|
62
|
+
readonly created_at: v.OptionalSchema<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>, undefined>;
|
|
63
|
+
}, undefined>, undefined>;
|
|
64
|
+
}, undefined>;
|
|
65
|
+
export declare const accountPrivacy: v.StrictObjectSchema<{
|
|
66
|
+
readonly find_by_phone: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
67
|
+
readonly phone_number: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
68
|
+
readonly calls: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
69
|
+
readonly chat_invites: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
70
|
+
readonly hide_online: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
71
|
+
readonly read_receipts: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
72
|
+
readonly profile_photo: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody", "contacts_except"], undefined>, undefined>;
|
|
73
|
+
readonly about: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody", "contacts_except"], undefined>, undefined>;
|
|
74
|
+
readonly last_seen: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody", "contacts_except"], undefined>, undefined>;
|
|
75
|
+
}, undefined>;
|
|
76
|
+
export declare const accountPrivacyChange: v.StrictObjectSchema<{
|
|
77
|
+
readonly operation_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
78
|
+
readonly privacy: v.StrictObjectSchema<{
|
|
79
|
+
readonly find_by_phone: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
80
|
+
readonly phone_number: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
81
|
+
readonly calls: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
82
|
+
readonly chat_invites: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody"], undefined>, undefined>;
|
|
83
|
+
readonly hide_online: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
84
|
+
readonly read_receipts: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
85
|
+
readonly profile_photo: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody", "contacts_except"], undefined>, undefined>;
|
|
86
|
+
readonly about: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody", "contacts_except"], undefined>, undefined>;
|
|
87
|
+
readonly last_seen: v.OptionalSchema<v.PicklistSchema<["everyone", "contacts", "nobody", "contacts_except"], undefined>, undefined>;
|
|
88
|
+
}, undefined>;
|
|
89
|
+
}, undefined>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { account } from "./account.js";
|
|
3
|
+
import { accountSession } from "./account-session.js";
|
|
4
|
+
import { id } from "./fields.js";
|
|
5
|
+
export const accountChange = v.strictObject({ operation_id: id, account: v.omit(account, ["provider", "scope"]) });
|
|
6
|
+
export const endedAccountSessions = v.strictObject({ operation_id: id, sessions: v.array(accountSession) });
|
|
7
|
+
const audience = v.picklist(["everyone", "contacts", "nobody"]);
|
|
8
|
+
const shownAudience = v.picklist(["everyone", "contacts", "nobody", "contacts_except"]);
|
|
9
|
+
export const accountPrivacy = v.strictObject({
|
|
10
|
+
find_by_phone: v.optional(audience),
|
|
11
|
+
phone_number: v.optional(audience),
|
|
12
|
+
calls: v.optional(audience),
|
|
13
|
+
chat_invites: v.optional(audience),
|
|
14
|
+
hide_online: v.optional(v.boolean()),
|
|
15
|
+
read_receipts: v.optional(v.boolean()),
|
|
16
|
+
profile_photo: v.optional(shownAudience),
|
|
17
|
+
about: v.optional(shownAudience),
|
|
18
|
+
last_seen: v.optional(shownAudience),
|
|
19
|
+
});
|
|
20
|
+
export const accountPrivacyChange = v.strictObject({ operation_id: id, privacy: accountPrivacy });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
export declare const accountProfile: v.StrictObjectSchema<{
|
|
3
|
+
readonly profile: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
4
|
+
readonly current: v.BooleanSchema<undefined>;
|
|
5
|
+
readonly account: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
6
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
7
|
+
}, undefined>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
export declare const analysisConsent: v.StrictObjectSchema<{
|
|
3
|
+
readonly chat: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
4
|
+
readonly provider: v.StringSchema<undefined>;
|
|
5
|
+
readonly at: 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`">]>;
|
|
6
|
+
}, undefined>;
|
|
7
|
+
export declare const analysisConsentRevocation: v.StrictObjectSchema<{
|
|
8
|
+
readonly revoked: v.BooleanSchema<undefined>;
|
|
9
|
+
}, undefined>;
|