indieclaw-agent 1.1.2 → 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 +84 -5
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -543,11 +543,88 @@ function handleTerminalStart(ws, { id }) {
543
543
  }
544
544
  }
545
545
 
546
- // Fallback: child_process.spawn
547
546
  const { spawn } = require('child_process');
548
- const proc = spawn(shell, ['-i'], {
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'];
624
+
625
+ const proc = spawn('script', scriptArgs, {
549
626
  cwd: os.homedir(),
550
- env: { ...process.env, TERM: 'dumb' },
627
+ env: { ...process.env, TERM: 'xterm-256color' },
551
628
  stdio: ['pipe', 'pipe', 'pipe'],
552
629
  });
553
630
 
@@ -583,11 +660,13 @@ function handleTerminalInput(ws, { id, data }) {
583
660
 
584
661
  function handleTerminalResize(ws, { id, cols, rows }) {
585
662
  const term = terminals.get(id);
586
- if (!term) return replyError(ws, id, 'Terminal not found');
663
+ if (!term) return;
587
664
  if (term._isPty && term.resize) {
588
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`);
589
669
  }
590
- // fallback processes don't support resize
591
670
  }
592
671
 
593
672
  function handleTerminalStop(ws, { id }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indieclaw-agent",
3
- "version": "1.1.2",
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": {