(rawSession: OcSession, storageDir: string)
| 262 | } |
| 263 | |
| 264 | function parseOpenCodeSession(rawSession: OcSession, storageDir: string): Session | null { |
| 265 | if (!rawSession.id) return null; |
| 266 | |
| 267 | const msgDir = path.join(storageDir, 'message', rawSession.id); |
| 268 | const rawMessages = readAllJsonInDir<OcMessage>(msgDir); |
| 269 | rawMessages.sort((a, b) => (a.time?.created || 0) - (b.time?.created || 0)); |
| 270 | if (rawMessages.length === 0) return null; |
| 271 | |
| 272 | const partsByMsg = indexPartsByMessage(rawMessages, storageDir); |
| 273 | const { wsId, wsName } = getOpenCodeWorkspace(rawSession); |
| 274 | const requests: SessionRequest[] = []; |
| 275 | let firstTs: number | null = null; |
| 276 | let lastTs: number | null = null; |
| 277 | |
| 278 | for (let i = 0; i < rawMessages.length; i++) { |
| 279 | const msg = rawMessages[i]; |
| 280 | if (msg.role !== 'user') continue; |
| 281 | |
| 282 | const userTs = msg.time?.created || null; |
| 283 | if (userTs && (!firstTs || userTs < firstTs)) firstTs = userTs; |
| 284 | |
| 285 | const assistantMsg = findAssistantMessage(rawMessages, i + 1, msg.id); |
| 286 | const assistantData = collectAssistantData(assistantMsg, partsByMsg, userTs, lastTs); |
| 287 | lastTs = assistantData.lastTs; |
| 288 | requests.push(buildOpenCodeRequest(msg, partsByMsg, assistantData, userTs)); |
| 289 | } |
| 290 | |
| 291 | if (requests.length === 0) return null; |
| 292 | |
| 293 | return createSession({ |
| 294 | sessionId: rawSession.id, |
| 295 | workspaceId: wsId, |
| 296 | workspaceName: wsName, |
| 297 | location: 'terminal', |
| 298 | harness: 'OpenCode', |
| 299 | creationDate: firstTs || (rawSession.time?.created || null), |
| 300 | lastMessageDate: lastTs || (rawSession.time?.updated || null), |
| 301 | requests, |
| 302 | hasDevcontainer: detectDevcontainerFromRequests(requests, rawSession.directory), |
| 303 | workspaceRootPath: rawSession.directory || undefined, |
| 304 | }); |
| 305 | } |
| 306 | |
| 307 | export function parseOpenCodeSessions(storageDir: string): Session[] { |
| 308 | const sessions: Session[] = []; |
no test coverage detected