@wirecat/cli-core 0.530.0 → 0.531.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/cli/index.d.ts +2 -2
  3. package/dist/cli/index.js +1 -1
  4. package/dist/cli/list-query.d.ts +0 -4
  5. package/dist/cli/list-query.js +19 -1
  6. package/dist/cli/messenger/schedule-command.d.ts +2 -19
  7. package/dist/cli/messenger/schedule-command.js +2 -231
  8. package/dist/cli/messenger/topics-command.js +22 -5
  9. package/dist/cli/schedule/schedule-command.d.ts +19 -0
  10. package/dist/cli/schedule/schedule-command.js +261 -0
  11. package/dist/cli/shared-command-exports.d.ts +1 -1
  12. package/dist/cli/shared-command-exports.js +2 -1
  13. package/dist/domain/models.d.ts +2 -0
  14. package/dist/entities/index.d.ts +41 -2
  15. package/dist/entities/index.js +3 -2
  16. package/dist/entities/list-results.d.ts +3 -0
  17. package/dist/entities/list-results.js +1 -0
  18. package/dist/entities/task-results.d.ts +30 -0
  19. package/dist/entities/task-results.js +1 -0
  20. package/dist/entities/task.d.ts +7 -0
  21. package/dist/entities/task.js +2 -0
  22. package/dist/errors/reasons.js +1 -0
  23. package/dist/mail/account-key.d.ts +2 -0
  24. package/dist/mail/account-key.js +1 -0
  25. package/dist/mail/cli/index.js +10 -10
  26. package/dist/mail/index.d.ts +1 -0
  27. package/dist/mail/index.js +1 -0
  28. package/dist/mail/retry.js +2 -1
  29. package/dist/mail/rule-stored.js +2 -1
  30. package/dist/mail/sender-scores.js +2 -1
  31. package/dist/mail/sync.js +3 -2
  32. package/dist/ports/messenger.d.ts +3 -0
  33. package/dist/services/tasks.d.ts +4 -2
  34. package/dist/services/tasks.js +2 -2
  35. package/dist/services/topics.d.ts +3 -0
  36. package/dist/services/topics.js +20 -6
  37. package/dist/store/index.d.ts +1 -0
  38. package/dist/store/sqlite/task-board.js +3 -1
  39. package/dist/store/sqlite/task-comments.d.ts +23 -0
  40. package/dist/store/sqlite/task-comments.js +41 -0
  41. package/dist/store/sqlite/things.js +8 -1
  42. package/dist/store/sqlite/work-tasks.d.ts +13 -2
  43. package/dist/store/sqlite/work-tasks.js +52 -1
  44. package/package.json +1 -1
@@ -0,0 +1,261 @@
1
+ import { existsSync, rmSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { CliError, resolvePaths, writeSecurely } from "@wirecat/cli-base";
4
+ import { annotate } from "@wirecat/cli-base/commands";
5
+ import { Argument, Command, Option } from "commander";
6
+ import { describeWhen, findProgram, lastRun, listSchedules, readSchedule, runSchedule, scheduleFile, scheduleName, timerFor, } from "../../background/schedules.js";
7
+ import { thisMachine } from "../../background/system.js";
8
+ import { locationVariables } from "../../background/units.js";
9
+ import { parseDuration } from "../../domain/duration.js";
10
+ import { readOnlyLockOf } from "../../ports/app.js";
11
+ import { aheadOf } from "../../services/moment.js";
12
+ import { storePath } from "../../store/path.js";
13
+ import { environmentOf, setExitCode } from "../context.js";
14
+ import { grantsAuthority, LOCAL_READ, LOCAL_WRITE, REMOTE_WRITE } from "../effects.js";
15
+ import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
16
+ import { withQuery } from "../list-query.js";
17
+ import { SCHEDULES_QUERY, scheduleFilter } from "../messenger/list-result-queries.js";
18
+ import { lineOf } from "../steps.js";
19
+ /** Each run of an agent is a paid model call that reads chats; keeping the store current is `serve`'s job. */
20
+ const AGENT_MINIMUM_MINUTES = 60;
21
+ const COMMAND_MINIMUM_MINUTES = 1;
22
+ const HARNESSES = ["claude", "codex"];
23
+ const whenOf = ({ every, at, atTime }, minimum) => {
24
+ if ([every ?? at, atTime].filter(Boolean).length !== 1) {
25
+ throw new CliError("validation_error", "say when: --every <30m|2h|1d>, --at HH:MM (daily), or --at-time <30m|2d|ISO time>");
26
+ }
27
+ if (atTime) {
28
+ const time = aheadOf(atTime, "--at-time");
29
+ if (time <= Date.now())
30
+ throw new CliError("validation_error", "--at-time is in the past");
31
+ return { once: new Date(time).toISOString() };
32
+ }
33
+ if (at) {
34
+ if (!/^([01]\d|2[0-3]):[0-5]\d$/.test(at))
35
+ throw new CliError("validation_error", `--at takes HH:MM, not "${at}"`);
36
+ if (every && parseDuration(every, "--every") !== 86_400_000) {
37
+ throw new CliError("validation_error", "--at runs once a day; leave out --every, or use --every 1d");
38
+ }
39
+ return { daily: at };
40
+ }
41
+ const minutes = parseDuration(every ?? "", "--every") / 60_000;
42
+ if (!Number.isInteger(minutes) || minutes < minimum) {
43
+ throw new CliError("validation_error", `--every is at least ${minimum} minute${minimum === 1 ? "" : "s"} here, in whole minutes`);
44
+ }
45
+ return { every: minutes };
46
+ };
47
+ /** A schedule as answered: snake_case, but its environment keeps the variables' own names. */
48
+ const scheduleAnswer = ({ environment, createdAt, ...schedule }, extra) => ({
49
+ ...snakeKeys(schedule),
50
+ environment,
51
+ created_at: createdAt,
52
+ ...snakeKeys(extra),
53
+ });
54
+ const withWhen = (command) => command
55
+ .option("--every <duration>", "repeat: 30m, 2h, 1d")
56
+ .option("--at <HH:MM>", "every day at this local time")
57
+ .option("--at-time <time>", "one run: 30m, 2d from now, or an ISO time; the schedule removes itself after it");
58
+ /**
59
+ * Runs the CLI's own commands, or an agent, later or on a timer — through systemd (Linux), launchd
60
+ * (macOS) or Task Scheduler (Windows). Every timer runs `schedule exec <file>`; the schedule file holds
61
+ * the rest, so what runs and with which variables is the same on all three.
62
+ */
63
+ export const scheduleCommandFor = ({ app, context: contextOf }) => {
64
+ const command = new Command("schedule").description(`run a ${app.command} command or an agent later or on a timer (systemd, launchd, Task Scheduler); an agent cannot send`);
65
+ const prepare = (self, resolving = {}) => {
66
+ const context = contextOf(self, resolving);
67
+ const system = environmentOf(self).system ?? thisMachine();
68
+ const state = resolvePaths({ appName: app.appName, prefix: app.envPrefix, env: context.env }).state;
69
+ const say = (value, lines) => renderAnswer(self, context, itemOf(value), () => lines.join("\n"));
70
+ const timer = () => timerFor(app, system, context.env);
71
+ // The command line refuses a schedule under the lock; a caller that gets here still passes the lock on.
72
+ const readOnly = readOnlyLockOf(app, context.env);
73
+ const environment = () => ({
74
+ [`${app.envPrefix}_PROFILE`]: context.profile,
75
+ ...locationVariables(app, context.env),
76
+ // The timer starts with almost no PATH; an agent runs `max` and its own tools by name.
77
+ ...(context.env.PATH ? { PATH: context.env.PATH } : {}),
78
+ ...(readOnly ? { [readOnly]: "1" } : {}),
79
+ });
80
+ const save = async (schedule) => {
81
+ const file = scheduleFile(state, schedule.name);
82
+ const replaced = existsSync(file);
83
+ if (replaced) {
84
+ const owner = readSchedule(file).environment[`${app.envPrefix}_PROFILE`];
85
+ if (owner && owner !== context.profile) {
86
+ throw new CliError("validation_error", `schedule ${schedule.name} already runs for profile ${owner}; name this one for ${context.profile}, e.g. ${schedule.name}-${context.profile}`);
87
+ }
88
+ }
89
+ writeSecurely(file, `${JSON.stringify(schedule, null, 2)}\n`, 0o600);
90
+ await timer().install(schedule, [...system.entry, "schedule", "exec", file]);
91
+ say(scheduleAnswer(schedule, { file, timer: timer().where(schedule.name), replaced }), [
92
+ `${replaced ? "Replaced" : "Added"} ${schedule.name}: ${describeWhen(schedule.when)}.`,
93
+ `It runs: ${schedule.kind === "agent" ? schedule.argv.join(" ") : `${app.command} ${schedule.argv.join(" ")}`}`,
94
+ `Output: ${join(dirname(file), "runs")} · now: ${lineOf(self, `schedule run ${schedule.name}`)} · stop: ${lineOf(self, `schedule remove ${schedule.name}`)}`,
95
+ ]);
96
+ };
97
+ return { context, system, state, say, timer, environment, save };
98
+ };
99
+ withWhen(grantsAuthority(annotate(command.command("command"), {
100
+ effects: LOCAL_WRITE,
101
+ examples: [
102
+ `${app.command} personal schedule command health --every 1h -- doctor`,
103
+ `${app.command} personal schedule command morning-check --at 08:00 -- doctor`,
104
+ ],
105
+ }))
106
+ .description(`run ${app.command} <args…> on a timer — reads save what they read, so this is how a chat's history fills the store`)
107
+ .argument("<name>", "lowercase letters, digits and dashes")
108
+ .argument("<args...>", `the ${app.command} command after its name, e.g. -- messages list <chat> --limit 50`)).action(async function (name, args) {
109
+ const { environment, save } = prepare(this);
110
+ if (args[0] === "schedule")
111
+ throw new CliError("validation_error", "a schedule cannot run schedule");
112
+ await save({
113
+ name: scheduleName(name),
114
+ kind: "command",
115
+ argv: args,
116
+ when: whenOf(this.opts(), COMMAND_MINIMUM_MINUTES),
117
+ environment: environment(),
118
+ createdAt: new Date().toISOString(),
119
+ });
120
+ });
121
+ withWhen(grantsAuthority(annotate(command.command("agent"), {
122
+ effects: LOCAL_WRITE,
123
+ examples: [
124
+ `${app.command} personal schedule agent review claude "review what came in overnight and draft replies" --at 08:30`,
125
+ `${app.command} personal schedule agent triage codex "list what needs an answer today" --every 2h --max-cost 1`,
126
+ ],
127
+ }))
128
+ .description(`start an agent (claude or codex) with a prompt on a timer; it runs with ${app.envPrefix}_READ_ONLY=1, so it reads and drafts and cannot send — its answer is kept and you are notified`)
129
+ .argument("<name>", "lowercase letters, digits and dashes")
130
+ .addArgument(new Argument("<harness>", "the agent to start").choices(HARNESSES))
131
+ .argument("<prompt>", `what to do, e.g. "run the daily follow-up review: ${app.command} skill show follow-ups"`)
132
+ .addOption(new Option("--max-cost <usd>", "claude only: stop a run that costs more than this, in US dollars").argParser(Number))).action(async function (name, harness, prompt) {
133
+ const { context, system, environment, save } = prepare(this);
134
+ const options = this.opts();
135
+ const program = findProgram(harness, context.env, system.platform);
136
+ if (!program)
137
+ throw new CliError("not_found", `${harness} is not on PATH`);
138
+ const paths = resolvePaths({ appName: app.appName, prefix: app.envPrefix, env: context.env });
139
+ const argv = harness === "claude"
140
+ ? [
141
+ program,
142
+ "-p",
143
+ prompt,
144
+ // The owner's own settings may let every tool run (bypassPermissions); here only the CLI may.
145
+ "--permission-mode",
146
+ "dontAsk",
147
+ "--allowedTools",
148
+ `Bash(${app.command}:*)`,
149
+ "--no-session-persistence",
150
+ ...(options.maxCost ? ["--max-budget-usd", String(options.maxCost)] : []),
151
+ ]
152
+ : [
153
+ program,
154
+ "exec",
155
+ "--skip-git-repo-check",
156
+ "--ephemeral",
157
+ "--sandbox",
158
+ "workspace-write",
159
+ // The CLI reaches the messenger and writes its store and state, and nothing else.
160
+ "-c",
161
+ "sandbox_workspace_write.network_access=true",
162
+ ...[dirname(storePath(context.env)), paths.state, paths.config, paths.cache].flatMap((dir) => [
163
+ "--add-dir",
164
+ dir,
165
+ ]),
166
+ prompt,
167
+ ];
168
+ await save({
169
+ name: scheduleName(name),
170
+ kind: "agent",
171
+ argv,
172
+ when: whenOf(options, AGENT_MINIMUM_MINUTES),
173
+ environment: environment(),
174
+ createdAt: new Date().toISOString(),
175
+ });
176
+ });
177
+ withQuery(annotate(command.command("list"), {
178
+ effects: LOCAL_READ,
179
+ examples: [`${app.command} personal schedule list`, `${app.command} personal schedule list kind:agent`],
180
+ }), SCHEDULES_QUERY)
181
+ .description("the schedules, when they run and how their last run went")
182
+ .action(function (words) {
183
+ const filter = scheduleFilter(words);
184
+ const { context, state } = prepare(this);
185
+ const rows = listSchedules(state, filter).map((schedule) => ({
186
+ name: schedule.name,
187
+ kind: schedule.kind,
188
+ when: describeWhen(schedule.when),
189
+ last: lastRun(scheduleFile(state, schedule.name)) ?? null,
190
+ }));
191
+ const answer = listOf("schedule list", {
192
+ items: rows.map((row) => snakeKeys(row)),
193
+ limit: Math.max(1, rows.length),
194
+ has_more: false,
195
+ });
196
+ renderAnswer(this, context, answer, () => {
197
+ if (rows.length === 0) {
198
+ context.renderer.note(`no schedules — \`${lineOf(this, "schedule command|agent")}\` adds one`);
199
+ return "";
200
+ }
201
+ return rows
202
+ .map(({ name, kind, when, last }) => [
203
+ name,
204
+ kind,
205
+ when,
206
+ last
207
+ ? `last ${last.at.slice(0, 16).replace("T", " ")} exit ${last.exitCode}` +
208
+ (last.failures
209
+ ? ` — failing since ${(last.failingSince ?? last.at).slice(0, 16).replace("T", " ")}, ` +
210
+ `${last.failures} in a row${last.reason ? `: ${last.reason}` : ""} — ${last.output}`
211
+ : "")
212
+ : "not run yet",
213
+ ].join(" "))
214
+ .join("\n");
215
+ });
216
+ });
217
+ annotate(command.command("run"), {
218
+ effects: REMOTE_WRITE,
219
+ examples: [`${app.command} personal schedule run health`],
220
+ })
221
+ .description("run a schedule now, as its timer would, and wait for it")
222
+ .argument("<name>", "the schedule's name, as `schedule list` shows it")
223
+ .action(async function (name) {
224
+ const { context, system, state, say, timer } = prepare(this);
225
+ const last = await runSchedule(app, system, context.env, scheduleFile(state, scheduleName(name)), {
226
+ timer: timer(),
227
+ });
228
+ say(snakeKeys({ name, ...last }), [`${name}: exit ${last.exitCode} — ${last.output}`]);
229
+ if (last.exitCode !== 0)
230
+ setExitCode(this, 1);
231
+ });
232
+ grantsAuthority(annotate(command.command("remove"), {
233
+ effects: LOCAL_WRITE,
234
+ examples: [`${app.command} personal schedule remove health`],
235
+ }))
236
+ .description("stop a schedule and remove its timer; its past output stays")
237
+ .argument("<name>", "the schedule's name, as `schedule list` shows it")
238
+ .action(async function (name) {
239
+ const { state, say, timer } = prepare(this);
240
+ const file = scheduleFile(state, scheduleName(name));
241
+ if (!existsSync(file))
242
+ throw new CliError("not_found", `no schedule ${name} — \`${lineOf(this, "schedule list")}\``);
243
+ await timer().remove(name);
244
+ rmSync(file, { force: true });
245
+ say({ name, removed: true }, [`Removed ${name}.`]);
246
+ });
247
+ annotate(command.command("exec"), {
248
+ effects: REMOTE_WRITE,
249
+ examples: [`${app.command} schedule exec ~/.local/share/${app.appName}/schedules/health/schedule.json`],
250
+ })
251
+ .description("what a timer runs, given the schedule's file; to run one by hand, use run")
252
+ .argument("<file>", "the schedule's schedule.json in the state folder, as the timer passes it")
253
+ .action(async function (file) {
254
+ // A timer starts it with no profile named; the schedule's own environment carries the profile.
255
+ const { context, system, timer } = prepare(this, { needsProfile: false });
256
+ const last = await runSchedule(app, system, context.env, file, { timer: timer() });
257
+ if (last.exitCode !== 0)
258
+ setExitCode(this, 1);
259
+ });
260
+ return command;
261
+ };
@@ -765,7 +765,7 @@ export declare const stickersCommand: (messenger: import("./index.js").Messenger
765
765
  export declare const repliesCommand: (messenger: import("./index.js").Messenger) => import("commander").Command;
766
766
  export declare const reviewCommand: (messenger: import("./index.js").Messenger) => import("commander").Command;
767
767
  export declare const scheduleCommand: (messenger: import("./index.js").Messenger) => import("commander").Command;
768
- export declare const scheduleCommandFor: (args_0: import("./messenger/schedule-command.js").ScheduleHost) => import("commander").Command;
768
+ export declare const scheduleCommandFor: (args_0: import("./schedule/schedule-command.js").ScheduleHost) => import("commander").Command;
769
769
  export declare const searchCommand: (messenger: import("./index.js").Messenger, args_1?: {
770
770
  topics?: boolean;
771
771
  } | undefined) => import("commander").Command;
@@ -41,7 +41,7 @@ import { reactionsCommand as reactionsCommandDefinition } from "./messenger/reac
41
41
  import { callsCommand as callsCommandDefinition, stickersCommand as stickersCommandDefinition, } from "./messenger/records-command.js";
42
42
  import { repliesCommand as repliesCommandDefinition } from "./messenger/replies-command.js";
43
43
  import { reviewCommand as reviewCommandDefinition } from "./messenger/review.js";
44
- import { scheduleCommand as scheduleCommandDefinition, scheduleCommandFor as scheduleCommandForDefinition, } from "./messenger/schedule-command.js";
44
+ import { scheduleCommand as scheduleCommandDefinition } from "./messenger/schedule-command.js";
45
45
  import { searchCommand as searchCommandDefinition } from "./messenger/search-command.js";
46
46
  import { searchesCommand as searchesCommandDefinition } from "./messenger/searches-command.js";
47
47
  import { serveCommand as serveCommandDefinition } from "./messenger/serve-command.js";
@@ -52,6 +52,7 @@ import { tasksCommand as tasksCommandDefinition, tasksStatsCommand as tasksStats
52
52
  import { topicsCommand as topicsCommandDefinition } from "./messenger/topics-command.js";
53
53
  import { watchCommand as watchCommandDefinition } from "./messenger/watch-command.js";
54
54
  import { runsCommand as runsCommandDefinition } from "./runs/command.js";
55
+ import { scheduleCommandFor as scheduleCommandForDefinition } from "./schedule/schedule-command.js";
55
56
  import { sharedCommand as protectedCommand } from "./shared-contracts.js";
56
57
  import { skillCommand as skillCommandDefinition } from "./skill-command.js";
57
58
  import { upgradeCommand as upgradeCommandDefinition } from "./upgrade-command.js";
@@ -608,6 +608,8 @@ export interface TopicChange {
608
608
  pinned?: boolean;
609
609
  /** Only a forum's General topic can be hidden from the topic list. */
610
610
  hidden?: boolean;
611
+ /** An emoji from the messenger's topic icon set; `null` removes the icon. */
612
+ icon?: string | null;
611
613
  }
612
614
  /** Someone who asked to join a group or channel that needs an admin's approval. */
613
615
  export interface JoinRequest {
@@ -40,7 +40,7 @@ import { inviteLink } from "./invite-link.js";
40
40
  import { job } from "./job.js";
41
41
  import { joinRequest } from "./join-request.js";
42
42
  import { organization, project, reminder } from "./knowledge-lists.js";
43
- import { botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, callRecord, scheduledJob, stickerInventory } from "./list-results.js";
43
+ import { botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, callRecord, scheduledJob, stickerInventory, topicIcon } from "./list-results.js";
44
44
  import { messageEvent, serveSummary, watchedMessage, watchItem } from "./listener.js";
45
45
  import { mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer } from "./media-archive.js";
46
46
  import { meeting } from "./meeting.js";
@@ -88,7 +88,7 @@ import { topic } from "./topic.js";
88
88
  * subset of its fields, never a renamed one. Commands move onto these one by one; until then, a schema
89
89
  * is the target, not a description of today's output.
90
90
  */
91
- 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, 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, organization, person, place, poll, pollChange, pollVote, project, ranking, reaction, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, reminder, 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, storeTable, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
91
+ 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, 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, organization, person, place, poll, pollChange, pollVote, project, ranking, reaction, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, reminder, 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, storeTable, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, topicIcon, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
92
92
  export declare const ENTITIES: {
93
93
  readonly meeting_ingestion: v.StrictObjectSchema<{
94
94
  readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
@@ -4441,6 +4441,9 @@ export declare const ENTITIES: {
4441
4441
  readonly name: v.StringSchema<undefined>;
4442
4442
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4443
4443
  }, undefined>;
4444
+ readonly topic_icon: v.StrictObjectSchema<{
4445
+ readonly emoji: v.StringSchema<undefined>;
4446
+ }, undefined>;
4444
4447
  readonly bot_webhook: v.StrictObjectSchema<{
4445
4448
  readonly url: v.StringSchema<undefined>;
4446
4449
  readonly types: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
@@ -4763,6 +4766,12 @@ export declare const ENTITIES: {
4763
4766
  readonly project: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4764
4767
  readonly project_key: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4765
4768
  readonly project_name: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4769
+ readonly created_by: v.OptionalSchema<v.NullableSchema<v.StrictObjectSchema<{
4770
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
4771
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4772
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4773
+ readonly owner: v.BooleanSchema<undefined>;
4774
+ }, undefined>, undefined>, undefined>;
4766
4775
  readonly account: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4767
4776
  readonly chat: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>, undefined>;
4768
4777
  readonly source_message: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>, undefined>;
@@ -4833,6 +4842,12 @@ export declare const ENTITIES: {
4833
4842
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
4834
4843
  readonly project_key: v.StringSchema<undefined>;
4835
4844
  readonly project_name: v.StringSchema<undefined>;
4845
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
4846
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
4847
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4848
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4849
+ readonly owner: v.BooleanSchema<undefined>;
4850
+ }, undefined>, undefined>;
4836
4851
  readonly title: v.StringSchema<undefined>;
4837
4852
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4838
4853
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -4939,6 +4954,12 @@ export declare const ENTITIES: {
4939
4954
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
4940
4955
  readonly project_key: v.StringSchema<undefined>;
4941
4956
  readonly project_name: v.StringSchema<undefined>;
4957
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
4958
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
4959
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4960
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4961
+ readonly owner: v.BooleanSchema<undefined>;
4962
+ }, undefined>, undefined>;
4942
4963
  readonly title: v.StringSchema<undefined>;
4943
4964
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4944
4965
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -5046,6 +5067,12 @@ export declare const ENTITIES: {
5046
5067
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
5047
5068
  readonly project_key: v.StringSchema<undefined>;
5048
5069
  readonly project_name: v.StringSchema<undefined>;
5070
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
5071
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
5072
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
5073
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5074
+ readonly owner: v.BooleanSchema<undefined>;
5075
+ }, undefined>, undefined>;
5049
5076
  readonly title: v.StringSchema<undefined>;
5050
5077
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5051
5078
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -5181,6 +5208,12 @@ export declare const ENTITIES: {
5181
5208
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
5182
5209
  readonly project_key: v.StringSchema<undefined>;
5183
5210
  readonly project_name: v.StringSchema<undefined>;
5211
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
5212
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
5213
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
5214
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5215
+ readonly owner: v.BooleanSchema<undefined>;
5216
+ }, undefined>, undefined>;
5184
5217
  readonly title: v.StringSchema<undefined>;
5185
5218
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5186
5219
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -5281,6 +5314,12 @@ export declare const ENTITIES: {
5281
5314
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
5282
5315
  readonly project_key: v.StringSchema<undefined>;
5283
5316
  readonly project_name: v.StringSchema<undefined>;
5317
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
5318
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
5319
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
5320
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5321
+ readonly owner: v.BooleanSchema<undefined>;
5322
+ }, undefined>, undefined>;
5284
5323
  readonly title: v.StringSchema<undefined>;
5285
5324
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5286
5325
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -42,7 +42,7 @@ import { inviteLink } from "./invite-link.js";
42
42
  import { job } from "./job.js";
43
43
  import { joinRequest } from "./join-request.js";
44
44
  import { organization, project, reminder } from "./knowledge-lists.js";
45
- import { botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, callRecord, scheduledJob, stickerInventory, } from "./list-results.js";
45
+ import { botAdmin, botMenuEntry, botProfile, botSeenChat, botTemplate, botWebhook, callRecord, scheduledJob, stickerInventory, topicIcon, } from "./list-results.js";
46
46
  import { messageEvent, serveSummary, watchedMessage, watchItem } from "./listener.js";
47
47
  import { mediaArchive, mediaArchiveCheck, mediaArchiveMove, mediaArchiveTimer } from "./media-archive.js";
48
48
  import { event, meeting, meetingDetails, meetingHit, meetingLink, meetingParticipants, meetingPassage, meetingProjectEvidence, meetingReview, meetingSpeaker, meetingStats, meetingSummary, meetingTranscript, } from "./meeting.js";
@@ -94,7 +94,7 @@ import { topic } from "./topic.js";
94
94
  * subset of its fields, never a renamed one. Commands move onto these one by one; until then, a schema
95
95
  * is the target, not a description of today's output.
96
96
  */
97
- 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, 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, organization, person, place, poll, pollChange, pollVote, project, ranking, reaction, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, reminder, 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, storeTable, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
97
+ 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, 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, organization, person, place, poll, pollChange, pollVote, project, ranking, reaction, reactionChange, recipient, recipientAdded, recipientChange, recipientOff, recipientRemoved, recordedRun, reference, relationship, reminder, 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, storeTable, tagChange, tagging, task, taskCard, taskCategories, taskClosed, taskCreated, taskLinks, taskMerge, taskPair, taskScan, taskSimilar, taskStats, taskUnmerge, topic, topicIcon, trackedChat, trackedChatHistory, watchedMessage, watchItem, };
98
98
  export const ENTITIES = {
99
99
  sync_progress: syncProgress,
100
100
  ...MEETING_RESULT_ENTITIES,
@@ -183,6 +183,7 @@ export const ENTITIES = {
183
183
  bot_seen_chat: botSeenChat,
184
184
  bot_admin: botAdmin,
185
185
  bot_menu_entry: botMenuEntry,
186
+ topic_icon: topicIcon,
186
187
  bot_webhook: botWebhook,
187
188
  scheduled_job: scheduledJob,
188
189
  call_record: callRecord,
@@ -37,6 +37,9 @@ export declare const botMenuEntry: v.StrictObjectSchema<{
37
37
  readonly name: v.StringSchema<undefined>;
38
38
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
39
39
  }, undefined>;
40
+ export declare const topicIcon: v.StrictObjectSchema<{
41
+ readonly emoji: v.StringSchema<undefined>;
42
+ }, undefined>;
40
43
  export declare const botWebhook: v.StrictObjectSchema<{
41
44
  readonly url: v.StringSchema<undefined>;
42
45
  readonly types: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
@@ -26,6 +26,7 @@ export const botAdmin = v.strictObject({
26
26
  title: v.nullable(text),
27
27
  });
28
28
  export const botMenuEntry = v.strictObject({ name: text, description: v.nullable(text) });
29
+ export const topicIcon = v.strictObject({ emoji: text });
29
30
  export const botWebhook = v.strictObject({ url: text, types: v.optional(v.array(text)) });
30
31
  export const scheduledJob = v.strictObject({
31
32
  name: text,
@@ -6,6 +6,12 @@ export declare const taskCard: v.StrictObjectSchema<{
6
6
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
7
7
  readonly project_key: v.StringSchema<undefined>;
8
8
  readonly project_name: v.StringSchema<undefined>;
9
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
10
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
11
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
12
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
13
+ readonly owner: v.BooleanSchema<undefined>;
14
+ }, undefined>, undefined>;
9
15
  readonly title: v.StringSchema<undefined>;
10
16
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
11
17
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -112,6 +118,12 @@ export declare const taskCreated: v.StrictObjectSchema<{
112
118
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
113
119
  readonly project_key: v.StringSchema<undefined>;
114
120
  readonly project_name: v.StringSchema<undefined>;
121
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
122
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
123
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
124
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
125
+ readonly owner: v.BooleanSchema<undefined>;
126
+ }, undefined>, undefined>;
115
127
  readonly title: v.StringSchema<undefined>;
116
128
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
117
129
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -219,6 +231,12 @@ export declare const taskLinks: v.UnionSchema<[v.StrictObjectSchema<{
219
231
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
220
232
  readonly project_key: v.StringSchema<undefined>;
221
233
  readonly project_name: v.StringSchema<undefined>;
234
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
235
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
236
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
237
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
238
+ readonly owner: v.BooleanSchema<undefined>;
239
+ }, undefined>, undefined>;
222
240
  readonly title: v.StringSchema<undefined>;
223
241
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
224
242
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -354,6 +372,12 @@ export declare const taskMerge: v.StrictObjectSchema<{
354
372
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
355
373
  readonly project_key: v.StringSchema<undefined>;
356
374
  readonly project_name: v.StringSchema<undefined>;
375
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
376
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
377
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
378
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
379
+ readonly owner: v.BooleanSchema<undefined>;
380
+ }, undefined>, undefined>;
357
381
  readonly title: v.StringSchema<undefined>;
358
382
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
359
383
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -454,6 +478,12 @@ export declare const taskUnmerge: v.StrictObjectSchema<{
454
478
  readonly project: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
455
479
  readonly project_key: v.StringSchema<undefined>;
456
480
  readonly project_name: v.StringSchema<undefined>;
481
+ readonly created_by: v.NullableSchema<v.StrictObjectSchema<{
482
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
483
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
484
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
485
+ readonly owner: v.BooleanSchema<undefined>;
486
+ }, undefined>, undefined>;
457
487
  readonly title: v.StringSchema<undefined>;
458
488
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
459
489
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
@@ -27,6 +27,7 @@ export const taskCard = v.strictObject({
27
27
  project: reference,
28
28
  project_key: text,
29
29
  project_name: text,
30
+ created_by: v.nullable(v.strictObject({ type: v.picklist(["person", "bot"]), id, name: v.nullable(text), owner: v.boolean() })),
30
31
  title: text,
31
32
  description: v.nullable(text),
32
33
  type: v.picklist(TASK_TYPES),
@@ -22,6 +22,13 @@ export declare const task: v.StrictObjectSchema<{
22
22
  /** The project's key and name, as `tasks counts` names it. */
23
23
  readonly project_key: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
24
24
  readonly project_name: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
25
+ /** Who added it: the owner, or an agent by its bot name. */
26
+ readonly created_by: v.OptionalSchema<v.NullableSchema<v.StrictObjectSchema<{
27
+ readonly type: v.PicklistSchema<["person", "bot"], undefined>;
28
+ readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
29
+ readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
30
+ readonly owner: v.BooleanSchema<undefined>;
31
+ }, undefined>, undefined>, undefined>;
25
32
  readonly account: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
26
33
  /** The chat it came from, as a `chat:` reference. */
27
34
  readonly chat: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>, undefined>;
@@ -25,6 +25,8 @@ export const task = v.strictObject({
25
25
  /** The project's key and name, as `tasks counts` names it. */
26
26
  project_key: v.optional(v.nullable(text)),
27
27
  project_name: v.optional(v.nullable(text)),
28
+ /** Who added it: the owner, or an agent by its bot name. */
29
+ created_by: v.optional(v.nullable(v.strictObject({ type: v.picklist(["person", "bot"]), id, name: v.nullable(text), owner: v.boolean() }))),
28
30
  account: v.optional(text),
29
31
  /** The chat it came from, as a `chat:` reference. */
30
32
  chat: v.optional(v.nullable(reference)),
@@ -133,6 +133,7 @@ const OTHERS = [
133
133
  ["task.stale", "configuration_error", "the task changed since it was read; read it again"],
134
134
  validation("task.column", "the task beside which it moves is in another column than the status asked for"),
135
135
  validation("task.dependency-cycle", "the task would depend on itself"),
136
+ validation("task.has-subtasks", "the task has subtasks; move or detach them before it moves to another project"),
136
137
  validation("task.duplicate-candidates", "open tasks may be the same job: attach to one, or add it as new"),
137
138
  validation("task.certainty-required", "an agent closes a task with its certainty, 0 to 1"),
138
139
  ["task.pair-decided", "permission_error", "the owner already decided the pair; an agent does not change it"],
@@ -0,0 +1,2 @@
1
+ import type { AccountKey } from "../store/index.js";
2
+ export declare const mailAccountKey: (address: string) => AccountKey;
@@ -0,0 +1 @@
1
+ export const mailAccountKey = (address) => ({ provider: "email", account: address.toLowerCase() });