diff --git a/ui-tui/src/components/appLayout.tsx b/ui-tui/src/components/appLayout.tsx index fe370700dd..d3d702355b 100644 --- a/ui-tui/src/components/appLayout.tsx +++ b/ui-tui/src/components/appLayout.tsx @@ -30,6 +30,8 @@ const TranscriptPane = memo(function TranscriptPane({ <> + + {transcript.virtualHistory.topSpacer > 0 ? : null} {transcript.virtualRows.slice(transcript.virtualHistory.start, transcript.virtualHistory.end).map(row => ( @@ -58,8 +60,6 @@ const TranscriptPane = memo(function TranscriptPane({ {transcript.virtualHistory.bottomSpacer > 0 ? : null} - - { + const tone = todoTone(status) + + return tone === 'active' ? t.color.cornsilk : tone === 'body' ? t.color.statusFg : t.color.dim +} + export const TodoPanel = memo(function TodoPanel({ t, todos }: { t: Theme; todos: TodoItem[] }) { if (!todos.length) { return null @@ -23,19 +29,12 @@ export const TodoPanel = memo(function TodoPanel({ t, todos }: { t: Theme; todos {todos.map(todo => { - const done = todo.status === 'completed' - const cancel = todo.status === 'cancelled' - const active = todo.status === 'in_progress' + const tone = todoTone(todo.status) + const color = rowColor(t, todo.status) return ( - - - {todoGlyph(todo.status)}{' '} - + + {todoGlyph(todo.status)} {todo.content} ) diff --git a/ui-tui/src/lib/liveLayout.test.ts b/ui-tui/src/lib/liveLayout.test.ts new file mode 100644 index 0000000000..3d40f6f851 --- /dev/null +++ b/ui-tui/src/lib/liveLayout.test.ts @@ -0,0 +1,9 @@ +import { describe, expect, it } from 'vitest' + +import { liveTailOrder } from './liveLayout.js' + +describe('liveTailOrder', () => { + it('keeps todo before transcript and assistant live output', () => { + expect(liveTailOrder()).toEqual(['todo', 'history', 'assistant']) + }) +}) diff --git a/ui-tui/src/lib/liveLayout.ts b/ui-tui/src/lib/liveLayout.ts new file mode 100644 index 0000000000..1107edfce7 --- /dev/null +++ b/ui-tui/src/lib/liveLayout.ts @@ -0,0 +1 @@ +export const liveTailOrder = () => ['todo', 'history', 'assistant'] as const diff --git a/ui-tui/src/lib/todo.test.ts b/ui-tui/src/lib/todo.test.ts index 38d95c9e02..bf8befa2c6 100644 --- a/ui-tui/src/lib/todo.test.ts +++ b/ui-tui/src/lib/todo.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { todoGlyph } from './todo.js' +import { todoGlyph, todoTone } from './todo.js' describe('todoGlyph', () => { it('uses fixed-width ASCII markers so the active row does not render wide or emoji-like', () => { @@ -10,3 +10,12 @@ describe('todoGlyph', () => { expect(todoGlyph('cancelled')).toBe('[-]') }) }) + +describe('todoTone', () => { + it('keeps todo status rows neutral instead of red/green', () => { + expect(todoTone('completed')).toBe('dim') + expect(todoTone('cancelled')).toBe('dim') + expect(todoTone('pending')).toBe('body') + expect(todoTone('in_progress')).toBe('active') + }) +}) diff --git a/ui-tui/src/lib/todo.ts b/ui-tui/src/lib/todo.ts index b6dc48968c..1846d02fe6 100644 --- a/ui-tui/src/lib/todo.ts +++ b/ui-tui/src/lib/todo.ts @@ -1,4 +1,9 @@ import type { TodoItem } from '../types.js' +export type TodoTone = 'active' | 'body' | 'dim' + export const todoGlyph = (status: TodoItem['status']) => status === 'completed' ? '[x]' : status === 'cancelled' ? '[-]' : status === 'in_progress' ? '[>]' : '[ ]' + +export const todoTone = (status: TodoItem['status']): TodoTone => + status === 'in_progress' ? 'active' : status === 'pending' ? 'body' : 'dim'