@leemour/max-cli 0.12.0 → 0.14.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.
Files changed (149) hide show
  1. package/README.md +92 -19
  2. package/dist/bot/auth.d.ts +23 -0
  3. package/dist/bot/auth.d.ts.map +1 -0
  4. package/dist/bot/auth.js +36 -0
  5. package/dist/bot/auth.js.map +1 -0
  6. package/dist/bot/client.d.ts +20 -0
  7. package/dist/bot/client.d.ts.map +1 -0
  8. package/dist/bot/client.js +91 -0
  9. package/dist/bot/client.js.map +1 -0
  10. package/dist/bot/generated/manifest.d.ts +3 -0
  11. package/dist/bot/generated/manifest.d.ts.map +1 -0
  12. package/dist/bot/generated/manifest.js +1232 -0
  13. package/dist/bot/generated/manifest.js.map +1 -0
  14. package/dist/bot/generated/schemas.d.ts +271 -0
  15. package/dist/bot/generated/schemas.d.ts.map +1 -0
  16. package/dist/bot/generated/schemas.js +869 -0
  17. package/dist/bot/generated/schemas.js.map +1 -0
  18. package/dist/bot/generated/types.d.ts +1088 -0
  19. package/dist/bot/generated/types.d.ts.map +1 -0
  20. package/dist/bot/generated/types.js +5 -0
  21. package/dist/bot/generated/types.js.map +1 -0
  22. package/dist/bot/input.d.ts +10 -0
  23. package/dist/bot/input.d.ts.map +1 -0
  24. package/dist/bot/input.js +88 -0
  25. package/dist/bot/input.js.map +1 -0
  26. package/dist/bot/map.d.ts +11 -0
  27. package/dist/bot/map.d.ts.map +1 -0
  28. package/dist/bot/map.js +76 -0
  29. package/dist/bot/map.js.map +1 -0
  30. package/dist/bot/permissions.d.ts +14 -0
  31. package/dist/bot/permissions.d.ts.map +1 -0
  32. package/dist/bot/permissions.js +53 -0
  33. package/dist/bot/permissions.js.map +1 -0
  34. package/dist/bot/registry.d.ts +27 -0
  35. package/dist/bot/registry.d.ts.map +1 -0
  36. package/dist/bot/registry.js +68 -0
  37. package/dist/bot/registry.js.map +1 -0
  38. package/dist/bot/russian-trusted-root.d.ts +8 -0
  39. package/dist/bot/russian-trusted-root.d.ts.map +1 -0
  40. package/dist/bot/russian-trusted-root.js +41 -0
  41. package/dist/bot/russian-trusted-root.js.map +1 -0
  42. package/dist/bot/transport.d.ts +41 -0
  43. package/dist/bot/transport.d.ts.map +1 -0
  44. package/dist/bot/transport.js +200 -0
  45. package/dist/bot/transport.js.map +1 -0
  46. package/dist/client.d.ts +32 -1
  47. package/dist/client.d.ts.map +1 -1
  48. package/dist/client.js +174 -18
  49. package/dist/client.js.map +1 -1
  50. package/dist/commands/bot-context.d.ts +21 -0
  51. package/dist/commands/bot-context.d.ts.map +1 -0
  52. package/dist/commands/bot-context.js +59 -0
  53. package/dist/commands/bot-context.js.map +1 -0
  54. package/dist/commands/bot-reads.d.ts +7 -0
  55. package/dist/commands/bot-reads.d.ts.map +1 -0
  56. package/dist/commands/bot-reads.js +103 -0
  57. package/dist/commands/bot-reads.js.map +1 -0
  58. package/dist/commands/bot-sends.d.ts +12 -0
  59. package/dist/commands/bot-sends.d.ts.map +1 -0
  60. package/dist/commands/bot-sends.js +225 -0
  61. package/dist/commands/bot-sends.js.map +1 -0
  62. package/dist/commands/bot.d.ts +3 -0
  63. package/dist/commands/bot.d.ts.map +1 -0
  64. package/dist/commands/bot.js +145 -0
  65. package/dist/commands/bot.js.map +1 -0
  66. package/dist/commands/chats.d.ts.map +1 -1
  67. package/dist/commands/chats.js +65 -1
  68. package/dist/commands/chats.js.map +1 -1
  69. package/dist/commands/context.d.ts +10 -1
  70. package/dist/commands/context.d.ts.map +1 -1
  71. package/dist/commands/context.js.map +1 -1
  72. package/dist/commands/doctor.d.ts +6 -0
  73. package/dist/commands/doctor.d.ts.map +1 -1
  74. package/dist/commands/doctor.js +57 -7
  75. package/dist/commands/doctor.js.map +1 -1
  76. package/dist/commands/mcp.d.ts +24 -0
  77. package/dist/commands/mcp.d.ts.map +1 -1
  78. package/dist/commands/mcp.js +80 -14
  79. package/dist/commands/mcp.js.map +1 -1
  80. package/dist/commands/models.d.ts.map +1 -1
  81. package/dist/commands/models.js +13 -2
  82. package/dist/commands/models.js.map +1 -1
  83. package/dist/commands/review.d.ts +8 -0
  84. package/dist/commands/review.d.ts.map +1 -0
  85. package/dist/commands/review.js +96 -0
  86. package/dist/commands/review.js.map +1 -0
  87. package/dist/commands/rules.d.ts +7 -0
  88. package/dist/commands/rules.d.ts.map +1 -0
  89. package/dist/commands/rules.js +69 -0
  90. package/dist/commands/rules.js.map +1 -0
  91. package/dist/diagnose.d.ts +19 -1
  92. package/dist/diagnose.d.ts.map +1 -1
  93. package/dist/diagnose.js +37 -1
  94. package/dist/diagnose.js.map +1 -1
  95. package/dist/domain/map.d.ts +6 -1
  96. package/dist/domain/map.d.ts.map +1 -1
  97. package/dist/domain/map.js +34 -1
  98. package/dist/domain/map.js.map +1 -1
  99. package/dist/domain/models.d.ts +79 -0
  100. package/dist/domain/models.d.ts.map +1 -1
  101. package/dist/domain/models.js.map +1 -1
  102. package/dist/generated/operations.generated.d.ts +3 -1
  103. package/dist/generated/operations.generated.d.ts.map +1 -1
  104. package/dist/install.d.ts +43 -0
  105. package/dist/install.d.ts.map +1 -0
  106. package/dist/install.js +142 -0
  107. package/dist/install.js.map +1 -0
  108. package/dist/mcp/prompts.d.ts.map +1 -1
  109. package/dist/mcp/prompts.js +28 -0
  110. package/dist/mcp/prompts.js.map +1 -1
  111. package/dist/mcp/tools.d.ts.map +1 -1
  112. package/dist/mcp/tools.js +39 -1
  113. package/dist/mcp/tools.js.map +1 -1
  114. package/dist/moderation/rules.d.ts +56 -0
  115. package/dist/moderation/rules.d.ts.map +1 -0
  116. package/dist/moderation/rules.js +138 -0
  117. package/dist/moderation/rules.js.map +1 -0
  118. package/dist/online.d.ts +23 -0
  119. package/dist/online.d.ts.map +1 -0
  120. package/dist/online.js +87 -0
  121. package/dist/online.js.map +1 -0
  122. package/dist/program.d.ts.map +1 -1
  123. package/dist/program.js +20 -3
  124. package/dist/program.js.map +1 -1
  125. package/dist/protocol/connection.d.ts.map +1 -1
  126. package/dist/protocol/connection.js +12 -1
  127. package/dist/protocol/connection.js.map +1 -1
  128. package/dist/report.d.ts.map +1 -1
  129. package/dist/report.js +13 -2
  130. package/dist/report.js.map +1 -1
  131. package/dist/review.d.ts +41 -0
  132. package/dist/review.d.ts.map +1 -0
  133. package/dist/review.js +111 -0
  134. package/dist/review.js.map +1 -0
  135. package/dist/spec/operations/chats.d.ts +4 -1
  136. package/dist/spec/operations/chats.d.ts.map +1 -1
  137. package/dist/spec/operations/chats.js +10 -4
  138. package/dist/spec/operations/chats.js.map +1 -1
  139. package/dist/transcribe/index.d.ts +1 -0
  140. package/dist/transcribe/index.d.ts.map +1 -1
  141. package/dist/transcribe/index.js +8 -4
  142. package/dist/transcribe/index.js.map +1 -1
  143. package/dist/transcribe/speech.d.ts.map +1 -1
  144. package/dist/transcribe/speech.js +2 -0
  145. package/dist/transcribe/speech.js.map +1 -1
  146. package/dist/version.d.ts +1 -1
  147. package/dist/version.js +1 -1
  148. package/package.json +14 -6
  149. package/skills/max-cli/SKILL.md +26 -1
@@ -0,0 +1,200 @@
1
+ import tls from "node:tls";
2
+ import { backoffMs, CliError, DEFAULT_RETRY, realSleep, singleLine, } from "@leemour/cli-core";
3
+ import { providerWaitMs, statusToCode } from "@leemour/cli-core/http";
4
+ import { isLosslessNumber, isSafeNumber, parse, stringify } from "lossless-json";
5
+ import { VERSION } from "../version.js";
6
+ import { RUSSIAN_TRUSTED_ROOT_CA } from "./russian-trusted-root.js";
7
+ export const BOT_API_URL = "https://platform-api2.max.ru";
8
+ const DEFAULT_TIMEOUT_MS = 60_000;
9
+ /** `GET /updates` holds the request open for up to its own `timeout`; ours has to outlast it. */
10
+ const LONG_POLL_MARGIN_MS = 15_000;
11
+ let trusted = false;
12
+ /**
13
+ * Adds the Минцифры root to this process's trusted roots, and nowhere else (`NEED-293`). Node
14
+ * exposes a process-wide default (22.19+); Bun takes the list per request instead.
15
+ */
16
+ export const botFetch = () => {
17
+ if ("Bun" in globalThis) {
18
+ const ca = [...tls.rootCertificates, RUSSIAN_TRUSTED_ROOT_CA];
19
+ return (input, init) => fetch(input, { ...init, tls: { ca } });
20
+ }
21
+ if (!trusted && typeof tls.setDefaultCACertificates === "function") {
22
+ tls.setDefaultCACertificates([...tls.getCACertificates("default"), RUSSIAN_TRUSTED_ROOT_CA]);
23
+ trusted = true;
24
+ }
25
+ return fetch;
26
+ };
27
+ const TLS_FAILURES = new Set([
28
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
29
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
30
+ "SELF_SIGNED_CERT_IN_CHAIN",
31
+ "CERT_HAS_EXPIRED",
32
+ ]);
33
+ const causeCode = (error) => {
34
+ const cause = error?.cause;
35
+ const code = typeof cause?.code === "string" ? cause.code : error?.code;
36
+ return typeof code === "string" ? code : undefined;
37
+ };
38
+ /**
39
+ * The official Bot API over HTTP. Speaks for one token, writes nothing to stdout or stderr, and
40
+ * turns every failure into a `CliError` that never contains the token.
41
+ */
42
+ export class BotTransport {
43
+ #token;
44
+ #baseUrl;
45
+ #fetch;
46
+ #timeoutMs;
47
+ #retry;
48
+ #sleep;
49
+ #random;
50
+ #signal;
51
+ constructor(options) {
52
+ this.#token = options.token;
53
+ this.#baseUrl = (options.baseUrl ?? BOT_API_URL).replace(/\/$/, "");
54
+ this.#fetch = options.fetch ?? botFetch();
55
+ this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
56
+ this.#retry = options.retry ?? DEFAULT_RETRY;
57
+ this.#sleep = options.sleep ?? realSleep;
58
+ this.#random = options.random ?? Math.random;
59
+ this.#signal = options.signal;
60
+ }
61
+ /** The parsed answer, numbers still lossless; `null` when MAX answered with no body. */
62
+ async call(operation, input = {}) {
63
+ if (operation.binding.kind !== "http") {
64
+ throw new CliError("configuration_error", `${operation.id} is not an HTTP operation`);
65
+ }
66
+ const url = this.#url(operation.binding.path, input);
67
+ const reads = operation.effect === "read";
68
+ const timeoutMs = this.#timeoutFor(operation, input);
69
+ for (let attempt = 1;; attempt++) {
70
+ try {
71
+ return await this.#once(operation, url, input.body, timeoutMs);
72
+ }
73
+ catch (error) {
74
+ if (!(error instanceof CliError))
75
+ throw error;
76
+ if (this.#signal?.aborted)
77
+ throw error;
78
+ const retryable = reads && error.details.retryable === true && attempt <= this.#retry.retries;
79
+ if (!retryable)
80
+ throw error;
81
+ const wait = error.details.retryAfterMs ?? backoffMs(attempt, this.#retry, this.#random);
82
+ if (wait > this.#retry.maxRetryAfterMs)
83
+ throw error;
84
+ try {
85
+ await this.#sleep(wait, this.#signal, "retry");
86
+ }
87
+ catch {
88
+ throw error;
89
+ }
90
+ }
91
+ }
92
+ }
93
+ #url(template, input) {
94
+ const path = template.replace(/\{([^}]+)\}/g, (_, name) => {
95
+ const value = input.path?.[name];
96
+ if (value === undefined)
97
+ throw new CliError("validation_error", `missing path parameter ${name}`);
98
+ return encodeURIComponent(value);
99
+ });
100
+ const url = new URL(`${this.#baseUrl}${path}`);
101
+ for (const [name, value] of Object.entries(input.query ?? {})) {
102
+ url.searchParams.set(name, typeof value === "string" ? value : value.join(","));
103
+ }
104
+ return url;
105
+ }
106
+ #timeoutFor(operation, input) {
107
+ const poll = Number(input.query?.timeout);
108
+ return operation.id === "getUpdates" && Number.isFinite(poll)
109
+ ? Math.max(this.#timeoutMs, poll * 1000 + LONG_POLL_MARGIN_MS)
110
+ : this.#timeoutMs;
111
+ }
112
+ async #once(operation, url, body, timeoutMs) {
113
+ const signals = [AbortSignal.timeout(timeoutMs), ...(this.#signal ? [this.#signal] : [])];
114
+ const reads = operation.effect === "read";
115
+ let response;
116
+ try {
117
+ response = await this.#fetch(url, {
118
+ method: operation.binding.kind === "http" ? operation.binding.method : "POST",
119
+ headers: {
120
+ Authorization: this.#token,
121
+ "User-Agent": `max-cli/${VERSION}`,
122
+ Accept: "application/json",
123
+ ...(body === undefined ? {} : { "Content-Type": "application/json" }),
124
+ },
125
+ ...(body === undefined ? {} : { body }),
126
+ signal: AbortSignal.any(signals),
127
+ });
128
+ }
129
+ catch (error) {
130
+ throw this.#transportFailure(operation, error, reads, timeoutMs);
131
+ }
132
+ const text = await response.text();
133
+ if (!response.ok)
134
+ throw this.#refusal(operation, response, text);
135
+ if (text.trim() === "")
136
+ return null;
137
+ try {
138
+ return parse(text);
139
+ }
140
+ catch {
141
+ throw new CliError("invalid_response", `MAX answered ${operation.id} with something that is not JSON`, {
142
+ operation: operation.id,
143
+ status: response.status,
144
+ });
145
+ }
146
+ }
147
+ #transportFailure(operation, error, reads, timeoutMs) {
148
+ const code = causeCode(error);
149
+ if (code && TLS_FAILURES.has(code)) {
150
+ return new CliError("network_error", `this machine does not trust ${new URL(this.#baseUrl).host}'s certificate (${code}). ` +
151
+ "max-cli adds the Russian Trusted Root CA itself on Node 22.19+ and Bun — update Node, " +
152
+ "or set NODE_EXTRA_CA_CERTS to that certificate", { operation: operation.id, retryable: false });
153
+ }
154
+ if (this.#signal?.aborted) {
155
+ const deadline = this.#signal.reason?.name === "TimeoutError";
156
+ if (!deadline)
157
+ return new CliError("cancelled", `${operation.id} was cancelled`, { operation: operation.id });
158
+ if (!reads) {
159
+ return new CliError("outcome_unknown", `the command's time ran out while ${operation.id} was in flight; MAX may or may not have carried it out`, { operation: operation.id, retryable: false });
160
+ }
161
+ return new CliError("timeout", `the command's time ran out during ${operation.id}`, {
162
+ operation: operation.id,
163
+ retryable: false,
164
+ });
165
+ }
166
+ const timedOut = error?.name === "TimeoutError";
167
+ if (!reads) {
168
+ return new CliError("outcome_unknown", `${operation.id} got no answer${timedOut ? ` within ${timeoutMs} ms` : ""}; MAX may or may not have ` +
169
+ "carried it out — check before repeating it", { operation: operation.id, retryable: false });
170
+ }
171
+ return new CliError(timedOut ? "timeout" : "network_error", timedOut ? `${operation.id} got no answer within ${timeoutMs} ms` : `${operation.id} could not reach MAX`, { operation: operation.id, retryable: true });
172
+ }
173
+ #refusal(operation, response, text) {
174
+ let maxCode;
175
+ let said;
176
+ try {
177
+ const body = parse(text);
178
+ if (typeof body?.code === "string")
179
+ maxCode = body.code;
180
+ said = typeof body?.message === "string" ? body.message : typeof body?.error === "string" ? body.error : undefined;
181
+ }
182
+ catch { }
183
+ const retryable = response.status === 429 || response.status === 502 || response.status === 503;
184
+ const retryAfterMs = providerWaitMs(response.headers, () => new Date());
185
+ const reason = said ? `: ${singleLine(said).replaceAll(this.#token, "<token>").slice(0, 300)}` : "";
186
+ return new CliError(statusToCode(response.status), `MAX refused ${operation.id} (${response.status}${maxCode ? ` ${maxCode}` : ""})${reason}`, {
187
+ operation: operation.id,
188
+ status: response.status,
189
+ retryable,
190
+ ...(maxCode ? { maxCode } : {}),
191
+ ...(retryAfterMs === undefined ? {} : { retryAfterMs }),
192
+ });
193
+ }
194
+ }
195
+ /**
196
+ * What `max bot api` prints: a number that fits a JS number stays one, and a bigger one becomes
197
+ * its exact digits as a string rather than a rounded different number.
198
+ */
199
+ export const plainJson = (value) => JSON.parse(stringify(value, (_, inner) => isLosslessNumber(inner) && !isSafeNumber(inner.value) ? inner.toString() : inner) ?? "null");
200
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/bot/transport.ts"],"names":[],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { CacheStore, PersonOrder, SyncSummary } from "./cache/store.js";
2
- import type { AccountSession, AttachmentLink, Chat, ChatCard, ChatKind, Contact, ContactImport, Deletion, Folder, GroupCard, GroupSettings, Id, Inbox, Message, MessageChange, MessageHit, Page, PersonCard, Pin, Profile, Reactions, ReadMark, WindowedMessage } from "./domain/models.js";
2
+ import type { AccountSession, AttachmentLink, Chat, ChatCard, ChatEvents, ChatKind, Contact, ContactImport, Deletion, Folder, GroupCard, GroupMembers, GroupSettings, Id, Inbox, Message, MessageChange, MessageHit, Page, PersonCard, Pin, Profile, Reactions, ReadMark, Review, WindowedMessage } from "./domain/models.js";
3
3
  import { type Wire } from "./protocol/connection.js";
4
4
  import { type Payload } from "./protocol/frame.js";
5
5
  import { type DiagnosticEvent } from "./runs/events.js";
@@ -113,6 +113,20 @@ export declare class MaxClient {
113
113
  show: (reference: string) => Promise<ChatCard>;
114
114
  /** The other person in a one-to-one chat, by the chat's participants; `undefined` for anything else. */
115
115
  partner: (chatId: Id) => Promise<Id | undefined>;
116
+ /**
117
+ * The owner and admins of a group, from the chat as the login carried it (`owner`, `admins`,
118
+ * `adminParticipants` — measured 2026-09-24, `FIND-116`). `undefined` when the login did not
119
+ * carry this chat or its admins: the login carries only chats that changed lately, and the rest
120
+ * come from the local copy.
121
+ */
122
+ adminIds: (chatId: Id) => Promise<Id[] | undefined>;
123
+ /**
124
+ * Who joined, left, was added or removed since a point: the service messages in the chat's
125
+ * history, read forward from `since` without reactions. At most `EVENTS_READ` messages, the oldest.
126
+ */
127
+ events: (reference: string, { since }: {
128
+ since: number;
129
+ }) => Promise<ChatEvents>;
116
130
  /** What a link leads to, without joining it. */
117
131
  inspect: (link: string) => Promise<GroupCard>;
118
132
  join: (link: string) => Promise<GroupCard>;
@@ -129,6 +143,12 @@ export declare class MaxClient {
129
143
  */
130
144
  create: (title: string, people?: string[]) => Promise<GroupCard>;
131
145
  members: {
146
+ /**
147
+ * Everyone in a group or channel, from MAX, page by page. Paging follows PyMax: each answer's
148
+ * `marker` asks for the next page, and none means the last. Stops at `MEMBERS_READ`, or when a
149
+ * page repeats its marker or brings nobody new, so a misread marker cannot loop.
150
+ */
151
+ list: (reference: string) => Promise<GroupMembers>;
132
152
  /** No history unless asked (`NEED-272`): what was said before somebody joined is not theirs by default. */
133
153
  add: (reference: string, people: string[], { history }?: {
134
154
  history?: boolean;
@@ -411,6 +431,17 @@ export declare class MaxClient {
411
431
  since: number;
412
432
  limit: number;
413
433
  }) => Promise<Inbox>;
434
+ /**
435
+ * **Every message, both sides, in each chat that changed after `since`** — what a review of
436
+ * commitments reads, where `since` reads only other people's newest few. The same cut at the
437
+ * chat list's newest message, so the next review starting at `until` misses nothing. Pages
438
+ * forward from `since`; a chat with more than `REVIEW_PER_CHAT` in the window is cut short and
439
+ * says so.
440
+ */
441
+ review: ({ since, chatId, }: {
442
+ since: number;
443
+ chatId?: Id;
444
+ }) => Promise<Omit<Review, "complete" | "unheard">>;
414
445
  };
415
446
  /**
416
447
  * **For a connection that stays open** (`max serve`). A one-shot command never calls these.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CliError } from "@leemour/cli-core";
2
- import { namesFrom, SETTING_FLAGS, toChat, toContact, toFolder, toGroupCard, toMessage, toProfile, toReactions, toSession, } from "./domain/map.js";
2
+ import { namesFrom, SETTING_FLAGS, toChat, toContact, toFolder, toGroupCard, toGroupMember, toMessage, toProfile, toReactions, toSession, } from "./domain/map.js";
3
3
  import { heldWindows } from "./export.js";
4
4
  import { wireClient } from "./generated/client.generated.js";
5
5
  import { parseMarkdown } from "./markdown.js";
@@ -202,6 +202,74 @@ export class MaxClient {
202
202
  const raw = asArray(this.#session().chats).find((chat) => asId(chat.id) === chatId);
203
203
  return raw ? this.#partnerOf(raw) : undefined;
204
204
  },
205
+ /**
206
+ * The owner and admins of a group, from the chat as the login carried it (`owner`, `admins`,
207
+ * `adminParticipants` — measured 2026-09-24, `FIND-116`). `undefined` when the login did not
208
+ * carry this chat or its admins: the login carries only chats that changed lately, and the rest
209
+ * come from the local copy.
210
+ */
211
+ adminIds: async (chatId) => {
212
+ await this.#connectOnce();
213
+ const raw = asArray(this.#session().chats).find((chat) => asId(chat.id) === chatId);
214
+ if (!raw || (raw.owner === undefined && raw.admins === undefined && raw.adminParticipants === undefined)) {
215
+ return undefined;
216
+ }
217
+ const ids = [
218
+ asId(raw.owner),
219
+ ...(Array.isArray(raw.admins) ? raw.admins.map(asId) : []),
220
+ ...Object.keys(record(raw.adminParticipants) ?? {}),
221
+ ];
222
+ return [...new Set(ids.filter((id) => id !== undefined))];
223
+ },
224
+ /**
225
+ * Who joined, left, was added or removed since a point: the service messages in the chat's
226
+ * history, read forward from `since` without reactions. At most `EVENTS_READ` messages, the oldest.
227
+ */
228
+ events: async (reference, { since }) => {
229
+ if (this.#offline)
230
+ throw new CliError("validation_error", "`--offline` has no history to read events from");
231
+ const chatId = await this.chats.resolve(reference);
232
+ const read = [];
233
+ let from = since;
234
+ let more = false;
235
+ while (true) {
236
+ const page = (await this.#history(chatId, { from, backward: 0, forward: REVIEW_PAGE + 1 }, { reactions: false })).filter((message) => Date.parse(message.timestamp) > from);
237
+ read.push(...page);
238
+ const last = page.at(-1);
239
+ if (page.length < REVIEW_PAGE || !last)
240
+ break;
241
+ if (read.length >= EVENTS_READ) {
242
+ more = true;
243
+ break;
244
+ }
245
+ from = Date.parse(last.timestamp);
246
+ }
247
+ const found = read.flatMap((message) => message.attachments
248
+ .filter((attachment) => attachment.kind === "control" && attachment.event !== undefined)
249
+ .map((attachment) => ({ message, attachment })));
250
+ const contacts = namesFrom(this.#session().contacts);
251
+ const ids = [
252
+ ...new Set([
253
+ ...found.flatMap(({ attachment }) => attachment.userIds ?? []),
254
+ ...found.flatMap(({ message }) => message.senderName === null && message.senderId ? [message.senderId] : []),
255
+ ]),
256
+ ];
257
+ const names = await this.#namesOf(ids.filter((id) => !contacts.has(id)));
258
+ const nameOf = (id) => contacts.get(id) ?? names.get(id) ?? null;
259
+ return {
260
+ chatId,
261
+ since: new Date(since).toISOString(),
262
+ more,
263
+ events: found.map(({ message, attachment }) => ({
264
+ messageId: message.id,
265
+ timestamp: message.timestamp,
266
+ event: attachment.event ?? "",
267
+ by: { id: message.senderId, name: message.senderName ?? (message.senderId && nameOf(message.senderId)) },
268
+ people: (attachment.userIds ?? []).map((id) => ({ id, name: nameOf(id) })),
269
+ ...(attachment.title ? { title: attachment.title } : {}),
270
+ })),
271
+ };
272
+ },
205
273
  /** What a link leads to, without joining it. */
206
274
  inspect: async (link) => {
207
275
  if (this.#offline)
@@ -271,6 +339,36 @@ export class MaxClient {
271
339
  }, userIds);
272
340
  },
273
341
  members: {
342
+ /**
343
+ * Everyone in a group or channel, from MAX, page by page. Paging follows PyMax: each answer's
344
+ * `marker` asks for the next page, and none means the last. Stops at `MEMBERS_READ`, or when a
345
+ * page repeats its marker or brings nobody new, so a misread marker cannot loop.
346
+ */
347
+ list: async (reference) => {
348
+ if (this.#offline)
349
+ throw new CliError("validation_error", "`--offline` has no member list; MAX has");
350
+ const chatId = await this.chats.resolve(reference);
351
+ await this.#connectOnce();
352
+ const members = new Map();
353
+ let marker = 0;
354
+ let complete = false;
355
+ while (members.size < MEMBERS_READ) {
356
+ const answer = await this.#wire.chats.members({ chatId, type: "MEMBER", marker, count: MEMBERS_PAGE });
357
+ const before = members.size;
358
+ for (const raw of asArray(answer.members)) {
359
+ const member = toGroupMember(raw);
360
+ if (member.id)
361
+ members.set(member.id, member);
362
+ }
363
+ const next = typeof answer.marker === "number" ? answer.marker : 0;
364
+ if (!next || next === marker || members.size === before) {
365
+ complete = !next;
366
+ break;
367
+ }
368
+ marker = next;
369
+ }
370
+ return { chatId, members: [...members.values()], complete };
371
+ },
274
372
  /** No history unless asked (`NEED-272`): what was said before somebody joined is not theirs by default. */
275
373
  add: (reference, people, { history = false } = {}) => this.#updateMembers(reference, people, "members.add", { operation: "add", showHistory: history }),
276
374
  remove: (reference, people) => this.#updateMembers(reference, people, "members.remove", { operation: "remove", cleanMsgPeriod: 0 }),
@@ -945,7 +1043,7 @@ export class MaxClient {
945
1043
  unread: async ({ limit }) => {
946
1044
  const chats = (await this.chats.list()).items;
947
1045
  const waiting = byRecency(chats.filter((chat) => (chat.unreadCount ?? 0) > 0));
948
- const { read, skipped } = capped(waiting);
1046
+ const { read, skipped } = capped(waiting, INBOX_CHATS);
949
1047
  const found = [];
950
1048
  for (const { id, title, kind, unreadCount } of read) {
951
1049
  const count = unreadCount ?? 0;
@@ -971,10 +1069,8 @@ export class MaxClient {
971
1069
  * never show. Anything newer than the snapshot waits for the next run and shows once there.
972
1070
  */
973
1071
  since: async ({ since, limit }) => {
974
- const chats = (await this.chats.list()).items;
975
- const changed = byRecency(chats.filter((chat) => chat.lastMessageAt !== null && Date.parse(chat.lastMessageAt) > since));
976
- const cut = Math.max(since, ...changed.map((chat) => Date.parse(chat.lastMessageAt ?? "")));
977
- const { read, skipped } = capped(changed);
1072
+ const { chats, changed, cut } = await this.#changedSince(since);
1073
+ const { read, skipped } = capped(changed, INBOX_CHATS);
978
1074
  let until = since;
979
1075
  const found = [];
980
1076
  for (const { id, title, kind, unreadCount } of read) {
@@ -998,7 +1094,54 @@ export class MaxClient {
998
1094
  partial: !this.#cache && this.#chatsCut && changed.length === chats.length,
999
1095
  };
1000
1096
  },
1097
+ /**
1098
+ * **Every message, both sides, in each chat that changed after `since`** — what a review of
1099
+ * commitments reads, where `since` reads only other people's newest few. The same cut at the
1100
+ * chat list's newest message, so the next review starting at `until` misses nothing. Pages
1101
+ * forward from `since`; a chat with more than `REVIEW_PER_CHAT` in the window is cut short and
1102
+ * says so.
1103
+ */
1104
+ review: async ({ since, chatId, }) => {
1105
+ const { chats, changed: all, cut } = await this.#changedSince(since);
1106
+ const changed = chatId === undefined ? all : all.filter((chat) => chat.id === chatId);
1107
+ const { read, skipped } = capped(changed, REVIEW_CHATS);
1108
+ const found = [];
1109
+ for (const { id, title, kind } of read) {
1110
+ const messages = [];
1111
+ let from = since;
1112
+ let more = false;
1113
+ while (true) {
1114
+ const page = await this.messages.list(id, { after: from, limit: REVIEW_PAGE });
1115
+ const inWindow = page.items.filter((message) => Date.parse(message.timestamp) <= cut);
1116
+ messages.push(...inWindow);
1117
+ const last = page.items.at(-1);
1118
+ if (!page.hasMore || !last || inWindow.length < page.items.length)
1119
+ break;
1120
+ if (messages.length >= REVIEW_PER_CHAT) {
1121
+ more = true;
1122
+ break;
1123
+ }
1124
+ from = Date.parse(last.timestamp);
1125
+ }
1126
+ if (messages.length > 0)
1127
+ found.push({ id, title, kind, messages: messages.slice(0, REVIEW_PER_CHAT), more });
1128
+ }
1129
+ return {
1130
+ since: new Date(since).toISOString(),
1131
+ until: new Date(cut).toISOString(),
1132
+ chats: found,
1133
+ skipped,
1134
+ partial: !this.#cache && this.#chatsCut && changed.length === chats.length,
1135
+ };
1136
+ },
1001
1137
  };
1138
+ /** Chats whose last message is after `since`, newest first, and that newest time: the snapshot to cut at. */
1139
+ async #changedSince(since) {
1140
+ const chats = (await this.chats.list()).items;
1141
+ const changed = byRecency(chats.filter((chat) => chat.lastMessageAt !== null && Date.parse(chat.lastMessageAt) > since));
1142
+ const cut = Math.max(since, ...changed.map((chat) => Date.parse(chat.lastMessageAt ?? "")));
1143
+ return { chats, changed, cut };
1144
+ }
1002
1145
  /**
1003
1146
  * A reaction is seen by the other person, so it goes through the send guard and the send log like a
1004
1147
  * message. Not retried: a reaction lost in transit costs a second command, and nothing about it is
@@ -1550,6 +1693,18 @@ export class MaxClient {
1550
1693
  const ids = [...new Set([...messages, ...quoted].filter(needsName).map((message) => message.senderId))];
1551
1694
  if (ids.length === 0)
1552
1695
  return messages;
1696
+ const names = await this.#namesOf(ids);
1697
+ const name = (message) => needsName(message) && names.has(message.senderId)
1698
+ ? { ...message, senderName: names.get(message.senderId) ?? null }
1699
+ : message;
1700
+ return messages.map((message) => ({
1701
+ ...name(message),
1702
+ replyTo: message.replyTo && name(message.replyTo),
1703
+ forwardedFrom: message.forwardedFrom && name(message.forwardedFrom),
1704
+ }));
1705
+ }
1706
+ /** Names we hold first, the rest from `CONTACT_INFO`, kept for next time. A refusal costs the names only. */
1707
+ async #namesOf(ids) {
1553
1708
  const names = this.#cache?.people.names(ids) ?? new Map();
1554
1709
  const fetched = [];
1555
1710
  try {
@@ -1565,18 +1720,11 @@ export class MaxClient {
1565
1720
  }
1566
1721
  }
1567
1722
  catch (error) {
1568
- this.#warnAbout("names_unread", `some senders are shown by id: their names could not be looked up (${reasonOf(error)})`);
1723
+ this.#warnAbout("names_unread", `some people are shown by id: their names could not be looked up (${reasonOf(error)})`);
1569
1724
  }
1570
1725
  if (fetched.length > 0)
1571
1726
  this.#cache?.people.upsert(fetched, "info");
1572
- const name = (message) => needsName(message) && names.has(message.senderId)
1573
- ? { ...message, senderName: names.get(message.senderId) ?? null }
1574
- : message;
1575
- return messages.map((message) => ({
1576
- ...name(message),
1577
- replyTo: message.replyTo && name(message.replyTo),
1578
- forwardedFrom: message.forwardedFrom && name(message.forwardedFrom),
1579
- }));
1727
+ return names;
1580
1728
  }
1581
1729
  /** INIT with the profile's own device, which is the device MAX then issues the token to (bite 8). */
1582
1730
  async #beforeLogin(flow) {
@@ -1943,6 +2091,9 @@ export const ADMIN_RIGHTS = {
1943
2091
  /** The most chats `max serve` holds from pushes before it logs in again instead. */
1944
2092
  const LIVE_CHATS = 10_000;
1945
2093
  const JOIN_REQUESTS = 100;
2094
+ /** PyMax's page, the one measured. */
2095
+ const MEMBERS_PAGE = 50;
2096
+ const MEMBERS_READ = 5000;
1946
2097
  /**
1947
2098
  * A private link goes as `join/<token>`, whatever came before it, as PyMax sends it and as
1948
2099
  * measured. A public one (`https://max.ru/<name>`) goes whole, which is PyMax's claim only.
@@ -2005,6 +2156,11 @@ export const timeOfMessageId = (id) => {
2005
2156
  * account rarely has that many chats change between two checks, and the rest are named, not lost.
2006
2157
  */
2007
2158
  const INBOX_CHATS = 20;
2159
+ /** A review reads every changed chat of a few days; past this many, the rest are named, not read. */
2160
+ const REVIEW_CHATS = 50;
2161
+ const REVIEW_PAGE = 100;
2162
+ const REVIEW_PER_CHAT = 500;
2163
+ const EVENTS_READ = 2000;
2008
2164
  export const FIRST_TAB_SYNC = { folders: 0, calls: 0, assets: {} };
2009
2165
  const numberOr = (value, fallback) => (typeof value === "number" ? value : fallback);
2010
2166
  const eventTime = (chat) => {
@@ -2027,9 +2183,9 @@ const CHAT_CHANGED = 135;
2027
2183
  const CHANGES_CHATS = new Set([140, 142]);
2028
2184
  /** Newest first — the chats a reader most likely came for are read before the cap. */
2029
2185
  const byRecency = (chats) => chats.toSorted((a, b) => Date.parse(b.lastMessageAt ?? "") - Date.parse(a.lastMessageAt ?? ""));
2030
- const capped = (chats) => ({
2031
- read: chats.slice(0, INBOX_CHATS),
2032
- skipped: chats.slice(INBOX_CHATS).map(({ id, title, lastMessageAt }) => ({ id, title, lastMessageAt })),
2186
+ const capped = (chats, most) => ({
2187
+ read: chats.slice(0, most),
2188
+ skipped: chats.slice(most).map(({ id, title, lastMessageAt }) => ({ id, title, lastMessageAt })),
2033
2189
  });
2034
2190
  const isPresent = (value) => value !== null && value !== undefined;
2035
2191
  const needsName = (message) => message.senderId !== null && message.senderName === null && message.outgoing !== true;