Skip to content
Merged
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
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ Describe what *is*, not what *isn't*. Replace constructions like "X is for Y, no
- ✅ "Analyses production builds in Vite 8+."

- ❌ "For tools that don't need Vite at all."
- ✅ "Standalone tools can build directly on DevFrame."
- ✅ "Standalone tools can build directly on Devframe."

### 2. Use callouts sparingly

Expand All @@ -207,9 +207,9 @@ Callouts (`> [!NOTE]`, `> [!TIP]`, `> [!INFO]`, `::: tip`, etc.) interrupt the r

### 3. Kit-first in `/docs/`

The main docs site is for **Vite DevTools** and **`@vitejs/devtools-kit`** users. DevFrame is the framework-neutral foundation underneath; mention it where relevant ("Kit is built on DevFrame; standalone tools can use DevFrame directly — see [DevFrame](https://devfra.me/guide/)") but lead examples and guides with the Kit / Vite plugin path.
The main docs site is for **Vite DevTools** and **`@vitejs/devtools-kit`** users. Devframe is the framework-neutral foundation underneath; mention it where relevant ("Kit is built on Devframe; standalone tools can use Devframe directly — see [Devframe](https://devfra.me/guide/)") but lead examples and guides with the Kit / Vite plugin path.

`devframe/docs/` is the inverse: DevFrame-first, with cross-links to Kit for hub-only features (docks, terminals, messages, commands).
`devframe/docs/` is the inverse: Devframe-first, with cross-links to Kit for hub-only features (docks, terminals, messages, commands).

### 4. Concise and precise

Expand Down
2 changes: 1 addition & 1 deletion devframe/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# DevFrame
# Devframe

Framework-neutral foundation for building generic DevTools — an RPC layer (birpc + valibot + WS presets), runtime hosts (RPC / docks / views / terminals / logs / commands / agent), and adapters that deploy a single devtool definition to seven targets: `cli`, `build`, `vite`, `kit`, `embedded`, `mcp`, plus the `spa` mode.

Expand Down
2 changes: 1 addition & 1 deletion devframe/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function devframeNav(prefix = ''): DefaultTheme.NavItemWithLink[] {
}

export default withMermaid(defineConfig({
title: 'DevFrame',
title: 'Devframe',
description: 'Framework-neutral foundation for building generic DevTools — RPC layer, hosts, and adapters.',
themeConfig: {
nav: [
Expand Down
2 changes: 1 addition & 1 deletion devframe/docs/errors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# Error Reference

DevFrame uses structured diagnostics to surface actionable warnings and errors at runtime. Each diagnostic has a unique error code, a human-readable message, and a link back to this documentation.
Devframe uses structured diagnostics to surface actionable warnings and errors at runtime. Each diagnostic has a unique error code, a human-readable message, and a link back to this documentation.

## How error codes work

Expand Down
4 changes: 2 additions & 2 deletions devframe/docs/guide/agent-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
outline: deep
---

# Agent-Native DevFrame
# Agent-Native Devframe

::: warning Experimental
The agent-native surface (`agent` field on `defineRpcFunction`, `DevToolsAgentHost`, and the `devframe/adapters/mcp` adapter) is experimental and may change without a major version bump until it stabilizes.
:::

DevFrame can expose the same surface the browser DevTools UI consumes — RPC functions, resources, and shared state — to coding agents (Claude Desktop / Cursor / Zed / Claude Code, or any MCP-speaking client). Agent exposure is opt-in per function; functions stay private by default.
Devframe can expose the same surface the browser DevTools UI consumes — RPC functions, resources, and shared state — to coding agents (Claude Desktop / Cursor / Zed / Claude Code, or any MCP-speaking client). Agent exposure is opt-in per function; functions stay private by default.

## How it works

Expand Down
6 changes: 3 additions & 3 deletions devframe/docs/guide/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# Client

The browser-side client is how a dock iframe, remote-hosted page, or standalone SPA talks to the DevFrame server. It provides type-safe RPC calls, access to shared state, and (in dev mode) a trust handshake against the local dev server.
The browser-side client is how a dock iframe, remote-hosted page, or standalone SPA talks to the Devframe server. It provides type-safe RPC calls, access to shared state, and (in dev mode) a trust handshake against the local dev server.

## Connecting

Expand All @@ -22,7 +22,7 @@ const modules = await rpc.call('my-devtool:get-modules', { limit: 10 })

### Runtime basePath discovery

DevFrame SPAs are base-agnostic — the same artifact can be served at `/`, `/__<id>/`, or any custom subpath without rebuilding. `connectDevtool` resolves `__connection.json` at runtime by reading `document.baseURI` and the executing script's URL.
Devframe SPAs are base-agnostic — the same artifact can be served at `/`, `/__<id>/`, or any custom subpath without rebuilding. `connectDevtool` resolves `__connection.json` at runtime by reading `document.baseURI` and the executing script's URL.

For SPA authors, that means:

Expand Down Expand Up @@ -158,7 +158,7 @@ With caching on, `query` / `static` function responses are memoized per argument

## Discovery (`__connection.json`)

DevFrame writes a JSON descriptor at `<base>/__connection.json` so the client knows where to connect:
Devframe writes a JSON descriptor at `<base>/__connection.json` so the client knows where to connect:

```json
{
Expand Down
2 changes: 1 addition & 1 deletion devframe/docs/guide/devtool-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# Devtool Definition

Every DevFrame tool starts with a single `defineDevtool` call. The returned `DevtoolDefinition` 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.
Every Devframe tool starts with a single `defineDevtool` call. The returned `DevtoolDefinition` 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.

## Minimal definition

Expand Down
24 changes: 12 additions & 12 deletions devframe/docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@
outline: deep
---

# DevFrame
# Devframe

**DevFrame** is the container for one devtool integration, portable across viewers. You describe a single tool — its RPC surface, its data model, its SPA, its CLI shape — and DevFrame deploys the same definition through any number of runtime adapters: a standalone CLI, a self-contained static report, an embedded SPA, an MCP server, or mounted inside a multi-integration hub.
**Devframe** is the container for one devtool integration, portable across viewers. You describe a single tool — its RPC surface, its data model, its SPA, its CLI shape — and Devframe deploys the same definition through any number of runtime adapters: a standalone CLI, a self-contained static report, an embedded SPA, an MCP server, or mounted inside a multi-integration hub.

DevFrame's surface is one tool. Hub-level features — docking, the command palette, terminal aggregation, cross-tool toasts — live in [`@vitejs/devtools-kit`](https://devtools.vite.dev/kit/). To drop a DevFrame app into Vite DevTools, wrap it with `createPluginFromDevframe` from `@vitejs/devtools-kit/node`; the kit synthesises the dock entry from your definition's `id` / `name` / `icon` / `basePath` and routes the hub-level ctx fields (`docks`, `terminals`, …) accordingly.
Devframe's surface is one tool. Hub-level features — docking, the command palette, terminal aggregation, cross-tool toasts — live in [`@vitejs/devtools-kit`](https://devtools.vite.dev/kit/). To drop a Devframe app into Vite DevTools, wrap it with `createPluginFromDevframe` from `@vitejs/devtools-kit/node`; the kit synthesises the dock entry from your definition's `id` / `name` / `icon` / `basePath` and routes the hub-level ctx fields (`docks`, `terminals`, …) accordingly.

> [!WARNING] Experimental
> The DevFrame API is still in development and may change between versions. The agent-native surface (`agent` on `defineRpcFunction`, `ctx.agent`, and the MCP adapter) is additionally flagged as experimental.
> The Devframe API is still in development and may change between versions. The agent-native surface (`agent` on `defineRpcFunction`, `ctx.agent`, and the MCP adapter) is additionally flagged as experimental.

## Design principles

DevFrame keeps its surface small and pushes hub-level UX to the kit consuming it:
Devframe keeps its surface small and pushes hub-level UX to the kit consuming it:

- **Single-integration scope.** DevFrame describes one tool. Anything that only matters across tools — docks, palette, cross-tool toasts, unified terminals — belongs in the [DevTools Kit](https://devtools.vite.dev/kit/).
- **Headless.** Hook into `onReady`, `cli.configure`, and friends to print your own startup banners and styling — DevFrame stays out of the way.
- **Single-integration scope.** Devframe describes one tool. Anything that only matters across tools — docks, palette, cross-tool toasts, unified terminals — belongs in the [DevTools Kit](https://devtools.vite.dev/kit/).
- **Headless.** Hook into `onReady`, `cli.configure`, and friends to print your own startup banners and styling — Devframe stays out of the way.
- **App-owned file watching.** Wire your own watcher (chokidar, fs.watch, …) and signal change via `ctx.rpc.sharedState.set(...)` or event-typed RPCs.
- **Context-aware mount paths.** Standalone adapters (`cli`, `spa`, `build`) serve at `/` by default; hosted adapters (`vite`, `embedded`, kit's `createPluginFromDevframe`) serve at `/.<id>/`. Override via `DevtoolDefinition.basePath`.
- **SPAs own their base at runtime.** Build with relative asset paths (`vite.base: './'`); `connectDevtool` discovers the effective base from the executing script's location.
- **CLI flags compose.** The `cac` instance is exposed to both the devtool (`cli.configure`) and the caller of `createCli`, so capability flags and app flags merge cleanly.

## What DevFrame provides
## What Devframe provides

| Subsystem | What it does |
|-----------|--------------|
Expand Down Expand Up @@ -76,7 +76,7 @@ pnpm add devframe

`devframe` ships ESM-only and has no Vite dependency. Adapters with optional peers (the MCP adapter needs `@modelcontextprotocol/sdk`) surface the requirement at import time.

## Hello, DevFrame
## Hello, Devframe

A minimal devtool with a CLI entry point:

Expand Down Expand Up @@ -128,7 +128,7 @@ The CLI adapter serves the SPA at `/` by default. When the same devtool is embed

## Adapters at a glance

DevFrame deploys the same `DevtoolDefinition` through one of these adapters:
Devframe deploys the same `DevtoolDefinition` through one of these adapters:

| Adapter | Entry | Target |
|---------|-------|--------|
Expand All @@ -143,9 +143,9 @@ DevFrame deploys the same `DevtoolDefinition` through one of these adapters:

## Dependency boundary

DevFrame is the lowest-level package in the Vite DevTools monorepo and is positioned to be extracted into its own repo. Imports from Vite or any `@vitejs/*` package are out of scope, in source and at the dependency-graph level. Hub-only concepts (docks, terminals, messages, commands) belong in the layers above:
Devframe is the lowest-level package in the Vite DevTools monorepo and is positioned to be extracted into its own repo. Imports from Vite or any `@vitejs/*` package are out of scope, in source and at the dependency-graph level. Hub-only concepts (docks, terminals, messages, commands) belong in the layers above:

- `@vitejs/devtools-kit` — the hub. Owns docking, terminals, messages, and the command palette; provides `createPluginFromDevframe` to bridge a DevFrame app into Vite DevTools.
- `@vitejs/devtools-kit` — the hub. Owns docking, terminals, messages, and the command palette; provides `createPluginFromDevframe` to bridge a Devframe app into Vite DevTools.
- `@vitejs/devtools` — the integration. Vite plugin that wraps the kit and exposes Vite DevTools' own UI.

For porting an existing inspector, use the [`cli`](./adapters#cli) adapter standalone and `createPluginFromDevframe` (from `@vitejs/devtools-kit/node`) to surface it inside Vite DevTools.
Expand Down
6 changes: 3 additions & 3 deletions devframe/docs/guide/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# RPC

DevFrame's RPC layer is type-safe bidirectional communication between your server (Node.js) and client (browser), built on [`birpc`](https://github.com/antfu/birpc) and validated at runtime with [`valibot`](https://valibot.dev/). In dev mode it runs over WebSocket; in build / SPA mode it serves a pre-computed static dump so the client still works offline.
Devframe's RPC layer is type-safe bidirectional communication between your server (Node.js) and client (browser), built on [`birpc`](https://github.com/antfu/birpc) and validated at runtime with [`valibot`](https://valibot.dev/). In dev mode it runs over WebSocket; in build / SPA mode it serves a pre-computed static dump so the client still works offline.

## Overview

Expand Down Expand Up @@ -179,7 +179,7 @@ Client-side registration (for server→client calls) goes through `rpc.client.re

## Static dumps

For `static` functions, DevFrame records the handler's output during `createBuild` and bakes it into the build:
For `static` functions, Devframe records the handler's output during `createBuild` and bakes it into the build:

```ts
defineRpcFunction({
Expand Down Expand Up @@ -213,7 +213,7 @@ At runtime, static clients resolve `rpc.call('my-devtool:get-session', 'session-

## JSON-serializable declaration

DevFrame's WS transport ships payloads using one of two encoders, picked per RPC function:
Devframe's WS transport ships payloads using one of two encoders, picked per RPC function:

| `jsonSerializable` | Encoder | Wire prefix | Round-trips |
|---|---|---|---|
Expand Down
6 changes: 3 additions & 3 deletions devframe/docs/guide/shared-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ outline: deep

# Shared State

Shared state is observable, immutable-by-default state synced between the server and every connected client. It's built on [`immer`](https://immerjs.github.io/immer/): you mutate a draft, DevFrame computes the patches to broadcast.
Shared state is observable, immutable-by-default state synced between the server and every connected client. It's built on [`immer`](https://immerjs.github.io/immer/): you mutate a draft, Devframe computes the patches to broadcast.

Shared state survives reconnects — a newly connected client receives the current snapshot before any further updates. Use it for anything that should stay reactive.

Expand Down Expand Up @@ -71,13 +71,13 @@ state.mutate((draft) => {
})
```

Under the hood, DevFrame:
Under the hood, Devframe:

1. Applies the recipe to the current state via `immer.produce`.
2. Emits an `updated` event with the new state (and patches, if enabled).
3. Broadcasts the update to all connected clients.

Mutations are idempotent across replay — DevFrame tracks a `syncIds` set internally so a patch round-tripped back from a client applies once.
Mutations are idempotent across replay — Devframe tracks a `syncIds` set internally so a patch round-tripped back from a client applies once.

## Patches (advanced)

Expand Down
4 changes: 2 additions & 2 deletions devframe/docs/guide/standalone-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
outline: deep
---

# Standalone CLI with DevFrame
# Standalone CLI with Devframe

This recipe walks through building a standalone CLI devtool on top of DevFrame — the shape where a user runs `npx my-tool` and gets a local dev server serving a Vue / Nuxt / React SPA backed by type-safe RPC, plus `build` / `spa` / `mcp` subcommands for free.
This recipe walks through building a standalone CLI devtool on top of Devframe — the shape where a user runs `npx my-tool` and gets a local dev server serving a Vue / Nuxt / React SPA backed by type-safe RPC, plus `build` / `spa` / `mcp` subcommands for free.

It's the pattern used by tools like an ESLint config inspector or a bundler-config viewer: a binary that opens a browser.

Expand Down
2 changes: 1 addition & 1 deletion devframe/docs/guide/when-clauses.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ outline: deep

When clauses are conditional expressions that gate the visibility and executability of docks, commands, and any other UI surface you wire them into. The syntax matches [VS Code's when-clause contexts](https://code.visualstudio.com/api/references/when-clause-contexts), evaluated against a reactive context object.

The evaluator is the external [`whenexpr`](https://github.com/antfu/whenexpr) package. DevFrame re-exports `evaluateWhen`, `resolveContextValue`, and the `WhenExpression<Ctx, S>` type helper from `devframe/utils/when`.
The evaluator is the external [`whenexpr`](https://github.com/antfu/whenexpr) package. Devframe re-exports `evaluateWhen`, `resolveContextValue`, and the `WhenExpression<Ctx, S>` type helper from `devframe/utils/when`.

## Usage

Expand Down
4 changes: 2 additions & 2 deletions devframe/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: home

hero:
name: DevFrame
name: Devframe
text: Framework-neutral foundation for DevTools
tagline: One devtool definition. Seven adapters. RPC, hosts, shared state, agent-native — without depending on Vite or any framework.
actions:
Expand All @@ -21,7 +21,7 @@ features:
details: Bidirectional, schema-validated calls built on birpc + valibot. Query, static, action, and event function types.
link: /guide/rpc
- title: Headless by Default
details: No banners, no logging, no opinionated styling. Hooks let your app own the UX while DevFrame owns the plumbing.
details: No banners, no logging, no opinionated styling. Hooks let your app own the UX while Devframe owns the plumbing.
link: /guide/
- title: Agent-Native (experimental)
details: Surface your devtool's RPC functions, tools, and resources to coding agents over MCP with a single field.
Expand Down
4 changes: 2 additions & 2 deletions devframe/packages/devframe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ pnpm add devframe

## Docs

See the [DevFrame documentation](https://devfra.me/) for the full guide and API reference.
See the [Devframe documentation](https://devfra.me/) for the full guide and API reference.

## Agent-Native (experimental)

> ⚠️ **Experimental.** The agent-native surface — the `agent` field on `defineRpcFunction`, `DevToolsAgentHost`, and the `devframe/adapters/mcp` adapter — is experimental and may change without a major version bump until it stabilizes.

DevFrame can expose a devtool's RPC functions, tools, and resources to coding agents over [MCP](https://modelcontextprotocol.io). Flag an RPC function with `agent: { description }` to surface it, then spin up an MCP server:
Devframe can expose a devtool's RPC functions, tools, and resources to coding agents over [MCP](https://modelcontextprotocol.io). Flag an RPC function with `agent: { description }` to surface it, then spin up an MCP server:

```ts
import { defineDevtool, defineRpcFunction } from 'devframe'
Expand Down
2 changes: 1 addition & 1 deletion devframe/packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@devframes/nuxt",
"type": "module",
"version": "0.1.21",
"description": "Nuxt module for DevFrame — wires a Nuxt-built SPA up as a devframe client",
"description": "Nuxt module for Devframe — wires a Nuxt-built SPA up as a devframe client",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"homepage": "https://github.com/vitejs/devtools#readme",
Expand Down
Loading
Loading