| 2026-07-09 |

Navi Code TUI: sub-agent spawn card + nested styling for subagent thinking/planning
...
Sub-agent activity was either rendered as a generic tool card (spawn_agent) or
dropped to raw debug output (turn_thinking was unhandled in the TUI chat model
and the raw CLI). The webclient nests subagent events inside the spawn_agent
card; the TUI is flat, so nesting is conveyed with a distinct spawn card plus
left-indented, dimmed subagent cards.
New renderers/subagent.py:
- SpawnAgentStartedRenderer: "↘ subagent · <profile_id>" card showing the task
(+ briefing dimmed), secondary border. Registered before ToolStartedRenderer.
- SpawnAgentResultRenderer: "↙ subagent · <profile_id> ✓/✗" card with the
result, success/error border. Registered before ToolResultRenderer.
Nested subagent styling (left indent via Padding + dim):
- ThinkingRenderer: is_subagent → "subagent thinking" title, dim border, indented.
- PlanningStatusRenderer / PlanReadyRenderer: is_subagent → indented (label/title
already mark it as subagent).
- ToolStartedRenderer / ToolResultRenderer: is_subagent → indented so inner
tool calls read as nested inside the spawn card.
chat_model handles turn_thinking → thinking_block item with is_subagent meta;
chat_panel._refresh forwards is_subagent to the thinking renderer. Raw CLI
render.py prints turn_thinking as a [thinking] block (with "(subagent)" prefix).
Tests: spawn card shows profile/task and status; subagent thinking/planning/tool
cards are indented and labeled; non-subagent tool card is not indented;
turn_thinking creates a subagent thinking_block. 593 passed, 1 skipped.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|

Navi Code: render planning as a progress line + plan card, not raw events
...
planning_status and plan_ready events were unhandled in the TUI chat model and
the raw CLI renderer, so they fell through to raw debug output (TUI:
"plan_ready: {...}" status lines; raw CLI: "[event: plan_ready] {msg}").
TUI:
- New renderers/planning.py: PlanningStatusRenderer renders a "⚙ Planning ·
<label>" line (info color; dim + "(subagent)" prefix for subagent planning);
PlanReadyRenderer renders the plan as a Panel wrapping themed Markdown, titled
"Plan" with an accent border ("subagent plan" + dim border for subagents).
- Registered both in default_registry().
- chat_model handles the events: non-subagent planning_status rolls in place
(Analysis → Execution plan → Plan review share one line instead of stacking);
plan_ready consumes the pending planning line and appends the plan card;
subagent planning is appended as its own dim line/card so it does not bleed
into the parent turn's indicator (matching the webclient).
- chat_panel._refresh maps the new kinds to the registry.
Raw CLI (render.py): planning_status prints "[planning] <label>"; plan_ready
prints a "[plan] … [/plan]" block with the plan text.
Tests: renderer accepts/render (label, subagent prefix, plan title/content);
chat_model rolling-in-place, plan_ready consumes indicator, subagent separation.
584 passed, 1 skipped.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|

Navi Code TUI: show final answer below tools, not scrolled out of view
...
The assistant answer bubble was created at stream_start (the first event of a
turn), placing it at the TOP of the turn — above the thinking blocks and tool
cards that follow. chat_panel._refresh() calls scroll_end, so the view pinned to
the bottom (tools/thinking) and the answer at the top scrolled out of view.
Users saw tool results, planning, and thinking, but not the final answer.
Fix in chat_model.handle_ws_event (client-only, no protocol/server change):
- stream_start no longer eagerly adds an empty assistant bubble; it resets the
current-assistant pointer so the first stream_delta opens the bubble lazily
at the position where text actually arrives.
- tool_started/tool_call reset the current-assistant pointer so the next
stream_delta opens a fresh bubble BELOW the tool cards — the final answer
lands at the bottom, visible after scroll_end.
- stream_end purges empty assistant/thinking bubbles and resets pointers.
Tests: stream_start creates no empty bubble; final assistant_message renders
after the last tool_call with no empty bubbles; empty bubbles purged on
stream_end. 574 passed, 1 skipped.
Co-Authored-By: Claude <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
2 days 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-23 |
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
|