@wirecat/cli-core 0.496.0 → 0.498.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 +64 -1
- package/dist/calendar/cli/answers.d.ts +277 -0
- package/dist/calendar/cli/answers.js +257 -0
- package/dist/calendar/cli/index.d.ts +10 -1
- package/dist/calendar/cli/index.js +78 -47
- package/dist/calendar/index.d.ts +1 -1
- package/dist/calendar/reads.d.ts +7 -0
- package/dist/calendar/server-search.d.ts +31 -0
- package/dist/calendar/server-search.js +41 -0
- package/dist/calendar/source.d.ts +14 -0
- package/dist/calendar/testing/answers.d.ts +6 -0
- package/dist/calendar/testing/answers.js +37 -0
- package/dist/calendar/testing/source.d.ts +2 -0
- package/dist/calendar/testing/source.js +9 -0
- package/dist/cli/commands-command.js +10 -2
- package/dist/cli/config-command.js +18 -8
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/messenger/store-maintenance-command.d.ts +1 -1
- package/dist/cli/program.js +2 -1
- package/dist/entities/index.d.ts +7 -0
- package/dist/errors/reasons.js +4 -0
- package/dist/meetings/read-answers.d.ts +10 -0
- package/dist/meetings/read-answers.js +7 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,64 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
|
|
|
5
5
|
minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
|
|
6
6
|
shape of this file.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 0.497.0 — 31.10.2026
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **A calendar source can offer its provider's own search, and the shared `search` uses it.** `CalendarSource.search(calendar,
|
|
13
|
+
{ query, limit })` is optional and answers `{ entries, more }` (new type `SearchPage`). With `serverSearch: true` in
|
|
14
|
+
`CalendarCommandDeps` (a flag, as `freeBusy`, so the source can stay unbuilt until a profile is open), `search` takes
|
|
15
|
+
`--backend <archive|server|both>`: `archive`, the default, is the stored search as before; `server` asks the provider
|
|
16
|
+
over each synced calendar and answers `{ query, by: "server", hits, has_more, untrusted }`, earliest first, cancelled
|
|
17
|
+
events left out, each hit with `provider`, `account`, `calendar`, `external_id`, `title`, `starts_at`, `ends_at`,
|
|
18
|
+
`all_day`, `status`, `location`, `url` when there is one, and `found_by: ["server"]`; `both` is refused. New reasons:
|
|
19
|
+
`search.offline`, `search.no-calendars`, `search.server-options`, `search.one-backend`. `fakeCalendarSource({ search:
|
|
20
|
+
true })` answers it in tests. A CLI that replaced the shared `search` to reach its provider can drop that
|
|
21
|
+
([WC-ARCH-6](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/architecture.md#wc-arch-6--replace-a-use-case-not-a-command)).
|
|
22
|
+
- **Every shared calendar command declares the entity it answers with, with its schema**
|
|
23
|
+
([WC-CMD-19](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/commands.md#wc-cmd-19--declare-the-entity-a-command-answers-with)),
|
|
24
|
+
so `commands --json` names it, `commands info --json` exports it and `--fields` can project it: `calendar`
|
|
25
|
+
(`calendars list`, `sync`, `unsync`), `calendar_busy`, `calendar_sync`, `calendar_sync_progress` (`status`), `event`
|
|
26
|
+
(`events list`, as before), `calendar_event` (`events show`), `calendar_event_write` (every `events` write),
|
|
27
|
+
`calendar_search_hit` (a stored or a server hit), `calendar_attendee` (`people list`), `calendar_linked_person`
|
|
28
|
+
(`people link`), `calendar_link_review` and `calendar_link_resolution`. Each describes the item a host prints, keys
|
|
29
|
+
in snake_case. The shared `event` entity takes the optional `change`, `changed_at`, `was` and `overlaps` that
|
|
30
|
+
`events list changed:` and `overlapping` add.
|
|
31
|
+
- **`calendars list` takes a query over the `calendar` entity**: `synced:`, `primary:` and `access_role:` narrow the
|
|
32
|
+
whole list the provider answered, as `[query...]` after the options
|
|
33
|
+
([WC-CMD-20](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/commands.md#wc-cmd-20--give-a-list-one-query-over-its-entitys-fields-as-its-last-argument)).
|
|
34
|
+
`events list` keeps its words for now.
|
|
35
|
+
- **The shared `config show --json` names the profile's `kind`, `permissions` and `permission_sources` at the top**,
|
|
36
|
+
as a messenger's own `config show` does, so an agent reads one shape from every CLI.
|
|
37
|
+
|
|
38
|
+
### Changed — may break callers
|
|
39
|
+
|
|
40
|
+
- **The shared calendar commands no longer add their own `--json` and `--jsonl`.** They read the host program's global
|
|
41
|
+
flags, as every other command does ([WC-CMD-14](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/commands.md#wc-cmd-14--keep-the-shared-global-flags-at-their-meaning)).
|
|
42
|
+
The per-command copies showed up in `commands --json` and as `json` and `jsonl` inputs of every calendar MCP tool,
|
|
43
|
+
and an agent that sent `jsonl: true` was refused with "choose --json or --jsonl", because the MCP runner always adds
|
|
44
|
+
`--json`. A host that mounts `addCalendarCommands` on a program without global `--json`/`--jsonl` must define them.
|
|
45
|
+
- **`people list` takes `[query...]` instead of `[event]`**: one event's attendees are `people list event:42`, and a
|
|
46
|
+
bare `people list 42` is now refused as a word with no field. Its MCP tool's input is `query` (`"event:42"`), no
|
|
47
|
+
longer `event` (WC-CMD-20).
|
|
48
|
+
- **`CalendarCommandDeps.embed` returns `{ model, embedded, left }`**, which `embedEvents` already answers, so
|
|
49
|
+
`calendar_sync` can describe `embeddings`. It was `Promise<unknown>`.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **`commands <path>` names the CLI's own groups when the path is unknown.** Its example of one path per call was
|
|
54
|
+
always `commands messages --json` and `commands chats --json`, even in a calendar CLI that has neither; it now names
|
|
55
|
+
the groups the caller typed, then the CLI's first groups.
|
|
56
|
+
- **A group given no subcommand points a script at its own help.** In machine mode `tg chats` answered "run `tg
|
|
57
|
+
--help` for the commands"; it now says `tg chats --help`
|
|
58
|
+
([WC-CMD-3](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/commands.md#wc-cmd-3--give-a-group-without-a-leaf-only-its-help-never-a-hidden-default-action)).
|
|
59
|
+
- **A CLI that is not a messenger (`messenger: false`) no longer shows `config show --bot` or `config set|unset
|
|
60
|
+
--personal|--bot`.** Only a messenger has bots, and with them the file's personal and bot sections; a calendar or
|
|
61
|
+
notes CLI listed the options in its help, `commands --json` and its MCP tools with nothing behind them. They are
|
|
62
|
+
hidden there and still accepted, so a script that passes one keeps working.
|
|
63
|
+
- **`config show` with moved folders no longer says a session made without them reads as none.** That was true
|
|
64
|
+
before cli-base 0.65.5; a moved run now reads the usual keyring entry, and keeps a sign-in it makes in a temporary
|
|
65
|
+
entry that `session end` removes. The note says so.
|
|
9
66
|
|
|
10
67
|
## 0.496.0 — 31.10.2026
|
|
11
68
|
|
|
@@ -38,6 +95,12 @@ shape of this file.
|
|
|
38
95
|
|
|
39
96
|
- **`NoteQuery.refs` checks a list of notes against a query, and `NoteHit.at` is the time `date:` read.**
|
|
40
97
|
|
|
98
|
+
### Added
|
|
99
|
+
|
|
100
|
+
- **`chatCoverage` and `ChatCoverage` are exported from `@wirecat/cli-core/services`, and `coverageGaps` from
|
|
101
|
+
`@wirecat/cli-core/cli`.** A CLI can now pass `ports.coverage` to `gatherProjectEvidence` and build `missing` and
|
|
102
|
+
`next` for chats held in part, as cli-core's own agenda and search do.
|
|
103
|
+
|
|
41
104
|
## 0.495.0 — 31.10.2026
|
|
42
105
|
|
|
43
106
|
### Changed — may break callers
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { type QueryRegistry } from "@wirecat/cli-base/query";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import * as v from "valibot";
|
|
4
|
+
export declare const calendar: v.StrictObjectSchema<{
|
|
5
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
6
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
7
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
8
|
+
readonly timezone: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
9
|
+
readonly access_role: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10
|
+
readonly primary: v.BooleanSchema<undefined>;
|
|
11
|
+
readonly synced: v.BooleanSchema<undefined>;
|
|
12
|
+
readonly seen_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>;
|
|
13
|
+
}, undefined>;
|
|
14
|
+
export declare const calendarBusy: v.StrictObjectSchema<{
|
|
15
|
+
readonly start: 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`">]>;
|
|
16
|
+
readonly end: 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`">]>;
|
|
17
|
+
readonly timezone: v.StringSchema<undefined>;
|
|
18
|
+
readonly calendars: v.ArraySchema<v.StrictObjectSchema<{
|
|
19
|
+
/** One of the account's calendars, by its id; or `person`, by the address asked. */
|
|
20
|
+
readonly calendar: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
21
|
+
readonly person: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
22
|
+
readonly id: v.StringSchema<undefined>;
|
|
23
|
+
readonly busy: v.ArraySchema<v.StrictObjectSchema<{
|
|
24
|
+
readonly start: 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`">]>;
|
|
25
|
+
readonly end: 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`">]>;
|
|
26
|
+
}, undefined>, undefined>;
|
|
27
|
+
readonly error: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
28
|
+
}, undefined>, undefined>;
|
|
29
|
+
readonly slots: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
30
|
+
readonly start: 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
|
+
readonly end: 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`">]>;
|
|
32
|
+
}, undefined>, undefined>, undefined>;
|
|
33
|
+
readonly unknown: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
34
|
+
}, undefined>;
|
|
35
|
+
export declare const calendarSync: v.StrictObjectSchema<{
|
|
36
|
+
readonly provider: v.StringSchema<undefined>;
|
|
37
|
+
readonly account_id: v.NumberSchema<undefined>;
|
|
38
|
+
readonly window: v.StrictObjectSchema<{
|
|
39
|
+
readonly from: v.NumberSchema<undefined>;
|
|
40
|
+
readonly to: v.NumberSchema<undefined>;
|
|
41
|
+
}, undefined>;
|
|
42
|
+
readonly calendars: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
43
|
+
readonly synced: v.ArraySchema<v.StrictObjectSchema<{
|
|
44
|
+
readonly calendar_id: v.NumberSchema<undefined>;
|
|
45
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
46
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
47
|
+
readonly round: v.PicklistSchema<["full", "changes"], undefined>;
|
|
48
|
+
readonly reset: v.BooleanSchema<undefined>;
|
|
49
|
+
readonly state: v.PicklistSchema<["partial", "complete"], undefined>;
|
|
50
|
+
readonly saved: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
51
|
+
readonly removed: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
52
|
+
readonly occurrences: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
53
|
+
readonly unseen: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
54
|
+
readonly error: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
55
|
+
}, undefined>, undefined>;
|
|
56
|
+
readonly not_synced: v.ArraySchema<v.StrictObjectSchema<{
|
|
57
|
+
readonly calendar_id: v.NumberSchema<undefined>;
|
|
58
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
59
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
60
|
+
}, undefined>, undefined>;
|
|
61
|
+
readonly complete: v.BooleanSchema<undefined>;
|
|
62
|
+
readonly state: v.PicklistSchema<["partial", "complete"], undefined>;
|
|
63
|
+
readonly stopped: v.OptionalSchema<v.PicklistSchema<["requests", "deadline", "cancelled"], undefined>, undefined>;
|
|
64
|
+
readonly progress: v.StrictObjectSchema<{
|
|
65
|
+
readonly calendars: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
66
|
+
readonly calendars_done: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
67
|
+
readonly requests: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
68
|
+
readonly saved: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
69
|
+
readonly steps: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
70
|
+
}, undefined>;
|
|
71
|
+
readonly hint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
72
|
+
/** What `sync --embed` embedded: `embedEvents`' answer. */
|
|
73
|
+
readonly embeddings: v.OptionalSchema<v.StrictObjectSchema<{
|
|
74
|
+
readonly model: v.StringSchema<undefined>;
|
|
75
|
+
readonly embedded: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
76
|
+
readonly left: v.BooleanSchema<undefined>;
|
|
77
|
+
}, undefined>, undefined>;
|
|
78
|
+
}, undefined>;
|
|
79
|
+
export declare const calendarSyncProgress: v.StrictObjectSchema<{
|
|
80
|
+
readonly calendar_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
81
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
82
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
83
|
+
readonly round: v.NullableSchema<v.PicklistSchema<["full", "changes"], undefined>, undefined>;
|
|
84
|
+
readonly job: v.StringSchema<undefined>;
|
|
85
|
+
readonly profile: v.StringSchema<undefined>;
|
|
86
|
+
readonly done: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
87
|
+
readonly total: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
88
|
+
readonly remaining: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
89
|
+
readonly state: v.PicklistSchema<["partial", "complete"], undefined>;
|
|
90
|
+
readonly updated_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>;
|
|
91
|
+
readonly cursor_age_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
92
|
+
readonly line: v.StringSchema<undefined>;
|
|
93
|
+
}, undefined>;
|
|
94
|
+
export declare const calendarEvent: v.StrictObjectSchema<{
|
|
95
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
96
|
+
readonly event_series_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
97
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
98
|
+
readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
99
|
+
readonly location: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
100
|
+
readonly starts_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>;
|
|
101
|
+
readonly ends_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>;
|
|
102
|
+
readonly timezone: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
103
|
+
readonly origin: v.PicklistSchema<["auto", "owner", "calendar"], undefined>;
|
|
104
|
+
readonly status: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
105
|
+
readonly all_day: v.BooleanSchema<undefined>;
|
|
106
|
+
readonly source_deleted_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>;
|
|
107
|
+
readonly deleted_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>;
|
|
108
|
+
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`">]>;
|
|
109
|
+
readonly updated_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`">]>;
|
|
110
|
+
readonly change: v.OptionalSchema<v.PicklistSchema<["new", "moved", "cancelled"], undefined>, undefined>;
|
|
111
|
+
readonly changed_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>;
|
|
112
|
+
readonly was: v.OptionalSchema<v.StrictObjectSchema<{
|
|
113
|
+
readonly starts_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>;
|
|
114
|
+
readonly ends_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>;
|
|
115
|
+
}, undefined>, undefined>;
|
|
116
|
+
readonly overlaps: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
117
|
+
readonly ref: v.StringSchema<undefined>;
|
|
118
|
+
readonly entries: v.ArraySchema<v.StrictObjectSchema<{
|
|
119
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
120
|
+
readonly calendar_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
121
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
122
|
+
readonly kind: v.StringSchema<undefined>;
|
|
123
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
124
|
+
readonly status: v.StringSchema<undefined>;
|
|
125
|
+
readonly event_type: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
126
|
+
readonly own_response: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
127
|
+
readonly starts_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>;
|
|
128
|
+
readonly ends_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>;
|
|
129
|
+
readonly join_url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
130
|
+
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
131
|
+
readonly deleted_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>;
|
|
132
|
+
}, undefined>, undefined>;
|
|
133
|
+
readonly attendees: v.ArraySchema<v.StrictObjectSchema<{
|
|
134
|
+
email: v.StringSchema<undefined>;
|
|
135
|
+
name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
136
|
+
response: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
137
|
+
organizer: v.BooleanSchema<undefined>;
|
|
138
|
+
optional: v.BooleanSchema<undefined>;
|
|
139
|
+
resource: v.BooleanSchema<undefined>;
|
|
140
|
+
self: v.BooleanSchema<undefined>;
|
|
141
|
+
/** `person:<id>` when the shared store knows the address. */
|
|
142
|
+
person: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
143
|
+
}, undefined>, undefined>;
|
|
144
|
+
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
145
|
+
readonly file_id: v.StringSchema<undefined>;
|
|
146
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
147
|
+
readonly document: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
148
|
+
}, undefined>, undefined>;
|
|
149
|
+
readonly history: v.ArraySchema<v.StrictObjectSchema<{
|
|
150
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
151
|
+
readonly starts_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>;
|
|
152
|
+
readonly ends_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>;
|
|
153
|
+
readonly location: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
154
|
+
readonly status: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
155
|
+
readonly changed_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`">]>;
|
|
156
|
+
}, undefined>, undefined>;
|
|
157
|
+
readonly untrusted: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
158
|
+
}, undefined>;
|
|
159
|
+
/** A hit of the stored search, or with `--backend server` one the provider's own search found and nothing stored. */
|
|
160
|
+
export declare const calendarSearchHit: v.UnionSchema<[v.StrictObjectSchema<{
|
|
161
|
+
readonly provider: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
162
|
+
readonly account: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
163
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
164
|
+
readonly starts_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>;
|
|
165
|
+
readonly ends_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>;
|
|
166
|
+
readonly all_day: v.BooleanSchema<undefined>;
|
|
167
|
+
readonly status: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
168
|
+
readonly location: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
169
|
+
readonly url: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
170
|
+
readonly untrusted: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
171
|
+
readonly ref: v.StringSchema<undefined>;
|
|
172
|
+
readonly excerpt: v.StringSchema<undefined>;
|
|
173
|
+
readonly occurrences: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
174
|
+
readonly updated_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`">]>;
|
|
175
|
+
readonly found_by: v.ArraySchema<v.PicklistSchema<["words", "meaning"], undefined>, undefined>;
|
|
176
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
177
|
+
readonly provider: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
178
|
+
readonly account: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
179
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
180
|
+
readonly starts_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>;
|
|
181
|
+
readonly ends_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>;
|
|
182
|
+
readonly all_day: v.BooleanSchema<undefined>;
|
|
183
|
+
readonly status: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
184
|
+
readonly location: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
185
|
+
readonly url: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
186
|
+
readonly untrusted: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
187
|
+
readonly calendar: v.StringSchema<undefined>;
|
|
188
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
189
|
+
readonly found_by: v.ArraySchema<v.LiteralSchema<"server", undefined>, undefined>;
|
|
190
|
+
}, undefined>], undefined>;
|
|
191
|
+
export declare const calendarEventWrite: v.StrictObjectSchema<{
|
|
192
|
+
readonly operation_id: v.StringSchema<undefined>;
|
|
193
|
+
readonly event: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
194
|
+
readonly entry: v.OptionalSchema<v.NullableSchema<v.StrictObjectSchema<{
|
|
195
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
196
|
+
readonly calendar_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
197
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
198
|
+
readonly kind: v.StringSchema<undefined>;
|
|
199
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
200
|
+
readonly status: v.StringSchema<undefined>;
|
|
201
|
+
readonly event_type: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
202
|
+
readonly own_response: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
203
|
+
readonly starts_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>;
|
|
204
|
+
readonly ends_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>;
|
|
205
|
+
readonly join_url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
206
|
+
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
207
|
+
readonly deleted_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>;
|
|
208
|
+
}, undefined>, undefined>, undefined>;
|
|
209
|
+
/** `this`, `series` or `following`. */
|
|
210
|
+
readonly scope: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
211
|
+
/** Copies the store marked deleted. */
|
|
212
|
+
readonly removed: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
213
|
+
/** The series a `--following` change ended before the occurrence. */
|
|
214
|
+
readonly ended: v.OptionalSchema<v.NullableSchema<v.StrictObjectSchema<{
|
|
215
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
216
|
+
readonly calendar_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
217
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
218
|
+
readonly kind: v.StringSchema<undefined>;
|
|
219
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
220
|
+
readonly status: v.StringSchema<undefined>;
|
|
221
|
+
readonly event_type: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
222
|
+
readonly own_response: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
223
|
+
readonly starts_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>;
|
|
224
|
+
readonly ends_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>;
|
|
225
|
+
readonly join_url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
226
|
+
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
227
|
+
readonly deleted_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>;
|
|
228
|
+
}, undefined>, undefined>, undefined>;
|
|
229
|
+
readonly converted: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
230
|
+
readonly from_calendar: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
231
|
+
readonly calendar: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
232
|
+
readonly hint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
233
|
+
readonly untrusted: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
234
|
+
}, undefined>;
|
|
235
|
+
export declare const calendarAttendee: v.StrictObjectSchema<{
|
|
236
|
+
readonly email: v.StringSchema<undefined>;
|
|
237
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
238
|
+
readonly response: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
239
|
+
readonly organizer: v.BooleanSchema<undefined>;
|
|
240
|
+
readonly optional: v.BooleanSchema<undefined>;
|
|
241
|
+
readonly resource: v.BooleanSchema<undefined>;
|
|
242
|
+
readonly self: v.BooleanSchema<undefined>;
|
|
243
|
+
readonly person: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
244
|
+
/** How many of the listed events the person attends; only on the week's list. */
|
|
245
|
+
readonly events: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
246
|
+
readonly untrusted: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
247
|
+
}, undefined>;
|
|
248
|
+
export declare const calendarLinkedPerson: v.StrictObjectSchema<{
|
|
249
|
+
readonly person: v.StringSchema<undefined>;
|
|
250
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
251
|
+
readonly identities: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
252
|
+
}, undefined>;
|
|
253
|
+
export declare const calendarLinkReview: v.StrictObjectSchema<{
|
|
254
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
255
|
+
readonly entry_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
256
|
+
readonly reason: v.StringSchema<undefined>;
|
|
257
|
+
readonly candidates: v.ArraySchema<v.StrictObjectSchema<{
|
|
258
|
+
readonly ref: v.StringSchema<undefined>;
|
|
259
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
260
|
+
readonly starts_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>;
|
|
261
|
+
}, undefined>, undefined>;
|
|
262
|
+
readonly untrusted: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
263
|
+
}, undefined>;
|
|
264
|
+
export declare const calendarLinkResolution: v.StrictObjectSchema<{
|
|
265
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
266
|
+
readonly status: v.StringSchema<undefined>;
|
|
267
|
+
readonly chosen: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
268
|
+
}, undefined>;
|
|
269
|
+
/**
|
|
270
|
+
* Each command's answer entity: one item of a list, or the one value. They describe what a host prints, with the
|
|
271
|
+
* keys in snake_case, though a command hands its host some keys in camelCase (`notSynced`, `hasMore`).
|
|
272
|
+
*/
|
|
273
|
+
export declare const declareCalendarAnswers: (program: Command, commands: readonly Command[]) => void;
|
|
274
|
+
export declare const CALENDAR_ANSWER_PATHS: string[];
|
|
275
|
+
/** The provider answers the whole list, never a page, so the terms narrow every calendar it has. */
|
|
276
|
+
export declare const CALENDARS_QUERY: QueryRegistry;
|
|
277
|
+
export declare const PEOPLE_QUERY: QueryRegistry;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { annotate } from "@wirecat/cli-base/commands";
|
|
2
|
+
import { queryFieldsOf } from "@wirecat/cli-base/query";
|
|
3
|
+
import * as v from "valibot";
|
|
4
|
+
import { answerEntity } from "../../cli/answer-entity.js";
|
|
5
|
+
import { count, id, text, time, untrusted } from "../../entities/fields.js";
|
|
6
|
+
import { event } from "../../meetings/index.js";
|
|
7
|
+
const nullableText = v.nullable(text);
|
|
8
|
+
const nullableTime = v.nullable(time);
|
|
9
|
+
const stretch = v.strictObject({ start: time, end: time });
|
|
10
|
+
const epochWindow = v.strictObject({ from: v.number(), to: v.number() });
|
|
11
|
+
export const calendar = v.strictObject({
|
|
12
|
+
id,
|
|
13
|
+
external_id: text,
|
|
14
|
+
title: nullableText,
|
|
15
|
+
timezone: nullableText,
|
|
16
|
+
access_role: nullableText,
|
|
17
|
+
primary: v.boolean(),
|
|
18
|
+
synced: v.boolean(),
|
|
19
|
+
seen_at: nullableTime,
|
|
20
|
+
});
|
|
21
|
+
const busyRow = v.strictObject({
|
|
22
|
+
/** One of the account's calendars, by its id; or `person`, by the address asked. */
|
|
23
|
+
calendar: v.optional(id),
|
|
24
|
+
person: v.optional(text),
|
|
25
|
+
id: text,
|
|
26
|
+
busy: v.array(stretch),
|
|
27
|
+
error: v.optional(text),
|
|
28
|
+
});
|
|
29
|
+
export const calendarBusy = v.strictObject({
|
|
30
|
+
start: time,
|
|
31
|
+
end: time,
|
|
32
|
+
timezone: text,
|
|
33
|
+
calendars: v.array(busyRow),
|
|
34
|
+
slots: v.optional(v.array(stretch)),
|
|
35
|
+
unknown: v.optional(v.array(text)),
|
|
36
|
+
});
|
|
37
|
+
const syncedCalendar = v.strictObject({
|
|
38
|
+
calendar_id: v.number(),
|
|
39
|
+
external_id: text,
|
|
40
|
+
title: nullableText,
|
|
41
|
+
round: v.picklist(["full", "changes"]),
|
|
42
|
+
reset: v.boolean(),
|
|
43
|
+
state: v.picklist(["partial", "complete"]),
|
|
44
|
+
saved: count,
|
|
45
|
+
removed: count,
|
|
46
|
+
occurrences: count,
|
|
47
|
+
unseen: count,
|
|
48
|
+
error: v.optional(text),
|
|
49
|
+
});
|
|
50
|
+
export const calendarSync = v.strictObject({
|
|
51
|
+
provider: text,
|
|
52
|
+
account_id: v.number(),
|
|
53
|
+
window: epochWindow,
|
|
54
|
+
calendars: count,
|
|
55
|
+
synced: v.array(syncedCalendar),
|
|
56
|
+
not_synced: v.array(v.strictObject({ calendar_id: v.number(), external_id: text, title: nullableText })),
|
|
57
|
+
complete: v.boolean(),
|
|
58
|
+
state: v.picklist(["partial", "complete"]),
|
|
59
|
+
stopped: v.optional(v.picklist(["requests", "deadline", "cancelled"])),
|
|
60
|
+
progress: v.strictObject({
|
|
61
|
+
calendars: count,
|
|
62
|
+
calendars_done: count,
|
|
63
|
+
requests: count,
|
|
64
|
+
saved: count,
|
|
65
|
+
steps: count,
|
|
66
|
+
}),
|
|
67
|
+
hint: v.optional(text),
|
|
68
|
+
/** What `sync --embed` embedded: `embedEvents`' answer. */
|
|
69
|
+
embeddings: v.optional(v.strictObject({ model: text, embedded: count, left: v.boolean() })),
|
|
70
|
+
});
|
|
71
|
+
export const calendarSyncProgress = v.strictObject({
|
|
72
|
+
calendar_id: id,
|
|
73
|
+
external_id: text,
|
|
74
|
+
title: nullableText,
|
|
75
|
+
round: v.nullable(v.picklist(["full", "changes"])),
|
|
76
|
+
job: text,
|
|
77
|
+
profile: text,
|
|
78
|
+
done: count,
|
|
79
|
+
total: v.nullable(count),
|
|
80
|
+
remaining: v.nullable(count),
|
|
81
|
+
state: v.picklist(["partial", "complete"]),
|
|
82
|
+
updated_at: nullableTime,
|
|
83
|
+
cursor_age_ms: v.nullable(count),
|
|
84
|
+
line: text,
|
|
85
|
+
});
|
|
86
|
+
const entry = v.strictObject({
|
|
87
|
+
id,
|
|
88
|
+
calendar_id: id,
|
|
89
|
+
external_id: text,
|
|
90
|
+
kind: text,
|
|
91
|
+
title: nullableText,
|
|
92
|
+
status: text,
|
|
93
|
+
event_type: nullableText,
|
|
94
|
+
own_response: nullableText,
|
|
95
|
+
starts_at: nullableTime,
|
|
96
|
+
ends_at: nullableTime,
|
|
97
|
+
join_url: nullableText,
|
|
98
|
+
url: nullableText,
|
|
99
|
+
deleted_at: nullableTime,
|
|
100
|
+
});
|
|
101
|
+
const attendee = {
|
|
102
|
+
email: text,
|
|
103
|
+
name: nullableText,
|
|
104
|
+
response: nullableText,
|
|
105
|
+
organizer: v.boolean(),
|
|
106
|
+
optional: v.boolean(),
|
|
107
|
+
resource: v.boolean(),
|
|
108
|
+
self: v.boolean(),
|
|
109
|
+
/** `person:<id>` when the shared store knows the address. */
|
|
110
|
+
person: nullableText,
|
|
111
|
+
};
|
|
112
|
+
const { untrusted: _eventMarker, ...eventFields } = event.entries;
|
|
113
|
+
export const calendarEvent = v.strictObject({
|
|
114
|
+
...eventFields,
|
|
115
|
+
ref: text,
|
|
116
|
+
entries: v.array(entry),
|
|
117
|
+
attendees: v.array(v.strictObject(attendee)),
|
|
118
|
+
attachments: v.array(v.strictObject({ file_id: text, title: nullableText, document: nullableText })),
|
|
119
|
+
history: v.array(v.strictObject({
|
|
120
|
+
title: nullableText,
|
|
121
|
+
starts_at: nullableTime,
|
|
122
|
+
ends_at: nullableTime,
|
|
123
|
+
location: nullableText,
|
|
124
|
+
status: nullableText,
|
|
125
|
+
changed_at: time,
|
|
126
|
+
})),
|
|
127
|
+
untrusted,
|
|
128
|
+
});
|
|
129
|
+
const hitFields = {
|
|
130
|
+
provider: nullableText,
|
|
131
|
+
account: nullableText,
|
|
132
|
+
title: nullableText,
|
|
133
|
+
starts_at: nullableTime,
|
|
134
|
+
ends_at: nullableTime,
|
|
135
|
+
all_day: v.boolean(),
|
|
136
|
+
status: nullableText,
|
|
137
|
+
location: nullableText,
|
|
138
|
+
url: v.optional(text),
|
|
139
|
+
untrusted,
|
|
140
|
+
};
|
|
141
|
+
/** A hit of the stored search, or with `--backend server` one the provider's own search found and nothing stored. */
|
|
142
|
+
export const calendarSearchHit = v.union([
|
|
143
|
+
v.strictObject({
|
|
144
|
+
...hitFields,
|
|
145
|
+
ref: text,
|
|
146
|
+
excerpt: text,
|
|
147
|
+
occurrences: count,
|
|
148
|
+
updated_at: time,
|
|
149
|
+
found_by: v.array(v.picklist(["words", "meaning"])),
|
|
150
|
+
}),
|
|
151
|
+
v.strictObject({
|
|
152
|
+
...hitFields,
|
|
153
|
+
calendar: text,
|
|
154
|
+
external_id: text,
|
|
155
|
+
found_by: v.array(v.literal("server")),
|
|
156
|
+
}),
|
|
157
|
+
]);
|
|
158
|
+
export const calendarEventWrite = v.strictObject({
|
|
159
|
+
operation_id: text,
|
|
160
|
+
event: nullableText,
|
|
161
|
+
entry: v.optional(v.nullable(entry)),
|
|
162
|
+
/** `this`, `series` or `following`. */
|
|
163
|
+
scope: v.optional(text),
|
|
164
|
+
/** Copies the store marked deleted. */
|
|
165
|
+
removed: v.optional(count),
|
|
166
|
+
/** The series a `--following` change ended before the occurrence. */
|
|
167
|
+
ended: v.optional(v.nullable(entry)),
|
|
168
|
+
converted: v.optional(text),
|
|
169
|
+
from_calendar: v.optional(id),
|
|
170
|
+
calendar: v.optional(id),
|
|
171
|
+
hint: v.optional(text),
|
|
172
|
+
untrusted,
|
|
173
|
+
});
|
|
174
|
+
export const calendarAttendee = v.strictObject({
|
|
175
|
+
...attendee,
|
|
176
|
+
/** How many of the listed events the person attends; only on the week's list. */
|
|
177
|
+
events: v.optional(count),
|
|
178
|
+
untrusted,
|
|
179
|
+
});
|
|
180
|
+
export const calendarLinkedPerson = v.strictObject({ person: text, name: nullableText, identities: v.array(text) });
|
|
181
|
+
export const calendarLinkReview = v.strictObject({
|
|
182
|
+
id,
|
|
183
|
+
entry_id: id,
|
|
184
|
+
reason: text,
|
|
185
|
+
candidates: v.array(v.strictObject({ ref: text, title: nullableText, starts_at: nullableTime })),
|
|
186
|
+
untrusted,
|
|
187
|
+
});
|
|
188
|
+
export const calendarLinkResolution = v.strictObject({ id, status: text, chosen: nullableText });
|
|
189
|
+
const ANSWERS = {
|
|
190
|
+
"calendars list": { name: "calendar", schema: calendar },
|
|
191
|
+
"calendars sync": { name: "calendar", schema: calendar },
|
|
192
|
+
"calendars unsync": { name: "calendar", schema: calendar },
|
|
193
|
+
"calendars busy": { name: "calendar_busy", schema: calendarBusy },
|
|
194
|
+
sync: { name: "calendar_sync", schema: calendarSync },
|
|
195
|
+
status: { name: "calendar_sync_progress", schema: calendarSyncProgress },
|
|
196
|
+
"events list": { name: "event" },
|
|
197
|
+
"events show": { name: "calendar_event", schema: calendarEvent },
|
|
198
|
+
"events create": { name: "calendar_event_write", schema: calendarEventWrite },
|
|
199
|
+
"events update": { name: "calendar_event_write", schema: calendarEventWrite },
|
|
200
|
+
"events delete": { name: "calendar_event_write", schema: calendarEventWrite },
|
|
201
|
+
"events move": { name: "calendar_event_write", schema: calendarEventWrite },
|
|
202
|
+
"events respond": { name: "calendar_event_write", schema: calendarEventWrite },
|
|
203
|
+
search: { name: "calendar_search_hit", schema: calendarSearchHit },
|
|
204
|
+
"people list": { name: "calendar_attendee", schema: calendarAttendee },
|
|
205
|
+
"people link": { name: "calendar_linked_person", schema: calendarLinkedPerson },
|
|
206
|
+
"links review": { name: "calendar_link_review", schema: calendarLinkReview },
|
|
207
|
+
"links resolve": { name: "calendar_link_resolution", schema: calendarLinkResolution },
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Each command's answer entity: one item of a list, or the one value. They describe what a host prints, with the
|
|
211
|
+
* keys in snake_case, though a command hands its host some keys in camelCase (`notSynced`, `hasMore`).
|
|
212
|
+
*/
|
|
213
|
+
export const declareCalendarAnswers = (program, commands) => {
|
|
214
|
+
const pathOf = (command) => {
|
|
215
|
+
const words = [];
|
|
216
|
+
for (let at = command; at && at !== program; at = at.parent)
|
|
217
|
+
words.unshift(at.name());
|
|
218
|
+
return words.join(" ");
|
|
219
|
+
};
|
|
220
|
+
for (const command of commands) {
|
|
221
|
+
const answer = ANSWERS[pathOf(command)];
|
|
222
|
+
if (!answer)
|
|
223
|
+
continue;
|
|
224
|
+
if (answer.schema)
|
|
225
|
+
answerEntity(command, answer.name, answer.schema);
|
|
226
|
+
else
|
|
227
|
+
annotate(command, { output: { entity: answer.name } });
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
export const CALENDAR_ANSWER_PATHS = Object.keys(ANSWERS);
|
|
231
|
+
const wholeValues = (registry) => ({
|
|
232
|
+
...registry,
|
|
233
|
+
fields: registry.fields.map((field) => field.native ? { ...field, operators: field.operators.filter((one) => one === "term" || one === "phrase") } : field),
|
|
234
|
+
});
|
|
235
|
+
/** The provider answers the whole list, never a page, so the terms narrow every calendar it has. */
|
|
236
|
+
export const CALENDARS_QUERY = wholeValues({
|
|
237
|
+
entity: "calendar",
|
|
238
|
+
backend: "native",
|
|
239
|
+
fields: queryFieldsOf(calendar, {
|
|
240
|
+
native: ["synced", "primary", "access_role"],
|
|
241
|
+
examples: { synced: "synced:true", primary: "primary:true", access_role: "access_role:owner" },
|
|
242
|
+
}),
|
|
243
|
+
});
|
|
244
|
+
export const PEOPLE_QUERY = wholeValues({
|
|
245
|
+
entity: "calendar_attendee",
|
|
246
|
+
backend: "native",
|
|
247
|
+
fields: queryFieldsOf(calendarAttendee, {
|
|
248
|
+
native: ["event"],
|
|
249
|
+
relations: {
|
|
250
|
+
event: {
|
|
251
|
+
type: "kw",
|
|
252
|
+
example: "event:42",
|
|
253
|
+
relation: "one event's attendees, by its id; without it, everyone in this week's events",
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
}),
|
|
257
|
+
});
|
|
@@ -20,10 +20,19 @@ export interface CalendarCommandDeps {
|
|
|
20
20
|
* build only once a profile is open.
|
|
21
21
|
*/
|
|
22
22
|
freeBusy?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The source answers `search`: `search` takes `--backend server` and asks the provider. A flag, as `freeBusy`, so the
|
|
25
|
+
* source can stay unbuilt until a profile is open.
|
|
26
|
+
*/
|
|
27
|
+
serverSearch?: boolean;
|
|
23
28
|
/** For a source with `expands: "local"`. */
|
|
24
29
|
expand?: CalendarExpander;
|
|
25
30
|
/** After `sync --embed`: embeds new events for search by meaning (`embedEvents`), as drive's `sync --embed`. */
|
|
26
|
-
embed?: (max: number) => Promise<
|
|
31
|
+
embed?: (max: number) => Promise<{
|
|
32
|
+
model: string;
|
|
33
|
+
embedded: number;
|
|
34
|
+
left: boolean;
|
|
35
|
+
}>;
|
|
27
36
|
write: (value: unknown, format: "json" | "jsonl" | "text") => void;
|
|
28
37
|
now?: () => number;
|
|
29
38
|
/** The zone `today`, `week` and a bare date are read in; the computer's when absent. */
|