fix(tui): stabilize Windows terminal snapshots

Treat an absolute path.relative() result as a cross-volume path instead of incorrectly abbreviating it beneath the user's home directory.

Allow embeddings to project a logical footer cwd without changing the operational session cwd. The recorded-session harness now uses a POSIX-shaped display alias for both the footer and filesystem result paths, preserving the existing pre-normalization layout width on every host.

Keep runtime-provided labels behind terminal-control escaping, cover that boundary, and document the embedding contract.
This commit is contained in:
Tianyi Cui
2026-07-19 13:20:59 +08:00
parent bdba206640
commit 0f8d0082e4
5 changed files with 68 additions and 12 deletions

View File

@@ -5,7 +5,7 @@ import type { ContentBlock } from '@deepseek-ai/dsh-llm'
import SessionStore, { SessionId, type Session } from '@deepseek-ai/dsh-session'
import type { ToolDefinition } from '@deepseek-ai/dsh-tools'
import UserInteractionService from '@deepseek-ai/dsh-user-interaction'
import { createTuiChat, type Config } from '../src/index.ts'
import { createTuiChat, type Config, type TuiRuntime } from '../src/index.ts'
interface FakeAgent extends Agent {
status: AgentStatus
@@ -21,6 +21,7 @@ export interface TuiHarnessOptions {
configureContext?: (ctx: Context) => Promise<void>
beforeMount?: (session: Session) => void
cwd?: string | null
formatCwd?: TuiRuntime['formatCwd']
}
export interface TuiHarness<TerminalType extends Terminal, Exit extends (code: number) => void> {
@@ -95,7 +96,11 @@ export async function createTuiTestHarness<TerminalType extends Terminal, Exit e
welcome: 'Coding agent ready.',
sessionId,
color: false,
}, options.config), { terminal, exit })
}, options.config), {
terminal,
exit,
...(options.formatCwd === undefined ? {} : { formatCwd: options.formatCwd }),
})
return { ctx, session, agent, terminal, exit, controller }
}

View File

@@ -364,6 +364,13 @@ describe('pi-tui chat lifecycle and transcript', () => {
const outsideResult = await setup({ cwd: '/opt' })
expect(outsideResult.terminal.output).toContain('/opt')
await dispose(outsideResult)
const logicalResult = await setup({
cwd: '/host/worktree',
formatCwd: cwd => `logical:${cwd}\x1b`,
})
expect(logicalResult.terminal.output).toContain('logical:/host/worktree\\x1b')
await dispose(logicalResult)
})
it('sends, steers, handles commands, global keys, and disposed-agent input', async () => {