fix(web): restore the Archive action in the default sidebar thread menu - #6526
Conversation
Archive was dropped from the new sidebar's per-thread menu when it became the default, leaving Delete as the only way to remove a thread from the sidebar even though Delete permanently clears history. Add Archive back to buildThreadActionMenuItems (the shared source for the sidebar row menu and chat header menu) and wire it through both surfaces, reusing the existing archiveThread mutation and confirmThreadArchive setting the legacy sidebar already relies on.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e2cc16e. Configure here.
ApprovabilityVerdict: Approved 1524c5e This PR restores the Archive action to the sidebar thread menu using existing archiveThread functionality. The changes are self-contained to menu UI logic, follow established patterns, and include tests. The author has prior history with this file. You can customize Macroscope's approvability policy. Learn more. |
…re toast Macroscope and Cursor Bugbot flagged two real issues in the single-thread archive path (sidebar row menu and chat header menu): the menu item stayed enabled while a thread had an active turn, so it always failed against archiveThread's ThreadArchiveBlockedError guard, and any failure after a successful archive (e.g. the post-archive navigation to a new thread) was reported as "Failed to archive thread" even though the thread had already been archived. Both are already handled correctly in the bulk-archive path (buildMultiSelectThreadContextMenuItems disables on hasRunningThread, and archiveSelectedThreadEntries distinguishes a post-archive navigation failure); this brings the single-thread path in line with that pattern.

What Changed
Adds an "Archive thread" item back to the per-thread action menu (
buildThreadActionMenuItemsinapps/web/src/components/threadActionMenu.logic.ts), which is the single source that both the default sidebar's right-click row menu (Sidebar.tsx) and the chat header menu (useThreadActionMenu.ts) render. Wired both surfaces to dispatch the new"archive"id to the existingarchiveThreadmutation fromuseThreadActions, reusing the sameconfirmThreadArchiveclient setting the legacy sidebar and the existing bulk-archive flow already use for an optional confirm dialog.Archive sits directly before Delete in the list (after Copy thread ID), without the
destructivestyling Delete uses — archiving hides a thread from the sidebar but keeps it under Settings > Archived threads, so it isn't a destructive action.No new capability gate was added:
archiveThread/unarchiveThreadare already dispatched unconditionally everywhere else in the codebase (the legacy sidebar's row button and bulk-select menu never check areadEnvironmentSupports*flag for archive), so gating it here would be inventing a capability the backend doesn't expose.Why
Closes #6511. PR #5672 made the new (non-legacy) sidebar the default and its per-thread menu never got an Archive item, even though:
archiveThreadmutation this PR now reuses.This restores parity with the legacy sidebar. If the removal was actually intentional, the maintainers may prefer to close #6511 instead of merging this — I'm not aware of any discussion establishing that, so I'm treating it as an unintentional regression per the issue.
UI Changes
The menu renders through the native context-menu bridge (
api.contextMenu.show), so on the desktop app it's an OS-native menu a browser screenshot can't capture. However,apps/web/src/localApi.tsfalls back to a DOM-rendered menu (showContextMenuFallbackinapps/web/src/contextMenuFallback.ts) wheneverwindow.desktopBridgeisn't present (i.e. the web app running in a plain browser). I exercised that real fallback renderer with the realbuildThreadActionMenuItemsoutput via a throwaway demo page served by the app's own Vite dev server (not committed — deleted after capturing evidence), and captured real screenshots with a headless Chromium:Before (pre-fix code, reproduced verbatim from the prior
buildThreadActionMenuItemsoutput):Settle thread → Snooze › → Rename thread → Mark unread → Copy path → Copy thread ID → Delete
After (current code):
Settle thread → Snooze › → Rename thread → Mark unread → Copy path → Copy thread ID → Archive thread → Delete
Please read these two images for what they are: the DOM fallback menu rendered by the real
showContextMenuFallbackfrom the realbuildThreadActionMenuItemsoutput, in an isolated demopage rather than inside the running app. They are evidence of item presence and ordering, not of
final visual styling — the icon sizing and label wrapping you see are artifacts of the bare demo
page's lack of app CSS, and are not introduced by this PR. On the desktop app this menu is an
OS-native menu, which no browser screenshot can capture; I could not produce a native-menu
screenshot and am not going to imply otherwise.
The before/after item ordering is additionally pinned by the two new tests in
apps/web/src/components/threadActionMenu.logic.test.ts("offers archive as a non-destructiveaction right before delete" and the updated capability-gating test), which fail if Archive's
presence or position regresses.
Verification
cd apps/web && pnpm exec vp test run --passWithNoTests --project unit src/components/threadActionMenu.logic.test.ts— 8 passed (6 pre-existing + 2 new).cd apps/web && pnpm exec vp test run --passWithNoTests --project unit src/hooks/useThreadActions.test.ts— 1 passed (unaffected, ran as a sanity check sincearchiveThreadis reused here).cd apps/web && pnpm exec tsgo --noEmit— no errors.pnpm exec vp lint --report-unused-disable-directiveson the changed files — no findings.pnpm exec vp format --checkon the changed files — all correctly formatted.I did not run the full test suite or a repo-wide typecheck, per the smallest-relevant-scope guidance.
Checklist
Closes #6511
Note
Low Risk
UI-only wiring to an existing
archiveThreadmutation and settings; no new server paths or auth changes.Overview
Restores Archive thread to the default sidebar and chat header per-thread menus, which regressed when the new sidebar became default (#6511).
buildThreadActionMenuItemsnow includes a non-destructive Archive thread item immediately before Delete, always shown (not capability-gated). Archive is disabled while a thread has an active running turn (isRunning), matching server rejection inarchiveThread.Sidebar and
useThreadActionMenuboth handle the"archive"action: optional confirm viaconfirmThreadArchive, thenarchiveThreadwith error toasts (including archive-succeeded-but-navigation-failed). Tests cover ordering, non-destructive styling, capability-off availability, and the running disable.Reviewed by Cursor Bugbot for commit 1524c5e. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Restore the Archive action in the sidebar and chat header thread menus
buildThreadActionMenuItems, positioned just before 'Delete' with no destructive styling.Sidebar.tsxanduseThreadActionMenu.ts, usingarchiveThreadfromuseThreadActionsand respecting theconfirmThreadArchivesetting.Macroscope summarized 1524c5e.