agent-assh 1.0.1 → 1.0.2

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,79 @@
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
+ If the user pasted a provider server-info block, write the block to a temporary file with mode `0600`, run:
15
+
16
+ ```bash
17
+ assh connect-info --file /path/to/tmp-server-info -n NAME
18
+ ```
19
+
20
+ 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`.
21
+
22
+ If first-contact password access may be needed:
23
+
24
+ ```bash
25
+ assh connect -H HOST -u root -E PASSWORD_ENV -n NAME
26
+ ```
27
+
28
+ If key login is already configured:
29
+
30
+ ```bash
31
+ assh connect -H HOST -u root -i ~/.ssh/id_agent_ed25519 -n NAME
32
+ ```
33
+
34
+ Use the returned `sid` and `next_commands`.
35
+
36
+ ## Normal Workflow
37
+
38
+ ```bash
39
+ assh session exec -s SID -- "pwd"
40
+ assh session read -s SID --seq 1 --limit 50
41
+ assh session exec -s SID --timeout 600 -- "git pull"
42
+ assh session read -s SID --seq 2 --stream stderr --limit 50
43
+ assh session close -s SID
44
+ ```
45
+
46
+ Clean up stale trusted sessions:
47
+
48
+ ```bash
49
+ assh session gc --older-than 24h --execute
50
+ ```
51
+
52
+ ## One-Off Commands
53
+
54
+ Use `exec/read` when no persistent directory or environment is needed:
55
+
56
+ ```bash
57
+ assh exec -H HOST -u root -i KEY -- "df -h"
58
+ assh read --id OUTPUT_ID --limit 50
59
+ ```
60
+
61
+ ## JSON Rules
62
+
63
+ - Operational commands emit one JSON value by default.
64
+ - Errors use `{"ok":false,"error":"code","message":"..."}`.
65
+ - `session exec` responses include `rc`, `seq`, `stdout_lines`, `stderr_lines`, `sid`, and `session`.
66
+ - Remote non-zero exit status is a command result, not a transport failure.
67
+
68
+ ## Context Discipline
69
+
70
+ 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.
71
+
72
+ ## Security Rules
73
+
74
+ - Never put passwords in command arguments.
75
+ - Passwords are passed only through env vars named by `--password-env`.
76
+ - For pasted server-info blocks, prefer `connect-info --file`; remove the temporary file after connect.
77
+ - If key login works, `connect` does not read the password env var.
78
+ - Prefer `--host-key-policy strict` when host keys are already managed.
79
+ - Treat `--host-key-policy no-check` as unsafe and only for disposable lab/dev hosts.
@@ -0,0 +1,61 @@
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
+ If the user pasted provider server info:
17
+ save it to a 0600 temp file
18
+ assh connect-info --file TMP -n NAME
19
+ delete TMP after connect
20
+ if parsing fails, extract host/user/password, put password in env, then use connect
21
+
22
+ First step:
23
+ assh connect -H HOST -u root -E PASSWORD_ENV -n NAME
24
+ or, when key login already works:
25
+ assh connect -H HOST -u root -i KEY -n NAME
26
+
27
+ Continue with returned sid:
28
+ assh session exec -s SID -- "pwd"
29
+ assh session read -s SID --seq 1 --limit 50
30
+ assh session exec -s SID --timeout 600 -- "git pull"
31
+ assh session read -s SID --seq 2 --stream stderr --limit 50
32
+ assh session close -s SID
33
+
34
+ Cleanup:
35
+ assh session gc --older-than 24h --execute
36
+
37
+ Audit:
38
+ assh audit --last 20 --host HOST --failed
39
+ ```
40
+
41
+ ### JSON Contract
42
+
43
+ `assh connect` returns a session id and next commands:
44
+
45
+ ```json
46
+ {"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"}}
47
+ ```
48
+
49
+ `assh session exec` returns command metadata:
50
+
51
+ ```json
52
+ {"ok":true,"rc":0,"seq":2,"stdout_lines":15,"stderr_lines":0,"sid":"f7a2b3c4","session":"deploy"}
53
+ ```
54
+
55
+ Rules:
56
+
57
+ - Operational commands emit one JSON value by default.
58
+ - `read --raw` and `session read --raw` print only content.
59
+ - Remote non-zero status is a command result, not a transport failure.
60
+ - Passwords are only accepted through environment variables; never put passwords in command arguments.
61
+ - Command text is not written to audit logs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-assh",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
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',