mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-11 22:51:26 +00:00
fix: allow background terminals to broadcast output across tasks
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>
This commit is contained in:
parent
0b4fa0b1d6
commit
e3adee4f15
3 changed files with 65 additions and 13 deletions
|
|
@ -3503,8 +3503,15 @@ export class Cline {
|
|||
details += "\n(No open tabs)"
|
||||
}
|
||||
|
||||
const busyTerminals = TerminalRegistry.getTerminals(true, this.taskId)
|
||||
const inactiveTerminals = TerminalRegistry.getTerminals(false, this.taskId)
|
||||
// Get task-specific and background terminals
|
||||
const busyTerminals = [
|
||||
...TerminalRegistry.getTerminals(true, this.taskId),
|
||||
...TerminalRegistry.getBackgroundTerminals(true),
|
||||
]
|
||||
const inactiveTerminals = [
|
||||
...TerminalRegistry.getTerminals(false, this.taskId),
|
||||
...TerminalRegistry.getBackgroundTerminals(false),
|
||||
]
|
||||
|
||||
if (busyTerminals.length > 0 && this.didEditFile) {
|
||||
await delay(300) // delay after saving file to let terminals catch up
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export class Terminal {
|
|||
*/
|
||||
public shellExecutionComplete(exitDetails: ExitCodeDetails): void {
|
||||
this.running = false
|
||||
this.busy = false
|
||||
|
||||
if (this.process) {
|
||||
// Add to the front of the queue (most recent first)
|
||||
|
|
@ -106,16 +107,7 @@ export class Terminal {
|
|||
* or don't belong to the current task
|
||||
*/
|
||||
public cleanCompletedProcessQueue(): void {
|
||||
// If this terminal has no task ID, it's not associated with any active task
|
||||
// In this case, we should remove all processes to prevent their output from appearing
|
||||
// in any task's context
|
||||
if (this.taskId === undefined) {
|
||||
this.completedProcesses = []
|
||||
return
|
||||
}
|
||||
|
||||
// If the terminal is associated with a task, keep only processes with unretrieved output
|
||||
// This ensures that when a task is active, it only sees output from its own processes
|
||||
// Keep only processes with unretrieved output
|
||||
this.completedProcesses = this.completedProcesses.filter((process) => process.hasUnretrievedOutput())
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +121,32 @@ export class Terminal {
|
|||
return [...this.completedProcesses]
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all unretrieved output from both active and completed processes
|
||||
* @returns Combined unretrieved output from all processes
|
||||
*/
|
||||
public getUnretrievedOutput(): string {
|
||||
let output = ""
|
||||
|
||||
// First check completed processes to maintain chronological order
|
||||
for (const process of this.completedProcesses) {
|
||||
const processOutput = process.getUnretrievedOutput()
|
||||
if (processOutput) {
|
||||
output += processOutput
|
||||
}
|
||||
}
|
||||
|
||||
// Then check active process for most recent output
|
||||
const activeOutput = this.process?.getUnretrievedOutput()
|
||||
if (activeOutput) {
|
||||
output += activeOutput
|
||||
}
|
||||
|
||||
this.cleanCompletedProcessQueue()
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
public runCommand(command: string): TerminalProcessResultPromise {
|
||||
this.busy = true
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ export class TerminalRegistry {
|
|||
if (!terminal) {
|
||||
return ""
|
||||
}
|
||||
return terminal.process ? terminal.process.getUnretrievedOutput() : ""
|
||||
return terminal.getUnretrievedOutput()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -190,6 +190,33 @@ export class TerminalRegistry {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets background terminals (taskId undefined) that have unretrieved output or are still running
|
||||
* @param busy Whether to get busy or non-busy terminals
|
||||
* @returns Array of Terminal objects
|
||||
*/
|
||||
/**
|
||||
* Gets background terminals (taskId undefined) filtered by busy state
|
||||
* @param busy Whether to get busy or non-busy terminals
|
||||
* @returns Array of Terminal objects
|
||||
*/
|
||||
static getBackgroundTerminals(busy?: boolean): Terminal[] {
|
||||
return this.getAllTerminals().filter((t) => {
|
||||
// Only get background terminals (taskId undefined)
|
||||
if (t.taskId !== undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If busy is undefined, return all background terminals
|
||||
if (busy === undefined) {
|
||||
return t.getProcessesWithOutput().length > 0 || t.process?.hasUnretrievedOutput()
|
||||
} else {
|
||||
// Filter by busy state
|
||||
return t.busy === busy
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static cleanup() {
|
||||
this.disposables.forEach((disposable) => disposable.dispose())
|
||||
this.disposables = []
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue