Скрипты
Вывод JSON, потоки, коды выхода, переменные окружения и работа без присмотра или в CI.
Вывод JSON
С --json stdout содержит только JSON с отступом в два пробела, заметки и прогресс остаются в stderr, и ничего не спрашивается. Список выводит { items, hasMore, nextCursor }, объект API выводится так, как его вернул API, а написанная вручную команда выводит объект, описанный в её справке.
openemail whoami --json | jq -r .workspaceIdopenemail emails list --status failed --json | jq -r ".items[].id"Ошибка уходит в stderr одной строкой JSON, а код выхода тот же, что получил бы человек:
{"error":{"type":"permission_error","code":"insufficient_scope","message":"This API key does not have the domains:write scope.","hint":"The credential is missing a scope this call needs. Use a key that has it, or sign in again with openemail login.","next":null,"status":403,"requestId":"req_7Hc2kQ","param":null,"docUrl":"https://openemail.uk/docs/api/errors#insufficient_scope","exitCode":4}}| Поле | Что в нём |
|---|---|
| type | Тип ошибки API или cli_error, network_error или internal_error для сбоя внутри CLI |
| code | Стабильный код, например insufficient_scope, not_signed_in или unknown_flag |
| message | Что пошло не так, одним предложением |
| hint, next | Что попробовать и какую команду запустить дальше, или null |
| status, requestId, param, docUrl | Из API, если ошибка пришла от него, иначе null |
| exitCode | Код выхода, с которым завершается процесс |
Потоки
Часть вывода это поток JSON-объектов, по одному в строке, чтобы конвейер обрабатывал каждый элемент по мере поступления:
- Список ресурсов с
--all, когда stdout не терминал, или с--ndjson.--max <n>останавливается после стольких элементов. openemail temp watch --json, по одной строке на новое письмо.openemail mcp serve, по одному сообщению JSON-RPC в строке в каждую сторону.
openemail contacts list --all > contacts.ndjsonopenemail emails list --status failed --all --max 500 | jq -r .idКоды выхода
| Код | Значение |
|---|---|
| 0 | Готово |
| 1 | Неожиданный сбой, ошибка сервера или неудачная отправка |
| 2 | Ошибка использования: неверный аргумент, неизвестная команда или флаг, значение или подтверждение, которое не удалось запросить, либо адрес или путь, куда CLI не отправит учётные данные |
| 3 | Вход не выполнен, либо вход отклонён, истёк или был завершён, пока работала команда |
| 4 | Не разрешено: не хватает scope или разрешения, код подтверждения не удалось запросить или он на паузе, или API-ключ там, где нужен вход через браузер |
| 5 | Не найдено |
| 6 | Конфликт с текущим состоянием |
| 7 | Ввод был неверным |
| 8 | Превышен лимит запросов или исчерпана квота ИИ |
| 9 | Сбой сети или истекло время ожидания |
| 10 | Отменено: вы отклонили подтверждение или вопрос |
| 130, 143 | Остановлено через Ctrl+C или SIGTERM |
Переменные окружения
| Переменная | Что делает |
|---|---|
| OPENEMAIL_API_KEY | API-ключ, который используется вместо любого сохранённого профиля |
| OPENEMAIL_PROFILE | Сохранённый профиль, который нужно использовать |
| OPENEMAIL_BASE_URL | Адрес API для OPENEMAIL_API_KEY, --api-key и команд, которые не отправляют учётных данных. Сохранённый вход уходит только в тот API, в который он вошёл |
| OPENEMAIL_APP_URL | Адрес веб-приложения, для входа, open и ссылок на документацию |
| OPENEMAIL_CONFIG_DIR | Где хранятся профили и токены ящиков, ~/.openemail, если не задано |
| OPENEMAIL_NO_UPDATE_CHECK | Никогда не проверять npm на новый выпуск. OPENEMAIL_DISABLE_UPDATE_NOTICE делает то же самое |
| NO_COLOR, FORCE_COLOR=0 | Без цвета |
| CI | Никогда не спрашивать, никогда не открывать браузер, никогда не проверять обновления. Большинство сервисов CI распознаются и без неё |
| VISUAL, EDITOR | Редактор, который send и reply открывают для тела |
Работа без присмотра
CLI задаёт вопросы, только когда stdin и stdout оба терминалы и не действует ни --json, ни --no-input, ни CI. Иначе:
- Отсутствующее обязательное значение завершается с кодом выхода
2и называет флаг, который нужно передать. - Разрушительная команда завершается с
Refusing to run unattended. Pass --yes to confirm.и кодом выхода2, если вы не передадите--yes. - Изменение, которому нужен код подтверждения, завершается с кодом выхода
4, потому что ввести его некому. Используйте API-ключ или сначала запуститеopenemail verify.
В CI
Дайте задаче API-ключ только с нужными scope, храните его в секрете и пусть его передаёт OPENEMAIL_API_KEY. Ничего не сохраняется, ничего не спрашивается, и проверка обновлений не запускается.
- name: Tell the team env: OPENEMAIL_API_KEY: ${{ secrets.OPENEMAIL_API_KEY }} run: | npx -y @openemail/[email protected] send \ --from [email protected] \ --to [email protected] \ --subject "Deployed ${{ github.sha }}" \ --text "Build ${{ github.run_number }} is live." \ --idempotency-key "deploy-${{ github.run_id }}"ADDRESS=$(npx -y @openemail/[email protected] temp new --ttl 15)./signup-test.sh "$ADDRESS"npx -y @openemail/[email protected] temp watch --first --json | jq -r .snippetnpx -y @openemail/[email protected] temp delete --yesfailed=$(openemail emails list --status failed --json | jq ".items | length")test "$failed" -eq 0Передавайте --idempotency-key при отправке, которую конвейер может повторить, и выводите его из того, что сделало отправку нужной, например из идентификатора запуска. Повтор шага тогда вернёт первую отправку, а не отправит письмо дважды.