ai-remote 0.4.13 → 0.4.15
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.
- package/README.md +117 -1
- package/SKILL.md +114 -10
- package/dist/cli-chunk-7UHHVT7Q.mjs +483 -0
- package/dist/cli-chunk-EYQCDSPT.mjs +1567 -0
- package/dist/cli-chunk-K2DYJXC5.mjs +63 -0
- package/dist/cli-chunk-RBCU3NX4.mjs +173 -0
- package/dist/cli-chunk-XN3E5SLX.mjs +51 -0
- package/dist/cli-chunk-XT2FISR5.mjs +201 -0
- package/dist/cli-copy-NRXMTHID.mjs +718 -0
- package/dist/cli-daemon-LU4LHDCH.mjs +8418 -0
- package/dist/cli-identities-ZILT4XCR.mjs +412 -0
- package/dist/cli-secrets-26D3F6EN.mjs +218 -0
- package/dist/cli-shell-TE6DLBIB.mjs +10 -0
- package/dist/cli-window-LN32ONC4.mjs +15 -0
- package/dist/cli.mjs +332 -11080
- package/dist/index.d.ts +10 -1
- package/dist/index.js +1 -1
- package/dist/protocols.d.ts +18 -1
- package/dist/protocols.js +14 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,6 +35,69 @@ npx ai-remote exec "systemctl status nginx"
|
|
|
35
35
|
npx ai-remote close
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
### What a command costs, and where the time actually goes
|
|
39
|
+
|
|
40
|
+
Measured on an M4, `list` with two sessions open:
|
|
41
|
+
|
|
42
|
+
| | median |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| Node itself, starting and doing nothing | 24 ms |
|
|
45
|
+
| this CLI, run directly | 27 ms |
|
|
46
|
+
| `npx he --version` -- a package with **no dependencies** | 332 ms |
|
|
47
|
+
| `npx ai-remote list` | 328 ms |
|
|
48
|
+
|
|
49
|
+
The third row is the one that matters. A package with nothing in it costs the
|
|
50
|
+
same under `npx` as this one does, because that 300 ms is `npm exec` resolving
|
|
51
|
+
the spec, revalidating a packument against the registry and spawning -- work npm
|
|
52
|
+
does before the package it is running exists to it. No published version of any
|
|
53
|
+
package can be faster than that row, and this one is at it.
|
|
54
|
+
|
|
55
|
+
So the way to spend less of it is to invoke `npx` fewer times, not to make each
|
|
56
|
+
invocation cheaper. Batch the steps:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Four npx invocations: ~1200 ms, of which ~1200 ms is npm.
|
|
60
|
+
npx ai-remote key MetaLeft
|
|
61
|
+
npx ai-remote type notepad
|
|
62
|
+
npx ai-remote key Enter
|
|
63
|
+
npx ai-remote shot -o s.png
|
|
64
|
+
|
|
65
|
+
# The same four steps, one invocation: ~305 ms.
|
|
66
|
+
npx ai-remote do "key MetaLeft; wait 800; type notepad; key Enter; wait 1500; shot s.png"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`ai-remote shell` is the same idea for a terminal: one invocation, a session
|
|
70
|
+
that stays open, and no npm between keystrokes.
|
|
71
|
+
|
|
72
|
+
Run `node bench/cli.bench.mjs` in this repository to get the table above for
|
|
73
|
+
your own machine -- including the no-dependency control, without which npm's
|
|
74
|
+
300 ms reads like something this package could fix.
|
|
75
|
+
|
|
76
|
+
### About the `npm notice run ...` lines
|
|
77
|
+
|
|
78
|
+
They are npm's, not this package's. `@npmcli/run-script` writes them
|
|
79
|
+
unconditionally at npm's default log level:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
@npmcli/run-script/lib/run-script-pkg.js:53
|
|
83
|
+
log.notice('run', `${cmd.trim()} ${args?.join(' ')}`.trim())
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
There is no field in `package.json`, no `.npmrc` inside the tarball and no
|
|
87
|
+
publish flag that reaches them -- they are printed before this program starts.
|
|
88
|
+
Silencing them is a choice made where the command is run:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx --silent ai-remote list # this invocation only
|
|
92
|
+
NPM_CONFIG_LOGLEVEL=error npx ... # this shell only
|
|
93
|
+
npm config set loglevel error # this machine, all npm commands
|
|
94
|
+
npm install -g ai-remote # no npm in the path at all; use `remotectl`
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The last one also skips the 300 ms: `remotectl list` answers in about 27 ms. It
|
|
98
|
+
is a per-machine decision rather than something the package can carry, which is
|
|
99
|
+
why `npx` is still what the examples here use.
|
|
100
|
+
|
|
38
101
|
### CLI Commands
|
|
39
102
|
|
|
40
103
|
```
|
|
@@ -48,11 +111,12 @@ npx ai-remote close
|
|
|
48
111
|
ai-remote key <Code> press keys, e.g. MetaLeft, ControlLeft+KeyA
|
|
49
112
|
ai-remote exec "cmd" run a command in the terminal (SSH)
|
|
50
113
|
ai-remote shell an interactive terminal
|
|
114
|
+
ai-remote cp <src> <dst> copy files; a remote path starts with ':'
|
|
51
115
|
ai-remote do "steps" several actions in one go
|
|
52
116
|
ai-remote view open the window on the session
|
|
53
117
|
ai-remote view --close close the window, session keeps running
|
|
54
118
|
ai-remote status what the session is doing
|
|
55
|
-
ai-remote list every session
|
|
119
|
+
ai-remote list every session open, and every password kept
|
|
56
120
|
ai-remote saved machines with a password kept
|
|
57
121
|
ai-remote forget [<host[:port]>] throw one away; --all throws all
|
|
58
122
|
ai-remote close close it; --all closes every session
|
|
@@ -75,6 +139,22 @@ npx ai-remote shot --session desk
|
|
|
75
139
|
npx ai-remote close --all
|
|
76
140
|
```
|
|
77
141
|
|
|
142
|
+
`list` answers both halves of "what can I get back to". Every open session, with
|
|
143
|
+
`password saved` against the ones that have one:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
* desk 192.168.1.50:3389 1920x1080 pid 6551 http://127.0.0.1:7373/?t=... password saved (login keychain)
|
|
147
|
+
build 192.168.1.60:3389 1280x800 pid 6808
|
|
148
|
+
|
|
149
|
+
Saved, nothing open (`ai-remote open <host>` needs no password):
|
|
150
|
+
owner@192.168.1.70:3389 login keychain saved 2026-08-28
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The second block is the machines with a password kept but nothing running --
|
|
154
|
+
`open` on one of those needs nothing else. It reads the index beside the
|
|
155
|
+
keystore rather than the keystore, so a listing never raises a keychain prompt;
|
|
156
|
+
`saved` shows that block on its own.
|
|
157
|
+
|
|
78
158
|
`probe` is the one command besides `open` that still takes an address, because
|
|
79
159
|
it answers whether a session could be opened at all; with no address it probes
|
|
80
160
|
the current session's host.
|
|
@@ -134,6 +214,40 @@ npx ai-remote exec "uname -a"
|
|
|
134
214
|
npx ai-remote shell # Ctrl-] to leave
|
|
135
215
|
```
|
|
136
216
|
|
|
217
|
+
### Copying files
|
|
218
|
+
|
|
219
|
+
`cp` is `scp` with the session standing in for the host: a remote path starts
|
|
220
|
+
with a colon, and anything else is on this machine.
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npx ai-remote cp ./setup.exe :C:/Users/owner/Desktop/ # to the session in hand
|
|
224
|
+
npx ai-remote cp :/var/log/syslog ./syslog # from it
|
|
225
|
+
npx ai-remote cp -r ./site :/srv/www # a whole directory
|
|
226
|
+
npx ai-remote cp desk:/tmp/a.txt build:/tmp/a.txt # between two sessions
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
SFTP underneath, which is what `scp` itself uses since OpenSSH 9 deprecated its
|
|
230
|
+
own wire protocol. So the host needs no `scp` binary, a filename with a space or
|
|
231
|
+
a quote in it is a length-prefixed string rather than a quoting problem, and
|
|
232
|
+
nothing passes through a shell -- which is why a Windows host needs no special
|
|
233
|
+
case here even though `exec` needs several.
|
|
234
|
+
|
|
235
|
+
Two rules about the grammar:
|
|
236
|
+
|
|
237
|
+
- **A one-letter prefix is a drive, not a session.** `C:/Users/owner/x.txt` is a
|
|
238
|
+
path on this machine, and always will be. Two or more characters before the
|
|
239
|
+
colon name a session -- by its name, or by its host.
|
|
240
|
+
- **A destination that already exists as a directory takes the source's name
|
|
241
|
+
under it.** `cp a.txt :/tmp` is `/tmp/a.txt`, and `cp -r ./site :/srv/www`
|
|
242
|
+
with `www` already there is `/srv/www/site`. A destination that does not exist
|
|
243
|
+
is the name the copy takes.
|
|
244
|
+
|
|
245
|
+
Chunks are 32 KB with eight in flight, so a transfer gets the bandwidth the link
|
|
246
|
+
has rather than one round trip per chunk. The mode travels with the file. The
|
|
247
|
+
transfer is its own SSH connection rather than the session's, so a large copy
|
|
248
|
+
does not stall the terminal somebody is watching. `--json` reports `bytes`,
|
|
249
|
+
`files` and `rate`.
|
|
250
|
+
|
|
137
251
|
### Signing in
|
|
138
252
|
|
|
139
253
|
Keys first, then a password.
|
|
@@ -174,6 +288,7 @@ where a decrypted key belongs, and it is offered from there.
|
|
|
174
288
|
|
|
175
289
|
- `--session NAME`: Which session to drive (default: the one opened last).
|
|
176
290
|
- `-o, --out FILE`: Screenshot output file path (default: `screen.png`).
|
|
291
|
+
- `-r, --recursive`: For `cp`, copy a directory.
|
|
177
292
|
- `--max-edge N`: Shrink a screenshot to fit N.
|
|
178
293
|
- `--json`: Output machine-readable JSON results on stdout.
|
|
179
294
|
|
|
@@ -216,6 +331,7 @@ npm install ai-remote
|
|
|
216
331
|
- RFC 4253 binary packet protocol with `curve25519-sha256` / `ecdh-sha2-nistp256`.
|
|
217
332
|
- AEAD ciphers (`aes256-gcm@openssh.com`, `aes128-gcm@openssh.com`).
|
|
218
333
|
- Terminal interactive and automated agent command execution.
|
|
334
|
+
- SFTP version 3 client on a subsystem channel, for file transfer.
|
|
219
335
|
- **VNC Engine:**
|
|
220
336
|
- RFB protocol integration with Apple Diffie-Hellman handshake support.
|
|
221
337
|
- **AI Agent Automation:**
|
package/SKILL.md
CHANGED
|
@@ -30,6 +30,27 @@ reconnects between acting and looking can never see the result of its own
|
|
|
30
30
|
action. Reuse also makes each command effectively instant — a keystroke is
|
|
31
31
|
~0.15s against ~5s for a fresh RDP handshake.
|
|
32
32
|
|
|
33
|
+
**Batch steps into one invocation where you can.** `npx` costs about 300 ms per
|
|
34
|
+
call before this tool runs at all — npm resolving the package, not the package
|
|
35
|
+
doing anything, and the same 300 ms for a package with no code in it. The tool
|
|
36
|
+
itself answers in about 27 ms. So four steps run as four commands spend roughly a
|
|
37
|
+
second waiting on npm and a tenth of one doing the work:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# ~1200 ms, nearly all npm
|
|
41
|
+
npx ai-remote key MetaLeft
|
|
42
|
+
npx ai-remote type notepad
|
|
43
|
+
npx ai-remote key Enter
|
|
44
|
+
npx ai-remote shot -o s.png
|
|
45
|
+
|
|
46
|
+
# ~305 ms, same four steps
|
|
47
|
+
npx ai-remote do "key MetaLeft; wait 800; type notepad; key Enter; wait 1500; shot s.png"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Look between steps when you need to see the result before choosing the next one;
|
|
51
|
+
batch the runs of steps you already know. The `npm notice run ...` lines npx
|
|
52
|
+
prints are npm's own and harmless — ignore them, or add `--silent`.
|
|
53
|
+
|
|
33
54
|
## Working loop
|
|
34
55
|
|
|
35
56
|
Act, then look. The session holds the framebuffer, so a screenshot taken after a
|
|
@@ -117,7 +138,9 @@ npx ai-remote exec "hostname"
|
|
|
117
138
|
npx ai-remote exec "dir C:\\Users"
|
|
118
139
|
```
|
|
119
140
|
|
|
120
|
-
`exec` reuses the session's own account and password, so it needs no flags
|
|
141
|
+
`exec` reuses the session's own account and password, so it needs no flags —
|
|
142
|
+
give `open` `--ssh-user NAME` or `--ssh-port N` only when the terminal signs in
|
|
143
|
+
as somebody else, or on a port other than 22. Its
|
|
121
144
|
stdout is the command's output, and it exits 0 when the command did and 1 when
|
|
122
145
|
it did not — the command's own status is in `exitStatus` under `--json` if you
|
|
123
146
|
need the number. `ai-remote shell` opens an interactive terminal (Ctrl-] to
|
|
@@ -126,6 +149,27 @@ leave) — that one is for a human, not for an agent, because it never returns.
|
|
|
126
149
|
Reach for the GUI when the task is genuinely graphical. Reach for `exec` for
|
|
127
150
|
anything a shell can do.
|
|
128
151
|
|
|
152
|
+
## Copying files
|
|
153
|
+
|
|
154
|
+
`cp` is scp with the session standing in for the host. A remote path starts with
|
|
155
|
+
a colon; anything else is on this machine.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
npx ai-remote cp ./setup.exe :C:/Users/owner/Desktop/ # to the session in hand
|
|
159
|
+
npx ai-remote cp :/var/log/syslog ./syslog # from it
|
|
160
|
+
npx ai-remote cp -r ./site :/srv/www # a directory
|
|
161
|
+
npx ai-remote cp desk:/tmp/a.txt build:/tmp/a.txt # between two sessions
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
SFTP underneath, so the host needs no `scp` binary, spaces in filenames need no
|
|
165
|
+
quoting, and nothing goes through a shell. Two rules worth knowing: a one-letter
|
|
166
|
+
prefix is a drive, not a session, so `C:/Users/owner/x.txt` is local; and a
|
|
167
|
+
destination that already exists as a directory takes the source's name under it,
|
|
168
|
+
so `cp -r ./site :/srv/www` with `www` there gives `/srv/www/site`.
|
|
169
|
+
|
|
170
|
+
Uploading is how you get a script onto a machine, which is usually better than
|
|
171
|
+
typing one into a GUI. `--json` reports `bytes`, `files` and `rate`.
|
|
172
|
+
|
|
129
173
|
## A Mac, or anything else that speaks VNC
|
|
130
174
|
|
|
131
175
|
`--vnc` opens the screen over VNC instead of RDP; port 5900 implies it. Every
|
|
@@ -141,7 +185,8 @@ npx ai-remote click 640,400
|
|
|
141
185
|
|
|
142
186
|
A session that is already open gets a screen with `ai-remote vnc`, which takes
|
|
143
187
|
no host because the session already knows the machine. That is the way to give a
|
|
144
|
-
terminal session a desktop without closing it
|
|
188
|
+
terminal session a desktop without closing it; `--vnc-port N` if the screen is
|
|
189
|
+
not on 5900.
|
|
145
190
|
|
|
146
191
|
## A host with no desktop
|
|
147
192
|
|
|
@@ -168,6 +213,42 @@ variable at all. `-i FILE` names a key instead, and repeats. A key with a
|
|
|
168
213
|
passphrase is never read off disk: `ssh-add` it, and it is offered from the
|
|
169
214
|
agent.
|
|
170
215
|
|
|
216
|
+
## Passwords, and not typing them twice
|
|
217
|
+
|
|
218
|
+
A desktop always wants one; a terminal usually does not, because of the keys
|
|
219
|
+
above. Three places are tried, in this order:
|
|
220
|
+
|
|
221
|
+
1. `AI_REMOTE_PASSWORD` in this shell, or `REMOTECTL_PASSWORD` under the other
|
|
222
|
+
name.
|
|
223
|
+
2. Whatever `--save` kept for that machine.
|
|
224
|
+
3. You, at the terminal — only when one is attached, and only after the first
|
|
225
|
+
two have come up empty.
|
|
226
|
+
|
|
227
|
+
This shell wins, so a password exported deliberately is never quietly overridden
|
|
228
|
+
by one saved months ago. There is no `--password` flag and there will not be: a
|
|
229
|
+
command line is visible to every process on the machine.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npx ai-remote open 192.168.1.20 -u owner --save # keep it, once it has worked
|
|
233
|
+
npx ai-remote list # sessions, each marked if it has one
|
|
234
|
+
npx ai-remote saved # only what is kept, and where
|
|
235
|
+
npx ai-remote forget 192.168.1.20 # one machine; --all for every one
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
`list` answers both halves of "what can I get back to": every open session, with
|
|
239
|
+
`password saved` against the ones that have one, and then the machines with a
|
|
240
|
+
password kept but nothing open — those need no `-u` or password to reopen. It
|
|
241
|
+
reads the index beside the keystore, not the keystore, so it never raises a
|
|
242
|
+
keychain prompt.
|
|
243
|
+
|
|
244
|
+
`--save` writes to the system keystore — the login keychain on macOS, the desktop
|
|
245
|
+
keyring on Linux — and where there is neither, to an encrypted file under
|
|
246
|
+
`~/.config/ai-remote`; the command says which it got. That file is proof against
|
|
247
|
+
a glance, not against somebody who can read your home directory.
|
|
248
|
+
|
|
249
|
+
`--no-prompt` (or `--batch`) turns a missing password into an immediate failure
|
|
250
|
+
instead of a question. Use it in anything unattended, where a prompt is a hang.
|
|
251
|
+
|
|
171
252
|
## Sessions
|
|
172
253
|
|
|
173
254
|
The session opened last is the one commands drive. With several open, name them:
|
|
@@ -176,14 +257,20 @@ The session opened last is the one commands drive. With several open, name them:
|
|
|
176
257
|
npx ai-remote open 192.168.1.20 -u owner --session desk
|
|
177
258
|
npx ai-remote open 192.168.1.30 -u owner --session build
|
|
178
259
|
|
|
179
|
-
npx ai-remote list # * marks the one commands will use
|
|
260
|
+
npx ai-remote list # * marks the one commands will use,
|
|
261
|
+
# and it also lists saved passwords
|
|
180
262
|
npx ai-remote shot --session desk # a name, a host, or host:port
|
|
181
263
|
npx ai-remote close --all # or `close` for the current one
|
|
182
264
|
```
|
|
183
265
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
266
|
+
`open` on a machine that already has a session attaches to that one instead of
|
|
267
|
+
building a second; `--no-reuse` is how you get two on purpose.
|
|
268
|
+
|
|
269
|
+
Nothing times out and nothing closes itself by default — a session that an agent
|
|
270
|
+
left mid-task is a feature, not a leak — so **close what you open** when the task
|
|
271
|
+
is done, or tell the user it is still running. `--idle MINUTES` at `open` time
|
|
272
|
+
sets one to close itself after that long unused, for when nobody will be back to
|
|
273
|
+
do it.
|
|
187
274
|
|
|
188
275
|
## Watching
|
|
189
276
|
|
|
@@ -203,9 +290,19 @@ fresh `shot` rather than trusting one from before you paused.
|
|
|
203
290
|
authority either way, so a session nobody watches is not a lesser session.
|
|
204
291
|
- `--fullscreen` fills the display and makes RDP use the current monitor's
|
|
205
292
|
logical resolution. Add `--side-panel` to `open` to start with a fixed-width
|
|
206
|
-
SSH terminal docked on the right; its
|
|
293
|
+
SSH terminal docked on the right; its 610 pixels -- eighty columns, which is
|
|
294
|
+
what a Windows shell assumes it has -- are removed from the RDP width, and the
|
|
295
|
+
divider between the panes can be dragged.
|
|
296
|
+
- `--audio` (RDP only) asks the host to redirect the session's sound and plays
|
|
297
|
+
it in the window; the toolbar's speaker button mutes it. Off unless asked for:
|
|
298
|
+
the stream costs bandwidth in both directions, and Windows stops playing
|
|
299
|
+
through the host's own speakers while it is redirected. A headless session
|
|
300
|
+
ignores the flag, having nowhere to play anything.
|
|
207
301
|
- `ai-remote view` adds a window to a headless session later (`view --watch-only`
|
|
208
302
|
for an observer one); `view --close` takes it away without ending the session.
|
|
303
|
+
- `--view-port N` moves the window's local server off 7373, which matters only
|
|
304
|
+
when two sessions want it at once. `--no-open` keeps the window but does not
|
|
305
|
+
launch a browser at it.
|
|
209
306
|
|
|
210
307
|
## Reading results
|
|
211
308
|
|
|
@@ -242,6 +339,9 @@ the other half of the answer is a key: `ssh-add ~/.ssh/id_ed25519`, or
|
|
|
242
339
|
`-i FILE`. The session's log names every key it offered and every key it passed
|
|
243
340
|
over, and why.
|
|
244
341
|
|
|
342
|
+
`-s nla | tls | rdp` pins the RDP security layer when `auto` picks one the host
|
|
343
|
+
will not finish; it makes no difference over VNC or SSH.
|
|
344
|
+
|
|
245
345
|
**Unreachable (10).** — `ai-remote probe <host>` is the one command besides
|
|
246
346
|
`open` that still takes an address: it answers whether anything is listening
|
|
247
347
|
before you spend a handshake finding out.
|
|
@@ -261,17 +361,20 @@ what `status` reports rather than what you asked for.
|
|
|
261
361
|
```bash
|
|
262
362
|
export AI_REMOTE_PASSWORD=...
|
|
263
363
|
npx ai-remote open HOST[:PORT] -u USER [-d DOMAIN] [--session NAME] [--fullscreen] [--side-panel]
|
|
364
|
+
[-W 1920 -H 1080] [-s auto|nla|tls|rdp] [--save] [--idle N] [--audio]
|
|
264
365
|
npx ai-remote open HOST --ssh -u USER [-i ~/.ssh/id_ed25519] # a terminal, no desktop
|
|
265
366
|
npx ai-remote open HOST --vnc -u USER # a screen over VNC
|
|
266
|
-
npx ai-remote vnc
|
|
367
|
+
npx ai-remote vnc [--vnc-port N] # ...or add one to this session
|
|
267
368
|
npx ai-remote shot [-o FILE] [--max-edge N] [--json]
|
|
268
369
|
npx ai-remote click X,Y [--button right|middle] [--double]
|
|
269
370
|
npx ai-remote type "text"
|
|
270
371
|
npx ai-remote key ControlLeft+KeyA
|
|
271
372
|
npx ai-remote do "key MetaLeft; wait 800; type notepad; shot s.png"
|
|
272
373
|
npx ai-remote exec "command"
|
|
374
|
+
npx ai-remote cp [-r] SRC DST # ':path' is on the session
|
|
273
375
|
npx ai-remote view [--watch-only] [--close]
|
|
274
376
|
npx ai-remote status | list | close [--all]
|
|
377
|
+
npx ai-remote saved | forget [HOST[:PORT]] [--all]
|
|
275
378
|
npx ai-remote probe [HOST[:PORT]]
|
|
276
379
|
```
|
|
277
380
|
|
|
@@ -292,5 +395,6 @@ node packages/core/dist/cli.mjs open HOST -u USER --headless
|
|
|
292
395
|
|
|
293
396
|
The CLI's own source is [`packages/core/src/cli/`](src/cli/):
|
|
294
397
|
`cli.ts` is the grammar, `sessions.ts` decides which session a command drives,
|
|
295
|
-
`daemon.ts` is the process that holds the connection,
|
|
296
|
-
`
|
|
398
|
+
`daemon.ts` is the process that holds the connection, `copy.ts` is `cp` over the
|
|
399
|
+
SFTP client in [`protocols/ssh/sftp.ts`](src/protocols/ssh/sftp.ts), and
|
|
400
|
+
`viewer.ts` plus `window.ts` are the window. `pnpm test` covers them.
|