feat: improve Theia IDE shell integration compatibility

- Add configurable shell integration timeout in VS Code settings (roo-cline.terminalShellIntegrationTimeout)
- Add automatic Theia IDE detection for better error messages
- Add debug logging for shell integration signal detection
- Create comprehensive Theia compatibility documentation
- Default timeout remains 5 seconds, configurable from 1-30 seconds

This addresses issue #9102 where Theia IDE users experienced shell integration
initialization failures due to insufficient timeout and lack of configuration options.
This commit is contained in:
Roo Code 2025-11-07 16:54:09 +00:00
parent 2abdad6d55
commit 4de34b67d3
4 changed files with 229 additions and 12 deletions

155
docs/THEIA_COMPATIBILITY.md Normal file
View file

@ -0,0 +1,155 @@
# Theia IDE Compatibility Guide
This guide provides instructions for using Roo Code with Theia IDE and other VS Code-compatible environments.
## Known Issues
Roo Code may encounter shell integration issues when running in Theia IDE, showing the error:
```
Shell integration initialization sequence '\x1b]633;A' was not received within 4 seconds
```
## Solution
### 1. Adjust Shell Integration Timeout
Theia IDE may require a longer timeout for shell integration initialization. You can configure this in your VS Code settings:
#### Using Settings UI:
1. Open Settings (Ctrl/Cmd + ,)
2. Search for "roo-cline.terminalShellIntegrationTimeout"
3. Increase the value from the default 5000ms to 10000ms or higher
#### Using settings.json:
```json
{
"roo-cline.terminalShellIntegrationTimeout": 10000
}
```
The timeout value is in milliseconds (range: 1000-30000ms).
### 2. Manual Shell Integration Setup (Advanced)
If automatic shell integration fails, you can manually configure your shell for Theia:
#### For Bash Users:
Add to your `~/.bashrc`:
```bash
# Detect Theia IDE environment
if [[ "$THEIA_CONFIG_DIR" ]] || [[ -n "$THEIA_WORKSPACE_ROOT" ]] || [[ -n "$GITPOD_REPO_ROOT" ]]; then
export TERM_PROGRAM="vscode"
export VSCODE_INJECTION="1"
# Shell integration functions
__vsc_prompt_start() { printf '\e]633;A\e\\'; }
__vsc_prompt_end() { printf '\e]633;B\e\\'; }
__vsc_command_start() { printf '\e]633;C\e\\'; }
__vsc_command_complete() {
local EXIT_CODE=$?
printf '\e]633;D;%s\e\\' "$EXIT_CODE"
return $EXIT_CODE
}
# Integrate into prompt
PS1='\[$(__vsc_prompt_start)\]'"$PS1"'\[$(__vsc_prompt_end)\]'
# Set up command execution hooks
trap '__vsc_preexec' DEBUG
__vsc_preexec() {
[[ -n "${COMP_LINE:-}" ]] && return
__vsc_command_start
}
PROMPT_COMMAND='__vsc_command_complete'
fi
```
#### For Zsh Users:
Add to your `~/.zshrc`:
```zsh
# Detect Theia IDE environment
if [[ "$THEIA_CONFIG_DIR" ]] || [[ -n "$THEIA_WORKSPACE_ROOT" ]] || [[ -n "$GITPOD_REPO_ROOT" ]]; then
export TERM_PROGRAM="vscode"
export VSCODE_INJECTION="1"
# Shell integration functions
__vsc_prompt_start() { printf '\e]633;A\e\\'; }
__vsc_prompt_end() { printf '\e]633;B\e\\'; }
__vsc_command_start() { printf '\e]633;C\e\\'; }
__vsc_command_complete() {
local EXIT_CODE=$?
printf '\e]633;D;%s\e\\' "$EXIT_CODE"
return $EXIT_CODE
}
# Integrate into prompt
PS1='%{$(__vsc_prompt_start)%}'"$PS1"'%{$(__vsc_prompt_end)%}'
# Set up command execution hooks
preexec() {
__vsc_command_start
}
precmd() {
__vsc_command_complete
}
fi
```
### 3. Debug Shell Integration Issues
If you continue to experience issues, enable debug logging to help diagnose the problem:
1. Open the VS Code Output panel (View > Output)
2. Select "Roo Code" from the dropdown
3. Look for messages starting with `[TerminalProcess]` which will show:
- Whether shell integration markers are being detected
- The timeout duration being used
- Whether Theia IDE was detected
## Supported Environments
Roo Code automatically detects the following Theia-based environments:
- Eclipse Theia IDE
- Gitpod workspaces
- Eclipse Che environments
- Other environments with `THEIA_CONFIG_DIR` or `THEIA_WORKSPACE_ROOT` variables
## Troubleshooting
### Shell Integration Still Failing?
1. **Verify environment detection**: Check if Roo Code detects Theia by looking for "in Theia IDE" in error messages
2. **Try increasing timeout further**: Some cloud environments may need up to 30000ms
3. **Check shell configuration**: Ensure your shell initialization files are being sourced correctly
4. **Restart Theia IDE**: After making configuration changes, a full restart may be required
### Performance Considerations
- Longer timeouts may delay the initial response when running terminal commands
- The timeout only affects the initial shell integration setup, not command execution
- Once shell integration is established, commands will run normally
## Related Issues
- [Issue #9102](https://github.com/RooCodeInc/Roo-Code/issues/9102) - Original Theia compatibility issue
- [Issue #2017](https://github.com/RooCodeInc/Roo-Code/issues/2017) - Terminal usage with OSC 633 escape sequences
- [Issue #1369](https://github.com/RooCodeInc/Roo-Code/issues/1369) - General shell integration unavailability
## Need Help?
If you continue to experience issues:
1. Report them on our [GitHub Issues](https://github.com/RooCodeInc/Roo-Code/issues)
2. Include your Theia version and environment details
3. Share any error messages from the VS Code Output panel
4. Join our [Discord community](https://discord.gg/roocode) for real-time support

View file

@ -6,6 +6,7 @@ import { BaseTerminal } from "./BaseTerminal"
import { TerminalProcess } from "./TerminalProcess"
import { ShellIntegrationManager } from "./ShellIntegrationManager"
import { mergePromise } from "./mergePromise"
import { Package } from "../../shared/package"
export class Terminal extends BaseTerminal {
public terminal: vscode.Terminal
@ -15,6 +16,13 @@ export class Terminal extends BaseTerminal {
constructor(id: number, terminal: vscode.Terminal | undefined, cwd: string) {
super("vscode", id, cwd)
// Initialize shell integration timeout from VS Code configuration
const config = vscode.workspace.getConfiguration(Package.name)
const configTimeout = config.get<number>("terminalShellIntegrationTimeout")
if (configTimeout !== undefined) {
Terminal.setShellIntegrationTimeout(configTimeout)
}
const env = Terminal.getEnv()
const iconPath = new vscode.ThemeIcon("rocket")
this.terminal = terminal ?? vscode.window.createTerminal({ cwd, name: "Roo Code", iconPath, env })
@ -79,15 +87,25 @@ export class Terminal extends BaseTerminal {
process.run(command)
})
.catch(() => {
console.log(`[Terminal ${this.id}] Shell integration not available. Command execution aborted.`)
const timeoutMs = Terminal.getShellIntegrationTimeout()
const isTheia = this.isTheiaIDE()
console.log(
`[Terminal ${this.id}] Shell integration not available${isTheia ? " in Theia IDE" : ""}. Command execution aborted.`,
)
// Clean up temporary directory if shell integration is not available
ShellIntegrationManager.zshCleanupTmpDir(this.id)
process.emit(
"no_shell_integration",
`Shell integration initialization sequence '\\x1b]633;A' was not received within ${Terminal.getShellIntegrationTimeout() / 1000}s. Shell integration has been disabled for this terminal instance. Increase the timeout in the settings if necessary.`,
)
let errorMessage = `Shell integration initialization sequence '\\x1b]633;A' was not received within ${timeoutMs / 1000}s. Shell integration has been disabled for this terminal instance.`
if (isTheia) {
errorMessage += ` You appear to be using Theia IDE. Consider increasing the timeout in VS Code settings (roo-cline.terminalShellIntegrationTimeout) or refer to the documentation for Theia-specific setup.`
} else {
errorMessage += ` Increase the timeout in the settings if necessary.`
}
process.emit("no_shell_integration", errorMessage)
})
})
@ -190,4 +208,25 @@ export class Terminal extends BaseTerminal {
return env
}
/**
* Detects if we're running in Theia IDE
* @returns true if running in Theia IDE, false otherwise
*/
private isTheiaIDE(): boolean {
// Check for Theia-specific environment variables or app name
if (process.env.THEIA_CONFIG_DIR || process.env.THEIA_WORKSPACE_ROOT || process.env.GITPOD_REPO_ROOT) {
return true
}
// Check if VSCode's appName contains "Theia"
if (vscode.env.appName && vscode.env.appName.toLowerCase().includes("theia")) {
return true
}
// Additional check: look for Theia-specific extension by ID (if any are known)
// This is a placeholder - actual Theia-specific extensions would need to be identified
return false
}
}

View file

@ -79,17 +79,18 @@ export class TerminalProcess extends BaseTerminalProcess {
this.removeAllListeners("stream_available")
// Emit no_shell_integration event with descriptive message
const timeoutSeconds = Terminal.getShellIntegrationTimeout() / 1000
console.debug(
`[TerminalProcess] Shell integration stream did not start within ${timeoutSeconds} seconds`,
)
this.emit(
"no_shell_integration",
`VSCE shell integration stream did not start within ${Terminal.getShellIntegrationTimeout() / 1000} seconds. Terminal problem?`,
`VSCE shell integration stream did not start within ${timeoutSeconds} seconds. Terminal problem?`,
)
// Reject with descriptive error
reject(
new Error(
`VSCE shell integration stream did not start within ${Terminal.getShellIntegrationTimeout() / 1000} seconds.`,
),
)
reject(new Error(`VSCE shell integration stream did not start within ${timeoutSeconds} seconds.`))
}, Terminal.getShellIntegrationTimeout())
// Clean up timeout if stream becomes available
@ -222,6 +223,9 @@ export class TerminalProcess extends BaseTerminalProcess {
const inspectPreOutput = inspect(preOutput, { colors: false, breakLength: Infinity })
console.error(`[Terminal Process] ${errorMsg} preOutput: ${inspectPreOutput}`)
console.debug(`[TerminalProcess] Shell integration markers not found in output`)
console.debug(`[TerminalProcess] Output contains: ${this.fullOutput.length} characters`)
console.debug(`[TerminalProcess] Looking for markers: \\x1b]633;C or \\x1b]133;C`)
// Emit no_shell_integration event
this.emit("no_shell_integration", errorMsg)
@ -402,7 +406,19 @@ export class TerminalProcess extends BaseTerminalProcess {
* If both exist, takes the content after the last marker found.
*/
private matchAfterVsceStartMarkers(data: string): string | undefined {
return this.matchVsceMarkers(data, "\x1b]633;C", "\x1b]133;C", undefined, undefined)
const result = this.matchVsceMarkers(data, "\x1b]633;C", "\x1b]133;C", undefined, undefined)
if (result === undefined) {
console.debug(`[TerminalProcess] No start markers found in data (length: ${data.length})`)
// Log first 200 chars of data in a safe way (escape control chars)
// eslint-disable-next-line no-control-regex
const preview = data.substring(0, 200).replace(/\x1b/g, "\\x1b").replace(/\x07/g, "\\x07")
console.debug(`[TerminalProcess] Data preview: ${preview}`)
} else {
console.debug(`[TerminalProcess] Found start markers, extracted ${result.length} characters`)
}
return result
}
/**

View file

@ -436,6 +436,13 @@
"minimum": 1,
"maximum": 200,
"description": "%settings.codeIndex.embeddingBatchSize.description%"
},
"roo-cline.terminalShellIntegrationTimeout": {
"type": "number",
"default": 5000,
"minimum": 1000,
"maximum": 30000,
"description": "Timeout in milliseconds for terminal shell integration initialization. Increase this value if you encounter 'Shell integration initialization sequence was not received' errors in IDEs like Theia (default: 5000ms, range: 1000-30000ms)."
}
}
}