@wirecat/cli-core 0.399.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 +82 -0
- package/dist/analysis/consents.d.ts +11 -6
- package/dist/analysis/consents.js +5 -2
- package/dist/cli/bot/mcp.js +2 -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/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 +12 -12
- 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/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-tracking-command.js +14 -6
- package/dist/cli/messenger/contacts-command.js +9 -5
- package/dist/cli/messenger/conversations-command.js +20 -16
- 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/images-command.js +1 -0
- 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/metadata-command.js +6 -1
- 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 +3 -3
- 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/search-command.js +3 -1
- package/dist/cli/messenger/searches-command.js +5 -1
- 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/statistics-query.d.ts +14 -0
- package/dist/cli/messenger/statistics-query.js +143 -0
- package/dist/cli/messenger/stats-command.js +5 -5
- 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 +7 -1
- package/dist/cli/messenger/tasks-command.js +47 -8
- package/dist/cli/messenger/transcribe-command.js +1 -0
- 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/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 +1 -1
- package/parity.json +8 -66
|
@@ -6,13 +6,13 @@ import { grantsAuthority, LOCAL_WRITE } from "../effects.js";
|
|
|
6
6
|
import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
7
7
|
import { messengerContext } from "./context.js";
|
|
8
8
|
/**
|
|
9
|
-
* The owner's way out of a remembered wait or a hold on writes, once they know it is over.
|
|
10
|
-
*
|
|
9
|
+
* The owner's way out of a remembered wait or a hold on writes, once they know it is over. An agent gets it only
|
|
10
|
+
* under `mcp.authority`: one that could lift a hold would send straight into a spam limit again.
|
|
11
11
|
*/
|
|
12
12
|
export const floodCommand = (messenger) => {
|
|
13
13
|
const { app } = messenger;
|
|
14
14
|
const name = messenger.name ?? app.command;
|
|
15
|
-
return
|
|
15
|
+
return new Command("flood")
|
|
16
16
|
.description(`the waits ${name} asked this profile to keep, and a hold on its writes`)
|
|
17
17
|
.addCommand(grantsAuthority(annotate(new Command("clear"), { effects: LOCAL_WRITE, examples: [`${app.command} personal flood clear`] }))
|
|
18
18
|
.summary("clear a profile's stored rate-limit hold")
|
|
@@ -21,7 +21,7 @@ const count = (value) => {
|
|
|
21
21
|
};
|
|
22
22
|
export const gapsCommand = (messenger) => {
|
|
23
23
|
const group = new Command("gaps").description("inspect recorded interior coverage gaps and explicitly fetch them");
|
|
24
|
-
annotate(group.command("plan"), { effects: LOCAL_READ })
|
|
24
|
+
annotate(group.command("plan"), { output: { entity: "store_gap_plan" }, effects: LOCAL_READ })
|
|
25
25
|
.description("local coverage plan; missing message ids alone do not imply missing history")
|
|
26
26
|
.argument("<chat>", messenger.chatArgument)
|
|
27
27
|
.action(async function (chat) {
|
|
@@ -29,7 +29,7 @@ export const gapsCommand = (messenger) => {
|
|
|
29
29
|
renderAnswer(this, context, itemOf(snakeKeys(await context.withServices((services) => services.gaps.plan(chat)))));
|
|
30
30
|
});
|
|
31
31
|
const fetching = messenger.fetching ?? FETCHING;
|
|
32
|
-
annotate(group.command("repair"), { effects: FETCH })
|
|
32
|
+
annotate(group.command("repair"), { output: { entity: "store_gap_repair" }, effects: FETCH })
|
|
33
33
|
.description("fetch bounded interior gaps and recheck coverage; never delete unseen messages")
|
|
34
34
|
.argument("<chat>", messenger.chatArgument)
|
|
35
35
|
.option("--limit <n>", "total messages in this repair, 500 by default", count)
|
|
@@ -5,10 +5,12 @@ import { SendJournal, sendsPathFor } from "../../sends/journal.js";
|
|
|
5
5
|
import { RecipientList, recipientsPathFor } from "../../sends/recipients.js";
|
|
6
6
|
import { FETCH, grantsAuthority, LOCAL_READ, LOCAL_WRITE } from "../effects.js";
|
|
7
7
|
import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
8
|
-
import { pagedList } from "../list-query.js";
|
|
8
|
+
import { pagedList, typedQuery, withQuery } from "../list-query.js";
|
|
9
9
|
import { withPaging } from "../paging.js";
|
|
10
10
|
import { wholeList } from "./chat-answers.js";
|
|
11
11
|
import { messengerContext } from "./context.js";
|
|
12
|
+
import { RECIPIENTS_QUERY, recipientFilter } from "./recipients-query.js";
|
|
13
|
+
import { SENDS_QUERY, sendFilter } from "./sends-query.js";
|
|
12
14
|
/**
|
|
13
15
|
* The chats this profile may send to. Off until the first `add`; `clear` deletes it, which turns it off again. It stops
|
|
14
16
|
* a model that a message talked into writing somewhere, not an agent set on getting around it.
|
|
@@ -17,19 +19,26 @@ export const recipientsCommand = (messenger) => {
|
|
|
17
19
|
const tool = `${messenger.app.command} personal`;
|
|
18
20
|
const listFor = (profile, env) => new RecipientList(recipientsPathFor(messenger.app, profile, env), messenger.app.command);
|
|
19
21
|
const command = new Command("recipients").description("the chats this profile may send to, when the list is on");
|
|
20
|
-
annotate(command.command("list"), {
|
|
22
|
+
withQuery(annotate(command.command("list"), { examples: [`${tool} recipients list`], effects: LOCAL_READ }), RECIPIENTS_QUERY)
|
|
21
23
|
.description("the chats on the list; empty and off until the first add")
|
|
22
|
-
.action(async function () {
|
|
24
|
+
.action(async function (words) {
|
|
25
|
+
const filter = recipientFilter(words);
|
|
23
26
|
const context = messengerContext(this, messenger);
|
|
24
27
|
const { settings, renderer, env } = context;
|
|
25
|
-
const
|
|
26
|
-
renderAnswer(this, context, wholeList("recipients list",
|
|
27
|
-
if (
|
|
28
|
+
const found = listFor(settings.profile, env).list(filter);
|
|
29
|
+
renderAnswer(this, context, wholeList("recipients list", found.items.map(snakeKeys)));
|
|
30
|
+
if (found.state === "off")
|
|
28
31
|
renderer.note("the recipient list is off — this profile may send to any chat");
|
|
29
|
-
else if (
|
|
32
|
+
else if (found.state === "empty")
|
|
30
33
|
renderer.note("the recipient list is on and empty — this profile may send nowhere");
|
|
34
|
+
else if (found.items.length === 0)
|
|
35
|
+
renderer.note("no recipients match the query");
|
|
31
36
|
});
|
|
32
|
-
grantsAuthority(annotate(command.command("add"), {
|
|
37
|
+
grantsAuthority(annotate(command.command("add"), {
|
|
38
|
+
examples: [`${tool} recipients add "Book club"`],
|
|
39
|
+
effects: FETCH,
|
|
40
|
+
output: { entity: "recipient_change", view: "added" },
|
|
41
|
+
}))
|
|
33
42
|
.argument("<chat>", messenger.chatArgument)
|
|
34
43
|
.description("allow sending to this chat; the first add turns the list on")
|
|
35
44
|
.action(async function (chat) {
|
|
@@ -44,7 +53,11 @@ export const recipientsCommand = (messenger) => {
|
|
|
44
53
|
});
|
|
45
54
|
renderAnswer(this, context, itemOf({ id: found.id, title: found.title, added }));
|
|
46
55
|
});
|
|
47
|
-
grantsAuthority(annotate(command.command("remove"), {
|
|
56
|
+
grantsAuthority(annotate(command.command("remove"), {
|
|
57
|
+
examples: [`${tool} recipients remove "Book club"`],
|
|
58
|
+
effects: LOCAL_WRITE,
|
|
59
|
+
output: { entity: "recipient_change", view: "removed" },
|
|
60
|
+
}))
|
|
48
61
|
.argument("<chat>", "chat id, or the title as the list shows it")
|
|
49
62
|
.description("stop allowing this chat; the list stays on")
|
|
50
63
|
.action(async function (chat) {
|
|
@@ -55,7 +68,11 @@ export const recipientsCommand = (messenger) => {
|
|
|
55
68
|
throw new CliError("not_found", `${chat.trim()} is not on the recipient list of ${settings.profile}`);
|
|
56
69
|
renderAnswer(this, context, itemOf({ id: gone.id, title: gone.title, removed: true }));
|
|
57
70
|
});
|
|
58
|
-
grantsAuthority(annotate(command.command("clear"), {
|
|
71
|
+
grantsAuthority(annotate(command.command("clear"), {
|
|
72
|
+
examples: [`${tool} recipients clear`],
|
|
73
|
+
effects: LOCAL_WRITE,
|
|
74
|
+
output: { entity: "recipient_change", view: "off" },
|
|
75
|
+
}))
|
|
59
76
|
.description("delete the list, which turns it off: this profile may send to any chat again")
|
|
60
77
|
.action(async function () {
|
|
61
78
|
const context = messengerContext(this, messenger);
|
|
@@ -65,16 +82,21 @@ export const recipientsCommand = (messenger) => {
|
|
|
65
82
|
return command;
|
|
66
83
|
};
|
|
67
84
|
/** Every attempt to send from this profile, kept whatever `--record` says. Never the text. */
|
|
68
|
-
export const sendsCommand = (messenger) => new Command("sends").description("every attempt to send from this profile — never the text").addCommand(withPaging(annotate(new Command("list"), {
|
|
85
|
+
export const sendsCommand = (messenger) => new Command("sends").description("every attempt to send from this profile — never the text").addCommand(withQuery(withPaging(annotate(new Command("list"), {
|
|
86
|
+
effects: LOCAL_READ,
|
|
87
|
+
examples: [`${messenger.app.command} personal sends list --limit 10`],
|
|
88
|
+
}).description("attempts to send, newest first: sent, refused, failed, or not known")), SENDS_QUERY).action(async function (words) {
|
|
89
|
+
const filter = sendFilter(words);
|
|
69
90
|
const context = messengerContext(this, messenger);
|
|
70
91
|
const { settings, renderer, env } = context;
|
|
71
|
-
const entries = new SendJournal(sendsPathFor(messenger.app, settings.profile, env)).entries().reverse();
|
|
92
|
+
const entries = new SendJournal(sendsPathFor(messenger.app, settings.profile, env)).entries(filter).reverse();
|
|
72
93
|
const from = settings.all ? 0 : (settings.page - 1) * settings.limit;
|
|
73
94
|
const shown = settings.all ? entries : entries.slice(from, from + settings.limit);
|
|
74
95
|
renderAnswer(this, context, pagedList("sends list", settings, {
|
|
75
96
|
items: shown.map(snakeKeys),
|
|
97
|
+
args: words.length ? { query: typedQuery(words) } : {},
|
|
76
98
|
has_more: from + shown.length < entries.length,
|
|
77
99
|
}));
|
|
78
100
|
if (entries.length === 0)
|
|
79
|
-
renderer.note(`profile ${settings.profile} has not tried to send anything`);
|
|
101
|
+
renderer.note(filter ? "no send attempts match the query" : `profile ${settings.profile} has not tried to send anything`);
|
|
80
102
|
}));
|
|
@@ -13,6 +13,7 @@ const DEFAULT_LIMIT = 100;
|
|
|
13
13
|
export const imagesCommand = (messenger) => {
|
|
14
14
|
const images = new Command("images").description("search pictures by what they show, with a model on this machine");
|
|
15
15
|
annotate(images.command("embed"), {
|
|
16
|
+
output: { entity: "image_embedding" },
|
|
16
17
|
effects: FETCH,
|
|
17
18
|
offline: false,
|
|
18
19
|
examples: [`${messenger.app.command} images embed`, `${messenger.app.command} images embed --limit 500`],
|
|
@@ -13,6 +13,7 @@ import { addMediaArchiveTimers } from "./media-archive-timer-command.js";
|
|
|
13
13
|
import { stopOnSignal } from "./patience.js";
|
|
14
14
|
export const addMediaArchiveCommands = (archive, messenger) => {
|
|
15
15
|
annotate(archive.command("download"), {
|
|
16
|
+
output: { entity: "media_archive" },
|
|
16
17
|
effects: FETCH,
|
|
17
18
|
examples: [`${messenger.app.command} attachments download ./media-archive`],
|
|
18
19
|
})
|
|
@@ -54,6 +55,7 @@ export const addMediaArchiveCommands = (archive, messenger) => {
|
|
|
54
55
|
}
|
|
55
56
|
});
|
|
56
57
|
annotate(archive.command("check"), {
|
|
58
|
+
output: { entity: "media_archive_check" },
|
|
57
59
|
effects: LOCAL_READ,
|
|
58
60
|
examples: [`${messenger.app.command} attachments check ./media-archive`],
|
|
59
61
|
})
|
|
@@ -8,6 +8,7 @@ import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
|
8
8
|
import { messengerContext, refuseLocalWrite } from "./context.js";
|
|
9
9
|
export const addMediaArchiveMove = (attachments, messenger) => {
|
|
10
10
|
annotate(attachments.command("move"), {
|
|
11
|
+
output: { entity: "media_archive_move" },
|
|
11
12
|
effects: LOCAL_WRITE,
|
|
12
13
|
examples: [
|
|
13
14
|
`${messenger.app.command} attachments move ./media-archive ./older-images --before-time 2026-10-01T00:00:00Z --dry-run`,
|
|
@@ -14,8 +14,8 @@ export const addMediaArchiveTimers = (attachments, messenger) => {
|
|
|
14
14
|
const archive = attachments.command("jobs").description("daily media archive timers for this profile");
|
|
15
15
|
for (const action of ["install", "start", "stop", "status", "uninstall"]) {
|
|
16
16
|
const command = annotate(archive.command(action), {
|
|
17
|
+
output: { entity: "media_archive_timer" },
|
|
17
18
|
effects: action === "status" ? LOCAL_READ : LOCAL_WRITE,
|
|
18
|
-
...(action === "status" ? {} : { mcp: false }),
|
|
19
19
|
examples: [`${messenger.app.command} attachments jobs ${action} ./media-archive`],
|
|
20
20
|
})
|
|
21
21
|
.description({
|
|
@@ -16,6 +16,7 @@ export const mentionsCommand = (messenger) => {
|
|
|
16
16
|
const tool = messenger.app.command;
|
|
17
17
|
const mentions = new Command("mentions").description("phones, e-mail, links, documents, names and addresses in stored messages");
|
|
18
18
|
annotate(mentions.command("list"), {
|
|
19
|
+
output: { entity: "mention" },
|
|
19
20
|
effects: LOCAL_READ,
|
|
20
21
|
query: MENTION_QUERY,
|
|
21
22
|
examples: [
|
|
@@ -55,6 +56,7 @@ export const mentionsCommand = (messenger) => {
|
|
|
55
56
|
context.renderer.note("more remain — a larger --limit shows them all and moves the --new point");
|
|
56
57
|
});
|
|
57
58
|
annotate(mentions.command("domains"), {
|
|
59
|
+
output: { entity: "mention_domain" },
|
|
58
60
|
effects: LOCAL_READ,
|
|
59
61
|
query: MENTION_QUERY,
|
|
60
62
|
examples: [`${tool} mentions domains`, `${tool} mentions domains status:found`],
|
|
@@ -77,7 +79,11 @@ export const mentionsCommand = (messenger) => {
|
|
|
77
79
|
`${firstAt.slice(0, 10)}…${lastAt.slice(0, 10)}\n`)
|
|
78
80
|
.join(""));
|
|
79
81
|
});
|
|
80
|
-
annotate(mentions.command("places"), {
|
|
82
|
+
annotate(mentions.command("places"), {
|
|
83
|
+
output: { entity: "place" },
|
|
84
|
+
effects: LOCAL_READ,
|
|
85
|
+
examples: [`${tool} mentions places`],
|
|
86
|
+
})
|
|
81
87
|
.summary("confirmed street addresses, most mentioned first")
|
|
82
88
|
.description("confirmed addresses, in every account, most mentioned first; `mentions confirm <id>` adds one")
|
|
83
89
|
.option("--limit <n>", "how many to show", positiveCount("--limit"))
|
|
@@ -90,7 +96,11 @@ export const mentionsCommand = (messenger) => {
|
|
|
90
96
|
has_more: places.hasMore,
|
|
91
97
|
}), () => places.items.map(({ id, address, mentions }) => `${id} ${address} ${mentions} mentioned\n`).join(""));
|
|
92
98
|
});
|
|
93
|
-
annotate(mentions.command("show"), {
|
|
99
|
+
annotate(mentions.command("show"), {
|
|
100
|
+
output: { entity: "mention", view: "details" },
|
|
101
|
+
effects: LOCAL_READ,
|
|
102
|
+
examples: [`${tool} mentions show 12`],
|
|
103
|
+
})
|
|
94
104
|
.description("one mention, the text around it, and how many other places hold its value")
|
|
95
105
|
.argument("<id>", "the mention's id, from mentions list", positiveCount("<id>"))
|
|
96
106
|
.action(async function (id) {
|
|
@@ -101,6 +111,7 @@ export const mentionsCommand = (messenger) => {
|
|
|
101
111
|
(found.candidates.length > 0 ? `may be ${found.candidates.join(", ")}\n` : ""));
|
|
102
112
|
});
|
|
103
113
|
annotate(mentions.command("confirm"), {
|
|
114
|
+
output: { entity: "mention_decision" },
|
|
104
115
|
effects: LOCAL_WRITE,
|
|
105
116
|
examples: [
|
|
106
117
|
`${tool} mentions confirm 12 person:7`,
|
|
@@ -123,6 +134,7 @@ export const mentionsCommand = (messenger) => {
|
|
|
123
134
|
renderAnswer(this, context, itemOf(snakeKeys(decided)));
|
|
124
135
|
});
|
|
125
136
|
annotate(mentions.command("reject"), {
|
|
137
|
+
output: { entity: "mention_decision" },
|
|
126
138
|
effects: LOCAL_WRITE,
|
|
127
139
|
examples: [`${tool} mentions reject 12`],
|
|
128
140
|
})
|
|
@@ -140,6 +152,7 @@ export const mentionsCommand = (messenger) => {
|
|
|
140
152
|
renderAnswer(this, context, itemOf(snakeKeys(decided)));
|
|
141
153
|
});
|
|
142
154
|
destroysNothing(annotate(mentions.command("rebuild"), {
|
|
155
|
+
output: { entity: "mention_rebuild" },
|
|
143
156
|
effects: LOCAL_WRITE,
|
|
144
157
|
examples: [`${tool} mentions rebuild`, `${tool} mentions rebuild person-name`],
|
|
145
158
|
}))
|
|
@@ -110,6 +110,7 @@ export const messagesCommand = (messenger) => {
|
|
|
110
110
|
};
|
|
111
111
|
messages.addCommand(sendCommand(messenger));
|
|
112
112
|
annotate(messages.command("show"), {
|
|
113
|
+
output: { entity: "message" },
|
|
113
114
|
examples: [`${messenger.app.command} personal messages show "Book club" 101`],
|
|
114
115
|
effects: REMOTE_READ,
|
|
115
116
|
})
|
|
@@ -122,6 +123,7 @@ export const messagesCommand = (messenger) => {
|
|
|
122
123
|
await readWindow(this, chat, message, { before: 0, after: 0 });
|
|
123
124
|
});
|
|
124
125
|
threadOptions(annotate(messages.command("context"), {
|
|
126
|
+
output: { entity: "message_context" },
|
|
125
127
|
examples: [`${messenger.app.command} personal messages context "Book club" 101 --before-n 3 --after-n 3`],
|
|
126
128
|
effects: REMOTE_READ,
|
|
127
129
|
}))
|
|
@@ -14,6 +14,7 @@ import { messengerContext } from "./context.js";
|
|
|
14
14
|
export const deleteCommand = (messenger) => annotate(new Command("delete"), {
|
|
15
15
|
examples: [`${messenger.app.command} personal messages delete "Book club" 101`],
|
|
16
16
|
effects: REMOTE_WRITE,
|
|
17
|
+
output: { entity: "message_deletion" },
|
|
17
18
|
})
|
|
18
19
|
.description("delete messages for you only; with --for-everyone, for everyone in the chat")
|
|
19
20
|
.argument("<chat>", messenger.chatArgument)
|
|
@@ -11,6 +11,7 @@ export const editCommand = (messenger) => {
|
|
|
11
11
|
const edit = annotate(new Command("edit"), {
|
|
12
12
|
examples: [`${messenger.app.command} personal messages edit "Book club" 101 "The meeting starts at 11."`],
|
|
13
13
|
effects: REMOTE_WRITE,
|
|
14
|
+
output: { entity: "message_write" },
|
|
14
15
|
})
|
|
15
16
|
.description("change the text of your own message; the other side may have read it already")
|
|
16
17
|
.argument("<chat>", messenger.chatArgument)
|
|
@@ -7,10 +7,12 @@ import { positiveCount } from "../paging.js";
|
|
|
7
7
|
import { messengerContext } from "./context.js";
|
|
8
8
|
import { evidenceAnswer } from "./message-answers.js";
|
|
9
9
|
export const evidenceCommand = (messenger) => annotate(new Command("evidence"), {
|
|
10
|
+
output: { entity: "evidence_packet" },
|
|
10
11
|
examples: [`${messenger.app.command} personal messages evidence "Book club" --limit 10`],
|
|
11
12
|
effects: LOCAL_READ,
|
|
12
13
|
})
|
|
13
|
-
.
|
|
14
|
+
.summary("a recent-chat evidence packet from stored messages")
|
|
15
|
+
.description("general chat context, newest first, with references, coverage and fingerprints for verification")
|
|
14
16
|
.argument("<chat>", messenger.chatArgument)
|
|
15
17
|
.option("--limit <n>", "how many, 1–100", positiveCount("--limit"))
|
|
16
18
|
.option("--cursor <cursor>", "go on from where page.next says the last packet stopped")
|
|
@@ -9,6 +9,7 @@ export const forwardCommand = (messenger) => {
|
|
|
9
9
|
const forward = annotate(new Command("forward"), {
|
|
10
10
|
examples: [`${messenger.app.command} personal messages forward "Book club" 101 --to "Project room"`],
|
|
11
11
|
effects: REMOTE_WRITE,
|
|
12
|
+
output: { entity: "message_write" },
|
|
12
13
|
})
|
|
13
14
|
.description("forward one message to another chat")
|
|
14
15
|
.argument("<chat>", `the chat the message is in: ${messenger.chatArgument}`)
|
|
@@ -10,6 +10,7 @@ export const pinCommand = (messenger) => {
|
|
|
10
10
|
const durations = messenger.pinDurations?.length ? messenger.pinDurations : undefined;
|
|
11
11
|
const command = annotate(new Command("pin"), {
|
|
12
12
|
effects: REMOTE_WRITE,
|
|
13
|
+
output: { entity: "message_pin" },
|
|
13
14
|
examples: [
|
|
14
15
|
`${tool} messages pin <chat> <message>`,
|
|
15
16
|
...(quiet ? [`${tool} messages pin <chat> <message> --notify`] : []),
|
|
@@ -38,6 +39,7 @@ export const pinCommand = (messenger) => {
|
|
|
38
39
|
};
|
|
39
40
|
export const unpinCommand = (messenger) => annotate(new Command("unpin"), {
|
|
40
41
|
effects: REMOTE_WRITE,
|
|
42
|
+
output: { entity: "message_pin" },
|
|
41
43
|
examples: [`${messenger.app.command} messages unpin <chat> <message>`],
|
|
42
44
|
})
|
|
43
45
|
.description("unpin a message in a chat")
|
|
@@ -53,6 +55,7 @@ export const starCommands = (messenger) => [true, false].map((starred) => {
|
|
|
53
55
|
const name = starred ? "star" : "unstar";
|
|
54
56
|
return annotate(new Command(name), {
|
|
55
57
|
effects: REMOTE_WRITE,
|
|
58
|
+
output: { entity: "message_star" },
|
|
56
59
|
examples: [`${messenger.app.command} messages ${name} <chat> <message>`],
|
|
57
60
|
})
|
|
58
61
|
.description(starred ? "star a message, so it is easy to find again; only you see the star" : "take the star off a message")
|
|
@@ -19,6 +19,7 @@ export const sendCommand = (messenger) => {
|
|
|
19
19
|
const send = annotate(new Command("send"), {
|
|
20
20
|
examples: [`${messenger.app.command} personal messages send "Book club" "The meeting starts at 10."`],
|
|
21
21
|
effects: REMOTE_WRITE,
|
|
22
|
+
output: { entity: "message_write" },
|
|
22
23
|
})
|
|
23
24
|
.description("send a text message; without [text], the text is read from stdin")
|
|
24
25
|
.argument("<chat>", messenger.chatArgument)
|
|
@@ -8,7 +8,11 @@ import { messengerContext, refuseLocalWrite } from "./context.js";
|
|
|
8
8
|
export const metadataCommand = (messenger) => {
|
|
9
9
|
const tool = messenger.app.command;
|
|
10
10
|
const command = new Command("metadata").description("cached group/channel descriptions for local automatic tags");
|
|
11
|
-
annotate(command.command("get"), {
|
|
11
|
+
annotate(command.command("get"), {
|
|
12
|
+
output: { entity: "chat_metadata" },
|
|
13
|
+
effects: LOCAL_READ,
|
|
14
|
+
examples: [`${tool} metadata get --chat 7`],
|
|
15
|
+
})
|
|
12
16
|
.description("a stored chat's cached description, as automatic tags read it")
|
|
13
17
|
.requiredOption("--chat <chat>", "a stored chat")
|
|
14
18
|
.action(async function () {
|
|
@@ -17,6 +21,7 @@ export const metadataCommand = (messenger) => {
|
|
|
17
21
|
renderAnswer(this, context, itemOf(snakeKeys(await context.withServices((services) => services.metadata.get(chat)))));
|
|
18
22
|
});
|
|
19
23
|
annotate(command.command("refresh"), {
|
|
24
|
+
output: { entity: "chat_metadata_refresh" },
|
|
20
25
|
effects: FETCH,
|
|
21
26
|
examples: [`${tool} metadata refresh --chat 7 --chat 8`, `${tool} metadata refresh --only-missing --limit 20`],
|
|
22
27
|
})
|
|
@@ -145,7 +145,11 @@ export const modelsCommand = (messenger) => {
|
|
|
145
145
|
}, { unbounded: true });
|
|
146
146
|
});
|
|
147
147
|
const key = text.command("key").description("API keys for embedding and analysis providers");
|
|
148
|
-
grantsAuthority(annotate(key.command("set"), {
|
|
148
|
+
grantsAuthority(annotate(key.command("set"), {
|
|
149
|
+
effects: LOCAL_WRITE,
|
|
150
|
+
output: { entity: "model_key", view: "stored" },
|
|
151
|
+
examples: [`${tool} models text key set openai`],
|
|
152
|
+
}))
|
|
149
153
|
.argument("<provider>", "openai, anthropic, or the host of a --base-url server that wants a key")
|
|
150
154
|
.description("store a key, typed at a hidden prompt or piped on stdin — never as an argument")
|
|
151
155
|
.action(async function (provider) {
|
|
@@ -159,7 +163,11 @@ export const modelsCommand = (messenger) => {
|
|
|
159
163
|
renderAnswer(this, context, itemOf({ provider, stored: source }));
|
|
160
164
|
});
|
|
161
165
|
});
|
|
162
|
-
grantsAuthority(annotate(key.command("remove"), {
|
|
166
|
+
grantsAuthority(annotate(key.command("remove"), {
|
|
167
|
+
effects: LOCAL_WRITE,
|
|
168
|
+
output: { entity: "model_key", view: "removed" },
|
|
169
|
+
examples: [`${tool} models text key remove openai`],
|
|
170
|
+
}))
|
|
163
171
|
.argument("<provider>", "openai, anthropic, or a server's host")
|
|
164
172
|
.description("forget a stored key")
|
|
165
173
|
.action(async function (provider) {
|
|
@@ -23,6 +23,7 @@ export const pollsCommand = (messenger) => {
|
|
|
23
23
|
? "read a poll, vote in it, create one"
|
|
24
24
|
: "read a poll, vote in it, close your own, create one");
|
|
25
25
|
annotate(polls.command("show"), {
|
|
26
|
+
output: { entity: "poll" },
|
|
26
27
|
effects: REMOTE_READ,
|
|
27
28
|
examples: [`${messenger.app.command} personal polls show "Book club" 101`],
|
|
28
29
|
})
|
|
@@ -67,6 +68,7 @@ export const pollsCommand = (messenger) => {
|
|
|
67
68
|
}), lines(({ voted_at, person_id, name, answers }) => [voted_at, name ?? person_id, answers.join(",")].join(" ")));
|
|
68
69
|
}));
|
|
69
70
|
annotate(polls.command("vote"), {
|
|
71
|
+
output: { entity: "poll_change" },
|
|
70
72
|
effects: REMOTE_WRITE,
|
|
71
73
|
examples: [`${messenger.app.command} personal polls vote "Book club" 101 0`],
|
|
72
74
|
})
|
|
@@ -95,6 +97,7 @@ export const pollsCommand = (messenger) => {
|
|
|
95
97
|
});
|
|
96
98
|
if (messenger.pollClose !== false)
|
|
97
99
|
annotate(polls.command("close"), {
|
|
100
|
+
output: { entity: "poll_change" },
|
|
98
101
|
effects: REMOTE_WRITE,
|
|
99
102
|
examples: [`${messenger.app.command} personal polls close "Book club" 101`],
|
|
100
103
|
})
|
|
@@ -107,6 +110,7 @@ export const pollsCommand = (messenger) => {
|
|
|
107
110
|
renderAnswer(this, context, itemOf(snakeKeys(closed)));
|
|
108
111
|
});
|
|
109
112
|
const create = annotate(polls.command("create"), {
|
|
113
|
+
output: { entity: "message_write" },
|
|
110
114
|
effects: REMOTE_WRITE,
|
|
111
115
|
examples: [`${messenger.app.command} personal polls create "Book club" "Which day?" Monday Tuesday`],
|
|
112
116
|
})
|
|
@@ -14,7 +14,7 @@ const NOTES_QUERY = unfilteredQuery("contact_note", contactNote);
|
|
|
14
14
|
const everyNote = (command, items) => listOf(command, { items, limit: Math.max(1, items.length), has_more: false });
|
|
15
15
|
export const privatePeopleCommands = (messenger) => {
|
|
16
16
|
const alias = new Command("alias").description("a private local display name in the selected account");
|
|
17
|
-
annotate(alias.command("set"), { effects: LOCAL_WRITE })
|
|
17
|
+
annotate(alias.command("set"), { effects: LOCAL_WRITE, output: { entity: "contact_alias" } })
|
|
18
18
|
.description("your own name for a person in this account; kept on this machine, never sent")
|
|
19
19
|
.argument("<person>", "the person's id, reference or known name")
|
|
20
20
|
.argument("<alias>", "the private name to use for this person")
|
|
@@ -23,7 +23,7 @@ export const privatePeopleCommands = (messenger) => {
|
|
|
23
23
|
refuseLocalWrite(context, messenger.app.command, "contacts.alias.set");
|
|
24
24
|
renderAnswer(this, context, itemOf(snakeKeys(await context.withServices((services) => services.privatePeople.alias(person, value)))));
|
|
25
25
|
});
|
|
26
|
-
annotate(alias.command("rm"), { effects: LOCAL_WRITE })
|
|
26
|
+
annotate(alias.command("rm"), { effects: LOCAL_WRITE, output: { entity: "contact_alias" } })
|
|
27
27
|
.description("drop your local name for a person; their own name shows again")
|
|
28
28
|
.argument("<person>", "the person's id, reference or known name")
|
|
29
29
|
.action(async function (person) {
|
|
@@ -78,7 +78,7 @@ export const privatePeopleCommands = (messenger) => {
|
|
|
78
78
|
renderAnswer(this, context, itemOf(saved));
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
-
annotate(notes.command("remove"), { effects: LOCAL_WRITE })
|
|
81
|
+
annotate(notes.command("remove"), { effects: LOCAL_WRITE, output: { entity: "contact_note_removal" } })
|
|
82
82
|
.description("delete one private note on a person")
|
|
83
83
|
.argument("<person>", "the person's id, reference or known name")
|
|
84
84
|
.argument("<id>", "the note id from contacts notes list")
|
|
@@ -12,6 +12,7 @@ import { renderAnswer } from "../envelope.js";
|
|
|
12
12
|
import { positiveCount } from "../paging.js";
|
|
13
13
|
import { messengerContext } from "./context.js";
|
|
14
14
|
import { syncOptions, syncRequest } from "./search-sync-options.js";
|
|
15
|
+
import { statisticsQuery, withStatisticsQuery } from "./statistics-query.js";
|
|
15
16
|
import { evidenceAnswer, rankingAnswer, refuseJsonl } from "./stats-answers.js";
|
|
16
17
|
const selectionOf = (value) => {
|
|
17
18
|
if (Buffer.byteLength(value) > RANKING_SELECTION_BYTES)
|
|
@@ -35,28 +36,22 @@ export const rankingsTopCommand = (messenger, target) => {
|
|
|
35
36
|
"engaging",
|
|
36
37
|
]))
|
|
37
38
|
.option("--weights <json>", "the complete component weights; replaces preset weights")
|
|
38
|
-
.addOption(new Option("--message-kind <kind>", "select proven all, posts or comments before ranking").choices([
|
|
39
|
-
"all",
|
|
40
|
-
"posts",
|
|
41
|
-
"comments",
|
|
42
|
-
]))
|
|
43
|
-
.option("--chat <chat>", `only this chat; ${messenger.chatArgument}`)
|
|
44
39
|
.option("--source <accounts>", "every held account of this messenger; personal, bots or all")
|
|
45
40
|
.option("--timezone <zone>", "the IANA timezone for dates and active days")
|
|
46
|
-
.option("--exact", "bare words match exact forms rather than stems")
|
|
47
41
|
.option("--limit <n>", "ranked rows, 1–100", positiveCount("--limit"))
|
|
48
42
|
.option("--saved <name|id>", "run a saved query or ranking run; typed options replace stored options");
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
const report = target === "contacts" ? "contacts-top" : "messages-top";
|
|
44
|
+
withStatisticsQuery(command, report);
|
|
51
45
|
command.action(async function (words) {
|
|
46
|
+
const filters = statisticsQuery(words, report);
|
|
52
47
|
const context = messengerContext(this, messenger);
|
|
53
48
|
refuseJsonl(context.format);
|
|
54
49
|
const options = this.opts();
|
|
55
50
|
const { saved, ...typed } = options;
|
|
56
|
-
let params = { ...typed, ...
|
|
51
|
+
let params = { ...typed, ...filters };
|
|
57
52
|
const found = await context.withServices(async (services) => {
|
|
58
53
|
if (saved !== undefined)
|
|
59
|
-
params = (await services.searches.resolve(saved, { ...params, text:
|
|
54
|
+
params = (await services.searches.resolve(saved, { ...params, text: filters.text ?? "" })).params;
|
|
60
55
|
if (params.target !== undefined && params.target !== target)
|
|
61
56
|
throw new CliError("validation_error", "saved ranking belongs to a different target");
|
|
62
57
|
if (params.newest || params.context)
|
|
@@ -8,6 +8,7 @@ export const reactionsCommand = (messenger) => {
|
|
|
8
8
|
const reactions = new Command("reactions").description("react to messages");
|
|
9
9
|
annotate(reactions.command("add"), {
|
|
10
10
|
effects: REMOTE_WRITE,
|
|
11
|
+
output: { entity: "reaction_change" },
|
|
11
12
|
examples: [`${messenger.app.command} personal reactions add "Book club" 101 👍`],
|
|
12
13
|
})
|
|
13
14
|
.description("put your reaction on a message; it replaces the one you had")
|
|
@@ -21,6 +22,7 @@ export const reactionsCommand = (messenger) => {
|
|
|
21
22
|
});
|
|
22
23
|
annotate(reactions.command("remove"), {
|
|
23
24
|
effects: REMOTE_WRITE,
|
|
25
|
+
output: { entity: "reaction_change" },
|
|
24
26
|
examples: [`${messenger.app.command} personal reactions remove "Book club" 101`],
|
|
25
27
|
})
|
|
26
28
|
.description("take your reaction off a message")
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type QueryRegistry } from "@wirecat/cli-base/query";
|
|
2
|
+
import type { RecipientFilter } from "../../sends/recipients.js";
|
|
3
|
+
import { type QueryWords } from "../list-query.js";
|
|
4
|
+
export declare const RECIPIENTS_QUERY: QueryRegistry;
|
|
5
|
+
export declare const recipientFilter: (words: QueryWords) => RecipientFilter;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { queryFieldsOf } from "@wirecat/cli-base/query";
|
|
2
|
+
import { recipient } from "../../entities/index.js";
|
|
3
|
+
import { queryTerms } from "../list-query.js";
|
|
4
|
+
export const RECIPIENTS_QUERY = {
|
|
5
|
+
entity: "recipient",
|
|
6
|
+
backend: "native",
|
|
7
|
+
fields: queryFieldsOf(recipient, {
|
|
8
|
+
native: ["id", "title"],
|
|
9
|
+
examples: { id: "id:7", title: 'title:"Book club"' },
|
|
10
|
+
}).map((field) => field.native
|
|
11
|
+
? { ...field, operators: field.operators.filter((operator) => operator === "term" || operator === "phrase") }
|
|
12
|
+
: field),
|
|
13
|
+
};
|
|
14
|
+
export const recipientFilter = (words) => {
|
|
15
|
+
const terms = queryTerms(words, RECIPIENTS_QUERY, "recipients list");
|
|
16
|
+
const id = terms.get("id"), title = terms.get("title");
|
|
17
|
+
return { ...(id === undefined ? {} : { id }), ...(title === undefined ? {} : { title }) };
|
|
18
|
+
};
|
|
@@ -83,6 +83,7 @@ export const callsCommand = (messenger) => {
|
|
|
83
83
|
/** `chats delete` and `chats clear` — for this account only; at the default level they ask first. */
|
|
84
84
|
export const chatDeletionCommands = (messenger) => [
|
|
85
85
|
annotate(new Command("delete"), {
|
|
86
|
+
output: { entity: "chat_removal" },
|
|
86
87
|
effects: REMOTE_WRITE,
|
|
87
88
|
mcp: false,
|
|
88
89
|
examples: [`${messenger.app.command} personal chats delete "Book club"`],
|
|
@@ -95,6 +96,7 @@ export const chatDeletionCommands = (messenger) => [
|
|
|
95
96
|
renderAnswer(this, context, itemOf(snakeKeys(await context.withServices((services) => services.admin.deleteChat(chat)))));
|
|
96
97
|
}),
|
|
97
98
|
annotate(new Command("clear"), {
|
|
99
|
+
output: { entity: "chat_removal" },
|
|
98
100
|
effects: REMOTE_WRITE,
|
|
99
101
|
mcp: false,
|
|
100
102
|
examples: [`${messenger.app.command} personal chats clear "Book club"`],
|
|
@@ -110,6 +112,7 @@ export const chatDeletionCommands = (messenger) => [
|
|
|
110
112
|
/** `chats mute` and `unmute` — the owner's own notifications for one chat; nobody in it is told. */
|
|
111
113
|
export const muteCommands = (messenger) => [
|
|
112
114
|
annotate(new Command("mute"), {
|
|
115
|
+
output: { entity: "chat_muting" },
|
|
113
116
|
effects: REMOTE_WRITE,
|
|
114
117
|
examples: [
|
|
115
118
|
`${messenger.app.command} chats mute "Book club"`,
|
|
@@ -126,6 +129,7 @@ export const muteCommands = (messenger) => [
|
|
|
126
129
|
renderAnswer(this, context, itemOf(snakeKeys(await context.withServices((services) => services.account.mute(chat, when)))));
|
|
127
130
|
}),
|
|
128
131
|
annotate(new Command("unmute"), {
|
|
132
|
+
output: { entity: "chat_muting" },
|
|
129
133
|
effects: REMOTE_WRITE,
|
|
130
134
|
examples: [`${messenger.app.command} chats unmute "Book club"`],
|
|
131
135
|
})
|
|
@@ -136,7 +140,8 @@ export const muteCommands = (messenger) => [
|
|
|
136
140
|
renderAnswer(this, context, itemOf(snakeKeys(await context.withServices((services) => services.account.mute(chat, null)))));
|
|
137
141
|
}),
|
|
138
142
|
];
|
|
139
|
-
const onChatCommand = (messenger, name, description, change) => annotate(new Command(name), {
|
|
143
|
+
const onChatCommand = (messenger, name, description, entity, change) => annotate(new Command(name), {
|
|
144
|
+
output: { entity },
|
|
140
145
|
effects: REMOTE_WRITE,
|
|
141
146
|
examples: [`${messenger.app.command} chats ${name} 123456789`],
|
|
142
147
|
})
|
|
@@ -148,16 +153,16 @@ const onChatCommand = (messenger, name, description, change) => annotate(new Com
|
|
|
148
153
|
});
|
|
149
154
|
/** `chats archive` and `unarchive` — the messenger's archive of chats, not the local store. */
|
|
150
155
|
export const archiveCommands = (messenger) => [
|
|
151
|
-
onChatCommand(messenger, "archive", "move a chat into the archive; nobody in it is told", (services, chat) => services.account.archive(chat, true)),
|
|
152
|
-
onChatCommand(messenger, "unarchive", "bring an archived chat back to the chat list", (services, chat) => services.account.archive(chat, false)),
|
|
156
|
+
onChatCommand(messenger, "archive", "move a chat into the archive; nobody in it is told", "chat_archive", (services, chat) => services.account.archive(chat, true)),
|
|
157
|
+
onChatCommand(messenger, "unarchive", "bring an archived chat back to the chat list", "chat_archive", (services, chat) => services.account.archive(chat, false)),
|
|
153
158
|
];
|
|
154
159
|
/** `chats pin` and `unpin` — where the chat sits in the owner's list; `messages pin` pins a message for everyone. */
|
|
155
160
|
export const chatPinCommands = (messenger) => [
|
|
156
|
-
onChatCommand(messenger, "pin", "keep a chat at the top of your chat list; nobody in it is told", (services, chat) => services.account.pinChat(chat, true)),
|
|
157
|
-
onChatCommand(messenger, "unpin", "let a pinned chat move down the chat list again", (services, chat) => services.account.pinChat(chat, false)),
|
|
161
|
+
onChatCommand(messenger, "pin", "keep a chat at the top of your chat list; nobody in it is told", "chat_pin", (services, chat) => services.account.pinChat(chat, true)),
|
|
162
|
+
onChatCommand(messenger, "unpin", "let a pinned chat move down the chat list again", "chat_pin", (services, chat) => services.account.pinChat(chat, false)),
|
|
158
163
|
];
|
|
159
164
|
/** `chats mark-unread` — undone by `chats mark-read`, which the other side does see. */
|
|
160
|
-
export const markUnreadCommand = (messenger) => onChatCommand(messenger, "mark-unread", "mark a chat unread on your own devices; nobody in it is told", (services, chat) => services.account.markUnread(chat));
|
|
165
|
+
export const markUnreadCommand = (messenger) => onChatCommand(messenger, "mark-unread", "mark a chat unread on your own devices; nobody in it is told", "chat_unread", (services, chat) => services.account.markUnread(chat));
|
|
161
166
|
const AUDIENCES = ["everyone", "contacts", "nobody"];
|
|
162
167
|
const audienceOf = (flag, value) => {
|
|
163
168
|
if (!AUDIENCES.includes(value))
|
|
@@ -202,6 +207,7 @@ export const privacyCommand = (messenger) => {
|
|
|
202
207
|
const keys = messenger.privacySettings ?? PRIVACY_SETTINGS;
|
|
203
208
|
const privacy = new Command("privacy").description("who may find, call or add the account");
|
|
204
209
|
annotate(privacy.command("show"), {
|
|
210
|
+
output: { entity: "account_privacy" },
|
|
205
211
|
effects: REMOTE_READ,
|
|
206
212
|
examples: [`${tool} account privacy show`, `${tool} account privacy show --json`],
|
|
207
213
|
})
|
|
@@ -214,6 +220,7 @@ export const privacyCommand = (messenger) => {
|
|
|
214
220
|
const audience = keys.find((key) => !SWITCHES.has(key));
|
|
215
221
|
const toggle = keys.find((key) => SWITCHES.has(key));
|
|
216
222
|
const set = annotate(new Command("set"), {
|
|
223
|
+
output: { entity: "account_privacy_change" },
|
|
217
224
|
effects: REMOTE_WRITE,
|
|
218
225
|
examples: [audience, toggle].flatMap((key) => (key === undefined ? [] : [exampleOf(tool, key)])),
|
|
219
226
|
}).description("change who may find, call or add the account; the settings not named stay");
|