@wirecat/cli-core 0.398.0 → 0.400.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +106 -0
- package/dist/analysis/consents.d.ts +11 -6
- package/dist/analysis/consents.js +5 -2
- package/dist/cli/analysis-choice.d.ts +1 -0
- package/dist/cli/analysis-choice.js +3 -0
- package/dist/cli/bot/admins.js +14 -4
- package/dist/cli/bot/command.js +38 -16
- package/dist/cli/bot/examples.d.ts +3 -0
- package/dist/cli/bot/examples.js +2 -0
- package/dist/cli/bot/mcp.js +6 -2
- package/dist/cli/bot/messages.js +17 -6
- package/dist/cli/bot/moderation.js +16 -4
- package/dist/cli/bot/people.js +16 -4
- package/dist/cli/bot/setup.js +27 -8
- package/dist/cli/bot/watch.js +7 -1
- package/dist/cli/config-command.js +20 -1
- package/dist/cli/context.d.ts +2 -0
- package/dist/cli/context.js +1 -1
- package/dist/cli/effects.d.ts +4 -1
- package/dist/cli/effects.js +10 -2
- package/dist/cli/embedding-choice.d.ts +2 -1
- package/dist/cli/embedding-choice.js +4 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/json-fields.js +12 -1
- package/dist/cli/messenger/account-command.js +15 -6
- package/dist/cli/messenger/account-profile-query.d.ts +2 -0
- package/dist/cli/messenger/account-profile-query.js +13 -0
- package/dist/cli/messenger/account-sessions-command.js +1 -0
- package/dist/cli/messenger/admin-commands.js +30 -21
- package/dist/cli/messenger/admin-contacts-command.js +6 -3
- package/dist/cli/messenger/admin-folders-command.js +5 -5
- package/dist/cli/messenger/admin-moderation-command.js +4 -4
- package/dist/cli/messenger/admin-statistics-command.js +6 -14
- package/dist/cli/messenger/analysis-consents-query.d.ts +5 -0
- package/dist/cli/messenger/analysis-consents-query.js +20 -0
- package/dist/cli/messenger/archive-commands.js +3 -3
- package/dist/cli/messenger/attachments-command.js +3 -0
- package/dist/cli/messenger/backfill-command.js +5 -4
- package/dist/cli/messenger/catch-up-answers.d.ts +2 -1
- package/dist/cli/messenger/catch-up-answers.js +6 -2
- package/dist/cli/messenger/chat-queries.d.ts +1 -0
- package/dist/cli/messenger/chat-queries.js +12 -2
- package/dist/cli/messenger/chats-command.js +2 -2
- package/dist/cli/messenger/chats-documents-command.js +7 -5
- package/dist/cli/messenger/chats-members-command.js +7 -3
- package/dist/cli/messenger/chats-read-command.js +1 -1
- package/dist/cli/messenger/chats-stats-command.js +1 -1
- package/dist/cli/messenger/chats-tracking-command.js +14 -6
- package/dist/cli/messenger/contacts-command.js +11 -7
- package/dist/cli/messenger/context.d.ts +2 -0
- package/dist/cli/messenger/conversations-command.js +47 -29
- package/dist/cli/messenger/doctor-command.js +5 -1
- package/dist/cli/messenger/document-links-query.d.ts +2 -0
- package/dist/cli/messenger/document-links-query.js +9 -0
- package/dist/cli/messenger/download-command.js +1 -0
- package/dist/cli/messenger/flood-command.d.ts +2 -2
- package/dist/cli/messenger/flood-command.js +3 -3
- package/dist/cli/messenger/gaps-command.js +2 -2
- package/dist/cli/messenger/guard-commands.js +35 -13
- package/dist/cli/messenger/hearing-command.d.ts +1 -1
- package/dist/cli/messenger/hearing-command.js +1 -1
- package/dist/cli/messenger/images-command.js +1 -0
- package/dist/cli/messenger/inbox.js +6 -4
- package/dist/cli/messenger/media-archive-command.js +2 -0
- package/dist/cli/messenger/media-archive-move-command.js +1 -0
- package/dist/cli/messenger/media-archive-timer-command.js +1 -1
- package/dist/cli/messenger/mentions-command.js +15 -2
- package/dist/cli/messenger/messages-command.js +2 -0
- package/dist/cli/messenger/messages-delete-command.js +1 -0
- package/dist/cli/messenger/messages-edit-command.js +1 -0
- package/dist/cli/messenger/messages-evidence-command.js +3 -1
- package/dist/cli/messenger/messages-forward-command.js +1 -0
- package/dist/cli/messenger/messages-pin-command.js +3 -0
- package/dist/cli/messenger/messages-send-command.js +1 -0
- package/dist/cli/messenger/messages-stats-command.js +1 -1
- package/dist/cli/messenger/metadata-command.js +7 -2
- package/dist/cli/messenger/models-command.js +10 -2
- package/dist/cli/messenger/polls-command.js +4 -0
- package/dist/cli/messenger/private-people-command.js +8 -6
- package/dist/cli/messenger/rankings-command.js +6 -11
- package/dist/cli/messenger/reactions-command.js +2 -0
- package/dist/cli/messenger/recipients-query.d.ts +5 -0
- package/dist/cli/messenger/recipients-query.js +18 -0
- package/dist/cli/messenger/records-command.js +13 -6
- package/dist/cli/messenger/replies-edit-command.d.ts +1 -1
- package/dist/cli/messenger/replies-edit-command.js +13 -5
- package/dist/cli/messenger/retention-command.js +1 -1
- package/dist/cli/messenger/review.js +6 -4
- package/dist/cli/messenger/search-command.js +3 -1
- package/dist/cli/messenger/searches-command.js +6 -2
- package/dist/cli/messenger/sends-query.d.ts +5 -0
- package/dist/cli/messenger/sends-query.js +33 -0
- package/dist/cli/messenger/serve-command.js +1 -0
- package/dist/cli/messenger/serve-relay.d.ts +1 -0
- package/dist/cli/messenger/statistics-query.d.ts +14 -0
- package/dist/cli/messenger/statistics-query.js +143 -0
- package/dist/cli/messenger/stats-command.js +6 -6
- package/dist/cli/messenger/store-maintenance-command.d.ts +1 -1
- package/dist/cli/messenger/store-maintenance-command.js +10 -10
- package/dist/cli/messenger/tags-command.js +18 -6
- package/dist/cli/messenger/tasks-command.js +47 -8
- package/dist/cli/messenger/transcribe-command.js +2 -1
- package/dist/cli/messenger/watch-answers.d.ts +6 -0
- package/dist/cli/messenger/watch-answers.js +69 -0
- package/dist/cli/messenger/watch-command.d.ts +1 -1
- package/dist/cli/messenger/watch-command.js +56 -7
- package/dist/cli/program.js +5 -1
- package/dist/cli/runs/command.js +25 -38
- package/dist/cli/runs/query.d.ts +5 -0
- package/dist/cli/runs/query.js +32 -0
- package/dist/cli/runs/search-command.d.ts +4 -0
- package/dist/cli/runs/search-command.js +27 -0
- package/dist/cli/runs/search-query.d.ts +4 -0
- package/dist/cli/runs/search-query.js +50 -0
- package/dist/cli/runs/search.d.ts +2 -1
- package/dist/cli/runs/search.js +6 -6
- package/dist/domain/attachments.js +9 -1
- package/dist/domain/rankings-options.js +3 -3
- package/dist/entities/account-change.d.ts +89 -0
- package/dist/entities/account-change.js +20 -0
- package/dist/entities/account-profile.d.ts +7 -0
- package/dist/entities/account-profile.js +8 -0
- package/dist/entities/analysis-consent.d.ts +9 -0
- package/dist/entities/analysis-consent.js +4 -0
- package/dist/entities/attachment-results.d.ts +96 -0
- package/dist/entities/attachment-results.js +31 -0
- package/dist/entities/batch-result.d.ts +27 -0
- package/dist/entities/batch-result.js +18 -0
- package/dist/entities/chat-admin.d.ts +234 -0
- package/dist/entities/chat-admin.js +84 -0
- package/dist/entities/chat-change.d.ts +25 -0
- package/dist/entities/chat-change.js +11 -0
- package/dist/entities/chat-metadata.d.ts +34 -0
- package/dist/entities/chat-metadata.js +15 -0
- package/dist/entities/chat-moderation.d.ts +44 -0
- package/dist/entities/chat-moderation.js +37 -0
- package/dist/entities/chat-tracking.d.ts +26 -0
- package/dist/entities/chat-tracking.js +23 -0
- package/dist/entities/contact-activity.d.ts +52 -0
- package/dist/entities/contact-activity.js +42 -0
- package/dist/entities/contact-context.d.ts +1568 -0
- package/dist/entities/contact-context.js +191 -0
- package/dist/entities/contact-write.d.ts +22 -0
- package/dist/entities/contact-write.js +6 -0
- package/dist/entities/conversation-preparation.d.ts +63 -0
- package/dist/entities/conversation-preparation.js +23 -0
- package/dist/entities/conversation-results.d.ts +567 -0
- package/dist/entities/conversation-results.js +94 -0
- package/dist/entities/document-link.d.ts +13 -0
- package/dist/entities/document-link.js +11 -0
- package/dist/entities/extraction-report.d.ts +95 -0
- package/dist/entities/extraction-report.js +34 -0
- package/dist/entities/image-embedding.d.ts +9 -0
- package/dist/entities/image-embedding.js +10 -0
- package/dist/entities/index.d.ts +8006 -1928
- package/dist/entities/index.js +174 -3
- package/dist/entities/listener.d.ts +2150 -0
- package/dist/entities/listener.js +46 -0
- package/dist/entities/media-archive.d.ts +43 -0
- package/dist/entities/media-archive.js +32 -0
- package/dist/entities/meeting-task-proposal.d.ts +14 -0
- package/dist/entities/meeting-task-proposal.js +19 -0
- package/dist/entities/meeting.d.ts +1 -1
- package/dist/entities/meeting.js +1 -1
- package/dist/entities/mention.d.ts +63 -0
- package/dist/entities/mention.js +44 -0
- package/dist/entities/message-change.d.ts +19 -0
- package/dist/entities/message-change.js +6 -0
- package/dist/entities/message-context.d.ts +617 -0
- package/dist/entities/message-context.js +20 -0
- package/dist/entities/message-read.d.ts +73 -0
- package/dist/entities/message-read.js +58 -0
- package/dist/entities/message-transfer.d.ts +379 -0
- package/dist/entities/message-transfer.js +83 -0
- package/dist/entities/message-write.d.ts +191 -0
- package/dist/entities/message-write.js +8 -0
- package/dist/entities/model-key.d.ts +14 -0
- package/dist/entities/model-key.js +10 -0
- package/dist/entities/poll.d.ts +40 -0
- package/dist/entities/poll.js +16 -0
- package/dist/entities/private-contact.d.ts +10 -0
- package/dist/entities/private-contact.js +4 -0
- package/dist/entities/reaction-change.d.ts +7 -0
- package/dist/entities/reaction-change.js +8 -0
- package/dist/entities/recipient.d.ts +29 -0
- package/dist/entities/recipient.js +11 -0
- package/dist/entities/recorded-run.d.ts +103 -0
- package/dist/entities/recorded-run.js +44 -0
- package/dist/entities/saved-search.d.ts +4 -0
- package/dist/entities/saved-search.js +2 -0
- package/dist/entities/send-attempt.d.ts +31 -0
- package/dist/entities/send-attempt.js +29 -0
- package/dist/entities/store-maintenance.d.ts +319 -0
- package/dist/entities/store-maintenance.js +145 -0
- package/dist/entities/store-records.d.ts +442 -0
- package/dist/entities/store-records.js +99 -0
- package/dist/entities/tag-change.d.ts +74 -0
- package/dist/entities/tag-change.js +31 -0
- package/dist/entities/task-pair.d.ts +31 -0
- package/dist/entities/task-pair.js +23 -0
- package/dist/entities/task-results.d.ts +524 -0
- package/dist/entities/task-results.js +142 -0
- package/dist/errors/reasons.js +1 -0
- package/dist/mcp/agent.d.ts +3 -1
- package/dist/mcp/agent.js +9 -6
- package/dist/mcp/bot/server.d.ts +2 -0
- package/dist/mcp/bot/server.js +1 -0
- package/dist/mcp/prompts.js +8 -2
- package/dist/mcp/server.js +3 -1
- package/dist/mcp/tools/attachments.js +1 -0
- package/dist/meetings/cli/index.js +1 -1
- package/dist/meetings/cli/passage.js +1 -0
- package/dist/meetings/index.d.ts +2 -1
- package/dist/meetings/index.js +1 -0
- package/dist/meetings/links.d.ts +16 -0
- package/dist/meetings/mcp/index.d.ts +15 -15
- package/dist/meetings/read-answers.d.ts +167 -0
- package/dist/meetings/read-answers.js +183 -0
- package/dist/runs/run.d.ts +10 -2
- package/dist/runs/run.js +11 -3
- package/dist/sends/journal.d.ts +8 -1
- package/dist/sends/journal.js +9 -2
- package/dist/sends/permissions.d.ts +5 -1
- package/dist/sends/permissions.js +11 -1
- package/dist/sends/recipients.d.ts +8 -0
- package/dist/sends/recipients.js +9 -0
- package/dist/services/admin-statistics.js +3 -3
- package/dist/services/chat-documents.d.ts +1 -0
- package/dist/services/chat-documents.js +9 -3
- package/dist/services/chats.d.ts +1 -1
- package/dist/services/chats.js +5 -2
- package/dist/services/meeting-links.d.ts +2 -17
- package/dist/store/exports.d.ts +1 -1
- package/dist/store/exports.js +1 -1
- package/dist/store/messages.d.ts +3 -1
- package/dist/store/messages.js +2 -2
- package/dist/store/roster.d.ts +4 -1
- package/dist/store/roster.js +2 -2
- package/dist/store/sqlite/chats.d.ts +12 -0
- package/dist/store/sqlite/chats.js +1 -0
- package/dist/store/sqlite/document-links.d.ts +1 -1
- package/dist/store/sqlite/document-links.js +5 -5
- package/dist/store/sqlite/involvements.js +2 -1
- package/dist/store/sqlite/roster.d.ts +2 -1
- package/dist/store/sqlite/roster.js +3 -2
- package/package.json +3 -3
- package/parity.json +76 -108
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import type { MeetingLink } from "./links.js";
|
|
3
|
+
import type { MeetingReviewItem } from "./review.js";
|
|
4
|
+
import type { MeetingSpeakerStats, MeetingStats } from "./stats.js";
|
|
5
|
+
/** One meeting in `review`: what the store holds about it, never transcript text. */
|
|
6
|
+
export declare const meetingReview: v.StrictObjectSchema<{
|
|
7
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
8
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
9
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
10
|
+
readonly started_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>;
|
|
11
|
+
readonly duration_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
12
|
+
readonly participants_count: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
13
|
+
readonly projects: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
14
|
+
/** Null when the meeting has no current transcript. */
|
|
15
|
+
readonly transcript: v.NullableSchema<v.StrictObjectSchema<{
|
|
16
|
+
readonly lines: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
17
|
+
readonly words: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
18
|
+
}, undefined>, undefined>;
|
|
19
|
+
/** The three who talked longest. */
|
|
20
|
+
readonly speakers: v.ArraySchema<v.StrictObjectSchema<{
|
|
21
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
22
|
+
readonly talk_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
23
|
+
}, undefined>, undefined>;
|
|
24
|
+
/** The newest stored summary; null when there is none. */
|
|
25
|
+
readonly summary: v.NullableSchema<v.StrictObjectSchema<{
|
|
26
|
+
readonly source: v.StringSchema<undefined>;
|
|
27
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
28
|
+
readonly overview: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
29
|
+
readonly next_steps: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
30
|
+
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
31
|
+
}, undefined>, undefined>;
|
|
32
|
+
}, undefined>;
|
|
33
|
+
export declare const meetingReviewItem: (one: MeetingReviewItem) => v.InferOutput<typeof meetingReview>;
|
|
34
|
+
/** A link shared in meeting chat, with where and how often; `mentions list` answers these. */
|
|
35
|
+
export declare const meetingLink: v.StrictObjectSchema<{
|
|
36
|
+
readonly url: v.StringSchema<undefined>;
|
|
37
|
+
readonly domain: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
38
|
+
/** The Google Docs, Sheets, Slides, Forms or Drive file it names. */
|
|
39
|
+
readonly document_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
40
|
+
readonly count: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
41
|
+
readonly first_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`">]>;
|
|
42
|
+
readonly last_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`">]>;
|
|
43
|
+
readonly senders: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
44
|
+
readonly meetings: v.ArraySchema<v.StrictObjectSchema<{
|
|
45
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
46
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
47
|
+
}, undefined>, undefined>;
|
|
48
|
+
}, undefined>;
|
|
49
|
+
export declare const meetingLinkItem: (link: MeetingLink) => v.InferOutput<typeof meetingLink>;
|
|
50
|
+
/** One speaker's talk over the selected meetings; `stats meetings top` answers these. */
|
|
51
|
+
export declare const meetingSpeaker: v.StrictObjectSchema<{
|
|
52
|
+
/** `person:<id>`, `identity:<id>`, `name:<lowercased name>` or `unknown`. */
|
|
53
|
+
readonly key: v.StringSchema<undefined>;
|
|
54
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
55
|
+
readonly person_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
56
|
+
readonly identity_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
57
|
+
readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
58
|
+
readonly lines: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
59
|
+
readonly words: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
60
|
+
readonly talk_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
61
|
+
/** This speaker's part of all talk time, 0–1. */
|
|
62
|
+
readonly share: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>]>;
|
|
63
|
+
}, undefined>;
|
|
64
|
+
export declare const meetingSpeakerItem: (one: MeetingSpeakerStats) => v.InferOutput<typeof meetingSpeaker>;
|
|
65
|
+
/** `stats meetings show`: how much was said over the selected meetings, by week, with the top speakers. */
|
|
66
|
+
export declare const meetingStats: v.StrictObjectSchema<{
|
|
67
|
+
readonly time_zone: v.StringSchema<undefined>;
|
|
68
|
+
readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
69
|
+
readonly lines: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
70
|
+
readonly words: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
71
|
+
readonly talk_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
72
|
+
/** `week_start` is the Monday, as a date in `time_zone`. */
|
|
73
|
+
readonly weeks: v.ArraySchema<v.StrictObjectSchema<{
|
|
74
|
+
readonly week_start: v.StringSchema<undefined>;
|
|
75
|
+
readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
76
|
+
readonly talk_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
77
|
+
}, undefined>, undefined>;
|
|
78
|
+
readonly top_speakers: v.ArraySchema<v.StrictObjectSchema<{
|
|
79
|
+
/** `person:<id>`, `identity:<id>`, `name:<lowercased name>` or `unknown`. */
|
|
80
|
+
readonly key: v.StringSchema<undefined>;
|
|
81
|
+
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
82
|
+
readonly person_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
83
|
+
readonly identity_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
84
|
+
readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
85
|
+
readonly lines: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
86
|
+
readonly words: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
87
|
+
readonly talk_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
88
|
+
/** This speaker's part of all talk time, 0–1. */
|
|
89
|
+
readonly share: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>]>;
|
|
90
|
+
}, undefined>, undefined>;
|
|
91
|
+
}, undefined>;
|
|
92
|
+
export declare const meetingStatsItem: (found: MeetingStats, top?: number) => v.InferOutput<typeof meetingStats>;
|
|
93
|
+
/** `meetings people`: one page of participant observations whose name or email matches. */
|
|
94
|
+
export declare const meetingParticipants: v.StrictObjectSchema<{
|
|
95
|
+
readonly schema_version: v.LiteralSchema<1, undefined>;
|
|
96
|
+
readonly kind: v.LiteralSchema<"meeting_participants", undefined>;
|
|
97
|
+
readonly account_id: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
98
|
+
readonly query: v.StringSchema<undefined>;
|
|
99
|
+
readonly items: v.ArraySchema<v.StrictObjectSchema<{
|
|
100
|
+
readonly participant_id: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
101
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
102
|
+
readonly identity_id: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
103
|
+
readonly display_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
104
|
+
readonly email: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
105
|
+
}, undefined>, undefined>;
|
|
106
|
+
/** Several identities on one page are observations, never speaker attribution or person links. */
|
|
107
|
+
readonly ambiguity: v.StrictObjectSchema<{
|
|
108
|
+
readonly scope: v.LiteralSchema<"page", undefined>;
|
|
109
|
+
readonly multiple_identities: v.BooleanSchema<undefined>;
|
|
110
|
+
readonly identity_ids: v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
111
|
+
}, undefined>;
|
|
112
|
+
readonly coverage: v.StrictObjectSchema<{
|
|
113
|
+
readonly scanned: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
114
|
+
readonly read_bytes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
115
|
+
readonly archive_completeness: v.LiteralSchema<"unknown", undefined>;
|
|
116
|
+
readonly truncated_by: v.NullableSchema<v.PicklistSchema<("limit" | "read_bytes" | "scan_limit")[], undefined>, undefined>;
|
|
117
|
+
}, undefined>;
|
|
118
|
+
readonly page: v.StrictObjectSchema<{
|
|
119
|
+
readonly mode: v.LiteralSchema<"cursor", undefined>;
|
|
120
|
+
readonly limit: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
121
|
+
readonly has_more: v.BooleanSchema<undefined>;
|
|
122
|
+
readonly next_cursor: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
123
|
+
}, undefined>;
|
|
124
|
+
}, undefined>;
|
|
125
|
+
/** `meetings passage`: a transcript line with the lines around it. */
|
|
126
|
+
export declare const meetingPassage: v.StrictObjectSchema<{
|
|
127
|
+
readonly schema_version: v.LiteralSchema<1, undefined>;
|
|
128
|
+
readonly kind: v.LiteralSchema<"meeting_context", undefined>;
|
|
129
|
+
readonly source: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
130
|
+
readonly target_ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
131
|
+
readonly target_fingerprint: v.StringSchema<undefined>;
|
|
132
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
133
|
+
readonly revision: v.PicklistSchema<["current", "superseded"], undefined>;
|
|
134
|
+
readonly limits: v.StrictObjectSchema<{
|
|
135
|
+
readonly before: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
136
|
+
readonly after: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
137
|
+
readonly bytes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
138
|
+
readonly max_read_bytes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
139
|
+
}, undefined>;
|
|
140
|
+
readonly content_bytes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
141
|
+
readonly coverage: v.StrictObjectSchema<{
|
|
142
|
+
readonly included: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
143
|
+
readonly before: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
144
|
+
readonly after: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
145
|
+
readonly has_before: v.BooleanSchema<undefined>;
|
|
146
|
+
readonly has_after: v.BooleanSchema<undefined>;
|
|
147
|
+
readonly truncated_by: v.NullableSchema<v.PicklistSchema<"bytes"[], undefined>, undefined>;
|
|
148
|
+
readonly before_ref: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
149
|
+
readonly after_ref: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
150
|
+
readonly continuation: v.LiteralSchema<"anchor-inclusive", undefined>;
|
|
151
|
+
readonly archive_completeness: v.LiteralSchema<"unknown", undefined>;
|
|
152
|
+
readonly input: v.LiteralSchema<"bounded-meeting-context", undefined>;
|
|
153
|
+
}, undefined>;
|
|
154
|
+
readonly items: v.ArraySchema<v.StrictObjectSchema<{
|
|
155
|
+
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
156
|
+
readonly fingerprint: v.StringSchema<undefined>;
|
|
157
|
+
readonly transcript_id: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
158
|
+
readonly content_hash: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
159
|
+
readonly position: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
160
|
+
readonly start_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
161
|
+
readonly end_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
162
|
+
readonly speaker_participant_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
163
|
+
readonly speaker_name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
164
|
+
readonly text: v.StringSchema<undefined>;
|
|
165
|
+
readonly revision: v.PicklistSchema<["current", "superseded"], undefined>;
|
|
166
|
+
}, undefined>, undefined>;
|
|
167
|
+
}, undefined>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { isoTime, reference } from "@wirecat/cli-base/standards";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { formatMeetingReference } from "./reference.js";
|
|
4
|
+
const text = v.string();
|
|
5
|
+
const count = v.pipe(v.number(), v.integer(), v.minValue(0));
|
|
6
|
+
const id = v.pipe(v.number(), v.integer(), v.minValue(1));
|
|
7
|
+
const iso = (ms) => (ms === null ? null : new Date(ms).toISOString());
|
|
8
|
+
const meetingRef = (accountId, meetingId) => formatMeetingReference({ type: "meeting", accountId, meetingId });
|
|
9
|
+
/** One meeting in `review`: what the store holds about it, never transcript text. */
|
|
10
|
+
export const meetingReview = v.strictObject({
|
|
11
|
+
ref: reference,
|
|
12
|
+
id: v.pipe(v.string(), v.minLength(1)),
|
|
13
|
+
title: v.nullable(text),
|
|
14
|
+
started_at: v.nullable(isoTime),
|
|
15
|
+
duration_ms: v.nullable(count),
|
|
16
|
+
participants_count: v.nullable(count),
|
|
17
|
+
projects: v.array(text),
|
|
18
|
+
/** Null when the meeting has no current transcript. */
|
|
19
|
+
transcript: v.nullable(v.strictObject({ lines: count, words: count })),
|
|
20
|
+
/** The three who talked longest. */
|
|
21
|
+
speakers: v.array(v.strictObject({ name: v.nullable(text), talk_ms: count })),
|
|
22
|
+
/** The newest stored summary; null when there is none. */
|
|
23
|
+
summary: v.nullable(v.strictObject({
|
|
24
|
+
source: text,
|
|
25
|
+
title: v.nullable(text),
|
|
26
|
+
overview: v.nullable(text),
|
|
27
|
+
next_steps: v.array(text),
|
|
28
|
+
url: v.nullable(text),
|
|
29
|
+
})),
|
|
30
|
+
});
|
|
31
|
+
export const meetingReviewItem = (one) => ({
|
|
32
|
+
ref: meetingRef(one.accountId, one.meetingId),
|
|
33
|
+
id: String(one.meetingId),
|
|
34
|
+
title: one.title,
|
|
35
|
+
started_at: iso(one.startedAt),
|
|
36
|
+
duration_ms: one.durationMs,
|
|
37
|
+
participants_count: one.participantsCount,
|
|
38
|
+
projects: one.projects,
|
|
39
|
+
transcript: one.transcript,
|
|
40
|
+
speakers: one.speakers.map((speaker) => ({ name: speaker.name, talk_ms: speaker.talkMs })),
|
|
41
|
+
summary: one.summary && {
|
|
42
|
+
source: one.summary.source,
|
|
43
|
+
title: one.summary.title,
|
|
44
|
+
overview: one.summary.overview,
|
|
45
|
+
next_steps: one.summary.nextSteps,
|
|
46
|
+
url: one.summary.url,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
/** A link shared in meeting chat, with where and how often; `mentions list` answers these. */
|
|
50
|
+
export const meetingLink = v.strictObject({
|
|
51
|
+
url: text,
|
|
52
|
+
domain: v.nullable(text),
|
|
53
|
+
/** The Google Docs, Sheets, Slides, Forms or Drive file it names. */
|
|
54
|
+
document_id: v.nullable(text),
|
|
55
|
+
count,
|
|
56
|
+
first_at: isoTime,
|
|
57
|
+
last_at: isoTime,
|
|
58
|
+
senders: v.array(text),
|
|
59
|
+
meetings: v.array(v.strictObject({ ref: reference, title: v.nullable(text) })),
|
|
60
|
+
});
|
|
61
|
+
export const meetingLinkItem = (link) => ({
|
|
62
|
+
url: link.url,
|
|
63
|
+
domain: link.domain,
|
|
64
|
+
document_id: link.documentId,
|
|
65
|
+
count: link.count,
|
|
66
|
+
first_at: new Date(link.firstAt).toISOString(),
|
|
67
|
+
last_at: new Date(link.lastAt).toISOString(),
|
|
68
|
+
senders: link.senders,
|
|
69
|
+
meetings: link.meetings.map((one) => ({ ref: meetingRef(one.accountId, one.meetingId), title: one.title })),
|
|
70
|
+
});
|
|
71
|
+
/** One speaker's talk over the selected meetings; `stats meetings top` answers these. */
|
|
72
|
+
export const meetingSpeaker = v.strictObject({
|
|
73
|
+
/** `person:<id>`, `identity:<id>`, `name:<lowercased name>` or `unknown`. */
|
|
74
|
+
key: text,
|
|
75
|
+
name: v.nullable(text),
|
|
76
|
+
person_id: v.nullable(id),
|
|
77
|
+
identity_id: v.nullable(id),
|
|
78
|
+
meetings: count,
|
|
79
|
+
lines: count,
|
|
80
|
+
words: count,
|
|
81
|
+
talk_ms: count,
|
|
82
|
+
/** This speaker's part of all talk time, 0–1. */
|
|
83
|
+
share: v.pipe(v.number(), v.minValue(0), v.maxValue(1)),
|
|
84
|
+
});
|
|
85
|
+
export const meetingSpeakerItem = (one) => ({
|
|
86
|
+
key: one.key,
|
|
87
|
+
name: one.name,
|
|
88
|
+
person_id: one.personId,
|
|
89
|
+
identity_id: one.identityId,
|
|
90
|
+
meetings: one.meetings,
|
|
91
|
+
lines: one.lines,
|
|
92
|
+
words: one.words,
|
|
93
|
+
talk_ms: one.talkMs,
|
|
94
|
+
share: one.share,
|
|
95
|
+
});
|
|
96
|
+
/** `stats meetings show`: how much was said over the selected meetings, by week, with the top speakers. */
|
|
97
|
+
export const meetingStats = v.strictObject({
|
|
98
|
+
time_zone: text,
|
|
99
|
+
meetings: count,
|
|
100
|
+
lines: count,
|
|
101
|
+
words: count,
|
|
102
|
+
talk_ms: count,
|
|
103
|
+
/** `week_start` is the Monday, as a date in `time_zone`. */
|
|
104
|
+
weeks: v.array(v.strictObject({ week_start: text, meetings: count, talk_ms: count })),
|
|
105
|
+
top_speakers: v.array(meetingSpeaker),
|
|
106
|
+
});
|
|
107
|
+
export const meetingStatsItem = (found, top = 10) => ({
|
|
108
|
+
time_zone: found.timeZone,
|
|
109
|
+
meetings: found.meetings,
|
|
110
|
+
lines: found.lines,
|
|
111
|
+
words: found.words,
|
|
112
|
+
talk_ms: found.talkMs,
|
|
113
|
+
weeks: found.weeks.map((week) => ({ week_start: week.weekStart, meetings: week.meetings, talk_ms: week.talkMs })),
|
|
114
|
+
top_speakers: found.speakers.slice(0, top).map(meetingSpeakerItem),
|
|
115
|
+
});
|
|
116
|
+
const truncated = (...why) => v.nullable(v.picklist(why));
|
|
117
|
+
/** `meetings people`: one page of participant observations whose name or email matches. */
|
|
118
|
+
export const meetingParticipants = v.strictObject({
|
|
119
|
+
schema_version: v.literal(1),
|
|
120
|
+
kind: v.literal("meeting_participants"),
|
|
121
|
+
account_id: id,
|
|
122
|
+
query: text,
|
|
123
|
+
items: v.array(v.strictObject({
|
|
124
|
+
participant_id: id,
|
|
125
|
+
meeting_id: id,
|
|
126
|
+
identity_id: id,
|
|
127
|
+
display_name: v.nullable(text),
|
|
128
|
+
email: v.nullable(text),
|
|
129
|
+
})),
|
|
130
|
+
/** Several identities on one page are observations, never speaker attribution or person links. */
|
|
131
|
+
ambiguity: v.strictObject({ scope: v.literal("page"), multiple_identities: v.boolean(), identity_ids: v.array(id) }),
|
|
132
|
+
coverage: v.strictObject({
|
|
133
|
+
scanned: count,
|
|
134
|
+
read_bytes: count,
|
|
135
|
+
archive_completeness: v.literal("unknown"),
|
|
136
|
+
truncated_by: truncated("limit", "scan_limit", "read_bytes"),
|
|
137
|
+
}),
|
|
138
|
+
page: v.strictObject({
|
|
139
|
+
mode: v.literal("cursor"),
|
|
140
|
+
limit: count,
|
|
141
|
+
has_more: v.boolean(),
|
|
142
|
+
next_cursor: v.optional(text),
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
const revision = v.picklist(["current", "superseded"]);
|
|
146
|
+
/** `meetings passage`: a transcript line with the lines around it. */
|
|
147
|
+
export const meetingPassage = v.strictObject({
|
|
148
|
+
schema_version: v.literal(1),
|
|
149
|
+
kind: v.literal("meeting_context"),
|
|
150
|
+
source: reference,
|
|
151
|
+
target_ref: reference,
|
|
152
|
+
target_fingerprint: text,
|
|
153
|
+
fingerprint: text,
|
|
154
|
+
revision,
|
|
155
|
+
limits: v.strictObject({ before: count, after: count, bytes: count, max_read_bytes: count }),
|
|
156
|
+
content_bytes: count,
|
|
157
|
+
coverage: v.strictObject({
|
|
158
|
+
included: count,
|
|
159
|
+
before: count,
|
|
160
|
+
after: count,
|
|
161
|
+
has_before: v.boolean(),
|
|
162
|
+
has_after: v.boolean(),
|
|
163
|
+
truncated_by: truncated("bytes"),
|
|
164
|
+
before_ref: v.nullable(reference),
|
|
165
|
+
after_ref: v.nullable(reference),
|
|
166
|
+
continuation: v.literal("anchor-inclusive"),
|
|
167
|
+
archive_completeness: v.literal("unknown"),
|
|
168
|
+
input: v.literal("bounded-meeting-context"),
|
|
169
|
+
}),
|
|
170
|
+
items: v.array(v.strictObject({
|
|
171
|
+
ref: reference,
|
|
172
|
+
fingerprint: text,
|
|
173
|
+
transcript_id: id,
|
|
174
|
+
content_hash: v.nullable(text),
|
|
175
|
+
position: count,
|
|
176
|
+
start_ms: count,
|
|
177
|
+
end_ms: count,
|
|
178
|
+
speaker_participant_id: v.nullable(id),
|
|
179
|
+
speaker_name: v.nullable(text),
|
|
180
|
+
text,
|
|
181
|
+
revision,
|
|
182
|
+
})),
|
|
183
|
+
});
|
package/dist/runs/run.d.ts
CHANGED
|
@@ -87,7 +87,7 @@ export declare const runsDirFor: (app: AppIdentity, env?: NodeJS.ProcessEnv) =>
|
|
|
87
87
|
* `run.json` is written **now**, with `status: "running"`, and again by `finish`. A directory
|
|
88
88
|
* holding events and no metadata is a special case `runs list` would carry forever.
|
|
89
89
|
*
|
|
90
|
-
* Each write also appends the metadata to the day's `index.jsonl`, which `runs list` and `runs
|
|
90
|
+
* Each write also appends the metadata to the day's `index.jsonl`, which `runs list` and `search runs`
|
|
91
91
|
* read instead of every `run.json`. It is only a cache: pruned with its day, and a day without one is read
|
|
92
92
|
* the slow way.
|
|
93
93
|
*/
|
|
@@ -95,13 +95,21 @@ export declare const startRun: (options: StartRunOptions) => Run;
|
|
|
95
95
|
export declare const runtime: () => string;
|
|
96
96
|
/** `20260920T084431Z-chats-list-a81f2c` — sortable, and readable without opening it. */
|
|
97
97
|
export declare const newRunId: (startedAt: Date, command: string) => string;
|
|
98
|
+
export interface RunListFilter {
|
|
99
|
+
runId?: string;
|
|
100
|
+
command?: string;
|
|
101
|
+
profile?: string;
|
|
102
|
+
status?: RunMetadata["status"];
|
|
103
|
+
errorCode?: string;
|
|
104
|
+
}
|
|
98
105
|
/**
|
|
99
106
|
* Newest first, which is the order anyone asking "what did I just do" wants. Days before `since` are
|
|
100
107
|
* not opened, nor any day once `atLeast` runs are in hand.
|
|
101
108
|
*/
|
|
102
|
-
export declare const listRuns: (runsDir: string, { since, atLeast }?: {
|
|
109
|
+
export declare const listRuns: (runsDir: string, { since, atLeast, filter, }?: {
|
|
103
110
|
since?: number;
|
|
104
111
|
atLeast?: number;
|
|
112
|
+
filter?: RunListFilter;
|
|
105
113
|
}) => RunMetadata[];
|
|
106
114
|
export declare const findRun: (runsDir: string, id: string) => {
|
|
107
115
|
dir: string;
|
package/dist/runs/run.js
CHANGED
|
@@ -19,7 +19,7 @@ export const runsDirFor = (app, env = process.env) => join(resolvePaths({ appNam
|
|
|
19
19
|
* `run.json` is written **now**, with `status: "running"`, and again by `finish`. A directory
|
|
20
20
|
* holding events and no metadata is a special case `runs list` would carry forever.
|
|
21
21
|
*
|
|
22
|
-
* Each write also appends the metadata to the day's `index.jsonl`, which `runs list` and `runs
|
|
22
|
+
* Each write also appends the metadata to the day's `index.jsonl`, which `runs list` and `search runs`
|
|
23
23
|
* read instead of every `run.json`. It is only a cache: pruned with its day, and a day without one is read
|
|
24
24
|
* the slow way.
|
|
25
25
|
*/
|
|
@@ -124,17 +124,25 @@ const writeRunFile = (dir, metadata) => {
|
|
|
124
124
|
// The index only makes reading faster; a day without one is read run by run.
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
|
+
const matchesListFilter = (run, filter) => (filter.runId === undefined || run.runId === filter.runId) &&
|
|
128
|
+
(filter.command === undefined || run.command === filter.command) &&
|
|
129
|
+
(filter.profile === undefined || run.profile === filter.profile) &&
|
|
130
|
+
(filter.status === undefined || run.status === filter.status) &&
|
|
131
|
+
(filter.errorCode === undefined || run.errorCode === filter.errorCode);
|
|
127
132
|
/**
|
|
128
133
|
* Newest first, which is the order anyone asking "what did I just do" wants. Days before `since` are
|
|
129
134
|
* not opened, nor any day once `atLeast` runs are in hand.
|
|
130
135
|
*/
|
|
131
|
-
export const listRuns = (runsDir, { since, atLeast = Number.POSITIVE_INFINITY } = {}) => {
|
|
136
|
+
export const listRuns = (runsDir, { since, atLeast = Number.POSITIVE_INFINITY, filter = {}, } = {}) => {
|
|
132
137
|
const first = since === undefined ? undefined : day(new Date(since));
|
|
133
138
|
const runs = [];
|
|
134
139
|
for (const date of days(runsDir).sort().reverse()) {
|
|
135
140
|
if ((first !== undefined && date < first) || runs.length >= atLeast)
|
|
136
141
|
break;
|
|
137
|
-
|
|
142
|
+
for (const metadata of runsOfDay(join(runsDir, date))) {
|
|
143
|
+
if (matchesListFilter(metadata, filter))
|
|
144
|
+
runs.push(metadata);
|
|
145
|
+
}
|
|
138
146
|
}
|
|
139
147
|
return runs;
|
|
140
148
|
};
|
package/dist/sends/journal.d.ts
CHANGED
|
@@ -59,6 +59,13 @@ export interface SendEntry {
|
|
|
59
59
|
reservation?: string;
|
|
60
60
|
errorCode?: string;
|
|
61
61
|
}
|
|
62
|
+
export interface SendFilter {
|
|
63
|
+
outcome?: SendOutcome;
|
|
64
|
+
chatId?: Id;
|
|
65
|
+
operationId?: string;
|
|
66
|
+
errorCode?: string;
|
|
67
|
+
key?: string;
|
|
68
|
+
}
|
|
62
69
|
/**
|
|
63
70
|
* `<state dir>/sends/<profile>.jsonl` — beside `runs`, never in the cache directory, so that
|
|
64
71
|
* clearing a cache cannot erase what was sent in the owner's name.
|
|
@@ -88,5 +95,5 @@ export declare class SendJournal {
|
|
|
88
95
|
* Oldest first, each reservation folded into its outcome; one with no outcome yet is in flight,
|
|
89
96
|
* or its process died. A line that does not parse is skipped: a torn last write must not block sending.
|
|
90
97
|
*/
|
|
91
|
-
entries(): SendEntry[];
|
|
98
|
+
entries(filter?: SendFilter): SendEntry[];
|
|
92
99
|
}
|
package/dist/sends/journal.js
CHANGED
|
@@ -54,13 +54,20 @@ export class SendJournal {
|
|
|
54
54
|
* Oldest first, each reservation folded into its outcome; one with no outcome yet is in flight,
|
|
55
55
|
* or its process died. A line that does not parse is skipped: a torn last write must not block sending.
|
|
56
56
|
*/
|
|
57
|
-
entries() {
|
|
57
|
+
entries(filter) {
|
|
58
58
|
const lines = this.#lines();
|
|
59
59
|
const settled = new Set(lines.filter((entry) => entry.outcome !== "reserved").map((entry) => entry.reservation));
|
|
60
|
-
|
|
60
|
+
const entries = lines
|
|
61
61
|
.filter((entry) => entry.outcome !== "reserved" || !settled.has(entry.reservation))
|
|
62
62
|
.map(({ reservation, ...entry }) => (entry.outcome === "reserved" ? { ...entry, reservation } : entry))
|
|
63
63
|
.map(withSendId);
|
|
64
|
+
return filter === undefined
|
|
65
|
+
? entries
|
|
66
|
+
: entries.filter((entry) => (filter.outcome === undefined || entry.outcome === filter.outcome) &&
|
|
67
|
+
(filter.chatId === undefined || entry.chatId === filter.chatId) &&
|
|
68
|
+
(filter.operationId === undefined || entry.operationId === filter.operationId) &&
|
|
69
|
+
(filter.errorCode === undefined || entry.errorCode === filter.errorCode) &&
|
|
70
|
+
(filter.key === undefined || entry.key === filter.key));
|
|
64
71
|
}
|
|
65
72
|
#lines() {
|
|
66
73
|
let text;
|
|
@@ -17,8 +17,12 @@ export type PermissionKey = string;
|
|
|
17
17
|
export declare const skipFlagFor: (key: string) => "--allow-dangerous" | "--yes";
|
|
18
18
|
/** Only what cannot be undone asks; the tool is meant to work without questions (owner, NEED-460). */
|
|
19
19
|
export declare const DEFAULT_PERMISSIONS: Readonly<Record<PermissionKey, Level>>;
|
|
20
|
+
/** Lets an MCP server offer the commands that change what a later run may do (`grantsAuthority`). */
|
|
21
|
+
export declare const AUTHORITY_KEY: PermissionKey;
|
|
22
|
+
/** Whether these levels let an agent run a command that changes what a later run may do; `ask` does, as for any write. */
|
|
23
|
+
export declare const authorityAllowed: (levels: Readonly<Record<PermissionKey, Level>>) => boolean;
|
|
20
24
|
/** The resources at the top of the command tree, which `readOnly` and `allow` turn read-only as a whole. */
|
|
21
|
-
export declare const RESOURCES: readonly ["messages", "reactions", "polls", "topics", "chats", "contacts", "account", "bot", "conversations", "tags", "mentions", "search", "searches", "tasks", "replies", "attachments", "stats", "store", "metadata"];
|
|
25
|
+
export declare const RESOURCES: readonly ["messages", "reactions", "polls", "topics", "chats", "contacts", "account", "bot", "conversations", "tags", "mentions", "search", "searches", "tasks", "replies", "attachments", "stats", "store", "metadata", "mcp"];
|
|
22
26
|
/** The command path an old `allow` word stood for, as one key — what an MCP tool's `permission` is checked against. */
|
|
23
27
|
export declare const keyOfWord: (word: Permission) => PermissionKey;
|
|
24
28
|
/**
|
|
@@ -77,6 +77,15 @@ export const DEFAULT_PERMISSIONS = {
|
|
|
77
77
|
"chats.clear": "ask",
|
|
78
78
|
// NEED-568: a rule writes to people with nobody typing a command; it waits for the owner's own allow.
|
|
79
79
|
"replies.send": "deny",
|
|
80
|
+
// NEED-1662: an agent that changes settings, schedules or recipients could lift its own limits; the owner opts in.
|
|
81
|
+
"mcp.authority": "deny",
|
|
82
|
+
};
|
|
83
|
+
/** Lets an MCP server offer the commands that change what a later run may do (`grantsAuthority`). */
|
|
84
|
+
export const AUTHORITY_KEY = "mcp.authority";
|
|
85
|
+
/** Whether these levels let an agent run a command that changes what a later run may do; `ask` does, as for any write. */
|
|
86
|
+
export const authorityAllowed = (levels) => {
|
|
87
|
+
const { level } = levelFor(levels, AUTHORITY_KEY);
|
|
88
|
+
return level === "allow" || level === "ask";
|
|
80
89
|
};
|
|
81
90
|
/** The resources at the top of the command tree, which `readOnly` and `allow` turn read-only as a whole. */
|
|
82
91
|
export const RESOURCES = [
|
|
@@ -99,6 +108,7 @@ export const RESOURCES = [
|
|
|
99
108
|
"stats",
|
|
100
109
|
"store",
|
|
101
110
|
"metadata",
|
|
111
|
+
"mcp",
|
|
102
112
|
];
|
|
103
113
|
const OLD_WORDS = {
|
|
104
114
|
send: ["messages.send", "polls.create", "chats.start"],
|
|
@@ -428,7 +438,7 @@ export const keyForCommand = (path) => {
|
|
|
428
438
|
const inner = keyForCommand(path.slice(1));
|
|
429
439
|
return `bot.${inner ?? path.slice(1).join(".")}`;
|
|
430
440
|
}
|
|
431
|
-
if (top === undefined || HOUSEKEEPING.has(top))
|
|
441
|
+
if (top === undefined || HOUSEKEEPING.has(top) || (top === "search" && next === "runs"))
|
|
432
442
|
return null;
|
|
433
443
|
// Picture models moved from `models image` (0.270.0); a model is housekeeping wherever it is listed.
|
|
434
444
|
if (top === "images" && next === "models")
|
|
@@ -7,6 +7,10 @@ export interface Recipient {
|
|
|
7
7
|
partnerId?: Id;
|
|
8
8
|
addedAt: string;
|
|
9
9
|
}
|
|
10
|
+
export interface RecipientFilter {
|
|
11
|
+
id?: Id;
|
|
12
|
+
title?: string;
|
|
13
|
+
}
|
|
10
14
|
/**
|
|
11
15
|
* A state file, not a setting: the configuration schema has deliberately no place for a chat id,
|
|
12
16
|
* and this list is data about a profile rather than a preference.
|
|
@@ -25,6 +29,10 @@ export declare class RecipientList {
|
|
|
25
29
|
constructor(path: string, command: string, lockWaitMs?: number | undefined);
|
|
26
30
|
/** `undefined` when the list is off. A file that cannot be read refuses rather than opening up. */
|
|
27
31
|
read(): Recipient[] | undefined;
|
|
32
|
+
list(filter?: RecipientFilter): {
|
|
33
|
+
state: "off" | "empty" | "on";
|
|
34
|
+
items: Recipient[];
|
|
35
|
+
};
|
|
28
36
|
/** Whether it was new. Adding one again fills in a partner an older entry was stored without. */
|
|
29
37
|
add(recipient: Recipient): boolean;
|
|
30
38
|
/** `add` waiting for the lock on timers: `recipients add` connects, so it runs inside `serve` when one holds the account. */
|
package/dist/sends/recipients.js
CHANGED
|
@@ -36,6 +36,15 @@ export class RecipientList {
|
|
|
36
36
|
`fix the file or turn the list off with \`${this.command} recipients clear\``);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
list(filter = {}) {
|
|
40
|
+
const chats = this.read();
|
|
41
|
+
// A query that matches nothing must not describe a nonempty allowlist as allowing nowhere.
|
|
42
|
+
return {
|
|
43
|
+
state: chats === undefined ? "off" : chats.length === 0 ? "empty" : "on",
|
|
44
|
+
items: (chats ?? []).filter((chat) => (filter.id === undefined || chat.id === filter.id) &&
|
|
45
|
+
(filter.title === undefined || chat.title?.toLocaleLowerCase() === filter.title.toLocaleLowerCase())),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
39
48
|
/** Whether it was new. Adding one again fills in a partner an older entry was stored without. */
|
|
40
49
|
add(recipient) {
|
|
41
50
|
return this.#locked(() => this.#added(recipient));
|
|
@@ -216,12 +216,12 @@ export const adminStatisticsService = (deps) => ({
|
|
|
216
216
|
cutoff,
|
|
217
217
|
olderThan: query.olderThan === undefined && pinned
|
|
218
218
|
? pinned.options.olderThan
|
|
219
|
-
: duration(query.olderThan ?? "24h", "
|
|
219
|
+
: duration(query.olderThan ?? "24h", "older_than"),
|
|
220
220
|
within: query.within === undefined && pinned ? pinned.options.within : duration(query.within ?? "7d", "--within"),
|
|
221
221
|
joinSince: window.since ?? pinned?.options.joinSince ?? cutoff - 30 * 86_400_000,
|
|
222
222
|
joinUntil: window.until ?? pinned?.options.joinUntil ?? cutoff,
|
|
223
|
-
minViews: count(query.minViews ?? pinned?.options.minViews ?? 1, "
|
|
224
|
-
maxReplies: count(query.maxReplies ?? pinned?.options.maxReplies ?? 0, "
|
|
223
|
+
minViews: count(query.minViews ?? pinned?.options.minViews ?? 1, "min_views"),
|
|
224
|
+
maxReplies: count(query.maxReplies ?? pinned?.options.maxReplies ?? 0, "max_replies"),
|
|
225
225
|
answerers: query.answerers === undefined && pinned
|
|
226
226
|
? pinned.options.answerers
|
|
227
227
|
: await answerers(store, query.answerers ?? [], prepared.execution.accounts),
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { googleDocumentLinks } from "../domain/google-documents.js";
|
|
2
|
-
import { formatLocator } from "../domain/locator.js";
|
|
2
|
+
import { formatLocator, parseLocator } from "../domain/locator.js";
|
|
3
3
|
import { accountStore } from "./deps.js";
|
|
4
4
|
import { chatIdIn } from "./message-resolution.js";
|
|
5
5
|
export const chatDocumentsService = (deps) => ({
|
|
6
|
-
list: async (chat, { limit, offset }) => {
|
|
6
|
+
list: async (chat, { limit, offset, ref }) => {
|
|
7
7
|
const store = await accountStore(deps);
|
|
8
8
|
const chatId = await chatIdIn(deps.messenger, chat, store, { includeLeft: true });
|
|
9
|
-
const
|
|
9
|
+
const target = ref === undefined ? undefined : parseLocator(ref);
|
|
10
|
+
const sameScope = target === undefined ||
|
|
11
|
+
(target.provider === store.account.provider && target.account === store.account.account && target.chat === chatId);
|
|
12
|
+
const messages = sameScope
|
|
13
|
+
? await store.messages.documentLinkMessages(chatId, target ? { messageId: target.message } : {})
|
|
14
|
+
: [];
|
|
15
|
+
const items = messages.flatMap((message) => googleDocumentLinks(message.text).map(({ url, documentId }) => {
|
|
10
16
|
const stored = documentId === null ? undefined : message.documents.find((one) => one.fileId === documentId);
|
|
11
17
|
return {
|
|
12
18
|
url,
|
package/dist/services/chats.d.ts
CHANGED
|
@@ -79,7 +79,7 @@ export interface ChatsService {
|
|
|
79
79
|
track?: boolean;
|
|
80
80
|
}): Promise<FetchedMembers>;
|
|
81
81
|
/** The chats whose members `serve` fetches daily, from the store. */
|
|
82
|
-
tracked(): Promise<TrackedChat[]>;
|
|
82
|
+
tracked(query?: QueryAst): Promise<TrackedChat[]>;
|
|
83
83
|
/** One chat's tracking and its member counts of the last `TRACKED_DAYS` days, tracked or not. */
|
|
84
84
|
trackedChat(chat: string): Promise<{
|
|
85
85
|
chatId: Id;
|
package/dist/services/chats.js
CHANGED
|
@@ -7,7 +7,7 @@ import { syncsOneChat } from "../ports/traits.js";
|
|
|
7
7
|
import { typedCommand } from "../runs/scope.js";
|
|
8
8
|
import { codeOf, guardedWrite } from "../sends/guarded.js";
|
|
9
9
|
import { newOperationId } from "../sends/send-id.js";
|
|
10
|
-
import { CHAT_COLUMNS, queryFilter, } from "../store/store.js";
|
|
10
|
+
import { CHAT_COLUMNS, queryFilter, TRACKED_CHAT_COLUMNS, } from "../store/store.js";
|
|
11
11
|
import { chatStats } from "./chat-stats.js";
|
|
12
12
|
import { accountStore, accountStoreIfOpen, fromStore, nothingStored, unlessBusy } from "./deps.js";
|
|
13
13
|
import { memberEvents } from "./member-history.js";
|
|
@@ -210,7 +210,10 @@ export const chatsService = (deps) => ({
|
|
|
210
210
|
const tracked = (await store.roster.trackedChats()).some((one) => one.chatId === chatId);
|
|
211
211
|
return { chatId, read: members.length, participants, complete, more, ...change, tracked };
|
|
212
212
|
},
|
|
213
|
-
tracked: async () =>
|
|
213
|
+
tracked: async (query) => {
|
|
214
|
+
const where = query ? queryFilter(query, TRACKED_CHAT_COLUMNS, { command: "chats tracking list" }) : undefined;
|
|
215
|
+
return (await accountStore(deps)).roster.trackedChats(where ? { where } : {});
|
|
216
|
+
},
|
|
214
217
|
memberHistory: async (chat, { since }) => {
|
|
215
218
|
const store = await accountStore(deps);
|
|
216
219
|
const chatId = await chatIdIn(deps.messenger, chat, store, { includeLeft: true });
|