-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Which version of the app are you using?
3.7.12+
Which API Provider are you using?
Anthropic
Which Model are you using?
Claude 3.7 Sonnet
What happened?
Multiple instances of TerminalManager are being created across different contexts in the application (one during extension activation in src/activate/registerTerminalActions.ts and one per active task/Roo webview). Each TerminalManager instance registers its own shell execution event handlers, leading to duplicate event handling.
When a terminal command is executed, the shell execution events (onDidStartTerminalShellExecution and onDidEndTerminalShellExecution) are being handled multiple times by different TerminalManager instances. This causes:
- Redundant processing of the same events
- Potential race conditions when multiple handlers try to update the same terminal state
- Inconsistent terminal ownership with ambiguity about which manager is responsible for resource cleanup
Steps to reproduce
- Run
sleep 30in one Roo instance - Click "open in editor" to launch a second Roo instance
- Run
sleep 30in the second instance - One of the commands will complete normally, but the other will hang indefinitely
Additional context
I have verified this by adding debug to the handlers that print duplicate records even for running a single command because every call to new TerminalManager registers the handlers again.
Terminal Architecture Refactoring
I am working on a pull request to redesign terminal integration handling as follows:
Hierarchy
- TerminalRegistry (static, global): Manages all terminals
- Terminal (class): Encapsulates VSCode terminal with ownership and state
- TerminalProcess (class): Represents a command execution within a terminal
Key Components
TerminalRegistry
- Singleton for global terminal management
- Centralized shell execution event handling
- Terminal creation, lookup, and task-based management
- Methods: getOrCreateTerminal, releaseTerminalsForTask, registerShellExecutionHandlers
Terminal
- Replaces TerminalInfo interface with proper class
- Manages single terminal instance with taskId ownership
- Handles command execution and process lifecycle
- Prevents concurrent command execution
- Methods: runCommand, claim, release, handleStreamAvailable, handleShellExecutionComplete
TerminalProcess
- Enhanced with stream handling
- Responsible for command execution state and results
- Exit code interpretation moved from TerminalManager
TerminalManager
TerminalManager is deprecated and removed because it is the problem child which causes terminal ownership confusion between instances
Command Execution Flow
- Cline obtains terminal via TerminalRegistry.getOrCreateTerminal(taskId, cwd)
- Terminal.runCommand(command) creates TerminalProcess
- Shell execution events routed through TerminalRegistry to Terminal to TerminalProcess
- Process completion handled at appropriate level
Multiple Cline Webview Support
- Global TerminalRegistry enables multiple Cline webview instances to share terminals
- Each Cline instance interacts with TerminalRegistry directly
- Terminal ownership tracked by taskId prevents conflicts between instances
- Shell execution events properly routed to correct Terminal/TerminalProcess regardless of source
Metadata
Metadata
Assignees
Labels
Type
Projects
Status