Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Monorepo (`pnpm` workspaces + `turbo`). ESM TypeScript; bundled with `tsdown`. P
| `packages/vite` | `@vitejs/devtools-vite` | Nuxt UI for the Vite dev server's plugin pipeline and module transforms. Hub-mounted via `Plugin.devtools.setup`. Serves at `/__devtools-vite/`. |
| `packages/oxc` | `@vitejs/devtools-oxc` | Oxc toolchain (oxlint/oxfmt) inspector, donated from [`yuyinws/oxc-inspector`](https://github.com/yuyinws/oxc-inspector) with full history; owned by Leo. Advertised by core as a built-in install launcher in the `viteplus` group (installed on demand), mounted via `DevToolsOxc()` from `@vitejs/devtools-oxc/vite` once present, plus a standalone CLI/client. Its Nuxt client is on the shared stack — UnoCSS via `presetDevToolsUI` and `@vitejs/devtools-ui` components (an oxc-cyan `primary` scale derived from the `BannerOxcDevTools` accent) — and is wired into the turbo build, `vue-tsc` typecheck (own `src/tsconfig.json` reference) and export-snapshot gates. It dogfoods its own oxlint/oxfmt on itself (run `pnpm -C packages/oxc lint`), whose formatting conflicts with the repo-wide antfu ESLint config, so it stays out of the shared ESLint run. |
| `packages/vitest` | `@vitejs/devtools-vitest` | Slim launcher for the Vitest UI, in the `viteplus` dock group. A `launcher` dock (only shown when the project uses Vitest) installs `@vitest/ui` on demand, spawns `vitest --ui`, then swaps to an iframe. Serves its favicon at `/__devtools-vitest/`. |
| `packages/agent` | `@vitejs/devtools-agent` | Agent (MCP) access to Vite DevTools. `DevToolsAgent()` registers read-only RPC queries marked with `agent` metadata, exposed through the host's `/__devtools/__mcp` route: `vite:agent:*` (Vite dev-server modules, transforms and plugin activity, backed by `@vitejs/devtools-vite`'s `vite:inspect:*` RPC) and `vite:rolldown:agent:*` (recorded Rolldown builds read from `node_modules/.rolldown` through `@vitejs/devtools-rolldown/node`). Both integrations are optional peers detected with `isPackageExists` at call time; a missing package returns an install hint (`AGDT0003`). |
| `packages/webext` | — | Browser extension scaffolding (ancillary). |

Meta-introspection ("DevTools for the DevTools") is provided by the official upstream `@devframes/plugin-inspect`, mounted as a built-in via `createPluginFromDevframe` (replaces the former `packages/self-inspect`).
Expand All @@ -38,10 +39,12 @@ flowchart TD
hub --> devframe
kit --> hub
core --> kit
core --> rolldown & vite & vitest
core --> rolldown & vite & vitest & agent
rolldown --> kit & ui
vite --> kit & ui
vitest --> kit
agent --> kit
agent -.-> rolldown & vite
webext --> core
```

Expand All @@ -62,6 +65,7 @@ flowchart TD
- **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`.
- **Hub-mounted Nuxt UI plugins** (rolldown, vite): each implements `Plugin.devtools.setup`, receives a `KitNodeContext`, registers RPC functions, hosts a static Nuxt SPA, and registers its dock entry.
- **Built-in devframe plugins** (`@devframes/plugin-inspect` today; `@devframes/plugin-terminals` / `@devframes/plugin-messages`): official portable `DevframeDefinition`s mounted as built-ins by `DevTools()` via kit's `createPluginFromDevframe` (gated by `builtinDevTools`).
- **Built-in agent integration** (`packages/core/src/node/plugins/builtin.ts` + `packages/agent`): when `@vitejs/devtools-agent` is installed, `DevTools()` mounts `DevToolsAgent()` (gated by `builtinDevTools`; manual registration coexists, duplicates are skipped). It has no install launcher — installing the package is the opt-in. Its Rolldown and Vite tools detect their own integration packages with `isPackageExists` rather than importing them eagerly.
- **Built-in install launchers** (`packages/core/src/node/plugins/index.ts` + kit's `createInstallLauncher`): keeps core dependency-light. For each optional integration (Rolldown / Vite / Vitest / Oxc) `DevTools()` mounts the real plugin when its package is installed, else registers a discovery launcher that installs it on demand (via `package-manager-detector`) and prompts a restart. The `@vitejs/devtools-*` packages are declared as optional peer deps; their marks are vendored in `packages/core/assets` and served at `/__devtools-assets/` so a launcher icon renders before its package exists.

## Development
Expand Down Expand Up @@ -111,6 +115,7 @@ All node-side warnings and errors use structured diagnostics via [`nostics`](htt
| `VDT` | `packages/vite` | `packages/vite/src/node/diagnostics.ts` |
| `VTDT` | `packages/vitest` | `packages/vitest/src/node/diagnostics.ts` |
| `OXDT` | `packages/oxc` | `packages/oxc/src/node/diagnostics.ts` |
| `AGDT` | `packages/agent` | `packages/agent/src/node/diagnostics.ts` |

`DF` codes belong to the upstream devframe/hub projects — file new ones there. The `DF8xxx` sub-range covers `@devframes/hub` (DF8100–DF8199 docks, DF8200–DF8299 terminals, DF8300–DF8399 messages, DF8400–DF8499 commands).

Expand Down Expand Up @@ -174,7 +179,7 @@ The sidebar in `docs/.vitepress/config.ts` globs the `errors/` directory by pref

### Scope

- **Node-side only**: `packages/kit/src/node`, `packages/core/src/node`, `packages/rolldown/src/node`, `packages/vite/src/node`, `packages/vitest/src/node`, `packages/oxc/src/node`.
- **Node-side only**: `packages/kit/src/node`, `packages/core/src/node`, `packages/rolldown/src/node`, `packages/vite/src/node`, `packages/vitest/src/node`, `packages/oxc/src/node`, `packages/agent/src/node`.
- **Client-side excluded**: Vue components, webcomponents, and browser-only code keep using `console.*` / `throw`.

## Before PRs
Expand Down
2 changes: 2 additions & 0 deletions alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const alias = {
'@vitejs/devtools-kit/utils/when': r('kit/src/utils/when.ts'),
'@vitejs/devtools-kit/utils/shared-state': r('kit/src/utils/shared-state.ts'),
'@vitejs/devtools-kit': r('kit/src/index.ts'),
'@vitejs/devtools-agent': r('agent/src/index.ts'),
'@vitejs/devtools-rolldown/node': r('rolldown/src/node/api.ts'),
'@vitejs/devtools-rolldown': r('rolldown/src/index.ts'),
'@vitejs/devtools-vite': r('vite/src/index.ts'),
'@vitejs/devtools-vitest': r('vitest/src/index.ts'),
Expand Down
9 changes: 9 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default extendConfig(withMermaid(defineConfig({
text: 'Guide',
items: [
{ text: 'Getting Started', link: '/guide/' },
{ text: 'Agents', link: '/guide/agents' },
{ text: 'Chrome Extension', link: '/guide/chrome-extension' },
],
},
Expand Down Expand Up @@ -159,6 +160,14 @@ export default extendConfig(withMermaid(defineConfig({
link: `/errors/${code}`,
})),
},
{
text: 'Agent Integration (AGDT)',
collapsed: true,
items: listErrorCodes('AGDT').map(code => ({
text: code,
link: `/errors/${code}`,
})),
},
{
text: 'Rolldown DevTools (RDDT)',
collapsed: true,
Expand Down
20 changes: 20 additions & 0 deletions docs/errors/AGDT0001.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
outline: deep
---

# AGDT0001: Rolldown Session Not Found

## Message
> Rolldown session "`{id}`" was not found in this project.

## Cause
An agent requested a build session absent from the selected project's recorded builds.

## Example
A session id from another project, or a deleted build, is passed to the summary tool.

## Fix
List recorded sessions on the selected instance and use a returned id. Generate a recorded build when the list is empty.

## Source
- [`packages/agent/src/node/rolldown/index.ts`](https://github.com/vitejs/devtools/blob/main/packages/agent/src/node/rolldown/index.ts) — `loadSession()` checks that the session belongs to the current project.
20 changes: 20 additions & 0 deletions docs/errors/AGDT0002.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
outline: deep
---

# AGDT0002: Vite Inspection Not Active

## Message
> Vite inspection is not active in this project.

## Cause
An agent requested Vite inspection data while `@vitejs/devtools-vite` is installed but its inspector is not mounted.

## Example
Calling `vite:agent:modules` with `builtinDevTools: false` and without `DevToolsViteInspect()` registered, or before restarting after installing the package.

## Fix
Restart the dev server so the installed package is mounted. With `builtinDevTools: false`, explicitly register `DevToolsViteInspect()` alongside `DevToolsAgent()`.

## Source
- [`packages/agent/src/node/vite/index.ts`](https://github.com/vitejs/devtools/blob/main/packages/agent/src/node/vite/index.ts) — `inspect()` checks for the registered inspection RPC.
20 changes: 20 additions & 0 deletions docs/errors/AGDT0003.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
outline: deep
---

# AGDT0003: Integration Package Not Installed

## Message
> `{pkg}` is not installed in this project.

## Cause
An agent called a tool whose data comes from an integration package that cannot be resolved from the project directory. The Rolldown tools need `@vitejs/devtools-rolldown`; the Vite tools need `@vitejs/devtools-vite`.

## Example
Calling `vite:rolldown:agent:summary` in a project that installed only `@vitejs/devtools-agent`.

## Fix
Install the named package as a dev dependency and restart the dev server.

## Source
- [`packages/agent/src/node/integration.ts`](https://github.com/vitejs/devtools/blob/main/packages/agent/src/node/integration.ts) — `assertInstalled()` throws this before an integration's tool runs.
10 changes: 10 additions & 0 deletions docs/errors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,13 @@ Emitted by `@vitejs/devtools-oxc`.
| [OXDT0006](./OXDT0006) | error | Oxfmt Setup Failed |
| [OXDT0007](./OXDT0007) | error | Failed to Run Oxfmt |
| [OXDT0008](./OXDT0008) | error | Failed to Delete Format Result |

## Agent Integration (AGDT)

Emitted by `@vitejs/devtools-agent`.

| Code | Level | Title |
|------|-------|-------|
| [AGDT0001](./AGDT0001) | error | Rolldown Session Not Found |
| [AGDT0002](./AGDT0002) | error | Vite Inspection Not Active |
| [AGDT0003](./AGDT0003) | error | Integration Package Not Installed |
170 changes: 170 additions & 0 deletions docs/guide/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
outline: deep
---

# Agents

Use `@vitejs/devtools-agent` to let an agent inspect Vite development activity and recorded Rolldown builds through MCP.

## Choose the data you need

| You want to investigate | Use | Data source |
| --- | --- | --- |
| Module imports, code transformations or plugin activity during development | Vite tools | Activity already observed by the running dev server |
| Output size, bundled dependencies or changes between builds | Rolldown tools | Recorded builds in `<project>/node_modules/.rolldown` |

For example, ask “Which plugin changed this module during development?” or “What made this build larger than the previous one?” The agent selects tools, reads measurements and follows up with more queries. Queries read existing data; generating new observations requires visiting the app or recording a build.

## Connect your agent

### 1. Install and enable

Install the agent integration alongside Vite DevTools:

```bash
pnpm add -D @vitejs/devtools @vitejs/devtools-agent
```

For Vite development inspection, also install `@vitejs/devtools-vite`. For Rolldown build inspection, install `@vitejs/devtools-rolldown`:

```bash
pnpm add -D @vitejs/devtools-vite @vitejs/devtools-rolldown
```

Both tool sets stay listed in the agent's MCP tool list. A tool whose package is missing replies with an install hint, so the agent can ask you to install it.

Enable the host in your Vite configuration. It automatically mounts the installed integrations.

```ts
import { defineConfig } from 'vite'

export default defineConfig({
devtools: { apply: 'serve' },
})
```

### 2. Configure MCP

Add the connector to your agent's MCP configuration:

```json
{
"mcpServers": {
"devframe": {
"command": "npx",
"args": ["devframe", "connect"]
}
}
}
```

Start the dev server and open Vite DevTools in the app to make the host discoverable. Keep the server running while the agent queries it. For connector options, see [devframe](https://devfra.me/guide/).

### 3. Select the project

Ask the agent to discover instances, match `rootDir` to your project directory and use the selected port for tool calls. If several servers match, select the intended server before investigating.

Within that host, Vite queries select an instance and environment with `vite` and `env`. Rolldown queries select a recorded build with `session`.

## Vite: inspect development activity

> Find `src/main.ts` in the client environment. Show its importers and identify which transformation steps changed its code.

Start with `environments`, search with `modules`, then use the exact module id with `module` or `transforms`. Pass the chosen `vite` and `env` to each query.

Tool names use the prefix `vite:agent:`.

| Tool | Use it to |
| --- | --- |
| `environments` | Discover instance ids, project roots and environment names |
| `modules` | Search module ids and rank by transform duration or id |
| `module` | Inspect an exact module's imports and importers |
| `transforms` | Read the recorded resolved id and load/transform steps |
| `plugins` | Search plugin resolve/transform timings and call counts |

### Read transformation code

`transforms` returns step metadata by default. To inspect code:

1. Set `includeCode: true`.
2. Select a step with `offset` and `limit: 1`.
3. Read its `code`, then increase `codeOffset` by 4,000 while `codeHasMore` is true.

Each step returns up to 4,000 UTF-16 code units per call. Queries use recorded steps without triggering another transformation.

## Rolldown: inspect recorded builds

Rolldown tools query recorded builds in `<project>/node_modules/.rolldown` while the dev server runs. Enable `build.rolldownOptions.devtools` and run a build to record one.

> Compare this project's latest two recorded builds. Show the largest output-size increases and trace the dependencies in the affected files.

Use `project` to confirm the directory and `list-sessions` to select builds. For a single build, follow `summary` → `assets` → `modules` → `trace-dependency`.

Tool names use the prefix `vite:rolldown:agent:`.

| Tool | Use it to |
| --- | --- |
| `project` | Confirm project and workspace directories |
| `list-sessions` | List recorded builds, newest first, with their entries |
| `summary` | Read build totals, entries and available data |
| `assets` | Find output files by filename or initial/async/static scope |
| `modules` | Find module ids, optionally within an output file |
| `module` | Inspect an exact module's imports (with their import kind, such as static or dynamic) and importers |
| `packages` | Find packages, duplicate copies and transformed code sizes |
| `plugins` | Query hook timings and call counts by plugin and hook |
| `trace-dependency` | Follow dependency paths for a module, package or output file |
| `compare` | Compare asset, chunk, package or plugin changes between builds |

### Select a stable build

For session-based queries, omit `session` or use `latest` to begin. Use the returned session id for follow-up queries so a newly recorded build does not change the investigation. The `module` tool returns `null` when the requested module is absent. Its import list and importer list page separately.

A single build command can record several sessions seconds apart, such as the client and server builds of a framework. `latest` is the newest of them, so use the entries from `list-sessions` to select the build you mean, and compare sessions that share the same entries.

`compare` requires two concrete session ids. Deltas are **current minus previous**, with changed items ranked by absolute delta. Hashed filenames are matched heuristically, so renamed outputs can appear as additions and removals.

## Understand the results

### Pagination and partial data

List responses include `items`, `total`, `offset`, `limit` and `hasMore`. Search filters apply before pagination. Most lists allow up to 100 items per page; Vite transformations allow 20 steps. A module's imports and importers use separate offsets and limits (`importsOffset`, `importsLimit`, `importersOffset`, `importersLimit`). Dependency tracing uses a path limit rather than offset pagination.

| Result | Meaning and next step |
| --- | --- |
| Vite `available: false` | Follow the returned `hint`: install `@vitejs/devtools-vite` and restart, or check manual registration |
| Error naming a missing package | Install the named `@vitejs/devtools-*` package as a dev dependency and restart the dev server |
| Empty Vite modules or transformations | Visit the relevant app page to produce observations, then query again |
| Empty Rolldown sessions | Enable build recording and run a build |
| Package graph unsupported | Package data is unavailable; this does not establish that dependencies are absent |
| Trace `truncated: true` | Limits omitted paths; narrow the target or adjust the path/depth limit |

Trace paths report where they stop: a recorded entry, graph root, missing node, cycle or depth limit. Returned paths place a recorded entry ahead of a graph boundary, a depth limit, a cycle, or a missing node, and shorter paths come first within each group. A graph root is not necessarily an application entry. Paths show recorded connections; they do not establish which exports survive tree shaking. An output file such as a sourcemap can be present and still have no module graph.

### Metric meanings

| Measurement | Meaning |
| --- | --- |
| Asset bytes | Uncompressed emitted file size |
| Initial JS bytes | Uncompressed size of the first emitted file for each initial chunk: an entry chunk and the chunks it imports statically |
| Package bytes | Transformed code size before final output optimization |
| Chunk comparison bytes | Emitted size where available, otherwise transformed size |
| Plugin duration | Sum of recorded hook milliseconds; calls can overlap |

Plugin timings alone do not establish wall-clock savings or explain an HMR issue. Use them to choose where to inspect next.

## Manual registration

With `builtinDevTools: false`, register the agent and any required inspector explicitly:

```ts
import { DevToolsAgent } from '@vitejs/devtools-agent'
import { DevToolsViteInspect } from '@vitejs/devtools-vite'
import { defineConfig } from 'vite'

export default defineConfig({
devtools: { apply: 'serve', builtinDevTools: false },
plugins: [DevToolsAgent(), DevToolsViteInspect()],
})
```

Include `DevToolsViteInspect()` when inspecting development activity. Rolldown tools are registered whenever `@vitejs/devtools-rolldown` is installed and read recorded logs directly. Set `devtools.mcp` to `false` to disable the host's MCP endpoint.
21 changes: 21 additions & 0 deletions packages/agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# @vitejs/devtools-agent

Inspect Vite development servers and recorded Rolldown builds from agents through Vite DevTools and `devframe connect`.

Install alongside `@vitejs/devtools`; the host discovers and mounts the plugin automatically:

```sh
pnpm add -D @vitejs/devtools @vitejs/devtools-agent
```

```ts
import { defineConfig } from 'vite'

export default defineConfig({
devtools: { apply: 'serve' },
})
```

To inspect the Vite dev server, also install `@vitejs/devtools-vite`. To analyze a Rolldown build, install `@vitejs/devtools-rolldown`, enable build recording and run a build.

See the [Agents guide](https://devtools.vite.dev/guide/agents) for connector setup, project selection and build inspection.
Loading
Loading