66 * found in the LICENSE file at https://angular.dev/license 
77 */ 
88
9- import  {  existsSync  }  from  'fs' ; 
10- import  {  stat  }  from  'fs/promises' ; 
119import  {  dirname ,  join ,  relative  }  from  'path' ; 
1210import  {  z  }  from  'zod' ; 
13- import  {  execAsync   }  from  './process-executor ' ; 
11+ import  {  CommandError ,   Host ,   LocalWorkspaceHost   }  from  '../host ' ; 
1412import  {  McpToolDeclaration ,  declareTool  }  from  './tool-registry' ; 
1513
1614interface  Transformation  { 
@@ -102,10 +100,10 @@ function createToolOutput(structuredContent: ModernizeOutput) {
102100  } ; 
103101} 
104102
105- function  findAngularJsonDir ( startDir : string ) : string  |  null  { 
103+ function  findAngularJsonDir ( startDir : string ,   host :  Host ) : string  |  null  { 
106104  let  currentDir  =  startDir ; 
107105  while  ( true )  { 
108-     if  ( existsSync ( join ( currentDir ,  'angular.json' ) ) )  { 
106+     if  ( host . existsSync ( join ( currentDir ,  'angular.json' ) ) )  { 
109107      return  currentDir ; 
110108    } 
111109    const  parentDir  =  dirname ( currentDir ) ; 
@@ -116,7 +114,7 @@ function findAngularJsonDir(startDir: string): string | null {
116114  } 
117115} 
118116
119- export  async  function  runModernization ( input : ModernizeInput )  { 
117+ export  async  function  runModernization ( input : ModernizeInput ,   host :  Host )  { 
120118  const  transformationNames  =  input . transformations  ??  [ ] ; 
121119  const  directories  =  input . directories  ??  [ ] ; 
122120
@@ -138,9 +136,9 @@ export async function runModernization(input: ModernizeInput) {
138136  } 
139137
140138  const  firstDir  =  directories [ 0 ] ; 
141-   const  executionDir  =  ( await  stat ( firstDir ) ) . isDirectory ( )  ? firstDir  : dirname ( firstDir ) ; 
139+   const  executionDir  =  ( await  host . stat ( firstDir ) ) . isDirectory ( )  ? firstDir  : dirname ( firstDir ) ; 
142140
143-   const  angularProjectRoot  =  findAngularJsonDir ( executionDir ) ; 
141+   const  angularProjectRoot  =  findAngularJsonDir ( executionDir ,   host ) ; 
144142  if  ( ! angularProjectRoot )  { 
145143    return  createToolOutput ( { 
146144      instructions : [ 'Could not find an angular.json file in the current or parent directories.' ] , 
@@ -164,9 +162,12 @@ export async function runModernization(input: ModernizeInput) {
164162      // Simple case, run the command. 
165163      for  ( const  dir  of  directories )  { 
166164        const  relativePath  =  relative ( angularProjectRoot ,  dir )  ||  '.' ; 
167-         const  command  =  `ng generate @angular/core:${ transformation . name } ${ relativePath }  ; 
165+         const  command  =  'ng' ; 
166+         const  args  =  [ 'generate' ,  `@angular/core:${ transformation . name }  ,  '--path' ,  relativePath ] ; 
168167        try  { 
169-           const  {  stdout,  stderr }  =  await  execAsync ( command ,  {  cwd : angularProjectRoot  } ) ; 
168+           const  {  stdout,  stderr }  =  await  host . runCommand ( command ,  args ,  { 
169+             cwd : angularProjectRoot , 
170+           } ) ; 
170171          if  ( stdout )  { 
171172            stdoutMessages . push ( stdout ) ; 
172173          } 
@@ -177,6 +178,14 @@ export async function runModernization(input: ModernizeInput) {
177178            `Migration ${ transformation . name } ${ relativePath }  , 
178179          ) ; 
179180        }  catch  ( e )  { 
181+           if  ( e  instanceof  CommandError )  { 
182+             if  ( e . stdout )  { 
183+               stdoutMessages . push ( e . stdout ) ; 
184+             } 
185+             if  ( e . stderr )  { 
186+               stderrMessages . push ( e . stderr ) ; 
187+             } 
188+           } 
180189          stderrMessages . push ( ( e  as  Error ) . message ) ; 
181190          instructions . push ( 
182191            `Migration ${ transformation . name } ${ relativePath }  , 
@@ -228,5 +237,5 @@ ${TRANSFORMATIONS.map((t) => `  * ${t.name}: ${t.description}`).join('\n')}
228237  outputSchema : modernizeOutputSchema . shape , 
229238  isLocalOnly : true , 
230239  isReadOnly : false , 
231-   factory : ( )  =>  runModernization , 
240+   factory : ( )  =>  ( input )   =>   runModernization ( input ,   LocalWorkspaceHost ) , 
232241} ) ; 
0 commit comments