# assh [![CI](https://github.com/izzzzzi/agent-assh/actions/workflows/ci.yml/badge.svg)](https://github.com/izzzzzi/agent-assh/actions/workflows/ci.yml) [![GitHub Release](https://img.shields.io/github/v/release/izzzzzi/agent-assh)](https://github.com/izzzzzi/agent-assh/releases) [![npm](https://img.shields.io/npm/v/agent-assh)](https://www.npmjs.com/package/agent-assh) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) Язык: Русский | [English](README.en.md) SSH-инструмент для LLM-агентов. `assh` подготавливает SSH-доступ, открывает persistent `tmux`-сессию на сервере и не тащит большой вывод в контекст агента. Команды сначала возвращают компактный JSON с метаданными, а агент читает только нужные строки.

assh architecture

## Быстрый старт ```bash npm i -g agent-assh assh version --check # проверить обновления export TARGET_PASS="..." assh connect -H 203.0.113.10 -u root -E TARGET_PASS -n deploy unset TARGET_PASS ``` Если вход по ключу уже работает, `assh connect` не читает `TARGET_PASS`. ```bash assh connect -H 203.0.113.10 -u root -i ~/.ssh/id_agent_ed25519 -n deploy ``` Если есть блок с данными сервера от провайдера, сохраните его в локальный файл и дайте `assh` распарсить его: ```bash assh connect-info --file server.txt -n deploy ``` `connect` возвращает session id и `next_commands`: ```json { "ok": true, "sid": "f7a2b3c4", "session": "deploy", "tmux_name": "assh_f7a2b3c4", "next_commands": { "exec": "assh session exec -s f7a2b3c4 -- \"pwd\"", "read": "assh session read -s f7a2b3c4 --seq 1 --limit 50", "close": "assh session close -s f7a2b3c4" } } ``` Дальше работайте через session API: ```bash assh session exec -s f7a2b3c4 -- "pwd" assh session read -s f7a2b3c4 --seq 1 --limit 50 assh session close -s f7a2b3c4 ``` ## Установка скилла assh в AI-агентов Скилл assh обучает AI-агентов правильно использовать assh для SSH-работы. После установки агент автоматически использует assh для всех SSH-задач. | Агент | Установка | | --- | --- | | **Claude Code** | `/plugin marketplace add izzzzzi/agent-assh` затем `/plugin install assh@assh` | | **Codex** | `codex plugin marketplace add izzzzzi/agent-assh` | | **Cursor** | Скопировать `.cursor/rules/assh.mdc` в `.cursor/rules/` проекта | | **Cline** | Скопировать `.clinerules/assh.md` в корень проекта | | **Copilot CLI** | `copilot plugin marketplace add izzzzzi/agent-assh` затем `copilot plugin install assh@assh` | | **OpenCode** | Добавить `"plugin": ["./.opencode/plugins/assh.mjs"]` в `opencode.json` | | **Pi** | `pi install git:github.com/izzzzzi/agent-assh` | | **Любой агент** | Файл `AGENTS.md` в корне репозитория — универсальная инструкция для всех агентов | Через `ctx7`: ```bash ctx7 skills install /izzzzzi/agent-assh assh ``` ## Что делает connect `assh connect`: - создаёт или переиспользует `~/.ssh/id_agent_ed25519`, если не указан `--identity`; - сначала пробует вход по ключу; - использует `--password-env` только если вход по ключу не сработал; - добавляет публичный ключ и проверяет повторный вход по ключу; - проверяет capabilities сервера; - ставит `tmux` неинтерактивно, если не указан `--no-install-tmux`; - безопасно чистит старые доверенные `assh`-сессии, если не указан `--no-gc`; - открывает доверенную `tmux`-сессию и сохраняет локальную registry metadata. ## Команды - `assh connect`: первый bootstrap и открытие session. - `assh connect-info`: распарсить provider server-info block и подключиться. - `assh session exec|read|close|gc`: persistent workflow через tmux. - `assh session ps|kill`: управление процессами. - `assh session service`: управление сервисами (status/restart/start/stop/logs). - `assh session exec-async|job-status|job-cancel`: фоновые задачи. - `assh session watch`: наблюдение за tmux-сессией агента человеком. - `assh exec`: выполнить одну remote-команду и сохранить вывод локально. - `assh read`: прочитать сохранённый вывод с пагинацией или через `--raw`. - `assh transfer put|get|read|list|stat|mkdir|rm|mv|sync`: файловые операции и синхронизация. `transfer read` читает удалённый текстовый файл по ssh и возвращает `output_id` для постраничного `assh read`. - `assh forward`: port forwarding (start/status/stop). - `assh fleet exec`: параллельное выполнение на нескольких хостах. - `assh scan`: вернуть JSON-инвентарь хоста (OS, CPU, память, диск, uptime). - `assh capabilities`: проверить поддержку session workflow на сервере. - `assh key-deploy`: низкоуровневая установка ключа через пароль из env. - `assh audit`: читать локальный audit через `--last`, `--host`, `--failed`. - `assh version`: вывести метаданные версии. ## Экономия токенов Сначала смотрите метаданные, потом читайте нужные окна вывода: ```bash assh session exec -s f7a2b3c4 -- "journalctl -p warning" assh session read -s f7a2b3c4 --seq 1 --limit 50 assh session read -s f7a2b3c4 --seq 1 --stream stderr --limit 50 ``` `--raw` используйте только для пайпов или точного вывода: ```bash assh session read -s f7a2b3c4 --seq 1 --raw ``` `assh audit --savings` показывает, сколько строк вывода было удержано из контекста пагинацией (метрика в строках, не в токенах): ```bash assh audit --savings # {"ok":true,"reads":12,"raw_lines":5000,"served_lines":600,"withheld_lines":4400} ``` ## Примеры для agent CLI Вставьте эту инструкцию в Codex, Claude Code, OpenCode или другой terminal agent перед передачей SSH-данных: ```text Используй `assh` для SSH-задач. Если я вставляю provider server-info block, сохрани весь блок во временный файл с mode 0600, выполни: assh connect-info --file TMP -n NAME затем удали TMP. Если `connect-info` не смог распарсить блок, извлеки host, user и password сам. Пароль положи во временную environment variable и выполни: assh connect -H HOST -u USER -E PASSWORD_ENV -n NAME затем удали переменную. Никогда не печатай, не логируй, не пересказывай и не повторяй пароли. Для всей remote-работы используй возвращенный sid и `next_commands`. ``` Короткие варианты для популярных CLI: ```text Codex: Используй `assh` для всего SSH-доступа. Для вставленного server info сначала пробуй `assh connect-info --file TMP -n NAME`; не передавай секреты в command arguments и ответы. ``` ```text Claude Code: Перед SSH-работой установи/запусти `assh`. Если вставлены server credentials, сохрани их в 0600 temp file, выполни `assh connect-info --file TMP -n NAME`, удали файл и продолжай через returned sid. ``` ```text OpenCode: Используй `assh connect-info` для provider server-info blocks и `assh session exec/read` после connect. Никогда не echo пароли. ``` ## Безопасность - Пароли принимаются только через env-переменные. Флага `--password` нет. - Вывод по умолчанию проходит редактирование секретов (AWS-ключи, JWT, bearer-токены, PEM-ключи, присваивания `password=`/`token=`) → `[REDACTED:type]`, в JSON появляется `"redacted":true`. Это гигиена по лучшему усилию, **не** механизм безопасности. Отключается флагом `--no-redact`. - Деклеративная политика безопасности: операторы могут добавить запрещённые команды в `~/.config/assh/safety.rules` (по одному имени команды в строке). Файл только **добавляет** запреты и не ослабляет встроенные правила; требует mode `0600`, иначе fail-closed (`safety_policy_invalid`). - `connect-info` читает пароли только из stdin или локального файла, но не из command arguments. - Если вход по ключу работает, `connect` не читает password env var. - Значения паролей не пишутся в audit logs. - Текст команд не пишется в audit logs; сохраняются hashes. - SSH запускается неинтерактивно и отключает pseudo-terminal allocation. - `--host-key-policy accept-new` используется по умолчанию. Для hardened окружений используйте `strict`. - `--host-key-policy no-check` небезопасен и подходит только для одноразовых lab/dev хостов. - `session exec` блокирует явно destructive-команды вроде `rm -rf`, `find ... -delete`, `mkfs`, `wipefs`, опасный `dd` и recursive permission changes; для намеренного запуска нужен `--confirm-danger`. - Remote cleanup удаляет только sessions с доверенной metadata `assh`. ## Плюсы - Одна команда делает первый вход, ключ, tmux, cleanup и открытие session. - ControlMaster connection pooling — повторные вызовы переиспользуют SSH-сокет. - Большой вывод не попадает в контекст агента без явного чтения. - Persistent sessions сохраняют рабочую директорию и окружение между командами. - JSON-ответы стабильны для парсинга агентом. - Встроенная проверка безопасности команд (safety classifier). - Фоновые задачи через tmux (exec-async). ## Ограничения - `tmux` sessions рассчитаны на Unix-like remote hosts. - Установка пакетов неинтерактивная; неподдерживаемые package managers возвращают machine-readable errors. - Интерактивные password prompts не поддерживаются в v1. - `assh` использует системный OpenSSH client. - `session exec` не пробрасывает локальный stdin в команду. Команды отправляются в remote `tmux`-окно через неинтерактивный ssh, поэтому piping вроде `cat f | assh session exec -s SID -- "docker exec -i ... cat >f"` данные теряет, а tmux-окно зависает в ожидании ввода. При детекции piped-stdin возвращается `{"ok":false,"error":"stdin_pipe_unsupported",...}` с подсказкой использовать `transfer put` или временный файл. Для разовых команд с stdin используйте `assh exec`. ## Ручная установка `npm i -g agent-assh` ставит wrapper, который скачивает подходящий Go-бинарь из GitHub Releases. Архивы можно скачать вручную: ```text https://github.com/izzzzzi/agent-assh/releases ``` ## English See [README.en.md](README.en.md).