Skip to content

v10.11.0

@github-actions github-actions tagged this 08 Oct 18:24
- The release workflow renders `docs/tools.json` and `docs/clients.json`
  right after it bumps the package version and commits them with the
  release: both files carry the version and the suite asserts the files on
  disk are the current rendering, so the first 10.11.0 run failed its own
  bump.
- The Safari automation hint names the setting the way the engine does: Safari > Settings > Developer > "Allow remote automation", with the Develop menu item on older Safari.

- `extension_dev` carries the control channel by default: `allowControl` defaults to true, so `extension_storage`, `extension_reload`, `extension_open` and `extension_dom_snapshot` work on a plain dev session and a later "reload it" costs no restart; pass `allowControl: false` for a read-only session. `allowEval` stays off until asked and still implies control. The descriptions, the hints, the docs gates, the README and the shipped rules say control is on unless asked off.
- `extension_wait` now says when it is needed (a session started with `wait: false`, a dev answer whose `ready.status` was not ready, a build-only session); `extension_dev`'s answer and the shipped rules say a ready answer ends the run recipe.
- `extension_docs_search`'s description is the trigger: any WebExtension API, manifest key, permission or browser-difference question is answered from the docs first, memory only when nothing matches.
- `extension_build` hands the reading of the output to `extension_analyze` in its hint, and `extension_create` says the scaffold needs no build to verify and names `extension_dev` as the next step.

- The `extension_logs` hint for a Safari session with no log file, the
  README, the rules and the `/extension debug` command name 4.1.21 as the
  Extension.js floor for Safari log streaming in place of 4.1.28, which no
  engine change backed (that number is the `navigate` verb's canary). The
  engine first streamed Safari background and content lines through the
  bridge in v4.1.20 (#533, the webkit background patch that stops Safari
  from skipping the MV3 worker), and v4.1.21 (#566) gave the dev-injected
  background of a project with no background of its own the same shape,
  so 4.1.21 is the first release where every project streams.
- `extension_build` always answers `outputPath`, the folder it checked the
  manifest in: the engine's reported path when the summary carries one, else
  `dist/<browser>` under the package root. On an engine older than the
  summaries contract the field used to be missing and an agent guessed the
  folder. `zipPath` stays beside it when a zip was asked for.
- `extension_create` answers `scripts`: every package.json script the
  scaffolder wrote that runs the engine, with the command, the browser it
  targets and the folder it writes (`npm run build` is flagless, so chromium
  into `dist/chromium`; `build:chrome` into `dist/chrome`; a monorepo
  script's folder is resolved under the package the engine builds). The
  `defaultsApplied.browser` sentence points at that list instead of
  restating it, and the description says to read the folder from there.
- `extension_project_create` defaults the build command to
  `npm run build -- --browser <browser>`, the browser's name per enabled
  browser, in place of `npm run build`: the platform runs the stored command
  as it is and reads `dist/<browser>` afterwards, and a flagless
  `extension build` writes `dist/chromium`, so a default-created project
  produced an empty artifact. `<browser>` in a command of your own is
  replaced the same way `outputDirectory` already did. The description and
  the `buildCommand` input say what the platform does with the command.
- The rules, the `/extension build` command and the `extension_build`,
  `extension_create` and `extension_project_create` descriptions now say
  what the engine does: `extension build` with no `--browser` targets
  chromium and writes `dist/chromium/`, so a scaffolded `npm run build`
  lands there, while `--browser=chrome` and `extension_build` (chrome by
  default) write `dist/chrome/`. The build rule tells the agent to read the
  folder from the build's answer (`outputPath`) instead of assuming
  `dist/chrome/`, which an agent did on 2026-10-08 and got `ls: exit 1`.
- The README and the `extension_create` description now say that a
  successful scaffold sends one `draft_seeded` event to PostHog, what it
  carries, and that `EXTENSION_DEV_NO_TELEMETRY=1` or `DO_NOT_TRACK=1` turns
  it off. Nothing about what is sent changed; a test fails if either text
  stops naming the event or the two variables.
- The Live Preview carrier copy that `extension_dev {carrier: true}` places
  no longer admits `http://localhost/*` or `http://127.0.0.1/*` in its
  `externally_connectable`: on a stranger's machine those ports belong to
  whatever runs there. `EXTENSION_DEV_CARRIER_LOOPBACK=1` on the server
  keeps them for the extension.dev apps' own dev servers; the `carrier`
  description names the permissions the carrier holds and the switch.
- `extension_inspect` no longer sleeps 1.5 s after navigating or 0.5 s when
  it did not navigate: the CDP navigate already waits for the page's load
  event, so both waits read nothing.
- A CDP event listener that throws is reported on stderr with the event
  name instead of being discarded with unparseable frames, and the
  recorded console is kept.
- `extension_list_extensions` connects once to the port the ready contract
  stamped instead of retrying three times 800 ms apart: the port is read
  from a live session's contract, so a refused connection is the answer.
- One JSON frame reader (`src/lib/frame-json.ts`) replaces the two private
  copies in `extension_open` and `extension_eval`.

- The server starts with the local group alone: the 23 of its 32 tools that
  work on this machine. The 9 platform tools (account, share, release and
  store) come on with `--features=local,platform` or
  `EXTENSION_DEV_FEATURES=local,platform` while the platform is in private
  alpha. The Connect recipes name both groups for the two reaches that need
  the platform. The README moves signing in, sharing and the store lane
  under one Platform heading.
- `scripts/live-lane.mjs` drives the real server and the real pinned engine
  per browser, headless, through create, build, dev, wait, logs, list,
  open, dom snapshot, eval, storage, reload, assert and stop, and writes a
  verdict table. On 2026-10-07 it passed on Chrome, Edge, Firefox, Brave,
  Opera, Vivaldi, Yandex, Waterfox, Zen and Floorp. LibreWolf refuses to
  launch until its overrides file turns remote debugging on, so it is no
  longer listed as a dev browser (the `browser` enum still accepts it).
- The build test fixtures feed the engine's own `--output json` envelope on
  stdout and its narration on stderr instead of prose the engine never
  prints; the Safari webdriver seed names the 4.1.32 writer it copies; the
  Gecko assert cells run the real list-tabs reader on the engine's tab
  rows; `extension_reload` has its own test.
- The package lints with the console's rules: eslint-config-auditor's
  recommended and typescript presets, the house style plugin (blank lines
  between statements, curly, banner-aware header rules, no JSDoc prose),
  consistent type imports and the migration warnings, with the React and
  Tailwind layers left out. Every source file was reformatted by the fixer;
  no behaviour changed.
- `extension_reload` of the background waits, bounded, for the engine's
  `ready.json` to stamp the executor detached and attached again, and
  reports `reattachedMs`, `detachedAt` and `attachedTs`; when the new
  background has not connected within the budget it answers `reloading`
  with a warning instead of `reloaded`. Before this the engine answered
  `reloading` 50 ms before the old background died, and a read landing in
  the detach-to-reattach gap (measured 11 to 129 ms on Zen and Floorp) got
  "the control channel did not answer". `extension_assert` names that gap
  when its Gecko read lands in it. Zen and Floorp pass the live lane 5 of 5.
- `@modelcontextprotocol/sdk` moves to 1.32.1, past GHSA-6qxp-vccf-f47h
  (the OAuth client paths it fixes are not used here). Its stdio reader now
  refuses a single client message over 10 MiB.
- Housekeeping: the July comment inventory left the repository, local
  audit folders and the package's own `.mcp.json` are ignored, and the
  template sync workflow commits with a plain sentence. The published
  tarball was checked file by file: only `dist`, `bin`, `claude`,
  `extensions`, the plugin manifests, `server.json` and the three top-level
  documents ship. The Extension.js pins already match npm's latest 4.1.32.
- Measured on this machine without a window: `extension_build` for Safari
  validates the manifest, generates the Xcode project and builds the app
  (31 s, bundle id derived from the app name). A Safari dev session and
  its surface reads still need Allow Remote Automation on and the
  extension enabled in Safari > Settings > Extensions, which are attended
  steps, so the live lane does not run Safari on its own.
- Measured on Extension.js 4.1.32: a Firefox MV3 event page answers
  `extension_eval` in `background` like an MV2 page does. The CSP refusal
  rewrite applies to a declared content_security_policy, never to MV3 as
  such.
- The envelope contract copied under the tests is the one Extension.js
  4.1.32 ships (it had stayed at the 4.0.17 bytes, so the byte comparison
  against the installed engine only warned), and the comparison now fails
  on any engine at or above the pinned release instead of only on an exact
  match. A new cell checks the build and doctor fixture builders key for
  key against the engine's golden frames.
- Test-only exports left the public surface: `reviewDist` (callers use
  `reviewDistReport`), `loginProjectRef`, `resolvedEngineVersion`
  (`resolvedEngineFacts` carries the version), the
  `HOLD_STILL_WORKS_SENTENCE` alias and the carrier registry's
  `rememberedCarriers`. A test-audit pass also removed cells that restated
  constants, pinned source spellings, or passed for a reason other than
  the one in their title, and fed the remaining hand-written frames from
  the engine's builders.
- No comments remain in the package beyond the file banner and tool-read
  directives. Every former invariant block is carried by a name, a cell
  title, or a `*-rules.test.ts` cell that fails when the rule is broken;
  each fixture builder names the engine or platform writer it copies, and
  a cell checks the engine markers against the installed engine. The 40
  browser, engine-internal and platform-server facts no code or cell can
  hold left the repository for the maintainers' notes.
- The invariant comments are cut to their rule: 509 blocks become 386 and
  3,744 lines become 2,814, with every ledger citation, date, commit, run
  id, first name and machine reference gone, the 120 that only restated a
  tested rule deleted, and five that no longer matched the code corrected
  (the build is an rslib bundle, the engine stamps the profile path, the
  Safari bundle id pattern is the engine's).
- The six inline `<workspace>/<project>` checks on login, project create
  and the create list now go through `isProjectRef`, so a ref with a space
  is refused where it enters instead of by the platform one call later. The
  login list keeps its own check because its exact-slug rule two lines down
  owns the message.
- Dead code out: `isManagedCarrier`, `credentialProjectRef`, `mirrorActionsUrlFromRunUrl`,
  `browserExitStamp`, `hasSourceMaps`, `REGISTRY_BASE_DEFAULT`,
  `SAFARI_MCP_ADD_COMMAND`, `BrowserType`, `ASSERT_RETIRED_IDS`, two unused
  `vi` imports and the live lane's unused `GECKO` set.
- The lint migration warnings no longer re-enable core `no-unused-vars`
  after typescript-eslint turned it off; `@typescript-eslint/no-unused-vars`
  stays. The same line left the monorepo's shared config.
- Nine test files write `ready.json` through the engine contract builder
  instead of by hand; the stop-hints cells name the dead server pid they
  cut in.
- Sleeps go through `node:timers/promises`; one JSON object reader serves
  login config and the approval gate; `consoleBase` and `consoleProjectUrl`
  moved to `src/lib/console-urls.ts`, which ends the login-flow, registry,
  registry-access import cycle; four shadowed names renamed; the
  platform-hold header read lost a catch nothing could reach.
- Five exports that existed only for tests are gone: `getSession`,
  `resetEngineVersionCache`, `resetSessionIdentityForTests`,
  `resetBatchCreateSessions` and `uninstallCarrierExitCleanup`. The cells
  that used them now read the in-memory registry through `listSessions`,
  or start a fresh module graph per cell, which is what "a new process"
  meant in those cells all along.
- The eval envelope has fixture builders in both shapes, and the golden
  frame cell now compares nine of the engine's twelve golden files key for
  key and names the three without a counterpart. The detect sentences are
  a pure function, so the not-found cell no longer runs a 20 s scan; the
  tool description rules are five tables instead of 160 cells.
- The manifest is trimmed: the 20 `pnpm.overrides` floors from the
  September advisory sweep are gone (the tree resolves past every one of
  them now, and the audit reads the same with or without them),
  `browser-extension-manifest-fields`, `vite`, `@eslint/js` and
  `typescript-eslint` leave the dependencies (nothing imported them), and
  the `clean`, `watch`, `start`, `build` and npm hook scripts leave
  (nothing called them; the release lane publishes with scripts ignored).
- Thirteen test cells that hand-wrote the CLI eval or target-not-found
  envelope now feed the fixture builders; one cell pinned `E_NO_SESSION`,
  a code the engine never sends, and now asserts the engine's
  `E_SESSION_NOT_FOUND`. The engine's own `golden.eval.ok.json` wraps the
  value as `{ result, context }` while its executor and CLI answer the bare
  value; the eval builder follows the engine and a cell names the
  disagreement until upstream settles it.
- The Live Preview carrier leaves the package: the bundled extension under
  `extensions/`, the `carrier` input on `extension_dev` and the loopback
  switch are gone. The carrier only ever reached a machine through this
  package, and with the platform in private alpha there is no public
  delivery for it, so the public package no longer ships a companion that
  holds `<all_urls>`, cookies, history, bookmarks and scripting. A copy an
  earlier server placed is still taken back on `extension_stop`,
  `extension_start` and `extension_build`, and a build that packs one is
  still refused.
Assets 2
Loading