mirror of
https://github.com/stablyai/orca.git
synced 2026-11-06 03:57:35 +00:00
* refactor(native-chat): remove the records-file and per-chat journal imports Every native chat user is on a build that already moved chat records and history into the app-wide database, so the one-time copies are dead code: the agent-sessions.json import and its owed-copy flag, the per-chat journal.db import and the write-queue hold behind it, and the pre-SQLite log.jsonl notice. * refactor(native-chat): remove what only the deleted imports used - JournalHostDatabase.unsyncedTransaction and the synchronous-pragma reset that undid it; JOURNAL_SYNCHRONOUS is now module-local. The stranded rollback test drives transaction() instead. - deleteUnpublishedJournalRows and its SQL, plus its test. - boundJournalStatusText. - Stale comments naming the removed first-use copy (queued messages, send refusal example, JOURNAL_SYNCHRONOUS doc). - Write-queue and readInOrder comments: a write also lags when issued behind one still waiting in line. - Resolved-append ordering test binds the sink from inside a running read, so a resolver that read at handover now fails it. * test(native-chat): run resolved-append in the SQLite runtime project
130 lines
4.8 KiB
TypeScript
130 lines
4.8 KiB
TypeScript
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { agentSessionRecordFixture } from '../../shared/agent-session-record.test-fixture'
|
|
import { safeParseWorkspaceSession } from '../../shared/workspace-session-schema'
|
|
import {
|
|
openTestAgentSessionRecordStore,
|
|
readPersistedTestAgentSessionStore,
|
|
seedTestAgentSessionRecordStore
|
|
} from './agent-session-record-store-test-harness'
|
|
import { collectSavedStructuredAgentSessionIds } from './saved-structured-agent-session-restoration'
|
|
|
|
const WORKSPACE = 'workspace-1'
|
|
const SESSION = 'session-alpha-1'
|
|
|
|
function structuredTab() {
|
|
return {
|
|
id: `agent-session:${SESSION}`,
|
|
entityId: SESSION,
|
|
groupId: 'group-1',
|
|
worktreeId: WORKSPACE,
|
|
contentType: 'agent-session' as const,
|
|
label: 'Codex Chat',
|
|
customLabel: null,
|
|
color: null,
|
|
sortOrder: 0,
|
|
createdAt: 1
|
|
}
|
|
}
|
|
|
|
function profileWithStructuredTab(): Record<string, unknown> {
|
|
return {
|
|
activeRepoId: null,
|
|
activeWorktreeId: WORKSPACE,
|
|
activeTabId: structuredTab().id,
|
|
tabsByWorktree: {},
|
|
terminalLayoutsByTabId: {},
|
|
activeTabIdByWorktree: { [WORKSPACE]: structuredTab().id },
|
|
unifiedTabs: { [WORKSPACE]: [structuredTab()] }
|
|
}
|
|
}
|
|
|
|
/** The pinned base rejects the new discriminator and salvages the remaining profile. */
|
|
function pinnedBaseRoundTrip(raw: Record<string, unknown>): Record<string, unknown> {
|
|
const unifiedTabs = raw.unifiedTabs as Record<string, unknown[]> | undefined
|
|
return {
|
|
...raw,
|
|
...(unifiedTabs
|
|
? {
|
|
unifiedTabs: Object.fromEntries(
|
|
Object.entries(unifiedTabs).map(([worktreeId, tabs]) => [
|
|
worktreeId,
|
|
tabs.filter((tab) => {
|
|
const contentType = (tab as { contentType?: unknown }).contentType
|
|
return (
|
|
contentType === 'terminal' ||
|
|
contentType === 'editor' ||
|
|
contentType === 'diff' ||
|
|
contentType === 'conflict-review' ||
|
|
contentType === 'check-details' ||
|
|
contentType === 'browser' ||
|
|
contentType === 'simulator'
|
|
)
|
|
})
|
|
])
|
|
)
|
|
}
|
|
: {})
|
|
}
|
|
}
|
|
|
|
let root: string
|
|
|
|
afterEach(async () => {
|
|
await rm(root, { recursive: true, force: true })
|
|
})
|
|
|
|
describe('structured session rollback compatibility', () => {
|
|
it('keeps the visible session reference through target → base → target', async () => {
|
|
root = await mkdtemp(join(tmpdir(), 'orca-structured-rollback-'))
|
|
const record = agentSessionRecordFixture({
|
|
...agentSessionRecordFixture().lease,
|
|
sessionId: SESSION,
|
|
runtimeKind: 'native'
|
|
})
|
|
await seedTestAgentSessionRecordStore(root, { records: [record] })
|
|
|
|
const target = await openTestAgentSessionRecordStore(root)
|
|
expect(target.getVisibleSessionTabIndex()).toEqual({ present: false, sessionIds: [] })
|
|
await target.setSessionTabVisibility(SESSION, true)
|
|
expect(target.getVisibleSessionTabIndex()).toEqual({ present: true, sessionIds: [SESSION] })
|
|
|
|
const targetProfile = profileWithStructuredTab()
|
|
const targetParsed = safeParseWorkspaceSession(targetProfile)
|
|
expect(targetParsed?.success).toBe(true)
|
|
expect(
|
|
collectSavedStructuredAgentSessionIds(targetParsed?.success ? targetParsed.data : null)
|
|
).toEqual([SESSION])
|
|
|
|
const baseProfile = pinnedBaseRoundTrip(targetProfile)
|
|
const baseParsed = safeParseWorkspaceSession(baseProfile)
|
|
expect(baseParsed?.success).toBe(true)
|
|
expect(
|
|
collectSavedStructuredAgentSessionIds(baseParsed?.success ? baseParsed.data : null)
|
|
).toEqual([])
|
|
|
|
await writeFile(join(root, 'profile.json'), JSON.stringify(baseProfile))
|
|
const targetReloadedProfile = safeParseWorkspaceSession(JSON.parse(JSON.stringify(baseProfile)))
|
|
expect(targetReloadedProfile?.success).toBe(true)
|
|
expect(
|
|
collectSavedStructuredAgentSessionIds(
|
|
targetReloadedProfile?.success ? targetReloadedProfile.data : null
|
|
)
|
|
).toEqual([])
|
|
const reloaded = await openTestAgentSessionRecordStore(root)
|
|
expect(reloaded.listVisibleSessionIds()).toEqual([SESSION])
|
|
expect(reloaded.getRecord(SESSION)?.providerHandleChain).toHaveLength(1)
|
|
expect((await readPersistedTestAgentSessionStore(root)).sessionTabs).toEqual([
|
|
{ tabId: expect.any(String), sessionId: SESSION }
|
|
])
|
|
|
|
await reloaded.setSessionTabVisibility(SESSION, false)
|
|
const afterClose = await openTestAgentSessionRecordStore(root)
|
|
expect(afterClose.getVisibleSessionTabIndex()).toEqual({ present: true, sessionIds: [] })
|
|
expect(afterClose.listVisibleSessionIds()).toEqual([])
|
|
expect(afterClose.getRecord(SESSION)?.providerHandleChain).toHaveLength(1)
|
|
})
|
|
})
|