From 29f3cb6d50151f8f80ce1d7b4ba8530511858d3c Mon Sep 17 00:00:00 2001 From: "Anthony Fu (via agent)" Date: Fri, 14 Aug 2026 12:10:48 +0000 Subject: [PATCH] feat(core): migrate to devframe 0.9.0-beta.4 and expose dockPreferences + embeddedVisibility Bump the devframe catalog to 0.9.0-beta.4 and surface the reference UI's `embeddedVisibility` and `dockPreferences` through `DevTools()` options, forwarding them to `createUi` so they publish via `ConnectionMeta.configs.ui`. The beta line moved the embedded dock's reveal policy from the injected `data-visibility` hint to connection-meta config, so the injection plugin now only bootstraps `embedded.js`; the former `visibility` option is renamed to `embeddedVisibility`. The dropped `devframe/helpers/vite` subpath is replaced with `devframeViteBridge` from `@devframes/vite/dev-spa` in the oxc Nuxt config. --- docs/guide/index.md | 22 +- packages/core/src/node/build-static.ts | 5 +- .../node/plugins/__tests__/injection.test.ts | 6 - packages/core/src/node/plugins/build.ts | 5 +- packages/core/src/node/plugins/index.ts | 34 +- packages/core/src/node/plugins/injection.ts | 21 +- packages/core/src/node/plugins/server.ts | 4 +- packages/core/src/node/server.ts | 8 +- packages/core/src/node/ui.ts | 28 +- packages/oxc/package.json | 1 + packages/oxc/src/nuxt.config.ts | 6 +- pnpm-lock.yaml | 361 ++++++++++-------- pnpm-workspace.yaml | 3 +- .../@vitejs/devtools/index.snapshot.d.ts | 1 + 14 files changed, 307 insertions(+), 198 deletions(-) diff --git a/docs/guide/index.md b/docs/guide/index.md index a04cfcc58..4546ecac4 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -99,7 +99,7 @@ pnpm dev Open your app in the browser; the floating docks appear in the corner. -The `visibility` option sets the starting mode. The default `'normal'` shows the docks immediately. `'passive'` keeps them out of the way and prints a console hint to reveal them with Shift + Alt + D ( D on macOS); revealing once is remembered in the project's `node_modules`, so later dev sessions on this machine open straight into the docks, and the "Hide DevTools" command returns to passive mode. `'hidden'` also starts hidden but never remembers — the shortcut reveals the docks for the current session only. +The `embeddedVisibility` option sets the starting mode. The default `'normal'` shows the docks immediately. `'passive'` keeps them out of the way and prints a console hint to reveal them with Shift + Alt + D ( D on macOS); revealing once persists per-origin in the browser, so later sessions on this browser open straight into the docks, and the "Hide DevTools" command returns to passive mode. `'hidden'` also starts hidden but never remembers — the shortcut reveals the docks for the current session only. ```ts [vite.config.ts] twoslash import { DevTools } from '@vitejs/devtools' @@ -108,7 +108,25 @@ import { defineConfig } from 'vite' export default defineConfig({ plugins: [ DevTools({ - visibility: 'passive', + embeddedVisibility: 'passive', + }), + ], +}) +``` + +The `dockPreferences` option seeds the dock bar's first-run layout — category ordering, the floating dock's inline-item capacity, and the default float/edge mode and position. Each is a user-overridable preference, so the visitor's own choice wins from then on. + +```ts [vite.config.ts] twoslash +import { DevTools } from '@vitejs/devtools' +import { defineConfig } from 'vite' + +export default defineConfig({ + plugins: [ + DevTools({ + dockPreferences: { + defaultMode: 'edge', + defaultPosition: 'bottom', + }, }), ], }) diff --git a/packages/core/src/node/build-static.ts b/packages/core/src/node/build-static.ts index fcf0c149f..737aa6650 100644 --- a/packages/core/src/node/build-static.ts +++ b/packages/core/src/node/build-static.ts @@ -1,6 +1,7 @@ /* eslint-disable no-console */ import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' +import type { ViteDevToolsUiOptions } from './ui' import { existsSync } from 'node:fs' import fs from 'node:fs/promises' import { DOCK_RENDERERS_STATE_KEY } from '@devframes/hub/constants' @@ -22,6 +23,8 @@ export interface BuildStaticOptions { context: ViteDevToolsNodeContext outDir: string withApp?: boolean + /** Reference-UI options forwarded to `createUi`. */ + ui?: ViteDevToolsUiOptions } export async function buildStaticDevTools(options: BuildStaticOptions): Promise { @@ -36,7 +39,7 @@ export async function buildStaticDevTools(options: BuildStaticOptions): Promise< // Bake the branded `@devframes/hub-ui` client into the snapshot: the // standalone viewer SPA, its embedded bootstrap, and the UI-owned assets // (e.g. `branding.json`) — the same `ui` slot the hub serves in dev. - const ui = createViteDevToolsUi() + const ui = createViteDevToolsUi(options.ui) if (ui.viewer) await fs.cp(ui.viewer.distDir, devToolsRoot, { recursive: true }) if (ui.embedded) diff --git a/packages/core/src/node/plugins/__tests__/injection.test.ts b/packages/core/src/node/plugins/__tests__/injection.test.ts index d6fc97c42..2fc3125af 100644 --- a/packages/core/src/node/plugins/__tests__/injection.test.ts +++ b/packages/core/src/node/plugins/__tests__/injection.test.ts @@ -17,11 +17,5 @@ describe('devToolsInjection', () => { expect(tag.injectTo).toBe('body') expect(tag.children).toContain(`${DEVTOOLS_MOUNT_PATH}embedded.js`) expect(tag.children).toContain('document.body.appendChild(s)') - expect(tag.children).toContain(`s.dataset.visibility = "normal"`) - }) - - it('forwards the visibility hint to the embedded bootstrap', () => { - const tag = injectedTags(DevToolsInjection({ visibility: 'passive' }))[0]! - expect(tag.children).toContain(`s.dataset.visibility = "passive"`) }) }) diff --git a/packages/core/src/node/plugins/build.ts b/packages/core/src/node/plugins/build.ts index 45ca1736e..80bd851eb 100644 --- a/packages/core/src/node/plugins/build.ts +++ b/packages/core/src/node/plugins/build.ts @@ -2,12 +2,15 @@ import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import type { Plugin, ResolvedConfig } from 'vite' +import type { ViteDevToolsUiOptions } from '../ui' import { colors as c } from 'devframe/utils/colors' import { resolve } from 'pathe' import { MARK_NODE } from '../constants' export interface DevToolsBuildOptions { outDir?: string + /** Reference-UI options forwarded to the static snapshot's `createUi`. */ + ui?: ViteDevToolsUiOptions } export function DevToolsBuild(options: DevToolsBuildOptions = {}): Plugin { @@ -35,7 +38,7 @@ export function DevToolsBuild(options: DevToolsBuildOptions = {}): Plugin { : resolve(resolvedConfig.root, resolvedConfig.build.outDir) const { buildStaticDevTools } = await import('../build-static') - await buildStaticDevTools({ context, outDir, withApp: true }) + await buildStaticDevTools({ context, outDir, withApp: true, ui: options.ui }) }, } } diff --git a/packages/core/src/node/plugins/index.ts b/packages/core/src/node/plugins/index.ts index 912cfae30..0d3b4f5cf 100644 --- a/packages/core/src/node/plugins/index.ts +++ b/packages/core/src/node/plugins/index.ts @@ -1,5 +1,5 @@ import type { Plugin } from 'vite' -import type { DevToolsVisibility } from './injection' +import type { ViteDevToolsUiOptions } from '../ui' import { DevToolsBuild } from './build' import { DevToolsBuiltin } from './builtin' import { DevToolsInjection } from './injection' @@ -16,19 +16,30 @@ export interface DevToolsOptions { builtinDevTools?: boolean /** - * Initial visibility of the injected overlay. + * How the embedded floating dock reveals itself on a fresh page. * * - `'normal'` — show the docks immediately. * - `'passive'` — the floating docks stay hidden and a console hint invites - * the developer to reveal them with a keyboard shortcut. Activating once - * persists a flag in the project's `node_modules`, so later dev sessions on - * this machine boot straight into normal mode. + * the developer to reveal them with a keyboard shortcut. Revealing once + * persists per-origin, so later dev sessions on this browser start shown; + * the "Hide DevTools" command returns to passive mode. * - `'hidden'` — always keep the docks hidden; the shortcut reveals them for * the current session only, without remembering the choice. * + * Seeds a user-overridable preference published as + * `ConnectionMeta.configs.ui.embeddedVisibility`. + * * @default 'normal' */ - visibility?: DevToolsVisibility + embeddedVisibility?: ViteDevToolsUiOptions['embeddedVisibility'] + + /** + * Dock-bar rendering preferences — category ordering, floating-dock + * inline-item capacity, and the first-run float/edge mode and position. + * Each seeds a user-overridable preference published as + * `ConnectionMeta.configs.ui.dockPreferences`. + */ + dockPreferences?: ViteDevToolsUiOptions['dockPreferences'] /** * Options for building static DevTools output alongside `vite build`. @@ -52,16 +63,19 @@ export async function DevTools(options: DevToolsOptions = {}): Promise const { builtinDevTools = true, build, - visibility = 'normal', + embeddedVisibility = 'normal', + dockPreferences, } = options + const ui = { embeddedVisibility, dockPreferences } + const plugins = [ - DevToolsInjection({ visibility }), - DevToolsServer(), + DevToolsInjection(), + DevToolsServer(ui), ] if (build?.withApp) { - plugins.push(DevToolsBuild({ outDir: build.outDir })) + plugins.push(DevToolsBuild({ outDir: build.outDir, ui })) } plugins.unshift( diff --git a/packages/core/src/node/plugins/injection.ts b/packages/core/src/node/plugins/injection.ts index 81b2a55cc..165d8885f 100644 --- a/packages/core/src/node/plugins/injection.ts +++ b/packages/core/src/node/plugins/injection.ts @@ -1,23 +1,13 @@ import type { Plugin } from 'vite' import { DEVTOOLS_MOUNT_PATH } from '@vitejs/devtools-kit/constants' -export type DevToolsVisibility = 'passive' | 'normal' | 'hidden' - -export interface DevToolsInjectionOptions { - /** - * Initial visibility of the injected overlay, forwarded to the - * `@devframes/hub-ui` embedded bootstrap as a `data-visibility` hint. - * - * @default 'normal' - */ - visibility?: DevToolsVisibility -} - /** * Inject the `@devframes/hub-ui` embedded bootstrap into the host app's HTML. * The hub serves the prebuilt, self-contained module at `embedded.js` * (the `ui.embedded` slot); the client bundles its own framework and styles - * and owns its visibility policy, so the host app's build never processes it. + * and reads its reveal policy and dock preferences from the connection meta + * (`ConnectionMeta.configs.ui`, seeded by `createUi`), so the host app's build + * never processes it. * * The bootstrap is loaded by an **inline** module that creates the `