( conversation: XcodeConversationRow, turns: XcodeTurnRow[], onTurnParseError?: (turnId: string, error: unknown) => void, )
| 267 | } |
| 268 | |
| 269 | function buildXcodeSession( |
| 270 | conversation: XcodeConversationRow, |
| 271 | turns: XcodeTurnRow[], |
| 272 | onTurnParseError?: (turnId: string, error: unknown) => void, |
| 273 | ): Session | null { |
| 274 | if (turns.length === 0) return null; |
| 275 | |
| 276 | const requests: SessionRequest[] = []; |
| 277 | for (let i = 0; i < turns.length; i++) { |
| 278 | const turn = turns[i]; |
| 279 | let turnData: XcodeTurnData; |
| 280 | try { |
| 281 | turnData = JSON.parse(turn.data) as XcodeTurnData; |
| 282 | } catch (error) { |
| 283 | onTurnParseError?.(turn.id, error); |
| 284 | continue; |
| 285 | } |
| 286 | |
| 287 | const request = processTurn(turns, i, turn, turnData); |
| 288 | if (request) requests.push(request); |
| 289 | } |
| 290 | |
| 291 | if (requests.length === 0) return null; |
| 292 | |
| 293 | return createSession({ |
| 294 | sessionId: conversation.id, |
| 295 | workspaceId: `xcode-${conversation.id}`, |
| 296 | workspaceName: conversation.title || 'Xcode Chat', |
| 297 | location: 'xcode', |
| 298 | harness: 'Xcode', |
| 299 | creationDate: conversation.createdAt * 1000, |
| 300 | lastMessageDate: turns[turns.length - 1].createdAt * 1000, |
| 301 | requests, |
| 302 | hasDevcontainer: detectDevcontainerFromRequests(requests), |
| 303 | }); |
| 304 | } |
| 305 | |
| 306 | export function parseXcodeDatabases(xcodeBase: string): Session[] { |
| 307 | const sessions: Session[] = []; |
no test coverage detected