This commit fixes an issue where subtasks weren't properly reporting back to parent tasks when cancelled and resumed. Previously, when a subtask was cancelled and a new task was started with the same message, the parent task would incorrectly resume, causing unexpected behavior.
The fix:
1. Stores parent-child relationship information before cancelling a task
2. Restores this relationship after task reinitialization
3. Ensures parent tasks only resume when explicitly instructed to do so
This approach maintains the correct task hierarchy throughout the cancellation and resumption process, preventing parent tasks from automatically resuming when unrelated tasks with similar messages are started.
Update TerminalProcessExec tests to properly handle shell integration
event sequences:
- Set terminal.running=true before command execution
- Remove duplicate command execution that could trigger extra events
- Replace arbitrary timeout with event-based waiting for output
- Ensure proper event sequence (run -> start -> output -> end)
This aligns the tests with the safeguards added in 62ffa797 that
prevent spurious shell integration events from corrupting terminal
state.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Add explicit checks and error logging to handle problematic event sequence:
0. terminal.running=false
1. terminal.shellIntegration.executeCommand(command)
2. onDidEndTerminalShellExecution // from unexpected 'OSC 633 D' sequence
3. onDidStartTerminalShellExecution
4. stream begins
5. onDidEndTerminalShellExecution
The first onDidEndTerminalShellExecution (from unexpected OSC 633 D) is
ignored because terminal.running is false, preventing process=undefined
from being set prematurely. After the stream begins and sets
terminal.running to true, the second onDidEndTerminalShellExecution
proceeds normally.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Fix issue where background processes (like compilers) couldn't broadcast their
output to new tasks after the launching task was closed. Previously commit
851a4cd prevented terminals from responding to any task except the one that
started them.
The fix allows background terminals (taskId undefined) to act as broadcast
sources that can update any task through getEnvironmentDetails, while still
maintaining proper isolation for task-specific terminals. This enables common
workflows where:
1. A task launches a background compiler
2. That task is closed and a new task is started
3. The new task can still receive compiler errors when making changes
This gives us the best of both worlds:
- Task isolation: Active tasks only see their own terminal output
- Background broadcasting: Background processes can inform any task that needs
their output
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Add Terminal.compressTerminalOutput static method to apply run-length encoding
before truncating terminal output. This significantly reduces output size for
repeated lines while maintaining readability.
- Add compressTerminalOutput static method to Terminal class
- Replace all truncateOutput calls with Terminal.compressTerminalOutput
- Import required functions from extract-text
Test program demonstrating compression:
```python
def generate_repeats():
patterns = [
("A\n", 10), # 10 lines
("AA\n", 100), # 100 lines
("AAA\n", 1000), # 1K lines
("AAAA\n", 10000), # 10K lines
("AAAAA\n", 100000), # 100K lines
("AAAAAA\n", 1000000) # 1M lines
]
for text, count in patterns:
print(text * count, end="")
```
Sample output showing compression:
```
A
A
A
A
A
A
A
A
A
A
AA
<previous line repeated 99 additional times>
AAA
<previous line repeated 999 additional times>
AAAA
<previous line repeated 9999 additional times>
AAAAA
<previous line repeated 99999 additional times>
AAAAAA
<previous line repeated 999999 additional times>
```
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Implement applyRunLengthEncoding function to compress repeated lines in text output:
- Add line repetition compression with count message
- Focus on single line repetitions
- Only compress when beneficial
- Add tests for empty input and single line repetitions
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Optimize terminal output handling to reduce memory pressure by:
- Remove continuous result accumulation during line processing
- Only store the same final output from the "completed" event that came from TerminalProcess
Also:
- Add clear error messages for undefined exit details
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Apply terminalOutputLineLimit to command output lines as they are received,
rather than only at the end of command execution. Also apply the limit to
terminal output shown in environment details.
This ensures consistent output truncation behavior across all terminal
output paths, preventing potential memory issues from large outputs.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Use string indices to find line boundaries instead of splitting into array.
This avoids creating large arrays in memory when truncating big inputs.
- Replace split/join with indexOf/lastIndexOf for line counting
- Use slice to extract start/end sections directly from string
- Maintain same 20/80 ratio for before/after content
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
When a terminal command completes with an undefined exit code:
- Add explicit handling for undefined exit code case
- Include clear message in output that exit code is undefined
- Notify user to help diagnose potential terminal issues
This helps identify and debug cases where the terminal process
completes but the exit code is not properly captured.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
When VSCE start sequence (]633;C or ]133;C) is not received, but the
stream has started:
- Emit no_shell_integration event with clear error message
- Include preOutput in completed event for bug reporting
- Call continue() to ensure proper cleanup
- Return early to prevent further processing
This helps diagnose potential upstream VSCE bugs by providing more context
in the error messages and ensuring proper cleanup of terminal state.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Add timeout and error handling to terminal stream initialization to prevent
UI from freezing when a stream is unavailable or never starts. This ensures
that if the VSCE shell integration stream does not start within 3 seconds:
- The streamAvailable promise is rejected with a clear error
- Event listeners are cleaned up to prevent memory leaks
- Terminal state is properly reset
- Execution continues rather than hanging indefinitely
This fixes a potential deadlock where the UI could freeze waiting for a
stream that never becomes available.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Add descriptive messages to shell integration failures to help users
understand and resolve integration issues more effectively. This improves
the debugging experience by providing specific details about why shell
integration failed.
- Add message parameter to no_shell_integration event
- Update UI to display specific error messages
- Update troubleshooting documentation link
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
As pointed out by @cte, passing and checking terminal IDs in events is
unnecessary since a TerminalProcess instance can never be associated with a
different Terminal instance. The event handling is already properly scoped
to the specific TerminalProcess instance.
- Remove terminal ID parameter from shell_execution_complete event
- Remove terminal ID parameter from stream_available event
- Update all event handlers to remove ID checks
- Update all test cases to match new event signatures
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
@cte reported that the stream property is not used anywhere in the codebase.
The stream is passed directly to the process via event emitter and does not need to be stored.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Update the test file path in the comment to match the actual test file name,
making it easier to run the specific test file directly.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Use a string instead of array for terminal output since it is faster
than splitting and joining. Also note that 'line' events may contain
multiple lines, so concatenating directly is more efficient.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
The TerminalProcess class is a critical component for VSCode shell integration.
This documentation explains why changes must be minimal and carefully considered:
- Performance optimizations using index-based operations and zero-copy implementation
- Accuracy requirements for handling terminal output and escape sequences
- Complex integration with VSCode shell features and command execution
- Careful handling of stream data and escape sequence processing
- Backwards compatibility considerations for VSCode releases
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Notice: this comment required updating system test snapshots with new
execute_command XML schema feature `cwd`
- Add required cwd parameter to Terminal constructor calls in tests
- Use './' for TerminalProcess.test.ts
- Use '/test/path' for TerminalProcessExec.test.ts to match shellIntegration.cwd
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Forcing terminals to `cd` back to the project directory was disrupting
shell state without providing feedback to the model. This caused issues
with capturing output from subsequent commands, particularly with custom
shell prompts.
Instead of forcing directory changes, we now track terminal state
through shell integration with a fallback mechanism, and provide
explicit working directory feedback to the model. This allows terminals
to maintain their natural state while ensuring accurate command output
capture.
Changes:
- Remove forced `cd` commands that were disrupting terminal state
- Add getCurrentWorkingDirectory() method with shell integration fallback
- Add customCwd parameter to executeCommandTool for flexible directory handling
- Add requiredCwd parameter to control terminal selection behavior
- Refactor terminal selection logic for more consistent state management
- Modify environment details to include terminal working directory feedback
- Update XML schema to include optional working directory parameter in execute_command
The environment details now provide explicit feedback about terminal state:
Command executed in terminal N from '/path/to/dir'. Exit code: 0
Fixes: #1388
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
These changes ensure proper isolation by preventing terminal process
output from one Cline task appearing in another task's context when
multiple Cline instances are running in parallel.
- Add taskId parameter to TerminalRegistry.getTerminals to filter terminals by Cline task ID
- Update Cline.ts to use taskId-filtered terminals
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>