dev, start, preview, and build run writes dist/extension-js/<browser>/ready.json atomically on each compile. The current contract is schemaVersion: 2.
Statuses
Two-phase readiness
status: "ready" means compiled, nothing more. The browser may still be launching, and the service worker may not be connected yet.
Act tooling (eval, storage, reload, open, inspect) needs the second phase. Wait until the contract carries runtime: "attached" and an executorAttachedAt timestamp before you drive the extension.
The attach stamp is idempotent and survives recompiles. An attach also clears any earlier extension_load_refused state, because the executor runs inside the guest.
Field reference (schema v2)
Fields that are always present:
Fields that appear when known:
Error states
Thecode field names the failure class. Three codes matter for automation:
A load refusal outlives the next successful compile. Only a new run (
starting) or a real executor attach clears it.
Waiting with —wait
extension dev --wait and extension start --wait poll the contract every 250 ms and exit when it reports ready. Pair them with --output json for a machine result.
The wait loop refuses to trust stale files. Three checks run on every read:
- The
commandfield must match the waiting command. - The
pidmust be alive. Fordev, a dead producer always means stale, so polling continues. - For
start, a dead pid is accepted only when the contract is fresh. Freshness meansts,compiledAt, orstartedAtis within the last 60 seconds.
E_READY_TIMEOUT. A contract in error status fails the wait with its message.
Joining the session files
The same directory holdsevents.ndjson (compile timeline) and logs.ndjson (extension console output). Every row in both carries the runId from ready.json.
events.ndjson is truncated at every run start, so it only ever describes the current run. Event types are compile_start, compile_success, compile_error, and shutdown.
Example
Next steps
- Read command results with the Result envelope.
- Stream the same session as frames with the Lifecycle stream.
- Wire the whole loop into tests with Playwright E2E.

