-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
What specific problem does this solve?
Additional context (optional)
No response
Roo Code Task Links (Optional)
No response
Request checklist
- I've searched existing Issues and Discussions for duplicates
- This describes a specific problem with clear impact and context
Interested in implementing this?
- Yes, I'd like to help implement this feature
Implementation requirements
- I understand this needs approval before implementation begins
How should this be solved? (REQUIRED if contributing, optional otherwise)
1. Desired Behavior
When the AI generates a command that spans multiple lines, Roo should intelligently convert it into a single, functionally identical line before execution. The end user should experience the exact same outcome as if they had pasted the original multiline command directly into a terminal, with the exception of unconvertible cases like Here Documents.
2. General Approach
The core of this feature is a pre-execution parsing and transformation step. Roo will analyze the complete, AI-generated command block and apply a series of shell-specific rules to flatten it. This process must be aware of the user's target shell (POSIX-like vs. PowerShell) to apply the correct syntax.
The transformation will follow these general principles:
-
Concatenate Simple Continuations: Lines explicitly continued with an escape character (
\
or ```) or an operator (|
, `&&`, `||`) will be joined together. -
Flatten Compound Commands: For control structures like loops, conditionals, and command groupings (
(...)
,{...}
), required newlines will be replaced with the appropriate command separator (almost always a semicolon;
). -
Convert Multiline Strings: String literals that span multiple lines will be converted into a valid single-line equivalent. This involves replacing physical newlines with their escaped counterparts (e.g.,
\n
or ``n`). The most complex part of this is safely handling strictly literal single-quoted strings by converting them to a type that supports escape sequences. -
Identify and Bypass Unconvertible Cases: If the command uses a structure that cannot be converted to a single line (e.g., a Here Document), the transformation will be aborted, and the command will be executed in its original multiline form.
3. Platform-Specific Implementation
POSIX Shells (bash, zsh)
These shells share a common syntax for multiline commands. The transformation logic will proceed as follows:
-
Continuation Characters: If a line ends with a backslash (
\
), the backslash and newline are removed to join the lines. If a line ends with a pipe (|
) or a logical operator (&&
,||
), the newline character is simply removed. -
Compound Commands: For structures like
if...fi
,for...do...done
,while...do...done
, and command groupings in parentheses(...)
or braces{...}
, newlines separating commands within the block will be replaced with a semicolon (;
). -
String Conversion:
-
Double-Quoted (
"..."
) and ANSI-C Quoted ($'...'
) Strings: Physical newlines within the string will be replaced with the literal escape sequence\n
. -
Single-Quoted (
'...'
) Strings: These are strictly literal and require conversion. A multiline single-quoted string will be transformed into an ANSI-C quoted string ($'...'
) using the following steps:-
Prepend a
$
to the opening'
. -
Within the string content, replace every literal backslash
\
with an escaped backslash\\
. -
Replace every physical newline with the literal escape sequence
\n
.
-
-
Note on fish
Shell
The fish
shell follows the same general principles as bash
and zsh
but uses different keywords for its compound commands. The logic for semicolon replacement is identical, but the parser must recognize that blocks are terminated with the end
keyword (e.g., if...end
, for...end
) instead of fi
or done
.
Windows PowerShell (pwsh)
PowerShell has a distinct syntax that requires its own transformation logic.
-
Continuation Characters: If a line ends with a backtick (```), the backtick and newline are removed to join the lines. PowerShell also implicitly continues a line if it ends with a pipe (
|
), a comma (`,`), or an operator (e.g., `-and`, `+`, `-eq`). In these cases, the newline character is simply removed. -
Compound Commands: For script blocks enclosed in braces (
{...}
) and sub-expressions in parentheses(...)
, such as inforeach
loops orif
statements, newlines separating commands will be replaced with a semicolon (;
). -
String Conversion:
-
Double-Quoted (
"..."
) Strings: Physical newlines will be replaced with the literal escape sequence ``n`. -
Single-Quoted (
'...'
) Strings: These are strictly literal and must be safely converted to an expandable, double-quoted string. This is a sensitive operation to prevent accidental variable expansion.-
First, process the raw string content that was inside the single quotes. Replace any escaped single quotes (
''
) with a single literal apostrophe ('
). -
Escape all characters that have special meaning inside a PowerShell double-quoted string:
-
$
becomes ``$` -
``` becomes ` ``
-
"
becomes ``"`
-
-
Replace every physical newline with the literal escape sequence ``n`.
-
Finally, wrap the fully escaped and converted content in double quotes (
"
).
-
-
How will we know it works? (Acceptance Criteria - REQUIRED if contributing, optional otherwise)
This PR must include a comprehensive testing suite for a huge number of weird terminal command formatting edge cases, as there are many, and it has to do so by emulating unix,
with a good tesitng suite, it should be easy to verify success — you just check that before and after this change, the terminal command executes in the same way.
Technical considerations (REQUIRED if contributing, optional otherwise)
We should consider at what stage of terminal execution this change is applied. which of these 3 is it?
- editing roo's output directly to change the context we move forward with?
- not doing the above, but showing the terminal command as the edited version in roo's UI
- showing the original command roo outputted in its UI, but then executing the one-line-ified version. [My personal recommendation]
Trade-offs and risks (REQUIRED if contributing, optional otherwise)
Minimal upside and VERY easy for a bug to be missed (hopefully good testing mitigates this risk). I'm also not sure if this is necessary on windows, as i'm on macos, so it could be overcomplicating things for them.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status