Skip to content

feat(tui): add session migration dialog#23250

Open
sim590 wants to merge 17 commits intoanomalyco:devfrom
sim590:session-migration-menu
Open

feat(tui): add session migration dialog#23250
sim590 wants to merge 17 commits intoanomalyco:devfrom
sim590:session-migration-menu

Conversation

@sim590
Copy link
Copy Markdown

@sim590 sim590 commented Apr 18, 2026

Issue for this PR

Closes #23249

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds a session migration dialog accessible via ctrl+o from the session list. This allows users to:

  1. 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 directory field 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.

  2. 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.

  3. Delete orphaned sessions — Since orphaned sessions don't appear in the normal /sessions list, the migration dialog is the only place where they can be found and deleted (ctrl+d with double-press confirmation).

How it works:

  • The dialog fetches all sessions via /experimental/session (bypassing the SDK's automatic directory filtering) and identifies orphans via a new GET /session/orphans endpoint.
  • Orphan detection uses two criteria: (1) the session directory no longer exists on disk, (2) a global session whose directory is inside a known project worktree.
  • Selecting a session opens a destination picker offering the current project (using the actual cwd), home directory, and all known projects.
  • Migration updates project_id and directory on the session and its children (sub-agents) via a new POST /session/:sessionID/migrate route.
  • After migration, the session list is refreshed so the migrated session appears immediately.

Files changed:

  • dialog-session-migrate.tsx — New migration dialog component
  • dialog-session-rescue.tsx — New destination picker component
  • dialog-session-list.tsx — Added ctrl+o keybind to open migration dialog
  • keybinds.ts — Added session_migrate keybind (default: ctrl+o)
  • session/session.ts — Added listOrphans() and migrate() functions
  • server/routes/instance/session.ts — Added orphans and migrate routes
  • sdk/js/src/v2/gen/ — Regenerated SDK with new endpoints

Note: 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:

  • Show a warning in the TUI when opening a migrated session, so the user can give context to the LLM about the project change.
  • Inject a system message after migration to orient the LLM toward the new project context.

How did you verify your code works?

Tested manually on Linux (Alacritty terminal):

  • Created orphaned sessions by renaming project directories (both cases from Sessions become orphaned when project directory is renamed #23248)
  • Verified orphan detection (yellow ! indicator appears and persists after filtering)
  • Migrated sessions between projects and verified they appear in /sessions immediately
  • Deleted orphaned sessions and verified full cascade removal (session, messages, parts)
  • Verified bun typecheck passes with zero errors

Screenshots / recordings

Migration dialog showing all sessions with orphaned ones marked with !:

image

Destination picker after selecting a session:

image

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

sim590 and others added 17 commits April 7, 2026 04:47
# 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
@sim590
Copy link
Copy Markdown
Author

sim590 commented Apr 18, 2026

Update: Improved the orphan indicator UX:

  • The ! orphan label in the footer was misleading — it looked like a keybind, as if pressing ! would "orphanize" a session
  • Replaced it with a contextual note at the bottom: NOTE: ! means the session is orphan
  • The note is only shown when orphaned sessions are actually present in the list
  • The ! in the note is displayed in the same warning color as the gutter indicator for consistency
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Add session migration dialog to recover orphaned or misplaced sessions

2 participants