@wirecat/cli-core 0.378.0 → 0.380.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 +73 -0
- package/dist/cli/envelope.d.ts +10 -0
- package/dist/cli/list-query.js +2 -2
- package/dist/cli/meeting-preparation-answer.d.ts +5 -0
- package/dist/cli/meeting-preparation-projects.d.ts +5 -0
- package/dist/cli/meeting-preparation-read.d.ts +5 -0
- package/dist/cli/meeting-preparation-read.js +5 -5
- package/dist/cli/meeting-series-inventory-read.js +3 -4
- package/dist/cli/messenger/chats-stats-command.js +5 -1
- package/dist/cli/messenger/contacts-command.js +8 -4
- package/dist/cli/messenger/stats-answers.d.ts +2 -1
- package/dist/cli/messenger/stats-answers.js +1 -1
- package/dist/cli/messenger/stats-command.js +4 -7
- package/dist/domain/moment.d.ts +8 -0
- package/dist/domain/moment.js +14 -0
- package/dist/domain/send-time.d.ts +2 -2
- package/dist/domain/send-time.js +4 -3
- package/dist/entities/account-session.d.ts +2 -2
- package/dist/entities/admin-report.d.ts +8 -8
- package/dist/entities/agenda.d.ts +12 -12
- package/dist/entities/chat-event.d.ts +1 -1
- package/dist/entities/chat-stats.d.ts +5 -5
- package/dist/entities/chat.d.ts +4 -4
- package/dist/entities/contact-note.d.ts +2 -2
- package/dist/entities/contact.d.ts +13 -13
- package/dist/entities/conversation.d.ts +3 -3
- package/dist/entities/counter-reading.d.ts +1 -1
- package/dist/entities/counters.d.ts +2 -2
- package/dist/entities/document.d.ts +2 -2
- package/dist/entities/evidence.d.ts +72 -72
- package/dist/entities/fact.d.ts +3 -3
- package/dist/entities/fields.d.ts +3 -1
- package/dist/entities/fields.js +2 -0
- package/dist/entities/hit.d.ts +1 -1
- package/dist/entities/index.d.ts +231 -215
- package/dist/entities/index.js +1 -0
- package/dist/entities/invite-link.d.ts +1 -1
- package/dist/entities/job.d.ts +2 -2
- package/dist/entities/join-request.d.ts +1 -1
- package/dist/entities/meeting-communications.d.ts +4 -4
- package/dist/entities/meeting-findings.d.ts +2 -2
- package/dist/entities/meeting-preparation-parts.d.ts +9 -9
- package/dist/entities/meeting-preparation.d.ts +28 -23
- package/dist/entities/meeting-series-inventory.d.ts +3 -3
- package/dist/entities/member.d.ts +3 -3
- package/dist/entities/memory.d.ts +3 -3
- package/dist/entities/message.d.ts +6 -6
- package/dist/entities/note.d.ts +3 -3
- package/dist/entities/official-stats.d.ts +2 -2
- package/dist/entities/poll-vote.d.ts +1 -1
- package/dist/entities/ranking.d.ts +2 -2
- package/dist/entities/relationship.d.ts +1 -1
- package/dist/entities/retention.d.ts +4 -4
- package/dist/entities/saved-search.d.ts +2 -2
- package/dist/entities/tagging.d.ts +1 -1
- package/dist/entities/task.d.ts +7 -7
- package/dist/entities/topic.d.ts +2 -2
- package/dist/mcp/meeting-preparation.d.ts +5 -0
- package/dist/mcp/tools/stats.js +9 -4
- package/dist/meetings/answers.d.ts +20 -14
- package/dist/meetings/answers.js +5 -0
- package/dist/meetings/cli/index.d.ts +2 -0
- package/dist/meetings/cli/index.js +12 -6
- package/dist/meetings/cli/search.js +12 -14
- package/dist/meetings/hit-query.d.ts +12 -0
- package/dist/meetings/hit-query.js +58 -0
- package/dist/meetings/import.d.ts +2 -0
- package/dist/meetings/import.js +8 -2
- package/dist/meetings/index.d.ts +2 -0
- package/dist/meetings/index.js +2 -0
- package/dist/meetings/item.d.ts +4 -4
- package/dist/meetings/mcp/search.d.ts +6 -0
- package/dist/meetings/mcp/search.js +5 -1
- package/dist/meetings/project-evidence-answer.d.ts +8 -3
- package/dist/meetings/pull.d.ts +2 -0
- package/dist/meetings/recording-schedule.js +6 -5
- package/dist/meetings/search-store.d.ts +3 -1
- package/dist/meetings/store.d.ts +7 -0
- package/dist/meetings/transcript-text.d.ts +20 -0
- package/dist/meetings/transcript-text.js +59 -0
- package/dist/render/markdown.js +2 -2
- package/dist/search/garbled.d.ts +29 -0
- package/dist/search/garbled.js +125 -0
- package/dist/search/russian-dictionary.d.ts +5 -0
- package/dist/search/russian-dictionary.js +66 -0
- package/dist/services/admin-statistics.js +2 -2
- package/dist/services/meeting-project-discovery.js +2 -2
- package/dist/services/moment.d.ts +25 -2
- package/dist/services/moment.js +32 -4
- package/dist/services/retention.js +6 -3
- package/dist/store/sqlite/facts.js +2 -1
- package/dist/store/sqlite/meeting-hit-query.d.ts +60 -0
- package/dist/store/sqlite/meeting-hit-query.js +262 -0
- package/dist/store/sqlite/meeting-hit-search.js +28 -45
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,79 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
|
|
|
5
5
|
minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
|
|
6
6
|
shape of this file.
|
|
7
7
|
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
## 0.380.0 — 21.10.2026
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Meetings import text transcripts.** `parseTranscriptText` reads the text form zoom-searcher wrote: the header
|
|
15
|
+
(`Встреча:` title, `Дата:` start as written, `Zoom ID:`, `Говорят:` speakers) and `[hh:mm:ss] Speaker: text`
|
|
16
|
+
blocks, a block running over several lines. `ImportFile.format: "text"` makes `importFiles` use it; `vtt` stays
|
|
17
|
+
the default. The file keeps start times only, so a line ends where the next begins.
|
|
18
|
+
- **An import says the zone it read file times in, and a host can explain its file names.** `RunReport.timezone` is
|
|
19
|
+
set when every imported file's meeting carries one zone; `MeetingCommandDeps.importHelp` adds the host's note
|
|
20
|
+
(file name patterns, how their time is read) under `meetings import --help`.
|
|
21
|
+
- **Meeting search finds words spread over neighbouring lines.** `"циан риелтор"~3` in a meeting query finds a
|
|
22
|
+
transcript line with one of the words when the others are at most three lines away in the same transcript; `~0`
|
|
23
|
+
is one line, any order; at most 20. The words widen to garbled spellings as single words do. It needs
|
|
24
|
+
`@wirecat/cli-base` 0.49.0 (`parseLucene({ proximity: true })`), now the pinned version and the peer range.
|
|
25
|
+
See [query language](docs/search/query-language.md#встречи).
|
|
26
|
+
|
|
27
|
+
- **Meeting search finds words speech recognition garbled.** `meetings.searchHits` widens each query word of four
|
|
28
|
+
letters or more to stored words one stem edit away that a Russian dictionary does not know, and to stems one side
|
|
29
|
+
extends, so «риелтор» finds «реелтора», «рилторов» and «дриелтора», «циана» finds «цианом», and «договор» does not
|
|
30
|
+
find «поговорить». Hits come typed form first, then other forms, then garbled spellings; a widened hit carries `match: "corrected"` and `corrections`, and `meeting_hit` items show both. Number words never
|
|
31
|
+
widen, and match only their own forms («семь» finds «семи», not «семьдесят»). See [meetings](docs/dev/MEETINGS.md).
|
|
32
|
+
- **Answers say which zone a typed date was read in, and the UTC window it gave** (cli-base `WC-TIME-3`, `WC-TIME-5`).
|
|
33
|
+
`stats charts`, the MCP `stats` tool and `contacts timeline` put `meta.timezone` (only when a value had no zone of
|
|
34
|
+
its own) and `meta.window: { since?, until? }` in UTC in their answers. `dateWindow` in `./cli`'s moment helpers
|
|
35
|
+
builds both from `--since-time`/`--until-time`. Other date filters follow.
|
|
36
|
+
|
|
37
|
+
### Changed — may break callers
|
|
38
|
+
|
|
39
|
+
- **Meeting search reads the messages query language.** `meetings.searchHits`, `search meetings` and MCP
|
|
40
|
+
`search_meetings` take `OR`, `(groups)`, `NOT`/`-word`, `"phrases"` (neighbouring words, any form), `exact:` and
|
|
41
|
+
`from:"Name"` — who said the line or wrote the chat message, a person through all their linked identities; an
|
|
42
|
+
ambiguous name is an error with the candidates. `:`, `(`, `"`, `-` and `AND`/`OR`/`NOT` in a meeting query are
|
|
43
|
+
now syntax, and a query of punctuation alone is a `validation_error`. `searchHits` also takes a `QueryAst`;
|
|
44
|
+
`meetingWordsQuery(text)` builds one from text that must stay plain words, as project discovery now does.
|
|
45
|
+
`MEETING_HIT_QUERY` and `parseMeetingQuery` are exported. See [query language](docs/search/query-language.md#встречи).
|
|
46
|
+
|
|
47
|
+
- **Meeting search reads `exact:` and has new cursors.** `exact:word` and `exact:"two words"` in a
|
|
48
|
+
`meetings.searchHits` query keep those words to their typed form, where `exact` was a search word before. Exact
|
|
49
|
+
hits now come before widened ones, so cursors from earlier versions are refused; start the search again.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **A recording archive schedule counts "today" in its own zone.** The window's end, its ten-year floor and its
|
|
54
|
+
look-back started from the UTC date, so a run between local midnight and UTC midnight worked on yesterday. The
|
|
55
|
+
schedule's `timeZone` was stored and never used for this.
|
|
56
|
+
- **A Markdown chat archive says which zone its times are in.** The file printed local wall times with no zone; it
|
|
57
|
+
now has `Times are in <zone>.` under the title.
|
|
58
|
+
- **`chats stats show` and `stats chats retention` read `--since-time`/`--until-time` in their `--timezone`.** They
|
|
59
|
+
used the computer's zone even when `--timezone` was given, and retention's `--until-time` dropped the day it named;
|
|
60
|
+
it now covers that whole local day.
|
|
61
|
+
|
|
62
|
+
## 0.379.0 — 21.10.2026
|
|
63
|
+
|
|
64
|
+
### Changed — may break callers
|
|
65
|
+
|
|
66
|
+
- **A typed date or time is read in a zone, and a date alone covers the whole local day** (cli-base `WC-TIME-3`,
|
|
67
|
+
`WC-TIME-5`). `--since-time`, `--until-time`, `--at-time`, `--due`, `--remind-time`, `chats mute --until`, fact
|
|
68
|
+
`occurredAt`, `meetings sync --since-time` and `search meetings --since-time`/`--until-time` used `Date.parse`: a date
|
|
69
|
+
alone was UTC midnight, a time without a zone was the process zone, and `--timezone` was ignored. Now a zone the
|
|
70
|
+
value names wins; otherwise the command's `--timezone` (stats, admin statistics, the MCP `stats` tool), else the
|
|
71
|
+
computer's IANA zone. A date alone starts at local midnight; as an end (`--until-time`) it is the last millisecond
|
|
72
|
+
of that local day, so the day is no longer dropped. A local time that daylight saving skips or repeats is refused.
|
|
73
|
+
List-query `time` terms (`timeBounds`) default to the computer's zone, not UTC. What to watch for: `momentOf` and
|
|
74
|
+
`aheadOf` keep their signature and take an optional `{ zone, end }`; a caller that passed a date alone and expected
|
|
75
|
+
UTC midnight now gets local midnight. `search meetings` now takes a time without an offset instead of refusing it.
|
|
76
|
+
The answers do not name the zone used yet (`meta.timezone`); that follows.
|
|
77
|
+
- **cli-base 0.48.0.** `isoTime` refuses offsets other than `Z`; two input schemas that take a caller's time with any
|
|
78
|
+
offset (meeting preparation, meeting series inventory) use the new `zonedTime` instead. The peer range moves to
|
|
79
|
+
`>=0.48.0 <0.49.0`, and `node-ci.yml` runs the tests in `Asia/Vladivostok`.
|
|
80
|
+
|
|
8
81
|
## 0.378.0 — 21.10.2026
|
|
9
82
|
|
|
10
83
|
### Added
|
package/dist/cli/envelope.d.ts
CHANGED
|
@@ -84,6 +84,11 @@ export declare const answerSchema: (item?: v.GenericSchema) => v.UnionSchema<[v.
|
|
|
84
84
|
readonly source: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
85
85
|
}, undefined>, undefined>, undefined>;
|
|
86
86
|
readonly truncated: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
87
|
+
readonly timezone: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>;
|
|
88
|
+
readonly window: v.OptionalSchema<v.StrictObjectSchema<{
|
|
89
|
+
readonly 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>;
|
|
90
|
+
readonly until: 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>;
|
|
91
|
+
}, undefined>, undefined>;
|
|
87
92
|
}, undefined>;
|
|
88
93
|
}, undefined>, v.StrictObjectSchema<{
|
|
89
94
|
readonly item: v.GenericSchema;
|
|
@@ -132,6 +137,11 @@ export declare const answerSchema: (item?: v.GenericSchema) => v.UnionSchema<[v.
|
|
|
132
137
|
readonly source: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
133
138
|
}, undefined>, undefined>, undefined>;
|
|
134
139
|
readonly truncated: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
140
|
+
readonly timezone: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>;
|
|
141
|
+
readonly window: v.OptionalSchema<v.StrictObjectSchema<{
|
|
142
|
+
readonly 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>;
|
|
143
|
+
readonly until: 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>;
|
|
144
|
+
}, undefined>, undefined>;
|
|
135
145
|
}, undefined>;
|
|
136
146
|
}, undefined>], undefined>;
|
|
137
147
|
/**
|
package/dist/cli/list-query.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
2
|
-
import { dateRange, defineQuery, fieldsHelp, fieldsNamed, OPERATORS_BY_TYPE, parseLucene, QUERY_LIMITS, queryError, queryFieldsOf, validateQuery, } from "@wirecat/cli-base/query";
|
|
2
|
+
import { dateRange, defineQuery, fieldsHelp, fieldsNamed, OPERATORS_BY_TYPE, parseLucene, QUERY_LIMITS, queryError, queryFieldsOf, timezoneOf, validateQuery, } from "@wirecat/cli-base/query";
|
|
3
3
|
import * as v from "valibot";
|
|
4
4
|
import { queryWordsAfterOptions } from "../meetings/cli/index.js";
|
|
5
5
|
import { listOf } from "./envelope.js";
|
|
@@ -131,7 +131,7 @@ export const queryTerms = (words, registry, command) => {
|
|
|
131
131
|
return terms;
|
|
132
132
|
};
|
|
133
133
|
/** A `time` term as epoch ms bounds: `time>=7d`, `time:[2026-10-01 TO 2026-10-07]`, `time:today`. */
|
|
134
|
-
export const timeBounds = (term, zone =
|
|
134
|
+
export const timeBounds = (term, zone = timezoneOf()) => {
|
|
135
135
|
if (!term)
|
|
136
136
|
return {};
|
|
137
137
|
const upper = term.operator === "range" ? (term.upper ?? "*") : term.value;
|
|
@@ -309,6 +309,11 @@ export declare const meetingPreparationAnswer: (packet: MeetingPreparation) => i
|
|
|
309
309
|
id: string;
|
|
310
310
|
excerpt: string;
|
|
311
311
|
offset_ms: number | null;
|
|
312
|
+
match?: "corrected" | "words" | undefined;
|
|
313
|
+
corrections?: {
|
|
314
|
+
from: string;
|
|
315
|
+
to: string[];
|
|
316
|
+
}[] | undefined;
|
|
312
317
|
source?: {
|
|
313
318
|
ref: string;
|
|
314
319
|
title: string | null;
|
|
@@ -29,6 +29,11 @@ export declare const mapPreparationProjectEvidence: (section: NonNullable<Meetin
|
|
|
29
29
|
id: string;
|
|
30
30
|
excerpt: string;
|
|
31
31
|
offset_ms: number | null;
|
|
32
|
+
match?: "corrected" | "words" | undefined;
|
|
33
|
+
corrections?: {
|
|
34
|
+
from: string;
|
|
35
|
+
to: string[];
|
|
36
|
+
}[] | undefined;
|
|
32
37
|
source?: {
|
|
33
38
|
ref: string;
|
|
34
39
|
title: string | null;
|
|
@@ -338,6 +338,11 @@ export declare const readMeetingPreparation: (read: MeetingPreparationReader, in
|
|
|
338
338
|
id: string;
|
|
339
339
|
excerpt: string;
|
|
340
340
|
offset_ms: number | null;
|
|
341
|
+
match?: "corrected" | "words" | undefined;
|
|
342
|
+
corrections?: {
|
|
343
|
+
from: string;
|
|
344
|
+
to: string[];
|
|
345
|
+
}[] | undefined;
|
|
341
346
|
source?: {
|
|
342
347
|
ref: string;
|
|
343
348
|
title: string | null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
|
-
import { isoTime } from "@wirecat/cli-base/standards";
|
|
3
2
|
import * as v from "valibot";
|
|
4
3
|
import { communicationFields } from "../context/communication-selection.js";
|
|
4
|
+
import { zonedTime } from "../entities/index.js";
|
|
5
5
|
import { validateMeetingChange } from "../meetings/index.js";
|
|
6
6
|
import { MEETING_PREPARATION_LIMITS, validateMeetingPreparationRequest, } from "../services/index.js";
|
|
7
7
|
import { validatePreparationCommunications } from "../services/meeting-communications-selection.js";
|
|
@@ -12,11 +12,11 @@ const bound = (name) => {
|
|
|
12
12
|
};
|
|
13
13
|
export const meetingPreparationInput = v.strictObject({
|
|
14
14
|
series_id: v.pipe(v.string(), v.minLength(1), v.maxLength(1000)),
|
|
15
|
-
communications: v.optional(v.strictObject({ ...communicationFields, after: v.optional(
|
|
15
|
+
communications: v.optional(v.strictObject({ ...communicationFields, after: v.optional(zonedTime), before: v.optional(zonedTime) })),
|
|
16
16
|
project: v.optional(v.pipe(v.string(), v.minLength(1), v.maxLength(200))),
|
|
17
|
-
after: v.optional(
|
|
18
|
-
until: v.optional(
|
|
19
|
-
history_after: v.optional(
|
|
17
|
+
after: v.optional(zonedTime),
|
|
18
|
+
until: v.optional(zonedTime),
|
|
19
|
+
history_after: v.optional(zonedTime),
|
|
20
20
|
meetings: bound("meetings"),
|
|
21
21
|
cues: bound("cues"),
|
|
22
22
|
context_limit: bound("contextLimit"),
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
|
-
import { isoTime } from "@wirecat/cli-base/standards";
|
|
3
2
|
import * as v from "valibot";
|
|
4
|
-
import { meetingSeriesInventory } from "../entities/index.js";
|
|
3
|
+
import { meetingSeriesInventory, zonedTime } from "../entities/index.js";
|
|
5
4
|
import { validateMeetingChange, validateMeetingSeriesInventoryCursor, } from "../meetings/index.js";
|
|
6
5
|
import { itemOf, metaNow, sealed, snakeKeys } from "./envelope.js";
|
|
7
6
|
const bounded = (min, max) => v.optional(v.pipe(v.number(), v.integer(), v.minValue(min), v.maxValue(max)));
|
|
8
7
|
export const meetingSeriesInventoryInput = v.strictObject({
|
|
9
|
-
after: v.optional(
|
|
10
|
-
until: v.optional(
|
|
8
|
+
after: v.optional(zonedTime),
|
|
9
|
+
until: v.optional(zonedTime),
|
|
11
10
|
limit: bounded(1, 100),
|
|
12
11
|
max_read_bytes: bounded(1, 1048576),
|
|
13
12
|
bytes: bounded(2048, 1048576),
|
|
@@ -21,7 +21,11 @@ export const statsCommand = (messenger) => annotate(new Command("show"), { effec
|
|
|
21
21
|
refuseJsonl(context.format);
|
|
22
22
|
const { stats, account } = await context.withServices(async (services) => ({
|
|
23
23
|
stats: await services.chats.stats(chat, {
|
|
24
|
-
...(sinceTime === undefined
|
|
24
|
+
...(sinceTime === undefined
|
|
25
|
+
? {}
|
|
26
|
+
: {
|
|
27
|
+
since: momentOf(sinceTime, "--since-time", Date.now(), timezone === undefined ? {} : { zone: timezone }),
|
|
28
|
+
}),
|
|
25
29
|
...(by ? { by } : {}),
|
|
26
30
|
...(timezone === undefined ? {} : { timezone }),
|
|
27
31
|
}),
|
|
@@ -4,7 +4,7 @@ import { Command } from "commander";
|
|
|
4
4
|
import { REGISTRIES, registriesCover } from "../../botcheck/registries.js";
|
|
5
5
|
import { levelFor } from "../../sends/permissions.js";
|
|
6
6
|
import { phoneOf } from "../../services/index.js";
|
|
7
|
-
import { momentOf } from "../../services/moment.js";
|
|
7
|
+
import { dateWindow, momentOf } from "../../services/moment.js";
|
|
8
8
|
import { maskedAccount } from "../../services/people.js";
|
|
9
9
|
import { CHAT_MESSAGES, CONTEXT_BYTES, CONTEXT_MESSAGES } from "../../services/person-context.js";
|
|
10
10
|
import { SCOPES, TIMELINE_ITEMS } from "../../services/person-timeline.js";
|
|
@@ -150,10 +150,14 @@ export const contactsCommand = (messenger) => {
|
|
|
150
150
|
if (scope !== undefined && !SCOPES.includes(scope))
|
|
151
151
|
throw new CliError("validation_error", `--scope is personal or work, not "${scope}"`);
|
|
152
152
|
const context = messengerContext(this, messenger);
|
|
153
|
+
const window = dateWindow({
|
|
154
|
+
...(sinceTime === undefined ? {} : { sinceTime }),
|
|
155
|
+
...(untilTime === undefined ? {} : { untilTime }),
|
|
156
|
+
});
|
|
153
157
|
const found = await context.withServices((services) => services.people.timeline(person, {
|
|
154
158
|
...(scope === undefined ? {} : { scope: scope }),
|
|
155
|
-
...(
|
|
156
|
-
...(
|
|
159
|
+
...(window.since === undefined ? {} : { since: window.since }),
|
|
160
|
+
...(window.until === undefined ? {} : { until: window.until }),
|
|
157
161
|
...(limit === undefined ? {} : { limit }),
|
|
158
162
|
...(cursor === undefined ? {} : { cursor }),
|
|
159
163
|
}));
|
|
@@ -170,7 +174,7 @@ export const contactsCommand = (messenger) => {
|
|
|
170
174
|
...(sinceTime === undefined ? {} : { since_time: sinceTime }),
|
|
171
175
|
...(untilTime === undefined ? {} : { until_time: untilTime }),
|
|
172
176
|
},
|
|
173
|
-
...(pending > 0 ? {
|
|
177
|
+
meta: { ...window.meta, ...(pending > 0 ? { truncated: true } : {}) },
|
|
174
178
|
}));
|
|
175
179
|
});
|
|
176
180
|
annotate(contacts.command("check"), { effects: REMOTE_READ })
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Meta } from "@wirecat/cli-base/standards";
|
|
1
2
|
import type { InferOutput } from "valibot";
|
|
2
3
|
import type { ChartData } from "../../charts/model.js";
|
|
3
4
|
import type { CounterState } from "../../domain/counters.js";
|
|
@@ -62,7 +63,7 @@ export declare const chartAnswer: (chart: ChartData, file?: {
|
|
|
62
63
|
format: "svg" | "png";
|
|
63
64
|
width: number;
|
|
64
65
|
height: number;
|
|
65
|
-
}) => ItemBody<Of<"chart">>;
|
|
66
|
+
}, meta?: Partial<Meta>) => ItemBody<Of<"chart">>;
|
|
66
67
|
/** A report or a chart is one object: `--jsonl` would print one line pretending to be a stream. */
|
|
67
68
|
export declare const refuseJsonl: (format: string) => void;
|
|
68
69
|
/** `stats chats show`, CLI and MCP alike; a chat the store does not hold whole names the sync that fills it. */
|
|
@@ -326,7 +326,7 @@ export const officialAnswer = (stats, provider) => {
|
|
|
326
326
|
graphs: stats.graphs,
|
|
327
327
|
}));
|
|
328
328
|
};
|
|
329
|
-
export const chartAnswer = (chart, file) => itemOf(defined({ ...chart, file }));
|
|
329
|
+
export const chartAnswer = (chart, file, meta) => itemOf(defined({ ...chart, file }), meta ? { meta } : {});
|
|
330
330
|
/** A report or a chart is one object: `--jsonl` would print one line pretending to be a stream. */
|
|
331
331
|
export const refuseJsonl = (format) => {
|
|
332
332
|
if (format === "jsonl")
|
|
@@ -9,7 +9,7 @@ import { CHART_SIZE } from "../../charts/model.js";
|
|
|
9
9
|
import { chartPng } from "../../charts/png.js";
|
|
10
10
|
import { chartRenderer } from "../../charts/render.js";
|
|
11
11
|
import { EVENTS_DAYS } from "../../services/chats.js";
|
|
12
|
-
import {
|
|
12
|
+
import { dateWindow } from "../../services/moment.js";
|
|
13
13
|
import { destroysNothing, LOCAL_WRITE } from "../effects.js";
|
|
14
14
|
import { renderAnswer } from "../envelope.js";
|
|
15
15
|
import { adminStatisticsCommand } from "./admin-statistics-command.js";
|
|
@@ -61,11 +61,8 @@ export const statsCommand = (messenger, loadRenderer = chartRenderer) => {
|
|
|
61
61
|
throw new CliError("validation_error", "--output takes a .svg or .png file; image output to stdout is unavailable");
|
|
62
62
|
}
|
|
63
63
|
const timezone = timezoneOf(given);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
timezone,
|
|
67
|
-
...(sinceTime === undefined ? {} : { since: momentOf(sinceTime, "--since-time") }),
|
|
68
|
-
}));
|
|
64
|
+
const window = dateWindow({ ...(sinceTime === undefined ? {} : { sinceTime }), zone: timezone });
|
|
65
|
+
const found = await context.withServices((services) => services.chats.stats(chat, { by, timezone, ...(window.since === undefined ? {} : { since: window.since }) }));
|
|
69
66
|
const chart = chatChart(found, { kind: chartKind, by, timezone });
|
|
70
67
|
let chartFile;
|
|
71
68
|
if (output !== undefined) {
|
|
@@ -85,7 +82,7 @@ export const statsCommand = (messenger, loadRenderer = chartRenderer) => {
|
|
|
85
82
|
}
|
|
86
83
|
if (chart.partial)
|
|
87
84
|
context.renderer.note("partial data — the chart shows lower bounds");
|
|
88
|
-
renderAnswer(this, context, chartAnswer(chart, chartFile));
|
|
85
|
+
renderAnswer(this, context, chartAnswer(chart, chartFile, window.meta));
|
|
89
86
|
});
|
|
90
87
|
return stats;
|
|
91
88
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface MomentZone {
|
|
2
|
+
/** The IANA zone a date or a time without a zone is read in; the computer's zone when left out. */
|
|
3
|
+
zone?: string;
|
|
4
|
+
/** A date alone means the last millisecond of that local day, not its first: the end of a range. */
|
|
5
|
+
end?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** A typed date or time as epoch ms, with the flag named when it is not one. */
|
|
8
|
+
export declare const calendarMoment: (wanted: string, flag: string, { zone, end }?: MomentZone) => number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { timezoneOf, zonedMoment } from "@wirecat/cli-base/query";
|
|
3
|
+
/** A typed date or time as epoch ms, with the flag named when it is not one. */
|
|
4
|
+
export const calendarMoment = (wanted, flag, { zone, end = false } = {}) => {
|
|
5
|
+
try {
|
|
6
|
+
return zonedMoment(wanted, timezoneOf(zone), { start: 0, end: wanted.length }, { end });
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
if (!(error instanceof CliError))
|
|
10
|
+
throw error;
|
|
11
|
+
const alternative = error.details?.alternative;
|
|
12
|
+
throw new CliError("validation_error", `${flag}: "${wanted}" is not a time${alternative ? ` — ${alternative}` : ""}`);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* `--at-time`: a time like `2026-09-25T09:00`, or a delay like `30m`, `2h`, `1d`, as an ISO time — the
|
|
3
3
|
* same words max-cli takes. Rounded down to the minute, because messengers send at the start of it
|
|
4
4
|
* (MAX measured, max-cli `FIND-141`), so the time printed is the time it goes. A time without an
|
|
5
|
-
* offset is
|
|
5
|
+
* offset is read in `zone`, the computer's zone when none is given.
|
|
6
6
|
*/
|
|
7
|
-
export declare const sendTime: (value: string, now?: number, flag?: string) => string;
|
|
7
|
+
export declare const sendTime: (value: string, now?: number, flag?: string, zone?: string) => string;
|
package/dist/domain/send-time.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { calendarMoment } from "./moment.js";
|
|
2
3
|
const MINUTE = 60_000;
|
|
3
4
|
const YEAR = 365 * 24 * 60 * MINUTE;
|
|
4
5
|
const DELAY = /^(\d+)(m|h|d)$/;
|
|
@@ -7,13 +8,13 @@ const UNIT_MS = { m: MINUTE, h: 60 * MINUTE, d: 24 * 60 * MINUTE };
|
|
|
7
8
|
* `--at-time`: a time like `2026-09-25T09:00`, or a delay like `30m`, `2h`, `1d`, as an ISO time — the
|
|
8
9
|
* same words max-cli takes. Rounded down to the minute, because messengers send at the start of it
|
|
9
10
|
* (MAX measured, max-cli `FIND-141`), so the time printed is the time it goes. A time without an
|
|
10
|
-
* offset is
|
|
11
|
+
* offset is read in `zone`, the computer's zone when none is given.
|
|
11
12
|
*/
|
|
12
|
-
export const sendTime = (value, now = Date.now(), flag = "--at-time") => {
|
|
13
|
+
export const sendTime = (value, now = Date.now(), flag = "--at-time", zone) => {
|
|
13
14
|
const trimmed = value.trim();
|
|
14
15
|
const [, amount, unit] = DELAY.exec(trimmed) ?? [];
|
|
15
16
|
const at = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}/.test(trimmed)
|
|
16
|
-
?
|
|
17
|
+
? calendarMoment(trimmed.replace(" ", "T"), flag, zone === undefined ? {} : { zone })
|
|
17
18
|
: amount && unit
|
|
18
19
|
? now + Number(amount) * (UNIT_MS[unit] ?? 0)
|
|
19
20
|
: Number.NaN;
|
|
@@ -5,6 +5,6 @@ export declare const accountSession: v.StrictObjectSchema<{
|
|
|
5
5
|
readonly client: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
6
6
|
readonly device: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
7
7
|
readonly location: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8
|
-
readonly last_active_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
9
|
-
readonly created_at: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
8
|
+
readonly last_active_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
9
|
+
readonly created_at: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>, undefined>;
|
|
10
10
|
}, undefined>;
|
|
@@ -13,8 +13,8 @@ export declare const adminRow: v.StrictObjectSchema<{
|
|
|
13
13
|
readonly median_ms: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
|
|
14
14
|
readonly p90_ms: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
|
|
15
15
|
readonly age_ms: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
16
|
-
readonly joined_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
17
|
-
readonly window_end: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
16
|
+
readonly joined_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>;
|
|
17
|
+
readonly window_end: 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>;
|
|
18
18
|
readonly pending: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
19
19
|
readonly views: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
20
20
|
readonly observed_replies: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
@@ -22,7 +22,7 @@ export declare const adminRow: v.StrictObjectSchema<{
|
|
|
22
22
|
readonly counters: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
23
23
|
readonly counter: v.PicklistSchema<["views", "reactions", "comments"], undefined>;
|
|
24
24
|
readonly value: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
|
|
25
|
-
readonly observed_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
25
|
+
readonly observed_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
26
26
|
readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
27
27
|
readonly age_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
28
28
|
readonly freshness: v.PicklistSchema<["fresh", "stale", "unknown"], undefined>;
|
|
@@ -32,7 +32,7 @@ export declare const adminRow: v.StrictObjectSchema<{
|
|
|
32
32
|
/** One administrator report over stored history: unanswered questions, responses, newcomers or discussion. */
|
|
33
33
|
export declare const adminReport: v.StrictObjectSchema<{
|
|
34
34
|
readonly report: v.PicklistSchema<["unanswered", "responses", "newcomers", "discussion"], undefined>;
|
|
35
|
-
readonly cutoff: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
35
|
+
readonly cutoff: 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`">]>;
|
|
36
36
|
/** Rows the report found; `rows` holds the first `--limit` of them. */
|
|
37
37
|
readonly total: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
38
38
|
readonly summary: v.StrictObjectSchema<{
|
|
@@ -54,7 +54,7 @@ export declare const adminReport: v.StrictObjectSchema<{
|
|
|
54
54
|
readonly archives: v.ArraySchema<v.StrictObjectSchema<{
|
|
55
55
|
readonly chat_ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
56
56
|
readonly state: v.StringSchema<undefined>;
|
|
57
|
-
readonly fetched_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
57
|
+
readonly fetched_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
58
58
|
}, undefined>, undefined>;
|
|
59
59
|
readonly archives_total: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
60
60
|
readonly membership: v.StringSchema<undefined>;
|
|
@@ -74,8 +74,8 @@ export declare const adminReport: v.StrictObjectSchema<{
|
|
|
74
74
|
readonly median_ms: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
|
|
75
75
|
readonly p90_ms: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
|
|
76
76
|
readonly age_ms: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
77
|
-
readonly joined_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
78
|
-
readonly window_end: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
77
|
+
readonly joined_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>;
|
|
78
|
+
readonly window_end: 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>;
|
|
79
79
|
readonly pending: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
80
80
|
readonly views: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
81
81
|
readonly observed_replies: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
@@ -83,7 +83,7 @@ export declare const adminReport: v.StrictObjectSchema<{
|
|
|
83
83
|
readonly counters: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
84
84
|
readonly counter: v.PicklistSchema<["views", "reactions", "comments"], undefined>;
|
|
85
85
|
readonly value: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
|
|
86
|
-
readonly observed_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
86
|
+
readonly observed_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
87
87
|
readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
88
88
|
readonly age_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
89
89
|
readonly freshness: v.PicklistSchema<["fresh", "stale", "unknown"], undefined>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
/** What needs a look today, from the store alone and without one message's text. */
|
|
3
3
|
export declare const agenda: v.StrictObjectSchema<{
|
|
4
|
-
readonly at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
4
|
+
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`">]>;
|
|
5
5
|
readonly account: v.StringSchema<undefined>;
|
|
6
|
-
readonly stored_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
6
|
+
readonly stored_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
7
7
|
/** The store saved nothing for a day: a chat may look quiet only because nothing was synced. */
|
|
8
8
|
readonly stale: v.BooleanSchema<undefined>;
|
|
9
9
|
readonly tasks: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -14,20 +14,20 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
14
14
|
readonly category: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
15
15
|
/** The message or note it came from. */
|
|
16
16
|
readonly source: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
17
|
-
readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
18
|
-
readonly next_check_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
17
|
+
readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
18
|
+
readonly next_check_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
19
19
|
/** Who works on it now; only the asker's own claims are listed unless the query names claimed:. */
|
|
20
20
|
readonly claimed_by: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
21
|
-
readonly claimed_until: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
21
|
+
readonly claimed_until: 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>;
|
|
22
22
|
/** An agent's close waiting on the owner: `tasks close` confirms it, `tasks reject` refuses it. */
|
|
23
23
|
readonly close_suggestion: v.NullableSchema<v.StrictObjectSchema<{
|
|
24
24
|
readonly as: v.PicklistSchema<["done", "dismissed"], undefined>;
|
|
25
25
|
readonly by: v.StringSchema<undefined>;
|
|
26
26
|
readonly certainty: v.NumberSchema<undefined>;
|
|
27
27
|
readonly reason: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
28
|
-
readonly at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
28
|
+
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`">]>;
|
|
29
29
|
}, undefined>, undefined>;
|
|
30
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
30
|
+
readonly created_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`">]>;
|
|
31
31
|
readonly reasons: v.ArraySchema<v.PicklistSchema<["overdue", "due", "check", "unplanned", "close-suggested"], undefined>, undefined>;
|
|
32
32
|
}, undefined>, undefined>;
|
|
33
33
|
/** Someone else wrote last, and the owner has not answered. */
|
|
@@ -37,7 +37,7 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
37
37
|
readonly kind: v.PicklistSchema<["dialog", "group", "channel", "saved", "unknown"], undefined>;
|
|
38
38
|
/** The newest message, never its text; `null` while it is not stored. */
|
|
39
39
|
readonly last_message: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
40
|
-
readonly last_message_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
40
|
+
readonly last_message_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`">]>;
|
|
41
41
|
/** `null` when the newest message is not stored, or the messenger did not say who sent it. */
|
|
42
42
|
readonly last_from_owner: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
43
43
|
/** Open tasks whose source is in this chat. */
|
|
@@ -50,7 +50,7 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
50
50
|
readonly kind: v.PicklistSchema<["dialog", "group", "channel", "saved", "unknown"], undefined>;
|
|
51
51
|
/** The newest message, never its text; `null` while it is not stored. */
|
|
52
52
|
readonly last_message: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
53
|
-
readonly last_message_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
53
|
+
readonly last_message_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`">]>;
|
|
54
54
|
/** `null` when the newest message is not stored, or the messenger did not say who sent it. */
|
|
55
55
|
readonly last_from_owner: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
56
56
|
/** Open tasks whose source is in this chat. */
|
|
@@ -63,7 +63,7 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
63
63
|
readonly kind: v.PicklistSchema<["dialog", "group", "channel", "saved", "unknown"], undefined>;
|
|
64
64
|
/** The newest message, never its text; `null` while it is not stored. */
|
|
65
65
|
readonly last_message: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
66
|
-
readonly last_message_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
66
|
+
readonly last_message_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`">]>;
|
|
67
67
|
/** `null` when the newest message is not stored, or the messenger did not say who sent it. */
|
|
68
68
|
readonly last_from_owner: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
69
69
|
/** Open tasks whose source is in this chat. */
|
|
@@ -77,8 +77,8 @@ export declare const agenda: v.StrictObjectSchema<{
|
|
|
77
77
|
readonly kind: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
|
|
78
78
|
readonly category: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
79
79
|
readonly source: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
80
|
-
readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
81
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
80
|
+
readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
81
|
+
readonly created_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`">]>;
|
|
82
82
|
/** `person:<id>`, each one who does it. */
|
|
83
83
|
readonly assignees: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
84
84
|
}, undefined>, undefined>;
|
|
@@ -2,7 +2,7 @@ import * as v from "valibot";
|
|
|
2
2
|
/** Somebody joined, left, was added or removed, or changed their profile, in one chat. */
|
|
3
3
|
export declare const chatEvent: v.StrictObjectSchema<{
|
|
4
4
|
readonly chat_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
5
|
-
readonly time: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
5
|
+
readonly time: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
6
6
|
/** `join`, `leave`, `add`, `remove`, `create`, `title`, `pin`, `profile`; a messenger may pass others through. */
|
|
7
7
|
readonly type: v.StringSchema<undefined>;
|
|
8
8
|
/** The service message that says so, where there is one. */
|
|
@@ -5,8 +5,8 @@ import * as v from "valibot";
|
|
|
5
5
|
*/
|
|
6
6
|
export declare const chatStats: v.StrictObjectSchema<{
|
|
7
7
|
readonly chat: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
8
|
-
readonly since: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
9
|
-
readonly until: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
8
|
+
readonly since: 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`">]>;
|
|
9
|
+
readonly until: 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`">]>;
|
|
10
10
|
/** The store holds the chat whole and the messenger read every join and leave; otherwise lower bounds. */
|
|
11
11
|
readonly complete: v.BooleanSchema<undefined>;
|
|
12
12
|
readonly completeness: v.StrictObjectSchema<{
|
|
@@ -14,7 +14,7 @@ export declare const chatStats: v.StrictObjectSchema<{
|
|
|
14
14
|
readonly up_to_date: v.NullableSchema<v.BooleanSchema<undefined>, undefined>;
|
|
15
15
|
readonly gaps: v.BooleanSchema<undefined>;
|
|
16
16
|
readonly reaches_start: v.BooleanSchema<undefined>;
|
|
17
|
-
readonly fetched_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
17
|
+
readonly fetched_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
18
18
|
}, undefined>;
|
|
19
19
|
readonly messages: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
20
20
|
readonly senders: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -26,7 +26,7 @@ export declare const chatStats: v.StrictObjectSchema<{
|
|
|
26
26
|
readonly comments: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
27
27
|
readonly top_posts: v.ArraySchema<v.StrictObjectSchema<{
|
|
28
28
|
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
29
|
-
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
29
|
+
readonly timestamp: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
30
30
|
readonly reactions: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
31
31
|
readonly views: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
32
32
|
readonly forwards: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
@@ -69,7 +69,7 @@ export declare const taskStats: v.StrictObjectSchema<{
|
|
|
69
69
|
readonly rows: v.ArraySchema<v.StrictObjectSchema<{
|
|
70
70
|
readonly chat: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
71
71
|
readonly open: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
72
|
-
readonly oldest_open_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
72
|
+
readonly oldest_open_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
73
73
|
readonly median_close_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
74
74
|
}, undefined>, undefined>;
|
|
75
75
|
}, undefined>;
|