Skip to content

Polish native main thread and session UI - #70

Merged
oldsj merged 7 commits into
mainfrom
native-main-thread-ui
Sep 21, 2026
Merged

oldsj merged 7 commits into
mainfrom
native-main-thread-ui

Conversation

@oldsj

@oldsj oldsj commented Sep 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Keep the main-thread composer visible, simplify its header, label child reports correctly, and render message text as safe markdown.
  • Show rejected sends and backend outages clearly, preserve drafts on send failure, and restore data when the connection returns.
  • Make sessions easier to reach and manage on mobile and desktop; add cancel and clear behavior with durable final status and archived history.
  • Add a per-worktree dev UI script and update the affected behavior specs.

Verification

  • Backend runtime suite: 119 tests passed (uv run -m unittest discover -s tests/runtime -p 'test_*.py').
  • Svelte check: 0 errors, 0 warnings.
  • Frontend production build: passed.
  • make lint: passed on 48 changed files.

Limits

  • Cancel/clear behavior has unit coverage with fakes; it has not been exercised against a live cluster.
  • Browser E2E tests were not run because their global setup resets the target database.

Main thread view
- Pin the input bar: the chat is the only scrolling region, and it follows
  the latest message.
- Drop the inline session list and thread replies from the native view;
  child sessions stay in the side panel.
- Compact header (state, model, pending) with a details toggle.
- Show a rejected send (409) inline, keep the text, and disable input while
  the thread is working or rotating.
- Label child reports, hide the pre-cut protocol turn, and render message
  text as safe markdown (raw HTML shown as text).
- Backend: /main-thread and conversation polling no longer queue behind a
  rotation.

Connection handling
- Add a connection store (/health probe plus request failures) and a banner
  when the backend is unreachable; disable input and mark the header stale.
- Retry the initial load and reload sessions, inbox and notifications when
  the backend returns.
- Show a real error in the session panel instead of "No sessions yet".
- Keep a message that the backend accepted if the reply poll later fails,
  so it isn't sent twice.

Dev
- Proxy /api through Vite (VITE_API_URL=/api, MAINLOOP_API_PROXY) so a
  remote dev box needs one forwarded port.
…e Logs tab

Session page
- Reload when only [id] changes; the page loaded once on mount, so
  clicking another session updated the URL but not the view
- Keep status live from the sessions store; show "can't reach the
  backend" (and retry on recovery) instead of "Session not found"
- Fix the "WAITING ON_USER" label; share status labels with the list
- Collapse the identity strip to one summary line with a details toggle
- Remove the Logs tab and its dead code: LogViewer, createTaskLogClient
  and the stub GET /sessions/{id}/logs endpoint

Mobile and layout
- Add the Sessions tab to the mobile tab bar (docs/specs/layout.md
  already called for it)
- Size the desktop inbox and projects panels to their content
- Highlight the open session in the list

Chat
- Wrap long unbroken text and scroll wide tables inside bubbles
- Show the date on messages that are not from today
- Input: refocus after a send, ignore Enter during IME composition,
  grow for multi-line text
- SessionChat: inline, self-clearing errors; restore the draft when a
  send fails; disable input while the backend is unreachable

Other
- Project page read `tasks`, which the API does not return, and crashed
  on load; list the project's sessions instead and reload on id change
- Use theme colors on the error page
- Update docs/specs/layout.md and sessions.md; update the two specs
  that asserted on the Logs tab

Not run: the Playwright fast/mobile projects, because their global
setup resets the target database.
Cancelled sessions came back as "needs input": cancel set status failed,
and the agent sync recomputed status every few seconds and overwrote it.
Cancel also never stopped the agent.

Status
- cancelled is its own final status; cancelled and failed ignore later
  agent activity (next_status)
- cancel stops the agent through Herdr and closes open deliveries; an
  unconfirmed stop is reported, not retried
- a child that has reported is completed (report becomes its summary);
  messaging it reopens it until the reply
- a cancelled or failed session refuses new messages (409)
- startup data fixes (idempotent): old "Cancelled by user" rows become
  cancelled; already-reported children become completed

Clearing
- sessions.archived_at; finished sessions (completed, failed,
  cancelled) can be cleared from the list, kept for audit. Never the main
  thread; a live session must be cancelled first
- POST /sessions/{id}/archive and /sessions/archive-finished
- session view: Clear on finished sessions, cancel/clear errors shown;
  list header: "clear N"
- main thread: `mainloop cancel <id>` and `mainloop clear [<id>]`
  (agent API + CLI + standing prompt), main role only, own children only

Needs a rebuilt workspace image for the CLI verbs; the backend needs a
rollout for everything else.

Tests: unit tests with fakes for the status rules and the cleanup verbs
(runtime suite: 119 pass). Not run against a live cluster.
- dev-ui.sh runs a worktree's Vite against the shared Kind backend:
  per-worktree port, one shared backend port-forward, explicit
  kubeconfig and context, up/status/logs/down [--all]
- AGENTS.md: document it; remove the Playwright commands and paragraph
…ents

- New-agent page: show the backend's reason when a start is refused,
  Ctrl+Enter to start, disable Start while the backend is unreachable,
  placeholder for the default title
- Apply the saved theme before first paint (no flash of the default)
- Theme button exposes aria-expanded
- Delete unused ProjectFilter and SessionExpandedView
@oldsj
oldsj merged commit 653389e into main Sep 21, 2026
5 of 6 checks passed
@oldsj
oldsj deleted the native-main-thread-ui branch September 21, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant