import { afterEach, expect, test } from 'bun:test' import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { loadConversationForResume, ResumeTranscriptTooLargeError, } from './conversationRecovery.ts' const tempDirs: string[] = [] const originalSimple = process.env.CLAUDE_CODE_SIMPLE const sessionId = '00000000-0000-4000-8000-000000001999' const ts = '2026-04-02T00:00:00.000Z' function id(n: number): string { return `00000000-0000-4000-8000-${String(n).padStart(12, '0')}` } function user(uuid: string, content: string) { return { type: 'user', uuid, parentUuid: null, timestamp: ts, cwd: '/tmp', userType: 'external', sessionId, version: 'test', isSidechain: false, isMeta: false, message: { role: 'user', content, }, } } async function writeJsonl(entry: unknown): Promise { const dir = await mkdtemp(join(tmpdir(), 'openclaude-conversation-recovery-')) tempDirs.push(dir) const filePath = join(dir, 'resume.jsonl') await writeFile(filePath, `${JSON.stringify(entry)}\n`) return filePath } afterEach(async () => { process.env.CLAUDE_CODE_SIMPLE = originalSimple await Promise.all(tempDirs.splice(0).map(dir => rm(dir, { recursive: true, force: true }))) }) test('loadConversationForResume accepts a small transcript from jsonl path', async () => { process.env.CLAUDE_CODE_SIMPLE = '1' const path = await writeJsonl(user(id(1), 'hello')) const result = await loadConversationForResume('fixture', path) expect(result).not.toBeNull() expect(result?.sessionId).toBe(sessionId) expect(result?.messages.length).toBeGreaterThan(0) }) test('loadConversationForResume rejects oversized reconstructed transcripts', async () => { process.env.CLAUDE_CODE_SIMPLE = '1' const hugeContent = 'x'.repeat(8 * 1024 * 1024 + 32 * 1024) const path = await writeJsonl(user(id(2), hugeContent)) let caught: unknown try { await loadConversationForResume('fixture', path) } catch (error) { caught = error } expect(caught).toBeInstanceOf(ResumeTranscriptTooLargeError) expect((caught as Error).message).toContain( 'Reconstructed transcript is too large to resume safely', ) })