@@ -714,6 +714,23 @@ async fn resolve_matching_package_manager_tool(
714714 Ok ( Some ( package_manager_bin_path ( & install_dir, bin_name) ) )
715715}
716716
717+ async fn prepend_js_child_process_path_env (
718+ cwd : & AbsolutePath ,
719+ node_bin_dir : & AbsolutePath ,
720+ ) -> Result < ( ) , Error > {
721+ let _ = prepend_to_path_env ( node_bin_dir, PrependOptions :: default ( ) ) ;
722+
723+ let Some ( npm_path) = resolve_matching_package_manager_tool ( cwd, "npm" ) . await ? else {
724+ return Ok ( ( ) ) ;
725+ } ;
726+ if let Some ( pm_bin_dir) = npm_path. parent ( )
727+ && pm_bin_dir != node_bin_dir
728+ {
729+ let _ = prepend_to_path_env ( pm_bin_dir, PrependOptions :: default ( ) ) ;
730+ }
731+ Ok ( ( ) )
732+ }
733+
717734/// Main shim dispatch entry point.
718735///
719736/// Called when the binary is invoked as node, npm, npx, corepack, or a
@@ -861,7 +878,10 @@ pub async fn dispatch(tool: &str, args: &[String]) -> i32 {
861878 // version was selected from `packageManager`, put that PM bin dir first so
862879 // nested invocations see the same PM version while recursion prevention is set.
863880 let node_bin_dir = node_path. parent ( ) . expect ( "Node has no parent directory" ) ;
864- let _ = prepend_to_path_env ( node_bin_dir, PrependOptions :: default ( ) ) ;
881+ if let Err ( e) = prepend_js_child_process_path_env ( & cwd, node_bin_dir) . await {
882+ eprintln ! ( "vp: Failed to resolve package manager for child process PATH: {e}" ) ;
883+ return 1 ;
884+ }
865885 if let Some ( pm_bin_dir) = tool_path. parent ( )
866886 && pm_bin_dir != node_bin_dir
867887 {
@@ -960,10 +980,15 @@ async fn dispatch_package_binary(tool: &str, args: &[String]) -> i32 {
960980 match ensure_installed ( & node_version) . await {
961981 Ok ( node_path) => {
962982 if let Some ( node_bin_dir) = node_path. parent ( ) {
963- let _ = prepend_to_path_env (
964- node_bin_dir,
965- PrependOptions :: default ( ) ,
966- ) ;
983+ if let Err ( e) =
984+ prepend_js_child_process_path_env ( & cwd, node_bin_dir) . await
985+ {
986+ eprintln ! (
987+ "vp: Failed to resolve package manager for child \
988+ process PATH: {e}"
989+ ) ;
990+ return 1 ;
991+ }
967992 }
968993 }
969994 Err ( e) => {
@@ -1066,7 +1091,13 @@ pub(crate) async fn package_binary_invocation(
10661091 // Prepare environment for recursive invocations
10671092 let node_bin_dir =
10681093 node_path. parent ( ) . ok_or_else ( || "Node has no parent directory" . to_string ( ) ) ?;
1069- let _ = prepend_to_path_env ( node_bin_dir, PrependOptions :: default ( ) ) ;
1094+ if let Ok ( cwd) = current_dir ( ) {
1095+ prepend_js_child_process_path_env ( & cwd, node_bin_dir) . await . map_err ( |e| {
1096+ format ! ( "Failed to resolve package manager for child process PATH: {e}" )
1097+ } ) ?;
1098+ } else {
1099+ let _ = prepend_to_path_env ( node_bin_dir, PrependOptions :: default ( ) ) ;
1100+ }
10701101
10711102 // JS binaries (determined at install time and stored in metadata) run
10721103 // through node; native executables run directly.
0 commit comments