Skip to content

feat(app): Codex-style sidebar navigation with live thread status, settle and pins - #48526

Open
malek262 wants to merge 14 commits into
anomalyco:devfrom
malek262:sidebar-navigation-pr
Open

feat(app): Codex-style sidebar navigation with live thread status, settle and pins#48526
malek262 wants to merge 14 commits into
anomalyco:devfrom
malek262:sidebar-navigation-pr

Conversation

@malek262

@malek262 malek262 commented Sep 11, 2026

Copy link
Copy Markdown

Issue for this PR

N/A — feature proposal, no existing issue.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds an optional persistent navigation sidebar (Settings → General → Navigation) as an
alternative to the title-bar tab strip. The tab mode stays the default and is untouched,
so this is purely additive.

The sidebar lists open projects with their threads (sessions) and keeps you aware of what
is happening without leaving the current chat:

  • Live status per thread: Working <elapsed> while the model runs, Needs input when a
    question or permission is waiting on you, Done when a run finishes until you open it.
  • Settle: hide finished threads out of the way (manually, or automatically after a
    configurable idle period — default 3 days). Settled threads are grouped per project
    under a collapsible "Settled" section and can be restored. Working, open and pinned
    threads are never auto-settled.
  • Pin a thread to keep it at the top of its project.
  • Right-click (or the row menu) on a thread: Rename, Share, Export, Settle/Unsettle,
    Delete — same actions as the built-in session menu, reflected live in the sidebar.
  • Hover card per thread with project, directory, git branch and model (with provider icon).
  • mod+shift+n opens a new thread in the current thread's project.
  • Filter box, per-project counts, unread/attention badges, background-open with
    cmd/ctrl+click, and open-tab indicators.

Server-side this relies on the existing archive timestamp: one small fix makes
time.archived clearable (null) over HTTP and makes archived=true return only archived
sessions instead of everything, which the Settled section uses.

Design credit: the concept (active-first sidebar with working/done states and settling)
was inspired by the Codex desktop app and T3 Code. Only the idea is borrowed — all code
here is written against this codebase's existing stores, components and i18n APIs.

How did you verify your code works?

  • bun typecheck clean in packages/app, packages/ui, packages/opencode, packages/core.
  • Full CI on my fork (unit tests, typecheck, playwright e2e, Linux desktop build) green
    on the same commits.
  • Daily-driven a Linux desktop build from those commits: settle/unsettle, pins, rename,
    delete, share, export, auto-settle window and the tabs/sidebar switch all exercised.
  • New unit tests cover the sidebar visibility/partition helpers; i18n parity tests pass
    for all locales (keys added to every locale file).

Screenshots / recordings

Screenshot From 2026-09-11 19-22-08 Screenshot From 2026-09-11 19-23-00 Screenshot From 2026-09-11 19-21-32 Screenshot From 2026-09-11 19-14-47

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

malek added 8 commits September 11, 2026 19:57
- projector writes explicit null for time_archived/time_compacting so
  updates can clear them; drizzle .set() skips undefined fields
- session update payload accepts null for time.archived to unarchive
- listGlobal returns only archived rows when archived=true instead of
  dropping the filter entirely
Settings > General gains a Navigation select (Tabs default, Sidebar)
that hides the titlebar tab strip on desktop widths and mounts a
navigation sidebar next to the session pane. The sidebar lists projects
with their active sessions, working indicators, unread badges, and
hover actions; sessions idle past a configurable window settle into an
expandable Settled section where they can be restored. Working, open,
and current sessions always stay visible.
Reuses existing translated keys where semantics match and reduces the new
key set to eight placeholder-free strings, then adds them to all 61 app
locales so the i18n parity tests stay green. Also drops the plural family
in favour of numeric day labels and fixes the archived row onOpen arity.
The sidebar navigation memo in the titlebar referenced the mobile media
query before its const declaration, so the app crashed on launch with a
temporal dead zone ReferenceError.
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Related PRs Found

PR #46670 - feat(app): add session history sidebar
#46670

This PR is potentially related as it also adds sidebar navigation features for sessions in the app. While PR #48526 focuses on Codex-style sidebar with thread status and settling, PR #46670 addresses session history in the sidebar, which may overlap in scope or UI implementation.

Note: The search shows PR #48526 (the current PR) is the primary match for most queries about sidebar navigation, suggesting this is a comprehensive feature that may have superseded or built upon earlier related work.

@malek262 malek262 closed this Sep 11, 2026
@malek262
malek262 deleted the sidebar-navigation-pr branch September 11, 2026 18:37
@malek262
malek262 restored the sidebar-navigation-pr branch September 11, 2026 18:40
@malek262 malek262 reopened this Sep 11, 2026
@malek262

Copy link
Copy Markdown
Author

PR #46670 is potentially related as it also adds sidebar navigation features for sessions in the app. (from the related-PRs bot above)

For transparency: I read #46670 before opening this. It ships a history tree for everyone — replacing the tab strip outright, no settings flag, rows marked running vs inactive, rename and archive as the only row actions.

This PR takes a different, opt-in approach and covers a wider ground:

  • The tab strip stays the untouched default; the sidebar is a settings toggle (General → Navigation), so neither users nor the existing layout are forced into a new paradigm.
  • Live status per thread from the sync stores: Working with an elapsed timer, Needs input when a question or permission is pending, Done until the thread is opened, plus unread/attention badges — not just a running/idle dot.
  • A settle model with configurable idle auto-settle (default 3 days) and a collapsible per-project Settled section with restore; working, open and pinned threads are never auto-settled. It required two small server fixes: time.archived clearable over HTTP, and archived=true actually filtering to archived sessions.
  • Pins that keep a thread at the top of its project, a filter box, per-project counts, open-tab indicators, and a hover card with project, directory, git branch and model with provider icon.
  • The full set of per-thread actions from the sidebar — rename, share, export, settle/unsettle, delete, close tab — each reflected live with correct navigation afterwards.
  • mod+shift+n for a new thread in the current project; background open with cmd/ctrl+click.
  • Keys added to every locale, unit tests for the visibility/partition logic, and green CI (unit, typecheck, e2e, desktop build).

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