Назад к обновлениям
New releaseSep 5, 2026

resterm v1.5.6

Терминальный API-клиент для HTTP, GraphQL и gRPC. Обычные .http-файлы, которые можно сравнивать и версионировать, с поддержкой workflows, моков, профилирования, трассировки, импорта OpenAPI, SSH-туннелей, проброса портов Kubernetes, WebSocket, SSE и CLI-раннера.

Поделиться

Resterm
Resterm

Терминальный API-клиент и рабочая среда для REST, GraphQL, gRPC, WebSocket и SSE.

Скриншот базового TUI Resterm

Resterm — это рабочая среда API-as-code или, более привычными словами, API-клиент, построенный вокруг обычных файлов .http и .rest, которые можно сравнивать, рецензировать и версионировать. Он сочетает интерактивное редактирование запросов с декларативными рабочими процессами, проверками (assertions), mock-серверами, трассировкой, профилированием и автоматизацией без графического интерфейса. Всё остаётся на вашей машине. Никаких аккаунтов, облачной синхронизации и телеметрии.

Если вы ищете клиент в стиле Postman, ориентированный на коллекции в GUI, Resterm, вероятно, не для вас, но всё равно попробуйте!

[!NOTE] Resterm теперь v1! Смотрите примечания к релизу v1.0.0 о новых функциях и критических изменениях.

Быстрые ссылки: Скриншоты, Быстрый старт, Файлы запросов, Установка, Документация.

Обзор скриншотов

Посмотреть интерфейс в действии (нажмите, чтобы развернуть)

Рабочие процессы

Скриншот Resterm с рабочим процессом

Трассировка и временная шкала

Скриншот Resterm с временной шкалой

Профилировщик

Скриншот профилировщика Resterm

Объяснение

Скриншот вкладки Explain в Resterm

RestermScript

Скриншот Resterm с RestermScript

Светлая тема

Скриншот Resterm в светлой теме

Демонстрация OAuth в браузере (старый дизайн интерфейса)

Поток OAuth в Resterm

Почему Resterm

  • HTTP, GraphQL, gRPC, WebSocket и SSE из коробки.
  • Автоматизация живёт в файлах запросов: условия (@when, @if/@elif/@else, @for-each), многошаговые рабочие процессы (@workflow / @step), захваты, переменные и проверки (@capture, @var, @assert).
  • RestermScript — небольшой язык выражений, созданный для Resterm, с JavaScript-хуками, когда они вам нужны.
  • Управление в стиле Vim с контекстными подсказками в нижней панели, доступной офлайн справкой, помощью K под курсором, поиском / и командами вроде :w, :q, :help и :docs.
  • Встроенные аутентификация и туннелирование: OAuth 2.0 (client credentials, password, auth code с PKCE), аутентификация через ваши существующие CLI, SSH-туннели и port-forwarding Kubernetes. Дополнительные инструменты не нужны.
  • CLI-раннер: resterm run для скриптовых запусков и CI с выводом в JSON и JUnit.
  • Mock-серверы, объявленные рядом с запросами, которые они имитируют, с правилами сопоставления, последовательностями, проверкой вызовов и горячей перезагрузкой.
  • Трассировка временной шкалы, профилирование и сравнение запусков в разных средах.
  • Потоковые транскрипты и интерактивная консоль для WebSocket и SSE.
  • Никакой интеграции с ИИ, никогда.

Быстрый старт

  1. Установите Resterm (см. Установка для скриптов, Windows и ручной установки). ```bash brew install resterm
  2. Инициализируйте рабочее пространство. ```bash mkdir my-api && cd my-api resterm init

resterm init создаёт небольшой проект, который работает без подключения к интернету. Сгенерированный requests.http включает локальные mock-сценарии и несколько запросов, которые строятся друг на друге. Они охватывают проверки (assertions), bearer-аутентификацию, сопоставление JSON, json-rules и @for-each.

  1. Запустите его и отправьте свой первый запрос. ```bash resterm

Нажмите Ctrl+Enter в редакторе, чтобы отправить выделенный запрос.

Файлов ещё нет? Просто запустите resterm, введите URL и нажмите Ctrl+Enter. Вставленная команда curl тоже подойдёт.

Файлы запросов

Файлы запросов Resterm используют стандартный синтаксис HTTP, а также директивы # @ для настройки и автоматизации:```http

@setting base-url https://api.example.com/v1/

Create users

// Send this request once for each name in the list.

@for-each ["david", "tom"] as name

@when env.mode == "development"

@assert response.statusCode == 201

POST users Content-Type: application/json

{"name":"{{= name }}"}

Настройки перед первым запросом применяются ко всему файлу, `###` разделяет запросы, а директивы могут повторяться, ограничивать или проверять запрос. Больше примеров здесь: [`_examples/`](https://github.com/unkn0wn-root/resterm/blob/main/_examples).

## CLI

`resterm run` выполняет файлы `.http` / `.rest` без открытия TUI — именно это запускает CI.```bash
resterm run --request CreateUser requests.http

Сгенерированный проект общается с локальным mock-сервером. Сначала запустите его в другом терминале:```bash resterm mock requests.http

В TUI нажмите `g Shift+M`, чтобы запустить тот же mock-сервер из рабочей области.

[Документация по CLI](https://github.com/unkn0wn-root/resterm/blob/main/docs/cli.md) описывает селекторы, форматы вывода и другие примеры.

## Шпаргалка по клавиатуре

- Фокус и раскладка панелей
  - `Tab` / `Shift+Tab`: переключение между боковой панелью, редактором и ответом.
  - `g+r`, `g+i`, `g+p`: переход к запросам, редактору или ответу.
  - `g+h` / `g+l`: изменение размера по горизонтали. Меняет ширину боковой панели, когда она в фокусе, иначе — разделение редактора/ответа.
  - `g+j` / `g+k`: изменение высоты редактора/ответа при вертикальном расположении, сворачивание или разворачивание веток в навигаторе.
  - `g+v` / `g+s`: переключение панели ответа между встроенной и вертикальной раскладкой.
  - `g+1`, `g+2`, `g+3`: сворачивание или восстановление боковой панели, редактора, ответа.
  - `g+z` / `g+Z`: увеличение панели в фокусе, сброс увеличения.
- Окружения и глобальные переменные
  - `Ctrl+E`: переключение окружений.
  - `Ctrl+G`: просмотр захваченных глобальных переменных.
- Справка и команды
  - `?`: открыть доступный для поиска офлайн-индекс справки.
  - `K` (обычный режим редактора): открыть справку по директиве, шаблону или ключевому слову под курсором.
  - `:help <тема>` / `:man <тема>`: открыть встроенную тему; `:docs <тема>` открывает полное руководство, соответствующее версии.
  - `Ctrl+O`: открыть всплывающее окно файла/рабочей области. Введите текст для фильтрации, прокручивайте с помощью `Up` / `Down` и используйте `Tab` для перехода в каталоги.
  - `:`: открыть командную строку. Используйте `Up` / `Down` для выбора предложений, `Tab` для автодополнения или `Enter` для принятия и запуска выбранного. Аргументы-пути, такие как `:mock start --source` и `:edit`, открывают файловую систему в том же всплывающем окне.
- Ответы
  - `Ctrl+V` / `Ctrl+U`: разделить панель ответа для сравнения бок о бок.
  - `Ctrl+Shift+C` или `g y` (фокус на ответе): скопировать всю вкладку Pretty, Raw или Headers.
  - `g x`: показать предпросмотр Explain для активного запроса без его отправки.
  - `g e`: открыть текущий файл во внешнем редакторе.

> [!TIP]
> Если вы запомните только три сочетания:
> - `Ctrl+Enter` отправляет запрос
> - `Tab` / `Shift+Tab` переключает панели
> - `g+p` переходит к ответу

## Установка

**Linux / macOS (Homebrew)**```bash
brew install resterm

[!NOTE] Установки через Homebrew следует обновлять с помощью Homebrew (brew upgrade resterm). Встроенная команда resterm --update предназначена для бинарных файлов, установленных из релизов GitHub или с помощью скриптов установки.

Linux / macOS (Shell-скрипт)

[!IMPORTANT] Готовые бинарные файлы для Linux зависят от glibc 2.32 или новее. На более старом дистрибутиве соберите из исходников с более новым тулчейном glibc или обновите glibc перед использованием архивов релизов.```bash curl -fsSL https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bash

или с помощью `wget`:```bash
wget -qO- https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bash

Windows (PowerShell)```powershell iwr -useb https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.ps1 | iex

Скрипты определяют вашу архитектуру, загружают последний релиз и устанавливают бинарный файл.

### Ручная установка

> [!NOTE]
> Вспомогательный скрипт ручной установки использует `curl` и `jq`. Установите `jq` с помощью вашего менеджера пакетов (`brew install jq`, `sudo apt install jq` и т. д.).

**Linux / macOS**```bash
# Detect latest tag
LATEST_TAG=$(curl -fsSL https://api.github.com/repos/unkn0wn-root/resterm/releases/latest | jq -r .tag_name)

# Download the matching binary (Darwin/Linux + amd64/arm64)
curl -fL -o resterm "https://github.com/unkn0wn-root/resterm/releases/download/${LATEST_TAG}/resterm_$(uname -s)_$(uname -m)"

# Make it executable and move it onto your PATH
chmod +x resterm
sudo install -m 0755 resterm /usr/local/bin/resterm

Windows (PowerShell)```powershell $latest = Invoke-RestMethod https://api.github.com/repos/unkn0wn-root/resterm/releases/latest $asset = $latest.assets | Where-Object { $.name -like 'resterm_Windows*' } | Select-Object -First 1 Invoke-WebRequest -Uri $asset.browser_download_url -OutFile resterm.exe

Optionally relocate to a directory on PATH, e.g.:

Move-Item resterm.exe "$env:USERPROFILE\bin\resterm.exe"

### Из исходного кода```bash
go install github.com/unkn0wn-root/resterm/cmd/resterm@latest

Обновление```bash

resterm --check-update resterm --update

Первая команда сообщает, доступна ли более новая версия. Вторая загружает, проверяет и устанавливает её на месте. В Windows старый бинарный файл остаётся рядом с новым как `resterm.exe.old` и удаляется при следующем обновлении.

## Конфигурация

- Окружения — это JSON-файлы (`resterm.env.json`), обнаруживаемые в каталоге запроса, корне рабочей области или текущем рабочем каталоге. Файл может определять именованные окружения или независимые группы, например api, app и credentials, которые объединяются в одно окружение. Файлы Dotenv (`.env`, `.env.*`) подключаются по желанию через `--env-file` и относятся к одной рабочей области. См. [группированные окружения](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#grouped-environments) и запускаемый пример в `_examples/grouped/`.
- Конфигурация хранится отдельно для каждой ОС и может быть переопределена с помощью `RESTERM_CONFIG_DIR`:
  - macOS: `~/Library/Application Support/resterm`
  - Windows: `%APPDATA%\resterm`
  - Linux/Unix: `~/.config/resterm`

## Мок-серверы

Вы можете определять мок-ответы в тех же `.http`-файлах, что и ваши запросы.

- Сопоставляйте входящие запросы по строке запроса, заголовкам или JSON-телу, затем выбирайте именованный или ответ по умолчанию.
- Возвращайте последовательность ответов для тестов опроса и повторных попыток. Используйте путь, строку запроса, заголовок или значение cookie, чтобы отслеживать каждую последовательность отдельно.
- Задерживайте ответы на фиксированное время или задавайте каждому запросу разную задержку с помощью `random`, `normal` или `jitter`.
- Стройте ответы из значений пути, строки запроса, заголовков и тела, с генераторами для динамических данных.
- Проверяйте количество вызовов с помощью `@expect` или просматривайте полученный трафик из RestermScript.
- Горячая перезагрузка исходных файлов и фикстур, с опциональным TLS.

Два сценария на одном маршруте:```http
### Payment accepted
# @mock method=POST path=/payments name=accepted default=true latency=150ms
HTTP/1.1 202 Accepted
Content-Type: application/json

{"id":"pay_123","status":"pending"}

### Payment declined
# @mock method=POST path=/payments name=declined
# @match query={"mode":"decline"} headers={"X-Tenant":"demo"} json={"amount":0}
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{"error":"amount must be positive"}

Подать один файл или целую директорию:```bash resterm mock ./requests.http resterm mock --recursive --addr 127.0.0.1:9090 ./requests

Больше в [справочнике Mock Servers](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#mock-servers), [руководстве по CLI `resterm mock`](https://github.com/unkn0wn-root/resterm/blob/main/docs/cli.md#resterm-mock) и [рабочем примере](https://github.com/unkn0wn-root/resterm/blob/main/_examples/mocks.http).

## Headless

Пакет [`headless`](https://github.com/unkn0wn-root/resterm/blob/main/headless) — это публичный Go API для того же движка, который обеспечивает работу TUI и CLI. Используйте его для запуска запросов, рабочих процессов, проверок, сравнения запусков и профилей из собственного кода Go или CI.

Если вы не хотите собирать раннер самостоятельно, существует [resterm-runner](https://github.com/unkn0wn-root/resterm-runner).

## Коллекции

Экспортируйте рабочее пространство как удобный для Git пакет и импортируйте его в другое. Пакеты содержат `manifest.json` с контрольными суммами, поэтому при импорте сначала проверяется целостность файлов. Значения окружения экспортируются как заполнители `REPLACE_ME`, поэтому секреты никогда не покидают вашу машину.```bash
resterm collection export --workspace ./my-api --out ./shared/my-api-bundle
resterm collection import --in ./shared/my-api-bundle --workspace ./my-local-api

Добавьте --dry-run для предварительного просмотра импорта и --force для перезаписи существующих файлов. Документация: общий доступ к коллекциям.

Импорт из curl

Вставьте команду curl в редактор и нажмите Ctrl+Enter, чтобы превратить её в структурированный запрос. Resterm понимает распространённые флаги, объединяет повторяющиеся сегменты данных и сохраняет multipart-загрузки нетронутыми. Префиксы оболочки, такие как sudo или $, игнорируются. CLI выполняет то же преобразование с помощью --from-curl.

Это:```bash curl -X POST https://api.example.com/login
-H "Content-Type: application/json"
--user demo:secret
-d '{"user":"demo"}'

становится этим:```http
### POST https://api.example.com/login
# @auth basic demo secret
POST https://api.example.com/login
Content-Type: application/json

{"user":"demo"}

Документация: inline-запросы и примеры импорта.

RestermScript

RestermScript (RTS) — это небольшой язык выражений, созданный для Resterm. Он напрямую работает с форматом запросов, рабочими процессами и директивами, что делает скрипты короткими и предсказуемыми. JavaScript-хуки остаются доступными, когда вам нужно больше возможностей.

Краткий пример (модуль RTS + запрос):```rts // rts/helpers.rts module helpers export fn authHeader(token) { return token ? "Bearer " + token : "" }

🛡️ Защита

  • Безопасность по умолчанию: Все конечные точки API защищены с помощью JWT-аутентификации, а пароли хэшируются с использованием bcrypt.
  • Контроль доступа на основе ролей (RBAC): Администраторы, аналитики и пользователи имеют разные уровни доступа.
  • Шифрование: Чувствительные данные шифруются в состоянии покоя с использованием AES-256.
  • Аудит-логи: Все действия пользователей и системные события записываются в неизменяемые журналы аудита.
  • Регулярные обновления безопасности: Зависимости автоматически проверяются на наличие уязвимостей с помощью Dependabot и Snyk.

📚 Документация

Полная документация доступна в Wiki:

🤝 Вклад

Мы приветствуем вклад сообщества! Пожалуйста, ознакомьтесь с нашим Руководством по вкладу перед отправкой pull request.

Процесс разработки

  1. Форкните репозиторий
  2. Создайте ветку для функции (git checkout -b feature/AmazingFeature)
  3. Зафиксируйте изменения (git commit -m 'Add some AmazingFeature')
  4. Отправьте изменения в ветку (git push origin feature/AmazingFeature)
  5. Откройте pull request

📄 Лицензия

Этот проект распространяется под лицензией MIT — подробности см. в файле LICENSE.

📬 Контакты

Ваше Имя - @yourtwitter - [email protected]

Ссылка на проект: https://github.com/yourusername/yourproject

🙏 Благодарности

# @use ./rts/helpers.rts
# @when env.has("feature")
# @assert response.statusCode == 200
GET https://api.example.com/users/{{= vars.get("user") }}
Authorization: {{= helpers.authHeader(vars.get("auth.token")) }}
```
Полная ссылка: [`docs/restermscript.md`](https://github.com/unkn0wn-root/resterm/blob/main/docs/restermscript.md).

## Подробный разбор

### OAuth 2.0

Используйте `@auth oauth2` для получения и внедрения токенов. Токены кэшируются для каждого окружения и обновляются, когда это возможно. По умолчанию используется предоставление учетных данных клиента. Также поддерживаются предоставление по паролю и код авторизации с PKCE:```http
### Service status
# @auth oauth2 token_url={{oauth.tokenUrl}} client_id={{oauth.clientId}} client_secret={{oauth.clientSecret}} cache_key=my-api
GET {{base.url}}/anything/projects
```
Пример: [`_examples/oauth2.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/oauth2.http). См. [документацию по OAuth 2.0](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#oauth-20-directive).

### Рабочие процессы и скрипты

Рабочие процессы объединяют именованные запросы в цепочку и могут выбирать следующий шаг на основе ответа:```http
### Sign in
# @workflow sign-in
# @step Login using=Login
// GetProfile and RefreshToken are request names.
// The first true condition runs the named request.
# @if last.statusCode == 200 run=GetProfile
# @elif last.statusCode == 401 run=RefreshToken
# @else fail="unexpected login response"
```
Они также могут передавать данные между шагами и выполнять хуки RestermScript или JavaScript. Пример: [`_examples/workflows.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/workflows.http). См. [документацию по рабочим процессам](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#workflows).

### Опрос и повторные попытки

Используйте `@poll`, чтобы повторять запрос до тех пор, пока условие ответа не станет истинным. Добавьте `@retry`, чтобы повторять сетевые сбои, тайм-ауты или выбранные ответы с экспоненциальной задержкой:```http
### Wait for job
# @retry count=4
# @retry-when response.statusCode in [429, 502, 503]
# @retry-backoff exponential(100ms, 2s) jitter=20%
# @poll every=500ms timeout=30s until=response.json().status == "completed"
GET {{base.url}}/jobs/{{job.id}}
```
Каждый цикл опроса получает собственный бюджет повторных попыток. Пример: [`_examples/polling-retries.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/polling-retries.http). См. [документацию по опросу и повторным попыткам](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#polling-and-retries).

### Сравнение запусков

`@compare` выполняет один запрос как минимум в двух окружениях и использует один результат в качестве базового:```http
### Compare health
# @compare dev stage prod base=prod
GET {{services.api.base}}/status
```
Нажмите `g+c`, чтобы запустить его в TUI, или укажите `--compare` в командной строке. Пример: [`_examples/compare.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/compare.http). См. [документацию по сравнению](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#compare-runs).

### Трассировка и временная шкала

`@trace` записывает фазы HTTP и может помечать запросы, превышающие бюджет задержки:```http
### Trace API
# @trace dns<=50ms connect<=120ms total<=400ms tolerance=25ms
GET https://api.example.com/health
```
Результаты появляются на вкладке Timeline и могут быть экспортированы в OpenTelemetry. Пример: [`_examples/trace.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/trace.http). См. [документацию по трассировке](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#timeline--tracing).

### Потоковая передача (WebSocket и SSE)

`@sse` записывает события сервера, а `@websocket` и `@ws` обрабатывают WebSocket-кадры. Оба создают транскрипты на вкладке Stream:```http
### Events
# @sse duration=30s idle=10s max-events=5
GET https://api.example.com/events

### Chat
# @websocket idle=3s
# @ws send Hello
# @ws close 1000 done
GET wss://api.example.com/chat
```
Пример: [`_examples/streaming.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/streaming.http). См. [документацию по потоковой передаче](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#streaming-sse--websocket).

### gRPC

Используйте строку запроса `GRPC` для сервера и `@grpc` для полного имени метода. Тело запроса — это protobuf JSON:```http
### Get user
# @grpc users.UserService/GetUser
# @grpc-plaintext true
GRPC {{grpc.host}}

{"tenantId":"{{tenant.id}}"}
```
Отражение сервера включено по умолчанию. Наборы дескрипторов и потоковые вызовы также поддерживаются. Пример: [`_examples/grpc.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/grpc.http). См. [документацию по gRPC](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#grpc).

### Импорт OpenAPI

Генерируйте запросы, моки или и то, и другое из локального документа OpenAPI или `http(s)`-URL:```bash
resterm --from-openapi _examples/openapi-spec.yml --http-out api.http --openapi-mode both
```
Удалённые загрузки учитывают `--insecure` и `--proxy`. Пример входных данных: [`_examples/openapi-spec.yml`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/openapi-spec.yml). См. [документацию по импорту](https://github.com/unkn0wn-root/resterm/blob/main/docs/cli.md#import-examples).

### SSH-туннели

Определите SSH-профиль перед запросами, которые его используют, затем выберите его с помощью `use=`:```http
// Set key to choose a key file. Leave it out to use your SSH agent or a default key.
# @ssh file edge host=jump.example.com user=ops key=~/.ssh/id_ed25519

### Internal API
# @ssh use=edge
GET http://10.0.0.10/v1/health
```
Профили могут быть файловыми или рабочей области, а также поддерживаются разовые встроенные туннели. Пример: [`_examples/ssh.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/ssh.http). См. [документацию по SSH](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#ssh-tunnels).

### Проброс портов Kubernetes

`@k8s` открывает управляемый проброс портов к поду, сервису, развёртыванию или statefulset:```http
### Service health
# @k8s namespace=default service=api port=http
GET http://api.default.svc.cluster.local/health
```
Цели могут использовать числовые или именованные порты и могут сохраняться как переиспользуемые профили. Пример: [`_examples/k8s.http`](https://github.com/unkn0wn-root/resterm/blob/main/_examples/k8s.http). См. [документацию Kubernetes](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#kubernetes-port-forwards).

### Темы и привязки клавиш

Настройте цвета и привязки клавиш с помощью `themes/*.toml` и `bindings.toml` или `bindings.json` в каталоге конфигурации. Документация: [`docs/resterm.md#theming`](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#theming) и [`docs/resterm.md#custom-bindings`](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#custom-bindings).

## Документация

- [`docs/resterm.md`](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md) охватывает синтаксис запросов, директивы, скрипты и транспорты.
- [`docs/cli.md`](https://github.com/unkn0wn-root/resterm/blob/main/docs/cli.md) охватывает `resterm run`, импортёры, коллекции и историю.
- [Совместимость](https://github.com/unkn0wn-root/resterm/blob/main/docs/resterm.md#compatibility) объясняет гарантии совместимости Resterm для v1.

Внутри TUI нажмите `?` или выполните `:help`. Используйте `:docs`, когда вам нужно полное веб-руководство для установленной версии.

## Лицензия

[Apache License 2.0](https://github.com/unkn0wn-root/resterm/blob/main/LICENSE).

Категории