ai-remote 0.4.6 → 0.4.8
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 +84 -2
- package/SKILL.md +49 -1
- package/dist/apple-dh.d.ts +27 -0
- package/dist/apple-dh.js +1 -0
- package/dist/cli.mjs +3011 -207
- package/dist/protocols/rdp/buffer.d.ts +38 -0
- package/dist/protocols/rdp/caps.d.ts +49 -0
- package/dist/protocols/rdp/cert.d.ts +18 -0
- package/dist/protocols/rdp/client.d.ts +56 -0
- package/dist/protocols/rdp/cliprdr.d.ts +27 -0
- package/dist/protocols/rdp/credssp.d.ts +34 -0
- package/dist/protocols/rdp/crypto.d.ts +63 -0
- package/dist/protocols/rdp/display.d.ts +38 -0
- package/dist/protocols/rdp/gcc.d.ts +23 -0
- package/dist/protocols/rdp/keymap.d.ts +9 -0
- package/dist/protocols/rdp/mcs.d.ts +40 -0
- package/dist/protocols/rdp/ntlm.d.ts +61 -0
- package/dist/protocols/rdp/pdu.d.ts +155 -0
- package/dist/protocols/rdp/rail.d.ts +119 -0
- package/dist/protocols/rdp/rle.d.ts +13 -0
- package/dist/protocols/rdp/sec.d.ts +59 -0
- package/dist/protocols/rdp/session.d.ts +62 -0
- package/dist/protocols/rdp/tls.d.ts +18 -0
- package/dist/protocols/rdp/vchannel.d.ts +28 -0
- package/dist/protocols/rdp/x224.d.ts +40 -0
- package/dist/protocols/ssh/identity.d.ts +39 -0
- package/dist/protocols/ssh/kex.d.ts +97 -0
- package/dist/protocols/ssh/messages.d.ts +52 -0
- package/dist/protocols/ssh/session.d.ts +67 -0
- package/dist/protocols/ssh/terminal.d.ts +46 -0
- package/dist/protocols/ssh/transport.d.ts +62 -0
- package/dist/protocols/ssh/wire.d.ts +52 -0
- package/dist/protocols/types.d.ts +127 -0
- package/dist/protocols/vnc/des.d.ts +25 -0
- package/dist/protocols/vnc/input.d.ts +5 -0
- package/dist/protocols/vnc/keysyms.d.ts +16 -0
- package/dist/protocols/vnc/rfb.d.ts +64 -0
- package/dist/protocols/vnc/session.d.ts +12 -0
- package/dist/protocols.js +13 -13
- package/dist/shared/connection.d.ts +81 -0
- package/dist/shared/device.d.ts +26 -0
- package/dist/shared/hosts.d.ts +63 -0
- package/dist/shared/icons.d.ts +46 -0
- package/dist/shared/protocol.d.ts +32 -0
- package/dist/shared/signals.d.ts +37 -0
- package/package.json +8 -3
- /package/dist/{protocols.d.ts → protocols/index.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -26,6 +26,11 @@ npx ai-remote key Enter
|
|
|
26
26
|
# Run commands in the remote terminal over SSH:
|
|
27
27
|
npx ai-remote exec "dir"
|
|
28
28
|
|
|
29
|
+
# A host with no desktop -- a Linux box, a Mac, a container -- is a terminal
|
|
30
|
+
# session. Keys are used before passwords, so this usually needs nothing set:
|
|
31
|
+
npx ai-remote open 192.168.1.60 --ssh -u deploy
|
|
32
|
+
npx ai-remote exec "systemctl status nginx"
|
|
33
|
+
|
|
29
34
|
# Let it go when you are done -- nothing closes on its own:
|
|
30
35
|
npx ai-remote close
|
|
31
36
|
```
|
|
@@ -34,6 +39,8 @@ npx ai-remote close
|
|
|
34
39
|
|
|
35
40
|
```
|
|
36
41
|
ai-remote open <host[:port]> connect, show a window, and stay open
|
|
42
|
+
ai-remote open <host> --ssh a terminal only: no desktop, no RDP
|
|
43
|
+
ai-remote open <host> --vnc a screen over VNC (implied by port 5900)
|
|
37
44
|
|
|
38
45
|
ai-remote shot screenshot the desktop
|
|
39
46
|
ai-remote click X,Y click, --button right|middle, --double
|
|
@@ -46,6 +53,8 @@ npx ai-remote close
|
|
|
46
53
|
ai-remote view --close close the window, session keeps running
|
|
47
54
|
ai-remote status what the session is doing
|
|
48
55
|
ai-remote list every session that is open
|
|
56
|
+
ai-remote saved machines with a password kept
|
|
57
|
+
ai-remote forget [<host[:port]>] throw one away; --all throws all
|
|
49
58
|
ai-remote close close it; --all closes every session
|
|
50
59
|
ai-remote probe [<host[:port]>] is anything listening?
|
|
51
60
|
```
|
|
@@ -70,9 +79,80 @@ npx ai-remote close --all
|
|
|
70
79
|
it answers whether a session could be opened at all; with no address it probes
|
|
71
80
|
the current session's host.
|
|
72
81
|
|
|
82
|
+
### A screen over VNC
|
|
83
|
+
|
|
84
|
+
Macs, Linux desktops and anything else running a VNC server are opened with
|
|
85
|
+
`--vnc`, or just by naming port 5900. Everything else is the same as RDP -- the
|
|
86
|
+
same window, the same `shot`, `click`, `type`, `key` and `do`, the same session
|
|
87
|
+
that stays open until it is closed:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
AI_REMOTE_PASSWORD=... npx ai-remote open 192.168.1.70 --vnc -u alex
|
|
91
|
+
npx ai-remote shot -o screen.png
|
|
92
|
+
npx ai-remote click 640,400
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The client is this package's own: no noVNC, no browser and no gateway. It signs
|
|
96
|
+
in either way a host may ask -- the classic VNC password, or the account and
|
|
97
|
+
password macOS Screen Sharing wants -- and decodes Raw and CopyRect, which
|
|
98
|
+
every host implements. Raw is bandwidth-hungry by design; on a LAN a 1080p
|
|
99
|
+
desktop is fine, over a slow link it will feel it.
|
|
100
|
+
|
|
101
|
+
A session that is already open can be given a screen without being reopened,
|
|
102
|
+
which is the point of `vnc` taking no host:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx ai-remote open 192.168.1.70 --ssh -u alex # a terminal
|
|
106
|
+
npx ai-remote vnc # ...and now a screen too
|
|
107
|
+
npx ai-remote exec "uptime" # both, one session
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Terminal-only sessions
|
|
111
|
+
|
|
112
|
+
`--ssh` opens a session that is a terminal and nothing else: no RDP handshake,
|
|
113
|
+
no framebuffer, and a window that is all terminal. Port 22 implies it, so
|
|
114
|
+
`open box:22` and `open box --ssh` are the same thing.
|
|
115
|
+
|
|
116
|
+
`exec`, `shell`, `status`, `view` and `close` work as they always do. The
|
|
117
|
+
commands about pixels -- `shot`, `click`, `type`, `key`, `do` -- say there is no
|
|
118
|
+
desktop rather than failing obscurely.
|
|
119
|
+
|
|
120
|
+
The session lasts until `close`. If the host drops the terminal -- an idle
|
|
121
|
+
timeout on its side, or an `exit` typed into the window -- the session stays
|
|
122
|
+
where it is and the next command opens another one; `status` says `disconnected`
|
|
123
|
+
in between.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx ai-remote open 192.168.1.60 --ssh -u deploy # a terminal window
|
|
127
|
+
npx ai-remote exec "uname -a"
|
|
128
|
+
npx ai-remote shell # Ctrl-] to leave
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Signing in
|
|
132
|
+
|
|
133
|
+
Keys first, then a password.
|
|
134
|
+
|
|
135
|
+
With no `--identity`, ssh-agent is asked for whatever it is holding, and
|
|
136
|
+
`~/.ssh/id_ed25519`, `id_ecdsa` and `id_rsa` are read if they have no
|
|
137
|
+
passphrase -- so a host that already takes your key needs nothing set at all.
|
|
138
|
+
Ed25519, ECDSA and RSA keys are supported, in OpenSSH's own format as well as
|
|
139
|
+
PKCS#8 and the older PEM containers.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx ai-remote open box --ssh -u deploy # agent + ~/.ssh
|
|
143
|
+
npx ai-remote open box --ssh -u deploy -i ~/.ssh/deploy_ed25519 # one named key
|
|
144
|
+
ssh-add ~/.ssh/id_ed25519 # a key with a passphrase
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
A key with a passphrase is not read off disk: add it to ssh-agent, which is
|
|
148
|
+
where a decrypted key belongs, and it is offered from there.
|
|
149
|
+
|
|
73
150
|
### Options for `open`
|
|
74
151
|
|
|
152
|
+
- `--ssh`: A terminal session only, with no desktop (implied by port 22).
|
|
153
|
+
- `--vnc`: A screen over VNC rather than RDP (implied by port 5900).
|
|
75
154
|
- `-u, --user NAME`: Account name on the host.
|
|
155
|
+
- `-i, --identity FILE`: A private key to sign in with. Repeatable.
|
|
76
156
|
- `-d, --domain NAME`: Windows domain or computer name.
|
|
77
157
|
- `--session NAME`: Name this session (default: `host_port`).
|
|
78
158
|
- `--ssh-user NAME`: Account for the SSH terminal (defaults to `--user`).
|
|
@@ -82,6 +162,7 @@ the current session's host.
|
|
|
82
162
|
- `--idle MINUTES`: Close an unused session (default: 0, never).
|
|
83
163
|
- `--headless` / `--no-view`: Run headless without opening the viewer window.
|
|
84
164
|
- `--no-reuse`: A second session beside one that is already open.
|
|
165
|
+
- `--save`: Keep the password for next time, once it has worked.
|
|
85
166
|
|
|
86
167
|
### Options for the rest
|
|
87
168
|
|
|
@@ -90,8 +171,9 @@ the current session's host.
|
|
|
90
171
|
- `--max-edge N`: Shrink a screenshot to fit N.
|
|
91
172
|
- `--json`: Output machine-readable JSON results on stdout.
|
|
92
173
|
|
|
93
|
-
The password comes from `AI_REMOTE_PASSWORD` (or
|
|
94
|
-
no `--password` flag: a command line is visible
|
|
174
|
+
The password, where one is wanted, comes from `AI_REMOTE_PASSWORD` (or
|
|
175
|
+
`REMOTECTL_PASSWORD`). There is no `--password` flag: a command line is visible
|
|
176
|
+
to every process on the machine.
|
|
95
177
|
|
|
96
178
|
---
|
|
97
179
|
|
package/SKILL.md
CHANGED
|
@@ -126,6 +126,48 @@ leave) — that one is for a human, not for an agent, because it never returns.
|
|
|
126
126
|
Reach for the GUI when the task is genuinely graphical. Reach for `exec` for
|
|
127
127
|
anything a shell can do.
|
|
128
128
|
|
|
129
|
+
## A Mac, or anything else that speaks VNC
|
|
130
|
+
|
|
131
|
+
`--vnc` opens the screen over VNC instead of RDP; port 5900 implies it. Every
|
|
132
|
+
desktop command works exactly as it does over RDP -- there is nothing
|
|
133
|
+
protocol-specific to remember:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
export AI_REMOTE_PASSWORD=... # the VNC password, or the macOS account's
|
|
137
|
+
npx ai-remote open 192.168.1.70 --vnc -u alex
|
|
138
|
+
npx ai-remote shot -o screen.png
|
|
139
|
+
npx ai-remote click 640,400
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
A session that is already open gets a screen with `ai-remote vnc`, which takes
|
|
143
|
+
no host because the session already knows the machine. That is the way to give a
|
|
144
|
+
terminal session a desktop without closing it.
|
|
145
|
+
|
|
146
|
+
## A host with no desktop
|
|
147
|
+
|
|
148
|
+
`--ssh` opens a session that is a terminal and nothing else — no RDP handshake
|
|
149
|
+
to wait for, and none to fail. Port 22 implies it.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npx ai-remote open 192.168.1.60 --ssh -u deploy
|
|
153
|
+
npx ai-remote exec "systemctl status nginx"
|
|
154
|
+
npx ai-remote close
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`exec`, `shell`, `status`, `view` and `close` work as usual; `shot`, `click`,
|
|
158
|
+
`type`, `key` and `do` say there is no desktop, because there is not one.
|
|
159
|
+
|
|
160
|
+
The session lasts until `close`, not until the terminal does: if the host drops
|
|
161
|
+
the connection, the next `exec` opens another one and the session name, the
|
|
162
|
+
account and the keys stay put.
|
|
163
|
+
|
|
164
|
+
**Keys before passwords.** With no `--identity`, ssh-agent is asked for what it
|
|
165
|
+
holds and `~/.ssh/id_ed25519`, `id_ecdsa` and `id_rsa` are read when they have
|
|
166
|
+
no passphrase — so a host that already takes your key needs no environment
|
|
167
|
+
variable at all. `-i FILE` names a key instead, and repeats. A key with a
|
|
168
|
+
passphrase is never read off disk: `ssh-add` it, and it is offered from the
|
|
169
|
+
agent.
|
|
170
|
+
|
|
129
171
|
## Sessions
|
|
130
172
|
|
|
131
173
|
The session opened last is the one commands drive. With several open, name them:
|
|
@@ -192,7 +234,10 @@ start a session implicitly, because they have no host to start one with.
|
|
|
192
234
|
**Credentials rejected (11), or a session that stops before it is ready.** —
|
|
193
235
|
Almost always `AI_REMOTE_PASSWORD` missing from *this* shell. It is deliberately
|
|
194
236
|
not a flag, and it does not carry across terminals; export it again. `open` says
|
|
195
|
-
so explicitly when it sees the host ask for NLA and finds no password.
|
|
237
|
+
so explicitly when it sees the host ask for NLA and finds no password. Over SSH
|
|
238
|
+
the other half of the answer is a key: `ssh-add ~/.ssh/id_ed25519`, or
|
|
239
|
+
`-i FILE`. The session's log names every key it offered and every key it passed
|
|
240
|
+
over, and why.
|
|
196
241
|
|
|
197
242
|
**Unreachable (10).** — `ai-remote probe <host>` is the one command besides
|
|
198
243
|
`open` that still takes an address: it answers whether anything is listening
|
|
@@ -213,6 +258,9 @@ what `status` reports rather than what you asked for.
|
|
|
213
258
|
```bash
|
|
214
259
|
export AI_REMOTE_PASSWORD=...
|
|
215
260
|
npx ai-remote open HOST[:PORT] -u USER [-d DOMAIN] [--session NAME] [--headless] [--watch-only]
|
|
261
|
+
npx ai-remote open HOST --ssh -u USER [-i ~/.ssh/id_ed25519] # a terminal, no desktop
|
|
262
|
+
npx ai-remote open HOST --vnc -u USER # a screen over VNC
|
|
263
|
+
npx ai-remote vnc # ...or add one to this session
|
|
216
264
|
npx ai-remote shot [-o FILE] [--max-edge N] [--json]
|
|
217
265
|
npx ai-remote click X,Y [--button right|middle] [--double]
|
|
218
266
|
npx ai-remote type "text"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apple's Diffie-Hellman, which is how macOS Screen Sharing signs somebody in.
|
|
3
|
+
*
|
|
4
|
+
* Security type 30: the host sends a generator, a prime and its public value;
|
|
5
|
+
* the client agrees a secret, keys AES with it, and sends back the account and
|
|
6
|
+
* password encrypted under that key followed by its own public value. None of
|
|
7
|
+
* it is negotiable -- the order, the widths and the padding are Apple's, and
|
|
8
|
+
* noVNC's `_negotiateARDAuth` is the reference every implementation follows.
|
|
9
|
+
*
|
|
10
|
+
* An entrypoint of its own because two very different programs need it: the
|
|
11
|
+
* Worker performs this exchange on behalf of a browser, and the CLI performs it
|
|
12
|
+
* for itself. One wire format, one implementation -- there is no version of
|
|
13
|
+
* this that is safe to have two of.
|
|
14
|
+
*
|
|
15
|
+
* Node's crypto rather than Web Crypto, because the exchange needs MD5 and
|
|
16
|
+
* single-block AES-ECB and Web Crypto has neither. Both callers run somewhere
|
|
17
|
+
* that has it: the CLI is Node, and the Worker runs with `nodejs_compat`.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The answer to a host's key exchange.
|
|
21
|
+
*
|
|
22
|
+
* `params` is what the host sent: two bytes of generator, two of key length,
|
|
23
|
+
* then the prime and the host's public value at that length -- 1028 bytes on a
|
|
24
|
+
* Mac. What comes back is the encrypted credentials first and this end's public
|
|
25
|
+
* value after, which is 640 bytes for the same Mac.
|
|
26
|
+
*/
|
|
27
|
+
export declare function appleDhResponse(params: Uint8Array, username: string, password: string): Uint8Array;
|
package/dist/apple-dh.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createCipheriv as B,createHash as p,randomBytes as w}from"node:crypto";var u=(e,i,n)=>{let r=1n,t=e%n,o=i;for(;o>0n;)o%2n===1n&&(r=r*t%n),o/=2n,t=t*t%n;return r},s=e=>e.reduce((i,n)=>i<<8n|BigInt(n),0n);function l(e,i){let n=new Uint8Array(i),r=e;for(let t=i-1;t>=0&&r>0n;t--)n[t]=Number(r&0xffn),r>>=8n;return n}function U(e,i,n){if(e.length<4)throw new Error(`Apple DH parameters are too short: ${e.length} bytes.`);let r=BigInt(e[0]<<8|e[1]),t=e[2]<<8|e[3];if(t===0||e.length<4+t*2)throw new Error(`Apple DH parameters are truncated: a ${t}-byte prime needs ${4+t*2} bytes, and ${e.length} arrived.`);let o=s(e.subarray(4,4+t)),y=s(e.subarray(4+t,4+t*2)),a=s(w(t)),d=l(u(r,a,o),t),g=l(u(y,a,o),t),b=p("md5").update(g).digest(),c=Buffer.alloc(128,0);Buffer.from(i,"utf8").subarray(0,63).copy(c,0),Buffer.from(n,"utf8").subarray(0,63).copy(c,64);let f=B("aes-128-ecb",b,Buffer.alloc(0));f.setAutoPadding(!1);let h=Buffer.concat([f.update(c),f.final()]);return new Uint8Array(Buffer.concat([h,Buffer.from(d)]))}export{U as appleDhResponse};
|