diff --git a/CHANGELOG.md b/CHANGELOG.md index 66488df7..6563ee15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,46 @@ номера версий по [семантике](https://semver.org/lang/ru/), то есть до `1.0.0` интерфейс команд ещё может меняться. -## 0.26.0 — 03.10.2026 +## 0.27.0 — 04.10.2026 ### Что нового -- **`max messages link` и MCP `max_messages_link` возвращают locator конкретного сообщения** - после проверки локального архива текущей учётной записи. Личный MAX пока не выдаёт нативный - permalink; `url` равен `null`, причина явно указана. Другие учётные записи отклоняются, - `--offline` не подключается. `messages links` по-прежнему показывает связи разговоров. +- **`max commands messages search --json` описывает одну команду, а `max commands messages --json` — группу.** + Агенту больше не нужно читать всё дерево перед каждой задачей; глобальные опции и коды завершения + сохраняются. Слова после `commands` задают один путь, разные группы смотрите отдельными вызовами. + Вызов без пути по-прежнему возвращает всё дерево. + +- **`max messages link` и MCP `max_messages_link` возвращают locator сообщения из локального архива.** + Сообщение проверяется в текущей учётной записи; locator другой учётной записи отклоняется. + Личный MAX пока не предоставляет подтверждённый permalink: `url` равен `null`, причина указана + в ответе. `--offline` не подключается к MAX. См. [сообщения](docs/usage.md). + +### Изменено — может сломать скрипты + +- **CLI и MCP используют `permissions` с уровнями `deny`, `readonly`, `ask`, `allow`.** + Один набор прав действует для команд и агентов. Большинство записей через MCP теперь доступно + по умолчанию; удаление сообщений и завершение других сессий требуют подтверждения, если не задан + явный `allow`. Например, `messages: readonly` и `messages.delete: allow` разрешают чтение и + удаление без вопроса, запрещая другие записи в сообщения; остальные ресурсы не ограничиваются. + Перед обновлением проверьте права агента и задайте `readonly` или `deny` нужным ресурсам. + `--confirm-send` требует форму перед каждой записью; в JSON-режиме `ask` требует явного флага. + +- **`config migrate` переводит старые настройки доступа и уровни правил модерации.** + `--dry-run` показывает изменения без записи; миграция сохраняет действовавшие уровни, настройки + MAX и сохранённые места проверки групп. После появления `permissions` менять `readOnly`, `allow` + и `mcpTools` нельзя. Старые MCP-флаги `--allow-send`, `--allow-mark-read`, `--allow-delete`, + `--allow-moderate` пока принимаются с предупреждением, но не дают прав. Список получателей и + лимит в час продолжают действовать. См. [настройки](docs/configuration.md) и [MCP](docs/mcp.md). + +### Исправлено + +- **Параллельное открытие локального архива ждёт краткую блокировку SQLite при запуске.** + Раньше настройка журнала могла встретить занятую базу до включения ожидания и отказать сразу. + Длительная блокировка по-прежнему завершается ошибкой; изменение не запускает загрузку истории. + +## 0.26.0 — 03.10.2026 + +### Что нового - **`max skill show link-conversations` печатает общий навык связывания разговоров.** Команда доступна без сессии; без имени по-прежнему выдаётся основной навык MAX. @@ -21,15 +53,6 @@ ### Изменено — может сломать скрипты -- **CLI и MCP используют четыре уровня `permissions`: `deny`, `readonly`, `ask`, `allow`.** - Можно разрешить удаление отдельно от остальных записей в сообщения. Большинство записей через - MCP теперь разрешено по умолчанию; удаление требует подтверждения, если не задан явный `allow`. - Ограничьте ресурсы через `readonly` или `deny`; `--confirm-send` требует форму для каждой записи. - Старые `--allow-*` принимаются с предупреждением и не дают прав. `config migrate --dry-run` - показывает перевод `readOnly`, `allow`, `mcpTools` и уровней модерации; `config migrate` сохраняет - его, после чего старые настройки нельзя менять. См. [настройки](docs/configuration.md). - - - **Скачанные фото получают расширение по HTTP MIME**, например `.webp` для WebP, а не JPEG по типу вложения. Исходные имена файлов сохраняются; лишних предварительных запросов нет. diff --git a/docs/commands.md b/docs/commands.md index 8c99cd87..98a6a4cc 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -1876,12 +1876,16 @@ max skill install [options] ## `max commands` -every command, option and exit code as JSON — what an agent reads instead of --help +commands, options and exit codes as JSON — inspect one command path per call ```sh -max commands +max commands [path] ``` +| Аргумент | | Что это | +|---|---|---| +| `path` | необязательный | one command path, for example: messages search; inspect other groups in separate calls. | + ## `max upgrade` upgrade max with the package manager that installed it; --check only looks diff --git a/docs/dev/BACKLOG.md b/docs/dev/BACKLOG.md index c175e951..ccb64fb7 100644 --- a/docs/dev/BACKLOG.md +++ b/docs/dev/BACKLOG.md @@ -202,3 +202,5 @@ which; the plan for it starts by saying so. - Completed 2026-10-03: chats-show member counts explain possible self omission or partial lists without claiming incomplete loading (SDK0.137, CLI-62). Online and offline consumer regressions retain JSON counts and members. - Completed 2026-10-03: MAX poll.already.voted refusal explains explicit retract before a new vote when the poll permits changing votes (CLI-61). Provider error identity and one attempted write are preserved; wire refusal regressions cover other errors and an explicit retract refusal. + +- Release coordination · 🚧 `release/coordinated-027` prepares MAX and TG together, aggregates parallel PR evidence, and keeps publication/sign-off pending. Handoff: `docs_ai/plans/2026-10-04-coordinated-release.md`. Avoid competing version/changelog bumps. diff --git a/docs/diagnostics.md b/docs/diagnostics.md index 9e0c3642..0cd5c4d2 100644 --- a/docs/diagnostics.md +++ b/docs/diagnostics.md @@ -169,7 +169,10 @@ max runs list --json | jq '.items[] | select(.status=="failed") | {runId, comman ## Справочник для скриптов `max commands --json` перечисляет команды, глобальные опции и коды завершения без подключения -к аккаунту. `cli` — имя инструмента, `version` — версия установленного пакета, `contract` — версия +к аккаунту. Для одной команды используйте `max commands messages search --json`, для группы — +`max commands messages --json`: глобальные опции и коды завершения остаются в ответе. +Слова после `commands` задают один путь; разные группы смотрите отдельными вызовами. +`cli` — имя инструмента, `version` — версия установленного пакета, `contract` — версия общего JSON-контракта (`0`). Она меняется при несовместимом изменении полей ответа; обновление пакета само по себе не меняет `contract`. Скрипт может читать отдельные поля, не сравнивая весь JSON с сохранённой строкой. diff --git a/docs/mcp.md b/docs/mcp.md index cd8dc4a9..3fcd139f 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -80,6 +80,9 @@ Windows `max` — это файл `max.cmd`, который клиент без `--allow-send` и другие переносятся в запись. Переменные `MAX_CONFIG_DIR`, `MAX_STATE_DIR` и `MAX_CACHE_DIR` попадают в неё, только если заданы; токен — никогда. `MAX_CACHE_DIR` теперь относится только к прежнему кэшу, а общую копию задаёт `MESSAGING_STORE`. +Если в терминале задан `MESSAGING_STORE`, добавьте то же значение в `env` записи MCP вручную: +`max mcp config` его не переносит. Иначе клиент, запущенный с рабочего стола, может открыть другой +архив, и локальный поиск или locator сообщения не найдут сохранённые данные. Если Node поставлен через nvm, fnm или Volta, путь к нему относится к одной версии Node — после её смены запустите `max mcp config` снова. Из `npx` команда отказывается работать: кэш `npx` diff --git a/docs/usage.md b/docs/usage.md index 26debd5e..1a9e6f61 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -861,10 +861,6 @@ max runs path # каталог, для jq и grep ### Что профилю можно -`allow` — список действий, которые профилю разрешены. Без него разрешено всё, как раньше. - -### Права по ресурсам и командам - ```sh max config set permissions.messages readonly max work config set permissions.messages.delete allow diff --git a/package.json b/package.json index 945b62ee..2dbaaf2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@leemour/max-cli", - "version": "0.26.0", + "version": "0.27.0", "description": "MAX Messenger bots through the official Bot API, and a personal MAX account, from the terminal — built for agents and scripts", "license": "MIT", "author": "Viacheslav Ptsarev", @@ -81,7 +81,7 @@ }, "dependencies": { "@leemour/cli-core": "0.17.0", - "@leemour/cli-messaging": "0.139.0", + "@leemour/cli-messaging": "0.140.0", "@modelcontextprotocol/server": "2.1.0", "@msgpack/msgpack": "3.1.3", "@valibot/to-json-schema": "1.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68059b96..a1d54cfd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: 0.17.0 version: 0.17.0(commander@15.0.0)(typescript@7.0.2) '@leemour/cli-messaging': - specifier: 0.139.0 - version: 0.139.0(@leemour/cli-core@0.17.0(commander@15.0.0)(typescript@7.0.2))(cac@6.7.14)(commander@15.0.0)(typescript@7.0.2) + specifier: 0.140.0 + version: 0.140.0(@leemour/cli-core@0.17.0(commander@15.0.0)(typescript@7.0.2))(cac@6.7.14)(commander@15.0.0)(typescript@7.0.2) '@modelcontextprotocol/server': specifier: 2.1.0 version: 2.1.0 @@ -618,8 +618,8 @@ packages: '@leemour/cli-messaging-sqlite@1.0.0': resolution: {integrity: sha512-NFJMG+/2BWIb3JdOMgyV8SFsB7Fuv3wLtUmMt08GZ4KTpgu0WuA7qQmQE6appEgJJuF/97vHj6+AuXw2z3HMHw==} - '@leemour/cli-messaging@0.139.0': - resolution: {integrity: sha512-v+16FOS85sJpdWYpZU73+u5kssC6vJqbIZ0LTJBQ5lMScEGyPSi7IjNtBwLeU1T2pJTLp9jEpXVoU5iB5GOnBg==} + '@leemour/cli-messaging@0.140.0': + resolution: {integrity: sha512-zruYLqNVoN2YmyOmvbFqCd/YMloaRf/1JLmVZv2QrLBxlvorPaEks6mq7vYm/M9cEhAyn9aoTkAj8+mEZl6hvA==} engines: {node: ^22.16.0 || >=24} hasBin: true peerDependencies: @@ -2064,7 +2064,7 @@ snapshots: '@leemour/cli-messaging-sqlite@1.0.0': {} - '@leemour/cli-messaging@0.139.0(@leemour/cli-core@0.17.0(commander@15.0.0)(typescript@7.0.2))(cac@6.7.14)(commander@15.0.0)(typescript@7.0.2)': + '@leemour/cli-messaging@0.140.0(@leemour/cli-core@0.17.0(commander@15.0.0)(typescript@7.0.2))(cac@6.7.14)(commander@15.0.0)(typescript@7.0.2)': dependencies: '@bomb.sh/tab': 0.0.22(cac@6.7.14)(commander@15.0.0) '@huggingface/tokenizers': 0.2.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d53db61d..51fbf6e3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,6 +6,6 @@ allowBuilds: lefthook: true minimumReleaseAgeExclude: - '@leemour/cli-core@0.1.0 || 0.1.1 || 0.2.0 || 0.3.0 || 0.4.0 || 0.5.0 || 0.6.0 || 0.6.1 || 0.7.0 || 0.8.0 || 0.9.0 || 0.10.0 || 0.12.0 || 0.14.0 || 0.15.0 || 0.16.0 || 0.17.0' - - '@leemour/cli-messaging@0.1.0 || 0.2.0 || 0.4.0 || 0.5.0 || 0.10.0 || 0.13.0 || 0.26.0 || 0.28.0 || 0.29.0 || 0.45.0 || 0.49.0 || 0.61.0 || 0.62.0 || 0.64.0 || 0.65.0 || 0.66.0 || 0.69.0 || 0.70.0 || 0.71.0 || 0.72.0 || 0.77.0 || 0.79.0 || 0.86.0 || 0.87.0 || 0.90.0 || 0.92.0 || 0.93.0 || 0.94.0 || 0.95.0 || 0.97.0 || 0.98.0 || 0.99.0 || 0.102.0 || 0.103.0 || 0.104.0 || 0.106.0 || 0.107.0 || 0.108.0 || 0.109.0 || 0.111.0 || 0.113.0 || 0.114.0 || 0.115.0 || 0.116.0 || 0.117.0 || 0.119.0 || 0.122.0 || 0.123.0 || 0.127.0 || 0.128.0 || 0.129.0 || 0.130.0 || 0.131.0 || 0.132.0 || 0.133.0 || 0.134.0 || 0.135.0 || 0.136.0 || 0.137.0 || 0.139.0' + - '@leemour/cli-messaging@0.1.0 || 0.2.0 || 0.4.0 || 0.5.0 || 0.10.0 || 0.13.0 || 0.26.0 || 0.28.0 || 0.29.0 || 0.45.0 || 0.49.0 || 0.61.0 || 0.62.0 || 0.64.0 || 0.65.0 || 0.66.0 || 0.69.0 || 0.70.0 || 0.71.0 || 0.72.0 || 0.77.0 || 0.79.0 || 0.86.0 || 0.87.0 || 0.90.0 || 0.92.0 || 0.93.0 || 0.94.0 || 0.95.0 || 0.97.0 || 0.98.0 || 0.99.0 || 0.102.0 || 0.103.0 || 0.104.0 || 0.106.0 || 0.107.0 || 0.108.0 || 0.109.0 || 0.111.0 || 0.113.0 || 0.114.0 || 0.115.0 || 0.116.0 || 0.117.0 || 0.119.0 || 0.122.0 || 0.123.0 || 0.127.0 || 0.128.0 || 0.129.0 || 0.130.0 || 0.131.0 || 0.132.0 || 0.133.0 || 0.134.0 || 0.135.0 || 0.136.0 || 0.137.0 || 0.139.0 || 0.140.0' - '@leemour/cli-messaging-sqlite@1.0.0' - '@leemour/cli-messaging-onnx@1.0.0' diff --git a/skills/max-cli/SKILL.md b/skills/max-cli/SKILL.md index f27d5807..ddd9325d 100644 --- a/skills/max-cli/SKILL.md +++ b/skills/max-cli/SKILL.md @@ -8,14 +8,18 @@ description: Читать и отправлять сообщения в личн `max` работает с **настоящим личным аккаунтом** владельца. Ошибка здесь не роняет тест, а пишет живому человеку. Один вызов — одно действие: подключиться, сделать, напечатать, выйти. -Полный список команд и флагов — **`max commands --json`**: всё дерево одним ответом — аргументы, -флаги (берёт ли значение, обязателен ли), коды выхода и пометка `mutates: true` на командах, которые -что-то меняют в MAX. `max --help` — то же для человека. Здесь — то, что справка не скажет: ловушки и -границы. +Прочитайте этот навык, затем откройте только команды, нужные для задачи. +**`max commands messages search --json`** описывает одну команду; +**`max commands messages --json`** — всю группу. Оба ответа содержат аргументы, флаги, +глобальные флаги и коды выхода. Для короткой справки — `max <команда> --help`. +Слова после `commands` задают один путь, а не список групп: разные группы смотрите отдельными +вызовами. **`max commands --json`** возвращает всё дерево для общего обзора; +не читайте его целиком перед каждой задачей. `mutates: true` обозначает запись, +а `local: true` ограничивает её этой машиной. Здесь — ловушки и границы. ## Первый запуск -До входа прочитайте `max --help`, `max setup --help` и `max commands --json`. +До входа прочитайте `max --help` и `max setup --help`. Эта инструкция доступна через `max skill show` без сессии. Для личного аккаунта запустите `max setup --agent codex` в локальном терминале владельца; @@ -160,6 +164,25 @@ description: Читать и отправлять сообщения в личн ## Типичный путь Id ниже выдуманные — подставить настоящие из предыдущего ответа. +Выбирайте команды по задаче владельца, а не начинайте всегда с последних сообщений: + +- **Найти договорённость или документ:** найдите нужные чаты и ищите в локальной копии. + Проверьте покрытие поиска и `store status`; `messages list` показывает только окно сообщений. + Уточняйте найденное через `messages context` или `messages show`, приводите ссылки на сообщения. + Проверьте связанные чаты на поздние изменения. Пустой результат, пустой чат и `hasMore: false` + не доказывают полноту истории MAX. Если это влияет на ответ, объясните пробел. + Скачивайте только разрешённый чат и ограниченный период или объём; сначала проверьте + `store fetch --estimate`. Без сети недостающую историю скачать нельзя. +- **Подготовиться к встрече:** найдите проектные группы и личные чаты участников. + Название личного чата может не содержать название проекта. Сравните сообщения по датам: + более позднее подтверждение в личке может закрыть старый блокер. Для подборки используйте + `messages evidence`, проверяйте покрытие и продолжайте по курсору. + Отделяйте решения, открытые вопросы и предположения о сроках. +- **Рекомендовать человека:** сравните подтверждённый опыт в разных чатах. + Сопоставьте id авторов с `contacts show` и личными чатами; одинаковые имена не означают одного + человека. Прошлая доступность не подтверждает нынешнюю. Подготовьте черновик, если владелец + не попросил отправить его конкретному получателю. При отказе по правам остановитесь и сохраните + черновик; не меняйте настройки и не переключайте профили. ```sh max chats list --search "проект" --json # найти чат, взять его id diff --git a/src/version.ts b/src/version.ts index ba50d13e..05603a2f 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ /** The one the running command reports. `pnpm version:check` fails when it and package.json disagree. */ -export const VERSION = "0.26.0" +export const VERSION = "0.27.0"