Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor terminal architecture to address critical issues with the current design #1365

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

KJ7LNW
Copy link

@KJ7LNW KJ7LNW commented Mar 4, 2025

Context

Refactoring the terminal architecture to address critical issues with the current design. See #1364.

This is a work in progress, not in yet intended to be pulled; I am putting it up for reference and commentary.

The existing implementation suffers from inconsistent terminal ownership, and which results in lack of a clear object-oriented model. This leads to even race conditions and event duplication, as well as inconsistent behavior when multiple Roo webviews are active.

Implementation

The refactoring goal:

  1. TerminalRegistry (static, global): Central manager for all Roo-managed terminals
  2. Terminal (class): Encapsulates a VSCode terminal with taskId ownership and state
  3. TerminalProcess (class): Represents a command execution within a terminal, handles IO
  4. TerminalManager will be removed completely and Cline will interact directly with TerminalRegistry to an available terminal as necessary.

Implementation Order

To implement these changes with minimal disruption, the following commit order is recommended:

  1. Rename and Relocate TerminalInfo:

    • Rename TerminalInfo to Terminal
    • Move to its own file (Terminal.ts)
    • Update imports and references
  2. Move interpretExitCode to TerminalProcess:

    • Move the method implementation to TerminalProcess class
    • Update all references to use the new location
  3. Move getTerminalContents to Terminal:

    • Move the method implementation to Terminal class as a static method
    • Update all references to use the new location
  4. Convert Terminal to Class:

    • Transform Terminal from interface to class
    • Add constructor, basic properties, and initial methods
    • Implement claim and release functionality
  5. Add Terminal Functionality:

    • Implement runCommand method
    • Add event handling methods
    • Add state management
  6. Enhance TerminalRegistry:

    • Add terminal management methods
    • Implement terminal lookup
    • Add task-based terminal management
  7. Move Shell Execution Handlers:

    • Add handler registration to TerminalRegistry
    • Update extension activation
    • Remove handlers from TerminalManager
  8. Update Cline Integration:

    • Modify Cline to use TerminalRegistry directly
    • Remove terminal tracking in Cline
    • Ensure proper cleanup on task abortion
  9. Remove TerminalManager:

    • Remove TerminalManager class
    • Update any remaining references
    • Final cleanup

How to Test (ongoing work)

To reproduce the issue that will ultimately be fixed by this PR:

  1. Using the current version, open two Cline instances
  2. Run sleep 30 in one instance
  3. Run another command in the second instance
  4. Observe that one command will hang indefinitely (bug Duplicate Terminal Shell Execution Handlers Causing Event Conflicts #1364)

Get in Touch

My handle on the Roo Code Discord is KJ7LNW. This PR addresses bug #1364.

This commit combines three related improvements to terminal testing:

- Create a reusable function for testing terminal commands with real output
- Update tests to properly invoke terminal shell execution handlers
- Add microsecond timing to measure execution performance

Key improvements:
- Added testTerminalCommand function that takes command and expected output
- Use child_process.execSync to run real commands and feed output into mock terminal stream
- Properly trigger VSCode onDidStartTerminalShellExecution and onDidEndTerminalShellExecution events
- Add timeout mechanism to prevent hanging tests
- Measure execution time from terminal process creation to command completion
- Display both microseconds and milliseconds in test output
- Add test for base64 encoded zeros with configurable line count
- Increase buffer size for execSync to handle large outputs
- Limit output display to avoid cluttering the terminal

Signed-off-by: Eric Wheeler <[email protected]>
Copy link

changeset-bot bot commented Mar 4, 2025

⚠️ No Changeset found

Latest commit: 3e8403f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Transformed the TerminalInfo interface into a proper Terminal class and moved it to its own file. This improves code organization and encapsulation by centralizing terminal-related functionality.

The change establishes a clearer object model for terminal management, setting the foundation for a more maintainable terminal architecture. All references throughout the codebase have been updated to use the new Terminal class while preserving existing functionality.

Tests have been updated and verified to ensure compatibility with the new structure.

Signed-off-by: Eric Wheeler <[email protected]>
@KJ7LNW KJ7LNW changed the title test: add comprehensive terminal command execution testing refactor terminal architecture to address critical issues with the current design Mar 4, 2025
Eric Wheeler added 3 commits March 3, 2025 21:14
This commit moves the interpretExitCode method from TerminalManager to TerminalProcess class, as part of the terminal refactoring effort. The method is responsible for translating exit codes into detailed results, including signal information.

Changes include:
- Moved interpretExitCode method to TerminalProcess class
- Updated imports in TerminalManager and Cline to reference ExitCodeDetails from TerminalProcess
- Added findTerminalIdByVscodeTerminal helper method in TerminalManager
- Added comprehensive unit tests for interpretExitCode in TerminalProcess
- Tests cover undefined exit codes, normal exit codes (0-127), and signal exit codes (128+)

This change improves code organization by placing the exit code interpretation logic closer to where it's primarily used, in the TerminalProcess class.

Signed-off-by: Eric Wheeler <[email protected]>
This commit partially addresses the issue of duplicate handler calls by removing
an unnecessary instantiation of TerminalManager in registerTerminalActions.ts.

Move the getTerminalContents method from TerminalManager to Terminal class as a static method
and update all references to use the new location.

Signed-off-by: Eric Wheeler <[email protected]>
Replace echo -e with printf command in terminal tests for better portability.

- Replace echo -e with printf to ensure consistent behavior across different shell implementations
- Not all implementations of echo support the -e flag for interpreting backslash escapes
- Using printf provides a more reliable way to handle escape sequences

Signed-off-by: Eric Wheeler <[email protected]>
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.

1 participant