Skip to content

fix(app): UI papercut sweep — non-blocking session flows, delete confirmation, resilient sidebar - #12

Draft
usehoplite[bot] wants to merge 5 commits into
mainfrom
hoplite/priene-6c72ebc6
Draft

fix(app): UI papercut sweep — non-blocking session flows, delete confirmation, resilient sidebar#12
usehoplite[bot] wants to merge 5 commits into
mainfrom
hoplite/priene-6c72ebc6

Conversation

@usehoplite

@usehoplite usehoplite Bot commented Sep 3, 2026

Copy link
Copy Markdown

What

An audit of the main user flows (startup, first run, create/navigate sessions, send & stream, sidebar Today/Earlier, settings, rename/delete) found five high-impact papercuts, all fixed in one OpenSpec change (openspec/changes/ui-papercut-sweep):

  1. UI freezes on session flows. The sidebar "New session" row, the palette "New session" command, and session activation all ran synchronous HTTP on the UI thread (create_session() + the blocking refresh(), which can spawn/rebuild and health-poll the daemon for seconds). All three surfaces now share the async path: activation clears the transcript, shows a localized Loading… state, and the daemon round trip happens on a background executor via schedule_refresh. The blocking refresh() method is deleted so no call site can regress.
  2. Activation failures were swallowed. list_messages().unwrap_or_default() silently rendered an empty chat when the load failed; failures now surface through the existing error banner.
  3. Deleting a session had no confirmation although the catalog already shipped session.delete_confirm. Delete is now staged behind a confirm overlay (cancel / Escape / outside click leaves the session untouched; confirm keeps the existing optimistic removal + background daemon delete).
  4. Any transient error hid the whole session list. The sidebar error now renders as a banner above the Today/Earlier sections instead of replacing them.
  5. One hardcoded UI string (empty project rename) moved into the locale catalog (settings.projects.rename_empty), plus a new messages.loading key for the transcript loading state.

Changes by file

  • crates/circulo-app/src/shell.rs — async activation + loading state, sidebar/palette new-session delegation, refresh()schedule_refresh migration, error-banner-above-list, localized rename rejection, staged delete (request/confirm/cancel), unit tests
  • crates/circulo-app/src/session_overlay.rsSessionOverlay::DeleteConfirm overlay
  • crates/circulo-i18n/ — two new keys + catalog test
  • openspec/changes/ui-papercut-sweep/ — proposal, design, delta specs, tasks
  • .hoplite/settings.json — sandbox setup script (Rust toolchain + X11 link libs for Linux test linking)

Verification

  • cargo test --workspace — green (app: 55 tests incl. 2 new ones for activation loading state and delete confirmation; i18n: 4; daemon: 26; persist/core/protocol/adapters all pass)
  • scripts/check-crate-boundaries.py — passes
  • New app unit tests cover the state transitions: activation_loads_transcript_in_background, delete_is_staged_behind_confirmation
  • Not verified here: the macOS manual pass from docs/FLOWS.md (daemon-down banner + list, cold-daemon session switching, delete confirm dialog) — this is a macOS-only GPUI app and the sandbox is Linux; the manual pass is pending on a Mac (OpenSpec change task 7.2).

Open in Hoplite

usehoplite Bot and others added 5 commits September 3, 2026 01:50
Sidebar/palette new-session call sites, session activation, error banner
visibility, session delete confirmation, and the localized rename
rejection.

Co-authored-by: Carlos Orozco O. P. <soycanopa@gmail.com>
Sidebar and palette New session route through the async create_new_session
path; session activation clears the transcript and shows a loading state
while the background refresh fetches it; every remaining blocking
refresh() call site moves to schedule_refresh and the synchronous method
is removed. A failed transcript load now surfaces in the error banner
instead of rendering a silently empty chat.

Co-authored-by: Carlos Orozco O. P. <soycanopa@gmail.com>
The context menu Delete action stages a confirmation overlay using the
existing session.delete_confirm copy; the daemon delete only fires on
explicit confirm, and cancel or switching sessions leaves the session
untouched.

Co-authored-by: Carlos Orozco O. P. <soycanopa@gmail.com>
…tion

The sidebar error now renders as a banner above the Today/Earlier
sections so transient failures never hide navigation, and the empty
project-rename rejection reads from the locale catalog instead of a
hardcoded string. Adds messages.loading and settings.projects.rename_empty
keys plus tests.

Co-authored-by: Carlos Orozco O. P. <soycanopa@gmail.com>
Fresh sandboxes need a Rust toolchain to build the workspace and X11 dev
libraries to link the GPUI test binaries on Linux.

Co-authored-by: Carlos Orozco O. P. <soycanopa@gmail.com>
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.

0 participants