@@ -43,6 +43,7 @@ import { logReportHeader } from '../reporting/report-logging.js';
43
43
import { DynamicProgressLogger } from '../progress/dynamic-progress-logger.js' ;
44
44
import { UserFacingError } from '../utils/errors.js' ;
45
45
import { getRunGroupId } from './grouping.js' ;
46
+ import { executeCommand } from '../utils/exec.js' ;
46
47
47
48
/**
48
49
* Orchestrates the entire assessment process for each prompt defined in the `prompts` array.
@@ -108,6 +109,9 @@ export async function generateCodeAndAssess(options: {
108
109
109
110
logReportHeader ( env , promptsToProcess . length , appConcurrency , options ) ;
110
111
112
+ // We need Chrome to collect runtime information.
113
+ await installChrome ( ) ;
114
+
111
115
if (
112
116
options . startMcp &&
113
117
env . mcpServerOptions . length &&
@@ -647,6 +651,24 @@ function getCandidateExecutablePrompts(
647
651
return result . filter ( ( { name } ) => name . includes ( promptFilter ) ) ;
648
652
}
649
653
654
+ let chromeInstallPromise : Promise < unknown > | null = null ;
655
+
656
+ /** Installs Chrome which is necessary for runtime checks. */
657
+ async function installChrome ( ) : Promise < void > {
658
+ // Ensure that Chrome is installed. Note that the
659
+ // installation is global so we can reuse the promise.
660
+ if ( ! chromeInstallPromise ) {
661
+ chromeInstallPromise = executeCommand (
662
+ 'npx puppeteer browsers install chrome' ,
663
+ process . cwd ( )
664
+ ) ;
665
+ }
666
+
667
+ try {
668
+ await chromeInstallPromise ;
669
+ } catch { }
670
+ }
671
+
650
672
/**
651
673
* Shuffles the elements of an array randomly in place.
652
674
*
0 commit comments