fix(tui): unify compaction progress presentation

This commit is contained in:
Hypatia May
2026-07-31 15:27:10 +08:00
parent 57e56915de
commit 85cef9de6f
11 changed files with 94 additions and 147 deletions
+6 -35
View File
@@ -1992,27 +1992,25 @@ describe('pi-tui chat lifecycle and transcript', () => {
await dispose(result)
})
it('shows a dynamic transcript marker and one glyph cell for a live standalone bracket while idle', async () => {
it('shows a live standalone compaction in the fixed status area', async () => {
let clock = 0
const result = await setup({ omitInitialLifecycle: true, now: () => clock })
const idleWidth = promptWidth(result.terminal.output)
result.session.append('compact/start', { turn: null })
await tick()
expect(result.terminal.output).toContain('◐ Compaction in progress…')
clock = 1_000
result.terminal.output = ''
await new Promise(resolve => setTimeout(resolve, 75))
expect(result.terminal.output).toContain('dsh ⊙ ')
expect(result.terminal.output).toContain('Context being compacted 1.0s')
expect(promptWidth(result.terminal.output)).toBe(idleWidth)
expect(result.terminal.progress.at(-1)).toBe(true)
clock = 1_050
clock = 1_450
result.terminal.output = ''
await new Promise(resolve => setTimeout(resolve, 75))
expect(result.terminal.output).toContain('◓')
expect(result.terminal.output).toContain('Context being compacted 1.4s')
await dispose(result)
})
@@ -2024,7 +2022,6 @@ describe('pi-tui chat lifecycle and transcript', () => {
expect(result.terminal.output).toContain('dsh > ')
expect(result.terminal.output).not.toContain('dsh ⊙ ')
expect(result.terminal.output).not.toContain('Compaction in progress…')
expect(result.terminal.progress.at(-1)).toBe(false)
await dispose(result)
})
@@ -2046,7 +2043,7 @@ describe('pi-tui chat lifecycle and transcript', () => {
expect(result.terminal.output).toContain('dsh > ')
expect(result.terminal.output).not.toMatch(/dsh [◍✻●⚙⊙]/u)
expect(result.terminal.output).not.toContain('Compaction in progress…')
expect(result.terminal.output).not.toContain('Context being compacted')
expect(result.terminal.progress.at(-1)).toBe(false)
await dispose(result)
})
@@ -2059,7 +2056,6 @@ describe('pi-tui chat lifecycle and transcript', () => {
await tick()
expect(result.terminal.output).toContain('Compaction failed: summary failed')
expect(result.terminal.output).not.toContain('Compaction in progress…')
expect(result.terminal.progress.at(-1)).toBe(false)
await dispose(result)
})
@@ -2075,7 +2071,6 @@ describe('pi-tui chat lifecycle and transcript', () => {
await tick()
expect(result.terminal.output).toContain('dsh ⊙ ')
expect(result.terminal.output).toContain('Compaction in progress…')
expect(result.terminal.progress.at(-1)).toBe(true)
await dispose(result)
})
@@ -2090,7 +2085,6 @@ describe('pi-tui chat lifecycle and transcript', () => {
expect(result.terminal.output).toContain('dsh ◍ ')
expect(result.terminal.output).not.toContain('dsh ⊙ ')
expect(result.terminal.output).toContain('Compaction in progress…')
result.session.append('compact/end', { turn: null })
await tick()
result.terminal.output = ''
@@ -2120,7 +2114,6 @@ describe('pi-tui chat lifecycle and transcript', () => {
expect(intervalSpy).toHaveBeenCalledOnce()
expect(result.terminal.output).toContain('dsh ⊙ ')
expect(result.terminal.output).toContain('Compaction in progress…')
expect(result.terminal.progress.at(-1)).toBe(true)
result.session.append('compact/end', { turn: null })
@@ -2148,33 +2141,11 @@ describe('pi-tui chat lifecycle and transcript', () => {
expect(result.terminal.output).toContain('dsh > ')
expect(result.terminal.output).not.toContain('dsh ⊙ ')
expect(result.terminal.output).not.toContain('Compaction in progress…')
expect(result.terminal.output).not.toContain('Context being compacted')
expect(result.terminal.progress.at(-1)).toBe(false)
await dispose(result)
})
it('keeps the live compaction marker at the transcript tail across new content and clear', async () => {
const result = await setup({ omitInitialLifecycle: true, now: () => 1_000 })
result.session.append('compact/start', { turn: null })
result.terminal.output = ''
appendUser(result.session, 'arrived during compaction')
await tick()
expect(result.terminal.output).toContain('arrived during compaction')
expect(result.terminal.output).toContain('Compaction in progress…')
result.terminal.output = ''
result.terminal.send('/clear')
result.terminal.send('\r')
await tick()
result.terminal.resize(result.terminal.columns + 1)
await tick()
expect(result.terminal.output).toContain('Compaction in progress…')
result.session.append('compact/end', { turn: null })
await dispose(result)
})
it('releases the live compaction timer and progress bit on dispose', async () => {
const intervalSpy = vi.spyOn(globalThis, 'setInterval')
const clearIntervalSpy = vi.spyOn(globalThis, 'clearInterval')