Repository navigation
Conversation
Discover, parse and build the pages that replace the browser new tab, bookmarks and history through chrome_url_overrides. Each page is a singleton view: app files replace shared ones instead of merging, and only the highest-precedence candidate is built. Select the override per build in one plugin: skip pages the target browser does not support and fail when more than one remains, because Chromium refuses to load an extension that overrides several pages. Write the selected page as a single manifest override that replaces raw chrome_url_overrides. Cover parsing, discovery, manifest generation, the selection policy and real Chrome rendering with unit, build and browser integration tests, and document the fixtures. BREAKING CHANGE: top-level newtab, bookmarks and history files and directories in app or shared sources are entrypoints now. Page entrypoints named newtab, bookmarks or history receive a numbered HTML filename such as history1.html; their aliases do not change.
Replace the background-named suite, registered through a side-effect import, with a table of export shapes in the OptionFile tests and rename its fixtures to export-shapes. Cover the shapes that were tested only through parsers or not at all: default-over-named precedence with an explicit false, property selection, foreign and locally declared definitions, alternative definitions, generic calls with type arguments, and a call behind satisfies. Use several framework definitions so the suite does not depend on one entrypoint.
Add real-fixture tests for the background, service, popup, sidebar and offscreen parsers and for the common options owned by AbstractParser. Cover the full command options and the execute-action command name. Keep the override parsers to their own concerns, drop the named-export scenario already covered by the option reader, and store parser fixtures by entrypoint.
Named exports, default-object precedence, and the as and satisfies wrappers belong to the option reader and are covered by its export shapes suite. Keep the scenarios owned by the options parser.
Organize option reader tests by what the reader can read and parser tests by entrypoint. Test shared schema fragments once at their owner and keep export shapes out of parser tests.
Select the tags plugin options from the HTML options schema instead of excluding a few known keys, so view, build and manifest options such as icon, apply, mode, debug or manifestVersion no longer reach it and a view without HTML options adds no tags plugin at all. Move the HTML options schema out of ViewParser into a parser schema module shared by the parser and the view, and cover the selection with real popup fixtures.
Describe install-time and optional API and host permissions once as PermissionsOptions with a matching schema module that a parser merges only when its entrypoint opts in. Apply it to the background family, which already declared these fields, without changing its behavior, and export the contract publicly. Document that schemas shared by unrelated parsers are mixin modules rather than members of AbstractParser or intermediate parser classes.
Let the new tab, bookmarks and history pages declare the permissions their code needs. The manifest receives them only from the page that reaches the build: a candidate that lost the selection or a page the target browser does not support contributes nothing. Expose the parsed options of the selected views from the view finder and collect permissions from them with a pure helper, so other view entrypoints can adopt the contract the same way. Cover the schema adoption, winner-only selection, the plugin policy and real builds across browsers, where a skipped History page no longer requests the browsing history permission.
Let popup, sidebar and options entrypoints declare the permissions their code needs. Whatever reaches the build contributes: every built popup or sidebar when several are allowed, because any of them can be switched to at runtime, and the single winning file otherwise. A sidebar that is unavailable for the target requests nothing. Collect the permissions in a view finder layer that only adopting entrypoints extend, next to the CSP layer, and expose one getter per kind typed with the manifest permission types. Plugins pass these values to the manifest builder explicitly; the override plugin follows the same shape and the standalone collecting helper is removed. Cover the adoption in each parser, the selection and caching on real directories, and real builds across Chrome and Firefox in MV2 and MV3.
Refer to types by name instead of indexing into other declarations, reuse an existing named type before declaring a new one, declare a type where its concept is owned, and compose contracts from named contracts.
Fail the build when two commands resolve to the same name instead of renaming the later one with a numeric suffix. A command name is its identity in the manifest and in the browser's shortcut settings, so the silent rename broke the runtime subscription and could move a user's custom shortcut to another command. Report a dedicated error for a second action command, and derive file-based names through NameGenerator.derive() without claiming them. Cover explicit, merged app/shared and action collisions with real fixtures in CommandFinder.test.ts, and derive() in NameGenerator.test.ts. BREAKING CHANGE: Projects whose commands share a name, explicitly or through their file names, now fail to build. Give each command a distinct "name" option or file name.
…rypoints Move the Relay export merging into mergeDefinition() in the transport resolvers, so every transport entrypoint interprets a default options object or init function the same way and takes its name from the build. Relay and Service expose typed resolveDefinition() wrappers, and the generated Service module becomes a single service(resolveDefinition(...)) call. Replace the generic transport template and its ":entry" placeholder, ts-ignore stripping and "adnbn/entry/:entry" declaration with a dedicated service template. Cover the shared merge rules in the transport resolver test, keep Relay's init-versus-render rule in its own test, and check the Service template in virtual.test.ts alongside Content and Relay.
…entry Move default-export interpretation out of the generated background module into resolveDefinition() in the background resolvers: default options override named exports, a default function becomes main, and any other default value is ignored. The generated module becomes a single background(resolveDefinition(module)) call, and adnbn/entry/background now exports only the startup function and resolveDefinition(). Cover the merge rules in the background resolver test and check the template in virtual.test.ts alongside the other thin templates. BREAKING CHANGE: adnbn/entry/background no longer exports isValidBackgroundDefinition() and isValidBackgroundMainHandler().
Extend the root TypeScript configuration from the command finder fixture project instead of using an empty one. The empty configuration had no paths or bundler resolution, so editors reported "adnbn" imports in the fixtures as missing even though the parser and the tests worked. Override include and exclude so the fixtures are not dropped by the root exclusion of tests/fixtures.
Move default-export interpretation out of the generated command module into resolveDefinition() in the command resolvers: default options override named exports, a default function becomes execute, and the build always supplies the name, as for Relay and Service. The generated module becomes a single command(resolveDefinition(module, name)) call, and adnbn/entry/command now exports only the startup function and resolveDefinition(). Cover the merge and naming rules in the command resolver test and check the template in virtual.test.ts alongside the other thin templates. BREAKING CHANGE: adnbn/entry/command no longer exports isValidCommandDefinition(), isValidCommandExecuteFunction() and isValidCommandName().
Remove the resolvers/index.ts barrels from the background, command, transport and content entrypoint runtimes and import each resolver from the file that owns it, as most callers already did. List the exports of adnbn/entry/transport explicitly, so mergeDefinition() stays internal and only the transport guards used by the offscreen and sandbox templates remain public. The behavior is unchanged and the existing suites cover the moved imports. Record both rules in the internal imports section of AGENTS.md.
Replace the view guards with mergeDefinition() and give the Vanilla and React adapters their own resolveDefinition(), so the generated view module becomes a single view(resolveDefinition(module)) call and only the React adapter knows React elements. Merge the view core builder and the duplicated adapter lifecycles into one abstract Builder that owns the title and the container, while adapters only resolve the render and mount its value; a Vanilla render of 0 is now rendered instead of skipped. Rename virtual:view-framework to virtual:view-builder for view, offscreen and sandbox. Cover definition merging, adapter recognition and both builders through their public build/destroy behavior, and check the template and the React-free Vanilla bundle graph in virtual.test.ts. BREAKING CHANGE: The adnbn/entry/view subpath is removed together with isViewDefinition() and isValidViewDefinitionRenderValue().
Share one render-value contract between the view and content adapters in src/entry/core/render.ts: a non-empty string or a number is inserted as text and never parsed as HTML, a DOM element is appended as is, and a React element still goes through React. The React adapters now render text and DOM elements instead of silently dropping them, the Vanilla view adapter stops parsing strings with innerHTML, and elements from another realm such as an iframe document are recognized by node type. Cover the shared contract in render.test.ts and the adapters through their builders, and document the rule in the content README. BREAKING CHANGE: A string returned by a Vanilla view render is shown as text; return an Element or use a UI framework to render markup.
Resolve offscreen exports in the runtime through resolveDefinition() over the shared transport merge, and let the offscreen Builder compose its transport with a view builder passed by the generated module, as Relay does with its content builder. Offscreen definitions adopt the new ViewRenderDefinition mixin, so render and container work with the adapter selected by the file extension, while init and main still receive only the offscreen options. The generated module becomes a single offscreen(resolveDefinition(module, name), ViewBuilder) call. Cover the startup and the layer composition in index.test.ts, and check the template and the adapter-free offscreen bundle graph in virtual.test.ts. BREAKING CHANGE: The offscreen Builder now takes the view builder class as its second constructor argument and no longer has a view() method.
Resolve sandbox exports in the runtime through resolveDefinition() over the shared transport merge, and let the sandbox Builder compose its transport with the view builder passed by the generated module, as offscreen does. Sandbox definitions adopt ViewRenderDefinition, so render and container use the adapter selected by the file extension, while init and main receive only the sandbox options; adnbn/entry/sandbox exports its startup function instead of TransportBuilder. With no template left on the transport guards, remove the adnbn/entry/transport subpath, make the options-object check private to mergeDefinition, and drop the Relay and offscreen types from the transport resolvers. Cover the startup and the layer composition in index.test.ts, and check the template and the adapter-free sandbox bundle graph in virtual.test.ts. BREAKING CHANGE: The sandbox Builder now takes the view builder class as its second constructor argument and no longer has a view() method, adnbn/entry/sandbox no longer exports TransportBuilder, and the adnbn/entry/transport subpath is removed.
Replace the eight virtual:*-entrypoint declarations with a single wildcard declaration: every generated module passes the entrypoint namespace to its runtime resolveDefinition(), which accepts any object, so the per-entrypoint export lists no longer describe anything the templates use. Keep the content and view builder declarations, whose startup and Builder types the templates still rely on. Remove the relay fixture assertions that pinned the old declaration to RelayUnresolvedDefinition; the fixture still type-checks the relay template against the real builders.
Extend the root TypeScript configuration from the empty fixture projects of the override, view and finder tests, as the command finder fixtures already do, so editors resolve "adnbn" imports in them. Override include and exclude, because the root configuration excludes tests/fixtures. Enable JSX for the expression default-export fixture, whose jsx.tsx did not type-check. The parsers read the same configurations, and the CLI suites pass unchanged.
…ract Split @typing/view into common options and containers, per-adapter render values, the combined render contract, and the definitions, the same way the content types are organized. The Vanilla adapter owns DOM, text and empty values, the React adapter owns React nodes and components, and render.ts combines them, so a new adapter only adds its own file. Export the render contract types from adnbn next to ViewDefinition and ViewOptions. A Promise is no longer accepted as a render value, matching the runtime, which never rendered one; handlers can still await data. Cover the public types through source and package APIs in view.integration.test.ts and list the check in the integration README.
Add a Chrome MV3 integration case whose application renders React offscreen and sandbox views through the builder injected by file extension, reads their text and titles from the popup, and checks that a headless offscreen gets no view container. The same case renders a "<b>…</b>" string through the React view, Vanilla view and React content adapters and asserts that each shows the tags as text. Document the fixture beside it and in the integration README.
Add src/entry/view/README.md covering adapter selection and the generated modules, how each adapter interprets the default export, the single builder and its container lifecycle, the render values shared with content, the type layout in src/types/view, how to add an adapter, and where each part is verified.
The React view and content adapters accepted arrays, portals and bigints in their render types, since both use React's own ReactNode, but passed only React elements to React and silently rendered nothing for the rest; a default-exported portal was even merged as an options object. Recognize every React node through isReactRenderValue() in src/entry/core/react.ts, which only the React adapters import, and hand it to the React root, while text, numbers and DOM elements keep the shared render path; an iterable needs a callable iterator, so options objects stay options. Cover recognition, default exports and rendering of arrays, fragments, portals and bigints for both adapters, extend the type fixtures, and describe the contract in the view and content READMEs, noting that a bigint renders only with React 19.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.