@@ -85,11 +85,16 @@ export class PackageManagerService {
8585 output = await PackageManagerService . execCommand ( args , dirPath , true ) ;
8686 } catch ( error ) {
8787 // npm returns non-zero exit code when package is not found, but still outputs valid JSON
88- // So we try to use the error as output if it looks like JSON
89- if ( typeof error === "string" && error . trim ( ) . startsWith ( "{" ) ) {
90- output = error ;
88+ if ( typeof error === "string" ) {
89+ try {
90+ // Try to parse as JSON - if successful, use it as output
91+ JSON . parse ( error . trim ( ) ) ;
92+ output = error ;
93+ } catch {
94+ // If it's not valid JSON, the package is not installed
95+ return false ;
96+ }
9197 } else {
92- // If it's not JSON output, the package is not installed
9398 return false ;
9499 }
95100 }
@@ -156,20 +161,24 @@ export class PackageManagerService {
156161 let useShell = false ;
157162
158163 if ( Array . isArray ( args ) ) {
159- // Check if any arg contains shell-specific syntax (redirections, pipes, etc.)
160- // We check if the arg starts/ends with operators or contains operators surrounded by spaces
161- // to avoid false positives with URLs or file paths that might contain these characters
162- const shellOperators = [ ">" , "|" , "&&" , "||" , ";" , "<" , ">>" , "2>" , "&" , "$(" ] ;
163- const hasShellSyntax = args . some ( ( arg ) =>
164- shellOperators . some (
164+ // Shell operators that indicate shell-specific syntax requiring shell mode
165+ // These include redirections (>, <, >>), pipes (|), command chaining (&&, ||, ;),
166+ // background execution (&), and command substitution ($())
167+ const SHELL_OPERATORS = [ ">" , "|" , "&&" , "||" , ";" , "<" , ">>" , "2>" , "&" , "$(" ] ;
168+
169+ // Check if any arg contains shell operators at word boundaries to avoid
170+ // false positives with URLs (e.g., http://example.com?a=1&b=2) or file paths
171+ const hasShellSyntax = args . some ( ( arg ) => {
172+ const trimmedArg = arg . trim ( ) ;
173+ return SHELL_OPERATORS . some (
165174 ( op ) =>
166- arg . trim ( ) . startsWith ( op ) ||
167- arg . trim ( ) . endsWith ( op ) ||
168- arg . includes ( ` ${ op } ` ) ||
169- arg . includes ( ` ${ op } ` ) ||
170- arg . includes ( `${ op } ` )
171- )
172- ) ;
175+ trimmedArg . startsWith ( op ) ||
176+ trimmedArg . endsWith ( op ) ||
177+ trimmedArg . includes ( ` ${ op } ` ) ||
178+ trimmedArg . includes ( ` ${ op } ` ) ||
179+ trimmedArg . includes ( `${ op } ` )
180+ ) ;
181+ } ) ;
173182
174183 if ( hasShellSyntax ) {
175184 // Use shell mode for commands with shell syntax
0 commit comments