Skip to content

[Feature] Command palette can navigate to sessions but not act on them — add Archive, Delete, and Rename #4255

Description

@randypitcherii

Problem or use case

The command palette can take you to a session but can't do anything to one. Its actions array (web/src/shell/CommandPalette.tsx ~L129) holds six entries — New chat, Go to Inbox / Automations / Settings, and the two sidebar toggles — none of which touch session lifecycle. Meanwhile the sidebar row's menu carries the entire lifecycle surface: Share, Rename, Mark as unread, Move to project, Stop session, Archive, Delete (shell/Sidebar.tsx ~L2652 onwards, mirrored between the kebab dropdown and the right-click context menu via ConversationMenuItems).

So the three most common housekeeping actions are mouse-only and sidebar-only:

  • Archive — the routine "I'm done with this one" gesture, and the main way the sidebar stays readable. Requires: reveal sidebar → find the row → right-click or hover-then-kebab → Archive.
  • Delete — same path, plus a confirm dialog.
  • Rename — same path, and it puts the row into inline edit mode (setIsEditing(true)), so it only works at the row.

That path breaks down exactly when you'd want it most:

  • The sidebar may not be on screen. It's toggleable (⌘⌥[) and collapses on mobile; both toggles are already palette actions, so the palette knows about a sidebar that may be hidden.
  • The row may not be findable. With many sessions, or under a My/Shared/All filter, or inside a collapsed project folder, "find the row" is itself a search task. The palette already has a server-backed search that finds sessions by title and chat content — strictly better at locating a session than scrolling the sidebar.
  • You're already in the session. Archiving the conversation you're looking at means leaving it, hunting its row in the list, and acting there.

There's an existing ask for part of this: #4163 wants keyboard rename via a /rename slash command (also tagged comp:tui). That's a different surface for the same missing capability, and both run into the same blocker described below. They should land on shared plumbing, not two independent rename paths.

Proposed solution

Add three verb commands to the palette's actions array, operating on the active session, each reusing the sidebar's existing mutation hooks so behavior stays identical:

Command Hook Behavior to preserve
Archive session useArchiveConversation Immediate, with the existing undo toast (ArchivedToast / showArchivedToast, Sidebar.tsx ~L310)
Delete session useStopAndDeleteConversation Keeps the confirm dialog — never a one-keystroke destructive action
Rename session useRenameConversation Prefilled with the current title, select-all on open

Gating, mirroring ConversationMenuItems exactly:

  • All three are owner-only (isOwner), matching the menu's disabled-with-tooltip treatment. Simplest palette equivalent: omit the command rather than list a dead one.
  • Hidden when there is no active session (landing page, Settings, Inbox, Automations).
  • Archive hidden for an already-archived session; consider ArchiveRestoreIcon / "Unarchive session" as its counterpart, since useArchiveConversation already handles both directions.

Keywords so they're findable by intent, not just label: ["archive", "done", "hide", "clean up"], ["delete", "remove", "destroy"], ["rename", "title", "retitle"].

The blocker worth naming up front: Rename has no non-sidebar surface. Today rename is the sidebar row — setIsEditing(true) flips that row into an inline input (Sidebar.tsx ~L3092). A palette action can't drive it when the sidebar is hidden, the row is filtered out, or it isn't rendered. So this needs a small standalone rename dialog wrapping useRenameConversation, with the sidebar's inline edit kept as-is for the mouse path. That dialog is also what #4163's /rename needs, and what a future rename-from-header would use. Archive and Delete have no such problem — Delete's confirm dialog already exists, and Archive is a bare mutation plus a toast.

Deliberately out of scope, to keep this reviewable: acting on a session other than the active one (pick-a-session-then-act, which would want the two-step palette shape) and the rest of the row menu (Share, Stop, Move to project, Mark as unread). Both are natural follow-ups once the verb-command pattern exists.

Interaction with #4240. That issue proposes splitting ⌘K (commands) from ⌘⇧F (session search). These three are unambiguously commands and belong on the ⌘K side under either outcome — no ordering dependency between the two issues.

Acceptance criteria

  • ⌘K lists Archive session, Delete session, and Rename session while a session is open and the viewer owns it; none of the three appear otherwise.
  • Archive from the palette archives the active session and shows the same undo toast as the sidebar menu.
  • Delete from the palette opens the existing confirmation before deleting; dismissing it deletes nothing.
  • Rename from the palette opens a rename dialog prefilled with the current title, works with the sidebar hidden, and persists via the same mutation the sidebar uses.
  • The sidebar's own menu and inline-edit behavior are unchanged.
  • Each command is reachable by intent keywords, not only by its exact label.
  • Vitest coverage in CommandPalette.test.tsx for presence/absence per gate, plus the rename dialog's own tests.

Alternatives considered

  • Direct hotkeys instead of palette commands (e.g. ⌘⌥A to archive). Fine for archive, wrong for delete — a destructive action one chord away invites accidents — and it spends scarce chords on actions whose frequency varies a lot per user. The palette is the right home for the long tail; a hotkey can be layered on archive later if it earns one.
  • Add a session-actions menu to the chat header. Duplicates the sidebar menu in a second place and doesn't help keyboard users, who are the ones stuck today.
  • Wait for [Feature] Separate the command palette (⌘K) from session search (⌘⇧F), per the VS Code convention #4240's split before adding commands. These belong on the commands side either way; adding them now gives that split more to justify itself with.
  • Have the palette drive the sidebar's inline edit for rename (scroll the row into view, then setIsEditing(true)). Avoids the new dialog, but couples a global surface to whether a specific row happens to be rendered — it breaks precisely in the collapsed-sidebar / filtered-list cases this issue exists to fix.

Harness

Not applicable

Platform or device

Not platform-specific

Harness mode

Not applicable

Expected reach

Most users

Authentication type

Not authentication-related

Metadata

Metadata

Assignees

Labels

FeatureNew feature or requestP2-mediumPriority: bug with workaround, important feature requestcomp:web-uiComponent: web frontend (ap-web)triagedIssue has been triaged by the bot

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions