refactor(tui): drop redundant native-mode guards
This commit is contained in:
committed by
brooklyn!
parent
7e35460ac2
commit
87d1c5b0c3
@@ -1841,7 +1841,7 @@ def cmd_chat(args):
|
||||
_launch_tui(
|
||||
passthrough.pop("resume"),
|
||||
tui_dev=getattr(args, "tui_dev", False),
|
||||
native_mode=True if getattr(args, "tui_native", False) else None,
|
||||
native_mode=getattr(args, "tui_native", False) or None,
|
||||
model=getattr(args, "model", None),
|
||||
accept_hooks=getattr(args, "accept_hooks", False),
|
||||
**passthrough,
|
||||
|
||||
@@ -91,7 +91,7 @@ function VirtualHarness({ items, scrollRef }: VirtualProps) {
|
||||
<Box flexDirection="column" width="100%">
|
||||
{virtual.topSpacer > 0 ? <Box height={virtual.topSpacer} /> : null}
|
||||
{items.slice(virtual.start, virtual.end).map(item => (
|
||||
<Box flexDirection="column" key={item.key} ref={virtual.measureRef(item.key)} minHeight={item.height}>
|
||||
<Box flexDirection="column" key={item.key} minHeight={item.height} ref={virtual.measureRef(item.key)}>
|
||||
<Text>{item.text}</Text>
|
||||
</Box>
|
||||
))}
|
||||
@@ -108,6 +108,7 @@ async function runSample(mode: 'native' | 'virtual', itemCount: number): Promise
|
||||
const scrollRef = { current: null as ScrollBoxHandle | null }
|
||||
|
||||
const items = makeItems(itemCount)
|
||||
|
||||
const renderHarness = (nextItems: readonly Item[]) =>
|
||||
mode === 'native' ? (
|
||||
<NativeHarness items={nextItems} />
|
||||
@@ -117,23 +118,27 @@ async function runSample(mode: 'native' | 'virtual', itemCount: number): Promise
|
||||
|
||||
const heapBefore = process.memoryUsage?.().heapUsed ?? null
|
||||
const mountStart = performance.now()
|
||||
|
||||
const instance = renderSync(renderHarness(items), {
|
||||
patchConsole: false,
|
||||
stderr: stderr as unknown as NodeJS.WriteStream,
|
||||
stdin: stdin as unknown as NodeJS.ReadStream,
|
||||
stdout: stdout as unknown as NodeJS.WriteStream
|
||||
})
|
||||
|
||||
await settle()
|
||||
const mountMs = performance.now() - mountStart
|
||||
|
||||
const rerenderItems = items.map((item, index) =>
|
||||
index === items.length - 1 ? { ...item, text: `${item.text} rerender` } : item
|
||||
)
|
||||
|
||||
const rerenderStart = performance.now()
|
||||
instance.rerender(renderHarness(rerenderItems))
|
||||
await settle()
|
||||
const rerenderMs = performance.now() - rerenderStart
|
||||
const heapAfter = process.memoryUsage?.().heapUsed ?? null
|
||||
|
||||
const sample = {
|
||||
heapDeltaBytes: heapBefore === null || heapAfter === null ? null : heapAfter - heapBefore,
|
||||
mountMs,
|
||||
@@ -147,13 +152,16 @@ async function runSample(mode: 'native' | 'virtual', itemCount: number): Promise
|
||||
stdin.destroy()
|
||||
stdout.destroy()
|
||||
stderr.destroy()
|
||||
|
||||
return sample
|
||||
}
|
||||
|
||||
function distribution(values: number[]) {
|
||||
const sorted = [...values].sort((a, b) => a - b)
|
||||
|
||||
const percentile = (p: number) =>
|
||||
sorted[Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * p) - 1))] ?? 0
|
||||
|
||||
return {
|
||||
max: sorted.at(-1) ?? 0,
|
||||
mean: sorted.reduce((sum, value) => sum + value, 0) / Math.max(1, sorted.length),
|
||||
@@ -168,7 +176,9 @@ function numericArg(name: string, fallback: number) {
|
||||
.slice(2)
|
||||
.find(arg => arg.startsWith(`--${name}=`))
|
||||
?.split('=', 2)[1]
|
||||
|
||||
const parsed = Number(raw)
|
||||
|
||||
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : fallback
|
||||
}
|
||||
|
||||
@@ -177,11 +187,16 @@ function workloadsArg() {
|
||||
.slice(2)
|
||||
.find(arg => arg.startsWith('--items='))
|
||||
?.split('=', 2)[1]
|
||||
if (!raw) return DEFAULT_WORKLOADS
|
||||
|
||||
if (!raw) {
|
||||
return DEFAULT_WORKLOADS
|
||||
}
|
||||
const parsed = raw.split(',').map(Number)
|
||||
|
||||
if (parsed.some(value => !Number.isSafeInteger(value) || value <= 0)) {
|
||||
throw new Error(`invalid --items workload list: ${raw}`)
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
|
||||
@@ -209,6 +224,7 @@ async function main() {
|
||||
|
||||
const virtual: Sample[] = []
|
||||
const native: Sample[] = []
|
||||
|
||||
for (let sample = 0; sample < sampleCount; sample++) {
|
||||
virtual.push(await runSample('virtual', itemCount))
|
||||
native.push(await runSample('native', itemCount))
|
||||
|
||||
@@ -181,14 +181,18 @@ const TranscriptPane = memo(function TranscriptPane({
|
||||
[transcript.historyItems]
|
||||
)
|
||||
|
||||
const clearBlankSelection = (e: { cellIsBlank?: boolean }) => {
|
||||
if (e.cellIsBlank) {
|
||||
actions.clearSelection()
|
||||
}
|
||||
}
|
||||
|
||||
const transcriptContent = (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
{!nativeMode && transcript.virtualHistory.topSpacer > 0 ? (
|
||||
<Box height={transcript.virtualHistory.topSpacer} />
|
||||
) : null}
|
||||
{transcript.virtualHistory.topSpacer > 0 ? <Box height={transcript.virtualHistory.topSpacer} /> : null}
|
||||
|
||||
{transcript.virtualRows
|
||||
.slice(nativeMode ? 0 : transcript.virtualHistory.start, nativeMode ? undefined : transcript.virtualHistory.end)
|
||||
.slice(transcript.virtualHistory.start, transcript.virtualHistory.end)
|
||||
.map(row => (
|
||||
<Box flexDirection="column" key={row.key} ref={transcript.virtualHistory.measureRef(row.key)}>
|
||||
{row.msg.role === 'user' && firstUserIdx >= 0 && row.index > firstUserIdx && (
|
||||
@@ -236,9 +240,7 @@ const TranscriptPane = memo(function TranscriptPane({
|
||||
</Box>
|
||||
))}
|
||||
|
||||
{!nativeMode && transcript.virtualHistory.bottomSpacer > 0 ? (
|
||||
<Box height={transcript.virtualHistory.bottomSpacer} />
|
||||
) : null}
|
||||
{transcript.virtualHistory.bottomSpacer > 0 ? <Box height={transcript.virtualHistory.bottomSpacer} /> : null}
|
||||
|
||||
<StreamingAssistant
|
||||
cols={bodyCols}
|
||||
@@ -258,15 +260,7 @@ const TranscriptPane = memo(function TranscriptPane({
|
||||
return (
|
||||
<>
|
||||
{nativeMode ? (
|
||||
<Box
|
||||
flexDirection="column"
|
||||
flexGrow={1}
|
||||
onClick={(e: { cellIsBlank?: boolean }) => {
|
||||
if (e.cellIsBlank) {
|
||||
actions.clearSelection()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Box flexDirection="column" flexGrow={1} onClick={clearBlankSelection}>
|
||||
{transcriptContent}
|
||||
</Box>
|
||||
) : (
|
||||
@@ -274,11 +268,7 @@ const TranscriptPane = memo(function TranscriptPane({
|
||||
flexDirection="column"
|
||||
flexGrow={1}
|
||||
flexShrink={1}
|
||||
onClick={(e: { cellIsBlank?: boolean }) => {
|
||||
if (e.cellIsBlank) {
|
||||
actions.clearSelection()
|
||||
}
|
||||
}}
|
||||
onClick={clearBlankSelection}
|
||||
ref={transcript.scrollRef}
|
||||
stickyScroll
|
||||
>
|
||||
@@ -421,10 +411,10 @@ const ComposerPane = memo(function ComposerPane({
|
||||
|
||||
<Box
|
||||
flexDirection="column"
|
||||
marginTop={nativeMode ? 0 : ui.statusBar === 'top' ? 0 : 1}
|
||||
marginTop={nativeMode || ui.statusBar === 'top' ? 0 : 1}
|
||||
position={nativeMode ? undefined : 'relative'}
|
||||
>
|
||||
{!nativeMode && <FloatingOverlays {...floatingOverlayProps} nativeMode={false} />}
|
||||
{!nativeMode && <FloatingOverlays {...floatingOverlayProps} />}
|
||||
|
||||
{!nativeMode && composer.input === '?' && !composer.inputBuf.length && <HelpHint t={ui.theme} />}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ export const TERMINAL_MODE_RESET =
|
||||
'\x1b[0m' + // attributes
|
||||
'\x1b[?25h' // cursor visible
|
||||
|
||||
type ResettableStream = Pick<NodeJS.WriteStream, 'isTTY' | 'write'> & {
|
||||
fd?: number
|
||||
}
|
||||
|
||||
/** Native mode leaves its frame in the primary buffer; wipe it on exit so the shell prompt starts clean. */
|
||||
export function clearNativeTuiFrame(stream: ResettableStream = process.stdout): boolean {
|
||||
if (!stream.isTTY) {
|
||||
return false
|
||||
@@ -34,10 +39,6 @@ export function clearNativeTuiFrame(stream: ResettableStream = process.stdout):
|
||||
}
|
||||
}
|
||||
|
||||
type ResettableStream = Pick<NodeJS.WriteStream, 'isTTY' | 'write'> & {
|
||||
fd?: number
|
||||
}
|
||||
|
||||
// OSC 10/11 set the terminal's DEFAULT foreground/background — so every cell,
|
||||
// including text rendered with no explicit color (markdown body, borders,
|
||||
// third-party output), takes the skin instead of the host profile's defaults.
|
||||
|
||||
Reference in New Issue
Block a user