mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 10:27:33 +00:00
Exercise predecessor status at its editor boundary
Replace a counterfactual shell boundary inside an application screen with recorded editor writes through the actual status producer. Verify stale support rejection, current repaint acceptance, and unattributed fallback. Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
This commit is contained in:
co-authored by
Jinjing
parent
a4a99099cf
commit
6abdd55456
@@ -1,3 +1,4 @@
|
||||
import { observeFreebuffTerminalStatus } from '../output/freebuff-terminal-status'
|
||||
import { HeadlessEmulator } from '../../../daemon/emulation/headless-emulator'
|
||||
import { readRuntimeFixture } from './agent-transcript-replay-test-harness'
|
||||
import { MAX_TAIL_CHARS } from '../output/tail/terminal-tail-limits'
|
||||
@@ -7,7 +8,6 @@ import {
|
||||
setTerminalLineOrigins,
|
||||
terminalOriginSpan,
|
||||
terminalScreenSupport,
|
||||
joinedTerminalOrigins,
|
||||
terminalSupportQuery
|
||||
} from '../../../../shared/terminal/output/terminal-content-origin'
|
||||
import { buildVisibleSnapshotReadFallback } from '../output/tail/terminal-tail-read'
|
||||
@@ -23,10 +23,7 @@ import {
|
||||
readWaitBlockedCarry
|
||||
} from './wait-blocked-check-state'
|
||||
import { restoreFromReattachedReadyScreen } from './reattached-ready-screen'
|
||||
import {
|
||||
readFreebuffScreenStatus,
|
||||
FreebuffScreenStatusTracker
|
||||
} from '../../../../shared/freebuff-screen-status'
|
||||
import { readFreebuffScreenStatus } from '../../../../shared/freebuff-screen-status'
|
||||
import { TerminalCommandPaint, terminalTitleIsPredecessor } from '../input/terminal-command-paint'
|
||||
import { buildTerminalActionText, readTerminalActionText } from '../output/terminal-action-text'
|
||||
import { extractAllOscTitleEntries } from '../../../../shared/agent-status/title/osc-title-extraction'
|
||||
@@ -156,29 +153,47 @@ it('does not promote a known predecessor screen on reattach and retains unknown
|
||||
expect(applyIdle).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('qualifies Freebuff supports before deduplication and keeps unknown grammar', async () => {
|
||||
it('qualifies edited Freebuff supports before publishing and keeps unknown grammar', async () => {
|
||||
const owner = {}
|
||||
const scope = { owner, epoch: 2 }
|
||||
const old = { owner, epoch: 1 }
|
||||
const current = { owner, epoch: 2 }
|
||||
const recording = readRuntimeFixture('freebuff-ready')
|
||||
const ready = `${recording.slice(recording.indexOf('\x1b[?1049h')).split('\x1b[?2026l')[0]!}\x1b[?2026l`
|
||||
const emulator = new HeadlessEmulator({ cols: 120, rows: 40 })
|
||||
let lines: string[]
|
||||
try {
|
||||
await emulator.write(ready)
|
||||
lines = emulator.getVisibleLines()
|
||||
await emulator.write(ready, { contentOrigin: old })
|
||||
expect(
|
||||
observeFreebuffTerminalStatus(emulator, ready, undefined, 'freebuff', old)
|
||||
).toMatchObject({
|
||||
state: 'done',
|
||||
sessionBoundary: true
|
||||
})
|
||||
const working = '\x1b[33;1Hworking...'
|
||||
await emulator.write(working, { contentOrigin: old })
|
||||
expect(
|
||||
observeFreebuffTerminalStatus(emulator, working, undefined, 'freebuff', old)
|
||||
).toMatchObject({
|
||||
state: 'working'
|
||||
})
|
||||
const erase = '\x1b[33;1H\x1b[2K'
|
||||
await emulator.write(erase, { contentOrigin: current })
|
||||
expect(
|
||||
observeFreebuffTerminalStatus(emulator, erase, undefined, 'freebuff', current)
|
||||
).toBeNull()
|
||||
expect(readFreebuffScreenStatus(emulator.getVisibleLines(), true)).toMatchObject({
|
||||
state: 'done',
|
||||
sessionBoundary: true
|
||||
})
|
||||
await emulator.write(ready, { contentOrigin: current })
|
||||
expect(
|
||||
observeFreebuffTerminalStatus(emulator, ready, undefined, 'freebuff', current)
|
||||
).toMatchObject({
|
||||
state: 'done',
|
||||
sessionBoundary: true
|
||||
})
|
||||
} finally {
|
||||
emulator.dispose()
|
||||
}
|
||||
const old = lines.map((line) => terminalOriginSpan(line.length, { owner, epoch: 1 }))
|
||||
setTerminalLineOrigins(lines, old)
|
||||
const joined = joinedTerminalOrigins(lines)
|
||||
const support = terminalSupportQuery(joined.origins, scope)
|
||||
const tracker = new FreebuffScreenStatusTracker(true)
|
||||
expect(tracker.observe('erase', () => ({ lines, alternate: true, support }))).toBeNull()
|
||||
expect(tracker.observe('paint', () => ({ lines, alternate: true }))).toMatchObject({
|
||||
state: 'done',
|
||||
sessionBoundary: true
|
||||
})
|
||||
expect(
|
||||
readFreebuffScreenStatus(
|
||||
['freebuff found agent files in this repository', 'Load and run these? [y/N]'],
|
||||
|
||||
@@ -315,34 +315,3 @@ it('does not promote a retained Qoder composer after replacement until it is rep
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('does not turn old Freebuff ready support into fresh status when only the working row is erased', async () => {
|
||||
const { runtime, handle } = await createTranscriptPane({
|
||||
paneTitle: 'Terminal',
|
||||
foregroundProcess: 'freebuff',
|
||||
launchAgent: 'freebuff',
|
||||
data: '',
|
||||
size: { cols: 120, rows: 40 }
|
||||
})
|
||||
vi.useFakeTimers()
|
||||
try {
|
||||
const write = (data: string) => runtime.onPtyData(TRANSCRIPT_PANE_PTY_ID, data, Date.now())
|
||||
const recording = readRuntimeFixture('freebuff-ready')
|
||||
const ready = `${recording.slice(recording.indexOf('\x1b[?1049h')).split('\x1b[?2026l')[0]!}\x1b[?2026l`
|
||||
write(`\x1b]133;C\x07\x1b]0;Freebuff: task\x07\x1b[?1049h\x1b[H${ready}`)
|
||||
await runtime.readTerminal(handle, { screen: true })
|
||||
write('\x1b[33;1Hworking...')
|
||||
await runtime.readTerminal(handle, { screen: true })
|
||||
write('\x1b]133;C\x07\x1b[33;1H\x1b[2K')
|
||||
const settled = vi.fn()
|
||||
const wait = runtime.waitForTerminal(handle, { condition: 'tui-idle', timeoutMs: 60000 })
|
||||
wait.then(settled, () => {})
|
||||
await vi.advanceTimersByTimeAsync(6000)
|
||||
expect(settled).not.toHaveBeenCalled()
|
||||
write(`\x1b[H${ready}`)
|
||||
await vi.advanceTimersByTimeAsync(4000)
|
||||
await expect(wait).resolves.toMatchObject({ satisfied: true })
|
||||
} finally {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user