Add persistent disk cache for parsed session data
Some checks are pending
CI / semgrep (push) Waiting to run

Cache normalized turns/calls to ~/.cache/codeburn/session-cache.json so
the CLI skips re-parsing unchanged JSONL files on subsequent runs.
File reconciliation uses dev+ino+mtime+size fingerprinting; cost,
classification, and summaries are recomputed at query time. Atomic
writes via temp+fsync+rename, deep structural validation on load,
per-provider env fingerprinting, and best-effort save so cache failures
never break the CLI. ~6x speedup on warm cache.
This commit is contained in:
iamtoruk 2026-05-16 01:04:13 -07:00
parent d568c8c103
commit bd41fa3962
6 changed files with 1236 additions and 51 deletions

View file

@ -117,4 +117,56 @@ describe('readSessionLines', () => {
await gen.next()
await gen.return(undefined)
})
it('reads from startByteOffset, yielding only lines after the offset', async () => {
const content = 'line1\nline2\nline3\n'
const p = await tmpPath(content)
const offset = Buffer.byteLength('line1\n')
const lines: string[] = []
for await (const line of readSessionLines(p, undefined, { startByteOffset: offset })) {
lines.push(line)
}
expect(lines).toEqual(['line2', 'line3'])
})
it('byteOffsetTracker tracks position after last complete newline', async () => {
const content = 'aaa\nbbb\nccc\n'
const p = await tmpPath(content)
const tracker = { lastCompleteLineOffset: 0 }
const lines: string[] = []
for await (const line of readSessionLines(p, undefined, { byteOffsetTracker: tracker })) {
lines.push(line)
}
expect(lines).toEqual(['aaa', 'bbb', 'ccc'])
expect(tracker.lastCompleteLineOffset).toBe(Buffer.byteLength(content))
})
it('byteOffsetTracker accounts for startByteOffset', async () => {
const content = 'line1\nline2\nline3\n'
const p = await tmpPath(content)
const offset = Buffer.byteLength('line1\n')
const tracker = { lastCompleteLineOffset: 0 }
for await (const _line of readSessionLines(p, undefined, { startByteOffset: offset, byteOffsetTracker: tracker })) {}
expect(tracker.lastCompleteLineOffset).toBe(Buffer.byteLength(content))
})
it('byteOffsetTracker excludes trailing partial line (no final newline)', async () => {
const content = 'line1\nline2\npartial'
const p = await tmpPath(content)
const tracker = { lastCompleteLineOffset: 0 }
for await (const _line of readSessionLines(p, undefined, { byteOffsetTracker: tracker })) {}
expect(tracker.lastCompleteLineOffset).toBe(Buffer.byteLength('line1\nline2\n'))
})
it('byteOffsetTracker updates for skipped lines too', async () => {
const content = 'skip-me\nkeep-me\n'
const p = await tmpPath(content)
const tracker = { lastCompleteLineOffset: 0 }
const lines: string[] = []
for await (const line of readSessionLines(p, head => head.includes('skip-me'), { byteOffsetTracker: tracker })) {
lines.push(line)
}
expect(lines).toEqual(['keep-me'])
expect(tracker.lastCompleteLineOffset).toBe(Buffer.byteLength(content))
})
})