Skip to content

Commit f14817a

Browse files
antfuclaude
andauthored
fix(devframe)!: decouple docks/terminals/messages/commands from devframe (#317)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9ab8ef1 commit f14817a

118 files changed

Lines changed: 1505 additions & 1959 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# AGENTS GUIDE
22

3+
## Positioning
4+
5+
Two layers, one mental model:
6+
7+
- **`devframe`***the 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.
8+
- **`@vitejs/devtools-kit`***the hub that unites many devtools integrations.* Owns docking, the command palette, toasts, terminal sessions — anything that only makes sense when more than one tool shares a UI. Provides `createPluginFromDevframe(devtoolApp)` so a portable devframe definition drops into Vite DevTools as a Vite plugin, with the dock entry auto-derived from the definition's metadata.
9+
10+
When deciding where something belongs: if a single-app standalone CLI would still need it, it lives in devframe; if it only matters once you have multiple integrations or a host UI, it lives in the kit.
11+
312
## Stack & Structure
413

514
Monorepo (`pnpm` workspaces + `turbo`). ESM TypeScript; bundled with `tsdown`. Path aliases in `alias.ts` (propagated to `tsconfig.base.json` — do not edit manually).
@@ -8,14 +17,14 @@ Monorepo (`pnpm` workspaces + `turbo`). ESM TypeScript; bundled with `tsdown`. P
817

918
| Package | npm | Description |
1019
|---------|-----|-------------|
11-
| `packages/devframe` | `devframe` | Framework-neutral foundation — RPC layer (birpc + valibot + WS presets), host classes, createHostContext, six adapters at `devframe/adapters/*` (cli/build/spa/vite/kit/embedded), connectDevtool client |
12-
| `packages/core` | `@vitejs/devtools` | Vite plugin, CLI, standalone/webcomponents client. Wraps devframe's createHostContext with the Vite plugin scan |
13-
| `packages/kit` | `@vitejs/devtools-kit` | Vite-specific superset of devframe — adds PluginWithDevTools, ViteDevToolsNodeContext, and re-exports devframe's public types |
14-
| `packages/ui` | `@vitejs/devtools-ui` | Shared UI components, composables, and UnoCSS preset (`presetDevToolsUI`). Private, not published |
15-
| `packages/rolldown` | `@vitejs/devtools-rolldown` | Nuxt UI for Rolldown build data. Serves at `/__devtools-rolldown/` |
16-
| `packages/vite` | `@vitejs/devtools-vite` | Nuxt UI for Vite DevTools (WIP). Serves at `/__devtools-vite/` |
17-
| `packages/self-inspect` | `@vitejs/devtools-self-inspect` | Meta-introspection — DevTools for the DevTools. Serves at `/__devtools-self-inspect/` |
18-
| `packages/webext` || Browser extension scaffolding (ancillary) |
20+
| `devframe/packages/devframe` | `devframe` | Framework-neutral container for one devtool integration. RPC layer (birpc + valibot + WS presets), `createHostContext`, six deployment adapters at `devframe/adapters/*` (cli/dev/build/vite/embedded/mcp), `connectDevtool` client. No docks, no terminals, no command palette — those are hub concerns. |
21+
| `packages/kit` | `@vitejs/devtools-kit` | The hub. `createKitContext` wraps devframe's context with `docks` / `terminals` / `messages` / `commands` host subsystems plus the Vite-augmented context type. `createPluginFromDevframe` bridges a portable devframe app into a `Plugin.devtools.setup` Vite plugin, auto-deriving its iframe dock entry from the definition. |
22+
| `packages/core` | `@vitejs/devtools` | Vite plugin + CLI + standalone/webcomponents client for Vite DevTools itself. Calls kit's `createKitContext`, scans Vite plugins for `.devtools.setup`, and serves the dock UI. |
23+
| `packages/ui` | `@vitejs/devtools-ui` | Shared UI components, composables, and UnoCSS preset (`presetDevToolsUI`). Private, not published. |
24+
| `packages/rolldown` | `@vitejs/devtools-rolldown` | Nuxt UI for Rolldown build data. Hub-mounted via `Plugin.devtools.setup`. Serves at `/__devtools-rolldown/`. |
25+
| `packages/vite` | `@vitejs/devtools-vite` | Nuxt UI for Vite DevTools (WIP). Hub-mounted via `Plugin.devtools.setup`. Serves at `/__devtools-vite/`. |
26+
| `packages/self-inspect` | `@vitejs/devtools-self-inspect` | Meta-introspection — DevTools for the DevTools. Hub-mounted via `Plugin.devtools.setup`. Serves at `/__devtools-self-inspect/`. |
27+
| `packages/webext` || Browser extension scaffolding (ancillary). |
1928

2029
Other top-level directories:
2130
- `docs/` — VitePress docs; guides in `docs/guide/`
@@ -34,15 +43,19 @@ flowchart TD
3443

3544
## Dep Boundary
3645

37-
`packages/devframe` is the lowest-level package in this monorepo and is positioned to be extracted into its own repo. It MUST NOT import from `vite` or any `@vitejs/*` package — not as a `dependencies` entry, not as an inlined dep, not as a source import. `packages/kit` and above build on top of devframe, never the reverse.
46+
`devframe/packages/devframe` is the lowest-level package in this monorepo and is positioned to be extracted into its own repo. It MUST NOT import from `vite`, `@vitejs/*`, or any hub-only concept (docks, terminals, messages, commands) — not as a `dependencies` entry, not as an inlined dep, not as a source import. `packages/kit` and above build on top of devframe; never the reverse. If a feature requires multi-integration awareness, it goes in kit.
47+
48+
`devframe/internal` is a marked-internal subpath that exposes a small set of helpers (`getInternalContext`, `resolveBasePath`) for first-party adapters that need to reach into devframe's private machinery — kit's relocated `DocksHost` uses it for remote-dock token allocation. End users should not import it.
3849

3950
## Architecture
4051

41-
- **Entry**: `createDevToolsContext` (`packages/core/src/node/context.ts`) builds `DevToolsNodeContext` with hosts for RPC, docks, views, terminals. Invokes `plugin.devtools.setup` hooks.
42-
- **Node context**: server-side (cwd, vite config, mode, hosts, auth storage at `node_modules/.vite/devtools/auth.json`).
52+
- **Devframe context** (`devframe/packages/devframe/src/node/context.ts`): `createHostContext` returns a `DevToolsNodeContext` carrying `rpc`, `views` (HTTP file-serving via `hostStatic`), `diagnostics`, `agent`, plus `cwd`/`workspaceRoot`/`mode`/`host`/`createJsonRenderer`. No docks, no terminals.
53+
- **Kit context** (`packages/kit/src/node/context.ts`): `createKitContext` wraps `createHostContext` and attaches the four hub hosts — `docks`, `terminals`, `messages`, `commands`. Optionally surfaces `viteConfig`/`viteServer` when mounted inside Vite DevTools. Wires the `'devframe:docks'` / `'devframe:commands'` shared-state sync.
54+
- **Bridge** (`packages/kit/src/node/create-plugin-from-devframe.ts`): `createPluginFromDevframe(d, opts?)` returns `PluginWithDevTools`; in its `setup`, mounts the SPA via `views.hostStatic`, auto-registers an iframe dock entry from `id`/`name`/`icon`/`basePath`, runs `d.setup(ctx)` for the devframe-level wiring, then runs `opts.setup?.(ctx)` for kit-only extensions.
55+
- **Vite DevTools entry** (`packages/core/src/node/context.ts`): `createDevToolsContext` calls `createKitContext`, registers Vite-specific commands (`vite:open-in-editor`, `vite:open-in-finder`), then scans Vite plugins for `.devtools.setup` hooks (which now receive the kit-augmented context).
4356
- **Client context**: webcomponents/Nuxt UI state (`packages/core/src/client/webcomponents/state/*`) — dock entries, panels, RPC client. Two modes: `embedded` (overlay in host app) and `standalone` (independent page).
4457
- **WS server** (`packages/core/src/node/ws.ts`): RPC via `devframe/rpc/transports/ws-server`. Auth skipped in build mode or when `devtools.clientAuth` is `false`.
45-
- **Nuxt UI plugins** (rolldown, vite, self-inspect): each registers RPC functions and hosts static Nuxt SPA at its own base path.
58+
- **Hub-mounted Nuxt UI plugins** (rolldown, vite, self-inspect): each implements `Plugin.devtools.setup`, receives a `KitNodeContext`, registers RPC functions, hosts a static Nuxt SPA, and registers its dock entry.
4659

4760
## Development
4861

@@ -69,14 +82,23 @@ pnpm -C docs run docs # docs dev server
6982

7083
### Devframe design principles
7184

72-
These apply to everything inside `packages/devframe` and to how host packages (`kit`, `core`, etc.) layer on top. When in doubt, err on the side of "devframe provides hooks, the app decides UX".
85+
These apply to everything inside `devframe/packages/devframe` and reinforce its positioning as "the container for one devtool integration, portable to multiple viewers". When in doubt, err on the side of "devframe provides primitives, the hub provides UX".
7386

87+
- **Single-integration scope.** Devframe describes one tool. If a feature only makes sense when multiple tools share a UI — docking, a unified command palette, cross-tool toasts, terminal aggregation — it lives in `@vitejs/devtools-kit`, not here.
7488
- **Headless by default.** No default startup banners, no opinionated logging to stdout, no default styling. Provide hooks (`onReady`, `cli.configure`, etc.); let the application print its own branding. Structured diagnostics via `logs-sdk` are fine — ad-hoc `console.log`s baked into adapters are not.
7589
- **File watching is the app's job, not devframe's.** Don't add a generic watcher primitive. Authors wire chokidar / fs.watch / watchman themselves and signal change via `ctx.rpc.sharedState.set(...)` or event-type RPCs. devframe stays out of the filesystem-observation business.
76-
- **Mount path depends on adapter context.** Given `id: 'foo'`, the default mount path is `/__foo/` for *hosted* adapters (`vite`, `kit`, `embedded`) and `/` for *standalone* adapters (`cli`, `spa`, `build`). Authors override via `DevtoolDefinition.basePath`. Don't hardcode `DEVTOOLS_MOUNT_PATH` in adapter code paths that may run standalone.
77-
- **SPAs own their basePath at runtime.** Build SPAs with relative asset paths (`vite.base: './'`); discover the effective base in the browser from the executing script's location / `document.baseURI`. `createBuild` / `createSpa` copy SPA output verbatim — no HTML rewriting, no build-time `--base` injection. The client (`connectDevtool`) resolves `__connection.json` relative to the runtime base automatically.
90+
- **Mount path depends on adapter context.** Given `id: 'foo'`, the default mount path is `/__foo/` for *hosted* adapters (`vite`, `embedded`, kit's `createPluginFromDevframe`) and `/` for *standalone* adapters (`cli`, `spa`, `build`). Authors override via `DevtoolDefinition.basePath`. Don't hardcode `DEVTOOLS_MOUNT_PATH` in adapter code paths that may run standalone.
91+
- **SPAs own their basePath at runtime.** Build SPAs with relative asset paths (`vite.base: './'`); discover the effective base in the browser from the executing script's location / `document.baseURI`. `createBuild` / `createSpa` copy SPA output verbatim — no HTML rewriting, no build-time `--base` injection. The client (`connectDevtool`) resolves `.connection.json` relative to the runtime base automatically.
7892
- **CLI flags compose from both sides.** The `cac` instance backing `createCli` is exposed both to the `DevtoolDefinition` (`cli.configure(cli)`) — for capabilities contributed by the tool itself — and to the `createCli` caller — for flags added at the final assembly stage. Parsed flag values are forwarded to `setup(ctx, { flags })`. Never hardcode domain-specific flags into `createCli`.
7993

94+
### Kit design principles
95+
96+
The kit is the integration hub. When adding to it, the question is "does this help unify multiple devtools?" — not "is this useful in general?".
97+
98+
- **Hub-only features.** `docks`, `terminals`, `messages`, `commands`, the auto-derived dock entry in `createPluginFromDevframe`, the unified user-settings shared state — these only have meaning across integrations and stay kit-side.
99+
- **Devframe definitions stay portable.** `createPluginFromDevframe(devtoolApp, opts?)` is the bridge. The devtool's own `setup(ctx)` should not assume kit context; if it needs hub features, contribute them via `opts.setup` or via a kit-only Vite plugin that augments the same context.
100+
- **Auto-derive what you can, override via options.** `createPluginFromDevframe` synthesizes the iframe dock entry from `id`/`name`/`icon`/`basePath`. Callers customise via `opts.dock` (category, when-clause, custom icon override) or `opts.setup` (terminals, additional dock entries). Don't push these into the portable `DevtoolDefinition`.
101+
80102
## Structured Diagnostics (Error Codes)
81103

82104
All node-side warnings and errors use structured diagnostics via [`logs-sdk`](https://github.com/vercel-labs/logs-sdk). Never use raw `console.warn`, `console.error`, or `throw new Error` with ad-hoc messages in node-side code — always define a coded diagnostic.
@@ -85,11 +107,13 @@ All node-side warnings and errors use structured diagnostics via [`logs-sdk`](ht
85107

86108
| Prefix | Package(s) | Diagnostics file |
87109
|--------|-----------|-----------------|
88-
| `DF` | `packages/devframe` | `packages/devframe/src/node/diagnostics.ts`, `packages/devframe/src/rpc/diagnostics.ts` |
89-
| `DTK` | `packages/core` (Vite-specific remainder) | `packages/core/src/node/diagnostics.ts` |
110+
| `DF` | `devframe/packages/devframe` | `devframe/packages/devframe/src/node/diagnostics.ts`, `devframe/packages/devframe/src/rpc/diagnostics.ts` |
111+
| `DTK` | `packages/kit` + `packages/core` (shared codespace, hub-side) | `packages/kit/src/node/diagnostics.ts`, `packages/core/src/node/diagnostics.ts` |
90112
| `RDDT` | `packages/rolldown` | `packages/rolldown/src/node/diagnostics.ts` |
91113
| `VDT` | `packages/vite` (reserved) ||
92114

115+
`DTK` is shared between core and kit because they're sibling layers of the Vite DevTools hub. Coordinate code numbers across both files: kit currently reserves `DTK0050+`; core's existing codes top out below that.
116+
93117
Codes are sequential 4-digit numbers per prefix (e.g. `DTK0033`, `RDDT0003`). Check the existing diagnostics file to find the next available number.
94118

95119
### Adding a new error

alias.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const alias = {
1515
'devframe/types': df('devframe/src/types/index.ts'),
1616
'devframe/node': df('devframe/src/node/index.ts'),
1717
'devframe/constants': df('devframe/src/constants.ts'),
18+
'devframe/internal': df('devframe/src/internal/index.ts'),
1819
'devframe/utils/events': df('devframe/src/utils/events.ts'),
1920
'devframe/utils/human-id': df('devframe/src/utils/human-id.ts'),
2021
'devframe/utils/nanoid': df('devframe/src/utils/nanoid.ts'),
@@ -27,7 +28,6 @@ export const alias = {
2728
'devframe/adapters/dev': df('devframe/src/adapters/dev.ts'),
2829
'devframe/adapters/build': df('devframe/src/adapters/build.ts'),
2930
'devframe/adapters/vite': df('devframe/src/adapters/vite.ts'),
30-
'devframe/adapters/kit': df('devframe/src/adapters/kit.ts'),
3131
'devframe/adapters/embedded': df('devframe/src/adapters/embedded.ts'),
3232
'devframe/adapters/mcp': df('devframe/src/adapters/mcp.ts'),
3333
'@devframes/nuxt/runtime/plugin.client': df('nuxt/src/runtime/plugin.client.ts'),

devframe/docs/.vitepress/config.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ function guideItems(prefix: string): DefaultTheme.NavItemWithLink[] {
2020
{ text: 'RPC', link: `${prefix}/guide/rpc` },
2121
{ text: 'Shared State', link: `${prefix}/guide/shared-state` },
2222
{ text: 'Streaming', link: `${prefix}/guide/streaming` },
23-
{ text: 'Dock System', link: `${prefix}/guide/dock-system` },
24-
{ text: 'Commands', link: `${prefix}/guide/commands` },
2523
{ text: 'When Clauses', link: `${prefix}/guide/when-clauses` },
26-
{ text: 'Messages & Notifications', link: `${prefix}/guide/messages` },
2724
{ text: 'Structured Diagnostics', link: `${prefix}/guide/diagnostics` },
28-
{ text: 'Terminals', link: `${prefix}/guide/terminals` },
2925
{ text: 'Client', link: `${prefix}/guide/client` },
3026
{ text: 'Standalone CLI', link: `${prefix}/guide/standalone-cli` },
3127
{ text: 'Nuxt Helper', link: `${prefix}/guide/nuxt` },

devframe/docs/errors/DF0001.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

devframe/docs/errors/DF0002.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

devframe/docs/errors/DF0003.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

devframe/docs/errors/DF0004.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

devframe/docs/errors/DF0005.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

devframe/docs/errors/DF0009.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

devframe/docs/errors/DF0010.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)