v5.1.0
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: truealone
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 aslogPath) instead of pipes. A detached
session outlives the MCP and a fresh MCP process rediscovers it through
ready.jsonand can stop it. Pinned by a detach-contract test. extension_previewno longer reportslaunchedfor a process that died
in seconds. It health-checks the child likedev/start(the MCP half of
engine bug 72), and all three launch tools read the engine's new
browser_exitedstamp, so a browser that dies after launch (for example a
rejected add-on) returnsstatus:"browser-exited"instead of success.extension_doctornames a dead browser. Abrowser_exitedready
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_createverifies the scaffold. A resolved create over a
partial tree (an interrupted template download) returnednextSteps
pointing at a project that could not compile. It now checks the manifest
exists and returnsstatus:"incomplete"when it does not.extension_manifest_validateis per-target honest.chromium:/
firefox:prefixed keys resolve per target,edgejoins the default
matrix,manifest_versionmust be 2 or 3, adefault_localewithout its
_localescatalog blocks, and a missing 128px store icon warns
(extension_inspectreportshas128Icon).- Stale state stops being served as live.
extension_logsstamps
stale:truewhen the producing session is dead or from a different run;
extension_waitreturnsruntimeErrorsalongside ready instead of a bare
green over a crashing worker;extension_buildreports
productionDivergencewhen the production manifest lost permissions or
resources relative to source. extension_open'sasTabfallback fires on the user-gesture wall, and
extension_storageset without akeyanswers in MCP vocabulary rather
than CLI flags.
Added
- Structured bundler warnings on
extension_build. The engine now
persists its build summary todist/extension-js/<browser>/ build-summary.json(the transport half of engine bug 73), and the tool
returns it asbuildWarnings(withbuildWarningsTruncatednaming 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 asrenderedAsTab.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 acceptsBrowser.setWindowBoundsand changes nothing, so
headless sessions get the honest fallback, not a resized window. The
measurement also leavesbody'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 typecheckcoverssrc/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_evaland
extension_dom_inspectnow 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_buildrefuses a broken build. It runs the
extension_manifest_validatechecks as a preflight and returns
status:"blocked"on build-blocking errors instead of shelling out to a build
it knows is broken. PassskipValidation: truefor the old behavior. It also
returnssuccess:falsewithstatus:"incomplete"when the bundler exits 0 but
a declared entrypoint never reacheddist/, because the browser refuses to
load that artifact. Non-blocking findings ride along asmanifestWarnings.- Browser resolution defaults to
chrome, notchromium. 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 withsource:"stale". extension_openrenamestabtotarget. The value is a CDP target id,
not achrome.tabsid, and the old name invited callers to pass it straight
into tools that need a numeric tab id.
Fixed
extension_doctorno longer reportshealthy:trueover a crashing
extension. Its runtime-error check read the wrong field, so every error row
inlogs.ndjsoncollapsed to an empty string and was skipped. It now reads the
engine'smessagePartspayload, with anerrorName/stackfallback, and
collapses a throw that repeats on every event.extension_devandextension_startno longer reportstatus:"started"
for a server that already exited. Both health-check the child process and
returnstatus:"exited"with the exit code, signal, and the child's own output
as evidence.extension_openno longer reports success for a navigation that failed.
Navigating to achrome-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 theurlnavigation path shipped in 4.9.0, not only the new
surface rendering.extension_opentargets 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_openacceptsasTabfor
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_evalandextension_dom_inspecttake a
urland otherwise default to the active tab, andextension_dom_inspect
gainslistTabsfor 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,hrefand
browserNamefold onto their canonical names,withConsoleacceptstrue,
and the input validator understands union types. extension_creatematches 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.