You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(hub): headless client host runtime that runs dock client scripts in the host page
Adopt the `@vitejs/devtools-kit` model at the framework level: instead of each
plugin shipping its own injection mechanism, the hub now ships a headless
client runtime — `createDevframeClientHost()` from `@devframes/hub/client` —
that a host page boots once. It assembles the full `DevframeClientContext`
(panel, docks, commands, when) from the hub's shared state, publishes it at
`__DEVFRAME_HUB_CLIENT_CONTEXT__`, and imports each dock entry's client script
(`action` / `custom-render` / iframe `clientScript`) into the page, handing it
a `DockClientScriptContext` with per-entry state, events, and a messages
client bridged over new `hub:messages:*` built-in RPCs.
The a11y inspector becomes the first consumer: its in-page agent is now the
a11y dock's client script (`a11yAgentBundlePath`, default-exported for the
loader), replacing the bespoke `a11yAgent()` Vite plugin and `A11Y_AGENT_PATH`
serving path introduced earlier in this branch. Both minimal hubs boot the
runtime from their existing client entry — the Vite host attaches the agent
via `/@fs/`, the Next host serves it through its catch-all route — and drop
the hand-placed script tags.
Created with the help of an agent.
Copy file name to clipboardExpand all lines: AGENTS.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
5
5
**`devframe`** is the framework-neutral container for one devtool integration, portable across viewers. Build a single tool (its RPC, its SPA, its diagnostics, its CLI/build/spa/embedded outputs) without caring how it'll be displayed. A devframe app runs standalone (CLI, static deploy, embedded SPA) just as well as it mounts inside a hub.
6
6
7
-
**`@devframes/hub`** is the framework-neutral hub layer that sits on top of devframe and provides the multi-integration orchestration (docks, terminals, messages, commands). It does not ship UI — implementers (e.g. `@vitejs/devtools-kit`) provide their own UI on top of the hub's RPC + shared-state protocol. See `examples/minimal-vite-devframe-hub/` for a working ~120-line Vite host demonstrating the protocol end to end.
7
+
**`@devframes/hub`** is the framework-neutral hub layer that sits on top of devframe and provides the multi-integration orchestration (docks, terminals, messages, commands). It does not ship UI — implementers (e.g. `@vitejs/devtools-kit`) provide their own UI on top of the hub's RPC + shared-state protocol. It does ship a **headless client runtime** (`createDevframeClientHost()` from `@devframes/hub/client`): booted in the host page, it assembles the shared `DevframeClientContext` (panel, docks, commands, when) and imports each dock entry's client script (`action` / `custom-render` / iframe `clientScript`) into that page — how a plugin like the a11y inspector runs code inside the page being inspected. See `examples/minimal-vite-devframe-hub/` for a working ~120-line Vite host demonstrating the protocol end to end.
Copy file name to clipboardExpand all lines: examples/minimal-next-devframe-hub/README.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,13 +18,14 @@ Open the printed URL. The dock on the left lists every mounted tool with its ico
18
18
19
19
Selecting a tool loads its SPA in the stage. The bottom drawer mirrors the hub's **Commands**, **Messages**, and **Terminals** subsystems, plus a button that dispatches a command through `hub:commands:execute`.
20
20
21
-
The A11y Inspector shows a live axe-core report of this hub's own page: the host serves the plugin's in-page agent bundle (`a11yAgentBundlePath`) same-origin through the catch-all route, and `app/layout.tsx`loads it into the page, so the docked panel and the agent share the origin their BroadcastChannel rides.
21
+
The A11y Inspector shows a live axe-core report of this hub's own page: the host serves the plugin's in-page agent module (`a11yAgentBundlePath`) same-origin through the catch-all route and attaches it as the a11y dock's `clientScript`; the hub client runtime — `createDevframeClientHost()` booted in `app/page.tsx`— imports it into the page, so the docked panel and the agent share the origin their BroadcastChannel rides.
22
22
23
23
## What the example proves
24
24
25
25
-`createHubContext()` boots a hub with no Vite-specific code path; a `DevframeHost` impl plugs Next specifics (static mounts, connection meta, storage, origin) in uniformly
26
26
-`mountDevframe(ctx, def)` registers any `DevframeDefinition` as a dock and serves both its SPA and its `__connection.json`, so the embedded SPA connects straight back to the hub
27
27
- The browser reads `devframe:docks` / `devframe:commands` shared state and dispatches commands over RPC — byte-for-byte the same protocol the Vite host speaks
28
+
-`createDevframeClientHost()` boots the hub's framework-level client runtime in the host page: it publishes the shared client context and imports each dock's `clientScript` (here, the a11y agent) so plugins run code in the page being inspected
Copy file name to clipboardExpand all lines: examples/minimal-vite-devframe-hub/README.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,14 +18,15 @@ Open the printed URL. The dock on the left lists every mounted tool with its ico
18
18
19
19
Selecting a tool loads its SPA in the stage. The bottom drawer mirrors the hub's **Commands**, **Messages**, and **Terminals** subsystems, plus a button that dispatches a command through `hub:commands:execute`.
20
20
21
-
The A11y Inspector shows a live axe-core report of this hub's own page: `a11yAgent()` (in `vite.config.ts`) serves the plugin's in-page agent and injects it into `index.html`, so the docked panel and the agent share the Vite origin their BroadcastChannel rides. Hover a violation to ring the offending element in the hub UI.
21
+
The A11y Inspector shows a live axe-core report of this hub's own page. `vite.config.ts` attaches the plugin's in-page agent as the a11y dock's `clientScript` (served via `/@fs/`), and the hub client runtime — `createDevframeClientHost()` booted in `src/client/main.ts` — imports it into the host page. Panel and agent share the Vite origin their BroadcastChannel rides; hover a violation to ring the offending element in the hub UI.
22
22
23
23
## What the example proves
24
24
25
25
-`createHubContext()` boots a hub with no Vite-specific code path; a `DevframeHost` impl plugs framework specifics (static mounts, connection meta, storage, origin) in uniformly
26
26
-`mountDevframe(ctx, def)` registers any `DevframeDefinition` as a dock and serves both its SPA and its `__connection.json`, so the embedded SPA connects straight back to the hub
27
27
- Real integrations work end to end through the mount path — the inspector lists every plugin's RPC functions live, terminals stream over the hub, and code-server launches an authenticated editor
28
28
- The browser reads `devframe:docks` / `devframe:commands` shared state and dispatches commands over RPC — no hub classes imported on the client
29
+
-`createDevframeClientHost()` boots the hub's framework-level client runtime in the host page: it publishes the shared client context and imports each dock's `clientScript` (here, the a11y agent) so plugins run code in the page being inspected
29
30
30
31
## Build your own
31
32
@@ -36,7 +37,7 @@ The dock UI is plain DOM in `src/client/`. To skin your own viewer, read the sam
36
37
| File | Role |
37
38
|---|---|
38
39
|`src/minimal-vite-devframe-hub.ts`| The Vite host — hub context, static + connection-meta mounts, side-car WS |
39
-
|`vite.config.ts`| Mounts the built-in plugins via the host's `devframes` option; adds `a11yAgent()` to load the a11y agent into the host page|
40
+
|`vite.config.ts`| Mounts the built-in plugins via the host's `devframes` option; attaches the a11y agent as its dock's `clientScript`|
40
41
|`src/client/main.ts`| The browser UI that consumes the hub protocol |
41
42
|`src/client/icons.ts`| Offline Phosphor icons for the dock |
0 commit comments