@wirecat/cli-core 0.405.0 → 0.407.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 +36 -1
- package/dist/botcheck/reasons.d.ts +1 -1
- package/dist/cli/analysis-choice.js +1 -1
- package/dist/cli/answer-entity.d.ts +8 -0
- package/dist/cli/answer-entity.js +31 -0
- package/dist/cli/command-contract.js +5 -6
- package/dist/cli/commands-command.js +4 -1
- package/dist/cli/effects.js +1 -1
- package/dist/cli/embedding-choice.d.ts +1 -1
- package/dist/cli/embedding-choice.js +2 -2
- package/dist/cli/help/command-help.js +2 -2
- package/dist/cli/index.d.ts +6 -2
- package/dist/cli/index.js +6 -2
- package/dist/cli/json-fields.js +2 -2
- package/dist/cli/meeting-batch.d.ts +1 -1
- package/dist/cli/meeting-batch.js +20 -2
- package/dist/cli/meeting-project-candidates-command.js +0 -1
- package/dist/cli/meeting-results.d.ts +3 -0
- package/dist/cli/meeting-results.js +31 -0
- package/dist/cli/meeting-series-inventory-command.js +0 -1
- package/dist/cli/messenger/admin-commands.js +14 -14
- package/dist/cli/messenger/archive-commands.js +2 -2
- package/dist/cli/messenger/attachments-command.js +7 -8
- package/dist/cli/messenger/backfill-command.js +1 -1
- package/dist/cli/messenger/chat-answers.js +3 -3
- package/dist/cli/messenger/chat-lists.js +3 -3
- package/dist/cli/messenger/chats-command.js +8 -8
- package/dist/cli/messenger/chats-members-command.js +1 -1
- package/dist/cli/messenger/contacts-command.js +10 -7
- package/dist/cli/messenger/context.d.ts +11 -4
- package/dist/cli/messenger/context.js +6 -0
- package/dist/cli/messenger/conversation-examples.js +7 -6
- package/dist/cli/messenger/conversations-command.d.ts +0 -4
- package/dist/cli/messenger/conversations-command.js +130 -135
- package/dist/cli/messenger/counters-command.js +4 -2
- package/dist/cli/messenger/doctor-command.js +8 -4
- package/dist/cli/messenger/gaps-command.js +2 -2
- 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 -1
- package/dist/cli/messenger/inbox.js +1 -3
- package/dist/cli/messenger/lacks.d.ts +1 -0
- package/dist/cli/messenger/lacks.js +1 -1
- package/dist/cli/messenger/mcp-command.js +4 -4
- package/dist/cli/messenger/messages-comments-command.js +10 -5
- package/dist/cli/messenger/metadata-command.js +5 -5
- package/dist/cli/messenger/models-command.js +101 -90
- package/dist/cli/messenger/private-people-command.js +5 -6
- package/dist/cli/messenger/replies-edit-command.js +0 -1
- package/dist/cli/messenger/review.js +1 -3
- package/dist/cli/messenger/serve-relay.d.ts +1 -0
- package/dist/cli/messenger/stats-command.js +1 -1
- package/dist/cli/messenger/store-maintenance-command.d.ts +1 -1
- package/dist/cli/messenger/store-maintenance-command.js +4 -4
- package/dist/cli/messenger/stored.js +5 -0
- package/dist/cli/messenger/tags-command.js +4 -10
- package/dist/cli/messenger/tasks-command.js +3 -3
- package/dist/cli/messenger/transcribe-command.js +1 -1
- package/dist/cli/moved.d.ts +2 -0
- package/dist/cli/moved.js +39 -1
- package/dist/cli/permission-keys.js +2 -0
- package/dist/cli/result-fields.js +19 -1
- package/dist/cli/settings.js +1 -1
- package/dist/cli/steps.js +4 -4
- package/dist/cli/store-settings.js +1 -1
- package/dist/cli/upgrade-command.js +0 -1
- package/dist/domain/models.d.ts +3 -3
- package/dist/domain/task-categories.js +1 -1
- package/dist/embeddings/remote.js +1 -1
- package/dist/entities/contact.d.ts +6 -0
- package/dist/entities/contact.js +3 -0
- package/dist/entities/index.d.ts +139 -0
- package/dist/entities/index.js +4 -1
- package/dist/entities/member.d.ts +2 -2
- package/dist/entities/member.js +2 -2
- package/dist/entities/store-records.d.ts +11 -0
- package/dist/entities/store-records.js +1 -0
- package/dist/mcp/agent.d.ts +1 -0
- package/dist/mcp/agent.js +1 -1
- package/dist/mcp/tools/attachments.js +1 -1
- package/dist/meetings/cli/index.js +10 -3
- package/dist/meetings/index.d.ts +1 -0
- package/dist/meetings/index.js +1 -0
- package/dist/meetings/result-items.d.ts +127 -0
- package/dist/meetings/result-items.js +125 -0
- package/dist/ports/app.d.ts +1 -1
- package/dist/ports/messenger.d.ts +6 -1
- package/dist/search/task-similarity.js +1 -1
- package/dist/sends/guard.js +2 -2
- package/dist/sends/permission-aliases.d.ts +5 -0
- package/dist/sends/permission-aliases.js +49 -0
- package/dist/sends/permissions.js +33 -25
- package/dist/services/admin.js +7 -7
- package/dist/services/chats.js +1 -1
- package/dist/services/conversations.d.ts +1 -1
- package/dist/services/conversations.js +1 -1
- package/dist/services/counters.js +1 -1
- package/dist/services/embeddings-maintenance.js +2 -2
- package/dist/services/embeddings-search.js +1 -1
- package/dist/services/embeddings.d.ts +4 -4
- package/dist/services/messages-search.d.ts +1 -1
- package/dist/services/messages-search.js +2 -2
- package/dist/services/metadata.js +2 -2
- package/dist/services/notes-search.js +3 -3
- package/dist/services/search-catchup.js +1 -1
- package/dist/speech/install.d.ts +4 -2
- package/dist/speech/install.js +16 -4
- package/dist/speech/local.js +1 -1
- package/dist/speech/transcribe.js +1 -1
- package/dist/store/search-index.d.ts +1 -1
- package/dist/store/sqlite/attachment-texts.d.ts +1 -1
- package/dist/store/sqlite/attachment-texts.js +1 -1
- package/dist/store/sqlite/batches.js +1 -1
- package/dist/store/sqlite/involvements.d.ts +1 -1
- package/dist/store/sqlite/note-index.d.ts +2 -2
- package/dist/store/sqlite/note-index.js +2 -2
- package/dist/store/sqlite/search-index.d.ts +1 -1
- package/dist/store/sqlite/search-index.js +1 -1
- package/dist/store/sqlite/stems-fill.d.ts +3 -3
- package/dist/store/sqlite/stems-fill.js +3 -3
- package/dist/store/sqlite/stems.d.ts +1 -1
- package/dist/store/sqlite/task-pairs.d.ts +1 -1
- package/dist/store/sqlite/task-pairs.js +1 -1
- package/package.json +1 -1
- package/parity.json +130 -139
- package/skills/follow-ups/SKILL.md +5 -5
- package/skills/link-conversations/SKILL.md +8 -8
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
export declare const MEETING_RESULT_ENTITIES: {
|
|
3
|
+
readonly meeting_ingestion: v.StrictObjectSchema<{
|
|
4
|
+
readonly meetings: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
5
|
+
readonly participants: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
6
|
+
readonly transcript_rows: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
7
|
+
readonly summaries: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
8
|
+
readonly warnings: v.ArraySchema<v.StrictObjectSchema<{
|
|
9
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
10
|
+
readonly message: v.StringSchema<undefined>;
|
|
11
|
+
}, undefined>, undefined>;
|
|
12
|
+
readonly timezone: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
13
|
+
}, undefined>;
|
|
14
|
+
readonly meeting_export: v.UnionSchema<[v.StrictObjectSchema<{
|
|
15
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
16
|
+
readonly format: v.PicklistSchema<["markdown", "vtt"], undefined>;
|
|
17
|
+
readonly filename: v.StringSchema<undefined>;
|
|
18
|
+
readonly content: v.StringSchema<undefined>;
|
|
19
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
20
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
21
|
+
readonly format: v.PicklistSchema<["markdown", "vtt"], undefined>;
|
|
22
|
+
readonly output: v.StringSchema<undefined>;
|
|
23
|
+
}, undefined>], undefined>;
|
|
24
|
+
readonly meeting_association: v.StrictObjectSchema<{
|
|
25
|
+
readonly scope: v.StrictObjectSchema<{
|
|
26
|
+
readonly provider: v.StringSchema<undefined>;
|
|
27
|
+
readonly account: v.StringSchema<undefined>;
|
|
28
|
+
}, undefined>;
|
|
29
|
+
readonly account_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
30
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
31
|
+
readonly change: v.UnionSchema<[v.StrictObjectSchema<{
|
|
32
|
+
readonly action: v.LiteralSchema<"event.link", undefined>;
|
|
33
|
+
readonly event_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
34
|
+
readonly expected_event_id: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>, undefined>;
|
|
35
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
36
|
+
readonly action: v.LiteralSchema<"person.link", undefined>;
|
|
37
|
+
readonly participant_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
38
|
+
readonly person_uid: v.StringSchema<undefined>;
|
|
39
|
+
readonly expected_person_uid: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
40
|
+
readonly target_account_ids: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>, undefined>;
|
|
41
|
+
}, undefined>], undefined>;
|
|
42
|
+
readonly applied: v.BooleanSchema<undefined>;
|
|
43
|
+
readonly result: v.OptionalSchema<v.UnionSchema<[v.StrictObjectSchema<{
|
|
44
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
45
|
+
readonly event_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
46
|
+
readonly previous_event_id: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
47
|
+
readonly changed: v.BooleanSchema<undefined>;
|
|
48
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
49
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
50
|
+
readonly participant_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
51
|
+
readonly person_uid: v.StringSchema<undefined>;
|
|
52
|
+
readonly previous_person_uid: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
53
|
+
readonly changed: v.BooleanSchema<undefined>;
|
|
54
|
+
}, undefined>], undefined>, undefined>;
|
|
55
|
+
}, undefined>;
|
|
56
|
+
readonly meeting_transcription: v.UnionSchema<[v.StrictObjectSchema<{
|
|
57
|
+
readonly applied: v.LiteralSchema<false, undefined>;
|
|
58
|
+
readonly account_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
59
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
60
|
+
readonly segments: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
61
|
+
readonly media: v.StrictObjectSchema<{
|
|
62
|
+
readonly id: v.StringSchema<undefined>;
|
|
63
|
+
readonly content_hash: v.StringSchema<undefined>;
|
|
64
|
+
readonly size: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
65
|
+
readonly duration_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
66
|
+
readonly format: v.StringSchema<undefined>;
|
|
67
|
+
readonly sample_rate: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
68
|
+
readonly channels: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
69
|
+
readonly recognition: v.StrictObjectSchema<{
|
|
70
|
+
readonly engine: v.StringSchema<undefined>;
|
|
71
|
+
readonly model: v.StringSchema<undefined>;
|
|
72
|
+
readonly version: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
73
|
+
readonly timing: v.OptionalSchema<v.PicklistSchema<["fixed-windows", "recognition-segments"], undefined>, undefined>;
|
|
74
|
+
}, undefined>;
|
|
75
|
+
}, undefined>;
|
|
76
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
77
|
+
readonly applied: v.LiteralSchema<true, undefined>;
|
|
78
|
+
readonly account_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
79
|
+
readonly external_id: v.StringSchema<undefined>;
|
|
80
|
+
readonly meeting_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
81
|
+
readonly created: v.BooleanSchema<undefined>;
|
|
82
|
+
readonly inserted_transcripts: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
83
|
+
readonly replayed_transcripts: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
84
|
+
readonly superseded_transcripts: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
85
|
+
readonly segments: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
86
|
+
readonly media_sha256: v.StringSchema<undefined>;
|
|
87
|
+
readonly engine: v.StringSchema<undefined>;
|
|
88
|
+
readonly model: v.StringSchema<undefined>;
|
|
89
|
+
readonly model_version: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
90
|
+
readonly timing: v.PicklistSchema<["fixed-windows", "recognition-segments"], undefined>;
|
|
91
|
+
}, undefined>], undefined>;
|
|
92
|
+
readonly meeting_embedding: v.UnionSchema<[v.StrictObjectSchema<{
|
|
93
|
+
readonly account_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
94
|
+
readonly model: v.StrictObjectSchema<{
|
|
95
|
+
readonly key: v.StringSchema<undefined>;
|
|
96
|
+
readonly dims: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
97
|
+
readonly kind: v.PicklistSchema<["local", "remote"], undefined>;
|
|
98
|
+
readonly model: v.StringSchema<undefined>;
|
|
99
|
+
}, undefined>;
|
|
100
|
+
readonly status: v.StrictObjectSchema<{
|
|
101
|
+
readonly chunks: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
102
|
+
readonly embedded: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
103
|
+
}, undefined>;
|
|
104
|
+
readonly applied: v.LiteralSchema<false, undefined>;
|
|
105
|
+
readonly scope: v.LiteralSchema<"existing-current-chunks", undefined>;
|
|
106
|
+
readonly rebuild_required: v.LiteralSchema<"explicit", undefined>;
|
|
107
|
+
}, undefined>, v.StrictObjectSchema<{
|
|
108
|
+
readonly account_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
109
|
+
readonly model: v.StrictObjectSchema<{
|
|
110
|
+
readonly key: v.StringSchema<undefined>;
|
|
111
|
+
readonly dims: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
112
|
+
readonly kind: v.PicklistSchema<["local", "remote"], undefined>;
|
|
113
|
+
readonly model: v.StringSchema<undefined>;
|
|
114
|
+
}, undefined>;
|
|
115
|
+
readonly saved: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
116
|
+
readonly skipped: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
117
|
+
readonly has_more: v.BooleanSchema<undefined>;
|
|
118
|
+
readonly next_hash: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
119
|
+
readonly applied: v.LiteralSchema<true, undefined>;
|
|
120
|
+
readonly rebuild: v.StrictObjectSchema<{
|
|
121
|
+
readonly transcripts: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
122
|
+
readonly chunks: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
123
|
+
readonly has_more: v.BooleanSchema<undefined>;
|
|
124
|
+
readonly next_transcript_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
125
|
+
}, undefined>;
|
|
126
|
+
}, undefined>], undefined>;
|
|
127
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
const text = v.string();
|
|
3
|
+
const identifier = v.pipe(text, v.minLength(1));
|
|
4
|
+
const nullableText = v.nullable(text);
|
|
5
|
+
const count = v.pipe(v.number(), v.integer(), v.minValue(0));
|
|
6
|
+
const flag = v.boolean();
|
|
7
|
+
const scope = v.strictObject({ provider: text, account: text });
|
|
8
|
+
const run = v.strictObject({
|
|
9
|
+
meetings: count,
|
|
10
|
+
participants: count,
|
|
11
|
+
transcript_rows: count,
|
|
12
|
+
summaries: count,
|
|
13
|
+
warnings: v.array(v.strictObject({ external_id: text, message: text })),
|
|
14
|
+
timezone: v.optional(text),
|
|
15
|
+
});
|
|
16
|
+
const exported = v.union([
|
|
17
|
+
v.strictObject({ meeting_id: identifier, format: v.picklist(["markdown", "vtt"]), filename: text, content: text }),
|
|
18
|
+
v.strictObject({ meeting_id: identifier, format: v.picklist(["markdown", "vtt"]), output: text }),
|
|
19
|
+
]);
|
|
20
|
+
const eventChange = v.strictObject({
|
|
21
|
+
action: v.literal("event.link"),
|
|
22
|
+
event_id: v.nullable(identifier),
|
|
23
|
+
expected_event_id: v.optional(v.nullable(identifier)),
|
|
24
|
+
});
|
|
25
|
+
const personChange = v.strictObject({
|
|
26
|
+
action: v.literal("person.link"),
|
|
27
|
+
participant_id: identifier,
|
|
28
|
+
person_uid: text,
|
|
29
|
+
expected_person_uid: v.optional(nullableText),
|
|
30
|
+
target_account_ids: v.optional(v.array(identifier)),
|
|
31
|
+
});
|
|
32
|
+
const eventResult = v.strictObject({
|
|
33
|
+
meeting_id: identifier,
|
|
34
|
+
event_id: v.nullable(identifier),
|
|
35
|
+
previous_event_id: v.nullable(identifier),
|
|
36
|
+
changed: flag,
|
|
37
|
+
});
|
|
38
|
+
const personResult = v.strictObject({
|
|
39
|
+
meeting_id: identifier,
|
|
40
|
+
participant_id: identifier,
|
|
41
|
+
person_uid: text,
|
|
42
|
+
previous_person_uid: nullableText,
|
|
43
|
+
changed: flag,
|
|
44
|
+
});
|
|
45
|
+
const meetingChange = v.strictObject({
|
|
46
|
+
scope,
|
|
47
|
+
account_id: identifier,
|
|
48
|
+
meeting_id: identifier,
|
|
49
|
+
change: v.union([eventChange, personChange]),
|
|
50
|
+
applied: flag,
|
|
51
|
+
result: v.optional(v.union([eventResult, personResult])),
|
|
52
|
+
});
|
|
53
|
+
const recognition = v.strictObject({
|
|
54
|
+
engine: text,
|
|
55
|
+
model: text,
|
|
56
|
+
version: v.optional(text),
|
|
57
|
+
timing: v.optional(v.picklist(["fixed-windows", "recognition-segments"])),
|
|
58
|
+
});
|
|
59
|
+
const transcription = v.union([
|
|
60
|
+
v.strictObject({
|
|
61
|
+
applied: v.literal(false),
|
|
62
|
+
account_id: identifier,
|
|
63
|
+
external_id: text,
|
|
64
|
+
segments: count,
|
|
65
|
+
media: v.strictObject({
|
|
66
|
+
id: text,
|
|
67
|
+
content_hash: text,
|
|
68
|
+
size: count,
|
|
69
|
+
duration_ms: count,
|
|
70
|
+
format: text,
|
|
71
|
+
sample_rate: count,
|
|
72
|
+
channels: count,
|
|
73
|
+
recognition,
|
|
74
|
+
}),
|
|
75
|
+
}),
|
|
76
|
+
v.strictObject({
|
|
77
|
+
applied: v.literal(true),
|
|
78
|
+
account_id: identifier,
|
|
79
|
+
external_id: text,
|
|
80
|
+
meeting_id: identifier,
|
|
81
|
+
created: flag,
|
|
82
|
+
inserted_transcripts: count,
|
|
83
|
+
replayed_transcripts: count,
|
|
84
|
+
superseded_transcripts: count,
|
|
85
|
+
segments: count,
|
|
86
|
+
media_sha256: text,
|
|
87
|
+
engine: text,
|
|
88
|
+
model: text,
|
|
89
|
+
model_version: nullableText,
|
|
90
|
+
timing: v.picklist(["fixed-windows", "recognition-segments"]),
|
|
91
|
+
}),
|
|
92
|
+
]);
|
|
93
|
+
const embeddingModel = v.strictObject({ key: text, dims: count, kind: v.picklist(["local", "remote"]), model: text });
|
|
94
|
+
const embedding = v.union([
|
|
95
|
+
v.strictObject({
|
|
96
|
+
account_id: identifier,
|
|
97
|
+
model: embeddingModel,
|
|
98
|
+
status: v.strictObject({ chunks: count, embedded: count }),
|
|
99
|
+
applied: v.literal(false),
|
|
100
|
+
scope: v.literal("existing-current-chunks"),
|
|
101
|
+
rebuild_required: v.literal("explicit"),
|
|
102
|
+
}),
|
|
103
|
+
v.strictObject({
|
|
104
|
+
account_id: identifier,
|
|
105
|
+
model: embeddingModel,
|
|
106
|
+
saved: count,
|
|
107
|
+
skipped: count,
|
|
108
|
+
has_more: flag,
|
|
109
|
+
next_hash: v.optional(text),
|
|
110
|
+
applied: v.literal(true),
|
|
111
|
+
rebuild: v.strictObject({
|
|
112
|
+
transcripts: count,
|
|
113
|
+
chunks: count,
|
|
114
|
+
has_more: flag,
|
|
115
|
+
next_transcript_id: v.optional(identifier),
|
|
116
|
+
}),
|
|
117
|
+
}),
|
|
118
|
+
]);
|
|
119
|
+
export const MEETING_RESULT_ENTITIES = {
|
|
120
|
+
meeting_ingestion: run,
|
|
121
|
+
meeting_export: exported,
|
|
122
|
+
meeting_association: meetingChange,
|
|
123
|
+
meeting_transcription: transcription,
|
|
124
|
+
meeting_embedding: embedding,
|
|
125
|
+
};
|
package/dist/ports/app.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface AppIdentity {
|
|
|
10
10
|
envPrefix: string;
|
|
11
11
|
description: string;
|
|
12
12
|
version: string;
|
|
13
|
-
/** Where a problem report goes — a new-issue page. `doctor
|
|
13
|
+
/** Where a problem report goes — a new-issue page. `doctor reports create` names it. */
|
|
14
14
|
issues?: string;
|
|
15
15
|
/** The language of the transcript a person reads: its day headings and the word for "you". `ru-RU` when unset. */
|
|
16
16
|
locale?: string;
|
|
@@ -377,6 +377,11 @@ export interface HistoryBatch {
|
|
|
377
377
|
votes?: HistoryVote[];
|
|
378
378
|
reactions?: HistoryReaction[];
|
|
379
379
|
stars?: HistoryStar[];
|
|
380
|
+
/** Deletions learned from a synced snapshot, scoped to their chat and applied after the batch's messages. */
|
|
381
|
+
deletions?: {
|
|
382
|
+
chatId: Id;
|
|
383
|
+
messageId: Id;
|
|
384
|
+
}[];
|
|
380
385
|
events?: HistoryChatEvent[];
|
|
381
386
|
}
|
|
382
387
|
/** For a messenger that pushes its history to the client instead of answering for it (`Messenger.history: "store"`). */
|
|
@@ -488,7 +493,7 @@ export interface AccountTools {
|
|
|
488
493
|
/** The owner's contact list as the messenger keeps it — the address book, not the chats. */
|
|
489
494
|
addressBook(): Promise<Member[]>;
|
|
490
495
|
}
|
|
491
|
-
/** Everything the messenger says about one person — what `contacts
|
|
496
|
+
/** Everything the messenger says about one person — what `contacts info` shows. */
|
|
492
497
|
export interface PersonProfiles {
|
|
493
498
|
/** Reading it tells them nothing. A chat that is not a person is refused. */
|
|
494
499
|
profile(person: string): Promise<ProfileFacts>;
|
|
@@ -2,7 +2,7 @@ import { normalize } from "../store/normalize.js";
|
|
|
2
2
|
import { createStemmer, DEFAULT_STEMMERS } from "./stem.js";
|
|
3
3
|
import { amountOf, dayOf, dueDayOf } from "./task-signature.js";
|
|
4
4
|
/**
|
|
5
|
-
* How alike two tasks are, field by field, as the tasks
|
|
5
|
+
* How alike two tasks are, field by field, as the tasks update's duplicate chain scores them
|
|
6
6
|
* (`docs/dev/tasks-plan.md`, "Duplicates — the comparison chain" § 1, 4, 5). Ported from the scorer that
|
|
7
7
|
* tuned the weights, WireCatLabs/cli-testing `performance/tasks/duplicates/` (cli-testing#60); the counts
|
|
8
8
|
* quoted beside each weight are that run's duplicate / other candidate pairs at the level.
|
package/dist/sends/guard.js
CHANGED
|
@@ -12,12 +12,12 @@ const HOUR_MS = 60 * 60 * 1000;
|
|
|
12
12
|
*/
|
|
13
13
|
const READS_UNDER_HOLD = new Set([
|
|
14
14
|
"attachments.extract",
|
|
15
|
-
"conversations.
|
|
15
|
+
"conversations.embeddings",
|
|
16
16
|
"conversations.links",
|
|
17
17
|
"messages.server-search",
|
|
18
18
|
"messages.sync-first",
|
|
19
19
|
"stats.contacts.top.sync-first",
|
|
20
|
-
"stats.messages.counters.
|
|
20
|
+
"stats.messages.counters.sync",
|
|
21
21
|
"stats.messages.show.sync-first",
|
|
22
22
|
"stats.messages.top.sync-first",
|
|
23
23
|
"store.gaps.repair",
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Level } from "./permissions.js";
|
|
2
|
+
/** Canonical names for internal permission keys; saved moved paths are refused below. */
|
|
3
|
+
export declare const canonicalPermissionKey: (key: string) => string;
|
|
4
|
+
/** WC-PERM-8: a moved saved path must name the replacement before any command runs. */
|
|
5
|
+
export declare const canonicalPermissions: (levels: Readonly<Record<string, Level>>) => Record<string, Level>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
const RENAMED = [
|
|
3
|
+
["models.audio.download", "models.download"],
|
|
4
|
+
["models.text.download", "models.download"],
|
|
5
|
+
["models.text.key", "models.keys"],
|
|
6
|
+
["models.audio", "models"],
|
|
7
|
+
["models.text", "models"],
|
|
8
|
+
["doctor.report", "doctor.reports"],
|
|
9
|
+
["contacts.aliases.rm", "contacts.aliases.remove"],
|
|
10
|
+
["contacts.alias.rm", "contacts.aliases.remove"],
|
|
11
|
+
["contacts.alias", "contacts.aliases"],
|
|
12
|
+
["contacts.profile", "contacts.info"],
|
|
13
|
+
["contacts.timeline", "contacts.events"],
|
|
14
|
+
["chats.links.revoke", "chats.links.remove"],
|
|
15
|
+
["chats.link.revoke", "chats.links.remove"],
|
|
16
|
+
["chats.link", "chats.links"],
|
|
17
|
+
["chats.members.audit", "chats.members.check"],
|
|
18
|
+
["chats.requests.accept", "chats.requests.confirm"],
|
|
19
|
+
["chats.requests.decline", "chats.requests.reject"],
|
|
20
|
+
["metadata.get", "metadata.show"],
|
|
21
|
+
["metadata.refresh", "metadata.sync"],
|
|
22
|
+
["tasks.plan", "tasks.update"],
|
|
23
|
+
["tags.auto", "tags.rebuild"],
|
|
24
|
+
["attachments.text.set", "attachments.update"],
|
|
25
|
+
["attachments.text", "attachments.update"],
|
|
26
|
+
["conversations.build", "conversations.links.rebuild"],
|
|
27
|
+
["conversations.embed", "conversations.embeddings"],
|
|
28
|
+
["conversations.batches.next", "conversations.batches.show"],
|
|
29
|
+
["conversations.consents.revoke", "conversations.consents.remove"],
|
|
30
|
+
["stats.messages.counters.refresh", "stats.messages.counters.sync"],
|
|
31
|
+
["store.gaps.plan", "store.gaps.show"],
|
|
32
|
+
["store.reindex", "store.rebuild"],
|
|
33
|
+
];
|
|
34
|
+
/** Canonical names for internal permission keys; saved moved paths are refused below. */
|
|
35
|
+
export const canonicalPermissionKey = (key) => {
|
|
36
|
+
if (key.startsWith("bot."))
|
|
37
|
+
return `bot.${canonicalPermissionKey(key.slice(4))}`;
|
|
38
|
+
const renamed = RENAMED.find(([old]) => key === old || key.startsWith(`${old}.`));
|
|
39
|
+
return renamed ? renamed[1] + key.slice(renamed[0].length) : key;
|
|
40
|
+
};
|
|
41
|
+
/** WC-PERM-8: a moved saved path must name the replacement before any command runs. */
|
|
42
|
+
export const canonicalPermissions = (levels) => {
|
|
43
|
+
for (const key of Object.keys(levels)) {
|
|
44
|
+
const canonical = canonicalPermissionKey(key);
|
|
45
|
+
if (key !== canonical)
|
|
46
|
+
throw new CliError("configuration_error", `permission path moved — rename permissions.${key} to permissions.${canonical}`, { permission: key, replacement: canonical, retryable: false });
|
|
47
|
+
}
|
|
48
|
+
return { ...levels };
|
|
49
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { canonicalPermissionKey, canonicalPermissions } from "./permission-aliases.js";
|
|
2
3
|
/**
|
|
3
4
|
* What a profile may be allowed to do (max-cli `CLI-37`, `NEED-251`). One name per thing the owner would
|
|
4
5
|
* recognise, so `sessions` — which logs the owner out of their phone — never rides along with
|
|
@@ -91,12 +92,11 @@ export const DEFAULT_PERMISSIONS = {
|
|
|
91
92
|
"server.start": "ask",
|
|
92
93
|
"server.stop": "ask",
|
|
93
94
|
"server.restart": "ask",
|
|
94
|
-
"models.
|
|
95
|
-
"models.text.download": "ask",
|
|
95
|
+
"models.download": "ask",
|
|
96
96
|
"images.models.download": "ask",
|
|
97
97
|
"schedule.run": "ask",
|
|
98
98
|
"schedule.exec": "ask",
|
|
99
|
-
"doctor.
|
|
99
|
+
"doctor.reports.create": "ask",
|
|
100
100
|
};
|
|
101
101
|
/** Commands under a housekeeping word, or store maintenance, that still have a key of their own: their path. */
|
|
102
102
|
const KEYED_UNDER_HOUSEKEEPING = new Set(Object.keys(DEFAULT_PERMISSIONS).filter((key) => /^(store|server|models|images|schedule|doctor)\./.test(key)));
|
|
@@ -163,7 +163,7 @@ const OLD_WORDS = {
|
|
|
163
163
|
"chats.leave",
|
|
164
164
|
"chats.members",
|
|
165
165
|
"chats.admins",
|
|
166
|
-
"chats.
|
|
166
|
+
"chats.links",
|
|
167
167
|
"chats.requests",
|
|
168
168
|
"chats.moderate",
|
|
169
169
|
"topics.enable",
|
|
@@ -199,7 +199,7 @@ export const layerPermissions = (layers) => {
|
|
|
199
199
|
const sources = {};
|
|
200
200
|
for (const [from, layer] of layers) {
|
|
201
201
|
const nearer = Object.keys(levels);
|
|
202
|
-
for (const [key, level] of Object.entries(layer ?? {})) {
|
|
202
|
+
for (const [key, level] of Object.entries(canonicalPermissions(layer ?? {}))) {
|
|
203
203
|
if (nearer.some((named) => key === named || key.startsWith(`${named}.`)))
|
|
204
204
|
continue;
|
|
205
205
|
levels[key] = level;
|
|
@@ -236,6 +236,8 @@ const FORMER_KEYS = { "chats.unmute": "chats.mute" };
|
|
|
236
236
|
* A path nothing names is allowed.
|
|
237
237
|
*/
|
|
238
238
|
export const levelFor = (permissions, key, defaults = DEFAULT_PERMISSIONS) => {
|
|
239
|
+
permissions = canonicalPermissions(permissions);
|
|
240
|
+
key = canonicalPermissionKey(key);
|
|
239
241
|
const found = profileLevel(permissions, key, defaults);
|
|
240
242
|
const ceiling = permissions[CEILING_KEY];
|
|
241
243
|
return ceiling && ORDER[ceiling] < ORDER[found.level] ? { level: ceiling, key: CEILING_KEY } : found;
|
|
@@ -290,7 +292,7 @@ const KIND_KEYS = {
|
|
|
290
292
|
/** The command path a guarded write belongs to, when the caller did not name it. */
|
|
291
293
|
export const keyForWrite = (kind, action) => {
|
|
292
294
|
if (kind === "chat")
|
|
293
|
-
return CHAT_KEYS[action ?? ""] ?? `chats.${action ?? "update"}
|
|
295
|
+
return canonicalPermissionKey(CHAT_KEYS[action ?? ""] ?? `chats.${action ?? "update"}`);
|
|
294
296
|
if (kind === "account") {
|
|
295
297
|
const key = ACCOUNT_KEYS[action];
|
|
296
298
|
if (!key)
|
|
@@ -301,6 +303,7 @@ export const keyForWrite = (kind, action) => {
|
|
|
301
303
|
};
|
|
302
304
|
/** `keyForWrite` read backwards, as far as a command's key says it: an unpin is a `pin`, a chat change names its action. */
|
|
303
305
|
export const writeOfKey = (key) => {
|
|
306
|
+
key = canonicalPermissionKey(key);
|
|
304
307
|
const account = Object.entries(ACCOUNT_KEYS).find(([, named]) => named === key)?.[0];
|
|
305
308
|
if (account)
|
|
306
309
|
return { kind: "account", action: account };
|
|
@@ -324,14 +327,14 @@ const NAMED_WRITE_KEYS = [
|
|
|
324
327
|
"messages.press",
|
|
325
328
|
"chats.start",
|
|
326
329
|
"chats.app",
|
|
327
|
-
"stats.messages.counters.
|
|
330
|
+
"stats.messages.counters.sync",
|
|
328
331
|
"stats.messages.show.sync-first",
|
|
329
332
|
"stats.messages.top.sync-first",
|
|
330
333
|
"stats.contacts.top.sync-first",
|
|
331
334
|
"account.sessions.list",
|
|
332
335
|
"attachments.extract",
|
|
333
336
|
"attachments.move",
|
|
334
|
-
"attachments.
|
|
337
|
+
"attachments.update",
|
|
335
338
|
"bot.callbacks.answer",
|
|
336
339
|
"bot.chats.action",
|
|
337
340
|
"bot.chats.admins.add",
|
|
@@ -346,14 +349,14 @@ const NAMED_WRITE_KEYS = [
|
|
|
346
349
|
"bot.messages.unpin",
|
|
347
350
|
"chats.admins.add",
|
|
348
351
|
"chats.admins.remove",
|
|
349
|
-
"chats.
|
|
350
|
-
"chats.
|
|
351
|
-
"chats.
|
|
352
|
-
"chats.
|
|
352
|
+
"chats.links.create",
|
|
353
|
+
"chats.links.reset",
|
|
354
|
+
"chats.links.remove",
|
|
355
|
+
"chats.links.update",
|
|
353
356
|
"chats.members.add",
|
|
354
357
|
"chats.members.remove",
|
|
355
358
|
"chats.moderate",
|
|
356
|
-
"conversations.
|
|
359
|
+
"conversations.embeddings",
|
|
357
360
|
"conversations.links",
|
|
358
361
|
"polls.close",
|
|
359
362
|
"polls.create",
|
|
@@ -361,13 +364,13 @@ const NAMED_WRITE_KEYS = [
|
|
|
361
364
|
"searches.clear",
|
|
362
365
|
"searches.create",
|
|
363
366
|
"searches.delete",
|
|
364
|
-
"contacts.
|
|
365
|
-
"contacts.
|
|
367
|
+
"contacts.aliases.set",
|
|
368
|
+
"contacts.aliases.remove",
|
|
366
369
|
"contacts.notes.add",
|
|
367
370
|
"contacts.notes.edit",
|
|
368
371
|
"contacts.notes.remove",
|
|
369
|
-
"tags.
|
|
370
|
-
"metadata.
|
|
372
|
+
"tags.rebuild",
|
|
373
|
+
"metadata.sync",
|
|
371
374
|
"mentions.rebuild",
|
|
372
375
|
"mentions.confirm",
|
|
373
376
|
"mentions.reject",
|
|
@@ -380,7 +383,7 @@ const NAMED_WRITE_KEYS = [
|
|
|
380
383
|
"tasks.duplicates.reject",
|
|
381
384
|
"tasks.link",
|
|
382
385
|
"tasks.merge",
|
|
383
|
-
"tasks.
|
|
386
|
+
"tasks.update",
|
|
384
387
|
"tasks.release",
|
|
385
388
|
"tasks.scan",
|
|
386
389
|
"tasks.unmerge",
|
|
@@ -397,7 +400,7 @@ export const WRITE_KEYS = [
|
|
|
397
400
|
...Object.values(ACCOUNT_KEYS),
|
|
398
401
|
...Object.values(CHAT_KEYS),
|
|
399
402
|
...PERMISSIONS.flatMap((word) => [...OLD_WORDS[word], ...botKeysOf(word)]),
|
|
400
|
-
]),
|
|
403
|
+
].map(canonicalPermissionKey)),
|
|
401
404
|
];
|
|
402
405
|
/** Commands that look after the tool and its files and never show a message: no level stops them. */
|
|
403
406
|
const HOUSEKEEPING = new Set([
|
|
@@ -483,6 +486,9 @@ export const readKeysForCommand = (path) => {
|
|
|
483
486
|
* `undefined` for a path this package does not know — a CLI's own command, which its CLI maps.
|
|
484
487
|
*/
|
|
485
488
|
export const keyForCommand = (path) => {
|
|
489
|
+
if (path.length === 0)
|
|
490
|
+
return null;
|
|
491
|
+
path = canonicalPermissionKey(path.join(".")).split(".");
|
|
486
492
|
const [top, next] = path;
|
|
487
493
|
if (top === "bot") {
|
|
488
494
|
if (next === undefined || BOT_HOUSEKEEPING.has(next))
|
|
@@ -505,11 +511,12 @@ export const keyForCommand = (path) => {
|
|
|
505
511
|
return null;
|
|
506
512
|
// The agent's answers write only to the local store: their own key, so read-only messages can still link (phase 4 A10).
|
|
507
513
|
if (top === "conversations" && next === "links")
|
|
508
|
-
return "conversations.links";
|
|
514
|
+
return path[2] === "rebuild" ? "conversations.links.rebuild" : "conversations.links";
|
|
509
515
|
// Vectors are written to the local store only, and the text never leaves the machine (phase 5 E10).
|
|
510
|
-
if ((
|
|
516
|
+
if ((top === "conversations" && next === "embeddings") ||
|
|
517
|
+
(top === "images" && next === "embed") ||
|
|
511
518
|
(top === "conversations" && next === "rebuild"))
|
|
512
|
-
return "conversations.
|
|
519
|
+
return "conversations.embeddings";
|
|
513
520
|
// Which files a message has, and where they are saved, tells as much as a message does; so does who
|
|
514
521
|
// shared which document link, and when.
|
|
515
522
|
if ((top === "attachments" && next === "list") || (top === "chats" && next === "documents"))
|
|
@@ -521,8 +528,7 @@ export const keyForCommand = (path) => {
|
|
|
521
528
|
return path.join(".");
|
|
522
529
|
if (top === "messages" && next === "sync")
|
|
523
530
|
return "messages";
|
|
524
|
-
if (SHOW_MESSAGES.has(top) ||
|
|
525
|
-
(top === "contacts" && (next === "context" || next === "prepare" || next === "timeline")))
|
|
531
|
+
if (SHOW_MESSAGES.has(top) || (top === "contacts" && (next === "context" || next === "prepare" || next === "events")))
|
|
526
532
|
return "messages";
|
|
527
533
|
if (RESOURCES.includes(top))
|
|
528
534
|
return path.join(".");
|
|
@@ -538,10 +544,12 @@ export const permissionOverrides = (entries = []) => {
|
|
|
538
544
|
throw new CliError("validation_error", "--permission takes a command path and level, e.g. messages.send=allow (deny, readonly, ask, allow)");
|
|
539
545
|
levels[key] = level;
|
|
540
546
|
}
|
|
541
|
-
return levels;
|
|
547
|
+
return canonicalPermissions(levels);
|
|
542
548
|
};
|
|
543
549
|
/** No startup flag grants access: an override may narrow the profile's level, never lift it or a key under it. */
|
|
544
550
|
export const assertOverridesTighten = (overrides, profile) => {
|
|
551
|
+
overrides = canonicalPermissions(overrides);
|
|
552
|
+
profile = canonicalPermissions(profile);
|
|
545
553
|
for (const [key, level] of Object.entries(overrides)) {
|
|
546
554
|
const under = Object.keys(profile).filter((named) => named.startsWith(`${key}.`));
|
|
547
555
|
const lifted = [key, ...under].find((named) => ORDER[level] > ORDER[levelFor(profile, named).level]);
|
package/dist/services/admin.js
CHANGED
|
@@ -111,14 +111,14 @@ export const adminService = (deps) => {
|
|
|
111
111
|
return { operationId, chat: card };
|
|
112
112
|
},
|
|
113
113
|
link: async (chat) => {
|
|
114
|
-
const group = await capability(await online("chats
|
|
114
|
+
const group = await capability(await online("chats links show"), "group", "read a group")(chat);
|
|
115
115
|
if (group.link === null) {
|
|
116
116
|
throw new CliError("not_found", `${group.title ?? group.id} shows you no invite link — only admins, or members when the group allows it`);
|
|
117
117
|
}
|
|
118
118
|
return { chatId: group.id, title: group.title, link: group.link };
|
|
119
119
|
},
|
|
120
120
|
resetLink: async (chat) => {
|
|
121
|
-
const connection = await online("chats
|
|
121
|
+
const connection = await online("chats links reset");
|
|
122
122
|
const reset = capability(connection, "resetInviteLink", "replace an invite link");
|
|
123
123
|
const { id: chatId } = await connection.resolve(chat);
|
|
124
124
|
const operationId = newOperationId();
|
|
@@ -127,7 +127,7 @@ export const adminService = (deps) => {
|
|
|
127
127
|
},
|
|
128
128
|
createLink: async (chat, { approval, expires, maxUses }) => {
|
|
129
129
|
const expiresAt = linkLimits({ approval, expires, maxUses });
|
|
130
|
-
const connection = await online("chats
|
|
130
|
+
const connection = await online("chats links create");
|
|
131
131
|
const create = capability(connection, "createInviteLink", "make another invite link");
|
|
132
132
|
const { id: chatId } = await connection.resolve(chat);
|
|
133
133
|
const operationId = newOperationId();
|
|
@@ -193,8 +193,8 @@ export const adminService = (deps) => {
|
|
|
193
193
|
},
|
|
194
194
|
revokeLink: async (chat, link) => {
|
|
195
195
|
if (link.trim() === "")
|
|
196
|
-
throw new CliError("validation_error", "which link? give it as `chats
|
|
197
|
-
const connection = await online("chats
|
|
196
|
+
throw new CliError("validation_error", "which link? give it as `chats links list` shows it");
|
|
197
|
+
const connection = await online("chats links remove");
|
|
198
198
|
const revoke = capability(connection, "revokeInviteLink", "revoke an invite link");
|
|
199
199
|
const { id: chatId } = await connection.resolve(chat);
|
|
200
200
|
const operationId = newOperationId();
|
|
@@ -203,12 +203,12 @@ export const adminService = (deps) => {
|
|
|
203
203
|
},
|
|
204
204
|
updateLink: async (chat, link, { approval, expires, maxUses }) => {
|
|
205
205
|
if (link.trim() === "")
|
|
206
|
-
throw new CliError("validation_error", "which link? give it as `chats
|
|
206
|
+
throw new CliError("validation_error", "which link? give it as `chats links list` shows it");
|
|
207
207
|
if (approval === undefined && expires === undefined && maxUses === undefined)
|
|
208
208
|
throw new CliError("validation_error", "nothing to change: give --approval, --no-approval, --expire-time or --max-uses");
|
|
209
209
|
const limited = linkLimits({ approval, expires: expires === "never" ? undefined : expires, maxUses });
|
|
210
210
|
const expiresAt = expires === "never" ? null : limited;
|
|
211
|
-
const connection = await online("chats
|
|
211
|
+
const connection = await online("chats links update");
|
|
212
212
|
const update = capability(connection, "updateInviteLink", "change an invite link");
|
|
213
213
|
const { id: chatId } = await connection.resolve(chat);
|
|
214
214
|
const change = {
|
package/dist/services/chats.js
CHANGED
|
@@ -161,7 +161,7 @@ export const chatsService = (deps) => ({
|
|
|
161
161
|
},
|
|
162
162
|
audit: async (chat, { budget = AUDIT_BUDGET, minScore = AUDIT_MIN_SCORE, pauseMs = AUDIT_PAUSE_MS, deep = 0, registry }) => {
|
|
163
163
|
if (deps.offline) {
|
|
164
|
-
throw new CliError("validation_error", "`chats members
|
|
164
|
+
throw new CliError("validation_error", "`chats members check` reads the member list from the messenger; not with --offline");
|
|
165
165
|
}
|
|
166
166
|
const connection = await deps.connection();
|
|
167
167
|
const { chatId: id, members: read, more, participants } = await readMembers(connection, chat, budget, pauseMs);
|
|
@@ -61,7 +61,7 @@ export interface ConversationsService {
|
|
|
61
61
|
batchStatus(chat: string, size: number): Promise<BatchStatus>;
|
|
62
62
|
/** The next window for the agent; `undefined` when every message is answered (A1–A4). */
|
|
63
63
|
nextBatch(chat: string, size: number): Promise<LinkBatch | undefined>;
|
|
64
|
-
/** Stores the agent's answer to a batch, all or nothing (A5); `conversations
|
|
64
|
+
/** Stores the agent's answer to a batch, all or nothing (A5); `conversations links rebuild` then uses it. */
|
|
65
65
|
addAnswers(batch: string, answer: AgentAnswer): Promise<{
|
|
66
66
|
chat: Id;
|
|
67
67
|
stored: number;
|
|
@@ -39,7 +39,7 @@ export const conversationsService = (deps) => {
|
|
|
39
39
|
const store = await accountStore(deps);
|
|
40
40
|
return { store, chatId: await chatIdIn(deps.messenger, chat, store, { includeLeft: true }) };
|
|
41
41
|
};
|
|
42
|
-
const notBuilt = (chatId) => new CliError("not_found", `chat ${chatId} has no conversations yet — \`${typedCommand(deps.messenger.app.command, `conversations
|
|
42
|
+
const notBuilt = (chatId) => new CliError("not_found", `chat ${chatId} has no conversations yet — \`${typedCommand(deps.messenger.app.command, `conversations links rebuild --chat ${chatId}`)}\``);
|
|
43
43
|
return {
|
|
44
44
|
build: async (chat, { maxMessages, check } = {}) => {
|
|
45
45
|
check?.();
|
|
@@ -115,7 +115,7 @@ export const countersService = (deps) => {
|
|
|
115
115
|
return preview;
|
|
116
116
|
if (deps.offline)
|
|
117
117
|
throw new CliError("validation_error", "counter refresh requires an online session");
|
|
118
|
-
const request = { chatId: null, key: "stats.messages.counters.
|
|
118
|
+
const request = { chatId: null, key: "stats.messages.counters.sync" };
|
|
119
119
|
await deps.guard.ask?.(request);
|
|
120
120
|
deps.guard.check(request, { reserve: false });
|
|
121
121
|
const controller = new AbortController(), timer = setTimeout(() => controller.abort(new Error("counter refresh time budget exhausted")), time);
|