| 2026-07-11 |

Navi Code TUI: show request duration (live timer + chat metadata)
...
Live elapsed timer next to the activity indicator (ticks once per second
during a turn, format 2m 16s), driven by the same stream_start/stream_end
hooks as the activity indicator — so it spans the whole turn (all LLM calls,
tool calls, planning, sub-agent steps). On stream_end it syncs to the
backend's authoritative elapsed_seconds before freezing; on stream_stopped/
error/disconnect it freezes at the locally-measured value.
On stream_end the model also appends a turn_meta ChatItem rendered as a dim
"⏱ 2m 16s" line below the answer — the total time the agent spent on the
user's request. The value comes from stream_end.elapsed_seconds, already
measured by the backend over the whole turn, so the TUI needs no timer for
accuracy. stream_stopped/error do not get a metadata line (only completed
requests).
Shared format_duration(): None -> "—", <60s -> "16s", <3600 -> "2m 16s",
>=3600 -> "1h 2m".
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
12 hours ago
|
Navi Code TUI: context-window fill gauge in the status bar
...
Add a ContextFill widget to the bottom StatusBar showing how full the LLM
context window is (absolute tokens + percent), colored by fill level:
dim < 70%, warning 70-89%, error >= 90%. Updates from stream_end and
compression_started/context_compressed events; seeded from get_session on
resume so the gauge isn't blank pre-turn. None from the backend keeps the
last known value.
Fix: name the widget attribute _ctx_fill, not _context — _context shadows
MessagePump._context (the internal context manager Textual wraps around
message processing) and hangs the app's message pump at mount time.
Polish: drop the "ctx " prefix (shows 12.0k/32.0k · 38%) and add a 1-char
margin between the activity indicator and the gauge.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
tui: load session message history into the chat panel on resume
...
Resuming or switching a session showed a blank chat — the past conversation
was never replayed. GET /sessions/{id} already returns the messages; the TUI
just ignored them.
- ChatModel.load_history maps persisted Message dicts back to the same
ChatItems the live stream produces (user/assistant text, thinking, tool
started/result, plan), skipping is_display=False (context-only user,
summaries, compression events) so only what the user would have seen
live is rebuilt.
- ChatPanel.load_history wraps it (clears the render cache + refresh).
- attach_session loads the messages from get_session, so resume/switch
replays the history before the cwd/Connected banners.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
14 hours ago
|

tui: activity indicator in a bottom status bar + 1-line input
...
Add an animated "agent is working" indicator so a silent gap (long-running
tool, the pause before the first token, sub-agent reasoning) reads as
"alive" rather than "hung": a braille spinner + phase label that runs on
its own timer, independent of the WebSocket event flow.
- New ActivityIndicator widget (rotating spinner + phase label, colored
status_online), started/stopped from tui_app WS phase transitions
(thinking / responding / planning / running <tool>) and stopped on
stream_end/stopped/error and on connection drop.
- New StatusBar bottom line replaces Textual's Footer: indicator on the
left, dim key-combo summary on the right. One line instead of the menu;
the key bindings themselves stay on the App so the keys still work.
- Input box: TextArea min-height 3 -> 1, so the prompt is one line by
default (auto-resize + max-height 12 unchanged).
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
14 hours ago
|

tui: add --resume <session_id> and print resume hint on TUI close
...
Closing Navi Code now tells the user the session id and the exact command to
continue it, so a session is one re-run away instead of lost to state lookup.
- cli.py: add --resume <session_id> (mutex with --new-session). Raw and TUI
paths resolve the given id via api.get_session; a bad id is a hard error,
not a silent new session. After app.run() returns and the terminal is
restored, print "Session <id>" / "Resume with: navi-code --resume <id>"
when a session is attached.
- tui_app._resolve_session: make the explicit-id branch strict — a failed
get_session surfaces an error event and returns None instead of falling
through to creating a new session (a --resume typo used to silently start
a fresh session). Saved-state resume stays lenient.
- tests: resume-flag resolve/bad-id/mutex + hint format; tui strict-on-bad
explicit id and explicit-id resume.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 hours ago
|
| 2026-07-10 |

tui: show the currently-served model in the status panel
...
The status panel's Model line was fed the global ollama_default_model, not the
session/profile model, and the server never told the client which model
actually served a call. Now:
- Backends stamp the resolved model onto LLMChunk (first chunk) / LLMResponse.
The fallback backend reports the model that survived its server+model
priority list (may differ from the profile's first choice).
- New ModelInfo event ({"type":"model_info","model":...}) emitted once per
turn from agent._consume_stream, re-emitted only when the model changes
across iterations. Additive WS event — old clients ignore it.
- TUI: attach_session/switch fetch the profile's configured model (first of
profile.model) via api.get_profile_model so the panel shows a value before
the first request; model_info then refines it to the actually-served model.
Not forwarded to the chat panel. raw CLI prints "[model] ...".
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-06-26 |
Navi Code: stop via Esc + project cwd propagation
...
- TUI: Esc stops active stream cooperatively via POST /sessions/{id}/stop
- TUI: render stream_stopped as status message
- CLI/WebSocket: send shell cwd in client->server message field
- Orchestrator stores cwd in session.session_metadata
- ContextBuilder injects [Working directory] into LLM context
- Agent sets current_working_directory ContextVar per turn
- tools/base: ToolContext gains cwd field
- filesystem/terminal/code_exec resolve relative paths against session cwd
- Add bin/navi-code wrapper for PATH symlink; document in README.md
- Update docs/websocket.md and tests
Full pytest: 544 passed, 1 skipped.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 days ago
|
Navi Code TUI: fix input box layout, command palette duplicate IDs, status renderer, and WS input loop
...
- clients/terminal/tui/widgets/input_box.py: switch Horizontal to Vertical with width: 100% for Input so it renders and accepts input in real terminals; add refresh on Input.Changed.
- clients/terminal/tui/screens/command_palette.py: remove fixed ListItem IDs to avoid DuplicateIds on fast filter.
- clients/terminal/tui/chat_model.py + renderers/status.py + widgets/chat_panel.py: render backend status events as dim system messages instead of raw dicts.
- clients/terminal/tui/ws_bridge.py: start NaviWebSocketClient.input_loop so enqueued user messages are actually sent to the backend.
- clients/terminal/tui/tui_app.py: focus InputBox synchronously in on_mount so typing works immediately.
- tests/clients/test_tui_app.py: regression test for visible input text.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
15 days ago
|
| 2026-06-24 |
Navi Code TUI: review fixes for Phase 5
...
- Fix raw CLI session API fields (session_id/name/preview)
- Add --mouse/--no-mouse flags and persistent TUI settings coercion
- Make attach_session/apply_theme public, add ChatPanel.clear()
- Deduplicate session selection handlers and editor error handling
- Update docs and tests
Eugene Sukhodolskiy
committed
17 days ago
|
Navi Code TUI: Phase 5.2 — SessionsPanel, /export, integration tests
...
- Add right-side SessionsPanel widget (DataTable) listing server sessions.
- Wire SessionsPanel into TUI layout and session selection flow.
- Add SessionSelected / SessionListUpdated events and refresh logic.
- Implement /export slash command: markdown rendering + $EDITOR.
- Update /new, /sessions, /switch, /profile to use session_id/name/preview.
- Add integration tests for SessionsPanel and /export; update layout test.
- Update docs/navi_code_cli.md with new panel and command.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
17 days ago
|
| 2026-06-23 |
Navi Code TUI: Phase 5.1 — config, mouse, themes, status
...
- Add TuiSettings persisted in ~/.navi_code/tui.json (theme, mouse, scroll_speed, diff_style, keybinds).
- TUI applies saved theme/mouse on startup; CLI gets --theme override.
- Add /themes picker with live preview and /mouse toggle command.
- Extend StatusPanel with backend URL, current theme, tokens/iter placeholders.
- Fix TuiContext.app() to use Textual active_app ContextVar.
- Add unit tests for settings, themes, and status panel.
513 passed, 1 skipped. Ruff clean.
Signed-off-by: Eugene Sukhodolskiy <eugene.sukhodolskiy@gmail.com>
Eugene Sukhodolskiy
committed
17 days ago
|
Navi Code TUI: fix Phase 4 review critical/medium issues
...
- PermissionEngine: always-deny returns None via check(); is_always_deny() exposed for explicit rejection; default rules for code_exec/ssh_exec/shell; extract_target() made public.
- ShellRunner: set ShellResult.truncated when output is actually truncated.
- File refs: restrict paths to base_dir/home, block sensitive files/dirs, skip binary, support glob brackets, shared guess_language.
- Permission dialog: deny now renders synthetic tool_call before stopping; shell ! commands require permission with always-allow/deny persistence.
- Tests: add permission tests, fix file_refs/shell tests, add __init__.py to fix pytest name collisions, update websocket integration for AgentSessionOrchestrator.
504 passed, 1 skipped. Ruff clean.
Signed-off-by: Eugene Sukhodolskiy <eugene.sukhodolskiy@gmail.com>
Eugene Sukhodolskiy
committed
17 days ago
|
Navi Code TUI: complete Phase 4
...
- @ file references with glob/dir support and size limits
- ! shell commands with timeout and output truncation
- inline permission dialog for destructive tool calls
- diff and artifact renderers with theme-aware highlighting
Tests: 40 client tests passing
Eugene Sukhodolskiy
committed
18 days ago
|
Navi Code TUI: command palette and themed markdown
...
- Add CommandPaletteScreen modal with fuzzy filtering and keyboard navigation.
- Bind Ctrl+P to push the palette; selected commands execute via registry.
- Make MarkdownRenderer theme-aware: headings, inline code, links, and code blocks use gnexus palette.
- Pick dracula/github-light code theme based on active theme brightness.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
18 days ago
|
Navi Code TUI: apply gnexus theme to widgets and renderers
...
- Register Navi themes as Textual themes so $tui-* CSS variables resolve.
- Update ChatPanel, StatusPanel, InputBox to use palette colors.
- Update all content renderers to draw from the active theme.
- Add set_active_theme/get_active_theme helpers for runtime color access.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
18 days ago
|
Navi Code TUI: add gnexus-ui-kit color theme support
...
- Extract exact gnexus-ui-kit cyberpunk palette from
webclient/vendor/gnexus-ui-kit/src/scss/_palette-colors.scss.
- Add clients/terminal/tui/themes.py with Theme dataclass, ThemeRegistry,
and gnexus-dark / gnexus-light themes.
- Wire theme into NaviCodeTui via _apply_theme() on mount; default is
gnexus-dark.
Tests: 463 passed, 1 skipped (excluded unrelated websocket test).
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
18 days ago
|
Navi Code: Phase 3 — Textual TUI skeleton (OpenCode-style)
...
- Add clients/terminal/tui package with micro-architecture:
- events, context, chat_model, ws_bridge, permissions engine.
- widgets: ChatPanel, StatusPanel, InputBox.
- renderers: user/assistant messages, thinking, tool calls, errors,
markdown, plain — registry-based and extensible.
- slash commands: /help, /new, /sessions, /switch, /profile, /thinking,
/compact, /quit — registry-based and extensible.
- Wire navi-code to launch TUI by default; keep click-CLI via --raw.
- Add textual>=0.70 dependency.
- Add TUI smoke tests via Textual Pilot.
- Add docs/plan_navi_code_tui.md with full Phase 4/5 roadmap.
Tests: 463 passed, 1 skipped (excluded unrelated websocket test).
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
18 days ago
|