@thenewlabs/entangle-connect 1.0.0 → 2.0.1
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/dist/connection.d.ts +69 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +250 -0
- package/dist/connection.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/single.d.ts.map +1 -1
- package/dist/single.js +40 -194
- package/dist/single.js.map +1 -1
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +41 -237
- package/dist/terminal.js.map +1 -1
- package/package.json +5 -5
- package/dist/run.d.ts +0 -14
- package/dist/run.d.ts.map +0 -1
- package/dist/run.js +0 -122
- package/dist/run.js.map +0 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export type SignalName = 'SIGINT' | 'SIGTERM' | 'SIGHUP' | 'SIGQUIT' | 'SIGKILL';
|
|
2
|
+
export interface StreamHandlers {
|
|
3
|
+
onOpened?: () => void;
|
|
4
|
+
onData?: (chunk: Uint8Array, channel: 'stdout' | 'stderr') => void;
|
|
5
|
+
onExit?: (code: number | null, signal: string | null) => void;
|
|
6
|
+
onError?: (message: string) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A live stream. `sid` starts as a provisional client id and is rebound to the
|
|
10
|
+
* agent-assigned id once the `opened` confirmation arrives; all writes use the
|
|
11
|
+
* current `sid`, so callers should write after `onOpened`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class StreamHandle {
|
|
14
|
+
sid: string;
|
|
15
|
+
private conn;
|
|
16
|
+
constructor(sid: string, conn: InvokeConnection);
|
|
17
|
+
write(chunk: Uint8Array): void;
|
|
18
|
+
signal(sig: SignalName): void;
|
|
19
|
+
resize(cols: number, rows: number): void;
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Node-side connection to an entangle agent via the blind relay. Implements
|
|
24
|
+
* the v2 handshake (per-session keys bound to the fresh nonces, client-side
|
|
25
|
+
* verification of the echoed nonceB and expiry) and the multi-stream data
|
|
26
|
+
* protocol. Both single-command and terminal invokers build on this.
|
|
27
|
+
*/
|
|
28
|
+
export declare class InvokeConnection {
|
|
29
|
+
private capId;
|
|
30
|
+
private S;
|
|
31
|
+
private password?;
|
|
32
|
+
private ws;
|
|
33
|
+
private reader;
|
|
34
|
+
private K_raw;
|
|
35
|
+
private bootstrapKeys;
|
|
36
|
+
private sessionKeys;
|
|
37
|
+
private counters;
|
|
38
|
+
private streamCounters;
|
|
39
|
+
private nonceB;
|
|
40
|
+
private authenticated;
|
|
41
|
+
private passwordVerified;
|
|
42
|
+
private requiresPassword;
|
|
43
|
+
private streams;
|
|
44
|
+
private pendingOpens;
|
|
45
|
+
private onCloseCb?;
|
|
46
|
+
constructor(capId: string, S: string, password?: string | undefined);
|
|
47
|
+
/** Connect and complete the handshake (including password if required). */
|
|
48
|
+
connect(wsUrl: string): Promise<void>;
|
|
49
|
+
private handleHandshakeFrame;
|
|
50
|
+
private dispatchStreamFrame;
|
|
51
|
+
private sendStream;
|
|
52
|
+
/** Open a command stream. */
|
|
53
|
+
openCmd(argv: string[], options?: {
|
|
54
|
+
cwd?: string;
|
|
55
|
+
}, handlers?: StreamHandlers): StreamHandle;
|
|
56
|
+
/** Open a PTY stream. */
|
|
57
|
+
openPty(options: {
|
|
58
|
+
cols: number;
|
|
59
|
+
rows: number;
|
|
60
|
+
cwd?: string;
|
|
61
|
+
}, handlers?: StreamHandlers): StreamHandle;
|
|
62
|
+
sendData(sid: string, chunk: Uint8Array): void;
|
|
63
|
+
sendSignal(sid: string, signal: SignalName): void;
|
|
64
|
+
sendResize(sid: string, cols: number, rows: number): void;
|
|
65
|
+
close(sid: string): void;
|
|
66
|
+
onClose(cb: () => void): void;
|
|
67
|
+
disconnect(): void;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEjF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAC;IACnE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9D,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACJ,GAAG,EAAE,MAAM;IAAE,OAAO,CAAC,IAAI;gBAAzB,GAAG,EAAE,MAAM,EAAU,IAAI,EAAE,gBAAgB;IAC9D,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAC9B,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAC7B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IACxC,KAAK,IAAI,IAAI;CACd;AAOD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAiBzB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,CAAC;IACT,OAAO,CAAC,QAAQ,CAAC;IAlBnB,OAAO,CAAC,EAAE,CAAa;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAa;gBAGrB,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,MAAM,EACT,QAAQ,CAAC,EAAE,MAAM,YAAA;IAG3B,2EAA2E;IACrE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAsC7B,oBAAoB;YAiEpB,mBAAmB;YAiDnB,UAAU;IASxB,6BAA6B;IAC7B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAO,EAAE,QAAQ,GAAE,cAAmB,GAAG,YAAY;IAWpG,yBAAyB;IACzB,OAAO,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,QAAQ,GAAE,cAAmB,GAAG,YAAY;IAY3G,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAI9C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAIjD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IAI7B,UAAU,IAAI,IAAI;CAGnB"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
import { randomBytes } from 'crypto';
|
|
3
|
+
import { FrameType, FrameReader, encodeFrame, } from '@thenewlabs/entangle-protocol';
|
|
4
|
+
import { deriveKeyMaterial, deriveBootstrapKeys, deriveSessionKeys, extractSaltFromCapId, aeadEncrypt, aeadDecrypt, computeHmac, streamAeadEncrypt, streamAeadDecrypt, frameAad, AeadDir, } from '@thenewlabs/entangle-crypto';
|
|
5
|
+
import { BidirectionalCounters, StreamCounters } from '@thenewlabs/entangle-utils';
|
|
6
|
+
import { encode, decode } from 'cborg';
|
|
7
|
+
/**
|
|
8
|
+
* A live stream. `sid` starts as a provisional client id and is rebound to the
|
|
9
|
+
* agent-assigned id once the `opened` confirmation arrives; all writes use the
|
|
10
|
+
* current `sid`, so callers should write after `onOpened`.
|
|
11
|
+
*/
|
|
12
|
+
export class StreamHandle {
|
|
13
|
+
sid;
|
|
14
|
+
conn;
|
|
15
|
+
constructor(sid, conn) {
|
|
16
|
+
this.sid = sid;
|
|
17
|
+
this.conn = conn;
|
|
18
|
+
}
|
|
19
|
+
write(chunk) { this.conn.sendData(this.sid, chunk); }
|
|
20
|
+
signal(sig) { this.conn.sendSignal(this.sid, sig); }
|
|
21
|
+
resize(cols, rows) { this.conn.sendResize(this.sid, cols, rows); }
|
|
22
|
+
close() { this.conn.close(this.sid); }
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Node-side connection to an entangle agent via the blind relay. Implements
|
|
26
|
+
* the v2 handshake (per-session keys bound to the fresh nonces, client-side
|
|
27
|
+
* verification of the echoed nonceB and expiry) and the multi-stream data
|
|
28
|
+
* protocol. Both single-command and terminal invokers build on this.
|
|
29
|
+
*/
|
|
30
|
+
export class InvokeConnection {
|
|
31
|
+
capId;
|
|
32
|
+
S;
|
|
33
|
+
password;
|
|
34
|
+
ws;
|
|
35
|
+
reader = new FrameReader();
|
|
36
|
+
K_raw;
|
|
37
|
+
bootstrapKeys;
|
|
38
|
+
sessionKeys;
|
|
39
|
+
counters = new BidirectionalCounters();
|
|
40
|
+
streamCounters = new StreamCounters();
|
|
41
|
+
nonceB;
|
|
42
|
+
authenticated = false;
|
|
43
|
+
passwordVerified = false;
|
|
44
|
+
requiresPassword = false;
|
|
45
|
+
streams = new Map();
|
|
46
|
+
pendingOpens = [];
|
|
47
|
+
onCloseCb;
|
|
48
|
+
constructor(capId, S, password) {
|
|
49
|
+
this.capId = capId;
|
|
50
|
+
this.S = S;
|
|
51
|
+
this.password = password;
|
|
52
|
+
}
|
|
53
|
+
/** Connect and complete the handshake (including password if required). */
|
|
54
|
+
async connect(wsUrl) {
|
|
55
|
+
const saltCap = extractSaltFromCapId(this.capId);
|
|
56
|
+
this.K_raw = await deriveKeyMaterial(this.S, saltCap);
|
|
57
|
+
this.bootstrapKeys = deriveBootstrapKeys(this.K_raw);
|
|
58
|
+
this.ws = new WebSocket(wsUrl);
|
|
59
|
+
await new Promise((resolve, reject) => {
|
|
60
|
+
const fail = (err) => { try {
|
|
61
|
+
this.ws.close();
|
|
62
|
+
}
|
|
63
|
+
catch { } reject(err); };
|
|
64
|
+
this.ws.on('open', () => {
|
|
65
|
+
// AUTH1 = HMAC(bootstrap K_auth, "hello"+capId+nonceB) || nonceB
|
|
66
|
+
this.nonceB = randomBytes(16).toString('hex');
|
|
67
|
+
const auth1Data = new TextEncoder().encode('hello' + this.capId + this.nonceB);
|
|
68
|
+
const hmac = computeHmac(this.bootstrapKeys.K_auth, auth1Data);
|
|
69
|
+
const nonceBBytes = new TextEncoder().encode(this.nonceB);
|
|
70
|
+
const payload = new Uint8Array(32 + nonceBBytes.length);
|
|
71
|
+
payload.set(hmac, 0);
|
|
72
|
+
payload.set(nonceBBytes, 32);
|
|
73
|
+
this.ws.send(encodeFrame(FrameType.AUTH1, payload));
|
|
74
|
+
});
|
|
75
|
+
this.ws.on('message', async (data) => {
|
|
76
|
+
if (!(data instanceof Buffer))
|
|
77
|
+
return;
|
|
78
|
+
for (const frame of this.reader.push(data)) {
|
|
79
|
+
try {
|
|
80
|
+
await this.handleHandshakeFrame(frame, resolve, fail);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
fail(err instanceof Error ? err : new Error(String(err)));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
this.ws.on('error', (err) => fail(err instanceof Error ? err : new Error(String(err))));
|
|
88
|
+
this.ws.on('close', () => { this.onCloseCb?.(); });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async handleHandshakeFrame(frame, resolve, fail) {
|
|
92
|
+
if (frame.type === FrameType.AUTH2 && !this.authenticated) {
|
|
93
|
+
const encrypted = decode(frame.payload);
|
|
94
|
+
// AUTH2 is protected with the bootstrap key.
|
|
95
|
+
const decrypted = aeadDecrypt(this.bootstrapKeys.K_enc, FrameType.AUTH2, encrypted.nonce, encrypted.cipher, AeadDir.ServerToClient);
|
|
96
|
+
const auth2 = decrypted.msg;
|
|
97
|
+
// Freshness checks: the agent must echo OUR nonceB and the session must
|
|
98
|
+
// not be expired. This is what rejects a relay replaying a stale AUTH2.
|
|
99
|
+
if (auth2.nonceB !== this.nonceB) {
|
|
100
|
+
return fail(new Error('AUTH2 nonce mismatch (possible replay)'));
|
|
101
|
+
}
|
|
102
|
+
if (typeof auth2.expiryTs !== 'number' || auth2.expiryTs <= Date.now()) {
|
|
103
|
+
return fail(new Error('AUTH2 expired'));
|
|
104
|
+
}
|
|
105
|
+
this.sessionKeys = deriveSessionKeys(this.K_raw, this.nonceB, auth2.nonceC);
|
|
106
|
+
this.requiresPassword = !!auth2.requiresPassword;
|
|
107
|
+
// AUTH3 HMAC keyed with the SESSION key.
|
|
108
|
+
const auth3Data = new TextEncoder().encode('ready' + auth2.nonceC);
|
|
109
|
+
const auth3Hmac = computeHmac(this.sessionKeys.K_auth, auth3Data);
|
|
110
|
+
this.ws.send(encodeFrame(FrameType.AUTH3, auth3Hmac));
|
|
111
|
+
this.authenticated = true;
|
|
112
|
+
if (this.requiresPassword) {
|
|
113
|
+
if (!this.password)
|
|
114
|
+
return fail(new Error('Password required but not provided'));
|
|
115
|
+
const ctr = this.counters.outgoing.next();
|
|
116
|
+
const enc = aeadEncrypt(this.sessionKeys.K_enc, FrameType.AUTH_PW, ctr, { password: this.password }, AeadDir.ClientToServer);
|
|
117
|
+
this.ws.send(encodeFrame(FrameType.AUTH_PW, encode(enc)));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.passwordVerified = true;
|
|
121
|
+
resolve();
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (frame.type === FrameType.AUTH_PW && this.authenticated && !this.passwordVerified) {
|
|
126
|
+
const encrypted = decode(frame.payload);
|
|
127
|
+
const decrypted = aeadDecrypt(this.sessionKeys.K_enc, FrameType.AUTH_PW, encrypted.nonce, encrypted.cipher, AeadDir.ServerToClient);
|
|
128
|
+
this.counters.incoming.validate(decrypted.ctr);
|
|
129
|
+
if (decrypted.msg?.ok) {
|
|
130
|
+
this.passwordVerified = true;
|
|
131
|
+
resolve();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
fail(new Error('Password verification failed'));
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (frame.type === FrameType.ERROR) {
|
|
139
|
+
const encrypted = decode(frame.payload);
|
|
140
|
+
const decrypted = aeadDecrypt(this.sessionKeys?.K_enc ?? this.bootstrapKeys.K_enc, FrameType.ERROR, encrypted.nonce, encrypted.cipher, AeadDir.ServerToClient);
|
|
141
|
+
fail(new Error(`Server error: ${decrypted.msg?.code} - ${decrypted.msg?.detail}`));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// Post-handshake stream frames.
|
|
145
|
+
await this.dispatchStreamFrame(frame);
|
|
146
|
+
}
|
|
147
|
+
async dispatchStreamFrame(frame) {
|
|
148
|
+
if (!this.sessionKeys)
|
|
149
|
+
return;
|
|
150
|
+
const aad = frameAad(frame.type, AeadDir.ServerToClient);
|
|
151
|
+
const plaintext = await streamAeadDecrypt(this.sessionKeys.K_enc, frame.payload, aad);
|
|
152
|
+
const message = decode(plaintext);
|
|
153
|
+
const sid = message?.msg?.sid;
|
|
154
|
+
if (!sid)
|
|
155
|
+
return;
|
|
156
|
+
// Per-stream incoming counter (drop out-of-order/replayed frames).
|
|
157
|
+
const expected = this.streamCounters.getNext(sid, 'incoming');
|
|
158
|
+
if (message.ctr !== expected)
|
|
159
|
+
return;
|
|
160
|
+
this.streamCounters.increment(sid, 'incoming');
|
|
161
|
+
switch (frame.type) {
|
|
162
|
+
case FrameType.STREAM_OPEN: {
|
|
163
|
+
if (message.msg.kind === 'opened') {
|
|
164
|
+
const pending = this.pendingOpens.shift();
|
|
165
|
+
if (pending) {
|
|
166
|
+
pending.handle.sid = sid; // rebind to agent-assigned id
|
|
167
|
+
this.streams.set(sid, pending.handlers);
|
|
168
|
+
pending.handlers.onOpened?.();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case FrameType.STREAM_DATA:
|
|
174
|
+
this.streams.get(sid)?.onData?.(new Uint8Array(message.msg.chunk), message.msg.channel === 'stderr' ? 'stderr' : 'stdout');
|
|
175
|
+
break;
|
|
176
|
+
case FrameType.STREAM_EXIT: {
|
|
177
|
+
const h = this.streams.get(sid);
|
|
178
|
+
this.streamCounters.removeStream(sid);
|
|
179
|
+
this.streams.delete(sid);
|
|
180
|
+
h?.onExit?.(message.msg.code ?? null, message.msg.signal ?? null);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case FrameType.STREAM_ERROR: {
|
|
184
|
+
// An error can arrive before `opened` (e.g. the agent rejected the
|
|
185
|
+
// open); in that case the stream is still pending under this sid.
|
|
186
|
+
let handlers = this.streams.get(sid);
|
|
187
|
+
if (!handlers) {
|
|
188
|
+
const idx = this.pendingOpens.findIndex((p) => p.handle.sid === sid);
|
|
189
|
+
if (idx >= 0)
|
|
190
|
+
handlers = this.pendingOpens.splice(idx, 1)[0].handlers;
|
|
191
|
+
}
|
|
192
|
+
handlers?.onError?.(message.msg.message || 'stream error');
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async sendStream(type, sid, msgBody) {
|
|
198
|
+
const ctr = this.streamCounters.getNext(sid, 'outgoing');
|
|
199
|
+
const plaintext = encode({ ctr, msg: { v: 1, sid, ...msgBody } });
|
|
200
|
+
const aad = frameAad(type, AeadDir.ClientToServer);
|
|
201
|
+
const ct = await streamAeadEncrypt(this.sessionKeys.K_enc, plaintext, aad);
|
|
202
|
+
this.ws.send(encodeFrame(type, ct));
|
|
203
|
+
this.streamCounters.increment(sid, 'outgoing');
|
|
204
|
+
}
|
|
205
|
+
/** Open a command stream. */
|
|
206
|
+
openCmd(argv, options = {}, handlers = {}) {
|
|
207
|
+
const handle = new StreamHandle(randomBytes(8).toString('hex'), this);
|
|
208
|
+
this.pendingOpens.push({ handle, handlers });
|
|
209
|
+
void this.sendStream(FrameType.STREAM_OPEN, handle.sid, {
|
|
210
|
+
kind: 'open',
|
|
211
|
+
mode: 'cmd',
|
|
212
|
+
exec: { argv, ...(options.cwd ? { cwd: options.cwd } : {}), stdin: true },
|
|
213
|
+
});
|
|
214
|
+
return handle;
|
|
215
|
+
}
|
|
216
|
+
/** Open a PTY stream. */
|
|
217
|
+
openPty(options, handlers = {}) {
|
|
218
|
+
const handle = new StreamHandle(randomBytes(8).toString('hex'), this);
|
|
219
|
+
this.pendingOpens.push({ handle, handlers });
|
|
220
|
+
void this.sendStream(FrameType.STREAM_OPEN, handle.sid, {
|
|
221
|
+
kind: 'open',
|
|
222
|
+
mode: 'pty',
|
|
223
|
+
pty: { cols: options.cols, rows: options.rows },
|
|
224
|
+
...(options.cwd ? { exec: { argv: [], cwd: options.cwd } } : {}),
|
|
225
|
+
});
|
|
226
|
+
return handle;
|
|
227
|
+
}
|
|
228
|
+
sendData(sid, chunk) {
|
|
229
|
+
void this.sendStream(FrameType.STREAM_DATA, sid, { kind: 'data', chunk });
|
|
230
|
+
}
|
|
231
|
+
sendSignal(sid, signal) {
|
|
232
|
+
void this.sendStream(FrameType.STREAM_SIGNAL, sid, { kind: 'signal', signal });
|
|
233
|
+
}
|
|
234
|
+
sendResize(sid, cols, rows) {
|
|
235
|
+
void this.sendStream(FrameType.STREAM_RESIZE, sid, { kind: 'pty-resize', cols, rows });
|
|
236
|
+
}
|
|
237
|
+
close(sid) {
|
|
238
|
+
void this.sendStream(FrameType.STREAM_CLOSE, sid, { kind: 'close' });
|
|
239
|
+
}
|
|
240
|
+
onClose(cb) {
|
|
241
|
+
this.onCloseCb = cb;
|
|
242
|
+
}
|
|
243
|
+
disconnect() {
|
|
244
|
+
try {
|
|
245
|
+
this.ws.close();
|
|
246
|
+
}
|
|
247
|
+
catch { }
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,12 @@ function parseCapUrl(u) {
|
|
|
27
27
|
const program = new Command();
|
|
28
28
|
program
|
|
29
29
|
.name('entangle-connect')
|
|
30
|
+
// Everything after <cap-url> is the remote command verbatim, so flags like
|
|
31
|
+
// `ls -la` or `sh -c '...'` are passed through instead of being parsed as
|
|
32
|
+
// entangle-connect options. entangle-connect's own options go before the URL
|
|
33
|
+
// (e.g. `entangle-connect --cwd /srv <url> ls -la`); `--` also works.
|
|
34
|
+
.enablePositionalOptions()
|
|
35
|
+
.passThroughOptions()
|
|
30
36
|
.description('Invoke commands or terminal sessions on remote capabilities')
|
|
31
37
|
.version(getVersionInfo())
|
|
32
38
|
.argument('<cap-url>', 'Capability URL (e.g., https://suncoder.dev/cap/capId#S=secret)')
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,SAAS,WAAW,CAAC,CAAS;IAC5B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEtC,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,0CAA0C;IAC1C,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;IAEnD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK;QACL,CAAC,EAAE,CAAC;QACJ,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/single.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../src/single.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../src/single.ts"],"names":[],"mappings":"AAKA,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,MAAM,EACT,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EACxF,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAuDf"}
|
package/dist/single.js
CHANGED
|
@@ -1,209 +1,55 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { FrameType, FrameReader, encodeFrame } from '@thenewlabs/entangle-protocol';
|
|
4
|
-
import { OutputHandler, parseOutputMode, BidirectionalCounters } from '@thenewlabs/entangle-utils';
|
|
5
|
-
import { encode, decode } from 'cborg';
|
|
1
|
+
import { OutputHandler, parseOutputMode } from '@thenewlabs/entangle-utils';
|
|
2
|
+
import { InvokeConnection } from './connection.js';
|
|
6
3
|
const output = new OutputHandler({ mode: parseOutputMode(process.env.OUTPUT_MODE || 'text') });
|
|
7
4
|
export async function runSingle(wsUrl, S, options, password) {
|
|
8
5
|
const { argv, cwd, abortAfterMs } = options;
|
|
9
6
|
if (!argv || argv.length === 0) {
|
|
10
7
|
throw new Error('No command provided');
|
|
11
8
|
}
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const keys = await deriveKeys(S, saltCap);
|
|
18
|
-
// Connect to relay
|
|
19
|
-
const ws = new WebSocket(wsUrl);
|
|
20
|
-
const reader = new FrameReader();
|
|
21
|
-
const counters = new BidirectionalCounters();
|
|
22
|
-
// Command ID for this run
|
|
23
|
-
const commandId = Math.random().toString(36).substr(2, 9);
|
|
24
|
-
return new Promise((_, reject) => {
|
|
25
|
-
let abortTimeout;
|
|
26
|
-
ws.on('open', async () => {
|
|
27
|
-
output.info('Connected to relay');
|
|
28
|
-
try {
|
|
29
|
-
// Send AUTH1
|
|
30
|
-
const nonceB = Math.random().toString(36).substr(2);
|
|
31
|
-
const auth1Data = new TextEncoder().encode('hello' + capId + nonceB);
|
|
32
|
-
const auth1Hmac = computeHmac(keys.K_auth, auth1Data);
|
|
33
|
-
// Send HMAC + nonceB
|
|
34
|
-
const nonceBBytes = new TextEncoder().encode(nonceB);
|
|
35
|
-
const auth1Payload = new Uint8Array(32 + nonceBBytes.length);
|
|
36
|
-
auth1Payload.set(auth1Hmac, 0);
|
|
37
|
-
auth1Payload.set(nonceBBytes, 32);
|
|
38
|
-
const auth1Frame = encodeFrame(FrameType.AUTH1, auth1Payload);
|
|
39
|
-
ws.send(auth1Frame);
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
output.error('Failed to send AUTH1', error instanceof Error ? error.message : String(error));
|
|
43
|
-
ws.close();
|
|
44
|
-
reject(error);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
let authenticated = false;
|
|
48
|
-
let passwordVerified = false;
|
|
49
|
-
let requiresPassword = false;
|
|
50
|
-
let nonceC;
|
|
9
|
+
const capId = wsUrl.split('/').pop();
|
|
10
|
+
const conn = new InvokeConnection(capId, S, password);
|
|
11
|
+
await conn.connect(wsUrl);
|
|
12
|
+
output.info('Authenticated');
|
|
13
|
+
await new Promise((_resolve, reject) => {
|
|
51
14
|
let exitCode = 0;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const encrypted = decode(frame.payload);
|
|
61
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.AUTH2, encrypted.nonce, encrypted.cipher);
|
|
62
|
-
const auth2 = decrypted.msg;
|
|
63
|
-
nonceC = auth2.nonceC;
|
|
64
|
-
requiresPassword = auth2.requiresPassword || false;
|
|
65
|
-
// Send AUTH3
|
|
66
|
-
const auth3Data = new TextEncoder().encode('ready' + nonceC);
|
|
67
|
-
const auth3Hmac = computeHmac(keys.K_auth, auth3Data);
|
|
68
|
-
const auth3Frame = encodeFrame(FrameType.AUTH3, auth3Hmac);
|
|
69
|
-
ws.send(auth3Frame);
|
|
70
|
-
authenticated = true;
|
|
71
|
-
output.info('Authenticated');
|
|
72
|
-
// If password is required, send it
|
|
73
|
-
if (requiresPassword) {
|
|
74
|
-
if (!password) {
|
|
75
|
-
// For non-interactive mode, we can't prompt for password
|
|
76
|
-
output.error('Password required but not provided. Use --password flag or include PW in URL fragment.');
|
|
77
|
-
ws.close();
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
80
|
-
output.info('Sending password...');
|
|
81
|
-
const pwMsg = {
|
|
82
|
-
ctr: counters.outgoing.next(),
|
|
83
|
-
msg: { passwordHash: sha256Hex(password) }
|
|
84
|
-
};
|
|
85
|
-
const pwEncrypted = aeadEncrypt(keys.K_enc, FrameType.AUTH_PW, pwMsg.ctr, pwMsg.msg);
|
|
86
|
-
const pwFrame = encodeFrame(FrameType.AUTH_PW, encode(pwEncrypted));
|
|
87
|
-
ws.send(pwFrame);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
passwordVerified = true;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else if (frame.type === FrameType.AUTH_PW && authenticated && !passwordVerified) {
|
|
94
|
-
// Handle password response
|
|
95
|
-
const encrypted = decode(frame.payload);
|
|
96
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.AUTH_PW, encrypted.nonce, encrypted.cipher);
|
|
97
|
-
counters.incoming.validate(decrypted.ctr);
|
|
98
|
-
const pwResponse = decrypted.msg;
|
|
99
|
-
if (pwResponse.ok) {
|
|
100
|
-
output.info('Password verified');
|
|
101
|
-
passwordVerified = true;
|
|
102
|
-
// Now send RUN command
|
|
103
|
-
const runMsg = {
|
|
104
|
-
commandId,
|
|
105
|
-
argv,
|
|
106
|
-
cwd,
|
|
107
|
-
limits: abortAfterMs ? { wallMs: abortAfterMs } : undefined,
|
|
108
|
-
};
|
|
109
|
-
const runEncrypted = aeadEncrypt(keys.K_enc, FrameType.RUN, counters.outgoing.next(), runMsg);
|
|
110
|
-
const runFrame = encodeFrame(FrameType.RUN, encode(runEncrypted));
|
|
111
|
-
ws.send(runFrame);
|
|
112
|
-
// Set abort timeout if specified
|
|
113
|
-
if (abortAfterMs) {
|
|
114
|
-
abortTimeout = setTimeout(() => {
|
|
115
|
-
output.info('Aborting command due to timeout');
|
|
116
|
-
const abortMsg = {
|
|
117
|
-
commandId,
|
|
118
|
-
reason: 'timeout',
|
|
119
|
-
};
|
|
120
|
-
const abortEncrypted = aeadEncrypt(keys.K_enc, FrameType.ABORT, counters.outgoing.next(), abortMsg);
|
|
121
|
-
const abortFrame = encodeFrame(FrameType.ABORT, encode(abortEncrypted));
|
|
122
|
-
ws.send(abortFrame);
|
|
123
|
-
}, abortAfterMs);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
output.error('Password verification failed');
|
|
128
|
-
ws.close();
|
|
129
|
-
process.exit(1);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
else if (frame.type === FrameType.STDOUT && authenticated) {
|
|
133
|
-
// Handle stdout
|
|
134
|
-
const encrypted = decode(frame.payload);
|
|
135
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.STDOUT, encrypted.nonce, encrypted.cipher);
|
|
136
|
-
counters.incoming.validate(decrypted.ctr);
|
|
137
|
-
const msg = decrypted.msg;
|
|
138
|
-
if (msg.commandId === commandId) {
|
|
139
|
-
process.stdout.write(Buffer.from(msg.chunk));
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
else if (frame.type === FrameType.STDERR && authenticated) {
|
|
143
|
-
// Handle stderr
|
|
144
|
-
const encrypted = decode(frame.payload);
|
|
145
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.STDERR, encrypted.nonce, encrypted.cipher);
|
|
146
|
-
counters.incoming.validate(decrypted.ctr);
|
|
147
|
-
const msg = decrypted.msg;
|
|
148
|
-
if (msg.commandId === commandId) {
|
|
149
|
-
process.stderr.write(Buffer.from(msg.chunk));
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
else if (frame.type === FrameType.EXIT && authenticated) {
|
|
153
|
-
// Handle exit
|
|
154
|
-
const encrypted = decode(frame.payload);
|
|
155
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.EXIT, encrypted.nonce, encrypted.cipher);
|
|
156
|
-
counters.incoming.validate(decrypted.ctr);
|
|
157
|
-
const msg = decrypted.msg;
|
|
158
|
-
if (msg.commandId === commandId) {
|
|
159
|
-
exitCode = msg.code ?? 1;
|
|
160
|
-
output.info(`Command exited: code=${msg.code}, signal=${msg.signal}, bytesOut=${msg.bytesOut}`);
|
|
161
|
-
if (abortTimeout) {
|
|
162
|
-
clearTimeout(abortTimeout);
|
|
163
|
-
}
|
|
164
|
-
ws.close();
|
|
165
|
-
process.exit(exitCode);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else if (frame.type === FrameType.ERROR) {
|
|
169
|
-
// Handle error
|
|
170
|
-
const encrypted = decode(frame.payload);
|
|
171
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.ERROR, encrypted.nonce, encrypted.cipher);
|
|
172
|
-
const error = decrypted.msg;
|
|
173
|
-
output.error('Server error', error instanceof Error ? error.message : String(error));
|
|
174
|
-
ws.close();
|
|
175
|
-
reject(new Error(`Server error: ${error.code} - ${error.detail}`));
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
output.error(`Failed to handle frame type ${frame.type}`, error instanceof Error ? error.message : String(error));
|
|
15
|
+
let abortTimer;
|
|
16
|
+
const handle = conn.openCmd(argv, cwd ? { cwd } : {}, {
|
|
17
|
+
onOpened: () => {
|
|
18
|
+
if (abortAfterMs) {
|
|
19
|
+
abortTimer = setTimeout(() => {
|
|
20
|
+
output.info('Aborting command due to timeout');
|
|
21
|
+
handle.signal('SIGTERM');
|
|
22
|
+
}, abortAfterMs);
|
|
180
23
|
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
24
|
+
},
|
|
25
|
+
onData: (chunk, channel) => {
|
|
26
|
+
(channel === 'stderr' ? process.stderr : process.stdout).write(Buffer.from(chunk));
|
|
27
|
+
},
|
|
28
|
+
onExit: (code, signal) => {
|
|
29
|
+
exitCode = code ?? 1;
|
|
30
|
+
output.info(`Command exited: code=${code}, signal=${signal}`);
|
|
31
|
+
if (abortTimer)
|
|
32
|
+
clearTimeout(abortTimer);
|
|
33
|
+
conn.disconnect();
|
|
34
|
+
process.exit(exitCode);
|
|
35
|
+
},
|
|
36
|
+
onError: (message) => {
|
|
37
|
+
output.error('Stream error', message);
|
|
38
|
+
if (abortTimer)
|
|
39
|
+
clearTimeout(abortTimer);
|
|
40
|
+
conn.disconnect();
|
|
41
|
+
reject(new Error(message));
|
|
42
|
+
},
|
|
186
43
|
});
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
clearTimeout(abortTimeout);
|
|
191
|
-
}
|
|
44
|
+
conn.onClose(() => {
|
|
45
|
+
if (abortTimer)
|
|
46
|
+
clearTimeout(abortTimer);
|
|
192
47
|
process.exit(exitCode);
|
|
193
48
|
});
|
|
194
|
-
// Handle SIGINT
|
|
195
49
|
process.on('SIGINT', () => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
reason: 'user interrupt',
|
|
200
|
-
};
|
|
201
|
-
const sigintEncrypted = aeadEncrypt(keys.K_enc, FrameType.ABORT, counters.outgoing.next(), abortMsg);
|
|
202
|
-
const sigintFrame = encodeFrame(FrameType.ABORT, encode(sigintEncrypted));
|
|
203
|
-
ws.send(sigintFrame);
|
|
204
|
-
}
|
|
205
|
-
ws.close();
|
|
206
|
-
process.exit(130); // 128 + SIGINT(2)
|
|
50
|
+
handle.signal('SIGINT');
|
|
51
|
+
conn.disconnect();
|
|
52
|
+
process.exit(130);
|
|
207
53
|
});
|
|
208
54
|
});
|
|
209
55
|
}
|
package/dist/single.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single.js","sourceRoot":"","sources":["../src/single.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"single.js","sourceRoot":"","sources":["../src/single.ts"],"names":[],"mappings":"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"}
|
package/dist/terminal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,MAAM,EACT,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EAC3F,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
|
package/dist/terminal.js
CHANGED
|
@@ -1,247 +1,51 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { FrameType, FrameReader, encodeFrame } from '@thenewlabs/entangle-protocol';
|
|
4
|
-
import { OutputHandler, parseOutputMode, BidirectionalCounters } from '@thenewlabs/entangle-utils';
|
|
5
|
-
import { encode, decode } from 'cborg';
|
|
6
|
-
// import * as readline from 'readline';
|
|
1
|
+
import { OutputHandler, parseOutputMode } from '@thenewlabs/entangle-utils';
|
|
2
|
+
import { InvokeConnection } from './connection.js';
|
|
7
3
|
const output = new OutputHandler({ mode: parseOutputMode(process.env.OUTPUT_MODE || 'text') });
|
|
8
4
|
export async function openTerminal(wsUrl, S, options, password) {
|
|
9
5
|
const { cwd, cols = 80, rows = 24 } = options;
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const ws = new WebSocket(wsUrl);
|
|
18
|
-
const reader = new FrameReader();
|
|
19
|
-
const counters = new BidirectionalCounters();
|
|
20
|
-
// Session ID for this terminal session
|
|
21
|
-
const sessionId = Math.random().toString(36).substr(2, 9);
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
ws.on('open', async () => {
|
|
24
|
-
output.info('Connected to relay');
|
|
25
|
-
try {
|
|
26
|
-
// Send AUTH1
|
|
27
|
-
const nonceB = Math.random().toString(36).substr(2);
|
|
28
|
-
const auth1Data = new TextEncoder().encode('hello' + capId + nonceB);
|
|
29
|
-
const auth1Hmac = computeHmac(keys.K_auth, auth1Data);
|
|
30
|
-
// Send HMAC + nonceB
|
|
31
|
-
const nonceBBytes = new TextEncoder().encode(nonceB);
|
|
32
|
-
const auth1Payload = new Uint8Array(32 + nonceBBytes.length);
|
|
33
|
-
auth1Payload.set(auth1Hmac, 0);
|
|
34
|
-
auth1Payload.set(nonceBBytes, 32);
|
|
35
|
-
const auth1Frame = encodeFrame(FrameType.AUTH1, auth1Payload);
|
|
36
|
-
ws.send(auth1Frame);
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
output.error('Failed to send AUTH1', error instanceof Error ? error.message : String(error));
|
|
40
|
-
ws.close();
|
|
41
|
-
reject(error);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
let authenticated = false;
|
|
45
|
-
let passwordVerified = false;
|
|
46
|
-
let requiresPassword = false;
|
|
47
|
-
let nonceC;
|
|
48
|
-
ws.on('message', async (data) => {
|
|
49
|
-
if (!(data instanceof Buffer))
|
|
50
|
-
return;
|
|
51
|
-
const frames = reader.push(data);
|
|
52
|
-
for (const frame of frames) {
|
|
6
|
+
const capId = wsUrl.split('/').pop();
|
|
7
|
+
const conn = new InvokeConnection(capId, S, password);
|
|
8
|
+
await conn.connect(wsUrl);
|
|
9
|
+
output.info('Authenticated');
|
|
10
|
+
await new Promise((resolve) => {
|
|
11
|
+
const cleanup = () => {
|
|
12
|
+
if (process.stdin.isTTY) {
|
|
53
13
|
try {
|
|
54
|
-
|
|
55
|
-
// Handle AUTH2
|
|
56
|
-
const encrypted = decode(frame.payload);
|
|
57
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.AUTH2, encrypted.nonce, encrypted.cipher);
|
|
58
|
-
const auth2 = decrypted.msg;
|
|
59
|
-
nonceC = auth2.nonceC;
|
|
60
|
-
requiresPassword = auth2.requiresPassword || false;
|
|
61
|
-
// Send AUTH3
|
|
62
|
-
const auth3Data = new TextEncoder().encode('ready' + nonceC);
|
|
63
|
-
const auth3Hmac = computeHmac(keys.K_auth, auth3Data);
|
|
64
|
-
const auth3Frame = encodeFrame(FrameType.AUTH3, auth3Hmac);
|
|
65
|
-
ws.send(auth3Frame);
|
|
66
|
-
authenticated = true;
|
|
67
|
-
output.info('Authenticated');
|
|
68
|
-
// If password is required, send it
|
|
69
|
-
if (requiresPassword) {
|
|
70
|
-
if (!password) {
|
|
71
|
-
// Interactive prompt for password
|
|
72
|
-
const readline = await import('readline');
|
|
73
|
-
const rl = readline.createInterface({
|
|
74
|
-
input: process.stdin,
|
|
75
|
-
output: process.stdout
|
|
76
|
-
});
|
|
77
|
-
const passwordPromise = new Promise((resolve) => {
|
|
78
|
-
rl.question('Agent password: ', (answer) => {
|
|
79
|
-
rl.close();
|
|
80
|
-
resolve(answer);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
password = await passwordPromise;
|
|
84
|
-
}
|
|
85
|
-
output.info('Sending password...');
|
|
86
|
-
const pwMsg = {
|
|
87
|
-
ctr: counters.outgoing.next(),
|
|
88
|
-
msg: { passwordHash: sha256Hex(password) }
|
|
89
|
-
};
|
|
90
|
-
const pwEncrypted = aeadEncrypt(keys.K_enc, FrameType.AUTH_PW, pwMsg.ctr, pwMsg.msg);
|
|
91
|
-
const pwFrame = encodeFrame(FrameType.AUTH_PW, encode(pwEncrypted));
|
|
92
|
-
ws.send(pwFrame);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
passwordVerified = true;
|
|
96
|
-
// Send TTY_OPEN immediately if no password required
|
|
97
|
-
const ttyOpen = {
|
|
98
|
-
sessionId,
|
|
99
|
-
cwd,
|
|
100
|
-
cols,
|
|
101
|
-
rows,
|
|
102
|
-
};
|
|
103
|
-
const ttyOpenEncrypted = aeadEncrypt(keys.K_enc, FrameType.TTY_OPEN, counters.outgoing.next(), ttyOpen);
|
|
104
|
-
const ttyOpenFrame = encodeFrame(FrameType.TTY_OPEN, encode(ttyOpenEncrypted));
|
|
105
|
-
ws.send(ttyOpenFrame);
|
|
106
|
-
// Set up terminal input
|
|
107
|
-
setupTerminalInput(ws, keys, counters, sessionId);
|
|
108
|
-
// Handle terminal resize
|
|
109
|
-
process.stdout.on('resize', () => {
|
|
110
|
-
const newCols = process.stdout.columns || 80;
|
|
111
|
-
const newRows = process.stdout.rows || 24;
|
|
112
|
-
const resize = {
|
|
113
|
-
sessionId,
|
|
114
|
-
cols: newCols,
|
|
115
|
-
rows: newRows,
|
|
116
|
-
};
|
|
117
|
-
const resizeEncrypted = aeadEncrypt(keys.K_enc, FrameType.TTY_RESIZE, counters.outgoing.next(), resize);
|
|
118
|
-
const resizeFrame = encodeFrame(FrameType.TTY_RESIZE, encode(resizeEncrypted));
|
|
119
|
-
ws.send(resizeFrame);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else if (frame.type === FrameType.AUTH_PW && authenticated && !passwordVerified) {
|
|
124
|
-
// Handle password response
|
|
125
|
-
const encrypted = decode(frame.payload);
|
|
126
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.AUTH_PW, encrypted.nonce, encrypted.cipher);
|
|
127
|
-
counters.incoming.validate(decrypted.ctr);
|
|
128
|
-
const pwResponse = decrypted.msg;
|
|
129
|
-
if (pwResponse.ok) {
|
|
130
|
-
output.info('Password verified');
|
|
131
|
-
passwordVerified = true;
|
|
132
|
-
// Now send TTY_OPEN
|
|
133
|
-
const ttyOpen = {
|
|
134
|
-
sessionId,
|
|
135
|
-
cwd,
|
|
136
|
-
cols,
|
|
137
|
-
rows,
|
|
138
|
-
};
|
|
139
|
-
const ttyOpenEncrypted = aeadEncrypt(keys.K_enc, FrameType.TTY_OPEN, counters.outgoing.next(), ttyOpen);
|
|
140
|
-
const ttyOpenFrame = encodeFrame(FrameType.TTY_OPEN, encode(ttyOpenEncrypted));
|
|
141
|
-
ws.send(ttyOpenFrame);
|
|
142
|
-
// Set up terminal input
|
|
143
|
-
setupTerminalInput(ws, keys, counters, sessionId);
|
|
144
|
-
// Handle terminal resize
|
|
145
|
-
process.stdout.on('resize', () => {
|
|
146
|
-
const newCols = process.stdout.columns || 80;
|
|
147
|
-
const newRows = process.stdout.rows || 24;
|
|
148
|
-
const resize = {
|
|
149
|
-
sessionId,
|
|
150
|
-
cols: newCols,
|
|
151
|
-
rows: newRows,
|
|
152
|
-
};
|
|
153
|
-
const resizeEncrypted = aeadEncrypt(keys.K_enc, FrameType.TTY_RESIZE, counters.outgoing.next(), resize);
|
|
154
|
-
const resizeFrame = encodeFrame(FrameType.TTY_RESIZE, encode(resizeEncrypted));
|
|
155
|
-
ws.send(resizeFrame);
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
output.error('Password verification failed');
|
|
160
|
-
ws.close();
|
|
161
|
-
reject(new Error('Password verification failed'));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else if (frame.type === FrameType.TTY_DATA && authenticated) {
|
|
165
|
-
// Handle TTY data from server
|
|
166
|
-
const encrypted = decode(frame.payload);
|
|
167
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.TTY_DATA, encrypted.nonce, encrypted.cipher);
|
|
168
|
-
counters.incoming.validate(decrypted.ctr);
|
|
169
|
-
const msg = decrypted.msg;
|
|
170
|
-
if (msg.sessionId === sessionId) {
|
|
171
|
-
process.stdout.write(Buffer.from(msg.chunk));
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
else if (frame.type === FrameType.TTY_EXIT && authenticated) {
|
|
175
|
-
// Handle TTY exit
|
|
176
|
-
const encrypted = decode(frame.payload);
|
|
177
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.TTY_EXIT, encrypted.nonce, encrypted.cipher);
|
|
178
|
-
counters.incoming.validate(decrypted.ctr);
|
|
179
|
-
const msg = decrypted.msg;
|
|
180
|
-
if (msg.sessionId === sessionId) {
|
|
181
|
-
output.info(`Terminal exited: code=${msg.code}, signal=${msg.signal}`);
|
|
182
|
-
ws.close();
|
|
183
|
-
resolve();
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
else if (frame.type === FrameType.ERROR) {
|
|
187
|
-
// Handle error
|
|
188
|
-
const encrypted = decode(frame.payload);
|
|
189
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.ERROR, encrypted.nonce, encrypted.cipher);
|
|
190
|
-
const error = decrypted.msg;
|
|
191
|
-
output.error('Server error', error instanceof Error ? error.message : String(error));
|
|
192
|
-
ws.close();
|
|
193
|
-
reject(new Error(`Server error: ${error.code} - ${error.detail}`));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
catch (error) {
|
|
197
|
-
output.error(`Failed to handle frame type ${frame.type}`, error instanceof Error ? error.message : String(error));
|
|
14
|
+
process.stdin.setRawMode(false);
|
|
198
15
|
}
|
|
16
|
+
catch { }
|
|
199
17
|
}
|
|
200
|
-
|
|
201
|
-
ws.on('error', (error) => {
|
|
202
|
-
output.error('WebSocket error', error instanceof Error ? error.message : String(error));
|
|
203
|
-
reject(error);
|
|
204
|
-
});
|
|
205
|
-
ws.on('close', () => {
|
|
206
|
-
output.info('Disconnected');
|
|
207
|
-
resolve();
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
function setupTerminalInput(ws, keys, counters, sessionId) {
|
|
212
|
-
// Set terminal to raw mode
|
|
213
|
-
if (process.stdin.isTTY) {
|
|
214
|
-
process.stdin.setRawMode(true);
|
|
215
|
-
}
|
|
216
|
-
process.stdin.resume();
|
|
217
|
-
// Handle input
|
|
218
|
-
process.stdin.on('data', (data) => {
|
|
219
|
-
const ttyData = {
|
|
220
|
-
sessionId,
|
|
221
|
-
chunk: new Uint8Array(data),
|
|
18
|
+
process.stdin.pause();
|
|
222
19
|
};
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
20
|
+
const handle = conn.openPty({ cols, rows, ...(cwd ? { cwd } : {}) }, {
|
|
21
|
+
onOpened: () => {
|
|
22
|
+
if (process.stdin.isTTY)
|
|
23
|
+
process.stdin.setRawMode(true);
|
|
24
|
+
process.stdin.resume();
|
|
25
|
+
process.stdin.on('data', (d) => handle.write(new Uint8Array(d)));
|
|
26
|
+
process.stdout.on('resize', () => {
|
|
27
|
+
handle.resize(process.stdout.columns || 80, process.stdout.rows || 24);
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
onData: (chunk) => {
|
|
31
|
+
process.stdout.write(Buffer.from(chunk));
|
|
32
|
+
},
|
|
33
|
+
onExit: (code, signal) => {
|
|
34
|
+
output.info(`Terminal exited: code=${code}, signal=${signal}`);
|
|
35
|
+
cleanup();
|
|
36
|
+
conn.disconnect();
|
|
37
|
+
resolve();
|
|
38
|
+
},
|
|
39
|
+
onError: (message) => {
|
|
40
|
+
output.error('Stream error', message);
|
|
41
|
+
cleanup();
|
|
42
|
+
conn.disconnect();
|
|
43
|
+
resolve();
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
process.on('SIGINT', () => handle.signal('SIGINT'));
|
|
47
|
+
process.on('exit', cleanup);
|
|
48
|
+
conn.onClose(() => { cleanup(); resolve(); });
|
|
236
49
|
});
|
|
237
|
-
// Cleanup on exit
|
|
238
|
-
const cleanup = () => {
|
|
239
|
-
if (process.stdin.isTTY) {
|
|
240
|
-
process.stdin.setRawMode(false);
|
|
241
|
-
}
|
|
242
|
-
process.stdin.pause();
|
|
243
|
-
};
|
|
244
|
-
process.on('exit', cleanup);
|
|
245
|
-
ws.on('close', cleanup);
|
|
246
50
|
}
|
|
247
51
|
//# sourceMappingURL=terminal.js.map
|
package/dist/terminal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thenewlabs/entangle-connect",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
|
-
"clean": "rm -rf dist",
|
|
11
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
12
12
|
"prepublishOnly": "npm run build"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@thenewlabs/entangle-crypto": "^
|
|
16
|
-
"@thenewlabs/entangle-protocol": "^
|
|
17
|
-
"@thenewlabs/entangle-utils": "^
|
|
15
|
+
"@thenewlabs/entangle-crypto": "^2.0.1",
|
|
16
|
+
"@thenewlabs/entangle-protocol": "^2.0.1",
|
|
17
|
+
"@thenewlabs/entangle-utils": "^2.0.1",
|
|
18
18
|
"cborg": "^4.5.8",
|
|
19
19
|
"commander": "^15.0.0",
|
|
20
20
|
"ws": "^8.21.0"
|
package/dist/run.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface RunOptions {
|
|
2
|
-
namespace: string;
|
|
3
|
-
capId: string;
|
|
4
|
-
S: string;
|
|
5
|
-
tool: string;
|
|
6
|
-
argv: string[];
|
|
7
|
-
cwd: string | undefined;
|
|
8
|
-
serverUrl: string;
|
|
9
|
-
abortAfterMs: number | undefined;
|
|
10
|
-
maxOutBytes: number | undefined;
|
|
11
|
-
}
|
|
12
|
-
export declare function runCommand(options: RunOptions): Promise<number>;
|
|
13
|
-
export {};
|
|
14
|
-
//# sourceMappingURL=run.d.ts.map
|
package/dist/run.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAuBA,UAAU,UAAU;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAmIrE"}
|
package/dist/run.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
|
-
import { FrameType, FrameReader, encodeFrame, } from '@sunpix/entangle-protocol';
|
|
3
|
-
import { deriveKeys, extractSaltFromCapId, aeadEncrypt, aeadDecrypt, computeHmac, initCrypto, } from '@sunpix/entangle-crypto';
|
|
4
|
-
import { createLogger, BidirectionalCounters, } from '@sunpix/entangle-utils';
|
|
5
|
-
import { encode, decode } from 'cborg';
|
|
6
|
-
const logger = createLogger('invoke-run');
|
|
7
|
-
export async function runCommand(options) {
|
|
8
|
-
await initCrypto();
|
|
9
|
-
const saltCap = extractSaltFromCapId(options.capId);
|
|
10
|
-
const keys = await deriveKeys(options.S, saltCap);
|
|
11
|
-
const counters = new BidirectionalCounters();
|
|
12
|
-
const wsUrl = options.serverUrl.replace(/^http/, 'ws') +
|
|
13
|
-
`/relay/${options.namespace}/${options.capId}`;
|
|
14
|
-
logger.info({ url: wsUrl }, 'Connecting to relay');
|
|
15
|
-
return new Promise((resolve, reject) => {
|
|
16
|
-
const ws = new WebSocket(wsUrl);
|
|
17
|
-
const reader = new FrameReader();
|
|
18
|
-
let authenticated = false;
|
|
19
|
-
let nonceB;
|
|
20
|
-
let commandId = Math.random().toString(36).substr(2, 9);
|
|
21
|
-
let exitCode = 0;
|
|
22
|
-
let abortTimer;
|
|
23
|
-
ws.on('open', async () => {
|
|
24
|
-
logger.info('Connected, starting auth');
|
|
25
|
-
nonceB = require('crypto').randomBytes(16).toString('hex');
|
|
26
|
-
const auth1Data = new TextEncoder().encode('hello' + options.capId + nonceB);
|
|
27
|
-
const auth1Hmac = computeHmac(keys.K_auth, auth1Data);
|
|
28
|
-
ws.send(encodeFrame(FrameType.AUTH1, auth1Hmac));
|
|
29
|
-
});
|
|
30
|
-
ws.on('message', async (data) => {
|
|
31
|
-
if (!(data instanceof Buffer))
|
|
32
|
-
return;
|
|
33
|
-
const frames = reader.push(data);
|
|
34
|
-
for (const frame of frames) {
|
|
35
|
-
try {
|
|
36
|
-
if (frame.type === FrameType.AUTH2 && !authenticated) {
|
|
37
|
-
const auth2Encrypted = decode(frame.payload);
|
|
38
|
-
const decrypted = aeadDecrypt(keys.K_enc, FrameType.AUTH2, auth2Encrypted.nonce, auth2Encrypted.cipher);
|
|
39
|
-
const auth2 = decrypted.msg;
|
|
40
|
-
if (!auth2.ok || auth2.nonceB !== nonceB) {
|
|
41
|
-
throw new Error('Invalid AUTH2 response');
|
|
42
|
-
}
|
|
43
|
-
const auth3Data = new TextEncoder().encode('ready' + auth2.nonceC);
|
|
44
|
-
const auth3Hmac = computeHmac(keys.K_auth, auth3Data);
|
|
45
|
-
ws.send(encodeFrame(FrameType.AUTH3, auth3Hmac));
|
|
46
|
-
authenticated = true;
|
|
47
|
-
logger.info('Authenticated, sending RUN');
|
|
48
|
-
const runMsg = {
|
|
49
|
-
ctr: counters.outgoing.next(),
|
|
50
|
-
msg: {
|
|
51
|
-
commandId,
|
|
52
|
-
tool: options.tool,
|
|
53
|
-
argv: options.argv,
|
|
54
|
-
cwd: options.cwd,
|
|
55
|
-
limits: {
|
|
56
|
-
maxOutBytes: options.maxOutBytes,
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
const runEncrypted = aeadEncrypt(keys.K_enc, FrameType.RUN, runMsg.ctr, runMsg.msg);
|
|
61
|
-
ws.send(encodeFrame(FrameType.RUN, encode(runEncrypted)));
|
|
62
|
-
if (options.abortAfterMs) {
|
|
63
|
-
abortTimer = setTimeout(() => {
|
|
64
|
-
logger.info('Sending abort');
|
|
65
|
-
const abortMsg = {
|
|
66
|
-
ctr: counters.outgoing.next(),
|
|
67
|
-
msg: {
|
|
68
|
-
commandId,
|
|
69
|
-
reason: 'Timeout',
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
const abortEncrypted = aeadEncrypt(keys.K_enc, FrameType.ABORT, abortMsg.ctr, abortMsg.msg);
|
|
73
|
-
ws.send(encodeFrame(FrameType.ABORT, encode(abortEncrypted)));
|
|
74
|
-
}, options.abortAfterMs);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
else if (authenticated) {
|
|
78
|
-
const msgEncrypted = decode(frame.payload);
|
|
79
|
-
const decrypted = aeadDecrypt(keys.K_enc, frame.type, msgEncrypted.nonce, msgEncrypted.cipher);
|
|
80
|
-
counters.incoming.validate(decrypted.ctr);
|
|
81
|
-
switch (frame.type) {
|
|
82
|
-
case FrameType.STDOUT:
|
|
83
|
-
process.stdout.write(Buffer.from(decrypted.msg.chunk));
|
|
84
|
-
break;
|
|
85
|
-
case FrameType.STDERR:
|
|
86
|
-
process.stderr.write(Buffer.from(decrypted.msg.chunk));
|
|
87
|
-
break;
|
|
88
|
-
case FrameType.EXIT:
|
|
89
|
-
if (abortTimer)
|
|
90
|
-
clearTimeout(abortTimer);
|
|
91
|
-
exitCode = decrypted.msg.code ?? 1;
|
|
92
|
-
logger.info({ code: exitCode, signal: decrypted.msg.signal }, 'Command exited');
|
|
93
|
-
ws.close();
|
|
94
|
-
resolve(exitCode);
|
|
95
|
-
break;
|
|
96
|
-
case FrameType.ERROR:
|
|
97
|
-
logger.error({ error: decrypted.msg }, 'Remote error');
|
|
98
|
-
ws.close();
|
|
99
|
-
reject(new Error(decrypted.msg.detail || decrypted.msg.code));
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
logger.error({ error }, 'Failed to handle frame');
|
|
106
|
-
ws.close();
|
|
107
|
-
reject(error);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
ws.on('error', (error) => {
|
|
112
|
-
logger.error({ error }, 'WebSocket error');
|
|
113
|
-
reject(error);
|
|
114
|
-
});
|
|
115
|
-
ws.on('close', () => {
|
|
116
|
-
if (abortTimer)
|
|
117
|
-
clearTimeout(abortTimer);
|
|
118
|
-
resolve(exitCode);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|