From 4d765dd56ce43af0a4c353cdc02e5bdb0a196556 Mon Sep 17 00:00:00 2001 From: Sakana <15715093608@163.com> Date: Fri, 23 Oct 2026 14:11:52 +0800 Subject: [PATCH] docs(kit): correct lifecycle, JSON dock and remote URL examples --- docs/kit/commands.md | 6 +++--- docs/kit/dock-system.md | 8 ++++---- docs/kit/json-render.md | 8 ++++---- docs/kit/messages.md | 12 ++++++------ docs/kit/remote-client.md | 10 +++++----- docs/kit/remote-demo.md | 2 +- docs/kit/terminals.md | 4 ++-- packages/core/src/node/json-render.ts | 9 ++++----- skills/vite-devtools-kit/SKILL.md | 2 +- .../vite-devtools-kit/references/dock-entry-types.md | 4 ++-- .../references/json-render-patterns.md | 6 +++--- .../references/remote-client-patterns.md | 10 +++++----- 12 files changed, 40 insertions(+), 41 deletions(-) diff --git a/docs/kit/commands.md b/docs/kit/commands.md index 169be7c02..b6a1f7aba 100644 --- a/docs/kit/commands.md +++ b/docs/kit/commands.md @@ -271,13 +271,13 @@ for (const cmd of commands) { } ``` -Subscribe to lifecycle events to react to registrations: +Subscribe to lifecycle events in the Node process to react to registrations: ```ts -ctx.commands.events.on('command:registered', (cmd) => { +ctx.commands.events.on('commands:registered', (cmd) => { console.log('new command:', cmd.id) }) -ctx.commands.events.on('command:unregistered', (id) => { +ctx.commands.events.on('commands:unregistered', (id) => { console.log('removed:', id) }) ``` diff --git a/docs/kit/dock-system.md b/docs/kit/dock-system.md index 6150b0c29..536a71853 100644 --- a/docs/kit/dock-system.md +++ b/docs/kit/dock-system.md @@ -98,8 +98,8 @@ interface DockEntry { /** Author-set single line of progress/status, shown inline on the card */ digest?: string } - /** JsonRenderer handle created by ctx.createJsonRenderer() (for type: 'json-render') */ - ui?: JsonRenderer + /** Serializable view reference from ctx.createJsonRenderer() (for type: 'json-render') */ + view?: JsonRenderViewRef } ``` @@ -425,7 +425,7 @@ The launcher tracks the spawned process for the life of the embed. When that pro JSON render panels describe a UI as a JSON spec on the server — the client renders it from a built-in component library. This is the shortest path to a DevTools panel: server-side TypeScript only. -Create a renderer handle with `ctx.createJsonRenderer()` and pass it as `ui` when registering a `json-render` dock entry: +Create a renderer handle with `ctx.createJsonRenderer()` and pass its `view` reference when registering a `json-render` dock entry: ```ts const ui = ctx.createJsonRenderer({ @@ -457,7 +457,7 @@ ctx.docks.register({ title: 'My Panel', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) ``` diff --git a/docs/kit/json-render.md b/docs/kit/json-render.md index 26588205d..d7069879a 100644 --- a/docs/kit/json-render.md +++ b/docs/kit/json-render.md @@ -10,7 +10,7 @@ Vite DevTools provides `ctx.createJsonRenderer()`; the `JsonRenderSpec` / `JsonR ## Getting started -Create a renderer handle with `ctx.createJsonRenderer()` and pass it as `ui` when registering a `json-render` dock entry: +Create a renderer handle with `ctx.createJsonRenderer()` and pass its `view` reference when registering a `json-render` dock entry: ```ts import type { PluginWithDevTools } from '@vitejs/devtools-kit' @@ -49,7 +49,7 @@ export function MyPlugin(): PluginWithDevTools { title: 'My Panel', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) }, }, @@ -109,7 +109,7 @@ ctx.docks.update({ type: 'json-render', title: 'My Panel', icon: 'ph:chart-bar-duotone', - ui, + view: ui.view, badge: hasWarnings ? '!' : undefined, }) ``` @@ -701,7 +701,7 @@ export function BuildReportPlugin(): PluginWithDevTools { title: 'Build Report', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) ctx.rpc.register(defineRpcFunction({ diff --git a/docs/kit/messages.md b/docs/kit/messages.md index d982af41b..b4a8cee19 100644 --- a/docs/kit/messages.md +++ b/docs/kit/messages.md @@ -167,19 +167,19 @@ The [A11y Checker example](/kit/examples#a11y-checker) is a plugin that uses mes ## Events -The host emits events for observers of the message stream: +The host emits these events within the Node process: ```ts -ctx.messages.events.on('message:added', (entry) => { /* ... */ }) -ctx.messages.events.on('message:updated', (entry) => { /* ... */ }) -ctx.messages.events.on('message:removed', (id) => { /* ... */ }) -ctx.messages.events.on('message:cleared', () => { /* ... */ }) +ctx.messages.events.on('messages:added', (entry) => { /* ... */ }) +ctx.messages.events.on('messages:updated', (entry) => { /* ... */ }) +ctx.messages.events.on('messages:removed', (id) => { /* ... */ }) +ctx.messages.events.on('messages:cleared', () => { /* ... */ }) ``` Use the events to bridge messages into external tools — mirror them into a structured log, forward certain categories to your own reporter, etc.: ```ts -ctx.messages.events.on('message:added', (entry) => { +ctx.messages.events.on('messages:added', (entry) => { if (entry.category === 'a11y') console.log('a11y finding:', entry.message) }) diff --git a/docs/kit/remote-client.md b/docs/kit/remote-client.md index 5f95feb81..767cd7678 100644 --- a/docs/kit/remote-client.md +++ b/docs/kit/remote-client.md @@ -85,8 +85,8 @@ interface RemoteDockOptions { #### `transport` -- **`'fragment'` (default)** — the descriptor rides as a URL fragment (`#vite-devtools-kit-connection=...`). Fragments stay client-side: they don't reach servers, don't enter access logs, and get stripped from `Referer` on sub-resource requests. The safest place to carry an auth token. -- **`'query'`** — the descriptor rides as a query parameter (`?vite-devtools-kit-connection=...`). Pick this when your SPA router uses the fragment for navigation, or when your hosting platform / CDN rewrites URLs in a way that drops fragments. +- **`'fragment'` (default)** — the descriptor rides as a URL fragment (`#devframe-remote-connection=...`). Fragments stay client-side: they don't reach servers, don't enter access logs, and get stripped from `Referer` on sub-resource requests. The safest place to carry an auth token. +- **`'query'`** — the descriptor rides as a query parameter (`?devframe-remote-connection=...`). Pick this when your SPA router uses the fragment for navigation, or when your hosting platform / CDN rewrites URLs in a way that drops fragments. > [!WARNING] > With `'query'` transport, the auth token appears in server access logs and outbound `Referer` headers. Use it only when you control the analytics / log pipeline on the hosted origin. @@ -156,8 +156,8 @@ const rpc = await connectRemoteDevTools({ For testing or non-browser environments, pass an explicit URL or raw fragment/query string to `parseRemoteConnection`: ```ts -parseRemoteConnection('https://example.com/p#vite-devtools-kit-connection=...') -parseRemoteConnection('?vite-devtools-kit-connection=...') +parseRemoteConnection('https://example.com/p#devframe-remote-connection=...') +parseRemoteConnection('?devframe-remote-connection=...') ``` ## Descriptor shape @@ -176,7 +176,7 @@ interface RemoteConnectionInfo { } ``` -It's JSON-encoded and base64url-encoded, then appended to the iframe URL under the parameter name `vite-devtools-kit-connection`. +It's JSON-encoded and base64url-encoded, then appended to the iframe URL under the parameter name `devframe-remote-connection`. ## Trust boundary diff --git a/docs/kit/remote-demo.md b/docs/kit/remote-demo.md index 38f2511f7..6d6b84c0b 100644 --- a/docs/kit/remote-demo.md +++ b/docs/kit/remote-demo.md @@ -174,7 +174,7 @@ ctx.docks.register({ ## How it works 1. Your plugin registers an iframe dock with `remote: true` pointing at this page. -2. The DevTools core allocates a session-only auth token and appends the connection descriptor to the iframe URL: `#vite-devtools-kit-connection=…` +2. The DevTools core allocates a session-only auth token and appends the connection descriptor to the iframe URL: `#devframe-remote-connection=…` 3. When this page loads, [`parseRemoteConnection()`](./remote-client#connect-from-the-hosted-page) reads the descriptor, and [`connectRemoteDevTools()`](./remote-client#connect-from-the-hosted-page) opens a WebSocket back to the local dev server. 4. The live "dock registry" list above subscribes to the `devframe:docks` shared state — it re-renders on every registration change. diff --git a/docs/kit/terminals.md b/docs/kit/terminals.md index 867789b13..309e176fb 100644 --- a/docs/kit/terminals.md +++ b/docs/kit/terminals.md @@ -132,10 +132,10 @@ ctx.terminals.update({ ## Events -Subscribe to lifecycle changes (register, update, remove) via the host event emitter: +Subscribe to lifecycle changes (register, update, remove) through the host event emitter in the Node process: ```ts -ctx.terminals.events.on('terminal:session:updated', (session) => { +ctx.terminals.events.on('terminals:session:updated', (session) => { console.log(session.id, session.status) }) ``` diff --git a/packages/core/src/node/json-render.ts b/packages/core/src/node/json-render.ts index c2263c24c..002627120 100644 --- a/packages/core/src/node/json-render.ts +++ b/packages/core/src/node/json-render.ts @@ -27,8 +27,8 @@ export type { JsonRenderView, JsonRenderViewRef } * The handle returned by `ctx.createJsonRenderer()`. It wraps a devframe * {@link JsonRenderView} and exposes the kit's method names. * - * Register a `json-render` dock entry with the handle as `ui` - * (`docks.register({ type: 'json-render', ui, … })`); the client subscribes + * Register a `json-render` dock entry with the handle's `view` reference + * (`docks.register({ type: 'json-render', view: ui.view, … })`); the client subscribes * through its `stateKey`. Drive the panel by calling `updateSpec` / * `updateState` on the handle. */ @@ -70,9 +70,8 @@ export function attachJsonRenderer(context: KitNodeContext): void { const createJsonRenderer: CreateJsonRenderer = (spec, options = {}) => { const view = createJsonRenderView(context, { id: `kit-${nanoid()}`, spec, ...options }) - // Methods are non-enumerable so the handle stays serializable when carried - // on a dock entry's `ui` field — the docks shared-state projection walks - // only enumerable own keys, so the closures never reach the wire. + // Keep methods non-enumerable on the handle. Dock entries carry handle.view, + // the serializable reference that clients use to subscribe to the spec. const handle = { _stateKey: view.ref.stateKey, view: view.ref, diff --git a/skills/vite-devtools-kit/SKILL.md b/skills/vite-devtools-kit/SKILL.md index 35f5ab101..4b0b583da 100644 --- a/skills/vite-devtools-kit/SKILL.md +++ b/skills/vite-devtools-kit/SKILL.md @@ -256,7 +256,7 @@ ctx.docks.register({ title: 'My Panel', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) ``` diff --git a/skills/vite-devtools-kit/references/dock-entry-types.md b/skills/vite-devtools-kit/references/dock-entry-types.md index af60c0712..2425a0f5a 100644 --- a/skills/vite-devtools-kit/references/dock-entry-types.md +++ b/skills/vite-devtools-kit/references/dock-entry-types.md @@ -232,7 +232,7 @@ Server-side JSON specs rendered by the built-in component library. No client cod ```ts interface JsonRenderEntry extends DockEntryBase { type: 'json-render' - ui: JsonRenderer // Handle from ctx.createJsonRenderer() + view: JsonRenderViewRef // Reference from ctx.createJsonRenderer().view } // Registration @@ -265,7 +265,7 @@ ctx.docks.register({ title: 'My Panel', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) ``` diff --git a/skills/vite-devtools-kit/references/json-render-patterns.md b/skills/vite-devtools-kit/references/json-render-patterns.md index c84304375..d0e46982f 100644 --- a/skills/vite-devtools-kit/references/json-render-patterns.md +++ b/skills/vite-devtools-kit/references/json-render-patterns.md @@ -44,7 +44,7 @@ ctx.docks.register({ title: 'My Panel', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) ``` @@ -70,7 +70,7 @@ ctx.docks.update({ type: 'json-render', title: 'My Panel', icon: 'ph:chart-bar-duotone', - ui, + view: ui.view, badge: hasWarnings ? '!' : undefined, }) ``` @@ -263,7 +263,7 @@ export function BuildReportPlugin(): PluginWithDevTools { title: 'Build Report', icon: 'ph:chart-bar-duotone', type: 'json-render', - ui, + view: ui.view, }) ctx.rpc.register(defineRpcFunction({ diff --git a/skills/vite-devtools-kit/references/remote-client-patterns.md b/skills/vite-devtools-kit/references/remote-client-patterns.md index 3c3f9b8a5..ad715349e 100644 --- a/skills/vite-devtools-kit/references/remote-client-patterns.md +++ b/skills/vite-devtools-kit/references/remote-client-patterns.md @@ -54,8 +54,8 @@ remote: { transport: 'query', originLock: false } | Value | Descriptor location | Visibility | |-------|--------------------|------------| -| `'fragment'` (default) | `#vite-devtools-kit-connection=...` | Not sent to servers, not in access logs, stripped from Referer | -| `'query'` | `?vite-devtools-kit-connection=...` | Appears in server logs and outbound Referer | +| `'fragment'` (default) | `#devframe-remote-connection=...` | Not sent to servers, not in access logs, stripped from Referer | +| `'query'` | `?devframe-remote-connection=...` | Appears in server logs and outbound Referer | Prefer `'fragment'`. Opt into `'query'` only when: - Your SPA router uses the fragment for navigation. @@ -113,8 +113,8 @@ const rpc = await connectRemoteDevTools({ For tests or non-browser environments, pass an explicit URL or raw fragment/query string to `parseRemoteConnection`: ```ts -parseRemoteConnection('https://example.com/p#vite-devtools-kit-connection=...') -parseRemoteConnection('?vite-devtools-kit-connection=...') +parseRemoteConnection('https://example.com/p#devframe-remote-connection=...') +parseRemoteConnection('?devframe-remote-connection=...') ``` ## Descriptor shape @@ -131,7 +131,7 @@ interface RemoteConnectionInfo { } ``` -JSON-encoded then base64url-encoded, appended to the iframe URL under the key `vite-devtools-kit-connection`. +JSON-encoded then base64url-encoded, appended to the iframe URL under the key `devframe-remote-connection`. ## Trust model