You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(commands): add heredoc and locale-quote support to command parser; fix pattern extractor
- parseCommand: mask heredocs (<<, <<-, all delimiter quoting styles) as single
atomic tokens before newline splitting; unterminated heredocs returned as opaque token
- parseCommand: add locale-quote ($"...") support alongside existing ANSI-C ($'...')
- findUnterminatedQuote: extend QuoteType with "locale" and "heredoc" variants
- extractPatternsFromCommand (webview): pre-split via parseCommand before shell-quote
tokenization, preventing spurious EOF/body-line/operator tokens in allow/deny selector
- Update changeset to cover all three fix areas
Copy file name to clipboardExpand all lines: .changeset/fix-multiline-quoted-command-parsing.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,16 @@
2
2
"zoo-code": patch
3
3
---
4
4
5
-
Fix command auto-approval for a single command that wraps a multi-line script in a quoted argument (e.g. `sh -c '...'`). The parser previously split on every newline before handling quotes, so newlines inside a quoted argument were treated as separate commands, which defeated allowlist auto-approval and produced a noisy command-pattern breakdown. Single-quoted and ANSI-C (`$'...'`) strings are now masked correctly so embedded newlines and operators stay within their command. Genuine unquoted newlines still split into separate sub-commands, each of which must be allowlisted for auto-approval. Quote masking is comment-aware: a quote character inside a `#` comment is not paired with a quote on a later line, so a comment cannot hide a real newline separator and merge two distinct commands. Commands with an unterminated quote (a shell syntax error, common in LLM-generated commands with nested quotes) are detected with a quote-aware scanner and returned as a single opaque token, so a line intended to live inside the unclosed quote cannot surface as an independently auto-approvable command.
5
+
Fix command auto-approval for multi-line shell constructs that must be treated as a single command.
6
+
7
+
**Quoted multi-line arguments** (`sh -c '...'`, `sh -c $'...'`, `sh -c "..."`): the parser previously split on every newline before handling quotes, so newlines inside a quoted argument were treated as separate commands, defeating allowlist auto-approval. Single-quoted, ANSI-C (`$'...'`), and double-quoted strings are now masked before the newline split so embedded newlines and operators stay within their command.
8
+
9
+
**Heredocs** (`<< EOF`, `<< 'EOF'`, `<< "EOF"`, `<<- EOF`): the entire heredoc -- opener line, body, and terminator -- is now treated as a single quoted region. Body lines are not split into independent sub-commands. All heredoc delimiter quoting styles (unquoted, single-quoted, double-quoted, backslash-escaped) are supported. An unterminated heredoc (missing terminator) is treated as malformed and returned as a single opaque token.
10
+
11
+
**Locale quoting** (`$"..."`): treated as a distinct token analogous to ANSI-C quoting, preserving the `$` prefix and preventing the double-quote handler from stripping it.
12
+
13
+
Quote masking is comment-aware: a quote character inside a `#` comment is not paired with a quote on a later line, so a comment cannot hide a real newline separator and merge two distinct commands. Commands with an unterminated quote are detected with a quote-aware scanner and returned as a single opaque token, preventing a line inside the unclosed quote from surfacing as an independently auto-approvable command. Genuine unquoted newlines still split into separate sub-commands, each of which must be allowlisted for auto-approval.
14
+
15
+
**Pattern selector (UI)**: the command pattern breakdown shown after execution now uses the same heredoc- and quote-aware parser (`parseCommand`) before extracting patterns, so an unterminated or terminated heredoc no longer produces spurious tokens like `EOF`, body-line words, or `<<` fragments in the allow/deny selector.
6
16
7
17
Note: this change only prevents *auto-approval* of fragments from a malformed command; it does not reject malformed commands before execution, which will be addressed in a separate PR to keep the scope focused here.
0 commit comments