Skip to content

v5.1.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 20:02
· 224 commits to main since this release

The engine closed its entire open bug range (Extension.js 61-73) in the
4.0.14 canary line. This release re-aligns the MCP with the fixed engine,
finishes the MCP-side half of those bugs, and continues the
report-failure-not-false-success program that 5.0.0 started. 5.0.0 was never
published to npm; installing 5.1.0 picks up both.

Fixed

  • Sessions now genuinely survive the MCP process. detached: true alone
    never did it: the child held pipes to the MCP, so when the MCP exited the
    next compile log line killed the dev server with EPIPE. Launch tools
    (extension_dev/start/preview) now stream the child's output to a
    session log file (returned as logPath) instead of pipes. A detached
    session outlives the MCP and a fresh MCP process rediscovers it through
    ready.json and can stop it. Pinned by a detach-contract test.
  • extension_preview no longer reports launched for a process that died
    in seconds.
    It health-checks the child like dev/start (the MCP half of
    engine bug 72), and all three launch tools read the engine's new
    browser_exited stamp, so a browser that dies after launch (for example a
    rejected add-on) returns status:"browser-exited" instead of success.
  • extension_doctor names a dead browser. A browser_exited ready
    contract now produces a runtime-errors failure that says the browser died,
    with the matching remedy, instead of the generic "fix the build error"
    wording that pointed at a build that was fine.
  • extension_create verifies the scaffold. A resolved create over a
    partial tree (an interrupted template download) returned nextSteps
    pointing at a project that could not compile. It now checks the manifest
    exists and returns status:"incomplete" when it does not.
  • extension_manifest_validate is per-target honest. chromium:/
    firefox: prefixed keys resolve per target, edge joins the default
    matrix, manifest_version must be 2 or 3, a default_locale without its
    _locales catalog blocks, and a missing 128px store icon warns
    (extension_inspect reports has128Icon).
  • Stale state stops being served as live. extension_logs stamps
    stale:true when the producing session is dead or from a different run;
    extension_wait returns runtimeErrors alongside ready instead of a bare
    green over a crashing worker; extension_build reports
    productionDivergence when the production manifest lost permissions or
    resources relative to source.
  • extension_open's asTab fallback fires on the user-gesture wall, and
    extension_storage set without a key answers in MCP vocabulary rather
    than CLI flags.

Added

  • Structured bundler warnings on extension_build. The engine now
    persists its build summary to dist/extension-js/<browser>/ build-summary.json (the transport half of engine bug 73), and the tool
    returns it as buildWarnings (with buildWarningsTruncated naming the
    true count when the engine capped the list). Older engines simply omit the
    field; nothing is scraped from stdout.
  • Popup-faithful headless rendering. A popup rendered as a tab is now
    sized like the real popup: the document's content size is measured over
    CDP, clamped to Chrome's 25x25-800x600 popup bounds, and the window is
    resized to it (reported as renderedAsTab.popupBounds). If the browser
    does not verifiably honor the resize, the tool keeps saying "no popup
    sizing" instead of implying fidelity. Note headless-new is one such
    browser: it accepts Browser.setWindowBounds and changes nothing, so
    headless sessions get the honest fallback, not a resized window. The
    measurement also leaves body's authored width alone; only the root takes
    the temporary fit-content override, so a popup that sizes itself through
    body { width } measures at its real width.
  • CI typechecks the tests. pnpm typecheck covers src/ and the test
    tsconfig, wired into the CI matrix, so type drift between tools and their
    tests cannot accumulate silently again.

Changed

  • Tool prose caught up with the fixed engine. extension_eval and
    extension_dom_inspect now advertise the surface contexts
    (popup/options/sidebar/devtools) and override pages
    (newtab/history/bookmarks) the engine's relay serves, needing no tab
    id. The "content eval is known-broken" guard is version-honest: on
    Extension.js >= 4.0.14 a null is the expression's real result, and the note
    says so instead of condemning a repaired path. Firefox hints name every
    working route.

A pass focused on a single question: when something has gone wrong, does the
tool say so? Five tools were reporting success over a failure. All five now
verify before they claim anything.

Breaking

  • extension_build refuses a broken build. It runs the
    extension_manifest_validate checks as a preflight and returns
    status:"blocked" on build-blocking errors instead of shelling out to a build
    it knows is broken. Pass skipValidation: true for the old behavior. It also
    returns success:false with status:"incomplete" when the bundler exits 0 but
    a declared entrypoint never reached dist/, because the browser refuses to
    load that artifact. Non-blocking findings ride along as manifestWarnings.
  • Browser resolution defaults to chrome, not chromium. A dead session
    used to fall through to a blind default, so every call after a dev server
    exited silently retargeted a browser the caller never ran. A dead session now
    resolves to its own browser with source:"stale".
  • extension_open renames tab to target. The value is a CDP target id,
    not a chrome.tabs id, and the old name invited callers to pass it straight
    into tools that need a numeric tab id.

Fixed

  • extension_doctor no longer reports healthy:true over a crashing
    extension.
    Its runtime-error check read the wrong field, so every error row
    in logs.ndjson collapsed to an empty string and was skipped. It now reads the
    engine's messageParts payload, with an errorName/stack fallback, and
    collapses a throw that repeats on every event.
  • extension_dev and extension_start no longer report status:"started"
    for a server that already exited.
    Both health-check the child process and
    return status:"exited" with the exit code, signal, and the child's own output
    as evidence.
  • extension_open no longer reports success for a navigation that failed.
    Navigating to a chrome-extension:// origin is cross process and swaps the
    render frame, so the pre-navigation session reported a stale error URL on
    success and success on failure. It now confirms against a fresh target list.
    This affected the url navigation path shipped in 4.9.0, not only the new
    surface rendering.
  • extension_open targets the right extension. A dev session also loads
    Extension.js's own manager extension, and taking the first extension target
    navigated against the wrong origin. The id is now derived from the dist path
    the session actually loaded.

Added

  • Headless surface rendering. extension_open accepts asTab for
    popup/options/sidebar, rendering the surface document in a real tab so it
    can be inspected where no window exists to host a popup. It is applied
    automatically when a headless session refuses to open the surface, with a note
    saying what was substituted.
  • Tab targeting by url. extension_eval and extension_dom_inspect take a
    url and otherwise default to the active tab, and extension_dom_inspect
    gains listTabs for discovery. The engine gained this in 4.0.13; the tool
    descriptions had been telling callers a numeric tab id was required.
  • Friendlier arguments. timeoutMs, lines, tabId, href and
    browserName fold onto their canonical names, withConsole accepts true,
    and the input validator understands union types.
  • extension_create matches your package manager. Hints and the engine
    warning now use bun, pnpm or yarn when that is what the scaffold used, and the
    warning reads the pin the scaffold actually wrote.