claude-code-remote-pilot 0.5.4 → 0.5.5

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/CHANGELOG.md CHANGED
@@ -1,11 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.5 — 2026-05-06
4
+
5
+ ### Fixed
6
+ - **Respawn loading no longer appears stuck**: web respawn now has a request timeout and surfaces a clear timeout error when the API call hangs, so the button always returns to clickable state.
7
+ - **Terminal output now feels realtime**: session detail terminal polling runs at a faster cadence and triggers immediate output refresh after sending input/keys, improving perceived connect speed and responsiveness.
8
+ - **"Connecting…" no longer gets stuck**: terminal detail view now clears connecting state on poll failures, shows a retrying error hint, and fixes session state initialization order for stable render behavior.
9
+
3
10
  ## 0.5.4 — 2026-05-06
4
11
 
5
12
  ### Fixed
6
13
  - **Web UI respawn completed**: offline session respawn now has loading/error feedback and immediately updates session detail state after success.
7
14
  - **Web respawn now matches CLI spawn behavior**: respawn starts a fresh session from stored path and default command semantics (same as watch-mode spawn), avoiding failures caused by stale stored command values.
8
- - **Respawn loading no longer appears stuck**: web respawn now has a request timeout and surfaces a clear timeout error when the API call hangs, so the button always returns to clickable state.
9
15
 
10
16
  ---
11
17
 
package/lib/ui.html CHANGED
@@ -575,6 +575,7 @@ function DashboardScreen({ onNavigate, sessions, activity, serverStatus }) {
575
575
 
576
576
  /* --- Session Detail --- */
577
577
  function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
578
+ const isOffline = session.status === 'offline';
578
579
  const [output, setOutput] = useState('');
579
580
  const [msg, setMsg] = useState('');
580
581
  const [sending, setSending] = useState(false);
@@ -582,9 +583,11 @@ function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
582
583
  const [respawning, setRespawning] = useState(false);
583
584
  const [respawnError, setRespawnError] = useState('');
584
585
  const [copyOk, setCopyOk] = useState(false);
586
+ const [connecting, setConnecting] = useState(!isOffline);
587
+ const [pollError, setPollError] = useState(false);
585
588
  const terminalRef = useRef(null);
586
589
  const inputRef = useRef(null);
587
- const isOffline = session.status === 'offline';
590
+ const pollNowRef = useRef(() => {});
588
591
 
589
592
  const copyAttachCmd = () => {
590
593
  const cmd = `tmux attach -t ${session.name}`;
@@ -599,18 +602,47 @@ function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
599
602
  if (!isOffline) setTimeout(() => inputRef.current?.focus(), 50);
600
603
  }, [session.name, isOffline]);
601
604
 
602
- // Poll terminal output every 2s
605
+ // Poll terminal output at near-realtime cadence
603
606
  useEffect(() => {
604
- if (isOffline) return;
607
+ if (isOffline) {
608
+ setConnecting(false);
609
+ setPollError(false);
610
+ return;
611
+ }
612
+ let mounted = true;
613
+ let inFlight = false;
614
+
605
615
  const poll = () => {
616
+ if (inFlight) return;
617
+ inFlight = true;
606
618
  apiFetch(`/api/sessions/${encodeURIComponent(session.name)}/output`, { cache: 'no-store' })
607
619
  .then(r => r.json())
608
- .then(d => setOutput(d.output || ''))
609
- .catch(e => { if (e && e.message !== 'Unauthorized') console.error('[ccp] output poll error:', e); });
620
+ .then(d => {
621
+ if (!mounted) return;
622
+ setOutput(d.output || '');
623
+ setConnecting(false);
624
+ setPollError(false);
625
+ })
626
+ .catch(e => {
627
+ if (!mounted) return;
628
+ if (e && e.message !== 'Unauthorized') console.error('[ccp] output poll error:', e);
629
+ setConnecting(false);
630
+ setPollError(true);
631
+ })
632
+ .finally(() => {
633
+ inFlight = false;
634
+ });
610
635
  };
636
+
637
+ setConnecting(true);
638
+ pollNowRef.current = poll;
611
639
  poll();
612
- const t = setInterval(poll, 2000);
613
- return () => clearInterval(t);
640
+ const t = setInterval(poll, 600);
641
+ return () => {
642
+ mounted = false;
643
+ pollNowRef.current = () => {};
644
+ clearInterval(t);
645
+ };
614
646
  }, [session.name, isOffline]);
615
647
 
616
648
  // Auto-scroll terminal to bottom
@@ -628,6 +660,7 @@ function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
628
660
  body: JSON.stringify({ message: msg }),
629
661
  });
630
662
  setMsg('');
663
+ pollNowRef.current();
631
664
  } catch {
632
665
  } finally {
633
666
  setSending(false);
@@ -643,6 +676,7 @@ function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
643
676
  headers: { 'Content-Type': 'application/json' },
644
677
  body: JSON.stringify({ key }),
645
678
  });
679
+ pollNowRef.current();
646
680
  } catch {}
647
681
  setTimeout(() => inputRef.current?.focus(), 0);
648
682
  };
@@ -764,7 +798,11 @@ function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
764
798
  ? '<span style="color:oklch(50% 0.018 50)">Session is offline — no output available.</span>'
765
799
  : _termHtml
766
800
  ? _termHtml + '<span style="opacity:0.4">▊</span>'
767
- : '<span style="color:oklch(50% 0.018 50)">Connecting…</span>'
801
+ : (connecting
802
+ ? '<span style="color:oklch(50% 0.018 50)">Connecting…</span>'
803
+ : (pollError
804
+ ? '<span style="color:oklch(64% 0.20 28)">Can\'t read terminal output. Retrying…</span>'
805
+ : '<span style="color:oklch(50% 0.018 50)">No output yet.</span>'))
768
806
  }}
769
807
  />
770
808
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-remote-pilot",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Interactive Claude Code supervisor — spawn and monitor multiple Claude sessions from a single terminal.",
5
5
  "type": "commonjs",
6
6
  "repository": {