Skip to content

Commit 1fc40af

Browse files
authored
refactor!: reframe devframe positioning + rename Vite integration (#2)
* refactor: reframe devframe positioning + rename Vite integration Reframe the docs/skill to position devframe as a portable, framework- and build-tool-agnostic asset rather than a single-tool surface that "lacks" hub features. Vite DevTools is now described as one host built on devframe, reached via the renamed `vite` adapter (was the `kit` adapter); the docs no longer enumerate things devframe doesn't provide and instead point at Vite DevTools or custom adapters as the escape valve. The previous `vite` SPA-mounting plugin is no longer an adapter — moved to `devframe/helpers/vite` and the factory renamed `createVitePlugin` → `viteDevBridge`. Updated the `@devframes/nuxt` consumer, internal JSDoc, error doc DF0033, tsnapi snapshots, `DevframeRuntime` type literal, and rebranded the client-side `[Vite DevTools]` timeout error to `[devframe]`. The `vite-devtools-auth` BroadcastChannel literal is kept for cross-tab interop with the existing Vite DevTools auth page. * fix: reorder tsnapi snapshot to match alphabetical interface order tsnapi emits interfaces alphabetically; the hand-edited snapshot had ViteDevBridgeOptions before DevframeVitePlugin, causing a snapshot mismatch on all CI matrix jobs. Reordered to DevframeVitePlugin first. Also picks up tsdown's idempotent re-sort of package.json exports (./helpers/vite slotted between ./constants and ./node).
1 parent 3af5f23 commit 1fc40af

27 files changed

Lines changed: 150 additions & 165 deletions

File tree

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ await createCli(devframe).parse()
4444
|---------|----------|
4545
| `cli` | Standalone CLI tool with `dev` / `build` / `mcp` subcommands. |
4646
| `build` | Generates a static, self-contained SPA snapshot. |
47-
| `vite` | Runs as a Vite plugin alongside the host app's dev server. |
48-
| `kit` | Mounts into a DevTools Kit aggregator (e.g. `@vitejs/devtools-kit`). |
47+
| `vite` | Mounts the devframe into Vite DevTools (or any compatible host) via `@vitejs/devtools-kit`. |
4948
| `embedded` | Overlays inside another devframe's UI. |
5049
| `mcp` | Surfaces the devframe's RPC to coding agents over MCP. |
5150

alias.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const alias = {
3232
'devframe/adapters/cli': r('devframe/src/adapters/cli.ts'),
3333
'devframe/adapters/dev': r('devframe/src/adapters/dev.ts'),
3434
'devframe/adapters/build': r('devframe/src/adapters/build.ts'),
35-
'devframe/adapters/vite': r('devframe/src/adapters/vite.ts'),
35+
'devframe/helpers/vite': r('devframe/src/helpers/vite.ts'),
3636
'devframe/adapters/embedded': r('devframe/src/adapters/embedded.ts'),
3737
'devframe/adapters/mcp': r('devframe/src/adapters/mcp.ts'),
3838
'@devframes/nuxt/runtime/plugin.client': r('nuxt/src/runtime/plugin.client.ts'),

docs/errors/DF0033.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ outline: deep
1010
1111
## Cause
1212

13-
`createVitePlugin({ devMiddleware })` could not bring up the bridge dev server that pairs a host-served SPA (Vite, Nuxt, Astro, etc.) with devframe's RPC backend. Common reasons:
13+
`viteDevBridge({ devMiddleware })` could not bring up the bridge dev server that pairs a host-served SPA (Vite, Nuxt, Astro, etc.) with devframe's RPC backend. Common reasons:
1414

1515
- The preferred port is in use and no fallback range was configured.
1616
- Calling `def.setup(ctx)` threw — the devframe's own setup logic surfaced an error.
@@ -20,10 +20,10 @@ This is a soft warning — the surrounding Vite dev server keeps running, but th
2020

2121
## Fix
2222

23-
- Pin a port via `cli.port` / `cli.portRange` on the devframe definition, or via `devMiddleware.port` on `createVitePlugin`.
23+
- Pin a port via `cli.port` / `cli.portRange` on the devframe definition, or via `devMiddleware.port` on `viteDevBridge`.
2424
- Inspect the `reason` (or the attached `cause`) for the underlying error — fix the setup function or free the port.
2525
- For Nuxt: pass `devMiddleware: { port: <free-port> }` to the `@devframes/nuxt` module.
2626

2727
## Source
2828

29-
- [`packages/devframe/src/adapters/vite.ts`](https://github.com/vitejs/devtools/blob/main/devframe/packages/devframe/src/adapters/vite.ts)`createVitePlugin({ devMiddleware })` logs `DF0033` when port resolution or `createDevServer` throws during `configureServer`.
29+
- [`packages/devframe/src/helpers/vite.ts`](https://github.com/vitejs/devtools/blob/main/devframe/packages/devframe/src/helpers/vite.ts)`viteDevBridge({ devMiddleware })` logs `DF0033` when port resolution or `createDevServer` throws during `configureServer`.

docs/guide/adapters.md

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ Every adapter factory has the shape `createXxx(devframeDef, options?)`.
1414
|---------|-------|---------|----------|
1515
| [`cli`](#cli) | `devframe/adapters/cli` | `createCli(def, options?)` | Standalone tools run via `node ./my-tool.js` |
1616
| [`dev`](#dev) | `devframe/adapters/dev` | `createDevServer(def, options?)` | Run the dev server programmatically — drive it from any CLI framework |
17-
| [`vite`](#vite) | `devframe/adapters/vite` | `createVitePlugin(def, options?)` | Mount a tool's UI inside an existing Vite dev server |
1817
| [`build`](#build) | `devframe/adapters/build` | `createBuild(def, options?)` | Offline reports, CI artifacts, deployable SPA snapshots |
19-
| [`kit`](#kit) | `@vitejs/devtools-kit/node` | `createPluginFromDevframe(def, options?)` | Integrating into Vite DevTools Kit |
18+
| [`vite`](#vite) | `@vitejs/devtools-kit/node` | `createPluginFromDevframe(def, options?)` | Mount the definition into Vite DevTools (or any compatible host) |
2019
| [`embedded`](#embedded) | `devframe/adapters/embedded` | `createEmbedded(def, { ctx })` | Runtime registration into an already-running host |
2120
| [`mcp`](#mcp) | `devframe/adapters/mcp` | `createMcpServer(def, options?)` | Exposing a devframe to coding agents |
2221

@@ -180,7 +179,7 @@ A devframe's SPA basePath depends on which adapter is running it:
180179
| Adapter kind | Default basePath | Reason |
181180
|--------------|------------------|--------|
182181
| `cli`, `spa`, `build` (standalone) | `/` | The devframe owns the origin. |
183-
| `vite`, `kit`, `embedded` (hosted) | `/__<id>/` | The devframe shares the origin with a host app and namespaces itself. |
182+
| `vite`, `embedded` (hosted) | `/__<id>/` | The devframe shares the origin with a host app and namespaces itself. |
184183

185184
Override either side explicitly with `DevframeDefinition.basePath`:
186185

@@ -194,26 +193,6 @@ defineDevframe({
194193

195194
SPA authors should build with relative asset paths (`vite.base: './'`); the client resolves its connection descriptor relative to the page at runtime. See [Client](./client#runtime-basepath-discovery) for the discovery rules.
196195

197-
## Vite
198-
199-
A thin Vite plugin that mounts a devframe's SPA into an existing Vite dev server as a *hosted* adapter — the mount path defaults to `/__<id>/` to namespace away from the app. The plugin mounts the SPA only; for RPC, use `kit` or `cli`.
200-
201-
```ts
202-
import { createVitePlugin } from 'devframe/adapters/vite'
203-
import { defineConfig } from 'vite'
204-
import devframe from './devframe'
205-
206-
export default defineConfig({
207-
plugins: [createVitePlugin(devframe)],
208-
})
209-
```
210-
211-
| Option | Default | Description |
212-
|--------|---------|-------------|
213-
| `base` | `def.basePath ?? '/__<id>/'` | Mount path inside the Vite dev server. |
214-
215-
Use this adapter when a devframe's UI is purely static and you want to surface it during Vite `serve` without shipping a separate dev server. Set `DevframeDefinition.basePath` on the definition for a custom path that stays consistent across adapters.
216-
217196
## Build
218197

219198
Produces a self-contained static deploy of a devframe:
@@ -252,9 +231,9 @@ When `def.spa` is set on the definition, `createBuild` also writes `spa-loader.j
252231

253232
Deployed SPAs that use `setupBrowser` ship their own client entry that registers the handlers.
254233

255-
## Kit
234+
## Vite
256235

257-
Wraps a `DevframeDefinition` so Vite DevTools Kit's plugin-scan picks it up. The factory lives in `@vitejs/devtools-kit/node` — kit owns docking and process management while devframe stays portable.
236+
The Vite-DevTools adapter — wraps a `DevframeDefinition` so Vite DevTools' kit plugin-scan picks it up. The factory lives in `@vitejs/devtools-kit/node` so devframe itself stays free of any Vite or `@vitejs/*` dependency. The pattern (`definition → host plugin → mount`) is general; other hosts can implement equivalent bridges.
258237

259238
```ts
260239
import { createPluginFromDevframe } from '@vitejs/devtools-kit/node'
@@ -265,18 +244,18 @@ export default function myVitePlugin() {
265244
}
266245
```
267246

268-
The returned object has the shape `{ name, devtools: { setup, capabilities } }`. Use this adapter when your devframe should live inside the Vite DevTools dock alongside other integrations. Kit synthesises an iframe dock entry from the definition's `id` / `name` / `icon` / `basePath`; for richer kit-specific behaviour (extra terminals, commands, dock overrides) pass `options.setup`. See the [DevTools Kit → DevTools Plugin](https://devtools.vite.dev/kit/devtools-plugin) page for the Vite-specific guide.
247+
The returned object has the shape `{ name, devtools: { setup, capabilities } }`. Use this adapter when your devframe should live inside the Vite DevTools dock alongside other integrations. The kit synthesises an iframe dock entry from the definition's `id` / `name` / `icon` / `basePath`; for richer host-side behaviour (extra terminals, commands, dock overrides) pass `options.setup`. See the [DevTools Kit → DevTools Plugin](https://devtools.vite.dev/kit/devtools-plugin) page for the Vite-specific guide.
269248

270249
| Option | Default | Description |
271250
|--------|---------|-------------|
272251
| `name` | `devframe:<id>` | Override the Vite plugin name. |
273252
| `base` | `def.basePath ?? /.${id}/` | Mount path override. |
274253
| `dock` | `{}` | Overrides for the synthesized iframe dock entry (category, icon, when). |
275-
| `setup` || Additional kit-only setup hook; receives the kit-augmented context. |
254+
| `setup` || Additional host-only setup hook; receives the kit-augmented context (Vite DevTools' `docks`, `terminals`, `messages`, `commands`). |
276255

277256
## Embedded
278257

279-
Register a devframe into an already-running context at runtime. Mirrors Kit's internal plugin-scan, but for callers that need dynamic, post-startup registration. The host decides the mount path; `embedded` is a hosted adapter and inherits the `/__<id>/` default when one is needed.
258+
Register a devframe into an already-running context at runtime. Mirrors the `vite` adapter's plugin-scan, but for callers that need dynamic, post-startup registration. The host decides the mount path; `embedded` is a hosted adapter and inherits the `/__<id>/` default when one is needed.
280259

281260
```ts
282261
import { createEmbedded } from 'devframe/adapters/embedded'
@@ -308,3 +287,29 @@ await createMcpServer(devframe, { transport: 'stdio' })
308287
`@modelcontextprotocol/sdk` is a peer dependency — install it when shipping MCP support. The current transport is `stdio`.
309288

310289
See the [Agent-Native](./agent-native) page for the full API, safety model, and Claude Desktop integration example.
290+
291+
## Helpers
292+
293+
These are not adapters — they're small utilities for integrating devframe into specific runtimes outside the adapter list.
294+
295+
### `devframe/helpers/vite`
296+
297+
A thin Vite plugin for mounting a devframe inside an existing Vite dev server, used by `@devframes/nuxt` and available for any Vite-based host (Astro, SolidStart, plain Vite apps). Two modes:
298+
299+
- **Static mount** (default) — mounts `def.cli.distDir` at `options.base` (`/__<id>/` by default). No RPC server.
300+
- **Bridge mode** (`devMiddleware: true | {…}`) — skips the static mount; the host app owns the SPA. Devframe spawns a separate RPC + WS server and registers Vite middleware at `<base>__connection.json` so the host-served SPA can discover the WS endpoint.
301+
302+
```ts
303+
import { viteDevBridge } from 'devframe/helpers/vite'
304+
import { defineConfig } from 'vite'
305+
import devframe from './devframe'
306+
307+
export default defineConfig({
308+
plugins: [viteDevBridge(devframe)],
309+
})
310+
```
311+
312+
| Option | Default | Description |
313+
|--------|---------|-------------|
314+
| `base` | `def.basePath ?? '/__<id>/'` | Mount path inside the Vite dev server. |
315+
| `devMiddleware` | `false` | `true` or `{ port?, host?, flags? }` to enable bridge mode. |

docs/guide/client.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const ok = await rpc.requestTrustWithToken('another-token')
8989

9090
### Broadcast-channel sync
9191

92-
`connectDevframe` listens on `BroadcastChannel('vite-devtools-auth')` for `auth-update` messages. When an auth page in another tab announces a new token, every open client requests trust with it automatically — no reload required.
92+
`connectDevframe` listens on a shared `BroadcastChannel` (named `vite-devtools-auth` for cross-tab handshake interop with Vite DevTools' auth page) for `auth-update` messages. When an auth page in another tab announces a new token, every open client requests trust with it automatically — no reload required.
9393

9494
## Calling functions
9595

@@ -183,7 +183,7 @@ await connectDevframe({
183183

184184
## Remote docks
185185

186-
Remote docks are a kit-side feature (see [Vite DevTools Kit → Remote Client](https://devtools.vite.dev/kit/remote-client)). The kit injects a connection descriptor into the iframe URL; on the hosted page, `connectDevframe` auto-detects the descriptor from the URL fragment / query string — call it as usual:
186+
Remote docks are a host-side feature — hosts that support them (Vite DevTools is one; see [its remote-client docs](https://devtools.vite.dev/kit/remote-client) for that implementation) inject a connection descriptor into the iframe URL. On the hosted page, `connectDevframe` auto-detects the descriptor from the URL fragment / query string — call it as usual:
187187

188188
```ts
189189
import { connectDevframe } from 'devframe/client'

docs/guide/devframe-definition.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ outline: deep
44

55
# Devframe Definition
66

7-
Every Devframe tool starts with a single `defineDevframe` call. The returned `DevframeDefinition` is a portable value that any of the [adapters](./adapters) can consume — the same definition runs under `createCli`, `createBuild`, `createMcpServer`, kit's `createPluginFromDevframe`, and so on.
7+
Every Devframe tool starts with a single `defineDevframe` call. The returned `DevframeDefinition` is a portable value that any of the [adapters](./adapters) can consume — the same definition runs under `createCli`, `createBuild`, `createMcpServer`, the `vite` adapter's `createPluginFromDevframe`, and so on.
88

99
## Minimal definition
1010

@@ -28,7 +28,7 @@ export default defineDevframe({
2828
})
2929
```
3030

31-
When mounted into Vite DevTools via [`createPluginFromDevframe`](./adapters#kit), the dock entry and iframe mount are derived from `id`, `name`, `icon`, and `basePath` automatically. Hub-level features (`docks`, `terminals`, `messages`, `commands`) live on the kit-augmented context.
31+
Host adapters (such as the [`vite` adapter](./adapters#vite) for Vite DevTools) derive their mount entry from `id`, `name`, `icon`, and `basePath` automatically.
3232

3333
## Definition fields
3434

@@ -38,7 +38,7 @@ When mounted into Vite DevTools via [`createPluginFromDevframe`](./adapters#kit)
3838
| `name` | `string` | **Required.** Display name shown in the dock and agent manifests. |
3939
| `icon` | `string \| { light, dark }` | Optional Iconify name or URL; supports light/dark pairs. |
4040
| `version` | `string` | Optional version string surfaced to clients. |
41-
| `basePath` | `string` | Optional mount path override. Defaults depend on the adapter: `/` for standalone (`cli` / `spa` / `build`), `/.<id>/` for hosted (`vite` / `kit` / `embedded`). |
41+
| `basePath` | `string` | Optional mount path override. Defaults depend on the adapter: `/` for standalone (`cli` / `spa` / `build`), `/.<id>/` for hosted (`vite` / `embedded`). |
4242
| `capabilities` | `{ dev?, build?, spa? }` | Per-runtime feature flags. A `boolean` applies to the runtime as a whole; an object enables individual features. |
4343
| `setup` | `(ctx, info?) => void \| Promise<void>` | **Required.** Server-side entry point. Runs in every runtime. The optional second argument carries runtime metadata — most notably the parsed CLI `flags` when running under `createCli`. |
4444
| `setupBrowser` | `(ctx) => void \| Promise<void>` | Browser-only entry used by the SPA adapter. |
@@ -84,14 +84,13 @@ interface DevToolsNodeContext {
8484
}
8585
```
8686

87-
Hub-level subsystems — `docks`, `terminals`, `messages`, `commands`, `createJsonRenderer` — live on the kit-augmented context owned by `@vitejs/devtools-kit`. A devframe app that wants to register kit-only behavior does so through the optional `setup` hook on `createPluginFromDevframe`.
87+
Host adapters can augment `ctx` with additional surfaces. For example, the [`vite` adapter](./adapters#vite) exposes Vite DevTools' dock, command, message, and terminal hosts via an optional `setup` hook on `createPluginFromDevframe` — consult the host's docs for those extras.
8888

89-
Each host has a dedicated page:
89+
Each devframe-level host has a dedicated page:
9090
- [RPC](./rpc)`ctx.rpc`
9191
- [Shared State](./shared-state)`ctx.rpc.sharedState`
9292
- [Diagnostics](./diagnostics)`ctx.diagnostics`
9393
- [Agent-Native](./agent-native)`ctx.agent`
94-
- Hub-side surfaces — [Dock System](https://devtools.vite.dev/kit/dock-system), [Commands](https://devtools.vite.dev/kit/commands), [Messages](https://devtools.vite.dev/kit/messages), [Terminals](https://devtools.vite.dev/kit/terminals) — live in the [Vite DevTools Kit](https://devtools.vite.dev/kit/) docs.
9594

9695
## Browser setup
9796

@@ -182,15 +181,15 @@ const devframe = defineDevframe({ id: 'my-devframe', name: 'My Devframe', setup(
182181
// 1. Standalone CLI:
183182
await createCli(devframe).parse()
184183

185-
// 2. Embedded in a Vite project (from `vite.config.ts`):
186-
export const myPlugin = () => createPluginFromDevframe(devframe)
187-
188-
// 3. Offline snapshot:
184+
// 2. Offline snapshot:
189185
await createBuild(devframe, { outDir: 'dist-static' })
186+
187+
// 3. Mount into a host (Vite DevTools shown — other hosts can implement equivalents):
188+
export const myPlugin = () => createPluginFromDevframe(devframe)
190189
```
191190

192191
## What's next
193192

194193
- [Adapters](./adapters) — pick a deployment target
195194
- [RPC](./rpc) — register server functions
196-
- [Vite DevTools Kit](https://devtools.vite.dev/kit/) — mount your devframe into the multi-integration hub
195+
- [`vite` adapter](./adapters#vite) — mount your devframe into Vite DevTools or another compatible host

0 commit comments

Comments
 (0)