This commit is contained in:
seb
2026-09-26 19:19:48 +02:00
parent 5b1d896157
commit 0149846a15
10 changed files with 822 additions and 29 deletions

View File

@@ -4,6 +4,7 @@ import assert from 'node:assert/strict';
import chalk from 'chalk';
import { createStore } from './src/ui/store.js';
import { App } from './src/ui/app.js';
import { TURN_STATES } from './src/turn-state.js';
// --- fixture: exercises header, history, command bar, token footer ---
function buildMainStore() {
@@ -74,10 +75,34 @@ assert.ok(outTiny.includes('in=1,234'), 'tiny fallback still shows totals');
assert.ok(!outTiny.includes('PgUp/PgDn history'), 'tiny fallback drops fullscreen key hints');
tiny.resolve(null);
// --- 4. live reasoning streams into the scrollable history pane ---
// --- 4. the status line renders the label for every non-idle state ---
// The status line is driven by the connection-state enum, so the smoke test
// walks the store through each busy state and checks the matching label. The
// previous fixture hardcoded the free-text 'thinking…'.
for (const [state, label] of [
[TURN_STATES.CONNECTING, 'connecting…'],
[TURN_STATES.THINKING, 'thinking…'],
[TURN_STATES.WORKING, 'working…'],
[TURN_STATES.STREAMING, 'streaming…'],
]) {
const s = createStore();
s.setBusy(true);
s.setTurnState(state);
const rendered = strip(renderToString(h(App, { store: s, sizeOverride: { columns: 80, rows: 24 } }), { columns: 80 }));
assert.ok(rendered.includes(label), `${state} renders as ${label}`);
assert.ok(!rendered.includes('› (idle)'), `${state} is not shown as idle`);
}
// The idle placeholder is the only thing shown when no turn is running.
const idleStore = createStore();
idleStore.setBusy(false);
const outIdle = strip(renderToString(h(App, { store: idleStore, sizeOverride: { columns: 80, rows: 24 } }), { columns: 80 }));
assert.ok(outIdle.includes('› (idle)'), 'idle placeholder renders when not busy');
// --- 5. live reasoning streams into the scrollable history pane ---
const reasoningStore = createStore();
reasoningStore.setBusy(true);
reasoningStore.setStatus('thinking…');
reasoningStore.setTurnState(TURN_STATES.THINKING);
reasoningStore.setReasoningDraft('Analyzing user question\nChecking relevant files');
const outLiveReasoning = strip(renderToString(h(App, { store: reasoningStore, sizeOverride: { columns: 80, rows: 24 } }), { columns: 80 }));
@@ -92,4 +117,4 @@ assert.ok(outFinalReasoning.includes('🧠 Reasoning'), 'finalized reasoning has
assert.ok(!outFinalReasoning.includes('🧠 Reasoning (thinking…)'), 'finalized reasoning drops thinking indicator from header');
assert.ok(outFinalReasoning.includes('Analyzing user question'), 'finalized reasoning preserves content');
console.log('\nSMOKE-OK: header/history/command-bar/footer + scroll + tiny fallback + streaming reasoning');
console.log('\nSMOKE-OK: header/history/command-bar/footer + scroll + tiny fallback + connection states + streaming reasoning');