dev, start, and preview stream one schema-1 frame per lifecycle transition. Each frame is a complete result envelope on its own line.
Turning the stream on
The stream keys off theEXTENSION_OUTPUT environment variable. Set it to json or ndjson and frames own stdout:
Frame statuses
Every frame’s
value carries the session identity: command, browser, distPath, pid, port, plus readyPath, eventsPath, runId, instanceId, and toolchainVersion when known.
Compile failures
Acompile-failed frame carries the compiler output inside value.output, so you never scrape stdout. The output is ANSI-stripped and capped at 2000 characters. When the cap cuts it, the frame sets truncated: true.
The first failure of a session uses code E_FIRST_COMPILE, every later one uses E_COMPILE.
Ready follows the contract
Theready frame reads ready.json before it fires. A compile can succeed while the browser refuses the extension, and the contract stays in error when that happens.
In that case the stream emits a failed frame with code E_READY_ERROR_STATUS instead, and value.readyCode names the contract’s own error code.
Browser exits
A background watcher pollsready.json once per second for the launcher’s exit stamp. When browserExitedAt appears, the stream emits one browser-exited frame.
The frame’s code depends on the evidence in the contract:
E_PROFILE_LOCKEDwhen the contract shows a locked profile. The browser never started, another session holds the profile.E_BROWSER_LAUNCHfor every other unexpected exit.
value carries exitCode and browserExitedAt when the contract has them.
Next steps
- Read the contract behind the frames in ready.json.
- Drive the whole loop from an agent with Driving the CLI.

