Commit Graph

4 Commits

Author SHA1 Message Date
DaiChaoXiong ea22f3d9ea fix(tui): restore real-time transcript growth lost in the tool-merge refactor
The on_agent_event handler (committing messages at MessageEnd and clearing
the live partial) was accidentally dropped during the merged-tool-block
refactor, so only the current turn's partial was visible: thinking1 vanished
when thinking2 streamed, and everything appeared only at Done.

- restore on_agent_event: MessageEnd(assistant/toolResult) commits into the
  transcript in real time; commit_partial clears the streamed partial
- tool-block state machine: committed call + result → done; committed call +
  running exec → running with live streamed output; otherwise → pending
  (a committed call no longer shows a bogus ✓ before its result arrives)
- live section skips running execs already rendered via committed blocks

regressions: transcript_grows_in_real_time (app-level),
committed_tool_with_running_exec_shows_live_output (state-level).
2026-08-09 23:05:06 +08:00
DaiChaoXiong 7d289580b5 fix(tui): merged tool request+result blocks; fix wheel-down bottom jump
1. wheel-down jumped to the bottom because max_scroll() derived the limit from
   geometry, which only covers expandable blocks — a text-only conversation
   left it at 0, so one down-notch clamped scroll to 0 with follow=true and
   the next draw snapped to the real bottom. The limit now uses
   content_lines (the full rendered line count, stored per draw).

2. tool request and result are now one block ('requested where it returns'):
   UiBlock::ToolCall/ToolResult/ToolExec are unified into UiBlock::Tool, built
   by merging each assistant tool call with its matching tool_result message
   (looked up by call_id). Collapsed shows the concrete summary + duration +
   status; expanded shows human-readable args, then '── 结果 ──', then the
   output (two-level: partial preview with remaining-line hint, then full).
   Live running executions reuse the same block. ToolResult messages are no
   longer rendered standalone.

tests updated for the merged model; wheel test now drives content_lines.
2026-08-09 22:43:01 +08:00
DaiChaoXiong acddf7be1b fix(tui): correct wheel/PageUp scroll direction and line-step
The scroll offset semantics were inverted for the wheel and PageUp:
is the content offset (larger = newer), so scrolling up must DECREASE it, but
ScrollUp and PageUp both INCREASED it — every wheel event (either direction)
moved toward the bottom, and at the bottom (follow=true) an up-notch added 3
then got clamped back to max, making the wheel dead until keyboard-scrolling
away. Now:

- wheel ScrollUp/ScrollLeft: offset -1, follow cleared (works from the bottom)
- wheel ScrollDown/ScrollRight: offset +1, follow restored at the bottom
- PageUp: offset - view_height; PageDown: offset + view_height
- one line per wheel notch (was 3) for line-by-line scrolling

regression test drives handle_mouse with synthetic events (direction,
line-step, no underflow, follow transitions).
2026-08-09 22:34:51 +08:00
DaiChaoXiong 676dc1503e feat(tui): add focus-tui terminal UI
- ratatui + crossterm chat UI: streaming assistant text, multi-line input,
  bottom status bar (model / protocol / session id / context usage)
- thinking blocks collapse to a summary with duration + estimated tokens;
  tool calls collapse to a concrete summary (path / command) + duration;
  click or Tab expands the details
- config modal (/config): provider, OpenAI protocol, baseUrl, apiKey, model,
  contextWindow — persisted to ~/.focus/config.json; session list (/sessions)
  on the harness JSONL tree; /new, /compact, /help
- auto-compaction (80% threshold, no confirmation) + dynamic system prompt
  with usage info run in a background job (fake-provider-testable)
- Esc aborts a run (abandons the job thread; bounded by the provider timeout)
- tests: config codec, summaries/durations/wrap/caret, UI state machine with
  an injected clock, job flow with a fake provider, session persistence
2026-08-09 21:35:58 +08:00