@thenewlabs/entangle-connect 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { getVersionInfo, OutputHandler, parseOutputMode } from '@thenewlabs/entangle-utils';
4
+ import { openTerminal } from './terminal.js';
5
+ import { runSingle } from './single.js';
6
+ function parseCapUrl(u) {
7
+ const url = new URL(u);
8
+ const parts = url.pathname.split('/');
9
+ const capId = parts[parts.length - 1];
10
+ if (!capId || capId === '') {
11
+ throw new Error('Invalid capability URL: missing capId');
12
+ }
13
+ // Extract S and optional PW from fragment
14
+ const hashParams = new URLSearchParams(url.hash.slice(1));
15
+ const s = hashParams.get('S');
16
+ const password = hashParams.get('PW') || undefined;
17
+ if (!s) {
18
+ throw new Error('Invalid capability URL: missing S in fragment');
19
+ }
20
+ return {
21
+ host: url.host,
22
+ capId,
23
+ S: s,
24
+ ...(password && { password })
25
+ };
26
+ }
27
+ const program = new Command();
28
+ program
29
+ .name('entangle-connect')
30
+ .description('Invoke commands or terminal sessions on remote capabilities')
31
+ .version(getVersionInfo())
32
+ .argument('<cap-url>', 'Capability URL (e.g., https://suncoder.dev/cap/capId#S=secret)')
33
+ .argument('[command...]', 'Command and arguments to execute (omit for terminal mode)')
34
+ .option('--cwd <path>', 'Working directory')
35
+ .option('--cols <n>', 'Terminal columns', '80')
36
+ .option('--rows <n>', 'Terminal rows', '24')
37
+ .option('--abort-after-ms <n>', 'Abort command after N milliseconds')
38
+ .option('--output-mode <mode>', 'Output mode: text or stream-json', 'text')
39
+ .option('--password <password>', 'Agent password (if required)')
40
+ .action(async (capUrl, commandArgs, options) => {
41
+ try {
42
+ // Propagate output mode to all modules in this process
43
+ process.env.OUTPUT_MODE = options.outputMode;
44
+ const outputMode = parseOutputMode(options.outputMode);
45
+ const output = new OutputHandler({ mode: outputMode });
46
+ const { host, capId, S, password: urlPassword } = parseCapUrl(capUrl);
47
+ const password = options.password || urlPassword;
48
+ const protocol = capUrl.startsWith('https://') ? 'wss' : 'ws';
49
+ const wsUrl = `${protocol}://${host}/relay/${capId}`;
50
+ const cols = parseInt(options.cols, 10);
51
+ const rows = parseInt(options.rows, 10);
52
+ if (commandArgs.length === 0) {
53
+ // Terminal mode
54
+ output.version('Entangle Invoke - Terminal Mode', getVersionInfo());
55
+ const terminalOptions = { cols, rows };
56
+ if (options.cwd !== undefined)
57
+ terminalOptions.cwd = options.cwd;
58
+ await openTerminal(wsUrl, S, terminalOptions, password);
59
+ }
60
+ else {
61
+ // Single command mode
62
+ output.version('Entangle Invoke - Command Mode', getVersionInfo());
63
+ const singleOptions = { argv: commandArgs };
64
+ if (options.cwd !== undefined)
65
+ singleOptions.cwd = options.cwd;
66
+ if (options.abortAfterMs !== undefined)
67
+ singleOptions.abortAfterMs = parseInt(options.abortAfterMs, 10);
68
+ await runSingle(wsUrl, S, singleOptions, password);
69
+ }
70
+ }
71
+ catch (error) {
72
+ const outputMode = parseOutputMode(options.outputMode);
73
+ const output = new OutputHandler({ mode: outputMode });
74
+ output.error('Failed', error instanceof Error ? error.message : String(error));
75
+ process.exit(1);
76
+ }
77
+ });
78
+ // Add examples to help text
79
+ program.addHelpText('after', `
80
+ Examples:
81
+ # Interactive terminal
82
+ entangle-connect https://suncoder.dev/cap/capId#S=secret
83
+
84
+ # Single command
85
+ entangle-connect https://suncoder.dev/cap/capId#S=secret ls -la
86
+
87
+ # With custom working directory
88
+ entangle-connect https://suncoder.dev/cap/capId#S=secret --cwd /home/user ls -la
89
+
90
+ # Terminal with custom size
91
+ entangle-connect https://suncoder.dev/cap/capId#S=secret --cols 120 --rows 40`);
92
+ program.parse();
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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;KACxB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,OAAO,CAAC,cAAc,EAAE,CAAC;KACzB,QAAQ,CAAC,WAAW,EAAE,gEAAgE,CAAC;KACvF,QAAQ,CAAC,cAAc,EAAE,2DAA2D,CAAC;KACrF,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC;KAC3C,MAAM,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,CAAC;KAC9C,MAAM,CAAC,YAAY,EAAE,eAAe,EAAE,IAAI,CAAC;KAC3C,MAAM,CAAC,sBAAsB,EAAE,oCAAoC,CAAC;KACpE,MAAM,CAAC,sBAAsB,EAAE,kCAAkC,EAAE,MAAM,CAAC;KAC1E,MAAM,CAAC,uBAAuB,EAAE,8BAA8B,CAAC;KAC/D,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,WAAqB,EAAE,OAAO,EAAE,EAAE;IAC/D,IAAI,CAAC;QACH,uDAAuD;QACvD,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;QAC7C,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAEvD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC;QACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,MAAM,KAAK,GAAG,GAAG,QAAQ,MAAM,IAAI,UAAU,KAAK,EAAE,CAAC;QAErD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAExC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,gBAAgB;YAChB,MAAM,CAAC,OAAO,CAAC,iCAAiC,EAAE,cAAc,EAAE,CAAC,CAAC;YAEpE,MAAM,eAAe,GAAmD,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACvF,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS;gBAAE,eAAe,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;YAEjE,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,sBAAsB;YACtB,MAAM,CAAC,OAAO,CAAC,gCAAgC,EAAE,cAAc,EAAE,CAAC,CAAC;YAEnE,MAAM,aAAa,GAA4D,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;YACrG,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS;gBAAE,aAAa,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;YAC/D,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;gBAAE,aAAa,CAAC,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAExG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;IAEH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,4BAA4B;AAC5B,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;gFAYmD,CAAC,CAAC;AAElF,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,14 @@
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
@@ -0,0 +1 @@
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 ADDED
@@ -0,0 +1,122 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function runSingle(wsUrl: string, S: string, options: {
2
+ argv: string[];
3
+ cwd?: string | undefined;
4
+ abortAfterMs?: number | undefined;
5
+ }, password?: string): Promise<void>;
6
+ //# sourceMappingURL=single.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single.d.ts","sourceRoot":"","sources":["../src/single.ts"],"names":[],"mappings":"AAQA,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,CAsOf"}
package/dist/single.js ADDED
@@ -0,0 +1,210 @@
1
+ import WebSocket from 'ws';
2
+ import { deriveKeys, extractSaltFromCapId, aeadEncrypt, aeadDecrypt, computeHmac, sha256Hex } from '@thenewlabs/entangle-crypto';
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
+ const output = new OutputHandler({ mode: parseOutputMode(process.env.OUTPUT_MODE || 'text') });
7
+ export async function runSingle(wsUrl, S, options, password) {
8
+ const { argv, cwd, abortAfterMs } = options;
9
+ if (!argv || argv.length === 0) {
10
+ throw new Error('No command provided');
11
+ }
12
+ // Extract capId from URL
13
+ const urlParts = wsUrl.split('/');
14
+ const capId = urlParts[urlParts.length - 1];
15
+ // Derive keys
16
+ const saltCap = extractSaltFromCapId(capId);
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;
51
+ let exitCode = 0;
52
+ ws.on('message', async (data) => {
53
+ if (!(data instanceof Buffer))
54
+ return;
55
+ const frames = reader.push(data);
56
+ for (const frame of frames) {
57
+ try {
58
+ if (frame.type === FrameType.AUTH2 && !authenticated) {
59
+ // Handle AUTH2
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));
180
+ }
181
+ }
182
+ });
183
+ ws.on('error', (error) => {
184
+ output.error('WebSocket error', error instanceof Error ? error.message : String(error));
185
+ reject(error);
186
+ });
187
+ ws.on('close', () => {
188
+ output.info('Disconnected');
189
+ if (abortTimeout) {
190
+ clearTimeout(abortTimeout);
191
+ }
192
+ process.exit(exitCode);
193
+ });
194
+ // Handle SIGINT
195
+ process.on('SIGINT', () => {
196
+ if (authenticated && ws.readyState === WebSocket.OPEN) {
197
+ const abortMsg = {
198
+ commandId,
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)
207
+ });
208
+ });
209
+ }
210
+ //# sourceMappingURL=single.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single.js","sourceRoot":"","sources":["../src/single.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function openTerminal(wsUrl: string, S: string, options: {
2
+ cwd?: string | undefined;
3
+ cols?: number | undefined;
4
+ rows?: number | undefined;
5
+ }, password?: string): Promise<void>;
6
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AASA,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,CAyOf"}
@@ -0,0 +1,247 @@
1
+ import WebSocket from 'ws';
2
+ import { deriveKeys, extractSaltFromCapId, aeadEncrypt, aeadDecrypt, computeHmac, sha256Hex } from '@thenewlabs/entangle-crypto';
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';
7
+ const output = new OutputHandler({ mode: parseOutputMode(process.env.OUTPUT_MODE || 'text') });
8
+ export async function openTerminal(wsUrl, S, options, password) {
9
+ const { cwd, cols = 80, rows = 24 } = options;
10
+ // Extract capId from URL
11
+ const urlParts = wsUrl.split('/');
12
+ const capId = urlParts[urlParts.length - 1];
13
+ // Derive keys
14
+ const saltCap = extractSaltFromCapId(capId);
15
+ const keys = await deriveKeys(S, saltCap);
16
+ // Connect to relay
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) {
53
+ try {
54
+ if (frame.type === FrameType.AUTH2 && !authenticated) {
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));
198
+ }
199
+ }
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),
222
+ };
223
+ const dataEncrypted = aeadEncrypt(keys.K_enc, FrameType.TTY_DATA, counters.outgoing.next(), ttyData);
224
+ const dataFrame = encodeFrame(FrameType.TTY_DATA, encode(dataEncrypted));
225
+ ws.send(dataFrame);
226
+ });
227
+ // Handle Ctrl+C
228
+ process.on('SIGINT', () => {
229
+ const signal = {
230
+ sessionId,
231
+ signal: 'SIGINT',
232
+ };
233
+ const signalEncrypted = aeadEncrypt(keys.K_enc, FrameType.TTY_SIGNAL, counters.outgoing.next(), signal);
234
+ const signalFrame = encodeFrame(FrameType.TTY_SIGNAL, encode(signalEncrypted));
235
+ ws.send(signalFrame);
236
+ });
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
+ }
247
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@thenewlabs/entangle-connect",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "bin": {
7
+ "entangle-connect": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "clean": "rm -rf dist",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "dependencies": {
15
+ "@thenewlabs/entangle-crypto": "^1.0.0",
16
+ "@thenewlabs/entangle-protocol": "^1.0.0",
17
+ "@thenewlabs/entangle-utils": "^1.0.0",
18
+ "cborg": "^4.5.8",
19
+ "commander": "^15.0.0",
20
+ "ws": "^8.21.0"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^20.19.43",
24
+ "@types/ws": "^8.18.1",
25
+ "typescript": "^5.9.3"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ]
30
+ }