mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Consolidates the personal dsh-tui customizations (module split into components/session/extension, prompt template + running-glyph indicator, copyable transcript, tool-card headers, timing placement, XML tool output, status/footer rework) and ports upstream's model reasoning-effort selector (Shift+Tab effort cycling, effort-aware /model, footer, and /status) onto the personal module layout.
588 lines
19 KiB
TypeScript
588 lines
19 KiB
TypeScript
import { Context } from 'cordis'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import type { Agent } from '@deepseek-ai/dsh-agent'
|
|
import type {
|
|
Component,
|
|
OverlayHandle,
|
|
} from '@earendil-works/pi-tui'
|
|
import type {
|
|
TuiComponent,
|
|
TuiOverlayHost,
|
|
TuiOverlayOptions,
|
|
TuiOverlaySession,
|
|
TuiTheme,
|
|
} from '../src/extension/types.ts'
|
|
import {
|
|
TuiExtensionServiceImpl,
|
|
TuiOverlayManager,
|
|
type TuiOverlayDriver,
|
|
} from '../src/extension/overlay-manager.ts'
|
|
|
|
const theme: TuiTheme = Object.freeze({
|
|
text: (value: string) => `text:${value}`,
|
|
muted: (value: string) => `muted:${value}`,
|
|
dim: (value: string) => `dim:${value}`,
|
|
accent: (value: string) => `accent:${value}`,
|
|
success: (value: string) => `success:${value}`,
|
|
warning: (value: string) => `warning:${value}`,
|
|
error: (value: string) => `error:${value}`,
|
|
bold: (value: string) => `bold:${value}`,
|
|
})
|
|
|
|
interface ShownOverlay {
|
|
component: Component
|
|
options: TuiOverlayOptions | undefined
|
|
hidden: boolean
|
|
focused: boolean
|
|
}
|
|
|
|
interface DriverFixture {
|
|
driver: TuiOverlayDriver
|
|
shown: ShownOverlay[]
|
|
errors: unknown[]
|
|
invalidations: number
|
|
showError?: unknown
|
|
onShow?: (component: Component) => void
|
|
}
|
|
|
|
function driverFixture(): DriverFixture {
|
|
const fixture: DriverFixture = {
|
|
shown: [],
|
|
errors: [],
|
|
invalidations: 0,
|
|
driver: undefined as never,
|
|
}
|
|
fixture.driver = {
|
|
viewport: () => ({ columns: 96, rows: 32 }),
|
|
theme: () => theme,
|
|
display: value => `safe:${value}`,
|
|
show(component, options) {
|
|
if (fixture.showError !== undefined) throw fixture.showError
|
|
const shown: ShownOverlay = {
|
|
component,
|
|
options,
|
|
hidden: false,
|
|
focused: true,
|
|
}
|
|
fixture.shown.push(shown)
|
|
const handle: OverlayHandle = {
|
|
hide() {
|
|
shown.hidden = true
|
|
shown.focused = false
|
|
},
|
|
setHidden(hidden) {
|
|
shown.hidden = hidden
|
|
},
|
|
isHidden: () => shown.hidden,
|
|
focus() {
|
|
shown.focused = true
|
|
},
|
|
unfocus() {
|
|
shown.focused = false
|
|
},
|
|
isFocused: () => shown.focused,
|
|
}
|
|
fixture.onShow?.(component)
|
|
return handle
|
|
},
|
|
invalidate() {
|
|
fixture.invalidations += 1
|
|
},
|
|
reportError(error) {
|
|
fixture.errors.push(error)
|
|
},
|
|
}
|
|
return fixture
|
|
}
|
|
|
|
function component(lines = ['overlay']): TuiComponent {
|
|
return {
|
|
render: () => lines,
|
|
invalidate() {},
|
|
}
|
|
}
|
|
|
|
async function microtask(): Promise<void> {
|
|
await Promise.resolve()
|
|
await Promise.resolve()
|
|
}
|
|
|
|
describe('TuiOverlayManager', () => {
|
|
it('serializes overlays, exposes the constrained host, and settles normal close once', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
let firstHost: TuiOverlayHost | undefined
|
|
const firstComponent = {
|
|
focused: false,
|
|
wantsKeyRelease: true,
|
|
inputs: [] as string[],
|
|
invalidated: 0,
|
|
render: (width: number) => [`first:${String(width)}`],
|
|
handleInput(data: string) {
|
|
this.inputs.push(data)
|
|
},
|
|
invalidate() {
|
|
this.invalidated += 1
|
|
},
|
|
}
|
|
const first = manager.open({
|
|
create(host) {
|
|
firstHost = host
|
|
return firstComponent
|
|
},
|
|
options: { width: '75%', minWidth: 24, maxHeight: 20, anchor: 'center', margin: { bottom: 1 } },
|
|
})
|
|
const secondOptions: TuiOverlayOptions = { width: 40, margin: { bottom: 2 } }
|
|
const second = manager.open({
|
|
create: () => component(['second']),
|
|
options: secondOptions,
|
|
})
|
|
;(secondOptions as { width: number }).width = 80
|
|
;(secondOptions.margin as { bottom: number }).bottom = 4
|
|
|
|
expect(manager.hasActiveOverlay()).toBe(true)
|
|
expect(first.state).toBe('active')
|
|
expect(second.state).toBe('queued')
|
|
expect(fixture.shown).toHaveLength(1)
|
|
expect(fixture.shown[0]?.options).toEqual({
|
|
width: '75%',
|
|
minWidth: 24,
|
|
maxHeight: 20,
|
|
anchor: 'center',
|
|
margin: { bottom: 1 },
|
|
})
|
|
expect(firstHost?.viewport).toEqual({ columns: 96, rows: 32 })
|
|
expect(Object.isFrozen(firstHost?.viewport)).toBe(true)
|
|
expect(firstHost?.theme.accent('x')).toBe('accent:x')
|
|
expect(firstHost?.display('\u001b')).toBe('safe:\u001b')
|
|
firstHost?.invalidate()
|
|
expect(firstComponent.invalidated).toBe(1)
|
|
expect(fixture.shown[0]?.component.render(40)).toEqual(['first:40'])
|
|
fixture.shown[0]!.component.handleInput?.('x')
|
|
fixture.shown[0]!.component.invalidate()
|
|
expect(firstComponent.inputs).toEqual(['x'])
|
|
expect(firstComponent.invalidated).toBe(2)
|
|
expect(fixture.shown[0]?.component.wantsKeyRelease).toBe(true)
|
|
;(fixture.shown[0]?.component as Component & { focused: boolean }).focused = true
|
|
expect(firstComponent.focused).toBe(true)
|
|
expect((fixture.shown[0]?.component as Component & { focused: boolean }).focused).toBe(true)
|
|
|
|
const firstOutcome = await first.close()
|
|
expect(firstOutcome).toEqual({ reason: 'closed' })
|
|
expect(await first.close()).toBe(firstOutcome)
|
|
expect(firstHost?.signal.aborted).toBe(true)
|
|
const beforeClosedInvalidation = fixture.invalidations
|
|
firstHost?.invalidate()
|
|
expect(fixture.invalidations).toBe(beforeClosedInvalidation)
|
|
await microtask()
|
|
|
|
expect(first.state).toBe('closed')
|
|
expect(second.state).toBe('active')
|
|
expect(fixture.shown[0]?.hidden).toBe(true)
|
|
expect(fixture.shown[1]?.options).toEqual({ width: 40, margin: { bottom: 2 } })
|
|
expect(Object.isFrozen(fixture.shown[1]?.options)).toBe(true)
|
|
expect(Object.isFrozen(fixture.shown[1]?.options?.margin)).toBe(true)
|
|
expect(fixture.shown[1]?.component.wantsKeyRelease).toBe(false)
|
|
expect((fixture.shown[1]?.component as Component & { focused: boolean }).focused).toBe(false)
|
|
;(fixture.shown[1]?.component as Component & { focused: boolean }).focused = true
|
|
fixture.shown[1]!.component.handleInput?.('ignored')
|
|
await second.close()
|
|
await microtask()
|
|
|
|
const numericMargin = manager.open({
|
|
create: () => component(['numeric margin']),
|
|
options: { margin: 1 },
|
|
})
|
|
expect(fixture.shown[2]?.options).toEqual({ margin: 1 })
|
|
await numericMargin.close()
|
|
await microtask()
|
|
|
|
const emptyOptions = manager.open({
|
|
create: () => component(['empty options']),
|
|
options: {},
|
|
})
|
|
expect(fixture.shown[3]?.options).toEqual({})
|
|
await emptyOptions.close()
|
|
await microtask()
|
|
|
|
expect(manager.hasActiveOverlay()).toBe(false)
|
|
await manager.dispose()
|
|
await manager.dispose()
|
|
})
|
|
|
|
it('removes pre-aborted, active, and queued requests without activating cancelled work', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const preAborted = new AbortController()
|
|
preAborted.abort()
|
|
const pre = manager.open({
|
|
signal: preAborted.signal,
|
|
create: () => component(['never']),
|
|
})
|
|
expect(await pre.closed).toEqual({ reason: 'aborted' })
|
|
expect(fixture.shown).toHaveLength(0)
|
|
|
|
const activeAbort = new AbortController()
|
|
let activeHost: TuiOverlayHost | undefined
|
|
const active = manager.open({
|
|
signal: activeAbort.signal,
|
|
create(host) {
|
|
activeHost = host
|
|
return component(['active'])
|
|
},
|
|
})
|
|
const queuedAbort = new AbortController()
|
|
const queued = manager.open({
|
|
signal: queuedAbort.signal,
|
|
create: () => component(['queued']),
|
|
})
|
|
queuedAbort.abort()
|
|
expect(await queued.closed).toEqual({ reason: 'aborted' })
|
|
expect(queued.state).toBe('closed')
|
|
activeAbort.abort()
|
|
expect(await active.closed).toEqual({ reason: 'aborted' })
|
|
expect(activeHost?.signal.aborted).toBe(true)
|
|
await microtask()
|
|
expect(fixture.shown).toHaveLength(1)
|
|
expect(manager.hasActiveOverlay()).toBe(false)
|
|
})
|
|
|
|
it('does not mount entries closed or aborted during component construction', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const closed = manager.open({
|
|
create(host) {
|
|
host.invalidate()
|
|
host.close()
|
|
return component(['closed during construction'])
|
|
},
|
|
})
|
|
await expect(closed.closed).resolves.toEqual({ reason: 'closed' })
|
|
|
|
const controller = new AbortController()
|
|
const aborted = manager.open({
|
|
signal: controller.signal,
|
|
create() {
|
|
controller.abort()
|
|
return component(['aborted during construction'])
|
|
},
|
|
})
|
|
await expect(aborted.closed).resolves.toEqual({ reason: 'aborted' })
|
|
|
|
const after = manager.open({ create: () => component(['after construction closes']) })
|
|
expect(fixture.shown).toHaveLength(1)
|
|
expect(fixture.shown[0]?.component.render(40)).toEqual(['after construction closes'])
|
|
await after.close()
|
|
})
|
|
|
|
it('hides a handle returned after reentrant closure during mounting', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
fixture.onShow = (shown) => {
|
|
;(shown as Component & { focused: boolean }).focused = true
|
|
}
|
|
const closed = manager.open({
|
|
create(host) {
|
|
return {
|
|
get focused(): boolean {
|
|
return false
|
|
},
|
|
set focused(_value: boolean) {
|
|
host.close()
|
|
},
|
|
render: () => ['closed during mount'],
|
|
invalidate() {},
|
|
}
|
|
},
|
|
})
|
|
await expect(closed.closed).resolves.toEqual({ reason: 'closed' })
|
|
expect(fixture.shown[0]?.hidden).toBe(true)
|
|
expect(manager.hasActiveOverlay()).toBe(false)
|
|
|
|
delete fixture.onShow
|
|
const after = manager.open({ create: () => component(['after mount close']) })
|
|
expect(fixture.shown[1]?.hidden).toBe(false)
|
|
expect(fixture.shown[1]?.component.render(40)).toEqual(['after mount close'])
|
|
await after.close()
|
|
})
|
|
|
|
it('stops admission and disposes active and queued overlays with the TUI', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const active = manager.open({ create: () => component(['active']) })
|
|
const queued = manager.open({ create: () => component(['queued']) })
|
|
manager.beginShutdown()
|
|
expect(() => manager.open({ create: () => component() })).toThrow('TUI is shutting down')
|
|
await manager.dispose()
|
|
expect(await active.closed).toEqual({ reason: 'tui-disposed' })
|
|
expect(await queued.closed).toEqual({ reason: 'tui-disposed' })
|
|
expect(fixture.shown).toHaveLength(1)
|
|
expect(fixture.shown[0]?.hidden).toBe(true)
|
|
await manager.dispose()
|
|
})
|
|
|
|
it('contains factory, mount, render, input, and invalidation failures', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const factoryError = new Error('factory failed')
|
|
const factory = manager.open({
|
|
create() {
|
|
throw factoryError
|
|
},
|
|
})
|
|
const afterFactory = manager.open({ create: () => component(['after factory']) })
|
|
expect(await factory.closed).toEqual({ reason: 'error', error: factoryError })
|
|
await microtask()
|
|
expect(afterFactory.state).toBe('active')
|
|
await afterFactory.close()
|
|
await microtask()
|
|
|
|
const showError = new Error('show failed')
|
|
fixture.showError = showError
|
|
const show = manager.open({ create: () => component(['show']) })
|
|
expect(await show.closed).toEqual({ reason: 'error', error: showError })
|
|
delete fixture.showError
|
|
await microtask()
|
|
|
|
const renderError = new Error('render failed')
|
|
const rendering = manager.open({
|
|
create: () => ({
|
|
render() {
|
|
throw renderError
|
|
},
|
|
invalidate() {
|
|
throw new Error('must be suppressed after the first failure')
|
|
},
|
|
}),
|
|
})
|
|
const renderComponent = fixture.shown.at(-1)!.component
|
|
expect(renderComponent.render(20)).toEqual([])
|
|
renderComponent.invalidate()
|
|
expect(fixture.errors.filter(error => error === renderError)).toHaveLength(1)
|
|
expect(await rendering.closed).toEqual({ reason: 'error', error: renderError })
|
|
await microtask()
|
|
|
|
const inputError = new Error('input failed')
|
|
const input = manager.open({
|
|
create: () => ({
|
|
render: () => ['input'],
|
|
handleInput() {
|
|
throw inputError
|
|
},
|
|
invalidate() {},
|
|
}),
|
|
})
|
|
fixture.shown.at(-1)!.component.handleInput?.('x')
|
|
expect(await input.closed).toEqual({ reason: 'error', error: inputError })
|
|
await microtask()
|
|
|
|
const invalidateError = new Error('invalidate failed')
|
|
let invalidatingHost: TuiOverlayHost | undefined
|
|
const invalidating = manager.open({
|
|
create(host) {
|
|
invalidatingHost = host
|
|
return {
|
|
render: () => ['invalidate'],
|
|
invalidate() {
|
|
throw invalidateError
|
|
},
|
|
}
|
|
},
|
|
})
|
|
const invalidationsBeforeFailure = fixture.invalidations
|
|
invalidatingHost?.invalidate()
|
|
invalidatingHost?.invalidate()
|
|
expect(fixture.invalidations).toBe(invalidationsBeforeFailure)
|
|
expect(await invalidating.closed).toEqual({ reason: 'error', error: invalidateError })
|
|
await microtask()
|
|
|
|
const focusError = new Error('focus failed')
|
|
const focus = manager.open({
|
|
create: () => ({
|
|
get focused(): boolean {
|
|
throw focusError
|
|
},
|
|
set focused(_value: boolean) {
|
|
throw new Error('focus assignment failed')
|
|
},
|
|
get wantsKeyRelease(): boolean {
|
|
throw new Error('key-release query failed')
|
|
},
|
|
render: () => ['focus'],
|
|
invalidate() {},
|
|
}),
|
|
})
|
|
const guarded = fixture.shown.at(-1)!.component as Component & { focused: boolean }
|
|
expect(guarded.focused).toBe(false)
|
|
guarded.focused = true
|
|
expect(guarded.wantsKeyRelease).toBe(false)
|
|
expect(await focus.closed).toEqual({ reason: 'error', error: focusError })
|
|
expect(fixture.errors).toEqual([
|
|
factoryError,
|
|
showError,
|
|
renderError,
|
|
inputError,
|
|
invalidateError,
|
|
focusError,
|
|
])
|
|
})
|
|
|
|
it('contains host redraw, overlay removal, and error-reporter failures', async () => {
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
let host: TuiOverlayHost | undefined
|
|
const invalidationError = new Error('redraw failed')
|
|
let redrawFails = false
|
|
fixture.driver.invalidate = () => {
|
|
if (redrawFails) throw invalidationError
|
|
}
|
|
fixture.driver.reportError = () => { throw new Error('report failed') }
|
|
const invalidating = manager.open({
|
|
create(value) {
|
|
host = value
|
|
return component()
|
|
},
|
|
})
|
|
redrawFails = true
|
|
host?.invalidate()
|
|
expect(await invalidating.closed).toEqual({ reason: 'error', error: invalidationError })
|
|
await microtask()
|
|
|
|
redrawFails = false
|
|
fixture.driver.invalidate = () => {}
|
|
const hideError = new Error('hide failed')
|
|
fixture.driver.show = () => ({
|
|
hide() { throw hideError },
|
|
setHidden() {},
|
|
isHidden: () => false,
|
|
focus() {},
|
|
unfocus() {},
|
|
isFocused: () => true,
|
|
})
|
|
const hiding = manager.open({
|
|
create(value) {
|
|
host = value
|
|
return component()
|
|
},
|
|
})
|
|
host?.close()
|
|
expect(await hiding.closed).toEqual({ reason: 'closed' })
|
|
})
|
|
})
|
|
|
|
describe('TuiExtensionService', () => {
|
|
it('binds an open overlay to the calling plugin fiber', async () => {
|
|
const ctx = new Context()
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const agent = {} as Agent
|
|
const provider = ctx.plugin((providerCtx) => {
|
|
new TuiExtensionServiceImpl(providerCtx, agent, manager)
|
|
})
|
|
await provider
|
|
let session: TuiOverlaySession | undefined
|
|
let host: TuiOverlayHost | undefined
|
|
const consumer = ctx.inject(['tui'], (consumerCtx) => {
|
|
expect(consumerCtx.tui.agent).toBe(agent)
|
|
session = consumerCtx.tui.openOverlay({
|
|
create(value) {
|
|
host = value
|
|
return component(['plugin'])
|
|
},
|
|
})
|
|
})
|
|
await consumer
|
|
expect(session?.state).toBe('active')
|
|
|
|
await consumer.dispose()
|
|
expect(await session?.closed).toEqual({ reason: 'owner-disposed' })
|
|
expect(host?.signal.aborted).toBe(true)
|
|
await provider.dispose()
|
|
await manager.dispose()
|
|
await ctx.fiber.dispose()
|
|
})
|
|
|
|
it('unloads and reloads dependent plugins with the mounted TUI service', async () => {
|
|
const ctx = new Context()
|
|
const agent = {} as Agent
|
|
const sessions: TuiOverlaySession[] = []
|
|
let starts = 0
|
|
const consumer = ctx.inject(['tui'], (consumerCtx) => {
|
|
starts += 1
|
|
sessions.push(consumerCtx.tui.openOverlay({ create: () => component([`start:${String(starts)}`]) }))
|
|
})
|
|
|
|
const firstFixture = driverFixture()
|
|
const firstManager = new TuiOverlayManager(firstFixture.driver)
|
|
const firstProvider = ctx.plugin((providerCtx) => {
|
|
new TuiExtensionServiceImpl(providerCtx, agent, firstManager)
|
|
})
|
|
await firstProvider
|
|
await consumer
|
|
expect(starts).toBe(1)
|
|
await firstProvider.dispose()
|
|
expect(await sessions[0]?.closed).toEqual({ reason: 'owner-disposed' })
|
|
|
|
const secondFixture = driverFixture()
|
|
const secondManager = new TuiOverlayManager(secondFixture.driver)
|
|
const secondProvider = ctx.plugin((providerCtx) => {
|
|
new TuiExtensionServiceImpl(providerCtx, agent, secondManager)
|
|
})
|
|
await secondProvider
|
|
await vi.waitFor(() => { expect(starts).toBe(2) })
|
|
await sessions[1]?.close()
|
|
await consumer.dispose()
|
|
await secondProvider.dispose()
|
|
await firstManager.dispose()
|
|
await secondManager.dispose()
|
|
await ctx.fiber.dispose()
|
|
})
|
|
|
|
it('rejects new service work after terminal shutdown begins', async () => {
|
|
const ctx = new Context()
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const provider = ctx.plugin((providerCtx) => {
|
|
new TuiExtensionServiceImpl(providerCtx, {} as Agent, manager)
|
|
})
|
|
await provider
|
|
manager.beginShutdown()
|
|
const consumer = ctx.inject(['tui'], (consumerCtx) => {
|
|
expect(() => consumerCtx.tui.openOverlay({ create: () => component() }))
|
|
.toThrow('TUI is shutting down')
|
|
})
|
|
await consumer
|
|
await consumer.dispose()
|
|
await provider.dispose()
|
|
await manager.dispose()
|
|
await ctx.fiber.dispose()
|
|
})
|
|
|
|
it('does not admit an overlay when called from an unloading plugin', async () => {
|
|
const ctx = new Context()
|
|
const fixture = driverFixture()
|
|
const manager = new TuiOverlayManager(fixture.driver)
|
|
const provider = ctx.plugin((providerCtx) => {
|
|
new TuiExtensionServiceImpl(providerCtx, {} as Agent, manager)
|
|
})
|
|
await provider
|
|
let error: unknown
|
|
const consumer = ctx.inject(['tui'], (consumerCtx) => {
|
|
consumerCtx.effect(() => () => {
|
|
try {
|
|
consumerCtx.tui.openOverlay({ create: () => component() })
|
|
} catch (value) {
|
|
error = value
|
|
}
|
|
})
|
|
})
|
|
await consumer
|
|
await consumer.dispose()
|
|
expect(error).toMatchObject({ code: 'INACTIVE_EFFECT' })
|
|
expect(fixture.shown).toHaveLength(0)
|
|
await provider.dispose()
|
|
await manager.dispose()
|
|
await ctx.fiber.dispose()
|
|
})
|
|
})
|