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
Copy file name to clipboardExpand all lines: AGENTS.md
+41-17Lines changed: 41 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,14 @@
1
1
# AGENTS GUIDE
2
2
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
+
3
12
## Stack & Structure
4
13
5
14
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
8
17
9
18
| Package | npm | Description |
10
19
|---------|-----|-------------|
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 Viteplugin 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/`|
|`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/`.|
-`docs/` — VitePress docs; guides in `docs/guide/`
@@ -34,15 +43,19 @@ flowchart TD
34
43
35
44
## Dep Boundary
36
45
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.
38
49
39
50
## Architecture
40
51
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).
43
56
-**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).
44
57
-**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.
46
59
47
60
## Development
48
61
@@ -69,14 +82,23 @@ pnpm -C docs run docs # docs dev server
69
82
70
83
### Devframe design principles
71
84
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".
73
86
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.
74
88
-**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.
75
89
-**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.
78
92
-**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`.
79
93
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
+
80
102
## Structured Diagnostics (Error Codes)
81
103
82
104
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
`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
+
93
117
Codes are sequential 4-digit numbers per prefix (e.g. `DTK0033`, `RDDT0003`). Check the existing diagnostics file to find the next available number.
0 commit comments