* lighten session list * fetch full session on open * sanitize session list * sanitize global sessions * preserve revert markers in session lists * fix: preserve session metadata in list sanitizers --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
155 lines
4.8 KiB
TypeScript
155 lines
4.8 KiB
TypeScript
import { describe, expect, test } from 'bun:test'
|
|
import type { Session } from '@opencode-ai/sdk/v2'
|
|
|
|
import { stripSessionDiffSnapshots, stripSessionListDetails } from './sanitize'
|
|
|
|
describe('stripSessionDiffSnapshots', () => {
|
|
test('removes oversized revert and summary diff payloads', () => {
|
|
const session = {
|
|
id: 'ses_1',
|
|
slug: 'session-one',
|
|
projectID: 'proj_1',
|
|
directory: '/repo/app',
|
|
title: 'Session',
|
|
version: '1.0.0',
|
|
time: { created: 1, updated: 2 },
|
|
revert: {
|
|
messageID: 'msg_2',
|
|
partID: 'part_3',
|
|
snapshot: 'gitsha',
|
|
diff: 'diff --git a/file b/file',
|
|
},
|
|
summary: {
|
|
additions: 2,
|
|
deletions: 1,
|
|
files: 1,
|
|
diffs: [{ additions: 2, deletions: 1, before: 'a', after: 'b', patch: '@@ -1 +1 @@' }],
|
|
},
|
|
} as unknown as Session
|
|
|
|
const next = stripSessionDiffSnapshots(session) as Session & {
|
|
revert?: { messageID?: string; partID?: string; snapshot?: string; diff?: string }
|
|
summary?: { diffs?: Array<{ before?: string; after?: string; patch?: string }> }
|
|
}
|
|
|
|
expect(next).not.toBe(session)
|
|
expect(next.revert).toEqual({ messageID: 'msg_2', partID: 'part_3' })
|
|
expect(next.summary?.diffs).toEqual([{ additions: 2, deletions: 1 }])
|
|
})
|
|
|
|
test('preserves object identity when nothing changes', () => {
|
|
const session = {
|
|
id: 'ses_1',
|
|
slug: 'session-one',
|
|
projectID: 'proj_1',
|
|
directory: '/repo/app',
|
|
title: 'Session',
|
|
version: '1.0.0',
|
|
time: { created: 1, updated: 2 },
|
|
revert: { messageID: 'msg_2', partID: 'part_3' },
|
|
summary: { additions: 2, deletions: 1, diffs: [{ additions: 2, deletions: 1 }] },
|
|
} as unknown as Session
|
|
|
|
expect(stripSessionDiffSnapshots(session)).toBe(session)
|
|
})
|
|
})
|
|
|
|
describe('stripSessionListDetails', () => {
|
|
test('removes detail-only fields from session list records', () => {
|
|
const session = {
|
|
id: 'ses_1',
|
|
slug: 'session-one',
|
|
projectID: 'proj_1',
|
|
directory: '/repo/app',
|
|
title: 'Session',
|
|
time: { created: 1, updated: 2 },
|
|
metadata: {
|
|
openchamber: {
|
|
kind: 'review',
|
|
originalSessionID: 'ses_original',
|
|
},
|
|
},
|
|
permission: [{ permission: 'todowrite' }],
|
|
revert: {
|
|
messageID: 'msg_2',
|
|
partID: 'part_3',
|
|
snapshot: 'gitsha',
|
|
diff: 'diff --git a/file b/file',
|
|
},
|
|
summary: {
|
|
additions: 2,
|
|
deletions: 1,
|
|
files: 1,
|
|
diffs: [{ additions: 2, deletions: 1, patch: '@@ -1 +1 @@' }],
|
|
},
|
|
} as unknown as Session
|
|
|
|
const next = stripSessionListDetails(session) as Session & {
|
|
metadata?: unknown
|
|
permission?: unknown
|
|
revert?: { messageID?: string; partID?: string; snapshot?: string; diff?: string }
|
|
summary?: { additions?: number; deletions?: number; files?: number; diffs?: unknown[] }
|
|
}
|
|
|
|
expect(next).not.toBe(session)
|
|
expect(next.metadata).toEqual({
|
|
openchamber: {
|
|
kind: 'review',
|
|
originalSessionID: 'ses_original',
|
|
},
|
|
})
|
|
expect(next.permission).toBe(undefined)
|
|
expect(next.revert).toEqual({ messageID: 'msg_2', partID: 'part_3' })
|
|
expect(next.summary).toEqual({ additions: 2, deletions: 1, files: 1 })
|
|
})
|
|
|
|
test('preserves metadata extension fields in session list records', () => {
|
|
const session = {
|
|
id: 'ses_1',
|
|
directory: '/repo/app',
|
|
title: 'Session',
|
|
time: { created: 1, updated: 2 },
|
|
metadata: { custom: { value: 'kept' } },
|
|
summary: { additions: 2, deletions: 1, files: 1, diffs: [{ patch: '@@ -1 +1 @@' }] },
|
|
} as unknown as Session
|
|
|
|
const next = stripSessionListDetails(session) as Session & {
|
|
metadata?: unknown
|
|
summary?: { diffs?: unknown[] }
|
|
}
|
|
|
|
expect(next).not.toBe(session)
|
|
expect(next.metadata).toEqual({ custom: { value: 'kept' } })
|
|
expect(next.summary?.diffs).toBe(undefined)
|
|
})
|
|
|
|
test('keeps summary fields other than list-only diffs', () => {
|
|
const session = {
|
|
id: 'ses_1',
|
|
directory: '/repo/app',
|
|
title: 'Session',
|
|
time: { created: 1, updated: 2 },
|
|
summary: { custom: 'kept', diffs: [{ patch: '@@ -1 +1 @@' }] },
|
|
} as unknown as Session
|
|
|
|
const next = stripSessionListDetails(session) as Session & {
|
|
summary?: { custom?: string; diffs?: unknown[] }
|
|
}
|
|
|
|
expect(next.summary).toEqual({ custom: 'kept' })
|
|
})
|
|
|
|
test('preserves object identity for already lightweight records with revert markers', () => {
|
|
const session = {
|
|
id: 'ses_1',
|
|
directory: '/repo/app',
|
|
title: 'Session',
|
|
time: { created: 1, updated: 2 },
|
|
revert: { messageID: 'msg_2', partID: 'part_3' },
|
|
summary: { additions: 2, deletions: 1, files: 1 },
|
|
} as unknown as Session
|
|
|
|
expect(stripSessionListDetails(session)).toBe(session)
|
|
})
|
|
})
|