( messages: Message[], teamInfo?: TeamInfo, startingParentUuidHint?: UUID, allMessages?: readonly Message[], )
| 1408 | // messagesToKeep → not a prefix → not tracked → CB gets parentUuid=null |
| 1409 | // (correct: truncates --continue chain at compact boundary). |
| 1410 | export async function recordTranscript( |
| 1411 | messages: Message[], |
| 1412 | teamInfo?: TeamInfo, |
| 1413 | startingParentUuidHint?: UUID, |
| 1414 | allMessages?: readonly Message[], |
| 1415 | ): Promise<UUID | null> { |
| 1416 | const cleanedMessages = cleanMessagesForLogging(messages, allMessages) |
| 1417 | const sessionId = getSessionId() as UUID |
| 1418 | const messageSet = await getSessionMessages(sessionId) |
| 1419 | const newMessages: typeof cleanedMessages = [] |
| 1420 | let startingParentUuid: UUID | undefined = startingParentUuidHint |
| 1421 | let seenNewMessage = false |
| 1422 | for (const m of cleanedMessages) { |
| 1423 | if (messageSet.has(m.uuid as UUID)) { |
| 1424 | // Only track skipped messages that form a prefix. After compaction, |
| 1425 | // messagesToKeep appear AFTER new CB/summary, so this skips them. |
| 1426 | if (!seenNewMessage && isChainParticipant(m)) { |
| 1427 | startingParentUuid = m.uuid as UUID |
| 1428 | } |
| 1429 | } else { |
| 1430 | newMessages.push(m) |
| 1431 | seenNewMessage = true |
| 1432 | } |
| 1433 | } |
| 1434 | if (newMessages.length > 0) { |
| 1435 | await getProject().insertMessageChain( |
| 1436 | newMessages, |
| 1437 | false, |
| 1438 | undefined, |
| 1439 | startingParentUuid, |
| 1440 | teamInfo, |
| 1441 | ) |
| 1442 | } |
| 1443 | // Return the last ACTUALLY recorded chain-participant's UUID, OR the |
| 1444 | // prefix-tracked UUID if no new chain participants were recorded. This lets |
| 1445 | // callers (useLogMessages) maintain the correct parent chain even when the |
| 1446 | // slice is all-recorded (rewind, /resume scenarios where every message is |
| 1447 | // already in messageSet). Progress is skipped — it's written to the JSONL |
| 1448 | // but nothing chains TO it (see isChainParticipant). |
| 1449 | const lastRecorded = newMessages.findLast(isChainParticipant) |
| 1450 | return (lastRecorded?.uuid as UUID | undefined) ?? startingParentUuid ?? null |
| 1451 | } |
| 1452 | |
| 1453 | export async function recordSidechainTranscript( |
| 1454 | messages: Message[], |
no test coverage detected