@@ -2,6 +2,7 @@ import { parse } from "shell-quote"
22
33type ShellToken = string | { op : string } | { command : string }
44
5+ // kilocode_change start
56/**
67 * Placeholders used to protect newlines within quoted strings during command parsing.
78 * These constants are used by the protectNewlinesInQuotes function to temporarily replace
@@ -10,6 +11,7 @@ type ShellToken = string | { op: string } | { command: string }
1011 */
1112export const NEWLINE_PLACEHOLDER = "___NEWLINE___"
1213export const CARRIAGE_RETURN_PLACEHOLDER = "___CARRIAGE_RETURN___"
14+ // kilocode_change end
1315
1416/**
1517 * # Command Denylist Feature - Longest Prefix Match Strategy
@@ -131,6 +133,7 @@ export function containsDangerousSubstitution(source: string): boolean {
131133 )
132134}
133135
136+ // kilocode_change start
134137/**
135138 * Protect newlines inside quoted strings by replacing them with placeholders.
136139 * This handles proper shell quoting rules where quotes can be concatenated.
@@ -223,7 +226,9 @@ export function protectNewlinesInQuotes(
223226
224227 return result
225228}
229+ // kilocode_change end
226230
231+ // kilocode_change start added exception for quoted newlines
227232/**
228233 * Split a command string into individual sub-commands by
229234 * chaining operators (&&, ||, ;, |, or &) and newlines.
@@ -235,16 +240,19 @@ export function protectNewlinesInQuotes(
235240 * - Chain operators (&&, ||, ;, |, &)
236241 * - Newlines as command separators (but not within quotes)
237242 */
243+ //kilocode_change end
238244export function parseCommand ( command : string ) : string [ ] {
239245 if ( ! command ?. trim ( ) ) return [ ]
240246
247+ // kilocode_change start
241248 // First, protect newlines inside quoted strings by replacing them with placeholders
242249 // This prevents splitting multi-line quoted strings (e.g., git commit -m "multi\nline")
243250 const protectedCommand = protectNewlinesInQuotes ( command , NEWLINE_PLACEHOLDER , CARRIAGE_RETURN_PLACEHOLDER )
244251
245252 // Split by newlines (handle different line ending formats)
246253 // This regex splits on \r\n (Windows), \n (Unix), or \r (old Mac)
247254 const lines = protectedCommand . split ( / \r \n | \r | \n / )
255+ // kilocode_change end
248256 const allCommands : string [ ] = [ ]
249257
250258 for ( const line of lines ) {
@@ -256,12 +264,14 @@ export function parseCommand(command: string): string[] {
256264 allCommands . push ( ...lineCommands )
257265 }
258266
267+ // kilocode_change start
259268 // Restore newlines and carriage returns in quoted strings
260269 return allCommands . map ( ( cmd ) =>
261270 cmd
262271 . replace ( new RegExp ( NEWLINE_PLACEHOLDER , "g" ) , "\n" )
263272 . replace ( new RegExp ( CARRIAGE_RETURN_PLACEHOLDER , "g" ) , "\r" ) ,
264273 )
274+ // kilocode_change end
265275}
266276
267277/**
0 commit comments