indieclaw-agent 1.1.3 → 1.1.4

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.
Files changed (2) hide show
  1. package/index.js +81 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -543,11 +543,84 @@ function handleTerminalStart(ws, { id }) {
543
543
  }
544
544
  }
545
545
 
546
- // Fallback: use script(1) to allocate a real PTY
547
546
  const { spawn } = require('child_process');
548
- const scriptArgs = os.platform() === 'darwin'
549
- ? ['-q', '/dev/null', shell]
550
- : ['-q', '-c', shell, '/dev/null'];
547
+
548
+ // macOS: use Python pty module (script(1) fails with piped stdin on macOS)
549
+ if (os.platform() === 'darwin') {
550
+ const pythonScript = `
551
+ import pty,os,sys,select,struct,fcntl,termios,signal
552
+ m,s=pty.openpty()
553
+ try:fcntl.ioctl(s,termios.TIOCSWINSZ,struct.pack('HHHH',24,80,0,0))
554
+ except:pass
555
+ p=os.fork()
556
+ if p==0:
557
+ os.close(m);os.setsid();fcntl.ioctl(s,termios.TIOCSCTTY,0)
558
+ os.dup2(s,0);os.dup2(s,1);os.dup2(s,2)
559
+ if s>2:os.close(s)
560
+ sh=os.environ.get('SHELL','/bin/zsh')
561
+ os.execvp(sh,[sh])
562
+ os.close(s);buf=b''
563
+ MK=b'\\x1b]9999;';EN=b'\\x07'
564
+ while True:
565
+ try:r,_,_=select.select([m,0],[],[])
566
+ except:break
567
+ if m in r:
568
+ try:d=os.read(m,16384)
569
+ except OSError:break
570
+ if not d:break
571
+ try:os.write(1,d)
572
+ except:break
573
+ if 0 in r:
574
+ try:d=os.read(0,4096)
575
+ except OSError:break
576
+ if not d:break
577
+ buf+=d
578
+ while MK in buf:
579
+ i=buf.index(MK)
580
+ if i>0:os.write(m,buf[:i]);buf=buf[i:]
581
+ try:j=buf.index(EN)
582
+ except ValueError:break
583
+ c=buf[len(MK):j].decode().split(',')
584
+ try:
585
+ fcntl.ioctl(m,termios.TIOCSWINSZ,struct.pack('HHHH',int(c[1]),int(c[0]),0,0))
586
+ os.kill(p,signal.SIGWINCH)
587
+ except:pass
588
+ buf=buf[j+1:]
589
+ if buf and MK not in buf:os.write(m,buf);buf=b''
590
+ try:os.kill(p,signal.SIGTERM)
591
+ except:pass
592
+ try:os.waitpid(p,0)
593
+ except:pass
594
+ `;
595
+ const proc = spawn('python3', ['-u', '-c', pythonScript], {
596
+ cwd: os.homedir(),
597
+ env: { ...process.env, TERM: 'xterm-256color' },
598
+ stdio: ['pipe', 'pipe', 'pipe'],
599
+ });
600
+
601
+ proc._ws = ws;
602
+ proc._isPty = false;
603
+ proc._hasPtyResize = true;
604
+
605
+ proc.stdout.on('data', (data) => {
606
+ send(ws, { type: 'terminal.output', id, data: data.toString() });
607
+ });
608
+
609
+ proc.stderr.on('data', (data) => {
610
+ send(ws, { type: 'terminal.output', id, data: data.toString() });
611
+ });
612
+
613
+ proc.on('exit', (exitCode) => {
614
+ send(ws, { type: 'terminal.exit', id, exitCode: exitCode ?? 0 });
615
+ terminals.delete(id);
616
+ });
617
+
618
+ terminals.set(id, proc);
619
+ return reply(ws, id, { pid: proc.pid });
620
+ }
621
+
622
+ // Linux: use script(1) to allocate a real PTY
623
+ const scriptArgs = ['-q', '-c', shell, '/dev/null'];
551
624
 
552
625
  const proc = spawn('script', scriptArgs, {
553
626
  cwd: os.homedir(),
@@ -587,11 +660,13 @@ function handleTerminalInput(ws, { id, data }) {
587
660
 
588
661
  function handleTerminalResize(ws, { id, cols, rows }) {
589
662
  const term = terminals.get(id);
590
- if (!term) return replyError(ws, id, 'Terminal not found');
663
+ if (!term) return;
591
664
  if (term._isPty && term.resize) {
592
665
  term.resize(cols, rows);
666
+ } else if (term._hasPtyResize) {
667
+ // Python PTY: send resize via custom OSC escape sequence
668
+ term.stdin.write(`\x1b]9999;${cols},${rows}\x07`);
593
669
  }
594
- // fallback processes don't support resize
595
670
  }
596
671
 
597
672
  function handleTerminalStop(ws, { id }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indieclaw-agent",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Manage your server from your phone. Agent for the IndieClaw mobile app.",
5
5
  "main": "index.js",
6
6
  "bin": {