Skip to content

Add sidebar status and edge fade settings - #6763

Closed
austinywang wants to merge 27 commits into
mainfrom
issue-6760-sidebar-tab-status-shadow
Closed

austinywang wants to merge 27 commits into
mainfrom
issue-6760-sidebar-tab-status-shadow

Conversation

@austinywang

@austinywang austinywang commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

Closes #6760

Summary

  • Add an opt-in Sidebar Status Style setting: the default Sentence mode keeps extension-sidebar agent status as subtitle text, while Dot mode replaces it with a compact colored indicator so rows stay one line.
  • Add an opt-in Tab List Edge Fade setting: the default Full mode keeps the current scroll-edge mask, Subtle shortens/lightens it, and Off removes the top/bottom fade.
  • Wire both settings through Settings UI, cmux.json parsing/template/schema/search, and localized EN/JA strings.

Before / After

  • Before Part A: extension-sidebar workspace rows always showed agent status as a subtitle under the workspace title when not super-compact.
  • After Part A: users can keep that default or switch to a colored status dot.
  • Before Part B: the sidebar tab list always used the fixed top/bottom edge fade.
  • After Part B: users can keep the default fade, reduce it, or disable it.

Validation

  • Ran JSON parsing for Resources/Localizable.xcstrings, web/data/cmux.schema.json, web/messages/en.json, and web/messages/ja.json.
  • Ran git diff --check and git diff --cached --check.
  • Did not run local tests or builds per request.

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Adds two opt‑in sidebar appearance settings and a compact status‑dot display driven by live agent lifecycle. Dot mode prioritizes “needs input,” preserves provider subtitles via subtitleRole, and edge fades can be tuned or turned off.

  • New Features

    • Settings: sidebar.workspaceStatusStyle (Sentence/Dot) and sidebar.scrollEdgeFade (Full/Subtle/Off), wired through Settings UI, search anchors/aliases, defaults, cmux.json template, JSON import/export, and schema enums/localizations.
    • Sidebar: Dot mode shows a small, color‑coded indicator beside the title and only replaces subtitles with subtitleRole: .agentStatus; rows collapse to one line when there’s no provider subtitle. Edge fades scale by style and fully disable when Off.
    • SDK: CmuxSidebarProviderRow.subtitleRole with .agentStatus; workspace snapshots expose agentStatus and agentStatusText for the dot’s accessible label.
  • Bug Fixes

    • Status indicators: derived from aggregated lifecycle with needs‑input priority; observation refreshes on lifecycle‑only changes; avoids repeated scans; keeps accessibility labels current.
    • Attention queue example: keeps “needs input” workspaces in Needs Attention even if other panels are running; uses structured agent status text.
    • Settings import: validates enum values for the new settings and logs invalid paths. Edge fades render per selected style, including fully disabling.
    • Push notifications: trims process.env.CMUX_PUSH_RATE_LIMIT_ID, falls back to env, applies to rate‑limit checks, and logs when missing/not found.

Written for commit 0f7ebfd. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added two new sidebar appearance settings: workspace status style (sentence vs colored dot) and scroll-edge fade (full, subtle, off).
    • Updated the settings UI, search/navigation, default templates, and localized labels/help text.
    • Extended the settings JSON schema/support so these options can be imported/exported.
  • Bug Fixes
    • Improved sidebar scroll-edge fade rendering to match the selected style (including fully disabling fades when set to off).
    • Refreshed sidebar status-dot updates when workspace lifecycle changes occur.
  • Tests
    • Added/extended coverage for defaults, persistence/round-tripping, JSON validation, and UI anchor resolution.

@vercel

vercel Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 27, 2026 5:14am
cmux-staging Building Building Preview, Comment Jun 27, 2026 5:14am

@coderabbitai

coderabbitai Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds two sidebar settings for workspace status presentation and scroll-edge fade strength, and wires them through settings storage, UI, search metadata, JSON handling, and sidebar rendering.

Changes

Sidebar appearance settings

Layer / File(s) Summary
Setting contracts and persistence
Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/SidebarWorkspaceStatusStyle.swift, Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/SidebarScrollEdgeFadeStyle.swift, Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/SidebarCatalogSection.swift, Sources/CmuxSettingsJSONPathSupport.swift, Sources/KeyboardShortcutSettingsFileStore*.swift, Packages/macOS/CmuxSettings/Tests/CmuxSettingsTests/UserDefaultsSettingsClientTests.swift, cmuxTests/SidebarWidthPolicyTests.swift, web/data/cmux.schema.json
Adds the sidebar enum types and catalog keys, wires string-enum JSON parsing and whitelist support, updates the default template, extends persistence tests, and adds schema definitions for the new settings.
Search, schema, and localization metadata
Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift, Sources/SettingsNavigation.swift, Sources/SettingsSearchAliases.swift, Resources/Localizable.xcstrings, web/messages/*
Adds curated setting entries, navigation anchors, search aliases, schema descriptions, and localized strings for the two new sidebar settings.
Settings panel controls
Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection.swift, Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Values/SidebarWorkspaceStatusStyle+Display.swift, Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Values/SidebarScrollEdgeFadeStyle+Display.swift, Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swift
SidebarSection stores, initializes, observes, and renders picker rows for workspace status style and scroll-edge fade, and the UI tests cover the new row anchors.
Workspace status row rendering
Sources/WorkspaceSidebarObservation.swift, Sources/Workspace.swift, Sources/AgentHibernation/AgentHibernationLifecycleState.swift, Sources/ContentView.swift, Sources/ExtensionSidebarWorkspaceRowView.swift, cmuxTests/WorkspaceSidebarObservationTests.swift
Workspace observation now carries agent lifecycle state by panel, ContentView derives per-workspace status lookups and forwards workspaceStatusStyle into the extension sidebar row, Workspace refreshes sidebar observation after agent lifecycle changes, and the row view switches between sentence and dot layouts with updated sizing and status color mapping.
Scroll-edge fade rendering
Sources/ContentView.swift, Sources/SidebarScrim.swift
ContentView updates the sidebar mask calls with fade style and scaled heights, and SidebarScrim renders style-specific gradients only when the corresponding height is nonzero.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • manaflow-ai/cmux#4165 — This PR relies on agent lifecycle state in the sidebar row path, which is introduced and consumed alongside the new workspace status style setting.
  • manaflow-ai/cmux#4610 — Both change the sidebar edge-fade mask behavior in Sources/SidebarScrim.swift and its Sources/ContentView.swift wiring.
  • manaflow-ai/cmux#5012 — Both add sidebar settings entries and anchor-resolution coverage for new settings paths.

Suggested reviewers

  • lawrencecchen
  • azooz2003-bit

Poem

A rabbit twitched its whiskers bright,
One dot for status, fade for night.
Tabs went slim with settings new,
Soft edges, labels, colors too.
🐇✨


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors, 2 warnings)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error Resources/Localizable.xcstrings adds the new sidebar keys only in en/ja, but the catalog already supports 20 locales, so the PR is not fully internationalized. Add translated entries for the 18 missing locales for settings.sidebar.workspaceStatusStyle and settings.sidebar.scrollEdgeFade (or update the supported locale set consistently).
Cmux No Ambient Global State ❌ Error FAIL: Sources/ContentView.swift:31-33 adds top-level mutable globals, and Sources/CmuxSettingsJSONPathSupport.swift adds file-scope static-namespace enums, both banned ambient state. Move the overlay keys onto the owning overlay/controller types, and move settings constants/helpers into constructable owner types or nested private helpers instead of file-scope static namespaces.
Out of Scope Changes check ⚠️ Warning The push API rate-limit env var change is unrelated to the sidebar settings requested in #6760. Move the push API change into a separate PR unless it is required for this issue.
Docstring Coverage ⚠️ Warning Docstring coverage is 3.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (21 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main sidebar settings change.
Linked Issues check ✅ Passed The PR satisfies #6760 by adding the status style and edge fade settings with UI, schema, parsing, and EN/JA localization.
Cmux Swift Actor Isolation ✅ Passed PASS: the new sidebar settings are plain Sendable enums, and the touched UI/Workspace call sites remain explicitly @MainActor; no new isolation regressions found.
Cmux Swift Blocking Runtime ✅ Passed Parsed the touched Swift diff and found zero added blocking/timing primitives; changes are settings/UI wiring only, with no new waits, sleeps, syncs, or locks.
Cmux Browser Automation Off-Main ✅ Passed PR only bumps ghostty and vendor/bonsplit submodule pointers; no browser.* automation or policy-test changes in the rule-target files.
Cmux Expensive Synchronous Load ✅ Passed The diff only adds sidebar settings/UI and in-memory lifecycle wiring; no new RestorableAgentSessionIndex.load() or history/JSONL scans appear in interactive paths.
Cmux Cache Substitution Correctness ✅ Passed Lifecycle state is live UI-only; it’s invalidated on changes, cleared on restore, and the sidebar snapshot is rebuilt from current workspace state, not persisted history.
Cmux No Hacky Sleeps ✅ Passed The diff changes only Zig/C header files via a submodule update; no TS/JS/shell/runtime scripts were modified and no sleep/poll/timer patterns appear.
Cmux Algorithmic Complexity ✅ Passed New sidebar/status lookups are linear and deduped by dictionaries; no nested full-collection rescans or repeated sorts/filtering in hot paths were introduced.
Cmux Swift Concurrency ✅ Passed No new legacy async patterns appear in the sidebar/settings diff; the change is synchronous UI/state wiring, and existing DispatchQueue/Combine use is preexisting boundary code.
Cmux Swift @Concurrent ✅ Passed The PR only adds synchronous sidebar settings/rendering code; no new @concurrent, nonisolated async, or actor-unsafe async helpers were introduced.
Cmux Swift File And Package Boundaries ✅ Passed No boundary breach: new logic is split into small package types/UI glue; app-target edits are small focused changes in existing files, not oversized growth or mixed responsibilities.
Cmux Swiftpm Lockfiles ✅ Passed Diff only updates submodule pointers; no .gitignore, Package.resolved, Package.swift, Xcode project, or workflow files changed.
Cmux Swift Logging ✅ Passed Touched Swift code adds only a sanitized os.Logger warning; no new print/debugPrint/dump/NSLog or MainActor-coupled logger violations were found.
Cmux User-Facing Error Privacy ✅ Passed No new user-facing error/alert/recovery copy exposes vendor, env, or secret details; added logs are internal and redacted, and API errors stay generic.
Cmux Swiftui State Layout ✅ Passed No new problematic SwiftUI state/layout patterns were introduced: row views use snapshots/closures, and the new settings UI follows the file’s existing state pattern without GeometryReader or rende...
Cmux Architecture Rethink ✅ Passed The status-dot path is a pure Workspace snapshot, refreshed via the existing sidebarMetadata bridge; no sleeps, polling, or duplicate ownership were added.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed No new standalone cmux-owned windows were added; the touched inspector window already uses cmux.extensionSidebarInspector and is listed in cmuxAuxiliaryWindowIdentifiers.
Cmux Source Artifacts ✅ Passed Changed paths are intentional source/config/localization/test files or deletions; the only TSV is a tracked CI budget file, not a stray artifact.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Only product-facing sidebar settings/UI logic was added in Sources; no new test/debug seam or DEBUG-only test accessor appears in the PR diff.
Description check ✅ Passed The PR description includes the required summary, before/after, and validation sections and is mostly complete despite missing the demo video and checklist items.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-6760-sidebar-tab-status-shadow

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds two sidebar appearance settings and wires them through the app and config surfaces.

  • Compact agent status dots for extension-sidebar workspace rows.
  • Configurable full, subtle, or disabled sidebar edge fades.
  • Settings UI, cmux.json import/template/schema/search, and localized strings.
  • Structured provider metadata for agent status and subtitle roles.
  • Push notification rate-limit ID trimming and fallback handling.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
Sources/ExtensionSidebarWorkspaceRowView.swift Renders the new dot status mode while preserving provider subtitles unless they are marked as agent status.
Sources/Workspace+PanelLifecycle.swift Builds a structured sidebar status snapshot from lifecycle state and allowed agent status keys.
Sources/ContentView.swift Connects the new live settings to sidebar row rendering and scroll-edge fade masks.
Sources/SidebarScrim.swift Adds full, subtle, and off fade behavior for the sidebar mask.
Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/AttentionQueueSidebar.swift Uses structured agent status to classify needs-input rows and mark only agent-status subtitles.
Sources/KeyboardShortcutSettingsFileStore.swift Imports and validates the new sidebar enum settings from cmux.json.
web/app/api/notifications/push/route.ts Normalizes the push rate-limit ID before passing it to the rate-limit check.

Reviews (23): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment thread Sources/ExtensionSidebarWorkspaceRowView.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/ExtensionSidebarWorkspaceRowView.swift`:
- Around line 137-155: The status dot color logic in agentStatusColor(for:) is
parsing localized subtitle text, so it fails for non-English locales. Update
ExtensionSidebarWorkspaceRowView to stop inferring state from the rendered
subtitle and instead use a structured status value from CmuxSidebarProviderRow;
add an optional status field (mirroring ChatAgentState) to that model and
populate it from the provider side. Then have agentStatusColor(for:) switch on
that typed status rather than matching English keywords in subtitle text.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2dd49a62-cc47-49ec-8b21-cca2fb2466a8

📥 Commits

Reviewing files that changed from the base of the PR and between 047e260 and 0719fca.

📒 Files selected for processing (21)
  • Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/SidebarCatalogSection.swift
  • Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/SidebarScrollEdgeFadeStyle.swift
  • Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/SidebarWorkspaceStatusStyle.swift
  • Packages/macOS/CmuxSettings/Tests/CmuxSettingsTests/UserDefaultsSettingsClientTests.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Values/SidebarScrollEdgeFadeStyle+Display.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Values/SidebarWorkspaceStatusStyle+Display.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/ContentView.swift
  • Sources/ExtensionSidebarWorkspaceRowView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/SettingsNavigation.swift
  • Sources/SettingsSearchAliases.swift
  • Sources/SidebarScrim.swift
  • cmuxTests/SidebarWidthPolicyTests.swift
  • web/data/cmux.schema.json
  • web/messages/en.json
  • web/messages/ja.json

Comment thread Sources/ExtensionSidebarWorkspaceRowView.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/ContentView.swift`:
- Around line 11705-11712: The
`extensionSidebarWorkspaceAgentLifecycleStatesById(for:)` implementation is
doing a full `tabManager.tabs.first(where:)` scan inside the loop over `rows`,
causing repeated O(rows × tabs) work on a render path. Precompute a `[UUID:
Workspace]` lookup from `tabManager.tabs` once at the start of the method, then
use that index for constant-time workspace retrieval before calling
`extensionSidebarAgentLifecycleState(for:)`, keeping the existing deduplication
by `statesById`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7549af80-5563-483a-8a5a-64d12a24f5cf

📥 Commits

Reviewing files that changed from the base of the PR and between 0719fca and a8b3fde.

📒 Files selected for processing (3)
  • Sources/ContentView.swift
  • Sources/ExtensionSidebarWorkspaceRowView.swift
  • Sources/Workspace.swift

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/ContentView.swift`:
- Around line 11705-11710: Avoid rebuilding the workspace index inside
extensionSidebarWorkspaceAgentLifecycleStatesById, since it rescans all tabs on
every extensionSidebarSection render. Reuse the existing workspace lookup from
renderContext.workspaceById (or build it once at the call site) and pass that
map into this helper so the lookup work is not repeated for each section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0dbe70d9-0519-4c51-97fe-752d3d71a1f9

📥 Commits

Reviewing files that changed from the base of the PR and between a8b3fde and 3c7b523.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (1)
  • Sources/ContentView.swift

Comment thread Sources/ContentView.swift Outdated
Comment thread web/messages/ko.json Outdated
Comment thread Sources/ExtensionSidebarWorkspaceRowView.swift Outdated
Comment thread Sources/ExtensionSidebarWorkspaceRowView.swift Outdated
Comment thread Sources/Workspace.swift
Comment thread Sources/ExtensionSidebarWorkspaceRowView.swift
Comment thread Sources/ExtensionSidebarWorkspaceRowView.swift
Comment thread Resources/Localizable.xcstrings
@blacksmith-sh

This comment has been minimized.

Comment thread Sources/Workspace+PanelLifecycle.swift
…b-status-shadow

# Conflicts:
#	.github/swift-file-length-budget.tsv
#	tests/test_claude_wrapper_user_binary_resolution.py
@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 0f7ebfd5 Deployed Jun 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sidebar tabs: agent status as a colored-dot symbol (one-line tabs) + adjustable/removable tab-list drop shadow

3 participants