feat(tui): add safe session resume flow

This commit is contained in:
NI0317
2026-07-24 12:31:26 +08:00
committed by ZiyaZhang
parent 65d29da8a1
commit 2ae9f4fdf3
57 changed files with 2312 additions and 192 deletions

View File

@@ -0,0 +1,16 @@
/** Child process that holds one JSONL live-session lease until it is killed. */
import { writeFile } from 'node:fs/promises'
import { Context } from 'cordis'
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl'
const [root, marker] = process.argv.slice(2)
if (root === undefined || marker === undefined) throw new Error('usage: live-lease-child.ts <root> <marker>')
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
await ctx.sessionPersistence.claimLive(SessionId('leased-session'))
await writeFile(marker, 'held')
await new Promise<never>(() => { setInterval(() => {}, 60_000) })

View File

@@ -0,0 +1,33 @@
/** Child process competing to reclaim one stale JSONL live-session lease. */
import { access, writeFile } from 'node:fs/promises'
import { Context } from 'cordis'
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl'
const [root, gate, marker, rawId] = process.argv.slice(2)
if (root === undefined || gate === undefined || marker === undefined || rawId === undefined) {
throw new Error('usage: live-lease-race-child.ts <root> <gate> <marker> <session-id>')
}
for (;;) {
try {
await access(gate)
break
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error
await new Promise(resolve => setTimeout(resolve, 5))
}
}
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
try {
await ctx.sessionPersistence.claimLive(SessionId(rawId))
await writeFile(marker, 'claimed')
await new Promise<never>(() => { setInterval(() => {}, 60_000) })
} catch (error) {
await writeFile(marker, `rejected:${error instanceof Error ? error.message : String(error)}`)
await ctx.fiber.dispose()
}