agent-assh 1.0.1 → 1.1.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.
@@ -0,0 +1,198 @@
1
+ # assh Agent Instructions
2
+
3
+ `assh` is the SSH workflow helper for LLM agents. Start with `assh connect` so access, key setup, tmux, cleanup, and the first persistent session are prepared in one step.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i -g agent-assh
9
+ assh version
10
+ ```
11
+
12
+ ## First SSH Step
13
+
14
+ Prefer `assh connect --ssh-config ALIAS` for hosts already in `~/.ssh/config`.
15
+
16
+ If the user pasted a provider server-info block, write the block to a temporary file with mode `0600`, run:
17
+
18
+ ```bash
19
+ assh connect-info --file /path/to/tmp-server-info -n NAME
20
+ ```
21
+
22
+ Then delete the temporary file. Server-info formats vary; if parsing fails, extract host, user, and password yourself, put the password in an environment variable, and use `assh connect -E PASSWORD_ENV`.
23
+
24
+ If first-contact password access may be needed:
25
+
26
+ ```bash
27
+ assh connect -H HOST -u root -E PASSWORD_ENV -n NAME
28
+ ```
29
+
30
+ If key login is already configured:
31
+
32
+ ```bash
33
+ assh connect -H HOST -u root -i ~/.ssh/id_agent_ed25519 -n NAME
34
+ ```
35
+
36
+ If host is in `~/.ssh/config`:
37
+
38
+ ```bash
39
+ assh connect --ssh-config my-alias -n NAME
40
+ ```
41
+
42
+ Use the returned `sid` and `next_commands`.
43
+
44
+ ## Normal Workflow
45
+
46
+ ```bash
47
+ assh session exec -s SID -- "pwd"
48
+ assh session read -s SID --seq 1 --limit 50
49
+ assh session exec -s SID --timeout 600 -- "git pull"
50
+ assh session read -s SID --seq 2 --stream stderr --limit 50
51
+ assh session close -s SID
52
+ ```
53
+
54
+ Pre/post hooks:
55
+
56
+ ```bash
57
+ assh session exec -s SID --before "git stash" --after "git stash pop" -- "deploy.sh"
58
+ ```
59
+
60
+ Clean up stale trusted sessions:
61
+
62
+ ```bash
63
+ assh session gc --older-than 24h --execute
64
+ ```
65
+
66
+ ## One-Off Commands
67
+
68
+ Use `exec/read` when no persistent directory or environment is needed:
69
+
70
+ ```bash
71
+ assh exec -H HOST -u root -i KEY -- "df -h"
72
+ assh read --id OUTPUT_ID --limit 50
73
+ ```
74
+
75
+ ## Host Scanning
76
+
77
+ ```bash
78
+ assh scan -H HOST -u USER
79
+ # Returns JSON with hostname, OS, kernel, arch, CPU cores, IP, uptime, load, memory, disk
80
+ ```
81
+
82
+ ## File Operations
83
+
84
+ ```bash
85
+ assh transfer list -H HOST -u USER --path /var/log
86
+ assh transfer stat -H HOST -u USER --path /etc/nginx.conf
87
+ assh transfer put -H HOST -u USER LOCAL_PATH REMOTE_PATH
88
+ assh transfer get -H HOST -u USER REMOTE_PATH LOCAL_PATH
89
+ assh transfer sync --direction push --source ./dist --dest /var/www -H HOST -u USER
90
+ assh transfer sync --direction pull --source /var/log --dest ./logs -H HOST -u USER
91
+ assh transfer mkdir -H HOST -u USER --path /opt/newapp
92
+ assh transfer rm -H HOST -u USER --path /tmp/junk.log
93
+ assh transfer rm -H HOST -u USER --path /tmp/old --recursive
94
+ assh transfer mv -H HOST -u USER --source /tmp/a --dest /tmp/b
95
+ ```
96
+
97
+ ## Process Management
98
+
99
+ ```bash
100
+ assh session ps -s SID --top 20
101
+ assh session ps -s SID --filter nginx
102
+ assh session kill -s SID --pid 1234
103
+ assh session kill -s SID --pid 1234 --signal KILL
104
+ ```
105
+
106
+ ## Service Management
107
+
108
+ ```bash
109
+ assh session service -s SID --action status --service nginx
110
+ assh session service -s SID --action restart --service docker
111
+ assh session service -s SID --action start --service postgresql
112
+ assh session service -s SID --action stop --service apache2
113
+ assh session service -s SID --action logs --service nginx --lines 100
114
+ ```
115
+
116
+ ## Background Jobs
117
+
118
+ For long-running commands (builds, deployments):
119
+
120
+ ```bash
121
+ assh session exec-async -s SID -- "make build"
122
+ # Returns job_id for tracking
123
+ assh session job-status -s SID --job-id JOB_ID
124
+ assh session job-cancel -s SID --job-id JOB_ID
125
+ ```
126
+
127
+ ## Docker Management
128
+
129
+ ```bash
130
+ assh session docker-ps -s SID
131
+ assh session docker-ps -s SID -a # all containers including stopped
132
+ assh session docker-logs -s SID --container myapp --tail 100
133
+ assh session docker-exec -s SID --container myapp -- "ls -la /app"
134
+ ```
135
+
136
+ ## Database Query (Read-Only)
137
+
138
+ Only SELECT, SHOW, DESCRIBE, and EXPLAIN queries are allowed for safety:
139
+
140
+ ```bash
141
+ assh session db-query -s SID --type mysql -d mydb -q "SELECT COUNT(*) FROM users"
142
+ assh session db-query -s SID --type postgres -d mydb -q "SELECT * FROM orders LIMIT 10"
143
+ assh session db-query -s SID --type mysql -d mydb -U dbuser -W dbpass -q "SHOW TABLES"
144
+ ```
145
+
146
+ ## Fleet (Multi-Host)
147
+
148
+ Execute the same command across multiple hosts in parallel:
149
+
150
+ ```bash
151
+ assh fleet exec -H host1 -H host2 -H host3 -u root -- "uptime"
152
+ assh fleet exec -H web01 -H web02 -u deploy -i ~/.ssh/id_ed25519 -- "df -h"
153
+ ```
154
+
155
+ ## Session Observability
156
+
157
+ Watch what the agent is doing in real-time:
158
+
159
+ ```bash
160
+ assh session watch -s SID
161
+ # Returns an attach_cmd — paste it in a terminal to attach to the agent's tmux
162
+ ```
163
+
164
+ ## MCP Server (for Claude Code, Cursor, Windsurf)
165
+
166
+ Start as an MCP stdio server so agents can call assh as MCP tools:
167
+
168
+ ```bash
169
+ assh mcp serve
170
+ # Wire into Claude Code: claude mcp add assh -- assh mcp serve
171
+ ```
172
+
173
+ ## JSON Rules
174
+
175
+ - Operational commands emit one JSON value by default.
176
+ - Errors use `{"ok":false,"error":"code","message":"..."}`.
177
+ - `session exec` responses include `rc`, `seq`, `stdout_lines`, `stderr_lines`, `sid`, and `session`.
178
+ - Remote non-zero exit status is a command result, not a transport failure.
179
+
180
+ ## Context Discipline
181
+
182
+ If `stdout_lines` or `stderr_lines` is large, do not read all output. Use targeted windows with `--limit`, `--offset`, and `--stream`. Use `read --raw` or `session read --raw` only when piping or exact output is required.
183
+
184
+ ## Security Rules
185
+
186
+ - Never put passwords in command arguments.
187
+ - Passwords are passed only through env vars named by `--password-env`.
188
+ - For pasted server-info blocks, prefer `connect-info --file`; remove the temporary file after connect.
189
+ - If key login works, `connect` does not read the password env var.
190
+ - Prefer `--host-key-policy strict` when host keys are already managed.
191
+ - Treat `--host-key-policy no-check` as unsafe and only for disposable lab/dev hosts.
192
+ - If `session exec` returns `dangerous_command_requires_confirmation`, do not add `--confirm-danger` unless the user explicitly intended the destructive action.
193
+ - `db-query` is read-only by design — write operations are blocked with a safety error.
194
+ - Use `assh session watch` to observe agent actions in real-time.
195
+
196
+ ## Connection Pooling (Automatic)
197
+
198
+ `assh` uses SSH ControlMaster to multiplex connections to the same host. The first `connect` or `session exec` opens a master connection; subsequent commands reuse it. Control sockets live in `~/.ssh/controlmasters/` with a 5-minute idle timeout. No configuration needed — this is automatic.
package/README.en.md CHANGED
@@ -11,6 +11,10 @@ SSH workflow helper for LLM agents.
11
11
 
12
12
  `assh` bootstraps SSH access, opens a persistent remote `tmux` session, and keeps large SSH output out of the agent context. Commands return compact JSON metadata first; agents read only the lines they need.
13
13
 
14
+ <p align="center">
15
+ <img src="docs/assh-architecture.png" alt="assh architecture" width="800">
16
+ </p>
17
+
14
18
  ## Quick Start
15
19
 
16
20
  ```bash
@@ -75,12 +79,22 @@ assh session close -s f7a2b3c4
75
79
  - `assh connect`: first-contact bootstrap and session open.
76
80
  - `assh connect-info`: parse a pasted provider server-info block and connect.
77
81
  - `assh session exec|read|close|gc`: persistent tmux workflow.
82
+ - `assh session ps|kill`: process management.
83
+ - `assh session service`: service management (status/restart/start/stop/logs).
84
+ - `assh session exec-async|job-status|job-cancel`: background jobs.
85
+ - `assh session docker-ps|docker-logs|docker-exec`: Docker management.
86
+ - `assh session db-query`: read-only MySQL/PostgreSQL queries.
87
+ - `assh session watch`: human observability into the agent's tmux session.
78
88
  - `assh exec`: run one remote command and store output locally.
79
89
  - `assh read`: read stored output with pagination or `--raw`.
90
+ - `assh transfer put|get|list|stat|mkdir|rm|mv|sync`: file ops and sync.
91
+ - `assh forward`: port forwarding (start/status/stop).
92
+ - `assh fleet exec`: parallel execution across multiple hosts.
93
+ - `assh scan`: return host inventory JSON (OS, CPU, memory, disk, uptime).
80
94
  - `assh capabilities`: inspect remote session support.
81
- - `assh scan`: return host inventory JSON.
82
95
  - `assh key-deploy`: low-level key deployment using a password from env.
83
96
  - `assh audit`: read local audit events with `--last`, `--host`, and `--failed`.
97
+ - `assh mcp serve`: start MCP stdio server for Claude Code/Cursor/Windsurf.
84
98
  - `assh version`: print version metadata.
85
99
 
86
100
  ## Token Economy
@@ -141,14 +155,20 @@ OpenCode: Use `assh connect-info` for provider server-info blocks and `assh sess
141
155
  - SSH runs non-interactively and disables pseudo-terminal allocation.
142
156
  - `--host-key-policy accept-new` is the default. Use `strict` for hardened environments.
143
157
  - `--host-key-policy no-check` is unsafe and should be limited to disposable lab/dev hosts.
158
+ - `session exec` blocks clearly destructive commands such as `rm -rf`, `find ... -delete`, `mkfs`, `wipefs`, dangerous `dd`, and recursive permission changes; intentional runs require `--confirm-danger`.
144
159
  - Remote cleanup only targets sessions with trusted `assh` metadata.
145
160
 
146
161
  ## Advantages
147
162
 
148
163
  - One command handles first login, key setup, tmux readiness, cleanup, and session open.
164
+ - ControlMaster connection pooling — repeat calls reuse the SSH socket.
149
165
  - Large output stays outside the agent context until explicitly paged in.
150
166
  - Persistent sessions preserve working directory and environment between commands.
151
167
  - JSON responses are stable for agent parsing.
168
+ - Built-in command safety classifier blocks destructive operations.
169
+ - Background jobs via tmux (exec-async).
170
+ - Read-only database queries with write protection.
171
+ - MCP server for Claude Code, Cursor, Windsurf.
152
172
 
153
173
  ## Limitations
154
174
 
package/README.md CHANGED
@@ -11,6 +11,10 @@ SSH-инструмент для LLM-агентов.
11
11
 
12
12
  `assh` подготавливает SSH-доступ, открывает persistent `tmux`-сессию на сервере и не тащит большой вывод в контекст агента. Команды сначала возвращают компактный JSON с метаданными, а агент читает только нужные строки.
13
13
 
14
+ <p align="center">
15
+ <img src="docs/assh-architecture.png" alt="assh architecture" width="800">
16
+ </p>
17
+
14
18
  ## Быстрый старт
15
19
 
16
20
  ```bash
@@ -75,12 +79,22 @@ assh session close -s f7a2b3c4
75
79
  - `assh connect`: первый bootstrap и открытие session.
76
80
  - `assh connect-info`: распарсить provider server-info block и подключиться.
77
81
  - `assh session exec|read|close|gc`: persistent workflow через tmux.
82
+ - `assh session ps|kill`: управление процессами.
83
+ - `assh session service`: управление сервисами (status/restart/start/stop/logs).
84
+ - `assh session exec-async|job-status|job-cancel`: фоновые задачи.
85
+ - `assh session docker-ps|docker-logs|docker-exec`: управление Docker.
86
+ - `assh session db-query`: read-only запросы к MySQL/PostgreSQL.
87
+ - `assh session watch`: наблюдение за tmux-сессией агента человеком.
78
88
  - `assh exec`: выполнить одну remote-команду и сохранить вывод локально.
79
89
  - `assh read`: прочитать сохранённый вывод с пагинацией или через `--raw`.
90
+ - `assh transfer put|get|list|stat|mkdir|rm|mv|sync`: файловые операции и синхронизация.
91
+ - `assh forward`: port forwarding (start/status/stop).
92
+ - `assh fleet exec`: параллельное выполнение на нескольких хостах.
93
+ - `assh scan`: вернуть JSON-инвентарь хоста (OS, CPU, память, диск, uptime).
80
94
  - `assh capabilities`: проверить поддержку session workflow на сервере.
81
- - `assh scan`: вернуть JSON-инвентарь хоста.
82
95
  - `assh key-deploy`: низкоуровневая установка ключа через пароль из env.
83
96
  - `assh audit`: читать локальный audit через `--last`, `--host`, `--failed`.
97
+ - `assh mcp serve`: запустить MCP stdio сервер для Claude Code/Cursor/Windsurf.
84
98
  - `assh version`: вывести метаданные версии.
85
99
 
86
100
  ## Экономия токенов
@@ -141,14 +155,20 @@ OpenCode: Используй `assh connect-info` для provider server-info blo
141
155
  - SSH запускается неинтерактивно и отключает pseudo-terminal allocation.
142
156
  - `--host-key-policy accept-new` используется по умолчанию. Для hardened окружений используйте `strict`.
143
157
  - `--host-key-policy no-check` небезопасен и подходит только для одноразовых lab/dev хостов.
158
+ - `session exec` блокирует явно destructive-команды вроде `rm -rf`, `find ... -delete`, `mkfs`, `wipefs`, опасный `dd` и recursive permission changes; для намеренного запуска нужен `--confirm-danger`.
144
159
  - Remote cleanup удаляет только sessions с доверенной metadata `assh`.
145
160
 
146
161
  ## Плюсы
147
162
 
148
163
  - Одна команда делает первый вход, ключ, tmux, cleanup и открытие session.
164
+ - ControlMaster connection pooling — повторные вызовы переиспользуют SSH-сокет.
149
165
  - Большой вывод не попадает в контекст агента без явного чтения.
150
166
  - Persistent sessions сохраняют рабочую директорию и окружение между командами.
151
167
  - JSON-ответы стабильны для парсинга агентом.
168
+ - Встроенная проверка безопасности команд (safety classifier).
169
+ - Фоновые задачи через tmux (exec-async).
170
+ - Read-only database queries с защитой от записи.
171
+ - MCP-сервер для Claude Code, Cursor, Windsurf.
152
172
 
153
173
  ## Ограничения
154
174
 
@@ -0,0 +1,122 @@
1
+ ## assh SSH Workflow
2
+
3
+ Use `assh` for SSH work so large remote output stays out of the agent context.
4
+
5
+ Install when missing:
6
+
7
+ ```bash
8
+ npm i -g agent-assh
9
+ assh version
10
+ ```
11
+
12
+ ### Agent Algorithm
13
+
14
+ ```text
15
+ Need SSH?
16
+ prefer assh connect --ssh-config ALIAS for hosts in ~/.ssh/config
17
+
18
+ If the user pasted provider server info:
19
+ save it to a 0600 temp file
20
+ assh connect-info --file TMP -n NAME
21
+ delete TMP after connect
22
+ if parsing fails, extract host/user/password, put password in env, then use connect
23
+
24
+ First step:
25
+ assh connect -H HOST -u root -E PASSWORD_ENV -n NAME
26
+ or, when key login already works:
27
+ assh connect -H HOST -u root -i KEY -n NAME
28
+ or, resolve from ~/.ssh/config:
29
+ assh connect --ssh-config my-alias -n NAME
30
+
31
+ Scan host health:
32
+ assh scan -H HOST -u USER
33
+
34
+ Continue with returned sid:
35
+ assh session exec -s SID -- "pwd"
36
+ assh session read -s SID --seq 1 --limit 50
37
+ assh session exec -s SID --timeout 600 -- "git pull"
38
+ assh session read -s SID --seq 2 --stream stderr --limit 50
39
+
40
+ File operations:
41
+ assh transfer list -H HOST -u USER --path /var/log
42
+ assh transfer stat -H HOST -u USER --path /etc/nginx.conf
43
+ assh transfer put -H HOST -u USER LOCAL_PATH REMOTE_PATH
44
+ assh transfer get -H HOST -u USER REMOTE_PATH LOCAL_PATH
45
+ assh transfer sync --direction push --source ./dist --dest /var/www -H HOST
46
+ assh transfer mkdir -H HOST -u USER --path /opt/newapp
47
+ assh transfer rm -H HOST -u USER --path /tmp/junk.log
48
+ assh transfer mv -H HOST -u USER --source /tmp/a --dest /tmp/b
49
+
50
+ Server management:
51
+ assh session ps -s SID --top 20
52
+ assh session kill -s SID --pid 1234
53
+ assh session service -s SID --action status --service nginx
54
+ assh session service -s SID --action restart --service docker
55
+ assh session service -s SID --action logs --service nginx --lines 100
56
+
57
+ Background jobs:
58
+ assh session exec-async -s SID -- "long-build.sh"
59
+ assh session job-status -s SID --job-id JOB_ID
60
+ assh session job-cancel -s SID --job-id JOB_ID
61
+
62
+ Docker:
63
+ assh session docker-ps -s SID
64
+ assh session docker-logs -s SID --container myapp
65
+ assh session docker-exec -s SID --container myapp -- "ls -la"
66
+
67
+ Database (read-only):
68
+ assh session db-query -s SID --type mysql -d mydb -q "SELECT COUNT(*) FROM users"
69
+
70
+ Fleet (multi-host):
71
+ assh fleet exec -H host1 -H host2 -H host3 -u root -- "uptime"
72
+
73
+ Pre/post hooks:
74
+ assh session exec -s SID --before "git stash" --after "git stash pop" -- "deploy.sh"
75
+
76
+ Watch agent session (human observability):
77
+ assh session watch -s SID
78
+ # Copy the attach_cmd to a terminal to see the agent's tmux in real-time.
79
+
80
+ Cleanup:
81
+ assh session gc --older-than 24h --execute
82
+
83
+ Audit:
84
+ assh audit --last 20 --host HOST --failed
85
+ ```
86
+
87
+ ### JSON Contract
88
+
89
+ `assh connect` returns a session id and next commands:
90
+
91
+ ```json
92
+ {"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"}}
93
+ ```
94
+
95
+ `assh session exec` returns command metadata:
96
+
97
+ ```json
98
+ {"ok":true,"rc":0,"seq":2,"stdout_lines":15,"stderr_lines":0,"sid":"f7a2b3c4","session":"deploy"}
99
+ ```
100
+
101
+ `assh scan` returns host inventory:
102
+
103
+ ```json
104
+ {"hostname":"web01","os":"Linux","kernel":"6.1.0","arch":"x86_64","cpu_cores":"4","ip":"10.0.0.1","uptime":"30 days","load":"0.15 0.10 0.05","mem_total_kb":"8176248","mem_avail_kb":"5241360","disk":"12G/50G (25%)"}
105
+ ```
106
+
107
+ `assh transfer list` returns file entries:
108
+
109
+ ```json
110
+ {"ok":true,"host":"web01","user":"root","path":"/var/log","count":5,"entries":[{"name":"syslog","type":"f","size":12345,"mtime":"2026-06-05T10:00:00Z"}]}
111
+ ```
112
+
113
+ Rules:
114
+
115
+ - Operational commands emit one JSON value by default.
116
+ - `read --raw` and `session read --raw` print only content.
117
+ - Remote non-zero status is a command result, not a transport failure.
118
+ - Passwords are only accepted through environment variables; never put passwords in command arguments.
119
+ - Command text is not written to audit logs.
120
+ - If `session exec` returns `dangerous_command_requires_confirmation`, ask for explicit user intent before rerunning with `--confirm-danger`.
121
+ - db-query is read-only — only SELECT/SHOW/DESCRIBE/EXPLAIN allowed.
122
+ - session watch shows a tmux attach command; the human opens a terminal to observe the agent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-assh",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "SSH workflow helper for LLM agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -34,6 +34,8 @@
34
34
  "scripts",
35
35
  "README.md",
36
36
  "README.en.md",
37
+ "AGENT_INSTRUCTIONS.md",
38
+ "SYSTEM_PROMPT_snippet.md",
37
39
  "LICENSE"
38
40
  ]
39
41
  }
@@ -8,8 +8,12 @@ const { target } = require('./platform');
8
8
  const { expectedArchives, verifyArtifactFiles } = require('./release-contract-test');
9
9
 
10
10
  const root = path.join(__dirname, '..');
11
+ const pkg = require(path.join(root, 'package.json'));
11
12
  const nativeDir = path.join(root, 'native');
12
13
 
14
+ assert.ok(pkg.files.includes('AGENT_INSTRUCTIONS.md'), 'package files must include AGENT_INSTRUCTIONS.md');
15
+ assert.ok(pkg.files.includes('SYSTEM_PROMPT_snippet.md'), 'package files must include SYSTEM_PROMPT_snippet.md');
16
+
13
17
  assert.deepEqual(target('linux', 'x64'), {
14
18
  os: 'linux',
15
19
  arch: 'amd64',