@wirecat/max-cli 0.50.0 → 0.52.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 (219) hide show
  1. package/README.md +9 -9
  2. package/dist/adapter/max-adapter.d.ts.map +1 -1
  3. package/dist/adapter/max-adapter.js +8 -4
  4. package/dist/adapter/max-adapter.js.map +1 -1
  5. package/dist/app.d.ts.map +1 -1
  6. package/dist/app.js +2 -0
  7. package/dist/app.js.map +1 -1
  8. package/dist/bot/adapter.d.ts.map +1 -1
  9. package/dist/bot/adapter.js +3 -2
  10. package/dist/bot/adapter.js.map +1 -1
  11. package/dist/bot/mcp-tools.d.ts.map +1 -1
  12. package/dist/bot/mcp-tools.js +3 -3
  13. package/dist/bot/mcp-tools.js.map +1 -1
  14. package/dist/bot/transport.d.ts.map +1 -1
  15. package/dist/bot/transport.js +8 -3
  16. package/dist/bot/transport.js.map +1 -1
  17. package/dist/bot/uploads.d.ts +2 -2
  18. package/dist/bot/uploads.d.ts.map +1 -1
  19. package/dist/bot/uploads.js +3 -3
  20. package/dist/bot/uploads.js.map +1 -1
  21. package/dist/client/account.d.ts +39 -0
  22. package/dist/client/account.d.ts.map +1 -0
  23. package/dist/client/account.js +92 -0
  24. package/dist/client/account.js.map +1 -0
  25. package/dist/client/chat-members.d.ts +27 -0
  26. package/dist/client/chat-members.d.ts.map +1 -0
  27. package/dist/client/chat-members.js +73 -0
  28. package/dist/client/chat-members.js.map +1 -0
  29. package/dist/client/chat-reads.d.ts +57 -0
  30. package/dist/client/chat-reads.d.ts.map +1 -0
  31. package/dist/client/chat-reads.js +160 -0
  32. package/dist/client/chat-reads.js.map +1 -0
  33. package/dist/client/chat-writes.d.ts +111 -0
  34. package/dist/client/chat-writes.d.ts.map +1 -0
  35. package/dist/client/chat-writes.js +240 -0
  36. package/dist/client/chat-writes.js.map +1 -0
  37. package/dist/client/contacts.d.ts +39 -0
  38. package/dist/client/contacts.d.ts.map +1 -0
  39. package/dist/client/contacts.js +93 -0
  40. package/dist/client/contacts.js.map +1 -0
  41. package/dist/client/delivery.d.ts +35 -0
  42. package/dist/client/delivery.d.ts.map +1 -0
  43. package/dist/client/delivery.js +62 -0
  44. package/dist/client/delivery.js.map +1 -0
  45. package/dist/client/folders.d.ts +20 -0
  46. package/dist/client/folders.d.ts.map +1 -0
  47. package/dist/client/folders.js +57 -0
  48. package/dist/client/folders.js.map +1 -0
  49. package/dist/client/history.d.ts +41 -0
  50. package/dist/client/history.d.ts.map +1 -0
  51. package/dist/client/history.js +111 -0
  52. package/dist/client/history.js.map +1 -0
  53. package/dist/client/live.d.ts +38 -0
  54. package/dist/client/live.d.ts.map +1 -0
  55. package/dist/client/live.js +182 -0
  56. package/dist/client/live.js.map +1 -0
  57. package/dist/client/login.d.ts +11 -0
  58. package/dist/client/login.d.ts.map +1 -0
  59. package/dist/client/login.js +8 -0
  60. package/dist/client/login.js.map +1 -0
  61. package/dist/client/message-reads.d.ts +53 -0
  62. package/dist/client/message-reads.d.ts.map +1 -0
  63. package/dist/client/message-reads.js +164 -0
  64. package/dist/client/message-reads.js.map +1 -0
  65. package/dist/client/message-writes.d.ts +84 -0
  66. package/dist/client/message-writes.d.ts.map +1 -0
  67. package/dist/client/message-writes.js +254 -0
  68. package/dist/client/message-writes.js.map +1 -0
  69. package/dist/client/people.d.ts +31 -0
  70. package/dist/client/people.d.ts.map +1 -0
  71. package/dist/client/people.js +130 -0
  72. package/dist/client/people.js.map +1 -0
  73. package/dist/client/polls.d.ts +53 -0
  74. package/dist/client/polls.d.ts.map +1 -0
  75. package/dist/client/polls.js +141 -0
  76. package/dist/client/polls.js.map +1 -0
  77. package/dist/client/read-policy.d.ts +2 -0
  78. package/dist/client/read-policy.d.ts.map +1 -0
  79. package/dist/client/read-policy.js +34 -0
  80. package/dist/client/read-policy.js.map +1 -0
  81. package/dist/client/request.d.ts +21 -0
  82. package/dist/client/request.d.ts.map +1 -0
  83. package/dist/client/request.js +69 -0
  84. package/dist/client/request.js.map +1 -0
  85. package/dist/client/session.d.ts +50 -0
  86. package/dist/client/session.d.ts.map +1 -0
  87. package/dist/client/session.js +293 -0
  88. package/dist/client/session.js.map +1 -0
  89. package/dist/client/stickers.d.ts +12 -0
  90. package/dist/client/stickers.d.ts.map +1 -0
  91. package/dist/client/stickers.js +29 -0
  92. package/dist/client/stickers.js.map +1 -0
  93. package/dist/client/types.d.ts +54 -0
  94. package/dist/client/types.d.ts.map +1 -0
  95. package/dist/client/types.js +2 -0
  96. package/dist/client/types.js.map +1 -0
  97. package/dist/client/upload-transport.d.ts +15 -0
  98. package/dist/client/upload-transport.d.ts.map +1 -0
  99. package/dist/client/upload-transport.js +49 -0
  100. package/dist/client/upload-transport.js.map +1 -0
  101. package/dist/client/uploads.d.ts +15 -0
  102. package/dist/client/uploads.d.ts.map +1 -0
  103. package/dist/client/uploads.js +25 -0
  104. package/dist/client/uploads.js.map +1 -0
  105. package/dist/client/values.d.ts +120 -0
  106. package/dist/client/values.d.ts.map +1 -0
  107. package/dist/client/values.js +186 -0
  108. package/dist/client/values.js.map +1 -0
  109. package/dist/client/writes.d.ts +40 -0
  110. package/dist/client/writes.d.ts.map +1 -0
  111. package/dist/client/writes.js +186 -0
  112. package/dist/client/writes.js.map +1 -0
  113. package/dist/client.d.ts +29 -644
  114. package/dist/client.d.ts.map +1 -1
  115. package/dist/client.js +267 -2828
  116. package/dist/client.js.map +1 -1
  117. package/dist/commands/bot-comments.d.ts.map +1 -1
  118. package/dist/commands/bot-comments.js +13 -13
  119. package/dist/commands/bot-comments.js.map +1 -1
  120. package/dist/commands/bot-context.d.ts.map +1 -1
  121. package/dist/commands/bot-context.js +11 -3
  122. package/dist/commands/bot-context.js.map +1 -1
  123. package/dist/commands/bot-members.d.ts.map +1 -1
  124. package/dist/commands/bot-members.js +25 -14
  125. package/dist/commands/bot-members.js.map +1 -1
  126. package/dist/commands/bot-messenger.d.ts +5 -2
  127. package/dist/commands/bot-messenger.d.ts.map +1 -1
  128. package/dist/commands/bot-messenger.js +7 -11
  129. package/dist/commands/bot-messenger.js.map +1 -1
  130. package/dist/commands/bot-setup.d.ts.map +1 -1
  131. package/dist/commands/bot-setup.js +3 -2
  132. package/dist/commands/bot-setup.js.map +1 -1
  133. package/dist/commands/bot.d.ts +2 -1
  134. package/dist/commands/bot.d.ts.map +1 -1
  135. package/dist/commands/bot.js +6 -6
  136. package/dist/commands/bot.js.map +1 -1
  137. package/dist/commands/config.d.ts.map +1 -1
  138. package/dist/commands/config.js +33 -33
  139. package/dist/commands/config.js.map +1 -1
  140. package/dist/commands/contacts.d.ts.map +1 -1
  141. package/dist/commands/contacts.js +4 -5
  142. package/dist/commands/contacts.js.map +1 -1
  143. package/dist/commands/doctor.d.ts.map +1 -1
  144. package/dist/commands/doctor.js +10 -9
  145. package/dist/commands/doctor.js.map +1 -1
  146. package/dist/commands/mcp.d.ts.map +1 -1
  147. package/dist/commands/mcp.js +13 -13
  148. package/dist/commands/mcp.js.map +1 -1
  149. package/dist/commands/messages.d.ts.map +1 -1
  150. package/dist/commands/messages.js +12 -4
  151. package/dist/commands/messages.js.map +1 -1
  152. package/dist/commands/paging.d.ts +0 -36
  153. package/dist/commands/paging.d.ts.map +1 -1
  154. package/dist/commands/paging.js +0 -50
  155. package/dist/commands/paging.js.map +1 -1
  156. package/dist/commands/recipients.d.ts.map +1 -1
  157. package/dist/commands/recipients.js +15 -14
  158. package/dist/commands/recipients.js.map +1 -1
  159. package/dist/commands/serve.d.ts.map +1 -1
  160. package/dist/commands/serve.js +14 -4
  161. package/dist/commands/serve.js.map +1 -1
  162. package/dist/commands/session.d.ts.map +1 -1
  163. package/dist/commands/session.js +8 -7
  164. package/dist/commands/session.js.map +1 -1
  165. package/dist/commands/setup.js +2 -2
  166. package/dist/commands/setup.js.map +1 -1
  167. package/dist/commands/watch.d.ts +4 -2
  168. package/dist/commands/watch.d.ts.map +1 -1
  169. package/dist/commands/watch.js +21 -5
  170. package/dist/commands/watch.js.map +1 -1
  171. package/dist/config.d.ts +843 -143
  172. package/dist/config.d.ts.map +1 -1
  173. package/dist/config.js +33 -33
  174. package/dist/config.js.map +1 -1
  175. package/dist/mcp/legacy-check.d.ts.map +1 -1
  176. package/dist/mcp/legacy-check.js +5 -3
  177. package/dist/mcp/legacy-check.js.map +1 -1
  178. package/dist/mcp/photo.d.ts.map +1 -1
  179. package/dist/mcp/photo.js +2 -2
  180. package/dist/mcp/photo.js.map +1 -1
  181. package/dist/mcp/prompts.d.ts.map +1 -1
  182. package/dist/mcp/prompts.js +10 -8
  183. package/dist/mcp/prompts.js.map +1 -1
  184. package/dist/mcp/tools.d.ts.map +1 -1
  185. package/dist/mcp/tools.js +36 -27
  186. package/dist/mcp/tools.js.map +1 -1
  187. package/dist/messenger.d.ts.map +1 -1
  188. package/dist/messenger.js +11 -1
  189. package/dist/messenger.js.map +1 -1
  190. package/dist/permissions.d.ts.map +1 -1
  191. package/dist/permissions.js +4 -1
  192. package/dist/permissions.js.map +1 -1
  193. package/dist/program.d.ts.map +1 -1
  194. package/dist/program.js +7 -3
  195. package/dist/program.js.map +1 -1
  196. package/dist/protocol/connection.d.ts.map +1 -1
  197. package/dist/protocol/connection.js +44 -12
  198. package/dist/protocol/connection.js.map +1 -1
  199. package/dist/sends.d.ts +1 -1
  200. package/dist/sends.js +1 -1
  201. package/dist/server/server.d.ts +3 -1
  202. package/dist/server/server.d.ts.map +1 -1
  203. package/dist/server/server.js +39 -21
  204. package/dist/server/server.js.map +1 -1
  205. package/dist/server/subscribe.d.ts.map +1 -1
  206. package/dist/server/subscribe.js +30 -4
  207. package/dist/server/subscribe.js.map +1 -1
  208. package/dist/server/subscribers.d.ts +18 -0
  209. package/dist/server/subscribers.d.ts.map +1 -0
  210. package/dist/server/subscribers.js +146 -0
  211. package/dist/server/subscribers.js.map +1 -0
  212. package/dist/upload.d.ts +6 -5
  213. package/dist/upload.d.ts.map +1 -1
  214. package/dist/upload.js +16 -11
  215. package/dist/upload.js.map +1 -1
  216. package/dist/version.d.ts +1 -1
  217. package/dist/version.js +1 -1
  218. package/package.json +3 -3
  219. package/skills/max-cli/SKILL.md +79 -59
package/dist/upload.js CHANGED
@@ -1,7 +1,7 @@
1
- import { realpathSync } from "node:fs";
2
- import { readFile } from "node:fs/promises";
1
+ import { openAsBlob, realpathSync } from "node:fs";
2
+ import { stat } from "node:fs/promises";
3
3
  import { basename, extname, isAbsolute, relative, resolve, sep } from "node:path";
4
- import { CliError, resolvePaths } from "@wirecat/cli-base";
4
+ import { CliError, isCliError, resolvePaths } from "@wirecat/cli-base";
5
5
  import { WEB_USER_AGENT } from "./spec/identity.js";
6
6
  const HEADERS = {
7
7
  "User-Agent": WEB_USER_AGENT.headerUserAgent,
@@ -37,15 +37,20 @@ const inside = (path, dir) => {
37
37
  const way = relative(fold(resolve(dir)), fold(path));
38
38
  return way === "" || (!way.startsWith("..") && !isAbsolute(way));
39
39
  };
40
- export const readUpload = async (path, { anyFile = false } = {}) => {
40
+ /** The file as a Blob that reads it while it uploads; nothing is held in memory first. */
41
+ export const openUpload = async (path, { anyFile = false } = {}) => {
41
42
  if (!anyFile && refusedPlace(path)) {
42
43
  throw new CliError("validation_error", `cannot send ${path}: credential files and max's own folders are not sent — ` +
43
44
  "add --allow-any-file if this file is meant to go");
44
45
  }
45
46
  try {
46
- return await readFile(path);
47
+ if (!(await stat(path)).isFile())
48
+ throw new CliError("validation_error", `cannot send ${path}: it is a folder`);
49
+ return await openAsBlob(path);
47
50
  }
48
51
  catch (error) {
52
+ if (isCliError(error))
53
+ throw error;
49
54
  const reason = error.code === "ENOENT" ? "no such file" : "it cannot be read";
50
55
  throw new CliError("validation_error", `cannot send ${path}: ${reason}`);
51
56
  }
@@ -55,10 +60,10 @@ const UPLOAD_MS = 15 * 60_000;
55
60
  const uploadDeadline = () => AbortSignal.timeout(UPLOAD_MS);
56
61
  const refused = (kind, status) => new CliError("network_error", `the ${kind} could not be uploaded: HTTP ${status} — nothing was sent`);
57
62
  /** Measured 2026-09-24: a multipart POST, field `file`, answers `{photos: {<key>: {token}}}`. */
58
- export const uploadPhoto = async (url, path, bytes) => {
63
+ export const uploadPhoto = async (url, path, body) => {
59
64
  const form = new FormData();
60
65
  const type = IMAGE_TYPES[extname(path).toLowerCase()] ?? "application/octet-stream";
61
- form.append("file", new Blob([bytes], { type }), `image${extname(path).toLowerCase()}`);
66
+ form.append("file", new Blob([body], { type }), `image${extname(path).toLowerCase()}`);
62
67
  const response = await fetch(url, { method: "POST", headers: HEADERS, body: form, signal: uploadDeadline() });
63
68
  if (!response.ok)
64
69
  throw refused("photo", response.status);
@@ -68,7 +73,7 @@ export const uploadPhoto = async (url, path, bytes) => {
68
73
  throw new CliError("provider_error", "the photo upload answered no token — nothing was sent");
69
74
  return token;
70
75
  };
71
- const postRaw = async (kind, url, path, bytes, range) => {
76
+ const postRaw = async (kind, url, path, body, range) => {
72
77
  const response = await fetch(url, {
73
78
  method: "POST",
74
79
  headers: {
@@ -77,7 +82,7 @@ const postRaw = async (kind, url, path, bytes, range) => {
77
82
  "Content-Range": range,
78
83
  "Content-Type": "application/octet-stream",
79
84
  },
80
- body: bytes,
85
+ body,
81
86
  signal: uploadDeadline(),
82
87
  });
83
88
  await response.body?.cancel();
@@ -88,7 +93,7 @@ const postRaw = async (kind, url, path, bytes, range) => {
88
93
  * Measured 2026-09-24: the bytes raw, with `Content-Range: 0-<end>/<size>` — no `bytes ` unit, as
89
94
  * PyMax sends it and MAX accepted.
90
95
  */
91
- export const uploadFile = (url, path, bytes) => postRaw("file", url, path, bytes, `0-${bytes.length - 1}/${bytes.length}`);
96
+ export const uploadFile = (url, path, body) => postRaw("file", url, path, body, `0-${body.size - 1}/${body.size}`);
92
97
  /** Measured 2026-09-27 with the `bytes ` unit, which PyMax and the web client send for these. */
93
- export const uploadMedia = (kind, url, path, bytes) => postRaw(kind, url, path, bytes, `bytes 0-${bytes.length - 1}/${bytes.length}`);
98
+ export const uploadMedia = (kind, url, path, body) => postRaw(kind, url, path, body, `bytes 0-${body.size - 1}/${body.size}`);
94
99
  //# sourceMappingURL=upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.50.0";
1
+ export declare const VERSION = "0.52.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "0.50.0";
1
+ export const VERSION = "0.52.0";
2
2
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/max-cli",
3
- "version": "0.50.0",
3
+ "version": "0.52.0",
4
4
  "description": "MAX Messenger bots through the official Bot API, and a personal MAX account, from the terminal — built for agents and scripts",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",
@@ -100,8 +100,8 @@
100
100
  "@modelcontextprotocol/server": "2.1.0",
101
101
  "@msgpack/msgpack": "3.1.3",
102
102
  "@valibot/to-json-schema": "1.8.0",
103
- "@wirecat/cli-base": "0.26.0",
104
- "@wirecat/cli-core": "0.262.0",
103
+ "@wirecat/cli-base": "0.28.1",
104
+ "@wirecat/cli-core": "0.276.0",
105
105
  "commander": "15.0.0",
106
106
  "lossless-json": "4.3.1",
107
107
  "ogg-opus-decoder": "1.7.5",
@@ -15,8 +15,8 @@ description: >-
15
15
  глобальные флаги и коды выхода. Для короткой справки — `max <команда> --help`.
16
16
  Слова после `commands` задают один путь, а не список групп: разные группы смотрите отдельными
17
17
  вызовами. **`max commands --json`** возвращает всё дерево для общего обзора;
18
- не читайте его целиком перед каждой задачей. `mutates: true` обозначает запись,
19
- а `local: true` ограничивает её этой машиной. `commands --json` не подключается к аккаунту. Его поле `contract` —
18
+ не читайте его целиком перед каждой задачей. `effects.remote: "write"` обозначает запись в MAX,
19
+ а один `effects.local: "write"` — запись только на этой машине. `commands --json` не подключается к аккаунту. Его поле `contract` —
20
20
  версия общего JSON-контракта; она меняется только при несовместимом изменении полей ответа, а не
21
21
  при обновлении пакета, поэтому проверяйте это поле, а не весь вывод целиком. Здесь — ловушки и границы.
22
22
 
@@ -24,9 +24,8 @@ description: >-
24
24
 
25
25
  `max commands schema messages list --json` показывает схемы и эффекты одной команды.
26
26
  Используйте `--json --no-input` для работы без вопросов; секреты передавайте явно через pipe.
27
- `--fields id,text` выбирает поля каждого элемента списка, сохраняя страницу, полноту и
28
- идентификаторы операций. Для id достаточно `--fields id`; `items.id` также поддерживается,
29
- а синтаксис `items[].id` не нужен. `--max-output-bytes` и `--max-input-bytes` задают byte budgets;
27
+ `--json=id,text` оставляет эти поля каждого элемента списка вместе со страницей и полнотой. Для id
28
+ достаточно `--json=id`. `--max-output-bytes` и `--max-input-bytes` задают byte budgets;
30
29
  одноразовые действия имеют срок 30 секунд, меняемый через `--timeout`.
31
30
  Перед чувствительной записью `--dry-run` проверяет форму запроса и права до действия;
32
31
  общий preview не подключается к мессенджеру, не резервирует запись и оставляет цели непроверенными.
@@ -103,11 +102,11 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
103
102
 
104
103
  - **В pipe или с `--json` stdout — только данные**, одно значение JSON. Всё остальное, включая
105
104
  предупреждения, уходит в stderr. Ошибка, завершающая команду, — тоже в stderr, stdout при ней пуст.
106
- - **Частичные чтения и загрузки могут завершиться кодом `0`**: проверьте `complete`, `batch.failed` и `issue`; JSONL частичной загрузки добавляет `batch_summary`. Успешная часть сохраняется, повторяйте только незавершённое после указанной паузы.
107
- - **Любой список — объект**, а не массив: `{ "items": [...], "page": 1, "limit": 20, "hasMore": true }`,
108
- у бота тоже. У списка без страниц `page` — 1, `limit` — сколько пришло, `hasMore` — `false`.
109
- `bot chats members list` кладёт рядом `marker` для следующей страницы.
110
- - **`--jsonl`** — по объекту на строку, удобно для `jq`. Есть ли ещё, пишется только в stderr.
105
+ - **Частичные чтения и загрузки могут завершиться кодом `0`**: проверьте `missing`, `next`, а у загрузок — `complete`, `batch.failed` и `issue`; JSONL частичной загрузки добавляет `batch_summary`. Успешная часть сохраняется, повторяйте только незавершённое после указанной паузы.
106
+ - **Любой список — объект**, а не массив: `{ "items": [...], "page": { "limit": 20, "has_more": true }, "meta": {…} }`,
107
+ у бота тоже; одна вещь — `{ "item": {…} }`. Ключи — snake_case. Следующую страницу называет шаг `page.next`
108
+ в `next` (его `cursor` или `page`), у бота тоже; чего в ответе нет — `missing`. У списка без страниц `page.has_more` — `false`.
109
+ - **`--jsonl`** — по объекту на строку, удобно для `jq`; последняя строка — `{"type": "end", …}` с `page`. Отчёты `stats` `--jsonl` не принимают.
111
110
  - **Ветвиться по коду возврата, а не по тексту**: `0` — успех, `2` — неверный ввод, `4` — нет
112
111
  входа, `5` — профилю это действие не разрешено (`permissions`; ошибка называет запрещённый ресурс или действие — не обходить), `6` — не найдено, `7` — чата нет в списке разрешённых,
113
112
  `8` — лимит: отправок за час, или MAX отказал во входе из-за частых попыток (тогда **не повторять**:
@@ -120,7 +119,7 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
120
119
  1. **Id — всегда строки.** Id сообщений 18-значные, больше `Number.MAX_SAFE_INTEGER`. Никогда не
121
120
  превращать их в число: `jq` и JavaScript молча округлят, и id станет чужим.
122
121
  2. **Первое слово — профиль, если это не команда.** `max work chats list` — профиль `work`.
123
- Флага `--profile` нет; то же делает переменная `MAX_PROFILE` или настройка `defaultProfile`.
122
+ Флага `--profile` нет; то же делает переменная `MAX_PROFILE` или настройка `default_profile`.
124
123
  **Профиль не подразумевается, даже единственный:** без имени команда завершается с кодом `2`
125
124
  и перечисляет профили (`error.profiles`) — спросите владельца, какой нужен, не берите первый.
126
125
  Без профиля работают `--help`, `commands`, `skill show`, `account list`, `config show`. Имя профиля — латиница, цифры,
@@ -133,9 +132,9 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
133
132
  `[{ id, name, username }]`. `contacts block`, `unblock`, `rename` и `account update --photo`
134
133
  меняют аккаунт владельца — только по его просьбе.
135
134
  4. **Код `14` — неизвестный исход записи, а не разрешение повторять её.** Проверьте
136
- `max personal sends list --json` по `operationId` и историю целевого чата. `operationId` связывает
135
+ `max personal sends list --json` по `operation_id` и историю целевого чата. `operation_id` связывает
137
136
  запись с журналом, но не является ключом идемпотентности. Повтор сообщения возможен только
138
- при подтверждённой дедупликации провайдера и с теми же чатом, темой, содержимым и `--send-id`;
137
+ при подтверждённой дедупликации провайдера и с теми же чатом, темой, содержимым и `--operation-id`;
139
138
  никакой автоматической повторной записи только по коду ошибки.
140
139
 
141
140
  5. **Искать начинайте с `max personal search all`**: сообщения, почта и заметки на этой машине одним ответом, у каждой
@@ -146,9 +145,9 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
146
145
  скачивания модели, со строгими ограничениями и подходящими прямыми ответами. Проверь
147
146
  отсутствующие слова, родительские ссылки и сами сообщения; первый результат и его оценка
148
147
  не доказывают ответ. Явный синтаксис остаётся строгим.
149
- **Без `--discover`, `max personal search messages` с одним чатом (`--chat` или `chat:`) спрашивает и сервер MAX**
148
+ **Без `--discover`, `max personal search messages` с одним чатом (`chat:` в запросе) спрашивает и сервер MAX**
150
149
  (`--backend archive` — только архив). Хороший поиск требует скачанных чатов: если ничего не нашлось, а
151
- `coverage.next` задан, выполните его (`max personal messages sync --all --background`) или спросите владельца, прежде чем
150
+ в `next` есть шаг `messages.sync`, выполните его (`max personal messages sync --all --background`) или спросите владельца, прежде чем
152
151
  говорить, что сообщения нет. Слова и фразы находят формы слов; `exact:` или `--exact` — только точную форму.
153
152
  Default — строгий профиль Lucene:
154
153
  фразы, AND/OR/NOT, field groups и date ranges. `alpha OR beta gamma` = `(alpha OR beta) AND gamma`.
@@ -160,7 +159,8 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
160
159
  Подсчёт — `max personal stats messages show`. Руководства: [поиск](https://github.com/WireCatLabs/max-cli/blob/main/docs/search.md),
161
160
  [поиск по темам](https://github.com/WireCatLabs/max-cli/blob/main/docs/topic-search.md) (разговоры по смыслу),
162
161
  [язык запросов](https://github.com/WireCatLabs/max-cli/blob/main/docs/query-language.md).
163
- 5a. **Substring-поиску имён нужны три символа:** --search у chats/contacts list. Строгие message
162
+ 5a. **Substring-поиску названий нужны три символа:** `title:` у chats list. Запрос `chats list` отвечает только из
163
+ локальной копии — с `--offline`; `contacts list name:`/`notes:` отказывают, пока в копии нет контактов. Строгие message
164
164
  terms могут быть короче; не заменяйте strict zero hits fuzzy discovery автоматически.
165
165
 
166
166
  5b. **`max personal store export` выгружает только скачанное и прочитанное** и в MAX не ходит. Какие куски
@@ -178,11 +178,11 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
178
178
  6. **`messages show` и `messages context` требуют чат и id сообщения** — или одну ссылку `msg:…` из
179
179
  `search messages`. Искомое сообщение в JSON помечено `"anchor": true`. Если сообщения нет, это
180
180
  `not_found`, а не соседнее сообщение.
181
- 7. **Время сообщения зашито в его id**: `id >> 16` — миллисекунды. Поэтому `--before-id` и
182
- `--after-id` работают для любого id, даже не прочитанного раньше. Само сообщение не входит ни в
183
- тот, ни в другой ответ. Две из `--before-id`, `--before-time`, `--after-id`, `--after-time` вместе —
184
- отказ с кодом `2`. `--since-time`, `--before-time` и `--after-time` понимают и `30m`, `2h`, `1d` —
185
- столько назад: `max personal review --since-time 1d`.
181
+ 7. **Время сообщения зашито в его id**: `id >> 16` — миллисекунды. Поэтому `id<…` и `id>…` в запросе
182
+ `messages list` работают для любого id, даже не прочитанного раньше. Само сообщение не входит ни в
183
+ тот, ни в другой ответ. Две начальные точки (`id<`, `id>`, `date<`, `date>`) вместе — отказ с кодом `2`.
184
+ `date` понимает и `30m`, `2h`, `1d` — столько назад: `max personal review 'date>1d'`; точное время — в
185
+ кавычках с секундами и смещением: `'date>"2026-09-23T09:00:00Z"'`. Запрос с `>` берите в одинарные кавычки.
186
186
  8. **`MAX_CONFIG_DIR`, `MAX_STATE_DIR` меняют и запись в ключнице.** Устаревший `MAX_CACHE_DIR`
187
187
  тоже влияет на неё. С этими переменными профиль ищет другой токен и может ответить
188
188
  «нет сессии», хотя владелец вошёл. Файл общей копии задаёт `MESSAGING_STORE`. `max config show`
@@ -195,12 +195,12 @@ remove|admins|update|link reset|requests accept|requests decline` видят д
195
195
  -1000`. Один перевод строки в самом конце отбрасывается, остальные сохраняются.
196
196
  11. **Номер страницы на живом списке может повторить или пропустить строку.** Сверху самое свежее,
197
197
  поэтому сообщение, пришедшее между первой страницей и второй, сдвигает кого-то через границу.
198
- Для переписки этого нет: `--before-id` привязан ко времени и точен.
198
+ Для переписки этого нет: `id<…` привязан ко времени и точен.
199
199
  12. **`max personal inbox --new` сдвигает место, где владелец остановился.** После него следующий
200
200
  `--new` владельца не покажет того, что уже увидел агент. Без сдвига: просто `max personal inbox`
201
- (непрочитанное) или `max personal inbox --since-time <время>`.
202
- 13. **`--at-time` ставит сообщение в очередь MAX, а не отправляет.** Ответ — `{sendId, operationId,
203
- message, scheduledFor}`; ушедшее сообщение получит другой id. Очередь: `max messages scheduled <чат>`.
201
+ (непрочитанное) или `max personal inbox 'date>2h'`.
202
+ 13. **`--at-time` ставит сообщение в очередь MAX, а не отправляет.** Ответ — `{item: {operation_id, operation_id,
203
+ message, scheduled_for}}`; ушедшее сообщение получит другой id. Очередь: `max messages scheduled <чат>`.
204
204
  Через MCP — параметр `at_time` у `max_write` (`command: "messages send"`) и инструмент `max_read` (`command: "messages scheduled"`).
205
205
  Отменить можно только в приложении MAX.
206
206
 
@@ -223,7 +223,7 @@ Id ниже выдуманные — подставить настоящие и
223
223
  - **Найти договорённость или документ:** найдите нужные чаты и ищите в локальной копии.
224
224
  Проверьте покрытие поиска и `store status`; `messages list` показывает только окно сообщений.
225
225
  Уточняйте найденное через `messages context` или `messages show`, приводите ссылки на сообщения.
226
- Проверьте связанные чаты на поздние изменения. Пустой результат, пустой чат и `hasMore: false`
226
+ Проверьте связанные чаты на поздние изменения. Пустой результат, пустой чат и `has_more: false`
227
227
  не доказывают полноту истории MAX. Если это влияет на ответ, объясните пробел.
228
228
  Скачивайте только разрешённый чат и ограниченный период или объём; сначала согласуйте
229
229
  с владельцем чат и предел сообщений или период. Без сети недостающую историю скачать нельзя.
@@ -239,48 +239,49 @@ Id ниже выдуманные — подставить настоящие и
239
239
  черновик; не меняйте настройки и не переключайте профили.
240
240
 
241
241
  ```sh
242
- max personal chats list --search "проект" --json # найти чат, взять его id
243
- max personal chats list --unread --json # где есть непрочитанное
242
+ max personal chats list title:проект --offline --json # найти чат, взять его id
243
+ max personal chats list 'unread_count>0' --offline --json # где есть непрочитанное
244
244
  max personal inbox --json # непрочитанное во всех чатах
245
245
  max personal inbox --new --json # что пришло с прошлой проверки, один раз
246
- max personal review --since-time 2026-09-23T09:00 --json # всё, свои тоже, для обзора «кто кому должен»
247
- max personal review --chat -1000 --unanswered 4h --json # вопросы в группе, на которые 4 часа не ответили ни владелец, ни админы
248
- max personal tasks list --state open --json # что ждёт ответа владельца; задачи открывает и закрывает review
246
+ max personal review 'date>"2026-09-23T09:00:00Z"' --json # всё, свои тоже, для обзора «кто кому должен»
247
+ max personal review 'chat:"-1000"' --unanswered 4h --json # вопросы в группе, на которые 4 часа не ответили ни владелец, ни админы
248
+ max personal tasks list state:open --json # что ждёт ответа владельца; задачи открывает и закрывает review
249
249
  max personal tasks close <задача> --as dismissed --reason no-reply-needed --json # только когда владелец так решил
250
250
  max personal watch --jsonl # новые сообщения по мере прихода; `max personal serve` запустится сам
251
251
  max personal watch --events --jsonl # плюс правки, удаления, реакции, прочтения, изменения чатов; поле "event"
252
252
  max personal server status --json # работает ли фоновый сервер, какой версии, подключён ли
253
253
  max personal chats show -1000 --json # один чат и кто в нём
254
- max personal chats events -1000 --since-time 2026-09-20T00:00 --json # кто вступил, вышел, кого добавили и удалили
255
- max personal chats members list -1000 --all --json # все участники от MAX: registeredAt, lastSeenAt
254
+ max personal chats events -1000 'time>=2026-09-20' --json # кто вступил, вышел, кого добавили и удалили
255
+ max personal chats members list -1000 --all --json # все участники от MAX: registered_at, last_seen_at
256
256
  max personal chats requests list -1000 --json # заявки в канал с одобрением; время неизвестно
257
257
  max personal chats requests accept -1000 20000002 # только по просьбе владельца; decline — отказать
258
258
  max personal chats rules show -1000 --json # правила модерации группы; set <ключ> <значение> меняет одно
259
259
  max personal chats moderate -1000 --dry-run --json # что нового нарушает правила; без --dry-run — только по слову владельца
260
260
  max personal contacts show @ivan --json # один человек и общие чаты
261
261
  max personal messages list -1000 --limit 20 --json # последние сообщения, от старых к новым
262
- max personal messages list -1000 --after-id 100000000000000001 --json # что было после этого сообщения
262
+ max personal messages list -1000 'id>100000000000000001' --json # что было после этого сообщения
263
263
  max personal messages context -1000 100000000000000001 --before-n 3 --after-n 3 --json
264
264
  max personal messages transcribe -1000 100000000000000001 --json # текст голосового, на этой машине
265
265
  ```
266
266
 
267
267
  **Обзор «кто кому должен» — `max personal review`**, одним вызовом: все сообщения обеих сторон во всех
268
- изменившихся чатах. `--since-time` — граница, на которой кончился прошлый обзор; её называет владелец или
268
+ изменившихся чатах. `date>…` в запросе — граница, на которой кончился прошлый обзор; её называет владелец или
269
269
  прошлый обзор. Разложить на «я должен», «жду от других», «нужно уточнить» — работа агента; у пункта
270
- чат, дата и id сообщений. Своё «сделаю» ищите в `"outgoing": true`. При `"complete": false` сказать,
271
- чего не хватает, и не предлагать новую границу; иначе закончить `--since-time` = `until`. Напоминания —
270
+ чат, дата и id сообщений. Своё «сделаю» ищите в `"outgoing": true`. Если есть `missing`, сказать,
271
+ чего не хватает. Следующий обзор начинать с запроса шага `review.next` из `next`: при неполном обзоре он
272
+ повторяет ту же границу. Напоминания —
272
273
  черновики, отправка — только по слову владельца.
273
274
 
274
275
  Голосовое — вложение `"kind": "voice"` в `messages list|show|context`, `search messages`, `inbox` и `review`.
275
276
  Его текст даёт `max personal messages transcribe`; до минуты на пять минут речи, повторно — сразу из общей
276
277
  локальной копии сообщений. Уже расшифрованное голосовое несёт поле `transcript` в
277
- `messages list` и `inbox`; `--transcribe` там расшифровывает остальные показанные, а не
278
- расшифрованные перечисляет в `unheard`. При отсутствии модели пакетное чтение сохраняет
279
- сообщения и сообщает `unheard`/`transcribeProblem`; одиночная `messages transcribe` откажет
278
+ `messages list`, `inbox` и `review`; остальные называет запись `transcript` в `missing` (обзор с ними не полон),
279
+ а `--transcribe` расшифровывает их и называет там то, что не вышло. При отсутствии модели пакетное чтение сохраняет
280
+ сообщения и сообщает причину там же; одиночная `messages transcribe` откажет
280
281
  и назовёт `max personal models audio download <id>`: **сказать об этом владельцу и не скачивать самому** — это сотни
281
282
  мегабайт, и выбор модели за ним.
282
283
 
283
- Каталог аудиомоделей общий с Telegram; путь есть в `max personal models audio list --json` (`directory`).
284
+ Каталог аудиомоделей общий с Telegram; путь каждой модели есть в `max personal models audio list --json` (`path`).
284
285
  Существующие файлы используются повторно; `WIRECAT_STATE_DIR` задаёт другое место.
285
286
 
286
287
  Вложение в JSON: `{ "kind": "photo", "url": "https://…", "width": 901, "height": 594 }`. Чтобы
@@ -298,13 +299,13 @@ max personal messages transcribe -1000 100000000000000001 --json # текст
298
299
  где человек писал и его личный чат с ботом; `bot messages between <кто> <кто>` — их переписка в
299
300
  чатах, где писал каждый (`--limit` — на чат). Всё это без сети, кроме `contacts show --refresh`.
300
301
  Чужие локальные копии ботов — `--all-bots` или `--bots <профили>` у `search messages`, `contacts show` и
301
- `messages between`, и только если владелец разрешил `readOtherBots`; иначе отказ с кодом `5` — скажите
302
+ `messages between`, и только если владелец разрешил `read_other_bots`; иначе отказ с кодом `5` — скажите
302
303
  владельцу команду из ошибки. `bot watch --jsonl` забирает события у всех других
303
304
  читателей бота — запускайте только по просьбе владельца. Отказ с кодом `7`
304
305
  значит «чата нет в списке получателей бота»: скажите владельцу, какую команду выполнить, и не
305
306
  пишите в обход. Остальные коды бота: `4` — нет токена бота или MAX его не принял, `5` — профиль только
306
307
  для чтения или действие не разрешено `allow`, `6` — чат не найден (название, которого бот не видел, или
307
- человек без `user:`), `8` — исчерпан `sendsPerHour`, `14` — неизвестно, выполнена ли запись. С `--json`
308
+ человек без `user:`), `8` — исчерпан `sends_per_hour`, `14` — неизвестно, выполнена ли запись. С `--json`
308
309
  stdout — только данные, в той же форме, что у личного аккаунта; id больше 2^53 приходит строкой.
309
310
  Все методы официальной схемы Bot API доступны, включая операции вне удобных команд:
310
311
  `max <имя> bot api <операция>`; её флаги —
@@ -333,7 +334,7 @@ MAX-боту; личный протокол явно отказывает неп
333
334
  из раздела установки. Убедись, что установленная команда доступна по имени.
334
335
 
335
336
  Для количества совпадений в архиве используй `max personal stats messages show [запрос] --by chat|sender|day|hour --json`: одна
336
- запись считается один раз. Проверяй completeness: неполный архив даёт нижнюю границу. `--source max` явно включает
337
+ запись считается один раз. Проверяй `missing`: неполный архив даёт нижнюю границу. Отчёт — один `{item}`, `--jsonl` он не принимает. `--source max` явно включает
337
338
  другие сохранённые профили; обычный вызов остаётся в текущей учётной записи.
338
339
 
339
340
  MCP `max_read` с `command: "stats chats show"` читает активность из архива без запроса вступлений и выходов.
@@ -383,7 +384,7 @@ PDF с текстовым слоем — unpdf. Фото и сканы чита
383
384
  вложениях укажите `--attachment`, начиная с 1.
384
385
 
385
386
  По умолчанию выполняйте OCR сами средствами чтения файлов и зрения агента. После загрузки и локального
386
- извлечения обработайте строки `needs-agent`: найдите `localPath` через `attachments list --needs-text`,
387
+ извлечения обработайте строки `needs-agent`: найдите `local_path` через `attachments list is:needs_text`,
387
388
  прочитайте фото или скан, затем сохраните буквальную расшифровку через `attachments text set`.
388
389
  Сохраняйте locator сообщения и номер вложения; проверьте результат запросом `content:`.
389
390
  Не заменяйте этот путь автоматическим вызовом отдельного API. Массовую обработку через API выбирает
@@ -400,7 +401,7 @@ PDF с текстовым слоем — unpdf. Фото и сканы чита
400
401
  ```sh
401
402
  max personal attachments extract --chat "Книжный клуб" --download --output-dir ./files
402
403
  max personal search messages 'content:договор'
403
- max personal attachments list --chat "Книжный клуб" --needs-text
404
+ max personal attachments list 'chat:"Книжный клуб" is:needs_text'
404
405
  max personal attachments text set "Книжный клуб" 204 --text-file ./scan.txt
405
406
  ```
406
407
 
@@ -424,7 +425,7 @@ output_dir в MCP также их защищает. Обычные скрыты
424
425
  Локальная речь: полная mono/stereo Ogg Opus запись без 10-минутного предела; длинные записи требуют больше памяти.
425
426
  Подготовка после явно разрешённой загрузки: `messages sync <чат> --catch-up` с
426
427
  `--catch-up-chunks`, `--catch-up-messages`, `--catch-up-time`; `--no-catch-up` отменяет
427
- настройку `searchCatchUp`. Модели не скачиваются, удалённый провайдер не вызывается.
428
+ настройку `search_catch_up`. Модели не скачиваются, удалённый провайдер не вызывается.
428
429
  Разрывы: сначала локальный `store gaps plan <чат>`, затем только по слову владельца
429
430
  `store gaps repair <чат> --fingerprint <хеш>`; ограничивайте `--max-gaps`, `--limit`,
430
431
  `--repair-time`, `--page-size`, `--pause`. `--background` использует обычные задания.
@@ -456,12 +457,12 @@ max personal contacts notes show 101 NOTE_ID --json
456
457
  max personal contacts notes edit 101 NOTE_ID --revision 1 --file /path/to/own-note.md
457
458
  max personal contacts notes remove 101 NOTE_ID
458
459
  max personal contacts show 101 --with-notes --json
459
- max personal contacts list --search-notes 'follow up' --json
460
+ max personal contacts list 'notes:"follow up"' --json
460
461
  max personal metadata get --chat CHAT_ID --json
461
462
  max personal metadata refresh --chat CHAT_ID --limit 1 --json
462
463
  max personal tags auto --chat CHAT_ID --dry-run --json
463
464
  max personal tags auto --chat CHAT_ID --refresh-metadata --limit 1 --json
464
- max personal tags list --source auto --json
465
+ max personal tags list sources:auto --json
465
466
  max personal tags remove news --chat CHAT_ID --source auto
466
467
  ```
467
468
 
@@ -473,16 +474,35 @@ max personal tags remove news --chat CHAT_ID --source auto
473
474
  Без `--source` удаление метки убирает оба источника; следующий явный запуск `tags auto` может
474
475
  создать автоматическую метку снова. Связывание людей не объединяет их личные заметки.
475
476
 
477
+ Телефоны, почта, ссылки и документы Google из сохранённых сообщений хранятся как упоминания: их находят
478
+ правила при каждой записи в базу. `mentions list` принимает запрос: `kind:phone|email|url|document`,
479
+ `status:found|linked|dismissed`, `domain:` (сайт ссылки или адреса; `docs.google.com` значит `google.com`)
480
+ и `value:`; слово без поля — значение в любой записи, `89001234567` найдёт `+79001234567`. Сообщения,
481
+ сохранённые до появления упоминаний, читает один `mentions rebuild`. У каждой строки есть `locator`
482
+ сообщения; текст упоминаний — только владельцу, не в логи и не в файлы. Поиск сообщений понимает `phone:`, `email:`,
483
+ `url:` и `domain:` (почта в кавычках: `email:"ana@example.com"`). `mentions confirm <id> [person:<uid>|organization:<id>]`
484
+ записывает, чьё значение, `mentions reject <id>` отклоняет его насовсем; автор записи — агент или владелец
485
+ (`--as-owner`).
486
+
487
+ ```sh
488
+ max personal mentions list kind:phone --json
489
+ max personal mentions list domain:google.com kind:url --json
490
+ max personal mentions show 12 --json
491
+ max personal mentions rebuild
492
+ max personal mentions confirm 12 person:<uid>
493
+ max personal mentions reject 12
494
+ ```
495
+
476
496
  Рейтинги архива: `max personal stats messages top` / `max personal stats contacts top` — метрика `--measure` или
477
497
  `--score helpful|active|engaging`; оценки используют всю допустимую выборку до limit.
478
- Читай coverage/quality и исключения: неизвестные счётчики не равны нулю, свежесть наблюдений показана по полям; старые значения остаются unknown. Используй drilldown.selection для `stats messages evidence` / `stats contacts evidence`,
479
- продолжай через nextCursor; при изменении данных начни без cursor.
498
+ Читай coverage/quality и исключения: неизвестные счётчики не равны нулю, свежесть наблюдений показана по полям; старые значения остаются unknown. Используй `selection` строки и шаг `stats.evidence` из `next` для `stats messages evidence` / `stats contacts evidence`,
499
+ продолжай по `cursor` шага `page.next`; при изменении данных начни без cursor.
480
500
  Руководство: [рейтинги](https://github.com/WireCatLabs/max-cli/blob/main/docs/rankings.md).
481
501
 
482
502
  Для вопросов без наблюдаемого ответа используй `stats messages unanswered`; время ответа явно
483
503
  выбранных людей — `stats contacts responses --answerer <person>`. Помощь новичкам с известной датой
484
504
  вступления — `stats chats newcomers <chat>`, посты каналов с просмотрами и малым обсуждением —
485
- `stats messages discussion`. Проверяй качество архива и reply-графа, копируй точные drilldown-аргументы
505
+ `stats messages discussion`. Проверяй качество архива и reply-графа, копируй точную `selection` строки
486
506
  с `--component report`. Неизвестные история и дата вступления не равны нулю. Отчёты читают только
487
507
  сохранённые данные; не выводи из выбранных id, кто был админом в прошлом.
488
508
 
@@ -494,22 +514,22 @@ max personal tags remove news --chat CHAT_ID --source auto
494
514
 
495
515
 
496
516
  Удалённому агенту доступны байты сохранённого файла: найдите attachments show через max_tools_search
497
- и вызовите max_read. Скрытые файлы, папки CLI и хранилище не передаются, включая ссылки. Соберите порции по nextOffsetBytes, передавайте if_sha256 и проверьте хеш.
498
- Если клиент не может открыть PDF, запросите каждую страницу через page:1..pdf.pageCount;
517
+ и вызовите max_read. Скрытые файлы, папки CLI и хранилище не передаются, включая ссылки. Соберите порции по next_offset_bytes, передавайте if_sha256 и проверьте хеш.
518
+ Если клиент не может открыть PDF, запросите каждую страницу через page:1..pdf.page_count;
499
519
  нужны необязательные unpdf/@napi-rs/canvas. Страница возвращается изображением; если видны только
500
520
  метаданные, запросите format:base64 и покажите PNG средствами агента. Просмотрите реальные пиксели
501
- всех страниц, не считайте получение base64 чтением. pdf.sourceSha256 — хеш исходного PDF,
521
+ всех страниц, не считайте получение base64 чтением. pdf.source_sha256 — хеш исходного PDF,
502
522
  верхний sha256 — хеш PNG. Нет внешнего OCR API или автоматической записи: сохраните свой буквальный
503
523
  текст через attachments text set и проверьте content:. Если показать страницы нельзя, сообщите об этом;
504
524
  не подставляйте прежний текст индекса. Качество зависит от разрешения, языка и структуры документа.
505
525
 
506
526
  Удержание: `max personal stats chats retention <chat> --checkpoints 1d,7d,30d --within 7d --json`.
507
- Используй только известные joinedAt; partial absence и пропущенные снимки — unknown, будущие окна — pending.
527
+ Используй только известные joined_at; partial absence и пропущенные снимки — unknown, будущие окна — pending.
508
528
  Показывай observable знаменатель, неизвестные и фактическую дату снимка; не называй это непрерывным участием.
509
- Cohort drilldown идёт через `stats messages evidence --component report` с точной selection.
529
+ Сообщения когорты — через `stats messages evidence --component report` с точной `selection` строки.
510
530
 
511
531
  Счётчики: `max personal stats messages counters show --chat <chat> --counters views,reactions --json`.
512
- Проверяй observedAt/source/freshness каждого поля (24h по умолчанию). Refresh — remote read + local write:
532
+ Проверяй observed_at/source/freshness каждого поля (24h по умолчанию). Refresh — remote read + local write:
513
533
  `stats messages counters refresh --chat <chat> --max-messages 20 --sync-time 30s --dry-run --json`.
514
534
  Предпросмотр не подключается. Реальный refresh требует разрешённой записи и явного chat или pinned selection;
515
535
  никогда не освежай весь аккаунт неявно. MAX поддерживает views/reactions; comments unsupported.
@@ -526,5 +546,5 @@ Cohort drilldown идёт через `stats messages evidence --component report
526
546
 
527
547
  Статистический `--answerer` также принимает сохранённое имя, своё имя и @username напрямую,
528
548
  без подключения. При неоднозначности используйте возвращённые кандидаты нужного аккаунта,
529
- не угадывайте. `identityKnown: false` вместе с `status: unknown` означает, что явно выбранный
549
+ не угадывайте. `identity_known: false` вместе с `status: unknown` означает, что явно выбранный
530
550
  ID не наблюдался; ноль ответов не доказывает нулевую активность.