@wirecat/cli-core 0.408.0 → 0.409.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 CHANGED
@@ -5,6 +5,16 @@ 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
+ ## 0.409.0 — 24.10.2026
9
+
10
+ ### Added
11
+
12
+ - **Shared lists declare typed queries, including bots, schedules, forum topics, calls and stickers.** Stored bot chats, recipients, send history,
13
+ profiles and schedules filter at their native readers; forum title terms go to the provider. Message predicates
14
+ require `--offline` and run in SQLite before the limit, reporting interpreted time bounds. Provider lists that
15
+ accept no filters refuse terms before connecting, instead of filtering an incomplete response. Existing empty
16
+ queries keep their previous behavior. Shared list-result contracts include the template schema for provider CLIs.
17
+
8
18
  ## 0.408.0 — 24.10.2026
9
19
 
10
20
  ### Fixed
@@ -75,7 +75,7 @@ export declare const scheduledRuns: (state: string) => {
75
75
  job: string;
76
76
  last: LastRun | undefined;
77
77
  }[];
78
- export declare const listSchedules: (state: string) => Schedule[];
78
+ export declare const listSchedules: (state: string, filter?: Partial<Pick<Schedule, "name" | "kind">>) => Schedule[];
79
79
  export declare const describeWhen: (when: When) => string;
80
80
  /** How one operating system starts `argv` at the schedule's times. Every timer runs the same thing: `<cli> schedule exec <file>`. */
81
81
  export interface Timer {
@@ -98,11 +98,13 @@ export const scheduledRuns = (state) => {
98
98
  return [];
99
99
  }
100
100
  };
101
- export const listSchedules = (state) => existsSync(schedulesDir(state))
101
+ export const listSchedules = (state, filter = {}) => existsSync(schedulesDir(state))
102
102
  ? readdirSync(schedulesDir(state))
103
103
  .map((name) => scheduleFile(state, name))
104
104
  .filter((file) => existsSync(file))
105
105
  .map(readSchedule)
106
+ .filter((schedule) => (filter.name === undefined || schedule.name === filter.name) &&
107
+ (filter.kind === undefined || schedule.kind === filter.kind))
106
108
  .sort((a, b) => a.name.localeCompare(b.name))
107
109
  : [];
108
110
  export const describeWhen = (when) => "every" in when
@@ -6,10 +6,12 @@ import { guardedWrite } from "../../sends/guarded.js";
6
6
  import { newOperationId } from "../../sends/send-id.js";
7
7
  import { REMOTE_READ, REMOTE_WRITE } from "../effects.js";
8
8
  import { renderAnswer, snakeKeys } from "../envelope.js";
9
+ import { listQuery, typedQuery, withQuery } from "../list-query.js";
9
10
  import { rightsOf } from "../messenger/admin-commands.js";
10
11
  import { renderItem, wholeList } from "../messenger/chat-answers.js";
11
12
  import { botContext, online } from "./context.js";
12
13
  import { botExamples } from "./examples.js";
14
+ import { BOT_ADMINS_QUERY } from "./list-queries.js";
13
15
  import { botCan } from "./messages.js";
14
16
  const CHAT = "a chat id, or the title of a chat this bot has seen";
15
17
  const PERSON = "the person's user id";
@@ -24,10 +26,10 @@ const personOf = (typed) => {
24
26
  export const botAdminsCommand = (bot) => {
25
27
  const offered = bot.adminRights ?? ADMIN_RIGHTS;
26
28
  const command = new Command("admins").description("the admins of a chat the bot is an admin in");
27
- annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "chats admins list Team") })
29
+ withQuery(annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "chats admins list Team") })
28
30
  .description("the chat's admins and what each may do")
29
- .argument("<chat>", CHAT)
30
- .action(async function (chat) {
31
+ .argument("<chat>", CHAT), BOT_ADMINS_QUERY).action(async function (chat, words) {
32
+ listQuery(typedQuery(words), BOT_ADMINS_QUERY, "bot chats admins list");
31
33
  const context = online(botContext(this, bot), this);
32
34
  const ref = context.chatRef(chat);
33
35
  await context.run(async (events) => {
@@ -6,10 +6,14 @@ import { guardedWrite } from "../../sends/guarded.js";
6
6
  import { newOperationId } from "../../sends/send-id.js";
7
7
  import { grantsAuthority, LOCAL_READ, LOCAL_WRITE, REMOTE_READ, REMOTE_WRITE } from "../effects.js";
8
8
  import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
9
+ import { withQuery } from "../list-query.js";
9
10
  import { renderItem, wholeList } from "../messenger/chat-answers.js";
11
+ import { RECIPIENTS_QUERY, recipientFilter } from "../messenger/recipients-query.js";
12
+ import { SENDS_QUERY, sendFilter } from "../messenger/sends-query.js";
10
13
  import { botAdminsCommand, botMembersCommand } from "./admins.js";
11
14
  import { botContext, online } from "./context.js";
12
15
  import { botExamples } from "./examples.js";
16
+ import { BOT_CHATS_QUERY, BOT_PROFILES_QUERY, botChatFilter, botProfileName } from "./list-queries.js";
13
17
  import { botMcpCommand } from "./mcp.js";
14
18
  import { botCan, botIdOf, botMessagesCommand } from "./messages.js";
15
19
  import { botModerateCommand, botRulesCommand } from "./moderation.js";
@@ -114,11 +118,12 @@ const meCommand = (bot) => annotate(new Command("me"), { effects: REMOTE_READ, e
114
118
  }
115
119
  });
116
120
  });
117
- const listCommand = (bot, tokenVariable) => annotate(new Command("list"), { effects: LOCAL_READ, examples: botExamples(bot, "list", "list --check") })
121
+ const listCommand = (bot, tokenVariable) => withQuery(annotate(new Command("list"), { effects: LOCAL_READ, examples: botExamples(bot, "list", "list --check") }), BOT_PROFILES_QUERY)
118
122
  .description(`every name on this machine that has a bot token; --check asks ${bot.name ?? "the messenger"} which bot each is`)
119
123
  .summary("every bot profile on this machine; --check asks which bot each is")
120
124
  .option("--check", "ask the messenger who each bot is, with its token")
121
- .action(async function () {
125
+ .action(async function (words) {
126
+ const wanted = botProfileName(words);
122
127
  const context = botContext(this, bot);
123
128
  const check = this.opts().check === true;
124
129
  if (check)
@@ -132,6 +137,8 @@ const listCommand = (bot, tokenVariable) => annotate(new Command("list"), { effe
132
137
  }
133
138
  const rows = [];
134
139
  for (const name of names) {
140
+ if (wanted !== undefined && name !== wanted)
141
+ continue;
135
142
  const tokens = bot.tokenStore?.(this, name) ??
136
143
  new BotTokenStore({
137
144
  app: bot.app,
@@ -161,11 +168,12 @@ const recipientsCommand = (bot) => {
161
168
  const command = new Command("recipients")
162
169
  .description("the chats this bot may write to; with no list, every chat — `clear` removes the list")
163
170
  .summary("the chats this bot may write to; with no list, every chat");
164
- annotate(command.command("list"), { effects: LOCAL_READ, examples: botExamples(bot, "recipients list") })
171
+ withQuery(annotate(command.command("list"), { effects: LOCAL_READ, examples: botExamples(bot, "recipients list") }), RECIPIENTS_QUERY)
165
172
  .description("the chats on the list, or nothing when there is no list")
166
- .action(async function () {
173
+ .action(async function (words) {
174
+ const filter = recipientFilter(words, "bot recipients list");
167
175
  const context = botContext(this, bot);
168
- await context.run(async () => renderAnswer(this, context, wholeList("bot recipients list", (context.recipients().read() ?? []).map(snakeKeys))));
176
+ await context.run(async () => renderAnswer(this, context, wholeList("bot recipients list", context.recipients().list(filter).items.map(snakeKeys))));
169
177
  });
170
178
  grantsAuthority(annotate(command.command("add"), {
171
179
  effects: LOCAL_WRITE,
@@ -203,21 +211,23 @@ const recipientsCommand = (bot) => {
203
211
  const sendsCommand = (bot) => new Command("sends")
204
212
  .description("what this bot sent, edited and deleted from this machine — ids and outcomes, never text")
205
213
  .summary("what this bot sent, edited and deleted from here — never the text")
206
- .addCommand(annotate(new Command("list"), { effects: LOCAL_READ, examples: botExamples(bot, "sends list") })
214
+ .addCommand(withQuery(annotate(new Command("list"), { effects: LOCAL_READ, examples: botExamples(bot, "sends list") }), SENDS_QUERY)
207
215
  .description("every send, edit and delete this bot made from this machine, with its outcome")
208
- .action(async function () {
216
+ .action(async function (words) {
217
+ const filter = sendFilter(words, "bot sends list");
209
218
  const context = botContext(this, bot);
210
- await context.run(async () => renderAnswer(this, context, wholeList("bot sends list", context.journal().entries().map(snakeKeys))));
219
+ await context.run(async () => renderAnswer(this, context, wholeList("bot sends list", context.journal().entries(filter).map(snakeKeys))));
211
220
  }));
212
221
  const chatsCommand = (bot) => {
213
222
  const command = new Command("chats")
214
223
  .description(`the chats this bot is in — ${bot.name ?? "the messenger"} gives a bot no list of them, so \`list\` shows the ones it has seen`)
215
224
  .summary("the chats this bot is in, and what it does there");
216
- annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "chats list") })
225
+ withQuery(annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "chats list") }), BOT_CHATS_QUERY)
217
226
  .description(`chats this bot has seen on this machine — not a complete list from ${bot.name ?? "the messenger"}`)
218
- .action(async function () {
227
+ .action(async function (words) {
228
+ const filter = botChatFilter(words);
219
229
  const context = botContext(this, bot);
220
- await context.run(async () => renderAnswer(this, context, wholeList("bot chats list", context.registry.list().map(snakeKeys))));
230
+ await context.run(async () => renderAnswer(this, context, wholeList("bot chats list", context.registry.list(filter).map(snakeKeys))));
221
231
  });
222
232
  annotate(command.command("show"), { effects: REMOTE_READ, examples: botExamples(bot, "chats show Team") })
223
233
  .description(`one chat from ${bot.name ?? "the messenger"}, and remember it`)
@@ -0,0 +1,27 @@
1
+ import { type QueryRegistry } from "@wirecat/cli-base/query";
2
+ import { type QueryWords } from "../list-query.js";
3
+ import type { SeenChat } from "./registry.js";
4
+ export declare const BOT_PROFILES_QUERY: QueryRegistry;
5
+ export declare const botProfileName: (words: QueryWords) => string | undefined;
6
+ export declare const BOT_CHATS_QUERY: QueryRegistry;
7
+ export declare const botChatFilter: (words: QueryWords) => Partial<Pick<SeenChat, "id" | "title" | "kind">>;
8
+ export declare const BOT_MESSAGES_QUERY: QueryRegistry;
9
+ export declare const botMessageWindow: (words: QueryWords) => {
10
+ window: {
11
+ before?: string | undefined;
12
+ since?: string | undefined;
13
+ threadId?: string | undefined;
14
+ outgoing?: boolean | undefined;
15
+ starred?: boolean | undefined;
16
+ };
17
+ meta: {
18
+ timezone: string;
19
+ window: {
20
+ since?: string;
21
+ until?: string;
22
+ };
23
+ } | undefined;
24
+ };
25
+ export declare const BOT_ADMINS_QUERY: QueryRegistry;
26
+ export declare const BOT_MENU_QUERY: QueryRegistry;
27
+ export declare const BOT_WEBHOOKS_QUERY: QueryRegistry;
@@ -0,0 +1,83 @@
1
+ import { queryError, queryFieldsOf } from "@wirecat/cli-base/query";
2
+ import { botAdmin, botMenuEntry, botProfile, botSeenChat, botWebhook, message } from "../../entities/index.js";
3
+ import { listQuery, nativeTerms, queryTerms, timeBounds, typedQuery, unfilteredQuery, } from "../list-query.js";
4
+ const termsOnly = (registry) => ({
5
+ ...registry,
6
+ fields: registry.fields.map((field) => field.native
7
+ ? {
8
+ ...field,
9
+ operators: field.operators.filter((operator) => operator === "term" || operator === "phrase"),
10
+ }
11
+ : field),
12
+ });
13
+ export const BOT_PROFILES_QUERY = termsOnly({
14
+ entity: "bot_profile",
15
+ backend: "native",
16
+ fields: queryFieldsOf(botProfile, { native: ["name"], examples: { name: "name:sales" } }),
17
+ });
18
+ export const botProfileName = (words) => queryTerms(words, BOT_PROFILES_QUERY, "bot list").get("name");
19
+ export const BOT_CHATS_QUERY = termsOnly({
20
+ entity: "bot_seen_chat",
21
+ backend: "native",
22
+ fields: queryFieldsOf(botSeenChat, {
23
+ native: ["id", "title", "kind"],
24
+ examples: { id: "id:7", title: 'title:"Book club"', kind: "kind:group" },
25
+ }),
26
+ });
27
+ export const botChatFilter = (words) => {
28
+ const terms = queryTerms(words, BOT_CHATS_QUERY, "bot chats list");
29
+ const id = terms.get("id"), title = terms.get("title");
30
+ const kind = botSeenChat.entries.kind.wrapped.options.find((value) => value === terms.get("kind"));
31
+ return {
32
+ ...(id === undefined ? {} : { id }),
33
+ ...(title === undefined ? {} : { title }),
34
+ ...(kind === undefined ? {} : { kind }),
35
+ };
36
+ };
37
+ export const BOT_MESSAGES_QUERY = {
38
+ entity: "message",
39
+ backend: "native",
40
+ fields: queryFieldsOf(message, {
41
+ native: ["id", "timestamp", "thread_id", "outgoing", "starred"],
42
+ examples: {
43
+ id: "id<42",
44
+ timestamp: "timestamp>2026-10-01",
45
+ thread_id: "thread_id:12",
46
+ outgoing: "outgoing:false",
47
+ starred: "starred:true",
48
+ },
49
+ }).map((field) => {
50
+ if (field.name === "id" || field.name === "timestamp")
51
+ return { ...field, operators: ["range"] };
52
+ return field.native ? { ...field, operators: ["term"] } : field;
53
+ }),
54
+ };
55
+ export const botMessageWindow = (words) => {
56
+ const command = "bot messages list";
57
+ const terms = nativeTerms(listQuery(typedQuery(words), BOT_MESSAGES_QUERY, command), command);
58
+ const id = terms.get("id");
59
+ if (id && (id.value !== "*" || !id.upper || id.upper === "*" || id.upper_inclusive !== false))
60
+ queryError("query.unsupported-operator", id.span, "id takes an exclusive upper bound here: id<42", { command });
61
+ const timestamp = terms.get("timestamp");
62
+ const bounds = timeBounds(timestamp);
63
+ if (timestamp && (bounds.since === undefined || bounds.until !== undefined))
64
+ queryError("query.unsupported-operator", timestamp.span, "timestamp takes a lower bound here: timestamp>7d", {
65
+ command,
66
+ });
67
+ const topic = terms.get("thread_id")?.value;
68
+ const outgoing = terms.get("outgoing")?.value.toLowerCase();
69
+ const starred = terms.get("starred")?.value.toLowerCase();
70
+ return {
71
+ window: {
72
+ ...(id?.upper === undefined ? {} : { before: id.upper }),
73
+ ...(bounds.since === undefined ? {} : { since: new Date(bounds.since).toISOString() }),
74
+ ...(topic === undefined ? {} : { threadId: topic }),
75
+ ...(outgoing === undefined ? {} : { outgoing: outgoing === "true" }),
76
+ ...(starred === undefined ? {} : { starred: starred === "true" }),
77
+ },
78
+ meta: bounds.meta,
79
+ };
80
+ };
81
+ export const BOT_ADMINS_QUERY = unfilteredQuery("bot_admin", botAdmin);
82
+ export const BOT_MENU_QUERY = unfilteredQuery("bot_menu_entry", botMenuEntry);
83
+ export const BOT_WEBHOOKS_QUERY = unfilteredQuery("bot_webhook", botWebhook);
@@ -9,12 +9,14 @@ import { readAttachments } from "../../sends/upload.js";
9
9
  import { environmentOf } from "../context.js";
10
10
  import { ownerOnlyOption, REMOTE_READ, REMOTE_WRITE } from "../effects.js";
11
11
  import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
12
+ import { typedQuery, withQuery } from "../list-query.js";
12
13
  import { wholeList } from "../messenger/chat-answers.js";
13
14
  import { messageItem } from "../messenger/message-items.js";
14
15
  import { readAll } from "../messenger/stdin.js";
15
16
  import { positiveCount } from "../paging.js";
16
17
  import { botContext } from "./context.js";
17
18
  import { botExamples } from "./examples.js";
19
+ import { BOT_MESSAGES_QUERY, botMessageWindow } from "./list-queries.js";
18
20
  /** The adapter's `method`, or a refusal naming what this messenger's bot cannot do. */
19
21
  export const botCan = (adapter, method, bot, what) => {
20
22
  const found = adapter[method];
@@ -32,10 +34,10 @@ export const botIdOf = async (context, adapter) => {
32
34
  context.registry.rememberBot(id);
33
35
  return id;
34
36
  };
35
- const show = (command, context, bot, botId, messages, one = false) => {
37
+ const show = (command, context, bot, botId, messages, one = false, meta) => {
36
38
  const reader = context.copy.accountOf(botId);
37
39
  const items = messages.map((message) => messageItem(message, reader));
38
- renderAnswer(command, context, one && items[0] ? itemOf(items[0]) : wholeList("bot messages list", items), () => renderMessages(messages, {
40
+ renderAnswer(command, context, one && items[0] ? itemOf(items[0]) : { ...wholeList("bot messages list", items), ...(meta ? { meta } : {}) }, () => renderMessages(messages, {
39
41
  color: context.color,
40
42
  verbosity: context.settings.detail,
41
43
  senderColors: context.settings.senderColors,
@@ -124,33 +126,37 @@ const sendCommand = (bot) => annotate(new Command("send"), {
124
126
  renderAnswer(this, context, written(context, botId, { operationId }, message));
125
127
  });
126
128
  });
127
- const listCommand = (bot) => annotate(new Command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "messages list Team --limit 20") })
129
+ const listCommand = (bot) => withQuery(annotate(new Command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "messages list Team --limit 20") })
128
130
  .description(`the latest messages in a chat; where ${bot.name ?? "the messenger"} gives a bot no history, and with --offline, ` +
129
131
  "the ones this bot has seen on this machine")
130
132
  .summary("the latest messages in a chat")
131
- .argument("<chat>", "a chat id, user:<id> for a person, or the title of a chat this bot has seen")
133
+ .argument("<chat>", "a chat id, user:<id> for a person, or the title of a chat this bot has seen"), BOT_MESSAGES_QUERY)
134
+ .addHelpText("after", "\nQueries filter the stored copy before limiting results; add --offline. The Bot API does not accept these filters.")
132
135
  .option("--limit <n>", "how many, the newest", positiveCount("--limit"))
133
- .action(async function (chat) {
136
+ .action(async function (chat, words) {
137
+ const narrowed = botMessageWindow(words);
134
138
  const context = botContext(this, bot);
139
+ if (typedQuery(words).trim() && !context.settings.offline)
140
+ throw new CliError("validation_error", "bot message queries filter the local copy; add --offline");
135
141
  const ref = context.chatRef(chat);
136
142
  const limit = this.opts().limit ?? context.settings.limit;
137
143
  await context.run(async (events) => {
138
144
  const fromCopy = async (botId) => {
139
- const page = await context.copy.read((store) => store.messages.messages(context.copy.accountOf(botId), ref, { limit }));
145
+ const page = await context.copy.read((store) => store.messages.messages(context.copy.accountOf(botId), ref, { limit, ...narrowed.window }));
140
146
  return page.items;
141
147
  };
142
148
  if (context.settings.offline) {
143
149
  const botId = context.registry.botId();
144
150
  if (!botId)
145
151
  throw nothingKept(context);
146
- show(this, context, bot, botId, await fromCopy(botId));
152
+ show(this, context, bot, botId, await fromCopy(botId), false, narrowed.meta);
147
153
  return;
148
154
  }
149
155
  const adapter = await context.authenticated({ events });
150
156
  const botId = await botIdOf(context, adapter);
151
157
  if (!adapter.history) {
152
158
  context.renderer.note(`${bot.name ?? "the messenger"} gives a bot no history: these are the messages it kept`);
153
- show(this, context, bot, botId, await fromCopy(botId));
159
+ show(this, context, bot, botId, await fromCopy(botId), false, narrowed.meta);
154
160
  return;
155
161
  }
156
162
  const messages = await adapter.history(ref, { limit });
@@ -24,7 +24,7 @@ export declare const botFiles: (app: AppIdentity, profile: string, env?: NodeJS.
24
24
  export declare class ChatRegistry {
25
25
  #private;
26
26
  constructor(app: AppIdentity, profile: string, env?: NodeJS.ProcessEnv);
27
- list(): SeenChat[];
27
+ list(filter?: Partial<Pick<SeenChat, "id" | "title" | "kind">>): SeenChat[];
28
28
  /** The bot's own user id, once any command has learned it — the key its messages are stored under. */
29
29
  botId(): string | undefined;
30
30
  rememberBot(id: string): void;
@@ -26,9 +26,11 @@ export class ChatRegistry {
26
26
  constructor(app, profile, env = process.env) {
27
27
  this.#path = botFiles(app, profile, env).registry;
28
28
  }
29
- list() {
29
+ list(filter = {}) {
30
30
  const { chats } = this.#read();
31
- return Array.isArray(chats) ? chats : [];
31
+ return (Array.isArray(chats) ? chats : []).filter((chat) => (filter.id === undefined || chat.id === filter.id) &&
32
+ (filter.kind === undefined || chat.kind === filter.kind) &&
33
+ (filter.title === undefined || chat.title?.toLocaleLowerCase() === filter.title?.toLocaleLowerCase()));
32
34
  }
33
35
  /** The bot's own user id, once any command has learned it — the key its messages are stored under. */
34
36
  botId() {
@@ -5,9 +5,11 @@ import { guardedWrite } from "../../sends/guarded.js";
5
5
  import { newOperationId } from "../../sends/send-id.js";
6
6
  import { REMOTE_READ, REMOTE_WRITE } from "../effects.js";
7
7
  import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
8
+ import { listQuery, typedQuery, withQuery } from "../list-query.js";
8
9
  import { wholeList } from "../messenger/chat-answers.js";
9
10
  import { botContext, online } from "./context.js";
10
11
  import { botExamples } from "./examples.js";
12
+ import { BOT_MENU_QUERY, BOT_WEBHOOKS_QUERY } from "./list-queries.js";
11
13
  import { botCan } from "./messages.js";
12
14
  import { botFiles } from "./registry.js";
13
15
  import { PressLog } from "./updates.js";
@@ -31,9 +33,10 @@ const botWrite = (context, key, write) => guardedWrite(context.guard(), { operat
31
33
  /** `bot commands`: the menu people see when they type `/`. */
32
34
  export const botMenuCommand = (bot) => {
33
35
  const command = new Command("commands").description("the bot's command menu — what people see after /");
34
- annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "commands list") })
36
+ withQuery(annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "commands list") }), BOT_MENU_QUERY)
35
37
  .description("the commands in the menu now")
36
- .action(async function () {
38
+ .action(async function (words) {
39
+ listQuery(typedQuery(words), BOT_MENU_QUERY, "bot commands list");
37
40
  const context = online(botContext(this, bot), this);
38
41
  await context.run(async (events) => {
39
42
  const adapter = await context.authenticated({ events });
@@ -111,9 +114,10 @@ export const botWebhooksCommand = (bot) => {
111
114
  const command = new Command("webhooks")
112
115
  .description("where the messenger pushes this bot's updates — while one is set, `bot watch` gets nothing")
113
116
  .summary("where the messenger pushes this bot's updates");
114
- annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "webhooks list") })
117
+ withQuery(annotate(command.command("list"), { effects: REMOTE_READ, examples: botExamples(bot, "webhooks list") }), BOT_WEBHOOKS_QUERY)
115
118
  .description("the webhooks this bot has")
116
- .action(async function () {
119
+ .action(async function (words) {
120
+ listQuery(typedQuery(words), BOT_WEBHOOKS_QUERY, "bot webhooks list");
117
121
  const context = online(botContext(this, bot), this);
118
122
  await context.run(async (events) => {
119
123
  const adapter = await context.authenticated({ events });
@@ -1,5 +1,6 @@
1
1
  export { AI_ENTRIES, AI_SETTING_KEYS, type AISettings, resolveAISettings } from "../analysis/settings.js";
2
2
  export { parseDuration } from "../domain/duration.js";
3
+ export { botTemplate } from "../entities/list-results.js";
3
4
  export { syncProgress } from "../entities/store-records.js";
4
5
  export { isCliFailure, isCommanderFailure } from "../errors/failures.js";
5
6
  export { type AppErrors, failureContext } from "../errors/reasons.js";
package/dist/cli/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { AI_ENTRIES, AI_SETTING_KEYS, resolveAISettings } from "../analysis/settings.js";
2
2
  export { parseDuration } from "../domain/duration.js";
3
+ export { botTemplate } from "../entities/list-results.js";
3
4
  export { syncProgress } from "../entities/store-records.js";
4
5
  export { isCliFailure, isCommanderFailure } from "../errors/failures.js";
5
6
  export { failureContext } from "../errors/reasons.js";
@@ -0,0 +1,9 @@
1
+ import { type QueryRegistry } from "@wirecat/cli-base/query";
2
+ import type { Schedule } from "../../background/schedules.js";
3
+ import { type QueryWords } from "../list-query.js";
4
+ export declare const SCHEDULES_QUERY: QueryRegistry;
5
+ export declare const scheduleFilter: (words: QueryWords) => Partial<Pick<Schedule, "name" | "kind">>;
6
+ export declare const TOPICS_QUERY: QueryRegistry;
7
+ export declare const topicTitle: (words: QueryWords) => string | undefined;
8
+ export declare const CALLS_QUERY: QueryRegistry;
9
+ export declare const STICKERS_QUERY: QueryRegistry;
@@ -0,0 +1,30 @@
1
+ import { queryFieldsOf } from "@wirecat/cli-base/query";
2
+ import { callRecord, scheduledJob, stickerInventory, topic } from "../../entities/index.js";
3
+ import { queryTerms, unfilteredQuery } from "../list-query.js";
4
+ const termsOnly = (registry) => ({
5
+ ...registry,
6
+ fields: registry.fields.map((field) => field.native
7
+ ? { ...field, operators: field.operators.filter((operator) => operator === "term" || operator === "phrase") }
8
+ : field),
9
+ });
10
+ export const SCHEDULES_QUERY = termsOnly({
11
+ entity: "scheduled_job",
12
+ backend: "native",
13
+ fields: queryFieldsOf(scheduledJob, {
14
+ native: ["name", "kind"],
15
+ examples: { name: "name:daily", kind: "kind:command" },
16
+ }),
17
+ });
18
+ export const scheduleFilter = (words) => {
19
+ const terms = queryTerms(words, SCHEDULES_QUERY, "schedule list");
20
+ const name = terms.get("name"), kind = terms.get("kind");
21
+ return { ...(name === undefined ? {} : { name }), ...(kind === "agent" || kind === "command" ? { kind } : {}) };
22
+ };
23
+ export const TOPICS_QUERY = termsOnly({
24
+ entity: "topic",
25
+ backend: "native",
26
+ fields: queryFieldsOf(topic, { native: ["title"], examples: { title: 'title:"Book club"' } }),
27
+ });
28
+ export const topicTitle = (words) => queryTerms(words, TOPICS_QUERY, "topics list").get("title");
29
+ export const CALLS_QUERY = unfilteredQuery("call_record", callRecord);
30
+ export const STICKERS_QUERY = unfilteredQuery("sticker_inventory", stickerInventory);
@@ -2,4 +2,4 @@ import { type QueryRegistry } from "@wirecat/cli-base/query";
2
2
  import type { RecipientFilter } from "../../sends/recipients.js";
3
3
  import { type QueryWords } from "../list-query.js";
4
4
  export declare const RECIPIENTS_QUERY: QueryRegistry;
5
- export declare const recipientFilter: (words: QueryWords) => RecipientFilter;
5
+ export declare const recipientFilter: (words: QueryWords, command?: string) => RecipientFilter;
@@ -11,8 +11,8 @@ export const RECIPIENTS_QUERY = {
11
11
  ? { ...field, operators: field.operators.filter((operator) => operator === "term" || operator === "phrase") }
12
12
  : field),
13
13
  };
14
- export const recipientFilter = (words) => {
15
- const terms = queryTerms(words, RECIPIENTS_QUERY, "recipients list");
14
+ export const recipientFilter = (words, command = "recipients list") => {
15
+ const terms = queryTerms(words, RECIPIENTS_QUERY, command);
16
16
  const id = terms.get("id"), title = terms.get("title");
17
17
  return { ...(id === undefined ? {} : { id }), ...(title === undefined ? {} : { title }) };
18
18
  };
@@ -6,8 +6,10 @@ import { sendTime } from "../../domain/send-time.js";
6
6
  import { capability } from "../../ports/messenger.js";
7
7
  import { ownerOnlyOption, REMOTE_READ, REMOTE_WRITE } from "../effects.js";
8
8
  import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
9
+ import { listQuery, typedQuery, withQuery } from "../list-query.js";
9
10
  import { positiveCount } from "../paging.js";
10
11
  import { messengerContext } from "./context.js";
12
+ import { CALLS_QUERY, STICKERS_QUERY } from "./list-result-queries.js";
11
13
  const kindsOf = (typed) => {
12
14
  const kinds = typed === undefined ? [...MEDIA_KINDS] : typed.split(",").map((kind) => kind.trim());
13
15
  for (const kind of kinds) {
@@ -49,10 +51,14 @@ export const mediaCommand = (messenger) => annotate(new Command("media"), { effe
49
51
  /** `stickers list` — the sets the account added, or one set's stickers with the ids `messages send --sticker` takes. */
50
52
  export const stickersCommand = (messenger) => {
51
53
  const stickers = new Command("stickers").description("the stickers the account has added");
52
- annotate(stickers.command("list"), { effects: REMOTE_READ })
54
+ withQuery(annotate(stickers.command("list"), {
55
+ effects: REMOTE_READ,
56
+ examples: [`${messenger.app.command} personal stickers list`],
57
+ }), STICKERS_QUERY)
53
58
  .description("sticker sets, or with --set the stickers in one; reading changes nothing")
54
59
  .option("--set <id>", "the stickers in this set")
55
- .action(async function () {
60
+ .action(async function (words) {
61
+ listQuery(typedQuery(words), STICKERS_QUERY, "stickers list");
56
62
  const context = messengerContext(this, messenger);
57
63
  const { set } = this.opts();
58
64
  const items = await context.withMessenger((adapter) => set === undefined
@@ -69,10 +75,14 @@ export const stickersCommand = (messenger) => {
69
75
  /** `calls list` — the account's call history, newest first. */
70
76
  export const callsCommand = (messenger) => {
71
77
  const calls = new Command("calls").description("the account's calls");
72
- annotate(calls.command("list"), { effects: REMOTE_READ })
78
+ withQuery(annotate(calls.command("list"), {
79
+ effects: REMOTE_READ,
80
+ examples: [`${messenger.app.command} personal calls list`],
81
+ }), CALLS_QUERY)
73
82
  .description("calls made and received, newest first; reading changes nothing")
74
83
  .option("--limit <n>", "how many to show", positiveCount("--limit"))
75
- .action(async function () {
84
+ .action(async function (words) {
85
+ listQuery(typedQuery(words), CALLS_QUERY, "calls list");
76
86
  const context = messengerContext(this, messenger);
77
87
  const limit = context.settings.limit;
78
88
  const page = await context.withMessenger((adapter) => capability(adapter, "calls", "list calls")({ limit }));
@@ -13,8 +13,10 @@ import { storePath } from "../../store/path.js";
13
13
  import { environmentOf, setExitCode } from "../context.js";
14
14
  import { grantsAuthority, LOCAL_READ, LOCAL_WRITE, REMOTE_WRITE } from "../effects.js";
15
15
  import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
16
+ import { withQuery } from "../list-query.js";
16
17
  import { lineOf } from "../steps.js";
17
18
  import { messengerContext } from "./context.js";
19
+ import { SCHEDULES_QUERY, scheduleFilter } from "./list-result-queries.js";
18
20
  /** Each run of an agent is a paid model call that reads chats; keeping the store current is `serve`'s job. */
19
21
  const AGENT_MINIMUM_MINUTES = 60;
20
22
  const COMMAND_MINIMUM_MINUTES = 1;
@@ -156,11 +158,12 @@ export const scheduleCommand = (messenger) => {
156
158
  createdAt: new Date().toISOString(),
157
159
  });
158
160
  });
159
- annotate(command.command("list"), { effects: LOCAL_READ })
161
+ withQuery(annotate(command.command("list"), { effects: LOCAL_READ }), SCHEDULES_QUERY)
160
162
  .description("the schedules, when they run and how their last run went")
161
- .action(function () {
163
+ .action(function (words) {
164
+ const filter = scheduleFilter(words);
162
165
  const { context, state } = prepare(this);
163
- const rows = listSchedules(state).map((schedule) => ({
166
+ const rows = listSchedules(state, filter).map((schedule) => ({
164
167
  name: schedule.name,
165
168
  kind: schedule.kind,
166
169
  when: describeWhen(schedule.when),
@@ -2,4 +2,4 @@ import { type QueryRegistry } from "@wirecat/cli-base/query";
2
2
  import type { SendFilter } from "../../sends/journal.js";
3
3
  import { type QueryWords } from "../list-query.js";
4
4
  export declare const SENDS_QUERY: QueryRegistry;
5
- export declare const sendFilter: (words: QueryWords) => SendFilter | undefined;
5
+ export declare const sendFilter: (words: QueryWords, command?: string) => SendFilter | undefined;
@@ -17,8 +17,8 @@ export const SENDS_QUERY = {
17
17
  ? { ...field, operators: field.operators.filter((operator) => operator === "term" || operator === "phrase") }
18
18
  : field),
19
19
  };
20
- export const sendFilter = (words) => {
21
- const terms = queryTerms(words, SENDS_QUERY, "sends list");
20
+ export const sendFilter = (words, command = "sends list") => {
21
+ const terms = queryTerms(words, SENDS_QUERY, command);
22
22
  if (terms.size === 0)
23
23
  return undefined;
24
24
  const outcome = sendAttempt.entries.outcome.options.find((value) => value === terms.get("outcome"));
@@ -3,9 +3,9 @@ import type { CacheDatabase } from "../../store/driver.js";
3
3
  import type { Messenger } from "./context.js";
4
4
  /** `doctor`'s short summary of the store. Must answer for a broken file, so an error is a field. */
5
5
  export declare const storeSummary: (env: NodeJS.ProcessEnv) => Promise<{
6
- error?: undefined;
7
6
  path: string;
8
7
  exists: boolean;
8
+ error?: undefined;
9
9
  } | {
10
10
  path: string;
11
11
  exists: boolean;
@@ -4,22 +4,26 @@ import { Command } from "commander";
4
4
  import { capability } from "../../ports/messenger.js";
5
5
  import { ownerOnlyOption, REMOTE_READ, REMOTE_WRITE } from "../effects.js";
6
6
  import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
7
+ import { typedQuery, withQuery } from "../list-query.js";
7
8
  import { window, withPaging } from "../paging.js";
8
9
  import { lines, pageOf, topicAnswer } from "./chat-answers.js";
9
10
  import { messengerContext } from "./context.js";
10
- const listed = (messenger) => async function (chat) {
11
- const [, query] = this.args;
11
+ import { TOPICS_QUERY, topicTitle } from "./list-result-queries.js";
12
+ const listed = (messenger) => async function (chat, value) {
13
+ const searching = this.name() === "topics";
14
+ const words = !searching && Array.isArray(value) ? value : [];
15
+ const query = searching && typeof value === "string" ? value : topicTitle(words);
12
16
  const context = messengerContext(this, messenger);
13
17
  if (context.settings.offline) {
14
18
  throw new CliError("validation_error", "`topics` asks the messenger; not with --offline");
15
19
  }
16
20
  const wanted = { ...window(context.settings), ...(query ? { search: query } : {}) };
17
21
  const found = await context.withMessenger((adapter) => capability(adapter, "topics", "list forum topics")(chat, wanted));
18
- const command = query === undefined ? "topics list" : "search topics";
22
+ const command = searching ? "search topics" : "topics list";
19
23
  renderAnswer(this, context, listOf(command, {
20
24
  items: found.items.map(topicAnswer),
21
25
  ...pageOf(context.settings, found),
22
- args: { chat, ...(query === undefined ? {} : { text: query }) },
26
+ args: { chat, ...(searching ? { text: query } : typedQuery(words) ? { query: typedQuery(words) } : {}) },
23
27
  }), lines(({ id, title, closed, pinned, unread_count }) => [id, title, closed ? "closed" : "", pinned ? "pinned" : "", unread_count ? `${unread_count} unread` : ""].join(" ")));
24
28
  };
25
29
  /** `search topics`: a forum group's topics whose title matches, asked of the messenger. */
@@ -30,9 +34,9 @@ export const topicsSearchCommand = (messenger) => withPaging(annotate(new Comman
30
34
  /** `topics list` and the writes — a forum group's topics, with the ids its messages carry as `threadId`. */
31
35
  export const topicsCommand = (messenger) => {
32
36
  const topics = annotate(new Command("topics"), { offline: false }).description("the topics of a forum group");
33
- topics.addCommand(withPaging(annotate(new Command("list"), { effects: REMOTE_READ })
37
+ topics.addCommand(withQuery(withPaging(annotate(new Command("list"), { effects: REMOTE_READ })
34
38
  .description("a forum group's topics, newest activity first")
35
- .argument("<chat>", messenger.chatArgument)).action(listed(messenger)));
39
+ .argument("<chat>", messenger.chatArgument)), TOPICS_QUERY).action(listed(messenger)));
36
40
  if (messenger.topicShow)
37
41
  annotate(topics.command("show"), { effects: REMOTE_READ })
38
42
  .description("one forum topic: its title, state and last activity")
@@ -39,6 +39,7 @@ import { imageEmbedding } from "./image-embedding.js";
39
39
  import { inviteLink } from "./invite-link.js";
40
40
  import { job } from "./job.js";
41
41
  import { joinRequest } from "./join-request.js";
42
+ import { botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, callRecord, scheduledJob, stickerInventory } from "./list-results.js";
42
43
  import { messageEvent, serveSummary, watchedMessage, watchItem } from "./listener.js";
43
44
  import { mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer } from "./media-archive.js";
44
45
  import { meeting } from "./meeting.js";
@@ -84,7 +85,7 @@ import { topic } from "./topic.js";
84
85
  * subset of its fields, never a renamed one. Commands move onto these one by one; until then, a schema
85
86
  * is the target, not a description of today's output.
86
87
  */
87
- export { account, accountChange, accountPrivacy, accountPrivacyChange, accountProfile, accountSession, adminReport, agenda, analysisConsent, analysisConsentRevocation, attachment, attachmentBytes, attachmentExtraction, attachmentTextChange, automaticTags, cachedChatMetadata, chart, chat, chatAdminChange, chatArchive, chatEvent, chatFolderChange, chatFolderOrder, chatFolderRemoval, chatGroupChange, chatInspection, chatInvite, chatInviteChange, chatMembersChange, chatMembersFetch, chatMetadata, chatMetadataRefresh, chatModeration, chatMuting, chatPin, chatRead, chatRemoval, chatRequestChange, chatRules, chatSender, chatStats, chatTracking, chatUnread, contact, contactActivity, contactAlias, contactCheck, contactContext, contactImport, contactLookup, contactNote, contactNoteRemoval, contactPreparation, contactProfile, contactStateChange, contactSync, contactUpdate, conversation, conversationBatch, conversationBatchStatus, conversationBuildResult, conversationChange, conversationDetails, conversationEmbedding, conversationEmbeddingStatus, conversationHit, conversationPreparation, conversationReadiness, counterRefresh, counters, document, documentLink, endedAccountSessions, evidence, evidencePacket, fact, folder, hit, identity, imageEmbedding, inviteLink, job, joinRequest, linkedPerson, mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer, meeting, meetingProjectCandidates, meetingSeriesInventory, member, memory, mention, mentionDecision, mentionDetails, mentionDomain, mentionRebuild, message, messageContext, messageCounts, messageDeletion, messageDownload, messageEvent, messageLink, messageLinks, messagePin, messageStar, messageSync, messageTranscript, messageWrite, model, modelKey, note, officialStats, person, place, poll, pollChange, pollVote, ranking, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, removedModelKey, retention, runDetails, runHit, runLocation, savedSearch, searchHistoryClear, sendAttempt, serveSummary, storeBackup, storeChatStatus, storeCheck, storeClear, storeCopyRemoval, storeDecrypt, storedModelKey, storeExport, storeGapPlan, storeGapRepair, storeInfo, storeJobCancel, storeJobClear, storeJobDetails, storeJobRetry, storeMigration, storeReindex, storeRepair, storeReset, storeRestore, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
88
+ export { account, accountChange, accountPrivacy, accountPrivacyChange, accountProfile, accountSession, adminReport, agenda, analysisConsent, analysisConsentRevocation, attachment, attachmentBytes, attachmentExtraction, attachmentTextChange, automaticTags, botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, cachedChatMetadata, callRecord, chart, chat, chatAdminChange, chatArchive, chatEvent, chatFolderChange, chatFolderOrder, chatFolderRemoval, chatGroupChange, chatInspection, chatInvite, chatInviteChange, chatMembersChange, chatMembersFetch, chatMetadata, chatMetadataRefresh, chatModeration, chatMuting, chatPin, chatRead, chatRemoval, chatRequestChange, chatRules, chatSender, chatStats, chatTracking, chatUnread, contact, contactActivity, contactAlias, contactCheck, contactContext, contactImport, contactLookup, contactNote, contactNoteRemoval, contactPreparation, contactProfile, contactStateChange, contactSync, contactUpdate, conversation, conversationBatch, conversationBatchStatus, conversationBuildResult, conversationChange, conversationDetails, conversationEmbedding, conversationEmbeddingStatus, conversationHit, conversationPreparation, conversationReadiness, counterRefresh, counters, document, documentLink, endedAccountSessions, evidence, evidencePacket, fact, folder, hit, identity, imageEmbedding, inviteLink, job, joinRequest, linkedPerson, mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer, meeting, meetingProjectCandidates, meetingSeriesInventory, member, memory, mention, mentionDecision, mentionDetails, mentionDomain, mentionRebuild, message, messageContext, messageCounts, messageDeletion, messageDownload, messageEvent, messageLink, messageLinks, messagePin, messageStar, messageSync, messageTranscript, messageWrite, model, modelKey, note, officialStats, person, place, poll, pollChange, pollVote, ranking, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, removedModelKey, retention, runDetails, runHit, runLocation, savedSearch, scheduledJob, searchHistoryClear, sendAttempt, serveSummary, stickerInventory, storeBackup, storeChatStatus, storeCheck, storeClear, storeCopyRemoval, storeDecrypt, storedModelKey, storeExport, storeGapPlan, storeGapRepair, storeInfo, storeJobCancel, storeJobClear, storeJobDetails, storeJobRetry, storeMigration, storeReindex, storeRepair, storeReset, storeRestore, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
88
89
  export declare const ENTITIES: {
89
90
  readonly meeting_ingestion: v.StrictObjectSchema<{
90
91
  readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
@@ -4741,6 +4742,88 @@ export declare const ENTITIES: {
4741
4742
  readonly account: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
4742
4743
  readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4743
4744
  }, undefined>;
4745
+ readonly bot_profile: v.StrictObjectSchema<{
4746
+ readonly name: v.StringSchema<undefined>;
4747
+ readonly token: v.StringSchema<undefined>;
4748
+ readonly bot: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4749
+ readonly id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
4750
+ readonly problem: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4751
+ }, undefined>;
4752
+ readonly bot_template: v.StrictObjectSchema<{
4753
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4754
+ readonly status: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4755
+ readonly language: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4756
+ readonly category: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4757
+ }, undefined>;
4758
+ readonly bot_seen_chat: v.StrictObjectSchema<{
4759
+ readonly title: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4760
+ readonly kind: v.OptionalSchema<v.PicklistSchema<["dialog", "group", "channel", "saved", "unknown"], undefined>, undefined>;
4761
+ readonly unread_count: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
4762
+ readonly unread_mentions: v.OptionalSchema<v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
4763
+ readonly last_message_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>;
4764
+ readonly participants_count: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
4765
+ readonly muted: v.OptionalSchema<v.OptionalSchema<v.BooleanSchema<undefined>, undefined>, undefined>;
4766
+ readonly archived: v.OptionalSchema<v.OptionalSchema<v.BooleanSchema<undefined>, undefined>, undefined>;
4767
+ readonly marked_unread: v.OptionalSchema<v.OptionalSchema<v.BooleanSchema<undefined>, undefined>, undefined>;
4768
+ readonly membership_state: v.OptionalSchema<v.OptionalSchema<v.PicklistSchema<["joined", "left", "public", "imported", "archived", "external"], undefined>, undefined>, undefined>;
4769
+ readonly scope: v.OptionalSchema<v.OptionalSchema<v.PicklistSchema<["personal", "work"], undefined>, undefined>, undefined>;
4770
+ readonly provider_metadata: v.OptionalSchema<v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>, undefined>;
4771
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4772
+ readonly parent_chat_id: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>, undefined>;
4773
+ readonly muted_until: 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>;
4774
+ readonly first_seen_at: v.OptionalSchema<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>;
4775
+ readonly last_seen_at: v.OptionalSchema<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>;
4776
+ }, undefined>;
4777
+ readonly bot_admin: v.StrictObjectSchema<{
4778
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4779
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4780
+ readonly username: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4781
+ readonly role: v.PicklistSchema<["owner", "admin"], undefined>;
4782
+ readonly rights: v.ArraySchema<v.PicklistSchema<["read", "members", "admins", "info", "pin", "link", "post", "edit", "delete"], undefined>, undefined>;
4783
+ readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4784
+ }, undefined>;
4785
+ readonly bot_menu_entry: v.StrictObjectSchema<{
4786
+ readonly name: v.StringSchema<undefined>;
4787
+ readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4788
+ }, undefined>;
4789
+ readonly bot_webhook: v.StrictObjectSchema<{
4790
+ readonly url: v.StringSchema<undefined>;
4791
+ readonly types: v.NullableSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
4792
+ }, undefined>;
4793
+ readonly scheduled_job: v.StrictObjectSchema<{
4794
+ readonly name: v.StringSchema<undefined>;
4795
+ readonly kind: v.PicklistSchema<["command", "agent"], undefined>;
4796
+ readonly when: v.StringSchema<undefined>;
4797
+ readonly last: v.NullableSchema<v.StrictObjectSchema<{
4798
+ 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`">]>;
4799
+ readonly exit_code: v.NumberSchema<undefined>;
4800
+ readonly output: v.StringSchema<undefined>;
4801
+ readonly trace_id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4802
+ readonly reason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4803
+ readonly error_code: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4804
+ readonly failing_since: v.OptionalSchema<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>;
4805
+ readonly failures: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
4806
+ }, undefined>, undefined>;
4807
+ }, undefined>;
4808
+ readonly call_record: v.StrictObjectSchema<{
4809
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4810
+ readonly chat_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
4811
+ readonly caller_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
4812
+ readonly direction: v.PicklistSchema<["incoming", "outgoing"], undefined>;
4813
+ readonly outcome: v.PicklistSchema<["answered", "missed", "declined"], undefined>;
4814
+ readonly kind: v.PicklistSchema<["audio", "video"], undefined>;
4815
+ 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`">]>;
4816
+ readonly duration_seconds: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
4817
+ }, undefined>;
4818
+ readonly sticker_inventory: v.StrictObjectSchema<{
4819
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4820
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4821
+ readonly count: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
4822
+ readonly link: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4823
+ readonly set_id: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>, undefined>;
4824
+ readonly emoji: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
4825
+ readonly url: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4826
+ }, undefined>;
4744
4827
  readonly note: v.StrictObjectSchema<{
4745
4828
  readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
4746
4829
  readonly kind: v.OptionalSchema<v.PicklistSchema<["note", "document"], undefined>, undefined>;
@@ -41,6 +41,7 @@ import { imageEmbedding } from "./image-embedding.js";
41
41
  import { inviteLink } from "./invite-link.js";
42
42
  import { job } from "./job.js";
43
43
  import { joinRequest } from "./join-request.js";
44
+ import { botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, callRecord, scheduledJob, stickerInventory, } from "./list-results.js";
44
45
  import { messageEvent, serveSummary, watchedMessage, watchItem } from "./listener.js";
45
46
  import { mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer } from "./media-archive.js";
46
47
  import { event, meeting, meetingDetails, meetingHit, meetingLink, meetingParticipants, meetingPassage, meetingProjectEvidence, meetingReview, meetingSpeaker, meetingStats, meetingSummary, meetingTranscript, } from "./meeting.js";
@@ -90,7 +91,7 @@ import { topic } from "./topic.js";
90
91
  * subset of its fields, never a renamed one. Commands move onto these one by one; until then, a schema
91
92
  * is the target, not a description of today's output.
92
93
  */
93
- export { account, accountChange, accountPrivacy, accountPrivacyChange, accountProfile, accountSession, adminReport, agenda, analysisConsent, analysisConsentRevocation, attachment, attachmentBytes, attachmentExtraction, attachmentTextChange, automaticTags, cachedChatMetadata, chart, chat, chatAdminChange, chatArchive, chatEvent, chatFolderChange, chatFolderOrder, chatFolderRemoval, chatGroupChange, chatInspection, chatInvite, chatInviteChange, chatMembersChange, chatMembersFetch, chatMetadata, chatMetadataRefresh, chatModeration, chatMuting, chatPin, chatRead, chatRemoval, chatRequestChange, chatRules, chatSender, chatStats, chatTracking, chatUnread, contact, contactActivity, contactAlias, contactCheck, contactContext, contactImport, contactLookup, contactNote, contactNoteRemoval, contactPreparation, contactProfile, contactStateChange, contactSync, contactUpdate, conversation, conversationBatch, conversationBatchStatus, conversationBuildResult, conversationChange, conversationDetails, conversationEmbedding, conversationEmbeddingStatus, conversationHit, conversationPreparation, conversationReadiness, counterRefresh, counters, document, documentLink, endedAccountSessions, evidence, evidencePacket, fact, folder, hit, identity, imageEmbedding, inviteLink, job, joinRequest, linkedPerson, mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer, meeting, meetingProjectCandidates, meetingSeriesInventory, member, memory, mention, mentionDecision, mentionDetails, mentionDomain, mentionRebuild, message, messageContext, messageCounts, messageDeletion, messageDownload, messageEvent, messageLink, messageLinks, messagePin, messageStar, messageSync, messageTranscript, messageWrite, model, modelKey, note, officialStats, person, place, poll, pollChange, pollVote, ranking, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, removedModelKey, retention, runDetails, runHit, runLocation, savedSearch, searchHistoryClear, sendAttempt, serveSummary, storeBackup, storeChatStatus, storeCheck, storeClear, storeCopyRemoval, storeDecrypt, storedModelKey, storeExport, storeGapPlan, storeGapRepair, storeInfo, storeJobCancel, storeJobClear, storeJobDetails, storeJobRetry, storeMigration, storeReindex, storeRepair, storeReset, storeRestore, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
94
+ export { account, accountChange, accountPrivacy, accountPrivacyChange, accountProfile, accountSession, adminReport, agenda, analysisConsent, analysisConsentRevocation, attachment, attachmentBytes, attachmentExtraction, attachmentTextChange, automaticTags, botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, cachedChatMetadata, callRecord, chart, chat, chatAdminChange, chatArchive, chatEvent, chatFolderChange, chatFolderOrder, chatFolderRemoval, chatGroupChange, chatInspection, chatInvite, chatInviteChange, chatMembersChange, chatMembersFetch, chatMetadata, chatMetadataRefresh, chatModeration, chatMuting, chatPin, chatRead, chatRemoval, chatRequestChange, chatRules, chatSender, chatStats, chatTracking, chatUnread, contact, contactActivity, contactAlias, contactCheck, contactContext, contactImport, contactLookup, contactNote, contactNoteRemoval, contactPreparation, contactProfile, contactStateChange, contactSync, contactUpdate, conversation, conversationBatch, conversationBatchStatus, conversationBuildResult, conversationChange, conversationDetails, conversationEmbedding, conversationEmbeddingStatus, conversationHit, conversationPreparation, conversationReadiness, counterRefresh, counters, document, documentLink, endedAccountSessions, evidence, evidencePacket, fact, folder, hit, identity, imageEmbedding, inviteLink, job, joinRequest, linkedPerson, mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer, meeting, meetingProjectCandidates, meetingSeriesInventory, member, memory, mention, mentionDecision, mentionDetails, mentionDomain, mentionRebuild, message, messageContext, messageCounts, messageDeletion, messageDownload, messageEvent, messageLink, messageLinks, messagePin, messageStar, messageSync, messageTranscript, messageWrite, model, modelKey, note, officialStats, person, place, poll, pollChange, pollVote, ranking, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, removedModelKey, retention, runDetails, runHit, runLocation, savedSearch, scheduledJob, searchHistoryClear, sendAttempt, serveSummary, stickerInventory, storeBackup, storeChatStatus, storeCheck, storeClear, storeCopyRemoval, storeDecrypt, storedModelKey, storeExport, storeGapPlan, storeGapRepair, storeInfo, storeJobCancel, storeJobClear, storeJobDetails, storeJobRetry, storeMigration, storeReindex, storeRepair, storeReset, storeRestore, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
94
95
  export const ENTITIES = {
95
96
  sync_progress: syncProgress,
96
97
  ...MEETING_RESULT_ENTITIES,
@@ -166,6 +167,15 @@ export const ENTITIES = {
166
167
  account_privacy: accountPrivacy,
167
168
  account_privacy_change: accountPrivacyChange,
168
169
  account_profile: accountProfile,
170
+ bot_profile: botProfile,
171
+ bot_template: botTemplate,
172
+ bot_seen_chat: botSeenChat,
173
+ bot_admin: botAdmin,
174
+ bot_menu_entry: botMenuEntry,
175
+ bot_webhook: botWebhook,
176
+ scheduled_job: scheduledJob,
177
+ call_record: callRecord,
178
+ sticker_inventory: stickerInventory,
169
179
  note,
170
180
  "note.hit": v.pick(note, [
171
181
  "kind",
@@ -0,0 +1,83 @@
1
+ import * as v from "valibot";
2
+ export declare const botProfile: v.StrictObjectSchema<{
3
+ readonly name: v.StringSchema<undefined>;
4
+ readonly token: v.StringSchema<undefined>;
5
+ readonly bot: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
6
+ readonly id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
7
+ readonly problem: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
8
+ }, undefined>;
9
+ export declare const botSeenChat: v.StrictObjectSchema<{
10
+ readonly title: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
11
+ readonly kind: v.OptionalSchema<v.PicklistSchema<["dialog", "group", "channel", "saved", "unknown"], undefined>, undefined>;
12
+ readonly unread_count: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
13
+ readonly unread_mentions: v.OptionalSchema<v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
14
+ readonly last_message_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>;
15
+ readonly participants_count: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
16
+ readonly muted: v.OptionalSchema<v.OptionalSchema<v.BooleanSchema<undefined>, undefined>, undefined>;
17
+ readonly archived: v.OptionalSchema<v.OptionalSchema<v.BooleanSchema<undefined>, undefined>, undefined>;
18
+ readonly marked_unread: v.OptionalSchema<v.OptionalSchema<v.BooleanSchema<undefined>, undefined>, undefined>;
19
+ readonly membership_state: v.OptionalSchema<v.OptionalSchema<v.PicklistSchema<["joined", "left", "public", "imported", "archived", "external"], undefined>, undefined>, undefined>;
20
+ readonly scope: v.OptionalSchema<v.OptionalSchema<v.PicklistSchema<["personal", "work"], undefined>, undefined>, undefined>;
21
+ readonly provider_metadata: v.OptionalSchema<v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>, undefined>;
22
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
23
+ readonly parent_chat_id: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>, undefined>;
24
+ readonly muted_until: 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>;
25
+ readonly first_seen_at: v.OptionalSchema<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>;
26
+ readonly last_seen_at: v.OptionalSchema<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>;
27
+ }, undefined>;
28
+ export declare const botAdmin: v.StrictObjectSchema<{
29
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
30
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
31
+ readonly username: v.NullableSchema<v.StringSchema<undefined>, undefined>;
32
+ readonly role: v.PicklistSchema<["owner", "admin"], undefined>;
33
+ readonly rights: v.ArraySchema<v.PicklistSchema<["read", "members", "admins", "info", "pin", "link", "post", "edit", "delete"], undefined>, undefined>;
34
+ readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
35
+ }, undefined>;
36
+ export declare const botMenuEntry: v.StrictObjectSchema<{
37
+ readonly name: v.StringSchema<undefined>;
38
+ readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
39
+ }, undefined>;
40
+ export declare const botWebhook: v.StrictObjectSchema<{
41
+ readonly url: v.StringSchema<undefined>;
42
+ readonly types: v.NullableSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
43
+ }, undefined>;
44
+ export declare const scheduledJob: v.StrictObjectSchema<{
45
+ readonly name: v.StringSchema<undefined>;
46
+ readonly kind: v.PicklistSchema<["command", "agent"], undefined>;
47
+ readonly when: v.StringSchema<undefined>;
48
+ readonly last: v.NullableSchema<v.StrictObjectSchema<{
49
+ 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`">]>;
50
+ readonly exit_code: v.NumberSchema<undefined>;
51
+ readonly output: v.StringSchema<undefined>;
52
+ readonly trace_id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
53
+ readonly reason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
54
+ readonly error_code: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
55
+ readonly failing_since: v.OptionalSchema<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>;
56
+ readonly failures: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
57
+ }, undefined>, undefined>;
58
+ }, undefined>;
59
+ export declare const botTemplate: v.StrictObjectSchema<{
60
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
61
+ readonly status: v.NullableSchema<v.StringSchema<undefined>, undefined>;
62
+ readonly language: v.NullableSchema<v.StringSchema<undefined>, undefined>;
63
+ readonly category: v.NullableSchema<v.StringSchema<undefined>, undefined>;
64
+ }, undefined>;
65
+ export declare const callRecord: v.StrictObjectSchema<{
66
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
67
+ readonly chat_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
68
+ readonly caller_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
69
+ readonly direction: v.PicklistSchema<["incoming", "outgoing"], undefined>;
70
+ readonly outcome: v.PicklistSchema<["answered", "missed", "declined"], undefined>;
71
+ readonly kind: v.PicklistSchema<["audio", "video"], undefined>;
72
+ 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`">]>;
73
+ readonly duration_seconds: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
74
+ }, undefined>;
75
+ export declare const stickerInventory: v.StrictObjectSchema<{
76
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
77
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
78
+ readonly count: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
79
+ readonly link: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
80
+ readonly set_id: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>, undefined>;
81
+ readonly emoji: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
82
+ readonly url: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
83
+ }, undefined>;
@@ -0,0 +1,69 @@
1
+ import * as v from "valibot";
2
+ import { chat } from "./chat.js";
3
+ import { id, text, time } from "./fields.js";
4
+ export const botProfile = v.strictObject({
5
+ name: text,
6
+ token: text,
7
+ bot: v.optional(text),
8
+ id: v.optional(id),
9
+ problem: v.optional(text),
10
+ });
11
+ export const botSeenChat = v.strictObject({
12
+ ...v.partial(v.omit(chat, ["ref", "provider", "account", "description", "invite_link", "settings", "members"]))
13
+ .entries,
14
+ id,
15
+ parent_chat_id: v.optional(v.nullable(id)),
16
+ muted_until: v.optional(v.nullable(time)),
17
+ first_seen_at: v.optional(time),
18
+ last_seen_at: v.optional(time),
19
+ });
20
+ export const botAdmin = v.strictObject({
21
+ id,
22
+ name: v.nullable(text),
23
+ username: v.nullable(text),
24
+ role: v.picklist(["owner", "admin"]),
25
+ rights: v.array(v.picklist(["read", "members", "admins", "info", "pin", "link", "post", "edit", "delete"])),
26
+ title: v.nullable(text),
27
+ });
28
+ export const botMenuEntry = v.strictObject({ name: text, description: v.nullable(text) });
29
+ export const botWebhook = v.strictObject({ url: text, types: v.nullable(v.array(text)) });
30
+ export const scheduledJob = v.strictObject({
31
+ name: text,
32
+ kind: v.picklist(["command", "agent"]),
33
+ when: text,
34
+ last: v.nullable(v.strictObject({
35
+ at: time,
36
+ exit_code: v.number(),
37
+ output: text,
38
+ trace_id: v.optional(text),
39
+ reason: v.optional(text),
40
+ error_code: v.optional(text),
41
+ failing_since: v.optional(time),
42
+ failures: v.optional(v.number()),
43
+ })),
44
+ });
45
+ export const botTemplate = v.strictObject({
46
+ name: v.nullable(text),
47
+ status: v.nullable(text),
48
+ language: v.nullable(text),
49
+ category: v.nullable(text),
50
+ });
51
+ export const callRecord = v.strictObject({
52
+ id,
53
+ chat_id: v.nullable(id),
54
+ caller_id: v.nullable(id),
55
+ direction: v.picklist(["incoming", "outgoing"]),
56
+ outcome: v.picklist(["answered", "missed", "declined"]),
57
+ kind: v.picklist(["audio", "video"]),
58
+ at: time,
59
+ duration_seconds: v.nullable(v.number()),
60
+ });
61
+ export const stickerInventory = v.strictObject({
62
+ id,
63
+ title: v.optional(text),
64
+ count: v.optional(v.number()),
65
+ link: v.optional(v.nullable(text)),
66
+ set_id: v.optional(v.nullable(id)),
67
+ emoji: v.optional(v.array(text)),
68
+ url: v.optional(v.nullable(text)),
69
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.408.0",
3
+ "version": "0.409.0",
4
4
  "description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",