@wirecat/max-cli 0.47.0 → 0.49.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 (123) hide show
  1. package/README.md +51 -49
  2. package/dist/adapter/max-adapter.js +1 -1
  3. package/dist/bin/max.js +4 -0
  4. package/dist/bin/max.js.map +1 -1
  5. package/dist/bot/adapter.d.ts +2 -2
  6. package/dist/bot/adapter.js +1 -1
  7. package/dist/bot/auth.d.ts +1 -1
  8. package/dist/bot/client.d.ts +1 -1
  9. package/dist/bot/client.js +1 -1
  10. package/dist/bot/generated/manifest.d.ts +1 -1
  11. package/dist/bot/generated/schemas.js +1 -1
  12. package/dist/bot/input.d.ts +1 -1
  13. package/dist/bot/joins.js +1 -1
  14. package/dist/bot/keep.js +1 -1
  15. package/dist/bot/transport.d.ts +3 -3
  16. package/dist/bot/transport.js +2 -2
  17. package/dist/bot/uploads.d.ts +2 -2
  18. package/dist/bot/uploads.js +2 -2
  19. package/dist/client.d.ts +1 -1
  20. package/dist/client.js +6 -6
  21. package/dist/client.js.map +1 -1
  22. package/dist/commands/bot-comments.js +2 -2
  23. package/dist/commands/bot-context.d.ts +5 -5
  24. package/dist/commands/bot-context.js +1 -1
  25. package/dist/commands/bot-members.js +2 -2
  26. package/dist/commands/bot-reads.js +1 -1
  27. package/dist/commands/bot-sends.d.ts +1 -1
  28. package/dist/commands/bot-sends.d.ts.map +1 -1
  29. package/dist/commands/bot-sends.js +6 -2
  30. package/dist/commands/bot-sends.js.map +1 -1
  31. package/dist/commands/bot-setup.js +1 -1
  32. package/dist/commands/complete.js +1 -1
  33. package/dist/commands/config.d.ts.map +1 -1
  34. package/dist/commands/config.js +10 -8
  35. package/dist/commands/config.js.map +1 -1
  36. package/dist/commands/contacts.js +1 -1
  37. package/dist/commands/context.d.ts +5 -5
  38. package/dist/commands/context.d.ts.map +1 -1
  39. package/dist/commands/context.js +3 -3
  40. package/dist/commands/context.js.map +1 -1
  41. package/dist/commands/doctor.js +2 -2
  42. package/dist/commands/doctor.js.map +1 -1
  43. package/dist/commands/mcp.js +6 -6
  44. package/dist/commands/mcp.js.map +1 -1
  45. package/dist/commands/messages.d.ts.map +1 -1
  46. package/dist/commands/messages.js +2 -1
  47. package/dist/commands/messages.js.map +1 -1
  48. package/dist/commands/paging.d.ts +1 -1
  49. package/dist/commands/paging.js +1 -1
  50. package/dist/commands/recipients.js +2 -2
  51. package/dist/commands/serve-members.js +1 -1
  52. package/dist/commands/serve.js +1 -1
  53. package/dist/commands/server.js +1 -1
  54. package/dist/commands/session.js +9 -9
  55. package/dist/commands/session.js.map +1 -1
  56. package/dist/commands/setup.d.ts.map +1 -1
  57. package/dist/commands/setup.js +13 -12
  58. package/dist/commands/setup.js.map +1 -1
  59. package/dist/commands/skill.js +1 -1
  60. package/dist/commands/skill.js.map +1 -1
  61. package/dist/commands/watch.js +1 -1
  62. package/dist/config.d.ts +6 -2
  63. package/dist/config.d.ts.map +1 -1
  64. package/dist/config.js +5 -2
  65. package/dist/config.js.map +1 -1
  66. package/dist/diagnose.js +3 -3
  67. package/dist/domain/map.js +1 -1
  68. package/dist/download.js +1 -1
  69. package/dist/format-markdown.js +1 -1
  70. package/dist/inbox-point.js +1 -1
  71. package/dist/install/postinstall.d.ts.map +1 -1
  72. package/dist/install/postinstall.js +2 -2
  73. package/dist/install/postinstall.js.map +1 -1
  74. package/dist/install.d.ts +1 -1
  75. package/dist/install.js +1 -1
  76. package/dist/mcp/photo.js +1 -1
  77. package/dist/mcp/resources.js +1 -1
  78. package/dist/mcp/server.js +1 -1
  79. package/dist/mcp/session.js +1 -1
  80. package/dist/mcp/shared.js +1 -1
  81. package/dist/mcp/tools.js +1 -1
  82. package/dist/messenger.d.ts.map +1 -1
  83. package/dist/messenger.js +1 -0
  84. package/dist/messenger.js.map +1 -1
  85. package/dist/moderation/check.js +1 -1
  86. package/dist/moderation/points.js +1 -1
  87. package/dist/permissions.js +2 -2
  88. package/dist/profile.d.ts +3 -3
  89. package/dist/profile.d.ts.map +1 -1
  90. package/dist/profile.js +5 -5
  91. package/dist/profile.js.map +1 -1
  92. package/dist/program.d.ts.map +1 -1
  93. package/dist/program.js +13 -7
  94. package/dist/program.js.map +1 -1
  95. package/dist/rendering/messages.js +1 -1
  96. package/dist/report.js +1 -1
  97. package/dist/sends.js +2 -2
  98. package/dist/sends.js.map +1 -1
  99. package/dist/server/replies.js +1 -1
  100. package/dist/server/server-connection.js +1 -1
  101. package/dist/server/server.js +1 -1
  102. package/dist/server/subscribe.js +1 -1
  103. package/dist/session/adopt.d.ts +1 -1
  104. package/dist/session/adopt.js +1 -1
  105. package/dist/session/browser.js +1 -1
  106. package/dist/session/login.js +1 -1
  107. package/dist/session/store.d.ts +1 -1
  108. package/dist/session/store.js +1 -1
  109. package/dist/skill.d.ts +2 -2
  110. package/dist/skill.js +1 -1
  111. package/dist/spec/define.js +1 -1
  112. package/dist/spec/guards.js +1 -1
  113. package/dist/transcribe/index.d.ts +1 -1
  114. package/dist/transcribe/index.js +1 -1
  115. package/dist/update.d.ts +2 -2
  116. package/dist/update.js +6 -6
  117. package/dist/update.js.map +1 -1
  118. package/dist/upload.js +1 -1
  119. package/dist/version.d.ts +1 -1
  120. package/dist/version.js +1 -1
  121. package/dist/voice.js +1 -1
  122. package/package.json +10 -9
  123. package/skills/max-cli/SKILL.md +99 -95
package/README.md CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
  ```text
26
26
  Вы: Что я кому обещал за последние три дня?
27
- Агент: (вызывает max review: 12 чатов, 3 голосовых расшифровано)
27
+ Агент: (вызывает max personal review: 12 чатов, 3 голосовых расшифровано)
28
28
  Я должен
29
29
  · Алисе Пример — прислать счёт до пятницы. Личный чат, 24.09
30
30
  Жду от других
@@ -40,13 +40,13 @@
40
40
 
41
41
  ```sh
42
42
  npm install -g @wirecat/max-cli
43
- max setup --agent claude # вход по QR-коду и навык для Claude Code
44
- max inbox # непрочитанное во всех чатах, ничего не отмечая
43
+ max personal setup --agent claude # вход по QR-коду и навык для Claude Code
44
+ max personal inbox # непрочитанное во всех чатах, ничего не отмечая
45
45
  ```
46
46
 
47
- `max setup` за пять минут проводит через вход: вы сканируете QR-код в приложении MAX, и `max`
47
+ `max personal setup` за пять минут проводит через вход: вы сканируете QR-код в приложении MAX, и `max`
48
48
  становится ещё одним вашим устройством. Вместо `claude` можно указать `codex`, `cursor`, `gemini`,
49
- `all` или `none`; войти можно и по SMS через web.max.ru — `max setup --help`.
49
+ `all` или `none`; войти можно и по SMS через web.max.ru — `max personal setup --help`.
50
50
 
51
51
  Нужен Node 22.16+ (ветка 22.x) или 24+, либо Bun 1.3+; работает в Windows, macOS и Linux.
52
52
  Попробовать без установки — `npx @wirecat/max-cli --help`. Если `max` не находится,
@@ -59,21 +59,21 @@ max inbox # непрочитанное во всех чатах
59
59
  **Разобрать, что пришло.** «Используй max CLI: кто ждёт моего ответа и что срочно?»
60
60
 
61
61
  ```sh
62
- max inbox
62
+ max personal inbox
63
63
  ```
64
64
 
65
65
  **Найти что угодно.** «Когда мы договорились о встрече с Алисой?» — ответ с датой и самим
66
66
  сообщением, по локальной копии и без запросов к MAX.
67
67
 
68
68
  ```sh
69
- max search all "встреча Алиса"
69
+ max personal search all "встреча Алиса"
70
70
  ```
71
71
 
72
72
  **Понять, кто кому что должен.** «Что я обещал и чего жду от других?» — вся переписка с прошлого
73
73
  обзора, ваши сообщения и голосовые текстом.
74
74
 
75
75
  ```sh
76
- max review --since-time 3d --transcribe
76
+ max personal review --since-time 3d --transcribe
77
77
  ```
78
78
 
79
79
  Ещё: сводки утром и вечером, итог недели по рабочему чату, кому вы обещали ответить, черновики
@@ -86,15 +86,15 @@ max review --since-time 3d --transcribe
86
86
  Ваш агент. Ваш MAX. Ваши правила.
87
87
 
88
88
  - **Агент с терминалом** — Claude Code, Codex, Cursor, Gemini CLI. Он сам вызывает `max`, а навык
89
- (skill) — инструкция для агента — объясняет ему команды и ограничения. `max setup` ставит навык
89
+ (skill) — инструкция для агента — объясняет ему команды и ограничения. `max personal setup` ставит навык
90
90
  сам; отдельно — `max skill install`.
91
91
  - **Приложение без терминала** — Claude Desktop, Cursor и другие клиенты MCP. Подключите
92
- MCP-сервер `max mcp`; готовые просьбы `/catch-up`, `/review`, `/reply` и `/find` уже внутри.
92
+ MCP-сервер `max personal mcp`; готовые просьбы `/catch-up`, `/review`, `/reply` и `/find` уже внутри.
93
93
  - **ChatGPT или Claude в браузере** — через HTTPS-туннель и вход по коду.
94
94
 
95
95
  ```sh
96
- max mcp setup claude-code # или codex
97
- max mcp config # запись для Claude Desktop, Cursor и других
96
+ max personal mcp setup claude-code # или codex
97
+ max personal mcp config # запись для Claude Desktop, Cursor и других
98
98
  ```
99
99
 
100
100
  С `--json` каждая команда отдаёт только данные, а ошибка приходит отдельно, с постоянным кодом
@@ -143,8 +143,8 @@ max mcp config # запись для Claude Desktop, Cursor и др
143
143
  > аккаунтов, потерю данных или другие последствия. Бот работает через официальный API, и к нему
144
144
  > это не относится.
145
145
 
146
- - **Читать.** Чаты, история, сообщение вместе с соседними, непрочитанное во всех чатах (`max inbox`),
147
- разбор «кто кому должен» (`max review`), новые сообщения по мере прихода (`max watch`), вложения,
146
+ - **Читать.** Чаты, история, сообщение вместе с соседними, непрочитанное во всех чатах (`max personal inbox`),
147
+ разбор «кто кому должен» (`max personal review`), новые сообщения по мере прихода (`max personal watch`), вложения,
148
148
  голосовые — текстом на вашем компьютере.
149
149
  - **Писать.** Текст и разметка, ответы, фото, видео, файлы и голосовые, правка, пересылка,
150
150
  закрепление, реакции, опросы, отложенная отправка, удаление — у себя или у всех.
@@ -153,19 +153,19 @@ max mcp config # запись для Claude Desktop, Cursor и др
153
153
  людях; профиль и фото; другие сеансы.
154
154
 
155
155
  ```sh
156
- max inbox # непрочитанное, ничего не отмечая
157
- max messages list "Алиса Пример" --limit 20
158
- max messages send "Алиса Пример" "Созвонимся в 15:00?" --reply-to <id>
159
- max reactions add "Алиса Пример" <id> 👍
160
- max messages send 0 "Позвонить Борису" --at-time 2h # напоминание себе в «Избранное»
161
- max chats mark-read "Алиса Пример" # отметить прочитанным, когда нужно
156
+ max personal inbox # непрочитанное, ничего не отмечая
157
+ max personal messages list "Алиса Пример" --limit 20
158
+ max personal messages send "Алиса Пример" "Созвонимся в 15:00?" --reply-to <id>
159
+ max personal reactions add "Алиса Пример" <id> 👍
160
+ max personal messages send 0 "Позвонить Борису" --at-time 2h # напоминание себе в «Избранное»
161
+ max personal chats mark-read "Алиса Пример" # отметить прочитанным, когда нужно
162
162
  ```
163
163
 
164
164
  Подробнее: [личный аккаунт](https://github.com/WireCatLabs/max-cli/blob/main/docs/usage.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/usage)), [один человек](https://github.com/WireCatLabs/max-cli/blob/main/docs/people.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/people)), [ответы](https://github.com/WireCatLabs/max-cli/blob/main/docs/replies.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/replies)).
165
165
 
166
166
  ## Бот
167
167
 
168
- `max bot` работает через **официальный** [Bot API MAX](https://dev.max.ru/docs-api) по токену бота.
168
+ `max sales bot` работает через **официальный** [Bot API MAX](https://dev.max.ru/docs-api) по токену бота.
169
169
  Ботов может быть несколько: каждый хранится под именем, которое вы выбираете, и это имя — первое
170
170
  слово команды. Бота создают на [business.max.ru](https://business.max.ru/self); MAX выдаёт их
171
171
  подтверждённым организациям, ИП и самозанятым.
@@ -178,7 +178,7 @@ max sales bot messages pin "Команда продаж" <mid> # id со
178
178
  max sales bot watch --events # всё, что происходит в чатах бота
179
179
  max sales bot chats moderate "Команда продаж" --dry-run # что нарушает правила — без действий
180
180
  max sales bot api get-updates --limit 10 # любой метод Bot API
181
- max bot list --check # все боты на этом компьютере
181
+ max sales bot list --check # все боты на этом компьютере
182
182
  ```
183
183
 
184
184
  - **Полный Bot API.** Каждый метод официальной схемы — `max <бот> bot api <операция>`: параметры —
@@ -196,11 +196,11 @@ max bot list --check # все боты на
196
196
  ## Группы, которые вы ведёте
197
197
 
198
198
  ```sh
199
- max review --chat "Поход" --unanswered # вопросы, на которые сутки никто не ответил
200
- max chats events "Поход" # кто вступил и вышел
201
- max chats members list "Поход" --all # все участники: когда заведён аккаунт
202
- max chats rules set "Поход" invites delete # приглашения в чужие чаты — удалять
203
- max chats moderate "Поход" --dry-run # что нарушает правила — без действий
199
+ max personal review --chat "Поход" --unanswered # вопросы, на которые сутки никто не ответил
200
+ max personal chats events "Поход" # кто вступил и вышел
201
+ max personal chats members list "Поход" --all # все участники: когда заведён аккаунт
202
+ max personal chats rules set "Поход" invites delete # приглашения в чужие чаты — удалять
203
+ max personal chats moderate "Поход" --dry-run # что нарушает правила — без действий
204
204
  ```
205
205
 
206
206
  Проверка сверяет новое в группе с вашими правилами: заблокированные люди, приглашения, ссылки,
@@ -216,11 +216,11 @@ max chats moderate "Поход" --dry-run # что нарушает
216
216
  историю чата можно скачать глубже и выгрузить.
217
217
 
218
218
  ```sh
219
- max search all "договор" # сообщения, почта и заметки сразу
220
- max search messages "договор" --chat "Проект Альфа" # только один чат
221
- max store fetch "Проект Альфа" --last 500 # последние 500 сообщений — в копию
222
- max store export "Проект Альфа" --format markdown --output alfa.md
223
- max chats list --offline # без подключения к MAX
219
+ max personal search all "договор" # сообщения, почта и заметки сразу
220
+ max personal search messages "договор" --chat "Проект Альфа" # только один чат
221
+ max personal messages sync "Проект Альфа" --last 500 # последние 500 сообщений — в копию
222
+ max personal store export "Проект Альфа" --format markdown --output alfa.md
223
+ max personal chats list --offline # без подключения к MAX
224
224
  ```
225
225
 
226
226
  Поиск понимает слова, людей, даты, файлы, ссылки и ваши метки; есть поиск по темам и сохранённые
@@ -244,9 +244,9 @@ max skill install --for all # или --for claude, --for agents
244
244
  доступен ресурсом `max://skill`.
245
245
 
246
246
  ```sh
247
- max mcp doctor # проверить локальный MCP
248
- max mcp --http --public-url https://<имя>.ts.net # для ChatGPT и Claude в браузере
249
- max mcp --permission messages.send=ask # временно изменить право
247
+ max personal mcp doctor # проверить локальный MCP
248
+ max personal mcp --http --public-url https://<имя>.ts.net # для ChatGPT и Claude в браузере
249
+ max personal mcp --permission messages.send=ask # временно изменить право
250
250
  ```
251
251
 
252
252
  Подробнее: [MCP-сервер](https://github.com/WireCatLabs/max-cli/blob/main/docs/mcp.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/mcp)), [браузер](https://github.com/WireCatLabs/max-cli/blob/main/docs/remote.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/remote)), [внешние модели](https://github.com/WireCatLabs/max-cli/blob/main/docs/external-models.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/external-models)).
@@ -270,15 +270,17 @@ max mcp --permission messages.send=ask # временно изме
270
270
  ## Вход и профили
271
271
 
272
272
  ```sh
273
- max setup --agent codex # QR-код в терминале и навык Codex
274
- max setup --method qr-chrome # QR через web.max.ru в браузере
275
- max setup --method sms # номер телефона — в браузере
276
- max setup --method token # готовый токен, скрытым вводом или через stdin
277
- max session start qr # повторный вход, когда сессия истекла
273
+ max personal setup --agent codex # QR-код в терминале и навык Codex
274
+ max personal setup --method qr-chrome # QR через web.max.ru в браузере
275
+ max personal setup --method sms # номер телефона — в браузере
276
+ max personal setup --method token # готовый токен, скрытым вводом или через stdin
277
+ max personal session start qr # повторный вход, когда сессия истекла
278
278
  ```
279
279
 
280
- Несколько аккаунтов — несколько профилей; профиль называется **первым словом**:
281
- `max personal chats list`, или `export MAX_PROFILE=personal` на всю сессию оболочки.
280
+ Профиль называется **первым словом** в каждой команде — `max personal chats list`, — или
281
+ `export MAX_PROFILE=personal` на всю сессию оболочки, или `max config set defaultProfile personal`
282
+ насовсем. `max` никогда не выбирает профиль сам, даже единственный: без имени команда останавливается
283
+ и перечисляет профили этого компьютера. Имя `personal` — пример: любое подойдёт.
282
284
 
283
285
  Подробнее: [вход и сессии](https://github.com/WireCatLabs/max-cli/blob/main/docs/sessions.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/sessions)), [профили](https://github.com/WireCatLabs/max-cli/blob/main/docs/profiles.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/profiles)).
284
286
 
@@ -295,8 +297,8 @@ max session start qr # повторный вход, когда сесс
295
297
  | `limit` | сколько строк в списке | `20` |
296
298
 
297
299
  ```sh
298
- max config set permissions.messages readonly # профиль только для чтения
299
- max config set permissions.messages.send ask # спрашивать перед отправкой
300
+ max personal config set permissions.messages readonly # профиль только для чтения
301
+ max personal config set permissions.messages.send ask # спрашивать перед отправкой
300
302
  ```
301
303
 
302
304
  Подробнее: [настройки](https://github.com/WireCatLabs/max-cli/blob/main/docs/configuration.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/configuration)), [права](https://github.com/WireCatLabs/max-cli/blob/main/docs/permissions.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/permissions)), [все ключи](https://github.com/WireCatLabs/max-cli/blob/main/docs/configuration-reference.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/configuration-reference)).
@@ -305,7 +307,7 @@ max config set permissions.messages.send ask # спрашивать перед
305
307
 
306
308
  `max` держит каждый профиль в одном темпе: первые 10 запросов идут сразу, дальше — 20 в минуту, и
307
309
  две команды одновременно делят этот темп. Если MAX отвечает «слишком много запросов», `max`
308
- останавливается и не повторяет запрос сам. Фоновый `max serve` держит одно подключение для всех
310
+ останавливается и не повторяет запрос сам. Фоновый `max personal serve` держит одно подключение для всех
309
311
  команд и сам останавливается, когда им 15 минут никто не пользуется.
310
312
 
311
313
  Подробнее: [ограничения и ожидания](https://github.com/WireCatLabs/max-cli/blob/main/docs/limits.md) ([wirecat.dev](https://wirecat.dev/ru/docs/max/limits)).
@@ -328,9 +330,9 @@ max config set permissions.messages.send ask # спрашивать перед
328
330
  ## Когда не работает
329
331
 
330
332
  ```sh
331
- max doctor # где лежат файлы и есть ли вход; к MAX не подключается
332
- max chats list --trace # каждый запрос к MAX — без текстов, имён и токена
333
- max runs list # неудачные и частичные запуски сохраняются сами
333
+ max personal doctor # где лежат файлы и есть ли вход; к MAX не подключается
334
+ max personal chats list --trace # каждый запрос к MAX — без текстов, имён и токена
335
+ max personal runs list # неудачные и частичные запуски сохраняются сами
334
336
  ```
335
337
 
336
338
  Запись `--trace` можно приложить к сообщению об ошибке.
@@ -366,7 +368,7 @@ pnpm generate # переписать сгенериро
366
368
  Протокол MAX неофициальный и разобран обратной инженерией. Каждый опкод объявлен один раз в
367
369
  `src/spec/`, а реестр, типизированный клиент и `docs/dev/protocol.md` из него генерируются; CI
368
370
  падает, если дерево устарело. Общая часть — потоки вывода, коды ошибок, хранилище паролей — в
369
- [`@wirecat/cli-core`](https://github.com/WireCatLabs/cli-base).
371
+ [`@wirecat/cli-base`](https://github.com/WireCatLabs/cli-base).
370
372
 
371
373
  ## Часть WireCat
372
374
 
@@ -1,4 +1,4 @@
1
- import { CliError, singleLine } from "@wirecat/cli-core";
1
+ import { CliError, singleLine } from "@wirecat/cli-base";
2
2
  import { observedCounters } from "@wirecat/cli-messaging";
3
3
  import { httpOnly, LARGEST_VOICE, streamBytes } from "../download.js";
4
4
  import { formatMarkdown, toNativeMarkup } from "../format-markdown.js";
package/dist/bin/max.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { catchCrashes } from "@wirecat/cli-base";
2
3
  import { migrateFolders } from "@wirecat/cli-messaging/background";
3
4
  import { ensureSqlite } from "@wirecat/cli-messaging/sqlite-runtime";
4
5
  import { MAX_APP } from "../app.js";
@@ -16,8 +17,11 @@ for (const stream of [process.stdout, process.stderr]) {
16
17
  });
17
18
  }
18
19
  // Before anything resolves a path: a write into a new folder first would strand the old one.
20
+ // The move stops with an error when two different stores exist; it reaches the person as the error object.
21
+ const stopCatching = catchCrashes({ cli: MAX_APP.command, interactive: process.stdout.isTTY === true });
19
22
  migrateFolders(MAX_APP);
20
23
  await ensureSqlite();
24
+ stopCatching();
21
25
  // A static import would load the whole program, and its SQLite, before ensureSqlite could swap it.
22
26
  const { run } = await import("../program.js");
23
27
  process.exitCode = await run(process.argv.slice(2));
@@ -1 +1 @@
1
- {"version":3,"file":"max.js","sourceRoot":"","sources":["../../src/bin/max.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,+FAA+F;AAC/F,gGAAgG;AAChG,iFAAiF;AACjF,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACxD,OAAM;QACR,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,6FAA6F;AAC7F,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,MAAM,YAAY,EAAE,CAAA;AACpB,mGAAmG;AACnG,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;AAC7C,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"max.js","sourceRoot":"","sources":["../../src/bin/max.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,+FAA+F;AAC/F,gGAAgG;AAChG,iFAAiF;AACjF,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACxD,OAAM;QACR,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,6FAA6F;AAC7F,2GAA2G;AAC3G,MAAM,YAAY,GAAG,YAAY,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAA;AACvG,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,MAAM,YAAY,EAAE,CAAA;AACpB,YAAY,EAAE,CAAA;AACd,mGAAmG;AACnG,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;AAC7C,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA"}
@@ -1,5 +1,5 @@
1
- import { type SleepLike } from "@wirecat/cli-core";
2
- import type { FetchLike } from "@wirecat/cli-core/http";
1
+ import { type SleepLike } from "@wirecat/cli-base";
2
+ import type { FetchLike } from "@wirecat/cli-base/http";
3
3
  import type { AdminRight, Markup } from "@wirecat/cli-messaging";
4
4
  import type { BotAdapter, EventSink } from "@wirecat/cli-messaging/cli";
5
5
  import { type BotApiClient } from "./client.js";
@@ -1,4 +1,4 @@
1
- import { CliError } from "@wirecat/cli-core";
1
+ import { CliError } from "@wirecat/cli-base";
2
2
  import { formatMarkdown, toHtml } from "../format-markdown.js";
3
3
  import { botOperations } from "./client.js";
4
4
  import { checkBody } from "./input.js";
@@ -1,4 +1,4 @@
1
- import type { KeyringStore } from "@wirecat/cli-core";
1
+ import type { KeyringStore } from "@wirecat/cli-base";
2
2
  import { BotTokenStore as SharedBotTokenStore } from "@wirecat/cli-messaging/cli";
3
3
  export interface BotTokenStoreOptions {
4
4
  profile: string;
@@ -1,4 +1,4 @@
1
- import type { ManifestOperation } from "@wirecat/cli-core/codegen";
1
+ import type { ManifestOperation } from "@wirecat/cli-base/codegen";
2
2
  import type { Chat, Message } from "@wirecat/cli-messaging";
3
3
  import type { PersonFacts } from "@wirecat/cli-messaging/store";
4
4
  import type { BotInfo as BotInfoType } from "./generated/types.js";
@@ -1,4 +1,4 @@
1
- import { CliError } from "@wirecat/cli-core";
1
+ import { CliError } from "@wirecat/cli-base";
2
2
  import * as v from "valibot";
3
3
  import { operations } from "./generated/manifest.js";
4
4
  import { BotInfo, Chat as ChatSchema, Message as MessageSchema } from "./generated/schemas.js";
@@ -1,3 +1,3 @@
1
- import type { ManifestOperation } from "@wirecat/cli-core/codegen";
1
+ import type { ManifestOperation } from "@wirecat/cli-base/codegen";
2
2
  export declare const operations: readonly ManifestOperation[];
3
3
  //# sourceMappingURL=manifest.d.ts.map
@@ -1,7 +1,7 @@
1
1
  // GENERATED. DO NOT EDIT.
2
2
  // Source: spec/bot/schema.yaml
3
3
  // Run: pnpm bot:generate
4
- import { int64, integer, number, unique } from "@wirecat/cli-core/codegen/runtime";
4
+ import { int64, integer, number, unique } from "@wirecat/cli-base/codegen/runtime";
5
5
  import * as v from "valibot";
6
6
  export const Bigint = int64();
7
7
  export const UserId = int64();
@@ -1,4 +1,4 @@
1
- import type { ManifestOperation, SchemaNode } from "@wirecat/cli-core/codegen";
1
+ import type { ManifestOperation, SchemaNode } from "@wirecat/cli-base/codegen";
2
2
  import { apiFlagOf, apiOptionKey, readApiBody } from "@wirecat/cli-messaging/cli";
3
3
  export { apiFlagOf as flagOf, apiOptionKey as optionKey, readApiBody as readBody };
4
4
  export declare const checkParameter: (name: string, node: SchemaNode, raw: string) => string | undefined;
package/dist/bot/joins.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { writeSecurely } from "@wirecat/cli-core";
3
+ import { writeSecurely } from "@wirecat/cli-base";
4
4
  import { botsDirectory } from "./registry.js";
5
5
  /** Past this, a join is too old for any check; the log does not grow for ever. */
6
6
  const KEEP_MS = 30 * 86_400_000;
package/dist/bot/keep.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CliError } from "@wirecat/cli-core";
1
+ import { CliError } from "@wirecat/cli-base";
2
2
  import { openStore, } from "@wirecat/cli-messaging/store";
3
3
  /** How a bot's messages are told apart from a personal account's in the shared store and its locators. */
4
4
  export const PROVIDER = "max-bot";
@@ -1,6 +1,6 @@
1
- import { type RetryConfig, type SleepLike } from "@wirecat/cli-core";
2
- import type { ManifestOperation } from "@wirecat/cli-core/codegen";
3
- import { type FetchLike } from "@wirecat/cli-core/http";
1
+ import { type RetryConfig, type SleepLike } from "@wirecat/cli-base";
2
+ import type { ManifestOperation } from "@wirecat/cli-base/codegen";
3
+ import { type FetchLike } from "@wirecat/cli-base/http";
4
4
  import { type DiagnosticEvent } from "@wirecat/cli-messaging/cli";
5
5
  export declare const BOT_API_URL = "https://platform-api2.max.ru";
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import tls from "node:tls";
2
- import { backoffMs, CliError, DEFAULT_RETRY, realSleep, singleLine, } from "@wirecat/cli-core";
3
- import { providerWaitMs, statusToCode } from "@wirecat/cli-core/http";
2
+ import { backoffMs, CliError, DEFAULT_RETRY, realSleep, singleLine, } from "@wirecat/cli-base";
3
+ import { providerWaitMs, statusToCode } from "@wirecat/cli-base/http";
4
4
  import { providerErrorKey } from "@wirecat/cli-messaging/cli";
5
5
  import { guardedWrite, newOperationId } from "@wirecat/cli-messaging/sends";
6
6
  import { isLosslessNumber, isSafeNumber, parse, stringify } from "lossless-json";
@@ -1,5 +1,5 @@
1
- import { type SleepLike } from "@wirecat/cli-core";
2
- import { type FetchLike } from "@wirecat/cli-core/http";
1
+ import { type SleepLike } from "@wirecat/cli-base";
2
+ import { type FetchLike } from "@wirecat/cli-base/http";
3
3
  import type { DiagnosticEvent } from "@wirecat/cli-messaging/cli";
4
4
  export declare const UPLOAD_TYPES: readonly ["image", "video", "audio", "file"];
5
5
  export type UploadType = (typeof UPLOAD_TYPES)[number];
@@ -1,7 +1,7 @@
1
1
  import { openAsBlob, statSync } from "node:fs";
2
2
  import { basename, extname } from "node:path";
3
- import { CliError, realSleep } from "@wirecat/cli-core";
4
- import { statusToCode } from "@wirecat/cli-core/http";
3
+ import { CliError, realSleep } from "@wirecat/cli-base";
4
+ import { statusToCode } from "@wirecat/cli-base/http";
5
5
  import { parse } from "lossless-json";
6
6
  import { plainJson } from "./transport.js";
7
7
  export const UPLOAD_TYPES = ["image", "video", "audio", "file"];
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type SleepLike } from "@wirecat/cli-core";
1
+ import { type SleepLike } from "@wirecat/cli-base";
2
2
  import { type DiagnosticEvent } from "@wirecat/cli-messaging/cli";
3
3
  import { type ChatAction, type SendGuard, type Upload as SharedUpload } from "@wirecat/cli-messaging/sends";
4
4
  import type { AccountSession, AttachmentLink, Button, CallRecord, Chat, ChatCard, ChatEvents, ChatKind, Contact, ContactImport, Deletion, Folder, GroupCard, GroupMember, GroupMembers, GroupSettings, Id, JoinRequest, MediaKind, Message, MessageChange, MessageHit, Page, PersonCard, Pin, PollMessage, PrivacySettings, Profile, ProfileFacts, Reactions, ReadMark, Sticker, StickerSet, WindowedMessage } from "./domain/models.js";
package/dist/client.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CliError, realSleep } from "@wirecat/cli-core";
1
+ import { CliError, realSleep } from "@wirecat/cli-base";
2
2
  import { pickPerson as pickStoredPerson } from "@wirecat/cli-messaging";
3
3
  import { providerErrorKey } from "@wirecat/cli-messaging/cli";
4
4
  import { currentOperation, } from "@wirecat/cli-messaging/sends";
@@ -181,14 +181,14 @@ export class MaxClient {
181
181
  this.#store.writeToken(token);
182
182
  }
183
183
  catch (error) {
184
- throw new CliError("configuration_error", `the other sessions are ended, but the new token for this one could not be saved: ${reasonOf(error)} — run \`max session start\``);
184
+ throw new CliError("configuration_error", `the other sessions are ended, but the new token for this one could not be saved: ${reasonOf(error)} — run \`max ${asFirstWord(this.#store.profile)}session start\``);
185
185
  }
186
186
  }
187
187
  try {
188
188
  return asArray((await this.#wire.account.sessions({})).sessions).map(toSession);
189
189
  }
190
190
  catch (error) {
191
- throw new CliError("authentication_error", `the other sessions are ended, and MAX no longer answers this one (${asCliError(error).message}) — run \`max session start\``);
191
+ throw new CliError("authentication_error", `the other sessions are ended, and MAX no longer answers this one (${asCliError(error).message}) — run \`max ${asFirstWord(this.#store.profile)}session start\``);
192
192
  }
193
193
  }),
194
194
  };
@@ -1170,7 +1170,7 @@ export class MaxClient {
1170
1170
  throw new CliError("outcome_unknown", "MAX accepted the deletion but its result could not be verified — read the messages before any retry", { reason: "deletion_unconfirmed" });
1171
1171
  }
1172
1172
  if (retained.length)
1173
- throw new CliError("outcome_unknown", "MAX still returns messages after the deletion — read them before any retry", { reason: "deletion_unconfirmed", retained });
1173
+ throw new CliError("outcome_unknown", `MAX still returns messages ${retained.join(", ")} after the deletion — read them before any retry`, { reason: "deletion_unconfirmed", retained });
1174
1174
  this.#sends?.record({ chatId, kind: "delete", outcome: "sent", count, forEveryone });
1175
1175
  return { chatId, deleted: messageIds, forEveryone };
1176
1176
  }
@@ -1826,7 +1826,7 @@ export class MaxClient {
1826
1826
  const token = candidate ?? this.#store.readToken();
1827
1827
  if (!token) {
1828
1828
  const profile = this.#store.profile;
1829
- // cli-core swallows a keyring that will not open, so the state file is the only witness: a
1829
+ // cli-base swallows a keyring that will not open, so the state file is the only witness: a
1830
1830
  // profile that has logged in lost its keyring, not its session, and another login would
1831
1831
  // register one more device for nothing (MAX-50, measured from cron 2026-09-25).
1832
1832
  if (this.#store.hasLoggedIn()) {
@@ -2783,7 +2783,7 @@ const asRefusal = (error) => {
2783
2783
  return new CliError("rate_limited", error.message, { operation: String(error.opcode) });
2784
2784
  }
2785
2785
  if (text.includes("token") || text.includes("auth")) {
2786
- return new CliError("authentication_error", `${error.message} — the session may have expired; run \`max session start\``);
2786
+ return new CliError("authentication_error", `${error.message} — the session may have expired; run \`max <profile> session start\``);
2787
2787
  }
2788
2788
  return new CliError("provider_error", error.message, { operation: String(error.opcode) });
2789
2789
  };