Summary
Allow users to move a terminal session from one Thread to another Thread within the same Project via a context menu action.
Important: Technical constraint
Terminals are in-memory only with composite keys `${threadId}\0${terminalId}` frozen at creation time in `Manager.ts`. There is no SQLite table for terminal sessions — only scrollback history on disk. The session map key cannot be changed after creation.
Live PTY reassignment (moving a running PTY without restart) requires an indirection layer that decouples the PTY process from the session key. This is a significant refactor.
Recommended v1 approach: close + reopen
Instead of live reassignment, v1 should:
- Save terminal scrollback history
- Close the terminal in the source Thread
- Open a new terminal in the target Thread at the same
cwd
- Restore scrollback history in the new terminal
This preserves context (history) without requiring the Manager refactor.
Future v2: live reassignment
- Introduce
TerminalProcess (owns PTY) separate from TerminalSession (owns key + UI binding)
- Allow re-keying a session to a different
(threadId, terminalId) without killing the PTY
- This enables true drag-and-drop terminal movement
Scope (v1)
- Add context menu option on terminal tabs: "Move to thread..." → shows list of threads in same Project
- On selection: close terminal in source, open in target with same cwd, restore history
- Reject cross-project moves (different
workspaceRoot)
Key files to modify
apps/server/src/terminal/Layers/Manager.ts — add close + reopen sequence
apps/server/src/terminal/Services/Manager.ts — add reassignTerminal method
apps/web/src/components/ThreadTerminalDrawer.tsx — context menu with "Move to thread..."
packages/contracts/src/terminal.ts — new RPC for reassignment if needed
Dependencies
None (independent of Client hierarchy, but P3 priority)
Acceptance criteria
Summary
Allow users to move a terminal session from one Thread to another Thread within the same Project via a context menu action.
Important: Technical constraint
Terminals are in-memory only with composite keys `${threadId}\0${terminalId}` frozen at creation time in `Manager.ts`. There is no SQLite table for terminal sessions — only scrollback history on disk. The session map key cannot be changed after creation.
Live PTY reassignment (moving a running PTY without restart) requires an indirection layer that decouples the PTY process from the session key. This is a significant refactor.
Recommended v1 approach: close + reopen
Instead of live reassignment, v1 should:
cwdThis preserves context (history) without requiring the Manager refactor.
Future v2: live reassignment
TerminalProcess(owns PTY) separate fromTerminalSession(owns key + UI binding)(threadId, terminalId)without killing the PTYScope (v1)
workspaceRoot)Key files to modify
apps/server/src/terminal/Layers/Manager.ts— add close + reopen sequenceapps/server/src/terminal/Services/Manager.ts— addreassignTerminalmethodapps/web/src/components/ThreadTerminalDrawer.tsx— context menu with "Move to thread..."packages/contracts/src/terminal.ts— new RPC for reassignment if neededDependencies
None (independent of Client hierarchy, but P3 priority)
Acceptance criteria