zot/internal/agent
patriceckhart 6019404644 fix(tui): blinking cursor in /btw, proper idle redraws, tighter status bar
Three related tweaks to how the interactive mode drives its redraw
loop, the terminal cursor, and the status-bar layout.

1) Redraw-on-tick narrowed to things that actually animate.

   The render loop used to force a redraw every 120ms for every
   open dialog (model picker, jump, sessions, btw, etc). Most
   of those are static pickers \u2014 the repaint was wasted and had
   a visible side effect: the re-emitted hide-cursor / show-cursor
   pair at the start of each frame cancels the terminal's blink
   cycle for any dialog that hosts its own input field. Concretely
   the blinking cursor in /btw never blinked, it just sat as a
   steady reverse-video block.

   Tick-driven redraw is now only triggered when i.busy (main
   spinner animates) or btw.Loading() (side-chat spinner animates).
   Static dialogs rely on the dirty-channel invalidations that
   fire on key events, which is sufficient because nothing else
   on screen is moving.

2) btw side-chat redraws on completion.

   Consequence of (1): the btw goroutine that streams a model
   response used to depend on the 120ms tick to make the final
   answer visible. With the tick gone for idle dialogs, the
   answer landed in d.turns but the screen stayed blank until
   the user pressed a key.

   btwDialog.Open and submit now take an invalidate callback
   that the goroutine fires after completeTurn, including the
   early-error branch. While the request is in flight,
   btw.Loading() returns true so the tick keeps the spinner
   animating; once the answer lands, a single invalidate()
   redraws and the tick stops.

3) Cursor routed into btw while it's open.

   btwDialog already had a CursorPos(width) method that returns
   where the side-chat editor's caret sits within the dialog's
   rendered rows. The host never used it \u2014 the real terminal
   cursor stayed on the main editor below. Now when btw is
   active the host picks up CursorPos and points the terminal
   cursor there, so the blink shows in the correct input and
   the main editor has no cursor.

4) Status bar idle-path spacing.

   Idle row used to render as "<pad><pad>(provider) model" =
   4 spaces before the model, so the line started at column 4
   while busy and idle didn't match. Dropped one pad in the
   idle branch; both paths now start at column 2, aligned with
   the conversation column ('  you' / '  zot' message markers).

No semantic change to transcripts or provider calls. All tests
pass.
2026-04-21 18:09:10 +02:00
..
extensions feat(ext): phase 4 - full-event interception, arg rewrites, /reload-ext 2026-04-19 17:02:04 +02:00
modes fix(tui): blinking cursor in /btw, proper idle redraws, tighter status bar 2026-04-21 18:09:10 +02:00
tools feat(tui): context diffs + framed tool blocks + paced streaming 2026-04-20 15:50:39 +02:00
args.go fix(no-yolo): don't auto-refuse tool calls in non-interactive modes 2026-04-19 19:17:05 +02:00
botcmd.go fix ci on windows: split detach helper into posix/windows variants 2026-04-18 10:58:10 +02:00
botcmd_unix.go fix ci on windows: split detach helper into posix/windows variants 2026-04-18 10:58:10 +02:00
botcmd_windows.go fix ci on windows: split detach helper into posix/windows variants 2026-04-18 10:58:10 +02:00
build.go rename: /lock -> /jail, /unlock -> /unjail 2026-04-20 08:57:40 +02:00
changelog.go feat(tui): show github release notes once after upgrading 2026-04-19 16:12:13 +02:00
cli.go fix(session): export the full running conversation, handle quoted paths 2026-04-20 10:19:53 +02:00
config.go feat(tui): show github release notes once after upgrading 2026-04-19 16:12:13 +02:00
extcmd.go feat: extension system (subprocess + json-rpc, any language) 2026-04-19 14:09:43 +02:00
modelsync.go initial commit 2026-04-17 20:36:38 +02:00
rpc.go fix(no-yolo): don't auto-refuse tool calls in non-interactive modes 2026-04-19 19:17:05 +02:00
systemprompt.go feat(tui): context diffs + framed tool blocks + paced streaming 2026-04-20 15:50:39 +02:00
update.go fix(update): re-check every launch when the cache says up-to-date 2026-04-20 18:31:51 +02:00