@tsufbarkai/relay-stream 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -37,7 +37,7 @@ relay-stream --relay <id> --token <jwt> --pty
37
37
  relay-stream --relay <id> --token <jwt> --pty -- python3
38
38
  ```
39
39
 
40
- PTY mode requires the optional `node-pty-prebuilt-multiarch` dependency, which is installed automatically on supported platforms. If it fails to install (e.g. missing build tools), pipe and wrap modes still work.
40
+ PTY mode uses the OS `script` command to allocate a real pseudo-terminal. This is available out of the box on macOS and Linux no native dependencies or build tools required.
41
41
 
42
42
  ## Options
43
43
 
@@ -199,17 +199,9 @@ async function main() {
199
199
  process.stderr.write('[relay-stream] done\n');
200
200
  }
201
201
 
202
- // ── Mode: pty (interactive terminal) ────────────────────────────────────
202
+ // ── Mode: pty (interactive terminal via OS `script` command) ─────────────
203
203
  if (isPtyMode) {
204
- let pty;
205
- try {
206
- pty = require('node-pty-prebuilt-multiarch');
207
- } catch {
208
- process.stderr.write(
209
- 'PTY mode requires node-pty-prebuilt-multiarch. Install it with: npm install node-pty-prebuilt-multiarch\n'
210
- );
211
- process.exit(1);
212
- }
204
+ const { spawn } = require('child_process');
213
205
 
214
206
  const shell = String(command.length > 0 ? command[0] : (process.env.SHELL || '/bin/bash'));
215
207
  const shellArgs = command.length > 1 ? command.slice(1) : [];
@@ -219,31 +211,33 @@ async function main() {
219
211
  process.exit(1);
220
212
  }
221
213
 
222
- const ptyProcess = pty.spawn(shell, shellArgs, {
223
- name: 'xterm-256color',
224
- cols: process.stdout.columns || 120,
225
- rows: process.stdout.rows || 30,
226
- env: process.env,
227
- });
228
-
229
- // Forward PTY output to stdout and relay buffer
230
- ptyProcess.onData((data) => {
231
- process.stdout.write(data);
232
- appendChunk(data);
233
- });
214
+ const cols = String(process.stdout.columns || 120);
215
+ const rows = String(process.stdout.rows || 30);
216
+ const childEnv = { ...process.env, TERM: 'xterm-256color', COLUMNS: cols, LINES: rows };
234
217
 
235
- // Forward stdin to PTY
236
- if (process.stdin.isTTY) {
237
- process.stdin.setRawMode(true);
218
+ // Use the OS `script` command to allocate a real PTY — zero native deps
219
+ // script -q /dev/null writes transcript to /dev/null, PTY output goes to stdout
220
+ let scriptArgs;
221
+ if (process.platform === 'darwin') {
222
+ scriptArgs = ['-q', '/dev/null', shell, ...shellArgs];
223
+ } else {
224
+ // Linux
225
+ scriptArgs = ['-qc', [shell, ...shellArgs].join(' '), '/dev/null'];
238
226
  }
239
- process.stdin.resume();
240
- process.stdin.on('data', (data) => {
241
- ptyProcess.write(data.toString());
227
+
228
+ const child = spawn('script', scriptArgs, {
229
+ stdio: ['inherit', 'pipe', 'pipe'],
230
+ env: childEnv,
242
231
  });
243
232
 
244
- // Handle terminal resize
245
- process.stdout.on('resize', () => {
246
- ptyProcess.resize(process.stdout.columns, process.stdout.rows);
233
+ // Forward PTY output to user's terminal and relay buffer
234
+ child.stdout.on('data', (data) => {
235
+ process.stdout.write(data);
236
+ appendChunk(data.toString());
237
+ });
238
+ child.stderr.on('data', (data) => {
239
+ process.stdout.write(data);
240
+ appendChunk(data.toString());
247
241
  });
248
242
 
249
243
  // Cleanup helper
@@ -251,26 +245,30 @@ async function main() {
251
245
  async function cleanup(exitCode) {
252
246
  if (exiting) return;
253
247
  exiting = true;
254
- try {
255
- if (process.stdin.isTTY) process.stdin.setRawMode(false);
256
- } catch {}
248
+ await flushBuffer();
257
249
  await closeStream(exitCode);
258
250
  process.exit(exitCode);
259
251
  }
260
252
 
261
253
  // Handle signals
262
254
  process.on('SIGINT', () => {
263
- ptyProcess.kill();
255
+ child.kill('SIGINT');
264
256
  cleanup(0);
265
257
  });
266
258
  process.on('SIGTERM', () => {
267
- ptyProcess.kill();
259
+ child.kill('SIGTERM');
268
260
  cleanup(0);
269
261
  });
270
262
 
271
263
  // Handle PTY exit
272
- ptyProcess.onExit(({ exitCode }) => {
273
- cleanup(exitCode ?? 0);
264
+ child.on('close', (code) => {
265
+ cleanup(code ?? 0);
266
+ });
267
+
268
+ child.on('error', async (err) => {
269
+ process.stderr.write(`[relay-stream] failed to spawn PTY: ${err.message}\n`);
270
+ await closeStream(1);
271
+ process.exit(1);
274
272
  });
275
273
 
276
274
  return; // let PTY drive exit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsufbarkai/relay-stream",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Stream your terminal to a Relay session",
5
5
  "bin": {
6
6
  "relay-stream": "./bin/relay-stream.js"
@@ -29,8 +29,5 @@
29
29
  },
30
30
  "scripts": {
31
31
  "postinstall": "node -e \"require('fs').chmodSync(require('path').join(__dirname, 'bin/relay-stream.js'), '755')\""
32
- },
33
- "optionalDependencies": {
34
- "node-pty-prebuilt-multiarch": "^0.10.0"
35
32
  }
36
33
  }