| 2026-10-09 |

webclient: the message area in en, uk and ru
...
The fourth area of the interface translation. Everything a conversation is made
of now builds its text through t(): the thinking card and the status line it
replaces while the model reasons, the plan card, the tool cards (both the plain
one and its sub-agent steps), the published-content card, the UI-component card
and the compression notice, plus the two new chat bubbles' copy button and the
"Scheduled recall" mark on an injected user message.
25 new slugs in all three dictionaries:
- 23 in messages.* — the cards' own headers and labels (Thinking, Plan,
Arguments, Show all / Hide older tools, Useful / Not useful, Open file,
Content, Unknown UI component: {name}, Context summary, Compressing context…,
Context compressed), the running and elapsed labels (Running {tool}…,
Preparing next action…, running, starting) and the two counted ones that a
compact JSON preview renders, "{n} items" and "{n} keys";
- 2 in common.* — Copy and Copied!, which the assistant and the user message
both need.
Three details worth knowing:
- The English values are verbatim the literals the code hard-coded, with one
exception: "{n} tools" and "({before} → {after} messages)" are now dictionary
plurals, so English says "1 tool" and "1 message" where it used to say
"1 tools" and "1 messages". No test asserted either string.
- The braces around the two compact-JSON counts stay in the template
(`[${t('messages.jsonItems', { n })}]`), so a translator never has to keep a
bracket it cannot see the other half of.
- The message list's ContentCard shows the same published-file widget as the
artifacts drawer, so it reads the six artifacts.* slugs of that widget rather
than carrying six duplicates under messages.*; and its two tool-output labels
— Result and Live output — are the words the tool card already uses, so they
sit in common.* and the drawer's copies moved there too. docs/i18n.md records
both.
Checked live in Chromium against the built bundle on the dev backend: five
saved sessions chosen so that between them they render every component of the
area (thinking cards, plan cards, 55 tool cards, published-content cards,
UI-component cards and a compression notice), six loads per language, with
every collapsed block expanded first and a scan for a slug leaking into the
rendered text as the pass condition. The sub-agent step cannot be reached from
a saved session — the runtime does not persist tool steps — so SubagentStep was
rendered on its own in a throwaway mount instead: "выполняется", "Аргументы",
"Результат", "[3 элемента]".
Eugene Sukhodolskiy
committed
1 day ago
|

webclient: animate <details> cards in every browser, not just Chromium
...
Open/close of the tool cards jumped in Firefox and Safari: the previous
attempt leaned on interpolate-size/::details-content, and interpolate-size
shipped in Chromium alone, so the @supports block degraded to a hard
attribute flip everywhere else.
Drive the element's own height from JS instead. Nothing there is
engine-specific: open animates to scrollHeight, close to the summary
height, overflow is clipped for the duration and the inline styles come
off on transitionend with a timer as a backstop. The element keeps its
native semantics — keyboard, screen readers, find-in-page — because the
open attribute is still what changes; the toggle event still fires, so
ContentCard's :open/@toggle pairing is untouched. prefers-reduced-motion
settles in a single frame.
A newly inserted card grows its grid row from 0fr to 1fr, which
interpolates everywhere and resolves to whatever the card measures, so
the card below slides instead of being displaced.
Measured in Chromium 153 and Firefox 155 against the real component
markup and the built bundle: 33 -> 586px over 18 distinct heights in
both, and the same for insertion, the nested Arguments block and the
plan card. The scroll behaviour of MessageList was left alone.
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-09-26 |
e2e fixes: tasks tool in profiles, bg timeout lift, stepIcon fix, queue semantics docs
...
E2E findings addressed:
- tasks tool was registered but not in any profile's tools.agent.native —
added to all six profiles (agent could not check/wait/cancel bg tasks)
- detached terminal/code_exec/ssh_exec runs without explicit timeout are
lifted to 300s: foreground defaults (20/30/60s) marked long commands
'completed' with partial output while the process still ran
- ToolCard.vue: define stepIcon(status) — template referenced it but the
function was missing (render crash on task_update step)
- message_queued reachability documented: WS read loop is sequential, the
queue path is only reachable from a second socket/headless recall
Eugene Sukhodolskiy
committed
14 days ago
|
webclient: background task chip, id-first tool matching, queued badge
...
- toolIndex (tool_call_id → card): exact matching for parallel batches and
late events after stream_end; legacy name+pending fallback kept
- bare tool_call synthesizes a card so results are never lost
- task_update: backgroundTasks chip above composer + steps appended to the
spawning tool card (parent_tool_call_id binding)
- message_queued badge, terminal_opened dispatch
- new BackgroundTasksChip component, task_update step rendering in ToolCard
Eugene Sukhodolskiy
committed
14 days ago
|
| 2026-07-13 |
renderers: colour diff line numbers + read line numbers, keep content neutral
...
Standard for diff and read output: the line number (and the +/- marker for
diffs) is the coloured anchor; the content itself reads plainly.
diff: "{num} {marker} {content}" with num+marker in the marker colour
(green/red), content neutral. Fixed the number-column regex to "^( +)(\d+)|"
so files with more than 9 lines (width > 1) still match — the old
single-space pattern silently fell back to whole-line colouring.
read: "{num}: {content}" with the number in the accent colour, content
neutral (was dim number).
Applied to both clients: the TUI diff/filesystem renderers and the webclient
ToolCard (renderDiff / renderRead). The model-facing text from the server is
unchanged — this is display-only.
Eugene Sukhodolskiy
committed
on 13 Jul
|
| 2026-05-26 |
Add persistent multi-session terminal tool with background support
...
- New TerminalManager module: named subprocess sessions per Navi session,
background readers, event-sink streaming, idle auto-cleanup
- Refactor terminal tool to multi-action: run, open, close, list,
status, send_input
- Add TerminalOutputDelta and TerminalClosed events for streaming
- Wire TerminalManager into AppContainer, orchestrator, and registry
- Persist session_metadata in Session model and pg_session_store
- Close all session terminals on session delete
- Webclient: handle terminal_output/terminal_closed WS events,
display live terminal output in tool cards
- Update unit tests for new terminal actions
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 26 May
|
| 2026-05-14 |
Compact and improve tool/thinking/plan card UX
...
- ToolCard: remove emoji header, collapse Arguments behind <details>,
render results with structured JSON (color-coded values) or markdown
detection for string outputs.
- SubagentStep: mirror ToolCard compact layout with same helpers.
- AssistantMessage: fold tool lists when >3 tools — show last 3 + summary
bar with count and toggle icon-button; TransitionGroup for smooth
expand/collapse animations.
- Plan card: switch accent color from info to secondary, compact sizing.
- Thinking card: compact sizing, remove bottom margin.
- app.scss: add details::details-content animation, fix nested chevron
rotation in subagent steps, adjust margins and input-bar padding.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 14 May
|
| 2026-04-30 |
Reduce spawn agent running indicators
Eugene Sukhodolskiy
committed
on 30 Apr
|
Improve content publishing UX
Eugene Sukhodolskiy
committed
on 30 Apr
|
| 2026-04-17 |

Route subagent planning events into spawn_agent card in the UI
...
Previously PlanningStatus/PlanReady had no is_subagent flag, so subagent
planning spinners and plan cards rendered as top-level Navi planning UI.
Backend:
- Add is_subagent field to PlanningStatus and PlanReady events
- _run_planning accepts is_subagent param, passes it through all yields
- run_ephemeral calls _run_planning with is_subagent=True
- websocket.py forwards is_subagent in planning_status and plan_ready messages
Frontend (chat.js):
- onPlanningStatus: if is_subagent, set planningLabel on the last spawn_agent
card instead of msg.statusLabel
- onPlanReady: if is_subagent, push plan into spawn card steps and clear
planningLabel; otherwise behave as before
Frontend (ToolCard.vue):
- Render subagent-planning-indicator (spinner + label) when planningLabel set
- Render plan cards inside subagent steps using the same plan-card pattern
Also includes leftover session changes: spawn_agent default 40 in description
and manual, updated manual content.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 17 Apr
|
| 2026-04-16 |
Migrate to Vue webclient; rename old client to old_webclient
...
- client/ → old_webclient/ (vanilla JS client preserved as reference)
- webclient/ — new Vue 3 + Pinia webclient (source + dist build)
- vite.config.js: outDir changed to webclient/dist/
- main.py: serve /assets and /images from webclient/dist/,
index.html from webclient/dist/index.html
- .gitignore: exclude webclient/node_modules/, include webclient/dist/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 16 Apr
|