( result: ResumeResult, setAppState: (f: (prev: AppState) => AppState) => void, )
| 97 | * Used by both SDK (print.ts) and interactive (REPL.tsx, main.tsx) resume paths. |
| 98 | */ |
| 99 | export function restoreSessionStateFromLog( |
| 100 | result: ResumeResult, |
| 101 | setAppState: (f: (prev: AppState) => AppState) => void, |
| 102 | ): void { |
| 103 | // Restore file history state |
| 104 | if (result.fileHistorySnapshots && result.fileHistorySnapshots.length > 0) { |
| 105 | fileHistoryRestoreStateFromLog(result.fileHistorySnapshots, newState => { |
| 106 | setAppState(prev => ({ ...prev, fileHistory: newState })) |
| 107 | }) |
| 108 | } |
| 109 | |
| 110 | // Restore attribution state (ant-only feature) |
| 111 | if ( |
| 112 | feature('COMMIT_ATTRIBUTION') && |
| 113 | result.attributionSnapshots && |
| 114 | result.attributionSnapshots.length > 0 |
| 115 | ) { |
| 116 | attributionRestoreStateFromLog(result.attributionSnapshots, newState => { |
| 117 | setAppState(prev => ({ ...prev, attribution: newState })) |
| 118 | }) |
| 119 | } |
| 120 | |
| 121 | // Restore context-collapse commit log + staged snapshot. Must run before |
| 122 | // the first query() so projectView() can rebuild the collapsed view from |
| 123 | // the resumed Message[]. Called unconditionally (even with |
| 124 | // undefined/empty entries) because restoreFromEntries resets the store |
| 125 | // first — without that, an in-session /resume into a session with no |
| 126 | // commits would leave the prior session's stale commit log intact. |
| 127 | if (feature('CONTEXT_COLLAPSE')) { |
| 128 | /* eslint-disable @typescript-eslint/no-require-imports */ |
| 129 | ;( |
| 130 | require('../services/contextCollapse/persist.js') as typeof import('../services/contextCollapse/persist.js') |
| 131 | ).restoreFromEntries( |
| 132 | result.contextCollapseCommits ?? [], |
| 133 | result.contextCollapseSnapshot, |
| 134 | ) |
| 135 | /* eslint-enable @typescript-eslint/no-require-imports */ |
| 136 | } |
| 137 | |
| 138 | // Restore TodoWrite state from transcript (SDK/non-interactive only). |
| 139 | // Interactive mode uses file-backed v2 tasks, so AppState.todos is unused there. |
| 140 | if (!isTodoV2Enabled() && result.messages && result.messages.length > 0) { |
| 141 | const todos = extractTodosFromTranscript(result.messages) |
| 142 | if (todos.length > 0) { |
| 143 | const agentId = getSessionId() |
| 144 | setAppState(prev => ({ |
| 145 | ...prev, |
| 146 | todos: { ...prev.todos, [agentId]: todos }, |
| 147 | })) |
| 148 | } |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * Compute restored attribution state from log snapshots. |
no test coverage detected