Skip to main content
The host-only registry API (loadPlugin / getContributions) and the test-only reset.

LoadedPlugin

Identity of a successfully-loaded plugin, for host chrome that must attribute a contribution to its origin (e.g. the shell’s provenance badge on plugin nav). The name is the same id the registry stamps on every contribution (pluginId); the version comes from the plugin’s manifest. Properties

PluginContributionsSnapshot

What usePluginContributions returns: the load status and the registry. Properties Related: PluginContributions

PluginLoadInputs

What the host knows about a plugin from its registry listing entry: mounts, the plugin’s own route items and their resolved absolute bases ({item: "/api/<base>"}), and declaredRoutePanels, the channels its manifest lists under contributions.route_panels. Properties

PluginLoaderState

The plugin load pass’s public state, mirrored for feature pages to read. It is the shape the app shell’s loader store already exposes: status gates when the contributions are complete, and the error fields carry the loud failures. Properties Related: LoadedPlugin

StaticToolDisplayNamesProvider

Serve a FIXED display-name map — the test seam for a consumer that renders a tool picker without a live fetch. reload defaults to a no-op; a test that exercises the reload wiring passes a spy. Re-exported from the testing entry. Parameters Related: ToolDisplayNamesContextValue

__resetContributions

Tests reset the module-level registry between cases.

__resetPluginHostState

Tests reset the module-level host state between cases.

contributionCovered

A full projection shows every contribution; an ABSENT requirement renders only for a full projection (safe-by-default); a declared requirement renders when the projection reaches at least one of its routes. Parameters Related: RequiredCapabilities

deferred

A promise whose settlement the test controls, returned alongside its own resolve/reject. It pins a component’s loading state for assertion: hand the unsettled promise to the code under test (e.g. as a mocked api call’s return value), assert the in-flight UI while it hangs, then call resolve/reject to drive the success or failure branch and assert the settled UI. Each call returns a fresh, independent deferred.

destructiveColorOffences

The properties in source that paint text with a destructive role token, in the order they appear. The destructive tokens are the fill, its hover and the label on that fill: a fill colour as text fails contrast on the dark grounds, so error text takes --tai-color-err-text instead. A color declaration (CSS or JSX) is an offence anywhere but the .tai-btn-danger rule, where the label colour belongs. A reference whose property cannot be read is reported as <no property found>: an unattributable declaration is a hole in the rule, not a pass. Parameters

flushResizeObservers

Fires every live ResizeObserver stub’s callback for the elements it is observing. Pair it with setElementOverflow to drive a component that measures itself (ScrollRegion and useProseScrollRegions re-read scrollWidth/clientWidth from their observer callbacks): setElementOverflow(region, true); flushResizeObservers(); Only meaningful once installJsdomStubs has installed the stub; with a real ResizeObserver present (a browser environment) there is nothing to flush.

flushResizeObserversFor

Delivers a resize for ONE element, to every stub observing it — the narrow form of flushResizeObservers. Use it to prove which element a component is watching: a measurement driven by a resize of a CHILD only arrives if that child is observed, so the assertion fails the moment a component narrows its observation to its own box. Parameters

getContributions

The shell reads this after loading every installed plugin bundle. Related: PluginContributions

getPluginHostState

The current mirrored host state — the snapshot usePluginContributions reads. Related: PluginLoaderState

installJsdomStubs

jsdom omits a handful of browser APIs the Studio components reach for while a test drives them. Installing every stub in one place keeps each feature’s test-setup.ts identical and lets interaction tests exercise the real components instead of mocking them out:
  • Radix primitives observe element size (ResizeObserver), scroll the active item into view, and capture the pointer while opening.
  • Export/download paths create and revoke object URLs.
  • File-import flows read the picked file via Blob.text().
  • Router scroll restoration calls scrollTo on navigation.
The ResizeObserver stub is a WORKING observer, not an inert one: it keeps a registry of the observers still in use, delivers an entry to the callback as each element is observed (as a real observer does for its initial observation), and lets a test re-deliver on demand via flushResizeObservers. Components that size themselves — ScrollRegion and useProseScrollRegions — are therefore exercised for real, with setElementOverflow supplying the scroll metrics jsdom cannot compute. Each stub only fills a MISSING API, so installing the whole set everywhere is harmless — the one exception is window.scrollTo, which jsdom ships as a “Not implemented” stub that logs loudly on every navigation, so it is replaced unconditionally. Call once from a package’s Vitest setupFiles entry.

loadPlugin

Load one plugin: call its register entry with a context bound to pluginId, then commit everything it staged into the global registry. entry is AWAITED before commit, so a synchronous or an async entry is fully done first: a post-await throw skips the commit (atomicity holds for async too) and a post-await registration cannot slip past the batch. The seal is set after entry has SETTLED, so a later registration throws loudly; registrations made during entry’s synchronous body — including a microtask it enqueues then — are still captured and committed. A register that throws commits nothing. Parameters Related: PluginEntry, PluginLoadInputs

setElementOverflow

Makes element report itself as overflowing (or not) on axis. jsdom runs no layout, so scroll* and client* are both 0 and every overflow test reads as “fits”; this shadows the prototype getters with own, configurable values so a test can drive either state. Call it again with the opposite flag to flip the element back. Parameters

setPluginHostState

The host loader pushes every load-pass transition here (it stays the single driver); every subscriber is notified so feature pages re-render off it. Props Related: PluginLoaderState

subscribePluginHost

Subscribe to host-state transitions; returns the unsubscribe function useSyncExternalStore requires so a subscriber detaches on unmount. Parameters

usePluginContributions

Subscribe to the plugin host state and read the committed contributions. The status drives re-renders as the load pass advances; contributions is only meaningful once status === 'ready' (before then the pass has committed nothing, so callers render their non-plugin content). Related: PluginContributionsSnapshot