chat: click-to-resume /chat sessions via Claude --resume

Clicking a session in the list loads its transcript (GET /chat/sessions/:id,
parsed from Claude's JSONL into display messages) and continues the actual Claude
session: a resumeSessionId is threaded chat handler -> send-claude-code -> sidecar
-> claude-manager, which passes --resume <uuid> (in-memory session mapping still
takes precedence for live turns). Parser verified against real transcripts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 10:11:58 +00:00
co-authored by Claude Opus 4.8
parent bea3d0a487
commit 9565cd9462
10 changed files with 158 additions and 16 deletions
+11 -1
View File
@@ -11,6 +11,14 @@ export type ClaudeSessionSummary = {
messageCount: number;
};
// Display-ready message, matching the frontend ChatMessage union (rebuilt from Claude's transcript).
export type ClaudeSessionMessage =
| { role: 'user'; text: string }
| { role: 'assistant'; id: string; text: string }
| { role: 'tool'; toolName: string; toolInput: Record<string, unknown>; toolCallId: string; output?: string; isError?: boolean };
export type ClaudeSessionDetail = { id: string; model: string; cwd: string; messages: ClaudeSessionMessage[] };
/** The /chat route's sessions, read straight from Claude's own transcript store (source of truth). */
export function useClaudeSessions() {
const client = useClient();
@@ -23,5 +31,7 @@ export function useClaudeSessions() {
staleTime: 30 * 1000,
});
return { sessions: data?.sessions ?? [], isLoading, refetch };
const loadSession = (id: string) => client.get<ClaudeSessionDetail>(`/chat/sessions/${id}`);
return { sessions: data?.sessions ?? [], isLoading, refetch, loadSession };
}