Accept story 39: Persistent Claude Code Sessions in Web UI

Use --resume <session_id> with claude -p so the web UI claude-code-pty
provider maintains full conversation context across messages, identical
to a long-running terminal Claude Code session.

Changes:
- Capture session_id from claude -p stream-json system event
- Pass --resume on subsequent messages in same chat session
- Thread session_id through ProviderConfig, ChatResult, WsResponse
- Frontend stores sessionId per chat, clears on New Session
- Unset CLAUDECODE env to allow nested spawning from server
- Wait for clean process exit to ensure transcript flush to disk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-20 11:51:19 +00:00
parent cff7f5fe7f
commit cde75bd7fb
11 changed files with 9524 additions and 61 deletions

View File

@@ -81,6 +81,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
const [lastUpcomingRefresh, setLastUpcomingRefresh] = useState<Date | null>(
null,
);
const [claudeSessionId, setClaudeSessionId] = useState<string | null>(null);
const storyId = "26_establish_tdd_workflow_and_gates";
const gateStatusColor = isGateLoading
@@ -500,6 +501,9 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
setLoading(false);
}
},
onSessionId: (sessionId) => {
setClaudeSessionId(sessionId);
},
onError: (message) => {
console.error("WebSocket error:", message);
setLoading(false);
@@ -611,6 +615,9 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
model,
base_url: "http://localhost:11434",
enable_tools: enableTools,
...(isClaudeCode && claudeSessionId
? { session_id: claudeSessionId }
: {}),
};
wsRef.current?.sendChat(newHistory, config);
@@ -663,6 +670,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
setMessages([]);
setStreamingContent("");
setLoading(false);
setClaudeSessionId(null);
}
};