@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.
- package/README.md +51 -49
- package/dist/adapter/max-adapter.js +1 -1
- package/dist/bin/max.js +4 -0
- package/dist/bin/max.js.map +1 -1
- package/dist/bot/adapter.d.ts +2 -2
- package/dist/bot/adapter.js +1 -1
- package/dist/bot/auth.d.ts +1 -1
- package/dist/bot/client.d.ts +1 -1
- package/dist/bot/client.js +1 -1
- package/dist/bot/generated/manifest.d.ts +1 -1
- package/dist/bot/generated/schemas.js +1 -1
- package/dist/bot/input.d.ts +1 -1
- package/dist/bot/joins.js +1 -1
- package/dist/bot/keep.js +1 -1
- package/dist/bot/transport.d.ts +3 -3
- package/dist/bot/transport.js +2 -2
- package/dist/bot/uploads.d.ts +2 -2
- package/dist/bot/uploads.js +2 -2
- package/dist/client.d.ts +1 -1
- package/dist/client.js +6 -6
- package/dist/client.js.map +1 -1
- package/dist/commands/bot-comments.js +2 -2
- package/dist/commands/bot-context.d.ts +5 -5
- package/dist/commands/bot-context.js +1 -1
- package/dist/commands/bot-members.js +2 -2
- package/dist/commands/bot-reads.js +1 -1
- package/dist/commands/bot-sends.d.ts +1 -1
- package/dist/commands/bot-sends.d.ts.map +1 -1
- package/dist/commands/bot-sends.js +6 -2
- package/dist/commands/bot-sends.js.map +1 -1
- package/dist/commands/bot-setup.js +1 -1
- package/dist/commands/complete.js +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +10 -8
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.js +1 -1
- package/dist/commands/context.d.ts +5 -5
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +3 -3
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/mcp.js +6 -6
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/messages.d.ts.map +1 -1
- package/dist/commands/messages.js +2 -1
- package/dist/commands/messages.js.map +1 -1
- package/dist/commands/paging.d.ts +1 -1
- package/dist/commands/paging.js +1 -1
- package/dist/commands/recipients.js +2 -2
- package/dist/commands/serve-members.js +1 -1
- package/dist/commands/serve.js +1 -1
- package/dist/commands/server.js +1 -1
- package/dist/commands/session.js +9 -9
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +13 -12
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skill.js +1 -1
- package/dist/commands/skill.js.map +1 -1
- package/dist/commands/watch.js +1 -1
- package/dist/config.d.ts +6 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -2
- package/dist/config.js.map +1 -1
- package/dist/diagnose.js +3 -3
- package/dist/domain/map.js +1 -1
- package/dist/download.js +1 -1
- package/dist/format-markdown.js +1 -1
- package/dist/inbox-point.js +1 -1
- package/dist/install/postinstall.d.ts.map +1 -1
- package/dist/install/postinstall.js +2 -2
- package/dist/install/postinstall.js.map +1 -1
- package/dist/install.d.ts +1 -1
- package/dist/install.js +1 -1
- package/dist/mcp/photo.js +1 -1
- package/dist/mcp/resources.js +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/session.js +1 -1
- package/dist/mcp/shared.js +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/messenger.d.ts.map +1 -1
- package/dist/messenger.js +1 -0
- package/dist/messenger.js.map +1 -1
- package/dist/moderation/check.js +1 -1
- package/dist/moderation/points.js +1 -1
- package/dist/permissions.js +2 -2
- package/dist/profile.d.ts +3 -3
- package/dist/profile.d.ts.map +1 -1
- package/dist/profile.js +5 -5
- package/dist/profile.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +13 -7
- package/dist/program.js.map +1 -1
- package/dist/rendering/messages.js +1 -1
- package/dist/report.js +1 -1
- package/dist/sends.js +2 -2
- package/dist/sends.js.map +1 -1
- package/dist/server/replies.js +1 -1
- package/dist/server/server-connection.js +1 -1
- package/dist/server/server.js +1 -1
- package/dist/server/subscribe.js +1 -1
- package/dist/session/adopt.d.ts +1 -1
- package/dist/session/adopt.js +1 -1
- package/dist/session/browser.js +1 -1
- package/dist/session/login.js +1 -1
- package/dist/session/store.d.ts +1 -1
- package/dist/session/store.js +1 -1
- package/dist/skill.d.ts +2 -2
- package/dist/skill.js +1 -1
- package/dist/spec/define.js +1 -1
- package/dist/spec/guards.js +1 -1
- package/dist/transcribe/index.d.ts +1 -1
- package/dist/transcribe/index.js +1 -1
- package/dist/update.d.ts +2 -2
- package/dist/update.js +6 -6
- package/dist/update.js.map +1 -1
- package/dist/upload.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/voice.js +1 -1
- package/package.json +10 -9
- 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
|
|
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
|
-
`
|
|
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-
|
|
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-
|
|
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));
|
package/dist/bin/max.js.map
CHANGED
|
@@ -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"}
|
package/dist/bot/adapter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type SleepLike } from "@wirecat/cli-
|
|
2
|
-
import type { FetchLike } from "@wirecat/cli-
|
|
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";
|
package/dist/bot/adapter.js
CHANGED
package/dist/bot/auth.d.ts
CHANGED
package/dist/bot/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ManifestOperation } from "@wirecat/cli-
|
|
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";
|
package/dist/bot/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliError } from "@wirecat/cli-
|
|
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,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-
|
|
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();
|
package/dist/bot/input.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ManifestOperation, SchemaNode } from "@wirecat/cli-
|
|
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-
|
|
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-
|
|
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";
|
package/dist/bot/transport.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type RetryConfig, type SleepLike } from "@wirecat/cli-
|
|
2
|
-
import type { ManifestOperation } from "@wirecat/cli-
|
|
3
|
-
import { type FetchLike } from "@wirecat/cli-
|
|
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
|
/**
|
package/dist/bot/transport.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import tls from "node:tls";
|
|
2
|
-
import { backoffMs, CliError, DEFAULT_RETRY, realSleep, singleLine, } from "@wirecat/cli-
|
|
3
|
-
import { providerWaitMs, statusToCode } from "@wirecat/cli-
|
|
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";
|
package/dist/bot/uploads.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type SleepLike } from "@wirecat/cli-
|
|
2
|
-
import { type FetchLike } from "@wirecat/cli-
|
|
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];
|
package/dist/bot/uploads.js
CHANGED
|
@@ -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-
|
|
4
|
-
import { statusToCode } from "@wirecat/cli-
|
|
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-
|
|
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-
|
|
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",
|
|
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-
|
|
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
|
};
|