feat(tui): add session migration dialog#23250
Conversation
# Conflicts: # packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx # packages/opencode/src/config/config.ts # packages/opencode/src/server/routes/instance/session.ts # packages/opencode/src/session/index.ts
Use a getter for gutter JSX to fix reactivity loss after filtering. Add ctrl+d keybind to delete sessions with double-press confirmation. Add orphan legend (!) indicator in the bottom bar.
# Conflicts: # packages/opencode/src/config/config.ts # packages/opencode/src/config/keybinds.ts # packages/opencode/src/config/provider.ts # packages/opencode/src/util/effect-zod.ts # packages/opencode/test/util/effect-zod.test.ts
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
|
This PR should be reopened. Here's why:
Could a maintainer please reopen this PR? |

Issue for this PR
Closes #23249
Type of change
What does this PR do?
Adds a session migration dialog accessible via
ctrl+ofrom the session list. This allows users to:Recover orphaned sessions — When a project directory is renamed or moved (Sessions become orphaned when project directory is renamed #23248, Session lookup fails with NotFoundError when PTY spawned from non-git directory context #8538), sessions become invisible because their
directoryfield points to a path that no longer exists. The migration dialog shows all sessions across all projects, marks orphaned ones with a yellow!indicator, and allows moving them to the correct project.Intentionally migrate sessions between projects — When work was started in the wrong project, users can move the session (with its full conversation history) to another project rather than starting over.
Delete orphaned sessions — Since orphaned sessions don't appear in the normal
/sessionslist, the migration dialog is the only place where they can be found and deleted (ctrl+dwith double-press confirmation).How it works:
/experimental/session(bypassing the SDK's automatic directory filtering) and identifies orphans via a newGET /session/orphansendpoint.project_idanddirectoryon the session and its children (sub-agents) via a newPOST /session/:sessionID/migrateroute.Files changed:
dialog-session-migrate.tsx— New migration dialog componentdialog-session-rescue.tsx— New destination picker componentdialog-session-list.tsx— Addedctrl+okeybind to open migration dialogkeybinds.ts— Addedsession_migratekeybind (default:ctrl+o)session/session.ts— AddedlistOrphans()andmigrate()functionsserver/routes/instance/session.ts— Added orphans and migrate routessdk/js/src/v2/gen/— Regenerated SDK with new endpointsNote: This does not fix the root cause of orphaned sessions (#23248). An automatic fix in
fromDirectory()to update session directories when a project worktree changes would still be valuable, but involves subtleties (e.g. multiple clones of the same repository sharing a project ID).Possible future improvements:
How did you verify your code works?
Tested manually on Linux (Alacritty terminal):
!indicator appears and persists after filtering)/sessionsimmediatelybun typecheckpasses with zero errorsScreenshots / recordings
Migration dialog showing all sessions with orphaned ones marked with
!:Destination picker after selecting a session:
Checklist