claude-code-remote-pilot 0.5.2 → 0.5.3

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,9 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.3 — 2026-05-06
4
+
5
+ ### Fixed
6
+ - **Auto-resume respects clock reset time**: limit recovery now waits until the parsed `resets at HH:MM` timestamp (with next-day rollover) before sending the resume command.
7
+ - **Web UI respawn completed**: offline session respawn now has loading/error feedback and immediately updates session detail state after success.
8
+
9
+ ---
10
+
3
11
  ## 0.5.2 — 2026-05-06
4
12
 
5
13
  ### Fixed
6
14
  - **Auto-resume now waits for reset time**: when Claude shows an explicit `resets at HH:MM` clock time, `Watcher` now resumes at that exact reset timestamp (including next-day rollover) instead of relying only on relative wait parsing.
15
+ - **Web UI respawn flow completed**: offline session respawn now shows in-button loading, inline errors, and immediately updates the detail view to the newly active session after successful `POST /api/sessions/:name/respawn`.
7
16
 
8
17
  ---
9
18
 
package/lib/ui.html CHANGED
@@ -574,11 +574,13 @@ function DashboardScreen({ onNavigate, sessions, activity, serverStatus }) {
574
574
  }
575
575
 
576
576
  /* --- Session Detail --- */
577
- function SessionDetailScreen({ session, onBack, onKilled }) {
577
+ function SessionDetailScreen({ session, onBack, onKilled, onRespawned }) {
578
578
  const [output, setOutput] = useState('');
579
579
  const [msg, setMsg] = useState('');
580
580
  const [sending, setSending] = useState(false);
581
581
  const [killing, setKilling] = useState(false);
582
+ const [respawning, setRespawning] = useState(false);
583
+ const [respawnError, setRespawnError] = useState('');
582
584
  const [copyOk, setCopyOk] = useState(false);
583
585
  const terminalRef = useRef(null);
584
586
  const inputRef = useRef(null);
@@ -661,14 +663,21 @@ function SessionDetailScreen({ session, onBack, onKilled }) {
661
663
  };
662
664
 
663
665
  const handleRespawn = async () => {
666
+ if (respawning) return;
667
+ setRespawning(true);
668
+ setRespawnError('');
664
669
  try {
665
670
  const res = await apiFetch(`/api/sessions/${encodeURIComponent(session.name)}/respawn`, { method: 'POST' });
671
+ const data = await res.json();
666
672
  if (!res.ok) {
667
- const d = await res.json();
668
- alert(d.error || 'Failed to respawn');
673
+ setRespawnError(data.error || 'Failed to respawn');
674
+ return;
669
675
  }
676
+ onRespawned(data);
670
677
  } catch (e) {
671
- if (e.message !== 'Unauthorized') alert('Network error');
678
+ if (e.message !== 'Unauthorized') setRespawnError('Network error');
679
+ } finally {
680
+ setRespawning(false);
672
681
  }
673
682
  };
674
683
 
@@ -700,9 +709,16 @@ function SessionDetailScreen({ session, onBack, onKilled }) {
700
709
  </div>
701
710
  <div className="detail-actions">
702
711
  {isOffline && (
703
- <button className="btn btn-sm btn-primary" onClick={handleRespawn}>
704
- Respawn
705
- </button>
712
+ <>
713
+ <button className="btn btn-sm btn-primary" onClick={handleRespawn} disabled={respawning}>
714
+ {respawning ? 'Respawning…' : '↺ Respawn'}
715
+ </button>
716
+ {respawnError && (
717
+ <span style={{ color: 'var(--error)', fontSize: 12, alignSelf: 'center' }}>
718
+ {respawnError}
719
+ </span>
720
+ )}
721
+ </>
706
722
  )}
707
723
  {!isOffline && (
708
724
  <button className="btn btn-sm" onClick={copyAttachCmd} title={`tmux attach -t ${session.name}`}>
@@ -1047,7 +1063,13 @@ function App() {
1047
1063
  case 'dashboard': return <DashboardScreen onNavigate={navigate} sessions={sessions} activity={activity} serverStatus={serverStatus} />;
1048
1064
  case 'sessions': return <SessionsScreen sessions={sessions} onNavigate={navigate} />;
1049
1065
  case 'create': return <CreateSessionScreen onBack={() => navigate('dashboard')} onCreated={s => navigate('detail', s)} />;
1050
- case 'detail': return <SessionDetailScreen session={selectedSession} onBack={() => navigate('dashboard')} onKilled={() => navigate('sessions')} />;
1066
+ case 'detail': return <SessionDetailScreen session={selectedSession} onBack={() => navigate('dashboard')} onKilled={() => navigate('sessions')} onRespawned={(respawned) => {
1067
+ setSessions(prev => {
1068
+ const next = prev.filter(s => s.name !== respawned.name);
1069
+ return [{ ...respawned, id: respawned.name }, ...next];
1070
+ });
1071
+ setSelectedSession({ ...respawned, id: respawned.name });
1072
+ }} />;
1051
1073
  default: return <DashboardScreen onNavigate={navigate} sessions={sessions} activity={activity} serverStatus={serverStatus} />;
1052
1074
  }
1053
1075
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-remote-pilot",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Interactive Claude Code supervisor — spawn and monitor multiple Claude sessions from a single terminal.",
5
5
  "type": "commonjs",
6
6
  "repository": {