@@ -28,8 +28,17 @@ process.on("exit", (code) => {
2828 NodeFS . rmSync ( runningMarker , { force : true } ) ;
2929} ) ;
3030// A cancelled setup must still leave a marker, or agents would wait forever.
31+ // During install, the signal goes on to the installer and setup exits when the
32+ // install output closes. Any child the shell leaves behind holds that output
33+ // open, so no marker appears while `vp i` can still write node_modules.
34+ let cancelSignal : NodeJS . Signals | undefined ;
35+ let activeInstall : NodeChildProcess . ChildProcess | undefined ;
3136for ( const signal of [ "SIGINT" , "SIGTERM" , "SIGHUP" ] as const ) {
32- process . on ( signal , ( ) => process . exit ( 1 ) ) ;
37+ process . on ( signal , ( ) => {
38+ cancelSignal = signal ;
39+ if ( activeInstall ) activeInstall . kill ( signal ) ;
40+ else process . exit ( 1 ) ;
41+ } ) ;
3342}
3443
3544const projectRoot = process . env . T3CODE_PROJECT_ROOT ;
@@ -48,6 +57,7 @@ const install = NodeChildProcess.spawn("vp i --frozen-lockfile -- --yes", {
4857 shell : true ,
4958 stdio : [ "ignore" , "pipe" , "pipe" ] ,
5059} ) ;
60+ activeInstall = install ;
5161let installOutput = "" ;
5262for ( const [ source , target ] of [
5363 [ install . stdout , process . stdout ] ,
@@ -60,9 +70,12 @@ for (const [source, target] of [
6070 } ) ;
6171}
6272const installStatus = await new Promise < number | null > ( ( resolve ) => install . on ( "close" , resolve ) ) ;
63- if ( installStatus !== 0 ) {
64- failureDetail = installOutput . trimEnd ( ) . split ( "\n" ) . slice ( - 30 ) . join ( "\n" ) ;
65- process . exit ( installStatus ?? 1 ) ;
73+ activeInstall = undefined ;
74+ if ( installStatus !== 0 || cancelSignal ) {
75+ failureDetail = cancelSignal
76+ ? `Cancelled by ${ cancelSignal } .`
77+ : installOutput . trimEnd ( ) . split ( "\n" ) . slice ( - 30 ) . join ( "\n" ) ;
78+ process . exit ( installStatus || 1 ) ;
6679}
6780
6881// pnpm cannot clone or hardlink across filesystems, so a store on another
8295 ` worktree: ${ worktree } ` ,
8396 "pnpm cannot hardlink or clone across filesystems, so it copied every package into node_modules." ,
8497 "Fix: put the store on the worktree's filesystem, for example:" ,
85- ` pnpm config set store-dir ${ NodePath . join ( NodePath . dirname ( worktree ) , ".pnpm-store" ) } --global` ,
98+ ` pnpm config set store-dir ${ JSON . stringify ( NodePath . join ( NodePath . dirname ( worktree ) , ".pnpm-store" ) ) } --global` ,
8699 "" ,
87100 "" ,
88101 ] . join ( "\n" ) ,
0 commit comments