Moving a session between projects
Re-file a session under a different project — one at a time, or several at once — from its own menu or a single keystroke, live on every window and on your phone at the same time. Covers the deliberate exception for a session that has already started, and the Undo that puts everything back exactly as it was.
What it is
What it is
Move a session relocates one or more Claude Code sessions from the project they currently live under to a different project in your sidebar. It is a quick organizational action — you reach it from the session's menu (the right-click menu on a sidebar row, the ⋯ menu at the top of an open session, or the right-click menu on a session row in the Inbox) or the M keyboard shortcut, pick the destination project, and the session immediately re-homes under it. In the left sidebar and in the Inbox you can multi-select several sessions and move them all at once; a single Undo toast lets you put it (or all of them) back exactly where it was.
The feature exists because sessions sometimes land in the wrong place — you started a session in "Scratch" that turned into real work for "Website", or you cloned a session's intent into the wrong project. Rather than archiving and re-spawning, you just move the existing session, conversation history and all.
The one subtle thing it does is protect where a started session runs. A session that has already spawned a Claude CLI process keeps running against its original folder even after the move — the move changes which project the session is filed under in the sidebar, but it does NOT yank a live agent's working directory out from under it (that would break in-flight file paths and git context). A session that has never been spawned yet adopts the destination project's folder, because nothing is pinned to the old one. See "What happens to the working directory" below.
Where to find it
A session's right-click / ⋯ menu → Move, or the M key with a session selected in the sidebar or Inbox.
How it behaves
How to use it
Keyboard shortcut: with a session selected in the sidebar/Inbox (or open in front of you), press
Mto open the destination picker directly — the same picker, skipping the menu. If you have several sessions multi-selected,Mmoves them all, exactly like the menu. It does nothing when no session is in context, and (like the other single-letter session keys) it stays out of your way while you're typing in a reply box.Mis rebindable in Settings → Keyboard Shortcuts and appears in the?shortcuts cheat-sheet.
- Open the session's menu from any place it lives:
- In the left sidebar — right-click the session row, or click its
⋯("More actions") button. - In an open session — click the
⋯menu in the session's header. - In the Inbox — right-click a session row (the "Move to" item shows only for actual sessions, not SMS / email / alarm / recipe rows). If you have multi-selected several session rows in the Inbox, right-clicking one of them moves the whole selection and the item reads "Move N selected to".
- In the left sidebar — right-click the session row, or click its
- Click "Move to" (folder-with-arrow icon) — or just hover over the row for a moment and the submenu pops out on its own (standard menu behavior; clicking still works). The eligible destination projects appear under a "Search projects…" box — as a side submenu from the sidebar or Inbox menu, or expanding inline in the header
⋯menu. - Type to filter if you have many projects, then click the destination project. The submenu and menu close.
- The session immediately moves — it disappears from the old project's session list and appears under the new one. A toast reads
Moved "<session>" to <project>with an Undo button. - Undo (click the toast button, or press your Undo-last-action shortcut — Ctrl+Z by default) puts the session back under its original project in its original position.
Which projects can you move to
The destination list only shows eligible projects — the ones that can actually host a running session. A project is excluded when it is:
- the project the session is already in (you can't move it to itself),
- a soft-deleted project, or
- a virtual / built-in area with no real session folder — the sidebar entries whose folder path is a sentinel like Gmail, SMS, Scratchpads, Tasks, Stats, Settings, etc. These have no folder on disk, so a session can't run under them.
Claude is an eligible destination. The built-in Claude area is the one sentinel that is not excluded: unlike the inbox/tool sentinels above, it resolves to a real folder (~/Claude) and hosts Claude sessions natively, so you can move a session into it like any ordinary project. (Internally the rule is "a real project folder or Claude" — not the older blunt "anything whose folder path starts with __ is out", which wrongly hid Claude.)
If no projects qualify, the submenu shows "No projects".
Where the move shows up
A move re-homes the session live on every surface at once — not just the window you did it in. The window you moved it from updates instantly, and the change also propagates to your other open windows and your phone / web session: the sidebar session list and the per-project counts re-home the session there on their own, with no manual refresh. A move made by an agent or a script over the CLI control API (POST /session/:id/move, below) shows up the same way — the app broadcasts a "session moved" signal that every open client applies, so an agent tidying your projects is reflected on your screen immediately. The one thing that is not instant on a device that did not initiate the move is the session's exact position within the destination project's list; that settles on the next normal refresh (the re-home itself is immediate).
What happens to the working directory
This is the only non-obvious behavior, and it is deliberate:
- A session that has already been started (it has spawned at least one Claude CLI process) keeps its original working directory permanently. The move stamps that folder onto the session as a pin so that resuming or sending another message still runs the agent in the same place it has always run — its file edits, git history, and relative paths stay valid. Moving it again later does not repoint it; the first pin wins.
- A session that has never been started (a fresh, unspawned row) has no pin, so after the move it resolves to the destination project's folder. When you eventually send its first message, the agent spawns in the new project's directory.
In short: moving is safe for running work (it never changes where a live agent operates) and intuitive for brand-new sessions (they follow the project you filed them under).
Undo is exact and backend-owned
The Undo restores the session's previous project, sidebar position, working-directory pin, and last-active timestamp from a record the main process kept at move time — not from anything the UI guessed. So Undo returns the session to precisely the state it was in before the move, including its old spot in the list order. The undo record is authoritative on the backend, which means the restore is correct even if the sidebar re-sorted in the meantime.
Scope and limits
- Also drivable over the CLI control server. Besides the in-app menus and the
Mhotkey, a move is exposed asPOST /session/:id/moveon Omniscio's local control server (it calls the same shared move core as the menu —moveSessionToProjectService— so every guarantee here holds identically, including the working-directory pin and the exact undo). So an external script or an AI driving Omniscio over the CLI control API can move a session, and — exactly like an in-app move — it re-homes the session live on every open client (see "Where the move shows up" above), not just on the device that made the call. - Bulk from the sidebar or the Inbox; single from an open session's header. When you multi-select session rows — in the left sidebar (Shift/Ctrl-click, or Shift+J/K) or in the Inbox — and right-click one that's part of the selection, "Move to" moves every selected session in one action: the item's label reads "Move N selected to", the toast reads
Moved <N> sessions to <project>, and a single Undo reverts them all, each back to its own original project (they can even come from different source folders — an Inbox selection commonly spans projects, and they all consolidate into the one you pick). The Inbox scopes the batch to what you've selected in the Inbox — a leftover sidebar selection never bleeds into an Inbox move. The open-session header⋯menu still acts on a single session, because it only ever has one session in context. Under the hood the bulk path just calls the same per-session move once per selected id (no separate bulk backend), so every safety guarantee below holds identically for each session. - Conversation history travels with the session. Moving re-files the whole session record — its messages, status, and tags are unaffected; only the parent project (and, for unspawned sessions, the eventual spawn folder) changes.
For agents
Where things live (for agents with repo access)
- Shared move gesture + Undo toast: /src/renderer/src/features/dashboard/useMoveSession.ts —
useMoveSession(single) calls the store'smoveSessionToProject(sessionId, targetProjectId), then registers an Undo that callsundoMoveSession(...)and shows thesessionActionstoast.useBulkMoveSessions(the sidebar multi-select and the Inbox multi-select) calls the store'sbulkMoveSessionsToProject(ids, targetProjectId)(optimistic + per-id reconcile, looping the same single IPC), then arms ONE Undo that loopsundoMoveSession(id, priorProjectId)per moved session. For the Inbox, /src/renderer/src/features/dashboard/SidebarOverlays.tsx resolves which sessions a right-click moves viaresolveInboxSessionsToMove(/src/renderer/src/features/dashboard/inbox-helpers.ts) over the Inbox-scoped selection fromgetSelectedInboxSessionIds(/src/renderer/src/lib/bulk-inbox-actions.ts) — never the sidebar union — and routes >1 target touseBulkMoveSessions, else the singleuseMoveSession. - Destination picker (eligibility filter + search): /src/renderer/src/features/dashboard/MoveToProjectMenu.tsx.
- Menu entry points: the "Move to" item in /src/renderer/src/features/dashboard/SessionContextMenu.tsx (left-sidebar right-click / kebab — a side flyout), /src/renderer/src/features/sessions/SessionOverflowMenu.tsx (open-session header
⋯menu — an inline picker), and /src/renderer/src/features/dashboard/InboxItemContextMenu.tsx (Inbox row right-click — a side flyout, gated to session rows viafindMovableSessionForInboxItemin /src/renderer/src/features/dashboard/inbox-helpers.ts). - Keyboard shortcut (
M): themoveSessionaction is declared in /src/shared/keybindings/core.keybindings.ts and handled byhandleMoveSessionin /src/renderer/src/hooks/keyboard-shortcuts/session-move-action.ts, which sets a target on /src/renderer/src/features/dashboard/move-session-picker-store.ts; the globally-mounted /src/renderer/src/features/dashboard/MoveSessionPicker.tsx opens the sameMoveToProjectMenuin a dialog and dispatches the sameuseMoveSession/useBulkMoveSessionsgestures. Each "Move to" menu trigger also carrieshotkeyActionAttr('moveSession'), so its hover tooltip shows the current key. - Backend move + undo (project re-home, working-dir pin, exact inverse):
moveSessionToProject/undoSessionMovein /src/main/db/queries-sessions/lifecycle.ts, the pre-move snapshot in /src/main/services/move-undo-registry.ts, and the workdir pin tier in /src/main/services/work-dir-resolver.ts. - IPC channels:
session:move-to-projectandsession:move-undoin /src/main/ipc/session-handlers.ts. - Live re-home on every surface: the move broadcasts a
SESSION_MOVEDpush (session-move-service.ts, the CLI route, and undo) that the renderer consumes in /src/renderer/src/hooks/session-sync/useSessionMetadataSync.ts (handleSessionMoved→ theupdateSessionProjectIdstore reducer, find-anywhere across live/archived/lazy). It is allowlisted for the web/mobile bridge in /src/main/services/web/web-access-push-filter.ts so a paired phone re-homes too. Locked bymove-session-contract.mdI8.
Related
Related
- archive-a-session.md — hide a session (also soft, also undoable) when it's done rather than re-filing it
- snooze-a-session.md — defer a session instead of moving it
- reorder-projects.md — rearrange the projects you're moving sessions between
- add-a-project.md — create the destination project first if it doesn't exist yet
Last verified 2026-10-05