@@ -43,6 +43,7 @@ import { logReportHeader } from '../reporting/report-logging.js';
4343import { DynamicProgressLogger } from '../progress/dynamic-progress-logger.js' ;
4444import { UserFacingError } from '../utils/errors.js' ;
4545import { getRunGroupId } from './grouping.js' ;
46+ import { executeCommand } from '../utils/exec.js' ;
4647
4748/**
4849 * Orchestrates the entire assessment process for each prompt defined in the `prompts` array.
@@ -108,6 +109,9 @@ export async function generateCodeAndAssess(options: {
108109
109110 logReportHeader ( env , promptsToProcess . length , appConcurrency , options ) ;
110111
112+ // We need Chrome to collect runtime information.
113+ await installChrome ( ) ;
114+
111115 if (
112116 options . startMcp &&
113117 env . mcpServerOptions . length &&
@@ -647,6 +651,24 @@ function getCandidateExecutablePrompts(
647651 return result . filter ( ( { name } ) => name . includes ( promptFilter ) ) ;
648652}
649653
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+
650672/**
651673 * Shuffles the elements of an array randomly in place.
652674 *
0 commit comments