diff --git a/ui-tui/src/__tests__/text.test.ts b/ui-tui/src/__tests__/text.test.ts index e96cbac3dd..1d61b71b1f 100644 --- a/ui-tui/src/__tests__/text.test.ts +++ b/ui-tui/src/__tests__/text.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { sameToolTrailGroup } from '../lib/text.js' +import { fmtK, sameToolTrailGroup } from '../lib/text.js' describe('sameToolTrailGroup', () => { it('matches bare check lines', () => { @@ -18,3 +18,19 @@ describe('sameToolTrailGroup', () => { expect(sameToolTrailGroup('🔍 searching', '🔍 searching extra ✓')).toBe(false) }) }) + +describe('fmtK', () => { + it('keeps small numbers plain', () => { + expect(fmtK(999)).toBe('999') + }) + + it('formats thousands as K', () => { + expect(fmtK(1000)).toBe('1K') + expect(fmtK(1500)).toBe('1.5K') + }) + + it('formats millions and billions', () => { + expect(fmtK(1_000_000)).toBe('1M') + expect(fmtK(1_000_000_000)).toBe('1B') + }) +}) diff --git a/ui-tui/src/app.tsx b/ui-tui/src/app.tsx index d17d0c0fbc..5a66dce58b 100644 --- a/ui-tui/src/app.tsx +++ b/ui-tui/src/app.tsx @@ -3,7 +3,7 @@ import { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Box, Static, Text, useApp, useInput, useStdout } from 'ink' +import { Box, Text, useApp, useInput, useStdout } from 'ink' import { useCallback, useEffect, useRef, useState } from 'react' import { ActivityLane } from './components/activityLane.js' @@ -250,7 +250,6 @@ export function App({ gw }: { gw: GatewayClient }) { const [sid, setSid] = useState(null) const [theme, setTheme] = useState(DEFAULT_THEME) const [info, setInfo] = useState(null) - const [introCollapsed, setIntroCollapsed] = useState(false) const [thinking, setThinking] = useState(false) const [turnKey, setTurnKey] = useState(0) const [activity, setActivity] = useState([]) @@ -385,7 +384,6 @@ export function App({ gw }: { gw: GatewayClient }) { setPastes([]) setActivity([]) setBgTasks(new Set()) - setIntroCollapsed(false) setUsage(ZERO) lastStatusNoteRef.current = '' protocolWarnedRef.current = false @@ -545,7 +543,6 @@ export function App({ gw }: { gw: GatewayClient }) { inflightPasteIdsRef.current = payload.usedIds setLastUserMsg(text) - setIntroCollapsed(true) appendMessage({ role: 'user', text }) setBusy(true) setStatus('running…') @@ -1683,28 +1680,18 @@ export function App({ gw }: { gw: GatewayClient }) { return ( - - {(m, i) => ( - - {m.kind === 'intro' && m.info ? ( - - {introCollapsed ? ( - - {theme.brand.icon} {theme.brand.name} · {m.info.model.split('/').pop()} - - ) : ( - <> - - - - )} - - ) : ( - - )} - - )} - + {historyItems.map((m, i) => ( + + {m.kind === 'intro' && m.info ? ( + + + + + ) : ( + + )} + + ))} {streaming && ( diff --git a/ui-tui/src/lib/text.ts b/ui-tui/src/lib/text.ts index ac2efb2cb7..264d741fde 100644 --- a/ui-tui/src/lib/text.ts +++ b/ui-tui/src/lib/text.ts @@ -80,7 +80,12 @@ export const estimateRows = (text: string, w: number, compact = false) => { export const flat = (r: Record) => Object.values(r).flat() -export const fmtK = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}k` : `${n}`) +const COMPACT_NUMBER = new Intl.NumberFormat('en-US', { + maximumFractionDigits: 1, + notation: 'compact' +}) + +export const fmtK = (n: number) => COMPACT_NUMBER.format(n) export const hasInterpolation = (s: string) => { INTERPOLATION_RE.lastIndex = 0