M7 #15 (pass-2): load transcript from state.db on session resume

Pass-2 observation: "When selecting a previous session from the
dashboard, the chat opens, loads, but starts fresh — we should
load the session with previous work like we do on the mac..."

The Mac's resume path does two things: (a) call session/resume on
ACPClient to re-bind Hermes to the session id, and (b) call
`richChatViewModel.loadSessionHistory(sessionId:acpSessionId:)` to
pull the persisted transcript out of state.db and populate the
message list. ScarfGo only did (a) — the ACP channel was wired up
correctly, but there was no SQLite read, so the UI showed an empty
bubble list until the user sent their first new prompt.

Added the loadSessionHistory call right after setSessionId in
ChatController.startResuming. It internally calls `dataService.refresh()`
first so the snapshot reflects whatever Hermes wrote between the
Dashboard's last SQLite pull and the resume tap. The acpSessionId
param is nil when resume preserved the id (no origin-vs-ACP split
needed) and set to the resolved id otherwise so the CLI + ACP
message streams can be merged chronologically — same behaviour the
Mac gets.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alan Wizemann
2026-04-24 14:33:18 +02:00
parent f3c4bc56e9
commit 1c2939dbbe
+10
View File
@@ -644,6 +644,16 @@ final class ChatController {
resolvedID = try await client.loadSession(cwd: home, sessionId: sessionID) resolvedID = try await client.loadSession(cwd: home, sessionId: sessionID)
} }
vm.setSessionId(resolvedID) vm.setSessionId(resolvedID)
// Pull the transcript out of state.db so the user sees
// everything said up to now. Mirrors the Mac resume flow
// (scarf/scarf/Features/Chat/ViewModels/ChatViewModel.swift:376).
// `loadSessionHistory` refreshes the SQLite snapshot first
// so we pick up messages Hermes wrote between the
// Dashboard's last load and now.
await vm.loadSessionHistory(
sessionId: sessionID,
acpSessionId: resolvedID == sessionID ? nil : resolvedID
)
state = .ready state = .ready
} catch { } catch {
state = .failed(error.localizedDescription) state = .failed(error.localizedDescription)