ai-remote 0.4.14 → 0.4.16
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 +194 -1
- package/SKILL.md +112 -7
- package/dist/cli-chunk-7UHHVT7Q.mjs +483 -0
- package/dist/cli-chunk-K2DYJXC5.mjs +63 -0
- package/dist/cli-chunk-Q33YGIDO.mjs +173 -0
- package/dist/cli-chunk-S2TWL5LF.mjs +1580 -0
- package/dist/cli-chunk-XN3E5SLX.mjs +51 -0
- package/dist/cli-chunk-XT2FISR5.mjs +201 -0
- package/dist/cli-copy-BOF44DWQ.mjs +718 -0
- package/dist/cli-daemon-4VU67MLE.mjs +8727 -0
- package/dist/cli-identities-ZILT4XCR.mjs +412 -0
- package/dist/cli-secrets-26D3F6EN.mjs +218 -0
- package/dist/cli-shell-45XRTE7O.mjs +10 -0
- package/dist/cli-window-LN32ONC4.mjs +15 -0
- package/dist/cli.mjs +391 -11121
- package/dist/index.d.ts +10 -1
- package/dist/index.js +1 -1
- package/dist/protocols.d.ts +18 -1
- package/dist/protocols.js +15 -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,14 @@ 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 reconnect a new terminal: fresh login, fresh PATH
|
|
115
|
+
ai-remote clipboard [on|off] share this machine's clipboard both ways
|
|
116
|
+
ai-remote cp <src> <dst> copy files; a remote path starts with ':'
|
|
51
117
|
ai-remote do "steps" several actions in one go
|
|
52
118
|
ai-remote view open the window on the session
|
|
53
119
|
ai-remote view --close close the window, session keeps running
|
|
54
120
|
ai-remote status what the session is doing
|
|
55
|
-
ai-remote list every session
|
|
121
|
+
ai-remote list every session open, and every password kept
|
|
56
122
|
ai-remote saved machines with a password kept
|
|
57
123
|
ai-remote forget [<host[:port]>] throw one away; --all throws all
|
|
58
124
|
ai-remote close close it; --all closes every session
|
|
@@ -75,6 +141,22 @@ npx ai-remote shot --session desk
|
|
|
75
141
|
npx ai-remote close --all
|
|
76
142
|
```
|
|
77
143
|
|
|
144
|
+
`list` answers both halves of "what can I get back to". Every open session, with
|
|
145
|
+
`password saved` against the ones that have one:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
* desk 192.168.1.50:3389 1920x1080 pid 6551 http://127.0.0.1:7373/?t=... password saved (login keychain)
|
|
149
|
+
build 192.168.1.60:3389 1280x800 pid 6808
|
|
150
|
+
|
|
151
|
+
Saved, nothing open (`ai-remote open <host>` needs no password):
|
|
152
|
+
owner@192.168.1.70:3389 login keychain saved 2026-08-28
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The second block is the machines with a password kept but nothing running --
|
|
156
|
+
`open` on one of those needs nothing else. It reads the index beside the
|
|
157
|
+
keystore rather than the keystore, so a listing never raises a keychain prompt;
|
|
158
|
+
`saved` shows that block on its own.
|
|
159
|
+
|
|
78
160
|
`probe` is the one command besides `open` that still takes an address, because
|
|
79
161
|
it answers whether a session could be opened at all; with no address it probes
|
|
80
162
|
the current session's host.
|
|
@@ -134,6 +216,113 @@ npx ai-remote exec "uname -a"
|
|
|
134
216
|
npx ai-remote shell # Ctrl-] to leave
|
|
135
217
|
```
|
|
136
218
|
|
|
219
|
+
### The clipboard
|
|
220
|
+
|
|
221
|
+
Off by default, and turned on either from the **clipboard button in the window's
|
|
222
|
+
toolbar** or from a command line:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npx ai-remote clipboard on # both directions, until turned off
|
|
226
|
+
npx ai-remote clipboard # what it is doing now
|
|
227
|
+
npx ai-remote open 192.168.1.50 -u owner --clipboard
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
While it is on, text copied on this machine reaches the remote clipboard and text
|
|
231
|
+
copied there reaches this one. Only a desktop carries a clipboard -- RDP
|
|
232
|
+
negotiates a `cliprdr` channel and VNC has cut-text in the protocol -- so a
|
|
233
|
+
terminal-only session has none and the toolbar button does not appear.
|
|
234
|
+
|
|
235
|
+
**The bridge is the session's, not the page's.** The obvious place to put it
|
|
236
|
+
would be the viewer, using the browser's `navigator.clipboard` -- but a browser
|
|
237
|
+
only grants a page the clipboard while that page is focused, and the moment
|
|
238
|
+
somebody wants the remote clipboard is exactly the moment they have clicked away
|
|
239
|
+
into a local application to paste it. So the session does the copying, on this
|
|
240
|
+
machine, whether or not a window is open; the toolbar button turns it on rather
|
|
241
|
+
than doing it. Two windows on one session are two views of one switch.
|
|
242
|
+
|
|
243
|
+
Two consequences worth knowing:
|
|
244
|
+
|
|
245
|
+
- **It polls.** No platform gives Node a clipboard-change event, so the local
|
|
246
|
+
side is read twice a second while sharing is on. That is why it is a toggle
|
|
247
|
+
and not always on, and why off is a real off: the timer is not running and the
|
|
248
|
+
host's clipboard messages are dropped.
|
|
249
|
+
- **Nothing goes round in circles.** Text that arrived from the host is not then
|
|
250
|
+
noticed by the poller and pushed back to it, and what was already on the
|
|
251
|
+
clipboard when sharing started is not treated as a change -- so turning
|
|
252
|
+
sharing on does not send something copied an hour ago.
|
|
253
|
+
|
|
254
|
+
It uses whatever the platform has: `pbcopy`/`pbpaste` on macOS,
|
|
255
|
+
`Set-Clipboard`/`Get-Clipboard` on Windows, and `wl-clipboard`, `xclip` or
|
|
256
|
+
`xsel` on Linux. A machine with none reports the clipboard as unavailable and
|
|
257
|
+
the button stays hidden rather than offering a switch that cannot work.
|
|
258
|
+
|
|
259
|
+
Sharing sits behind the same control gate as keyboard and pointer input: a
|
|
260
|
+
watch-only viewer can read the screen and cannot reach either clipboard.
|
|
261
|
+
|
|
262
|
+
### A new terminal, after installing something
|
|
263
|
+
|
|
264
|
+
A shell inherits its environment when it signs in, and nothing can change a
|
|
265
|
+
running process's inherited environment from outside it. So a program installed
|
|
266
|
+
a moment ago is simply not on the PATH of the shell that installed it, and
|
|
267
|
+
running the command again will not find it however many times it is tried.
|
|
268
|
+
|
|
269
|
+
`reconnect` is the fix, and it is the same one a person reaches for -- close the
|
|
270
|
+
terminal, open another:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
npx ai-remote exec "winget install OpenJS.NodeJS"
|
|
274
|
+
npx ai-remote reconnect
|
|
275
|
+
npx ai-remote exec "node --version"
|
|
276
|
+
|
|
277
|
+
npx ai-remote exec --reconnect "node --version" # or both in one call
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
The session, the desktop and the window stay exactly where they are; only the
|
|
281
|
+
terminal is new. That also means the working directory and any exported
|
|
282
|
+
variables are gone, which is the point -- it is a new login, not a refresh.
|
|
283
|
+
|
|
284
|
+
On Windows a fresh login can still inherit a stale environment, because sshd
|
|
285
|
+
built its own environment block when the service started. Reading the PATH
|
|
286
|
+
straight out of the registry works regardless:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
npx ai-remote exec '$env:Path = [Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [Environment]::GetEnvironmentVariable("Path","User")'
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Copying files
|
|
293
|
+
|
|
294
|
+
`cp` is `scp` with the session standing in for the host: a remote path starts
|
|
295
|
+
with a colon, and anything else is on this machine.
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
npx ai-remote cp ./setup.exe :C:/Users/owner/Desktop/ # to the session in hand
|
|
299
|
+
npx ai-remote cp :/var/log/syslog ./syslog # from it
|
|
300
|
+
npx ai-remote cp -r ./site :/srv/www # a whole directory
|
|
301
|
+
npx ai-remote cp desk:/tmp/a.txt build:/tmp/a.txt # between two sessions
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
SFTP underneath, which is what `scp` itself uses since OpenSSH 9 deprecated its
|
|
305
|
+
own wire protocol. So the host needs no `scp` binary, a filename with a space or
|
|
306
|
+
a quote in it is a length-prefixed string rather than a quoting problem, and
|
|
307
|
+
nothing passes through a shell -- which is why a Windows host needs no special
|
|
308
|
+
case here even though `exec` needs several.
|
|
309
|
+
|
|
310
|
+
Two rules about the grammar:
|
|
311
|
+
|
|
312
|
+
- **A one-letter prefix is a drive, not a session.** `C:/Users/owner/x.txt` is a
|
|
313
|
+
path on this machine, and always will be. Two or more characters before the
|
|
314
|
+
colon name a session -- by its name, or by its host.
|
|
315
|
+
- **A destination that already exists as a directory takes the source's name
|
|
316
|
+
under it.** `cp a.txt :/tmp` is `/tmp/a.txt`, and `cp -r ./site :/srv/www`
|
|
317
|
+
with `www` already there is `/srv/www/site`. A destination that does not exist
|
|
318
|
+
is the name the copy takes.
|
|
319
|
+
|
|
320
|
+
Chunks are 32 KB with eight in flight, so a transfer gets the bandwidth the link
|
|
321
|
+
has rather than one round trip per chunk. The mode travels with the file. The
|
|
322
|
+
transfer is its own SSH connection rather than the session's, so a large copy
|
|
323
|
+
does not stall the terminal somebody is watching. `--json` reports `bytes`,
|
|
324
|
+
`files` and `rate`.
|
|
325
|
+
|
|
137
326
|
### Signing in
|
|
138
327
|
|
|
139
328
|
Keys first, then a password.
|
|
@@ -166,6 +355,7 @@ where a decrypted key belongs, and it is offered from there.
|
|
|
166
355
|
- `-s, --security MODE`: `auto` | `nla` | `tls` | `rdp` (default: `auto`).
|
|
167
356
|
- `-W, --width N` / `-H, --height N`: Desktop resolution (default: 1280x800).
|
|
168
357
|
- `--idle MINUTES`: Close an unused session (default: 0, never).
|
|
358
|
+
- `--clipboard`: Share this machine's clipboard with the desktop, both ways.
|
|
169
359
|
- `--headless` / `--no-view`: Run headless without opening the viewer window.
|
|
170
360
|
- `--no-reuse`: A second session beside one that is already open.
|
|
171
361
|
- `--save`: Keep the password for next time, once it has worked.
|
|
@@ -174,6 +364,8 @@ where a decrypted key belongs, and it is offered from there.
|
|
|
174
364
|
|
|
175
365
|
- `--session NAME`: Which session to drive (default: the one opened last).
|
|
176
366
|
- `-o, --out FILE`: Screenshot output file path (default: `screen.png`).
|
|
367
|
+
- `-r, --recursive`: For `cp`, copy a directory.
|
|
368
|
+
- `--reconnect`: For `exec`, open a new terminal first, then run the command.
|
|
177
369
|
- `--max-edge N`: Shrink a screenshot to fit N.
|
|
178
370
|
- `--json`: Output machine-readable JSON results on stdout.
|
|
179
371
|
|
|
@@ -216,6 +408,7 @@ npm install ai-remote
|
|
|
216
408
|
- RFC 4253 binary packet protocol with `curve25519-sha256` / `ecdh-sha2-nistp256`.
|
|
217
409
|
- AEAD ciphers (`aes256-gcm@openssh.com`, `aes128-gcm@openssh.com`).
|
|
218
410
|
- Terminal interactive and automated agent command execution.
|
|
411
|
+
- SFTP version 3 client on a subsystem channel, for file transfer.
|
|
219
412
|
- **VNC Engine:**
|
|
220
413
|
- RFB protocol integration with Apple Diffie-Hellman handshake support.
|
|
221
414
|
- **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
|
|
@@ -128,6 +149,71 @@ leave) — that one is for a human, not for an agent, because it never returns.
|
|
|
128
149
|
Reach for the GUI when the task is genuinely graphical. Reach for `exec` for
|
|
129
150
|
anything a shell can do.
|
|
130
151
|
|
|
152
|
+
**After installing anything, reconnect.** A shell's environment is fixed when it
|
|
153
|
+
signs in, so a `node` installed a moment ago is not on the PATH of the shell that
|
|
154
|
+
installed it, and asking again will never find it:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npx ai-remote exec "winget install OpenJS.NodeJS"
|
|
158
|
+
npx ai-remote reconnect # a new login, so a new PATH
|
|
159
|
+
npx ai-remote exec "node --version"
|
|
160
|
+
|
|
161
|
+
npx ai-remote exec --reconnect "node --version" # or both in one call
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The session, the desktop and the window all stay put — only the terminal is new,
|
|
165
|
+
which also means the working directory and any exported variables are gone. On
|
|
166
|
+
Windows, if a fresh login still cannot see it, sshd handed down its own stale
|
|
167
|
+
environment; read the PATH straight out of the registry instead:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npx ai-remote exec '$env:Path = [Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [Environment]::GetEnvironmentVariable("Path","User")'
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Note `&&` is not valid in PowerShell 5.1 — use `;` to chain, or `if ($?) { ... }`
|
|
174
|
+
when the second command should only run if the first worked.
|
|
175
|
+
|
|
176
|
+
## The clipboard
|
|
177
|
+
|
|
178
|
+
Off by default. The **clipboard button in the window's toolbar** turns it on, or
|
|
179
|
+
from a command line:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
npx ai-remote clipboard on # both directions, until turned off
|
|
183
|
+
npx ai-remote clipboard # what it is doing now
|
|
184
|
+
npx ai-remote open HOST -u USER --clipboard # on from the start
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
While it is on, text copied on this machine reaches the remote clipboard and
|
|
188
|
+
text copied there reaches this one — so a password, a path or a stack trace
|
|
189
|
+
moves without being typed. Only a desktop has a clipboard: RDP negotiates one
|
|
190
|
+
and VNC has it in the protocol, while an `--ssh` session has none and the button
|
|
191
|
+
does not appear.
|
|
192
|
+
|
|
193
|
+
Turn it off before copying anything on this machine that the remote end should
|
|
194
|
+
not see. Off is a real off — nothing is read and nothing is written.
|
|
195
|
+
|
|
196
|
+
## Copying files
|
|
197
|
+
|
|
198
|
+
`cp` is scp with the session standing in for the host. A remote path starts with
|
|
199
|
+
a colon; anything else is on this machine.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npx ai-remote cp ./setup.exe :C:/Users/owner/Desktop/ # to the session in hand
|
|
203
|
+
npx ai-remote cp :/var/log/syslog ./syslog # from it
|
|
204
|
+
npx ai-remote cp -r ./site :/srv/www # a directory
|
|
205
|
+
npx ai-remote cp desk:/tmp/a.txt build:/tmp/a.txt # between two sessions
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
SFTP underneath, so the host needs no `scp` binary, spaces in filenames need no
|
|
209
|
+
quoting, and nothing goes through a shell. Two rules worth knowing: a one-letter
|
|
210
|
+
prefix is a drive, not a session, so `C:/Users/owner/x.txt` is local; and a
|
|
211
|
+
destination that already exists as a directory takes the source's name under it,
|
|
212
|
+
so `cp -r ./site :/srv/www` with `www` there gives `/srv/www/site`.
|
|
213
|
+
|
|
214
|
+
Uploading is how you get a script onto a machine, which is usually better than
|
|
215
|
+
typing one into a GUI. `--json` reports `bytes`, `files` and `rate`.
|
|
216
|
+
|
|
131
217
|
## A Mac, or anything else that speaks VNC
|
|
132
218
|
|
|
133
219
|
`--vnc` opens the screen over VNC instead of RDP; port 5900 implies it. Every
|
|
@@ -188,10 +274,17 @@ command line is visible to every process on the machine.
|
|
|
188
274
|
|
|
189
275
|
```bash
|
|
190
276
|
npx ai-remote open 192.168.1.20 -u owner --save # keep it, once it has worked
|
|
191
|
-
npx ai-remote
|
|
277
|
+
npx ai-remote list # sessions, each marked if it has one
|
|
278
|
+
npx ai-remote saved # only what is kept, and where
|
|
192
279
|
npx ai-remote forget 192.168.1.20 # one machine; --all for every one
|
|
193
280
|
```
|
|
194
281
|
|
|
282
|
+
`list` answers both halves of "what can I get back to": every open session, with
|
|
283
|
+
`password saved` against the ones that have one, and then the machines with a
|
|
284
|
+
password kept but nothing open — those need no `-u` or password to reopen. It
|
|
285
|
+
reads the index beside the keystore, not the keystore, so it never raises a
|
|
286
|
+
keychain prompt.
|
|
287
|
+
|
|
195
288
|
`--save` writes to the system keystore — the login keychain on macOS, the desktop
|
|
196
289
|
keyring on Linux — and where there is neither, to an encrypted file under
|
|
197
290
|
`~/.config/ai-remote`; the command says which it got. That file is proof against
|
|
@@ -208,7 +301,8 @@ The session opened last is the one commands drive. With several open, name them:
|
|
|
208
301
|
npx ai-remote open 192.168.1.20 -u owner --session desk
|
|
209
302
|
npx ai-remote open 192.168.1.30 -u owner --session build
|
|
210
303
|
|
|
211
|
-
npx ai-remote list # * marks the one commands will use
|
|
304
|
+
npx ai-remote list # * marks the one commands will use,
|
|
305
|
+
# and it also lists saved passwords
|
|
212
306
|
npx ai-remote shot --session desk # a name, a host, or host:port
|
|
213
307
|
npx ai-remote close --all # or `close` for the current one
|
|
214
308
|
```
|
|
@@ -240,7 +334,14 @@ fresh `shot` rather than trusting one from before you paused.
|
|
|
240
334
|
authority either way, so a session nobody watches is not a lesser session.
|
|
241
335
|
- `--fullscreen` fills the display and makes RDP use the current monitor's
|
|
242
336
|
logical resolution. Add `--side-panel` to `open` to start with a fixed-width
|
|
243
|
-
SSH terminal docked on the right; its
|
|
337
|
+
SSH terminal docked on the right; its 610 pixels -- eighty columns, which is
|
|
338
|
+
what a Windows shell assumes it has -- are removed from the RDP width, and the
|
|
339
|
+
divider between the panes can be dragged.
|
|
340
|
+
- `--audio` (RDP only) asks the host to redirect the session's sound and plays
|
|
341
|
+
it in the window; the toolbar's speaker button mutes it. Off unless asked for:
|
|
342
|
+
the stream costs bandwidth in both directions, and Windows stops playing
|
|
343
|
+
through the host's own speakers while it is redirected. A headless session
|
|
344
|
+
ignores the flag, having nowhere to play anything.
|
|
244
345
|
- `ai-remote view` adds a window to a headless session later (`view --watch-only`
|
|
245
346
|
for an observer one); `view --close` takes it away without ending the session.
|
|
246
347
|
- `--view-port N` moves the window's local server off 7373, which matters only
|
|
@@ -304,7 +405,7 @@ what `status` reports rather than what you asked for.
|
|
|
304
405
|
```bash
|
|
305
406
|
export AI_REMOTE_PASSWORD=...
|
|
306
407
|
npx ai-remote open HOST[:PORT] -u USER [-d DOMAIN] [--session NAME] [--fullscreen] [--side-panel]
|
|
307
|
-
[-W 1920 -H 1080] [-s auto|nla|tls|rdp] [--save] [--idle N]
|
|
408
|
+
[-W 1920 -H 1080] [-s auto|nla|tls|rdp] [--save] [--idle N] [--audio]
|
|
308
409
|
npx ai-remote open HOST --ssh -u USER [-i ~/.ssh/id_ed25519] # a terminal, no desktop
|
|
309
410
|
npx ai-remote open HOST --vnc -u USER # a screen over VNC
|
|
310
411
|
npx ai-remote vnc [--vnc-port N] # ...or add one to this session
|
|
@@ -313,7 +414,10 @@ npx ai-remote click X,Y [--button right|middle] [--double]
|
|
|
313
414
|
npx ai-remote type "text"
|
|
314
415
|
npx ai-remote key ControlLeft+KeyA
|
|
315
416
|
npx ai-remote do "key MetaLeft; wait 800; type notepad; shot s.png"
|
|
316
|
-
npx ai-remote exec "command"
|
|
417
|
+
npx ai-remote exec "command" [--reconnect]
|
|
418
|
+
npx ai-remote reconnect # a new login: fresh PATH
|
|
419
|
+
npx ai-remote clipboard [on|off] # share text both ways
|
|
420
|
+
npx ai-remote cp [-r] SRC DST # ':path' is on the session
|
|
317
421
|
npx ai-remote view [--watch-only] [--close]
|
|
318
422
|
npx ai-remote status | list | close [--all]
|
|
319
423
|
npx ai-remote saved | forget [HOST[:PORT]] [--all]
|
|
@@ -337,5 +441,6 @@ node packages/core/dist/cli.mjs open HOST -u USER --headless
|
|
|
337
441
|
|
|
338
442
|
The CLI's own source is [`packages/core/src/cli/`](src/cli/):
|
|
339
443
|
`cli.ts` is the grammar, `sessions.ts` decides which session a command drives,
|
|
340
|
-
`daemon.ts` is the process that holds the connection,
|
|
341
|
-
`
|
|
444
|
+
`daemon.ts` is the process that holds the connection, `copy.ts` is `cp` over the
|
|
445
|
+
SFTP client in [`protocols/ssh/sftp.ts`](src/protocols/ssh/sftp.ts), and
|
|
446
|
+
`viewer.ts` plus `window.ts` are the window. `pnpm test` covers them.
|