diff --git a/AGENTS.md b/AGENTS.md index ede1ada1..5061719f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ **`devframe`** is the framework-neutral 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. -**`@devframes/hub`** is the framework-neutral hub layer that sits on top of devframe and provides the multi-integration orchestration (docks, terminals, messages, commands). It does not ship UI — implementers (e.g. `@vitejs/devtools-kit`) provide their own UI on top of the hub's RPC + shared-state protocol. It does ship a **headless client runtime** (`createDevframeClientHost()` from `@devframes/hub/client`): booted in the host page, it assembles the shared `DevframeClientContext` (panel, docks, commands, when) and imports each dock entry's client script (`action` / `custom-render` / iframe `clientScript`) into that page — how a plugin like the a11y inspector runs code inside the page being inspected. See `examples/minimal-vite-devframe-hub/` for a working ~120-line Vite host demonstrating the protocol end to end. +**`@devframes/hub`** is the framework-neutral hub layer that sits on top of devframe and provides the multi-integration orchestration (docks, terminals, messages, commands). It does not ship UI — implementers (e.g. `@vitejs/devtools-kit`) provide their own UI on top of the hub's RPC + shared-state protocol. It does ship a **headless client runtime** (`createDevframeClientHost()` from `@devframes/hub/client`): booted in the host page, it assembles the shared `DevframeClientContext` (panel, docks, commands, when) and imports each dock entry's client script (`action` / `custom-render` / iframe `clientScript`) into that page — how a plugin like the a11y inspector runs code inside the page being inspected. See `examples/vite-devframe-hub/` for a working ~120-line Vite host demonstrating the protocol end to end. ## Stack & Structure diff --git a/alias.ts b/alias.ts index 788d6b25..a12df299 100644 --- a/alias.ts +++ b/alias.ts @@ -55,7 +55,7 @@ export const alias = { '@devframes/json-render-ui/components': r('json-render-ui/src/components/index.ts'), '@devframes/json-render-ui/spa': r('json-render-ui/src/spa.ts'), '@devframes/json-render-ui': r('json-render-ui/src/index.ts'), - 'minimal-json-render/dashboard': fileURLToPath(new URL('./examples/minimal-json-render/src/dashboard.ts', import.meta.url)), + 'json-render/dashboard': fileURLToPath(new URL('./examples/json-render/src/dashboard.ts', import.meta.url)), '@devframes/plugin-code-server/client': p('code-server/src/client/index.ts'), '@devframes/plugin-code-server/node': p('code-server/src/node/index.ts'), '@devframes/plugin-code-server/constants': p('code-server/src/constants.ts'), diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 7b905336..fa9c5130 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -79,11 +79,11 @@ function examplesItems(prefix: string) { { text: 'Overview', link: `${prefix}/examples/` }, { text: 'Built with Devframe', link: `${prefix}/examples/built-with` }, { text: 'files-inspector', link: `${prefix}/examples/files-inspector` }, - { text: 'minimal-json-render', link: `${prefix}/examples/minimal-json-render` }, + { text: 'json-render', link: `${prefix}/examples/json-render` }, { text: 'streaming-chat', link: `${prefix}/examples/streaming-chat` }, { text: 'next-runtime-snapshot', link: `${prefix}/examples/next-runtime-snapshot` }, - { text: 'minimal-vite-devframe-hub', link: `${prefix}/examples/minimal-vite-devframe-hub` }, - { text: 'minimal-next-devframe-hub', link: `${prefix}/examples/minimal-next-devframe-hub` }, + { text: 'vite-devframe-hub', link: `${prefix}/examples/vite-devframe-hub` }, + { text: 'next-devframe-hub', link: `${prefix}/examples/next-devframe-hub` }, ] satisfies DefaultTheme.NavItemWithLink[] } @@ -114,17 +114,21 @@ export function devframeSidebar(prefix = ''): DefaultTheme.SidebarItem[] { export function devframeNav(prefix = ''): DefaultTheme.NavItem[] { return [ - { text: 'Guide', items: guideItems(prefix) }, - { text: 'Adapters', items: adaptersItems(prefix) }, { - text: 'Resources', + text: 'Guide', + items: [ + ...guideItems(prefix), + { text: 'Examples', items: examplesItems(prefix) }, + ], + }, + { + text: 'Adapters', items: [ - { text: 'Examples', link: `${prefix}/examples/` }, - { text: 'Built with Devframe', link: `${prefix}/examples/built-with` }, + ...adaptersItems(prefix), { text: 'Helpers', items: helpersItems(prefix) }, - { text: 'Plugins', items: pluginsItems(prefix) }, ], }, + { text: 'Plugins', items: pluginsItems(prefix) }, { text: 'Errors', link: `${prefix}/errors/` }, { text: `v${pkg.version}`, diff --git a/docs/examples/index.md b/docs/examples/index.md index 9655d837..7fc4351d 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -9,11 +9,11 @@ End-to-end examples that exercise the full adapter surface, each a runnable app | Example | UI framework | What it shows | |---------|--------------|---------------| | [files-inspector](./files-inspector) | Preact | Lists files in the cwd via RPC; exercises the CLI dev / build / spa surfaces. | -| [minimal-json-render](./minimal-json-render) | Vue | A server-authored JSON-render view rendered by `@devframes/json-render-ui`, with live state and an action bridge. | +| [json-render](./json-render) | Vue | A server-authored JSON-render view rendered by `@devframes/json-render-ui`, with live state and an action bridge. | | [streaming-chat](./streaming-chat) | Preact | Streams synthetic chat tokens server → client, with history kept in shared state. | | [next-runtime-snapshot](./next-runtime-snapshot) | React (Next.js) | A Next.js App Router SPA over RPC, surfacing the host Node runtime. | -| [minimal-vite-devframe-hub](./minimal-vite-devframe-hub) | Vanilla TypeScript (Vite) | A ~120-line Vite host wiring `@devframes/hub` end to end. | -| [minimal-next-devframe-hub](./minimal-next-devframe-hub) | React (Next.js) | The same hub protocol, hosted from a Next.js route handler. | +| [vite-devframe-hub](./vite-devframe-hub) | Vanilla TypeScript (Vite) | A ~120-line Vite host wiring `@devframes/hub` end to end. | +| [next-devframe-hub](./next-devframe-hub) | React (Next.js) | The same hub protocol, hosted from a Next.js route handler. | ## Run any example diff --git a/docs/examples/minimal-json-render.md b/docs/examples/json-render.md similarity index 73% rename from docs/examples/minimal-json-render.md rename to docs/examples/json-render.md index f75731f7..7e189fe1 100644 --- a/docs/examples/minimal-json-render.md +++ b/docs/examples/json-render.md @@ -2,13 +2,13 @@ outline: deep --- -# minimal-json-render +# json-render A standalone devframe that serves a **JSON-render view**: the server authors an `@json-render/core` spec once, and the prebuilt `@devframes/json-render-ui` SPA renders it — the app ships no client build of its own. -Package: `minimal-json-render` · frontend: **prebuilt `@devframes/json-render-ui/spa`** +Package: `json-render` · frontend: **prebuilt `@devframes/json-render-ui/spa`** ## What it shows @@ -29,12 +29,12 @@ Package: `minimal-json-render` · frontend: **prebuilt `@devframes/json-render-u ## Run it ```sh -pnpm --filter minimal-json-render dev # CLI dev server (live RPC) -pnpm --filter minimal-json-render cli:build # static deploy → dist/static +pnpm --filter json-render dev # CLI dev server (live RPC) +pnpm --filter json-render cli:build # static deploy → dist/static ``` -The dev server serves the SPA at `/__minimal-json-render/`. +The dev server serves the SPA at `/__json-render/`. ## Source -[`examples/minimal-json-render`](https://github.com/devframes/devframe/tree/main/examples/minimal-json-render) +[`examples/json-render`](https://github.com/devframes/devframe/tree/main/examples/json-render) diff --git a/docs/examples/minimal-next-devframe-hub.md b/docs/examples/next-devframe-hub.md similarity index 77% rename from docs/examples/minimal-next-devframe-hub.md rename to docs/examples/next-devframe-hub.md index de617263..b6cc5fc4 100644 --- a/docs/examples/minimal-next-devframe-hub.md +++ b/docs/examples/next-devframe-hub.md @@ -2,11 +2,11 @@ outline: deep --- -# minimal-next-devframe-hub +# next-devframe-hub -The same hub protocol as the [Vite host](./minimal-vite-devframe-hub), hosted from a **Next.js** App Router app. It wires [`@devframes/hub`](/guide/hub) by lazily starting a side-car RPC / WebSocket server from a Node route handler — proof that the hub is host-runtime-agnostic. +The same hub protocol as the [Vite host](./vite-devframe-hub), hosted from a **Next.js** App Router app. It wires [`@devframes/hub`](/guide/hub) by lazily starting a side-car RPC / WebSocket server from a Node route handler — proof that the hub is host-runtime-agnostic. -Package: `minimal-next-devframe-hub` · framework: **React (Next.js)** +Package: `next-devframe-hub` · framework: **React (Next.js)** ## What it proves @@ -22,7 +22,7 @@ Package: `minimal-next-devframe-hub` · framework: **React (Next.js)** ```sh pnpm install -pnpm --filter minimal-next-devframe-hub dev +pnpm --filter next-devframe-hub dev ``` Open the printed URL to see the docks, commands, messages, and terminals lists, plus a button that dispatches a sample command through `hub:commands:execute`. @@ -33,4 +33,4 @@ Open the printed URL to see the docks, commands, messages, and terminals lists, ## Source -[`examples/minimal-next-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/minimal-next-devframe-hub) +[`examples/next-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/next-devframe-hub) diff --git a/docs/examples/streaming-chat.md b/docs/examples/streaming-chat.md index 4a3eec45..3cb57af0 100644 --- a/docs/examples/streaming-chat.md +++ b/docs/examples/streaming-chat.md @@ -10,7 +10,7 @@ Package: `streaming-chat-example` · framework: **Preact + Vite** ## What it shows -- A scoped context (`ctx.scope('devframe-streaming-chat')`) auto-namespaces every id. +- A scoped context (`ctx.scope('example:streaming-chat')`) auto-namespaces every id. - `my.rpc.streaming.create('tokens', …)` registers a streaming channel for low-latency token rendering. - `my.rpc.sharedState('history', …)` keeps the message log on the server; each `send` appends a user + assistant pair atomically. - The producer streams tokens live, then commits the joined content back to shared state when done — so refreshes and new clients see the finished message immediately. diff --git a/docs/examples/minimal-vite-devframe-hub.md b/docs/examples/vite-devframe-hub.md similarity index 86% rename from docs/examples/minimal-vite-devframe-hub.md rename to docs/examples/vite-devframe-hub.md index 3eab1f40..f00f1ecd 100644 --- a/docs/examples/minimal-vite-devframe-hub.md +++ b/docs/examples/vite-devframe-hub.md @@ -2,11 +2,11 @@ outline: deep --- -# minimal-vite-devframe-hub +# vite-devframe-hub A protocol-witness host: roughly 120 lines of Vite plugin code that wire [`@devframes/hub`](/guide/hub) into a Vite dev server. The browser UI is plain **vanilla TypeScript**, so nothing distracts from the hub protocol itself. Every framework's hub host follows the same shape. -Package: `minimal-vite-devframe-hub` · framework: **Vanilla TypeScript (Vite)** +Package: `vite-devframe-hub` · framework: **Vanilla TypeScript (Vite)** ## What it proves @@ -22,11 +22,11 @@ Package: `minimal-vite-devframe-hub` · framework: **Vanilla TypeScript (Vite)** ```sh pnpm install -pnpm --filter minimal-vite-devframe-hub dev +pnpm --filter vite-devframe-hub dev ``` Open the printed URL to see the docks, commands, messages, and terminals lists the hub exposes, plus a button that dispatches a sample command through `hub:commands:execute`. ## Source -[`examples/minimal-vite-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/minimal-vite-devframe-hub) +[`examples/vite-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/vite-devframe-hub) diff --git a/docs/guide/client-context.md b/docs/guide/client-context.md index cae05031..41928059 100644 --- a/docs/guide/client-context.md +++ b/docs/guide/client-context.md @@ -186,4 +186,4 @@ state.domElements.iframe = iframeEl state.events.emit('dom:iframe:mounted', iframeEl) ``` -That announcement is what the adapter attaches to. Both minimal hubs wire this end to end — see the "Tabbed Tool" in [`examples/minimal-vite-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/minimal-vite-devframe-hub) and [`examples/minimal-next-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/minimal-next-devframe-hub), including the SPA's `postMessage` shim. +That announcement is what the adapter attaches to. Both minimal hubs wire this end to end — see the "Tabbed Tool" in [`examples/vite-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/vite-devframe-hub) and [`examples/next-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/next-devframe-hub), including the SPA's `postMessage` shim. diff --git a/docs/guide/hub.md b/docs/guide/hub.md index 4a588be9..1c5059bc 100644 --- a/docs/guide/hub.md +++ b/docs/guide/hub.md @@ -152,7 +152,7 @@ Each mounted SPA is served at `/__/` and references its assets relatively (` export default { skipTrailingSlashRedirect: true } ``` -[`examples/minimal-next-devframe-hub/`](https://github.com/devframes/devframe/tree/main/examples/minimal-next-devframe-hub) is a working Next.js App Router host that mounts the built-in plugins this way. +[`examples/next-devframe-hub/`](https://github.com/devframes/devframe/tree/main/examples/next-devframe-hub) is a working Next.js App Router host that mounts the built-in plugins this way. ### Duplicate devframes @@ -260,8 +260,8 @@ The hub also ships a headless browser runtime, `createDevframeClientHost()` from Two minimal, copyable hubs mount every built-in plugin (git, terminals, code-server, inspect, a11y) behind an icon dock — the same shape [vite-devtools](https://github.com/vitejs/devtools) wears as the full Vite viewer, shrunk to the smallest thing you can build your own viewer from: -- [`examples/minimal-vite-devframe-hub/`](https://github.com/devframes/devframe/tree/main/examples/minimal-vite-devframe-hub) — a ~120-line Vite plugin host with a vanilla DOM UI. -- [`examples/minimal-next-devframe-hub/`](https://github.com/devframes/devframe/tree/main/examples/minimal-next-devframe-hub) — the same protocol hosted from a Next.js App Router app. +- [`examples/vite-devframe-hub/`](https://github.com/devframes/devframe/tree/main/examples/vite-devframe-hub) — a ~120-line Vite plugin host with a vanilla DOM UI. +- [`examples/next-devframe-hub/`](https://github.com/devframes/devframe/tree/main/examples/next-devframe-hub) — the same protocol hosted from a Next.js App Router app. Both also mount a "Tabbed Tool" that demonstrates [shared-iframe soft navigation](./client-context#shared-iframe-soft-navigation) — one SPA whose tabs surface as separate docks sharing a single iframe. diff --git a/docs/guide/json-render.md b/docs/guide/json-render.md index 35094323..c3a2f473 100644 --- a/docs/guide/json-render.md +++ b/docs/guide/json-render.md @@ -211,8 +211,8 @@ the browser and render it with no shared state at all (see [client-only docks](./client-context#client-only-docks)). The client host disposes the renderer when the dock deactivates. -Both hub example shells dogfood this end to end: the [Vite hub](/examples/minimal-vite-devframe-hub) -registers `@devframes/json-render-ui` (Vue), and the [Next hub](/examples/minimal-next-devframe-hub) +Both hub example shells dogfood this end to end: the [Vite hub](/examples/vite-devframe-hub) +registers `@devframes/json-render-ui` (Vue), and the [Next hub](/examples/next-devframe-hub) registers a small in-example React registry — the same dock, two frontends. ## Swapping the frontend @@ -228,5 +228,5 @@ placeholder — showing the component type and a gist of its prop keys (`{ label onPress }`) — and logs a `console.warn`, while the rest of the view renders normally. -See the [`minimal-json-render` example](/examples/minimal-json-render) for a +See the [`json-render` example](/examples/json-render) for a runnable end-to-end app. diff --git a/docs/helpers/next.md b/docs/helpers/next.md index 22bd31d4..ff473fc4 100644 --- a/docs/helpers/next.md +++ b/docs/helpers/next.md @@ -131,4 +131,4 @@ Route handlers that call `fetch` pin `export const runtime = 'nodejs'`: the stat - [Vite Bridge](./vite-bridge) — the equivalent for Vite-based hosts - [Hub](/guide/hub) — `createHubContext`, `mountDevframe`, and `DevframeHost` -- [minimal-next-devframe-hub](/examples/minimal-next-devframe-hub) — a full working host +- [next-devframe-hub](/examples/next-devframe-hub) — a full working host diff --git a/examples/a11y-messages-playground/README.md b/examples/a11y-messages-playground/README.md index 83983259..c95b80db 100644 --- a/examples/a11y-messages-playground/README.md +++ b/examples/a11y-messages-playground/README.md @@ -4,7 +4,7 @@ A focused hub playground for testing **[`@devframes/plugin-a11y`](../../plugins/ alongside **[`@devframes/plugin-messages`](../../plugins/messages)** — and, above all, the **message → dock navigation** they share. -Where [`minimal-vite-devframe-hub`](../minimal-vite-devframe-hub) mounts every +Where [`vite-devframe-hub`](../vite-devframe-hub) mounts every built-in plugin against the hub's own (mostly accessible) UI, this example ships a deliberately **inaccessible, multi-route app under test** so the a11y scanner always has real violations to find, track per route, and link back to from the diff --git a/examples/a11y-messages-playground/src/a11y-messages-playground.ts b/examples/a11y-messages-playground/src/a11y-messages-playground.ts index 842e4ee3..35474674 100644 --- a/examples/a11y-messages-playground/src/a11y-messages-playground.ts +++ b/examples/a11y-messages-playground/src/a11y-messages-playground.ts @@ -27,7 +27,7 @@ export interface A11yMessagesPlaygroundOptions { /** * A tiny Vite plugin that runs `@devframes/hub` inside the Vite dev server — - * the same shape as `examples/minimal-vite-devframe-hub`, trimmed to the two + * the same shape as `examples/vite-devframe-hub`, trimmed to the two * plugins this playground pairs (a11y + messages). It creates a hub context, * implements the framework-neutral `DevframeHost` surface, mounts each devframe * as a dock (attaching the a11y agent as its client script), and exposes the diff --git a/examples/files-inspector/README.md b/examples/files-inspector/README.md index 5057ab44..0e9b983d 100644 --- a/examples/files-inspector/README.md +++ b/examples/files-inspector/README.md @@ -1,4 +1,4 @@ -# devframe-files-inspector +# files-inspector A simplified [node-modules-inspector](https://github.com/antfu/node-modules-inspector)-style example built on [devframe](../../packages/devframe). Lists files in the current working directory and renders them through a Preact SPA. Exercises every devframe surface end-to-end: diff --git a/examples/files-inspector/src/client/app.tsx b/examples/files-inspector/src/client/app.tsx index a48a9e20..672dac50 100644 --- a/examples/files-inspector/src/client/app.tsx +++ b/examples/files-inspector/src/client/app.tsx @@ -5,7 +5,7 @@ import { nav, navBrand, tab as tabClass, tabsList } from './design' import { About } from './routes/about' import { Home } from './routes/home' -const NAMESPACE = 'devframe-files-inspector' +const NAMESPACE = 'example:files-inspector' export type InspectorCtx = DevframeScopedClientContext const NAV_ITEMS = [ diff --git a/examples/files-inspector/src/client/routes/home.tsx b/examples/files-inspector/src/client/routes/home.tsx index babbe918..7e9627b1 100644 --- a/examples/files-inspector/src/client/routes/home.tsx +++ b/examples/files-inspector/src/client/routes/home.tsx @@ -9,7 +9,7 @@ export function Home({ ctx }: { ctx: InspectorCtx }) { async function refresh() { setLoading(true) try { - // Scoped call — `list-files` resolves to `devframe-files-inspector:list-files`. + // Scoped call — `list-files` resolves to `example:files-inspector:list-files`. const result = await ctx.rpc.call('list-files') setFiles(result) } diff --git a/examples/files-inspector/src/devframe.ts b/examples/files-inspector/src/devframe.ts index bef5eb96..144bb379 100644 --- a/examples/files-inspector/src/devframe.ts +++ b/examples/files-inspector/src/devframe.ts @@ -7,7 +7,7 @@ const BASE_PATH = '/__devframe-files-inspector/' const distDir = fileURLToPath(new URL('../dist/client', import.meta.url)) export default defineDevframe({ - id: 'devframe-files-inspector', + id: 'example:files-inspector', name: 'Files Inspector', version: pkg.version, packageName: pkg.name, diff --git a/examples/files-inspector/src/rpc/functions/get-cwd.ts b/examples/files-inspector/src/rpc/functions/get-cwd.ts index ae33b8fc..6d18b99b 100644 --- a/examples/files-inspector/src/rpc/functions/get-cwd.ts +++ b/examples/files-inspector/src/rpc/functions/get-cwd.ts @@ -2,7 +2,7 @@ import process from 'node:process' import { defineRpcFunction } from 'devframe' export const getCwd = defineRpcFunction({ - name: 'get-cwd', // scoped registration namespaces it to `devframe-files-inspector:get-cwd` + name: 'get-cwd', // scoped registration namespaces it to `example:files-inspector:get-cwd` type: 'static', jsonSerializable: true, setup: ctx => ({ diff --git a/examples/files-inspector/src/rpc/functions/list-files.ts b/examples/files-inspector/src/rpc/functions/list-files.ts index 7c81ecb7..cd5e5422 100644 --- a/examples/files-inspector/src/rpc/functions/list-files.ts +++ b/examples/files-inspector/src/rpc/functions/list-files.ts @@ -3,7 +3,7 @@ import { defineRpcFunction } from 'devframe' import { glob } from 'tinyglobby' export const listFiles = defineRpcFunction({ - name: 'list-files', // scoped registration namespaces it to `devframe-files-inspector:list-files` + name: 'list-files', // scoped registration namespaces it to `example:files-inspector:list-files` type: 'query', jsonSerializable: true, snapshot: true, diff --git a/examples/files-inspector/src/rpc/index.ts b/examples/files-inspector/src/rpc/index.ts index c8a7acd7..e0eee9f3 100644 --- a/examples/files-inspector/src/rpc/index.ts +++ b/examples/files-inspector/src/rpc/index.ts @@ -2,7 +2,7 @@ import type { RpcDefinitionsToFunctionsWithNamespace } from 'devframe/rpc' import { getCwd } from './functions/get-cwd.ts' import { listFiles } from './functions/list-files.ts' -export const NAMESPACE = 'devframe-files-inspector' +export const NAMESPACE = 'example:files-inspector' export const serverFunctions = [getCwd, listFiles] as const diff --git a/examples/files-inspector/tests/_utils.ts b/examples/files-inspector/tests/_utils.ts index 269a6092..3e564a6b 100644 --- a/examples/files-inspector/tests/_utils.ts +++ b/examples/files-inspector/tests/_utils.ts @@ -29,7 +29,7 @@ export const CLIENT_DIST = resolve(HERE, '../dist/client') export function assertClientBuilt(): void { if (!existsSync(path.join(CLIENT_DIST, 'index.html'))) { throw new Error( - `[devframe-files-inspector] dist/client missing — run \`pnpm -C examples/files-inspector run build\` first.`, + `[example:files-inspector] dist/client missing — run \`pnpm -C examples/files-inspector run build\` first.`, ) } } diff --git a/examples/files-inspector/tests/dev-server.test.ts b/examples/files-inspector/tests/dev-server.test.ts index ddec5112..e95746b4 100644 --- a/examples/files-inspector/tests/dev-server.test.ts +++ b/examples/files-inspector/tests/dev-server.test.ts @@ -59,10 +59,10 @@ describe('dev-server (CLI surface)', () => { }) const rpc = createRpcClient({}, { channel }) - const cwdResult = await rpc.$call('devframe-files-inspector:get-cwd') + const cwdResult = await rpc.$call('example:files-inspector:get-cwd') expect(cwdResult).toEqual({ cwd }) - const files = await rpc.$call('devframe-files-inspector:list-files') + const files = await rpc.$call('example:files-inspector:list-files') expect(files).toEqual(['README.md', 'package.json', 'sample.txt']) }) }) diff --git a/examples/files-inspector/tests/static-build.test.ts b/examples/files-inspector/tests/static-build.test.ts index 97302ca3..d9d8e94d 100644 --- a/examples/files-inspector/tests/static-build.test.ts +++ b/examples/files-inspector/tests/static-build.test.ts @@ -75,11 +75,11 @@ describe('static build (CLI build surface)', () => { ), ) as DumpManifest - expect(manifest['devframe-files-inspector:get-cwd']).toMatchObject({ type: 'static' }) - expect(manifest['devframe-files-inspector:list-files']).toMatchObject({ type: 'query' }) + expect(manifest['example:files-inspector:get-cwd']).toMatchObject({ type: 'static' }) + expect(manifest['example:files-inspector:list-files']).toMatchObject({ type: 'query' }) // The list-files dump records the cwd-fixture's contents. - const listEntry = manifest['devframe-files-inspector:list-files'] + const listEntry = manifest['example:files-inspector:list-files'] if (!('records' in listEntry)) throw new Error('expected query manifest entry') const recordPaths = Object.values(listEntry.records) diff --git a/examples/files-inspector/tests/static-serve.test.ts b/examples/files-inspector/tests/static-serve.test.ts index c35da419..77d96518 100644 --- a/examples/files-inspector/tests/static-serve.test.ts +++ b/examples/files-inspector/tests/static-serve.test.ts @@ -102,7 +102,7 @@ describe('static serve (deployed SPA contract)', () => { const manifest = await manifestRes.json() as Record // get-cwd: static entry → its `path` is fetchable. - const getCwdEntry = manifest['devframe-files-inspector:get-cwd'] + const getCwdEntry = manifest['example:files-inspector:get-cwd'] expect(getCwdEntry?.type).toBe('static') const getCwdRes = await fetch(`${server.origin}${mountBase}${getCwdEntry.path}`) expect(getCwdRes.status).toBe(200) @@ -110,7 +110,7 @@ describe('static serve (deployed SPA contract)', () => { expect(getCwdRecord.output.cwd).toBe(cwd) // list-files: query entry → exactly one record matching the fixture. - const listEntry = manifest['devframe-files-inspector:list-files'] + const listEntry = manifest['example:files-inspector:list-files'] expect(listEntry?.type).toBe('query') const recordPaths = Object.values(listEntry.records) as string[] expect(recordPaths).toHaveLength(1) diff --git a/examples/minimal-json-render/README.md b/examples/json-render/README.md similarity index 85% rename from examples/minimal-json-render/README.md rename to examples/json-render/README.md index b6a099e6..51783159 100644 --- a/examples/minimal-json-render/README.md +++ b/examples/json-render/README.md @@ -1,4 +1,4 @@ -# minimal-json-render +# json-render A standalone devframe that serves a **JSON-render view**: the server authors an `@json-render/core` spec once, and the browser renders it with the official @@ -27,7 +27,7 @@ dashboard** that exercises **every base-catalog component** — `Stack`, `Card`, ## Run ```sh -pnpm --filter minimal-json-render dev # live dev server (http://localhost:9877/__minimal-json-render/) +pnpm --filter json-render dev # live dev server (http://localhost:9877/__json-render/) node bin.mjs build --out-dir dist/static # static snapshot (read-only; actions render disabled) ``` @@ -37,8 +37,8 @@ the action bridge reports actions as unavailable — there is no live RPC. ## Reused by the hub shells The view is factored into `src/dashboard.ts` and exported as -`minimal-json-render/dashboard` (`createDashboardView(ctx)` + `dashboardSpec`), +`json-render/dashboard` (`createDashboardView(ctx)` + `dashboardSpec`), so the hub examples plug the very same view into their hub context and project -it onto a `json-render` dock — the [Vite hub](../minimal-vite-devframe-hub) +it onto a `json-render` dock — the [Vite hub](../vite-devframe-hub) renders it with `@devframes/json-render-ui` (Vue), and the -[Next hub](../minimal-next-devframe-hub) renders it with a small React registry. +[Next hub](../next-devframe-hub) renders it with a small React registry. diff --git a/examples/minimal-json-render/bin.mjs b/examples/json-render/bin.mjs similarity index 100% rename from examples/minimal-json-render/bin.mjs rename to examples/json-render/bin.mjs diff --git a/examples/minimal-json-render/package.json b/examples/json-render/package.json similarity index 88% rename from examples/minimal-json-render/package.json rename to examples/json-render/package.json index 73ced36a..eea9ffd9 100644 --- a/examples/minimal-json-render/package.json +++ b/examples/json-render/package.json @@ -1,17 +1,17 @@ { - "name": "minimal-json-render", + "name": "json-render", "type": "module", "version": "0.7.14", "private": true, "description": "Standalone devframe that serves a JSON-render view — a server-authored spec rendered by @devframes/json-render-ui, with live state and an action bridge.", - "homepage": "https://github.com/devframes/devframe/tree/main/examples/minimal-json-render", + "homepage": "https://github.com/devframes/devframe/tree/main/examples/json-render", "exports": { ".": "./src/devframe.ts", "./dashboard": "./src/dashboard.ts" }, "main": "src/devframe.ts", "bin": { - "minimal-json-render": "./bin.mjs" + "json-render": "./bin.mjs" }, "scripts": { "dev": "node bin.mjs", diff --git a/examples/minimal-json-render/src/dashboard.ts b/examples/json-render/src/dashboard.ts similarity index 100% rename from examples/minimal-json-render/src/dashboard.ts rename to examples/json-render/src/dashboard.ts diff --git a/examples/minimal-json-render/src/devframe.ts b/examples/json-render/src/devframe.ts similarity index 85% rename from examples/minimal-json-render/src/devframe.ts rename to examples/json-render/src/devframe.ts index 3dfd09cc..c4afb962 100644 --- a/examples/minimal-json-render/src/devframe.ts +++ b/examples/json-render/src/devframe.ts @@ -6,16 +6,16 @@ import { createDashboardView } from './dashboard.ts' // `cli.distDir` at the prebuilt `@devframes/json-render-ui` SPA, so this // example serves the out-of-box renderer with no client build of its own. export default createJsonRenderDevframe({ - id: 'minimal-json-render', - name: 'Minimal JSON-Render', + id: 'example:json-render', + name: 'JSON-Render', version: pkg.version, packageName: pkg.name, homepage: pkg.homepage, description: pkg.description, icon: 'ph:layout-duotone', - basePath: '/__minimal-json-render/', + basePath: '/__json-render/', cli: { - command: 'minimal-json-render', + command: 'json-render', port: 9877, // Single-user localhost demo — skip the trust handshake so the served SPA // can call the action RPCs without an OTP round-trip. diff --git a/examples/minimal-json-render/src/shared.ts b/examples/json-render/src/shared.ts similarity index 65% rename from examples/minimal-json-render/src/shared.ts rename to examples/json-render/src/shared.ts index 0fa92a3a..04e62f53 100644 --- a/examples/minimal-json-render/src/shared.ts +++ b/examples/json-render/src/shared.ts @@ -6,6 +6,6 @@ export const VIEW_ID = 'dashboard' // Spec action names dispatched by the bridge — each is an RPC method the server // registers. -export const REFRESH_ACTION = 'minimal-json-render:refresh' -export const DEPLOY_ACTION = 'minimal-json-render:deploy' -export const SAVE_ACTION = 'minimal-json-render:save' +export const REFRESH_ACTION = 'example:json-render:refresh' +export const DEPLOY_ACTION = 'example:json-render:deploy' +export const SAVE_ACTION = 'example:json-render:save' diff --git a/examples/minimal-json-render/tsconfig.json b/examples/json-render/tsconfig.json similarity index 100% rename from examples/minimal-json-render/tsconfig.json rename to examples/json-render/tsconfig.json diff --git a/examples/minimal-next-devframe-hub/.gitignore b/examples/next-devframe-hub/.gitignore similarity index 100% rename from examples/minimal-next-devframe-hub/.gitignore rename to examples/next-devframe-hub/.gitignore diff --git a/examples/minimal-next-devframe-hub/README.md b/examples/next-devframe-hub/README.md similarity index 91% rename from examples/minimal-next-devframe-hub/README.md rename to examples/next-devframe-hub/README.md index 2cdb7db7..aa19d6e6 100644 --- a/examples/minimal-next-devframe-hub/README.md +++ b/examples/next-devframe-hub/README.md @@ -1,14 +1,14 @@ -# Minimal Next Devframe Hub +# Next Devframe Hub A tiny, copyable **vite-devtools-style hub on Next.js**. [vite-devtools](https://github.com/vitejs/devtools) is the full Vite viewer built on `@devframes/hub`; this example wears the same shape — an icon dock, an iframe stage, a subsystem drawer — but hosts it from a Next.js App Router app, lazily starting a side-car RPC/WS server from a Node route handler. It's the reference for bringing the same integrations to any non-Vite host. -`src/client/devframe/minimal-next-devframe-hub.ts` is the entire host. +`src/client/devframe/next-devframe-hub.ts` is the entire host. ## Run it ```sh pnpm install -pnpm --filter minimal-next-devframe-hub dev +pnpm --filter next-devframe-hub dev ``` Open the printed URL. The dock on the left lists every mounted tool with its icon: @@ -35,7 +35,7 @@ The plugins run node-side (child processes, the native `zigpty` PTY backend) and | File | Role | |---|---| -| `src/client/devframe/minimal-next-devframe-hub.ts` | The Next host — hub context, static-mount registry (incl. the a11y agent), side-car WS | +| `src/client/devframe/next-devframe-hub.ts` | The Next host — hub context, static-mount registry (incl. the a11y agent), side-car WS | | `src/client/app/%5F_hub/%5F_connection.json/route.ts` | Boots the singleton host and serves `/__hub/__connection.json` | | `src/client/app/%5F_[id]/[[...path]]/route.ts` | Serves each mounted SPA and its connection meta under `/__/` | | `src/client/app/page.tsx` | The browser UI that consumes the hub protocol | diff --git a/examples/minimal-next-devframe-hub/package.json b/examples/next-devframe-hub/package.json similarity index 92% rename from examples/minimal-next-devframe-hub/package.json rename to examples/next-devframe-hub/package.json index cc2164ce..2932ca1b 100644 --- a/examples/minimal-next-devframe-hub/package.json +++ b/examples/next-devframe-hub/package.json @@ -1,10 +1,10 @@ { - "name": "minimal-next-devframe-hub", + "name": "next-devframe-hub", "type": "module", "version": "0.7.14", "private": true, "description": "Protocol-witness example — a tiny Next.js Devframe Hub built on @devframes/hub that exercises every hub subsystem end-to-end.", - "homepage": "https://github.com/devframes/devframe/tree/main/examples/minimal-next-devframe-hub", + "homepage": "https://github.com/devframes/devframe/tree/main/examples/next-devframe-hub", "scripts": { "dev": "pnpm -C ../.. run build && next dev src/client", "build": "next build src/client", @@ -25,7 +25,7 @@ "colorjs.io": "catalog:frontend", "devframe": "workspace:*", "dompurify": "catalog:frontend", - "minimal-json-render": "workspace:*", + "json-render": "workspace:*", "next": "catalog:frontend", "react": "catalog:frontend", "react-dom": "catalog:frontend" diff --git a/examples/minimal-next-devframe-hub/spa/next-demo-tool-b/index.html b/examples/next-devframe-hub/spa/next-demo-tool-b/index.html similarity index 100% rename from examples/minimal-next-devframe-hub/spa/next-demo-tool-b/index.html rename to examples/next-devframe-hub/spa/next-demo-tool-b/index.html diff --git a/examples/minimal-next-devframe-hub/spa/next-demo-tool/index.html b/examples/next-devframe-hub/spa/next-demo-tool/index.html similarity index 83% rename from examples/minimal-next-devframe-hub/spa/next-demo-tool/index.html rename to examples/next-devframe-hub/spa/next-demo-tool/index.html index 8b6c1381..11617e43 100644 --- a/examples/minimal-next-devframe-hub/spa/next-demo-tool/index.html +++ b/examples/next-devframe-hub/spa/next-demo-tool/index.html @@ -14,7 +14,7 @@

Next Demo Tool

Served from

-

This SPA is mounted by minimal-next-devframe-hub via DevframeHost.mountStatic().

+

This SPA is mounted by next-devframe-hub via DevframeHost.mountStatic().

diff --git a/examples/minimal-next-devframe-hub/spa/next-tabbed-tool/index.html b/examples/next-devframe-hub/spa/next-tabbed-tool/index.html similarity index 100% rename from examples/minimal-next-devframe-hub/spa/next-tabbed-tool/index.html rename to examples/next-devframe-hub/spa/next-tabbed-tool/index.html diff --git a/examples/minimal-next-devframe-hub/src/client/app/%5F_[id]/[[...path]]/route.ts b/examples/next-devframe-hub/src/client/app/%5F_[id]/[[...path]]/route.ts similarity index 79% rename from examples/minimal-next-devframe-hub/src/client/app/%5F_[id]/[[...path]]/route.ts rename to examples/next-devframe-hub/src/client/app/%5F_[id]/[[...path]]/route.ts index 64210ba0..ce601989 100644 --- a/examples/minimal-next-devframe-hub/src/client/app/%5F_[id]/[[...path]]/route.ts +++ b/examples/next-devframe-hub/src/client/app/%5F_[id]/[[...path]]/route.ts @@ -1,4 +1,4 @@ -import { ensureMinimalNextDevframeHub } from '../../../devframe/minimal-next-devframe-hub' +import { ensureNextDevframeHub } from '../../../devframe/next-devframe-hub' export const runtime = 'nodejs' export const dynamic = 'force-dynamic' @@ -11,6 +11,6 @@ export const dynamic = 'force-dynamic' * `serveStaticHandler`) and the connection-meta responses. */ export async function GET(request: Request): Promise { - const hub = await ensureMinimalNextDevframeHub() + const hub = await ensureNextDevframeHub() return hub.fetch(request) } diff --git a/examples/minimal-next-devframe-hub/src/client/app/%5F_hub/%5F_connection.json/route.ts b/examples/next-devframe-hub/src/client/app/%5F_hub/%5F_connection.json/route.ts similarity index 75% rename from examples/minimal-next-devframe-hub/src/client/app/%5F_hub/%5F_connection.json/route.ts rename to examples/next-devframe-hub/src/client/app/%5F_hub/%5F_connection.json/route.ts index 41bcaf4c..f1ee760d 100644 --- a/examples/minimal-next-devframe-hub/src/client/app/%5F_hub/%5F_connection.json/route.ts +++ b/examples/next-devframe-hub/src/client/app/%5F_hub/%5F_connection.json/route.ts @@ -1,4 +1,4 @@ -import { ensureMinimalNextDevframeHub } from '../../../devframe/minimal-next-devframe-hub' +import { ensureNextDevframeHub } from '../../../devframe/next-devframe-hub' export const runtime = 'nodejs' export const dynamic = 'force-dynamic' @@ -10,6 +10,6 @@ export const dynamic = 'force-dynamic' * catch-all SPA route. */ export async function GET(request: Request): Promise { - const hub = await ensureMinimalNextDevframeHub() + const hub = await ensureNextDevframeHub() return hub.fetch(request) } diff --git a/examples/minimal-next-devframe-hub/src/client/app/globals.css b/examples/next-devframe-hub/src/client/app/globals.css similarity index 100% rename from examples/minimal-next-devframe-hub/src/client/app/globals.css rename to examples/next-devframe-hub/src/client/app/globals.css diff --git a/examples/minimal-next-devframe-hub/src/client/app/icons.ts b/examples/next-devframe-hub/src/client/app/icons.ts similarity index 100% rename from examples/minimal-next-devframe-hub/src/client/app/icons.ts rename to examples/next-devframe-hub/src/client/app/icons.ts diff --git a/examples/minimal-next-devframe-hub/src/client/app/layout.tsx b/examples/next-devframe-hub/src/client/app/layout.tsx similarity index 95% rename from examples/minimal-next-devframe-hub/src/client/app/layout.tsx rename to examples/next-devframe-hub/src/client/app/layout.tsx index 1ef0c233..d7294636 100644 --- a/examples/minimal-next-devframe-hub/src/client/app/layout.tsx +++ b/examples/next-devframe-hub/src/client/app/layout.tsx @@ -4,7 +4,7 @@ import './globals.css' import '@antfu/design/styles.css' export const metadata: Metadata = { - title: 'Minimal Next Devframe Hub', + title: 'Next Devframe Hub', description: 'A Next.js host for the @devframes/hub protocol.', } diff --git a/examples/minimal-next-devframe-hub/src/client/app/page.tsx b/examples/next-devframe-hub/src/client/app/page.tsx similarity index 99% rename from examples/minimal-next-devframe-hub/src/client/app/page.tsx rename to examples/next-devframe-hub/src/client/app/page.tsx index f7949c42..8ffd8806 100644 --- a/examples/minimal-next-devframe-hub/src/client/app/page.tsx +++ b/examples/next-devframe-hub/src/client/app/page.tsx @@ -284,7 +284,7 @@ export default function Page() { const refreshMessages = async () => { const entries = await rpc.call( - 'minimal-next-devframe-hub:messages:list' as any, + 'example:next-devframe-hub:messages:list' as any, ) as DevframeMessageEntry[] if (!cancelled) setMessages(entries) @@ -292,7 +292,7 @@ export default function Page() { const refreshTerminals = async () => { const sessions = await rpc.call( - 'minimal-next-devframe-hub:terminals:list' as any, + 'example:next-devframe-hub:terminals:list' as any, ) as TerminalSummary[] if (!cancelled) setTerminals(sessions) @@ -427,7 +427,7 @@ export default function Page() { try { const result = await rpcRef.current.call( 'hub:commands:execute' as any, - 'minimal-next-devframe-hub:ping', + 'example:next-devframe-hub:ping', ) setPingResult(`Ping returned ${JSON.stringify(result)}`) } @@ -445,7 +445,7 @@ export default function Page() {

- Minimal Next Devframe Hub + Next Devframe Hub

diff --git a/examples/minimal-next-devframe-hub/src/client/devframe/demo-devframe-b.ts b/examples/next-devframe-hub/src/client/devframe/demo-devframe-b.ts similarity index 93% rename from examples/minimal-next-devframe-hub/src/client/devframe/demo-devframe-b.ts rename to examples/next-devframe-hub/src/client/devframe/demo-devframe-b.ts index da46a76c..38da33ad 100644 --- a/examples/minimal-next-devframe-hub/src/client/devframe/demo-devframe-b.ts +++ b/examples/next-devframe-hub/src/client/devframe/demo-devframe-b.ts @@ -7,7 +7,7 @@ import pkg from '../../../package.json' with { type: 'json' } const HERE = dirname(fileURLToPath(import.meta.url)) export default defineDevframe({ - id: 'next-demo-tool-b', + id: 'example:next-demo-tool-b', name: 'Next Demo Tool B', version: pkg.version, packageName: pkg.name, @@ -22,7 +22,7 @@ export default defineDevframe({ const ctx = rawCtx as unknown as DevframeHubContext ctx.commands.register({ - id: 'next-demo-tool-b:say-hello', + id: 'example:next-demo-tool-b:say-hello', title: 'Next Demo Tool B: Say Hello', icon: 'ph:hand-waving-duotone', category: 'demo', diff --git a/examples/minimal-next-devframe-hub/src/client/devframe/demo-devframe.ts b/examples/next-devframe-hub/src/client/devframe/demo-devframe.ts similarity index 93% rename from examples/minimal-next-devframe-hub/src/client/devframe/demo-devframe.ts rename to examples/next-devframe-hub/src/client/devframe/demo-devframe.ts index cc562c47..6a620091 100644 --- a/examples/minimal-next-devframe-hub/src/client/devframe/demo-devframe.ts +++ b/examples/next-devframe-hub/src/client/devframe/demo-devframe.ts @@ -7,7 +7,7 @@ import pkg from '../../../package.json' with { type: 'json' } const HERE = dirname(fileURLToPath(import.meta.url)) export default defineDevframe({ - id: 'next-demo-tool', + id: 'example:next-demo-tool', name: 'Next Demo Tool', version: pkg.version, packageName: pkg.name, @@ -22,7 +22,7 @@ export default defineDevframe({ const ctx = rawCtx as unknown as DevframeHubContext ctx.commands.register({ - id: 'next-demo-tool:say-hello', + id: 'example:next-demo-tool:say-hello', title: 'Next Demo Tool: Say Hello', icon: 'ph:hand-waving-duotone', category: 'demo', diff --git a/examples/minimal-next-devframe-hub/src/client/devframe/minimal-next-devframe-hub.ts b/examples/next-devframe-hub/src/client/devframe/next-devframe-hub.ts similarity index 88% rename from examples/minimal-next-devframe-hub/src/client/devframe/minimal-next-devframe-hub.ts rename to examples/next-devframe-hub/src/client/devframe/next-devframe-hub.ts index 899fcca4..6d9b1049 100644 --- a/examples/minimal-next-devframe-hub/src/client/devframe/minimal-next-devframe-hub.ts +++ b/examples/next-devframe-hub/src/client/devframe/next-devframe-hub.ts @@ -10,7 +10,7 @@ import { toJsonRenderDockEntry } from '@devframes/json-render/hub' import { createDevframeNextHost } from '@devframes/next' import { startHttpAndWs } from 'devframe/node' import { getPort } from 'get-port-please' -import { createDashboardView } from 'minimal-json-render/dashboard' +import { createDashboardView } from 'json-render/dashboard' import { dirname, join } from 'pathe' import demoDevframe from './demo-devframe' import demoDevframeB from './demo-devframe-b' @@ -80,7 +80,7 @@ async function loadA11yAgentMount(): Promise { } } -export interface MinimalNextDevframeHubOptions { +export interface NextDevframeHubOptions { /** Preferred port for the side-car RPC/WS server. Default: a free port near 9877. */ port?: number /** Hostname for the side-car server. Default: `localhost`. */ @@ -91,7 +91,7 @@ export interface MinimalNextDevframeHubOptions { devframes?: DevframeDefinition[] } -export interface StartedMinimalNextDevframeHub extends StartedServer { +export interface StartedNextDevframeHub extends StartedServer { context: DevframeHubContext connectionMeta: ConnectionMeta & { backend: 'websocket', websocket: number } /** @@ -102,8 +102,8 @@ export interface StartedMinimalNextDevframeHub extends StartedServer { fetch: DevframeNextHost['fetch'] } -const minimalNextHubMessagesList = defineHubRpcFunction({ - name: 'minimal-next-devframe-hub:messages:list', +const nextHubMessagesList = defineHubRpcFunction({ + name: 'example:next-devframe-hub:messages:list', type: 'static', jsonSerializable: true, setup: (ctx: DevframeHubContext) => ({ @@ -113,8 +113,8 @@ const minimalNextHubMessagesList = defineHubRpcFunction({ }), }) -const minimalNextHubTerminalsList = defineHubRpcFunction({ - name: 'minimal-next-devframe-hub:terminals:list', +const nextHubTerminalsList = defineHubRpcFunction({ + name: 'example:next-devframe-hub:terminals:list', type: 'static', jsonSerializable: true, setup: (ctx: DevframeHubContext) => ({ @@ -129,9 +129,9 @@ const minimalNextHubTerminalsList = defineHubRpcFunction({ }), }) -export async function minimalNextDevframeHub( - options: MinimalNextDevframeHubOptions = {}, -): Promise { +export async function nextDevframeHub( + options: NextDevframeHubOptions = {}, +): Promise { const cwd = options.cwd ?? process.cwd() const hostName = options.host ?? 'localhost' @@ -145,8 +145,8 @@ export async function minimalNextDevframeHub( if (scope === 'workspace') return join(cwd, '.devframe') if (scope === 'project') - return join(cwd, 'node_modules/.minimal-next-devframe-hub') - return join(homedir(), '.minimal-next-devframe-hub') + return join(cwd, 'node_modules/.next-devframe-hub') + return join(homedir(), '.next-devframe-hub') }, }) const host = nextHost.host @@ -164,13 +164,13 @@ export async function minimalNextDevframeHub( mode: 'dev', host, builtinRpcDeclarations: [ - minimalNextHubMessagesList, - minimalNextHubTerminalsList, + nextHubMessagesList, + nextHubTerminalsList, ], }) context.commands.register({ - id: 'minimal-next-devframe-hub:ping', + id: 'example:next-devframe-hub:ping', title: 'Next Hub: Ping', icon: 'ph:bell-duotone', category: 'hub', @@ -194,7 +194,7 @@ export async function minimalNextDevframeHub( await context.messages.add({ level: 'success', - message: 'Minimal Next Devframe Hub started', + message: 'Next Devframe Hub started', description: `Side-car WS on port ${port}. ${devframes.length} devframe(s) registered.`, }) @@ -219,7 +219,7 @@ export async function minimalNextDevframeHub( // renders it with a mini React registry (registry replacement). const jsonRenderView = createDashboardView(context) context.docks.register(toJsonRenderDockEntry(jsonRenderView, { - id: 'minimal-json-render', + id: 'example:json-render', title: 'JSON Render', icon: 'ph:layout-duotone', category: 'app', @@ -260,16 +260,16 @@ export async function minimalNextDevframeHub( }) } -const GLOBAL_KEY = '__minimalNextDevframeHub' +const GLOBAL_KEY = '__nextDevframeHub' type GlobalWithHub = typeof globalThis & { - [GLOBAL_KEY]?: Promise + [GLOBAL_KEY]?: Promise } -export function ensureMinimalNextDevframeHub( - options: MinimalNextDevframeHubOptions = {}, -): Promise { +export function ensureNextDevframeHub( + options: NextDevframeHubOptions = {}, +): Promise { const globalHub = globalThis as GlobalWithHub - globalHub[GLOBAL_KEY] ??= minimalNextDevframeHub(options) + globalHub[GLOBAL_KEY] ??= nextDevframeHub(options) return globalHub[GLOBAL_KEY] } diff --git a/examples/minimal-next-devframe-hub/src/client/devframe/tabbed-devframe.ts b/examples/next-devframe-hub/src/client/devframe/tabbed-devframe.ts similarity index 92% rename from examples/minimal-next-devframe-hub/src/client/devframe/tabbed-devframe.ts rename to examples/next-devframe-hub/src/client/devframe/tabbed-devframe.ts index f312e017..59e68e5a 100644 --- a/examples/minimal-next-devframe-hub/src/client/devframe/tabbed-devframe.ts +++ b/examples/next-devframe-hub/src/client/devframe/tabbed-devframe.ts @@ -9,13 +9,13 @@ const HERE = dirname(fileURLToPath(import.meta.url)) /** * A demo of **shared-iframe soft navigation**. This devframe is a single SPA * with several internal views (Overview / Components / Timeline / Settings). - * Mounted as a `subTabs` anchor (see `minimal-next-devframe-hub.ts`), the hub's + * Mounted as a `subTabs` anchor (see `next-devframe-hub.ts`), the hub's * client host attaches its frame-nav adapter: the SPA's `postMessage` shim * reports its tabs, each becomes a client-only hub dock sharing this one iframe, * and switching docks soft-navigates inside it instead of reloading. */ export default defineDevframe({ - id: 'next-tabbed-tool', + id: 'example:next-tabbed-tool', name: 'Next Tabbed Tool', version: pkg.version, packageName: pkg.name, diff --git a/examples/minimal-next-devframe-hub/src/client/json-render/dock-renderer.tsx b/examples/next-devframe-hub/src/client/json-render/dock-renderer.tsx similarity index 98% rename from examples/minimal-next-devframe-hub/src/client/json-render/dock-renderer.tsx rename to examples/next-devframe-hub/src/client/json-render/dock-renderer.tsx index e6adc044..db7b2652 100644 --- a/examples/minimal-next-devframe-hub/src/client/json-render/dock-renderer.tsx +++ b/examples/next-devframe-hub/src/client/json-render/dock-renderer.tsx @@ -48,7 +48,7 @@ function sanitizeSpec(spec: Spec): Spec { if (!result.success) { changed = true const issues = result.error.issues.map(i => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ') - console.warn(`[minimal-next-devframe-hub] invalid props on element "${key}" (${element.type}): ${issues}`) + console.warn(`[example:next-devframe-hub] invalid props on element "${key}" (${element.type}): ${issues}`) elements[key] = { ...element, type: ERROR_COMPONENT_TYPE, props: { message: `${element.type}: ${issues}` } } continue } diff --git a/examples/minimal-next-devframe-hub/src/client/json-render/registry.tsx b/examples/next-devframe-hub/src/client/json-render/registry.tsx similarity index 100% rename from examples/minimal-next-devframe-hub/src/client/json-render/registry.tsx rename to examples/next-devframe-hub/src/client/json-render/registry.tsx diff --git a/examples/minimal-next-devframe-hub/src/client/next.config.mjs b/examples/next-devframe-hub/src/client/next.config.mjs similarity index 100% rename from examples/minimal-next-devframe-hub/src/client/next.config.mjs rename to examples/next-devframe-hub/src/client/next.config.mjs diff --git a/examples/minimal-next-devframe-hub/src/client/postcss.config.mjs b/examples/next-devframe-hub/src/client/postcss.config.mjs similarity index 100% rename from examples/minimal-next-devframe-hub/src/client/postcss.config.mjs rename to examples/next-devframe-hub/src/client/postcss.config.mjs diff --git a/examples/minimal-next-devframe-hub/src/client/tsconfig.json b/examples/next-devframe-hub/src/client/tsconfig.json similarity index 100% rename from examples/minimal-next-devframe-hub/src/client/tsconfig.json rename to examples/next-devframe-hub/src/client/tsconfig.json diff --git a/examples/minimal-next-devframe-hub/tests/minimal-next-devframe-hub.test.ts b/examples/next-devframe-hub/tests/next-devframe-hub.test.ts similarity index 70% rename from examples/minimal-next-devframe-hub/tests/minimal-next-devframe-hub.test.ts rename to examples/next-devframe-hub/tests/next-devframe-hub.test.ts index b957673c..549cec9a 100644 --- a/examples/minimal-next-devframe-hub/tests/minimal-next-devframe-hub.test.ts +++ b/examples/next-devframe-hub/tests/next-devframe-hub.test.ts @@ -2,7 +2,7 @@ import { createRpcClient } from 'devframe/rpc/client' import { createWsRpcChannel } from 'devframe/rpc/transports/ws-client' import { afterEach, describe, expect, it, vi } from 'vitest' import { WebSocket } from 'ws' -import { minimalNextDevframeHub } from '../src/client/devframe/minimal-next-devframe-hub' +import { nextDevframeHub } from '../src/client/devframe/next-devframe-hub' vi.stubGlobal('WebSocket', WebSocket) @@ -11,8 +11,8 @@ function bootRpc(port: number) { return createRpcClient({}, { channel }) } -describe('minimal-next-devframe-hub (example)', () => { - let server: Awaited> | undefined +describe('next-devframe-hub (example)', () => { + let server: Awaited> | undefined afterEach(async () => { await server?.close() @@ -20,7 +20,7 @@ describe('minimal-next-devframe-hub (example)', () => { }) it('returns connection meta pointing at the WS backend', async () => { - server = await minimalNextDevframeHub({ host: '127.0.0.1' }) + server = await nextDevframeHub({ host: '127.0.0.1' }) expect(server.connectionMeta).toEqual({ backend: 'websocket', @@ -29,11 +29,11 @@ describe('minimal-next-devframe-hub (example)', () => { }) it('registers a hub-owned settings dock and the mounted plugin docks', async () => { - server = await minimalNextDevframeHub({ host: '127.0.0.1' }) + server = await nextDevframeHub({ host: '127.0.0.1' }) const docks = server.context.docks.values() const dockIds = docks.map(d => d.id) - expect(dockIds).toContain('next-demo-tool') + expect(dockIds).toContain('example:next-demo-tool') // The hub synthesizes no built-in docks; the integration registers the // settings tab itself, declaring the `~builtin` category explicitly. expect(dockIds).toContain('~settings') @@ -44,20 +44,20 @@ describe('minimal-next-devframe-hub (example)', () => { }) it('lists startup and demo messages through the kit-local RPC', async () => { - server = await minimalNextDevframeHub({ host: '127.0.0.1' }) + server = await nextDevframeHub({ host: '127.0.0.1' }) const rpc = bootRpc(server.port) - const messages = await rpc.$call('minimal-next-devframe-hub:messages:list') as { message: string }[] - expect(messages.map(m => m.message)).toContain('Minimal Next Devframe Hub started') + const messages = await rpc.$call('example:next-devframe-hub:messages:list') as { message: string }[] + expect(messages.map(m => m.message)).toContain('Next Devframe Hub started') expect(messages.map(m => m.message)).toContain('Next demo devframe loaded') }) it('executes the ping command through the hub command RPC', async () => { - server = await minimalNextDevframeHub({ host: '127.0.0.1' }) + server = await nextDevframeHub({ host: '127.0.0.1' }) const rpc = bootRpc(server.port) await expect( - rpc.$call('hub:commands:execute', 'minimal-next-devframe-hub:ping'), + rpc.$call('hub:commands:execute', 'example:next-devframe-hub:ping'), ).resolves.toBe('pong') }) }) diff --git a/examples/minimal-next-devframe-hub/tsconfig.json b/examples/next-devframe-hub/tsconfig.json similarity index 100% rename from examples/minimal-next-devframe-hub/tsconfig.json rename to examples/next-devframe-hub/tsconfig.json diff --git a/examples/minimal-next-devframe-hub/uno.config.ts b/examples/next-devframe-hub/uno.config.ts similarity index 100% rename from examples/minimal-next-devframe-hub/uno.config.ts rename to examples/next-devframe-hub/uno.config.ts diff --git a/examples/minimal-next-devframe-hub/vitest.config.ts b/examples/next-devframe-hub/vitest.config.ts similarity index 100% rename from examples/minimal-next-devframe-hub/vitest.config.ts rename to examples/next-devframe-hub/vitest.config.ts diff --git a/examples/next-runtime-snapshot/README.md b/examples/next-runtime-snapshot/README.md index 833bf591..62d10213 100644 --- a/examples/next-runtime-snapshot/README.md +++ b/examples/next-runtime-snapshot/README.md @@ -7,17 +7,17 @@ type-safe RPC. ## What it shows -- `next-runtime-snapshot:system` — a `static` RPC function. Runs once at +- `example:next-runtime-snapshot:system` — a `static` RPC function. Runs once at build time when baked into a static dump, otherwise resolved live over WebSocket. Returns Node version, platform/arch, pid, cwd, start time. -- `next-runtime-snapshot:memory` — a `query` RPC function. Re-runnable; +- `example:next-runtime-snapshot:memory` — a `query` RPC function. Re-runnable; the UI has a refresh button that re-invokes the handler. -- `next-runtime-snapshot:env` — a `query` RPC function with valibot-validated +- `example:next-runtime-snapshot:env` — a `query` RPC function with valibot-validated args (`pattern`, `limit`). Lists environment variables matching a regex, redacting keys that look secret. - Next.js App Router with `'use client'` components calling `connectDevframe()` once, then sharing the scoped client - (`client.scope('next-runtime-snapshot')`) through React context. + (`client.scope('example:next-runtime-snapshot')`) through React context. ## Run it diff --git a/examples/next-runtime-snapshot/src/client/app/components/connect.tsx b/examples/next-runtime-snapshot/src/client/app/components/connect.tsx index cbb86b44..7c415d59 100644 --- a/examples/next-runtime-snapshot/src/client/app/components/connect.tsx +++ b/examples/next-runtime-snapshot/src/client/app/components/connect.tsx @@ -7,7 +7,7 @@ import { useMemo } from 'react' // Inlined (not imported from the server `rpc/index.ts`) so the client // bundle stays free of node-only server code. -const NAMESPACE = 'next-runtime-snapshot' +const NAMESPACE = 'example:next-runtime-snapshot' export type SnapshotCtx = DevframeScopedClientContext diff --git a/examples/next-runtime-snapshot/src/devframe.ts b/examples/next-runtime-snapshot/src/devframe.ts index 937d57b5..8a457f8a 100644 --- a/examples/next-runtime-snapshot/src/devframe.ts +++ b/examples/next-runtime-snapshot/src/devframe.ts @@ -11,7 +11,7 @@ const BASE_PATH = '/__next-runtime-snapshot/' const distDir = fileURLToPath(new URL('../dist/client', import.meta.url)) export default defineDevframe({ - id: 'next-runtime-snapshot', + id: 'example:next-runtime-snapshot', name: 'Next Runtime Snapshot', version: pkg.version, packageName: pkg.name, diff --git a/examples/next-runtime-snapshot/src/rpc/index.ts b/examples/next-runtime-snapshot/src/rpc/index.ts index c2ebd6df..b3d10224 100644 --- a/examples/next-runtime-snapshot/src/rpc/index.ts +++ b/examples/next-runtime-snapshot/src/rpc/index.ts @@ -3,7 +3,7 @@ import { env } from './functions/env.ts' import { memory } from './functions/memory.ts' import { system } from './functions/system.ts' -export const NAMESPACE = 'next-runtime-snapshot' +export const NAMESPACE = 'example:next-runtime-snapshot' export const serverFunctions = [system, memory, env] as const diff --git a/examples/next-runtime-snapshot/tests/next-runtime-snapshot.test.ts b/examples/next-runtime-snapshot/tests/next-runtime-snapshot.test.ts index 8a048d7e..d06ecf3c 100644 --- a/examples/next-runtime-snapshot/tests/next-runtime-snapshot.test.ts +++ b/examples/next-runtime-snapshot/tests/next-runtime-snapshot.test.ts @@ -34,7 +34,7 @@ describe('next-runtime-snapshot (example)', () => { it('returns system info from the static RPC', async () => { const rpc = bootRpc(server.port) - const info = await rpc.$call('next-runtime-snapshot:system') as SystemInfo + const info = await rpc.$call('example:next-runtime-snapshot:system') as SystemInfo expect(info.node).toBe(process.version) expect(info.platform).toBe(process.platform) expect(info.arch).toBe(process.arch) @@ -45,7 +45,7 @@ describe('next-runtime-snapshot (example)', () => { it('returns a memory snapshot with the expected shape', async () => { const rpc = bootRpc(server.port) - const snap = await rpc.$call('next-runtime-snapshot:memory') as MemorySnapshot + const snap = await rpc.$call('example:next-runtime-snapshot:memory') as MemorySnapshot expect(snap.memory.rss).toBeGreaterThan(0) expect(snap.memory.heapTotal).toBeGreaterThan(0) expect(snap.memory.heapUsed).toBeGreaterThan(0) @@ -55,9 +55,9 @@ describe('next-runtime-snapshot (example)', () => { it('refreshing memory yields monotonically non-decreasing uptime', async () => { const rpc = bootRpc(server.port) - const first = await rpc.$call('next-runtime-snapshot:memory') as MemorySnapshot + const first = await rpc.$call('example:next-runtime-snapshot:memory') as MemorySnapshot await new Promise(r => setTimeout(r, 30)) - const second = await rpc.$call('next-runtime-snapshot:memory') as MemorySnapshot + const second = await rpc.$call('example:next-runtime-snapshot:memory') as MemorySnapshot expect(second.uptimeSeconds).toBeGreaterThanOrEqual(first.uptimeSeconds) expect(second.capturedAt).toBeGreaterThanOrEqual(first.capturedAt) }) @@ -67,7 +67,7 @@ describe('next-runtime-snapshot (example)', () => { // Seed an env var that is guaranteed to match the filter. process.env.DEVFRAME_TEST_MARKER = 'present' try { - const snap = await rpc.$call('next-runtime-snapshot:env', { pattern: 'devframe_test_marker' }) as EnvSnapshot + const snap = await rpc.$call('example:next-runtime-snapshot:env', { pattern: 'devframe_test_marker' }) as EnvSnapshot expect(snap.pattern).toBe('devframe_test_marker') expect(snap.total).toBe(1) const entry = snap.entries.find(e => e.key === 'DEVFRAME_TEST_MARKER') @@ -85,7 +85,7 @@ describe('next-runtime-snapshot (example)', () => { process.env.DEVFRAME_TEST_API_KEY = 'sk-xyz-123' process.env.DEVFRAME_TEST_SECRET_PAYLOAD = 'shh' try { - const snap = await rpc.$call('next-runtime-snapshot:env', { pattern: 'DEVFRAME_TEST_' }) as EnvSnapshot + const snap = await rpc.$call('example:next-runtime-snapshot:env', { pattern: 'DEVFRAME_TEST_' }) as EnvSnapshot const apiKey = snap.entries.find(e => e.key === 'DEVFRAME_TEST_API_KEY')! const secret = snap.entries.find(e => e.key === 'DEVFRAME_TEST_SECRET_PAYLOAD')! expect(apiKey.redacted).toBe(true) @@ -101,7 +101,7 @@ describe('next-runtime-snapshot (example)', () => { it('returns all env vars when no pattern is supplied (up to the limit)', async () => { const rpc = bootRpc(server.port) - const snap = await rpc.$call('next-runtime-snapshot:env', { pattern: '', limit: 5 }) as EnvSnapshot + const snap = await rpc.$call('example:next-runtime-snapshot:env', { pattern: '', limit: 5 }) as EnvSnapshot expect(snap.entries.length).toBeLessThanOrEqual(5) expect(snap.total).toBeGreaterThan(0) expect(snap.total).toBeGreaterThanOrEqual(snap.entries.length) @@ -110,7 +110,7 @@ describe('next-runtime-snapshot (example)', () => { it('matches nothing on an invalid regex pattern', async () => { const rpc = bootRpc(server.port) // '[' is unterminated — `new RegExp('[', 'i')` throws SyntaxError. - const snap = await rpc.$call('next-runtime-snapshot:env', { pattern: '[' }) as EnvSnapshot + const snap = await rpc.$call('example:next-runtime-snapshot:env', { pattern: '[' }) as EnvSnapshot expect(snap.entries).toEqual([]) expect(snap.total).toBe(0) expect(snap.pattern).toBe('[') @@ -118,8 +118,8 @@ describe('next-runtime-snapshot (example)', () => { it('respects the limit cap on the entries slice', async () => { const rpc = bootRpc(server.port) - const small = await rpc.$call('next-runtime-snapshot:env', { pattern: '', limit: 2 }) as EnvSnapshot - const big = await rpc.$call('next-runtime-snapshot:env', { pattern: '', limit: 100 }) as EnvSnapshot + const small = await rpc.$call('example:next-runtime-snapshot:env', { pattern: '', limit: 2 }) as EnvSnapshot + const big = await rpc.$call('example:next-runtime-snapshot:env', { pattern: '', limit: 100 }) as EnvSnapshot expect(small.entries.length).toBeLessThanOrEqual(2) expect(big.entries.length).toBeGreaterThanOrEqual(small.entries.length) expect(big.total).toBe(small.total) diff --git a/examples/streaming-chat/README.md b/examples/streaming-chat/README.md index 0debc0ca..20a52faf 100644 --- a/examples/streaming-chat/README.md +++ b/examples/streaming-chat/README.md @@ -1,4 +1,4 @@ -# devframe-streaming-chat +# streaming-chat End-to-end demo of devframe's streaming-channel API combined with shared state for persistent chat history. Mirrors the AI-deltas use case from @@ -10,12 +10,12 @@ client (re)joins mid-stream. ## What it shows -- A scoped context (`ctx.scope('devframe-streaming-chat')`) is the +- A scoped context (`ctx.scope('example:streaming-chat')`) is the preferred entry point — it auto-namespaces every id. - `my.rpc.streaming.create('tokens', opts)` registers a streaming channel - (`devframe-streaming-chat:tokens`). + (`example:streaming-chat:tokens`). - `my.rpc.sharedState('history', …)` keeps the message log on the server - (`devframe-streaming-chat:history`). Each `send` action appends a user + + (`example:streaming-chat:history`). Each `send` action appends a user + assistant pair atomically. - The producer streams tokens via the channel for low-latency rendering, then commits the joined content back to the shared state when it's diff --git a/examples/streaming-chat/src/constants.ts b/examples/streaming-chat/src/constants.ts index a6c259df..99bbf59a 100644 --- a/examples/streaming-chat/src/constants.ts +++ b/examples/streaming-chat/src/constants.ts @@ -1,4 +1,4 @@ -export const NAMESPACE = 'devframe-streaming-chat' +export const NAMESPACE = 'example:streaming-chat' // Bare ids — pass these to the scoped context, which namespaces them. export const CHANNEL = 'tokens' diff --git a/examples/streaming-chat/src/devframe.ts b/examples/streaming-chat/src/devframe.ts index 1f56fb37..c074c1ce 100644 --- a/examples/streaming-chat/src/devframe.ts +++ b/examples/streaming-chat/src/devframe.ts @@ -11,7 +11,7 @@ const BASE_PATH = '/__devframe-streaming-chat/' const distDir = fileURLToPath(new URL('../dist/client', import.meta.url)) export default defineDevframe({ - id: 'devframe-streaming-chat', + id: 'example:streaming-chat', name: 'Streaming Chat', version: pkg.version, packageName: pkg.name, @@ -32,10 +32,10 @@ export default defineDevframe({ // A scoped context auto-namespaces channel + state ids with `NAMESPACE:`. const my = ctx.scope(NAMESPACE) - const channel = my.rpc.streaming.create(CHANNEL, { // -> devframe-streaming-chat:tokens + const channel = my.rpc.streaming.create(CHANNEL, { // -> example:streaming-chat:tokens replayWindow: 1024, }) - const history = await my.rpc.sharedState(HISTORY, { // -> devframe-streaming-chat:history + const history = await my.rpc.sharedState(HISTORY, { // -> example:streaming-chat:history initialValue: { messages: [] }, }) diff --git a/examples/streaming-chat/tests/streaming-chat.test.ts b/examples/streaming-chat/tests/streaming-chat.test.ts index fb57d989..84b69d55 100644 --- a/examples/streaming-chat/tests/streaming-chat.test.ts +++ b/examples/streaming-chat/tests/streaming-chat.test.ts @@ -10,8 +10,8 @@ import { startStreamingChatServer } from './_utils' vi.stubGlobal('WebSocket', WebSocket) -const CHANNEL = 'devframe-streaming-chat:tokens' -const HISTORY_KEY = 'devframe-streaming-chat:history' as const +const CHANNEL = 'example:streaming-chat:tokens' +const HISTORY_KEY = 'example:streaming-chat:history' as const interface FakeClient { rpc: ReturnType @@ -66,7 +66,7 @@ interface SendResult { } async function send(client: FakeClient, prompt: string, intervalMs = 1): Promise { - return await (client.rpc as any).$call('devframe-streaming-chat:send', { + return await (client.rpc as any).$call('example:streaming-chat:send', { prompt, intervalMs, }) as SendResult @@ -84,7 +84,7 @@ async function getHistory(ctx: DevframeNodeContext): Promise { return state.value() as ChatHistory } -describe('devframe-streaming-chat (example)', () => { +describe('streaming-chat (example)', () => { let server: StartedServer & { basePath: string, ctx: DevframeNodeContext } beforeEach(async () => { @@ -189,7 +189,7 @@ describe('devframe-streaming-chat (example)', () => { expect((await getHistory(server.ctx)).messages).toHaveLength(2) - await (client.rpc as any).$call('devframe-streaming-chat:clear') + await (client.rpc as any).$call('example:streaming-chat:clear') await new Promise(r => setTimeout(r, 30)) expect((await getHistory(server.ctx)).messages).toHaveLength(0) diff --git a/examples/minimal-vite-devframe-hub/README.md b/examples/vite-devframe-hub/README.md similarity index 89% rename from examples/minimal-vite-devframe-hub/README.md rename to examples/vite-devframe-hub/README.md index 43f1e700..440ac802 100644 --- a/examples/minimal-vite-devframe-hub/README.md +++ b/examples/vite-devframe-hub/README.md @@ -1,14 +1,14 @@ -# Minimal Vite Devframe Hub +# Vite Devframe Hub A tiny, copyable **vite-devtools-style hub**. [vite-devtools](https://github.com/vitejs/devtools) is the full viewer that docks many Vite integrations behind one icon rail on top of `@devframes/hub`; this example is the smallest thing shaped like it — an icon dock, an iframe stage, and a drawer of hub subsystems — so you can see the whole protocol and build your own viewer from it. -`src/minimal-vite-devframe-hub.ts` is the entire host: ~120 lines of Vite plugin that wires `@devframes/hub` into a Vite dev server. Every framework's hub host follows the same shape. +`src/vite-devframe-hub.ts` is the entire host: ~120 lines of Vite plugin that wires `@devframes/hub` into a Vite dev server. Every framework's hub host follows the same shape. ## Run it ```sh pnpm install -pnpm --filter minimal-vite-devframe-hub dev +pnpm --filter vite-devframe-hub dev ``` Open the printed URL. The dock on the left lists every mounted tool with its icon: @@ -36,7 +36,7 @@ The dock UI is plain DOM in `src/client/`. To skin your own viewer, read the sam | File | Role | |---|---| -| `src/minimal-vite-devframe-hub.ts` | The Vite host — hub context, static + connection-meta mounts, side-car WS | +| `src/vite-devframe-hub.ts` | The Vite host — hub context, static + connection-meta mounts, side-car WS | | `vite.config.ts` | Mounts the built-in plugins via the host's `devframes` option; attaches the a11y agent as its dock's `clientScript` | | `src/client/main.ts` | The browser UI that consumes the hub protocol | | `src/client/icons.ts` | Offline Phosphor icons for the dock | diff --git a/examples/minimal-vite-devframe-hub/index.html b/examples/vite-devframe-hub/index.html similarity index 94% rename from examples/minimal-vite-devframe-hub/index.html rename to examples/vite-devframe-hub/index.html index 2f69b436..ce359553 100644 --- a/examples/minimal-vite-devframe-hub/index.html +++ b/examples/vite-devframe-hub/index.html @@ -3,7 +3,7 @@ - Minimal Vite Devframe Hub + Vite Devframe Hub diff --git a/examples/minimal-vite-devframe-hub/spa/tabbed-tool/index.html b/examples/vite-devframe-hub/spa/tabbed-tool/index.html similarity index 100% rename from examples/minimal-vite-devframe-hub/spa/tabbed-tool/index.html rename to examples/vite-devframe-hub/spa/tabbed-tool/index.html diff --git a/examples/minimal-vite-devframe-hub/src/client/env.d.ts b/examples/vite-devframe-hub/src/client/env.d.ts similarity index 100% rename from examples/minimal-vite-devframe-hub/src/client/env.d.ts rename to examples/vite-devframe-hub/src/client/env.d.ts diff --git a/examples/minimal-vite-devframe-hub/src/client/icons.ts b/examples/vite-devframe-hub/src/client/icons.ts similarity index 100% rename from examples/minimal-vite-devframe-hub/src/client/icons.ts rename to examples/vite-devframe-hub/src/client/icons.ts diff --git a/examples/minimal-vite-devframe-hub/src/client/main.ts b/examples/vite-devframe-hub/src/client/main.ts similarity index 99% rename from examples/minimal-vite-devframe-hub/src/client/main.ts rename to examples/vite-devframe-hub/src/client/main.ts index 75efd012..676fb202 100644 --- a/examples/minimal-vite-devframe-hub/src/client/main.ts +++ b/examples/vite-devframe-hub/src/client/main.ts @@ -391,7 +391,7 @@ async function main() { // to refresh on broadcast; this minimal example polls instead. const refreshMessages = async () => { const entries = await rpc.call( - 'minimal-vite-devframe-hub:messages:list' as any, + 'example:vite-devframe-hub:messages:list' as any, ) as DevframeMessageEntry[] renderList(messagesEl, entries, m => `

  • [${m.level}] ${m.message}
  • `) @@ -401,7 +401,7 @@ async function main() { // 4. Terminals — same pattern as messages. const refreshTerminals = async () => { const sessions = await rpc.call( - 'minimal-vite-devframe-hub:terminals:list' as any, + 'example:vite-devframe-hub:terminals:list' as any, ) as Pick[] renderList(terminalsEl, sessions, t => `
  • ${t.title} ${t.id} · ${t.status}
  • `) @@ -419,7 +419,7 @@ async function main() { try { const result = await rpc.call( 'hub:commands:execute' as any, - 'minimal-vite-devframe-hub:ping', + 'example:vite-devframe-hub:ping', ) pingBtn.textContent = `Ping returned ${JSON.stringify(result)}` } diff --git a/examples/minimal-vite-devframe-hub/src/devframe-b.ts b/examples/vite-devframe-hub/src/devframe-b.ts similarity index 93% rename from examples/minimal-vite-devframe-hub/src/devframe-b.ts rename to examples/vite-devframe-hub/src/devframe-b.ts index 9840ebf5..342829ae 100644 --- a/examples/minimal-vite-devframe-hub/src/devframe-b.ts +++ b/examples/vite-devframe-hub/src/devframe-b.ts @@ -4,7 +4,7 @@ import { defineDevframe } from 'devframe/types' import pkg from '../package.json' with { type: 'json' } export default defineDevframe({ - id: 'demo-tool-b', + id: 'example:demo-tool-b', name: 'Demo Tool B', version: pkg.version, packageName: pkg.name, @@ -19,7 +19,7 @@ export default defineDevframe({ const ctx = rawCtx as unknown as DevframeHubContext ctx.commands.register({ - id: 'demo-tool-b:say-hello', + id: 'example:demo-tool-b:say-hello', title: 'Demo B · Say Hello', icon: 'ph:hand-waving-duotone', category: 'demo', diff --git a/examples/minimal-vite-devframe-hub/src/devframe.ts b/examples/vite-devframe-hub/src/devframe.ts similarity index 95% rename from examples/minimal-vite-devframe-hub/src/devframe.ts rename to examples/vite-devframe-hub/src/devframe.ts index 1bfaa7fd..9b5a483e 100644 --- a/examples/minimal-vite-devframe-hub/src/devframe.ts +++ b/examples/vite-devframe-hub/src/devframe.ts @@ -13,7 +13,7 @@ import pkg from '../package.json' with { type: 'json' } * threads a hub-augmented context through `d.setup`. */ export default defineDevframe({ - id: 'demo-tool', + id: 'example:demo-tool', name: 'Demo Tool', version: pkg.version, packageName: pkg.name, @@ -28,7 +28,7 @@ export default defineDevframe({ const ctx = rawCtx as unknown as DevframeHubContext ctx.commands.register({ - id: 'demo-tool:say-hello', + id: 'example:demo-tool:say-hello', title: 'Demo · Say Hello', icon: 'ph:hand-waving-duotone', category: 'demo', diff --git a/examples/minimal-vite-devframe-hub/src/tabbed-tool.ts b/examples/vite-devframe-hub/src/tabbed-tool.ts similarity index 97% rename from examples/minimal-vite-devframe-hub/src/tabbed-tool.ts rename to examples/vite-devframe-hub/src/tabbed-tool.ts index 01a165da..cc72940f 100644 --- a/examples/minimal-vite-devframe-hub/src/tabbed-tool.ts +++ b/examples/vite-devframe-hub/src/tabbed-tool.ts @@ -13,7 +13,7 @@ import pkg from '../package.json' with { type: 'json' } * multi-tab tool like Nuxt DevTools. */ export default defineDevframe({ - id: 'tabbed-tool', + id: 'example:tabbed-tool', name: 'Tabbed Tool', version: pkg.version, packageName: pkg.name, diff --git a/examples/minimal-vite-devframe-hub/src/minimal-vite-devframe-hub.ts b/examples/vite-devframe-hub/src/vite-devframe-hub.ts similarity index 90% rename from examples/minimal-vite-devframe-hub/src/minimal-vite-devframe-hub.ts rename to examples/vite-devframe-hub/src/vite-devframe-hub.ts index 1b3351ce..530d08be 100644 --- a/examples/minimal-vite-devframe-hub/src/minimal-vite-devframe-hub.ts +++ b/examples/vite-devframe-hub/src/vite-devframe-hub.ts @@ -11,7 +11,7 @@ import { serveStaticNodeMiddleware } from 'devframe/utils/serve-static' import { getPort } from 'get-port-please' import { join } from 'pathe' -export interface MinimalViteDevframeHubOptions { +export interface ViteDevframeHubOptions { /** Mount path for the hub's connection-meta endpoint. Default: `/__hub/`. */ base?: string /** Preferred port for the side-car RPC/WS server. Default: a free port near 9777. */ @@ -34,8 +34,8 @@ export interface MinimalViteDevframeHubOptions { // Minimal hub-local RPCs — used by the UI for read-side data. A more // ambitious hub host might hoist these into `@devframes/hub` itself. -const minimalViteHubMessagesList = defineHubRpcFunction({ - name: 'minimal-vite-devframe-hub:messages:list', +const viteHubMessagesList = defineHubRpcFunction({ + name: 'example:vite-devframe-hub:messages:list', type: 'static', jsonSerializable: true, setup: (ctx: DevframeHubContext) => ({ @@ -45,8 +45,8 @@ const minimalViteHubMessagesList = defineHubRpcFunction({ }), }) -const minimalViteHubTerminalsList = defineHubRpcFunction({ - name: 'minimal-vite-devframe-hub:terminals:list', +const viteHubTerminalsList = defineHubRpcFunction({ + name: 'example:vite-devframe-hub:terminals:list', type: 'static', jsonSerializable: true, setup: (ctx: DevframeHubContext) => ({ @@ -70,13 +70,13 @@ const minimalViteHubTerminalsList = defineHubRpcFunction({ * This file is the entire Vite host — every other framework's hub host is * the same shape: a thin layer that adapts a framework's dev server to the hub. */ -export function minimalViteDevframeHub(options: MinimalViteDevframeHubOptions = {}): Plugin { +export function viteDevframeHub(options: ViteDevframeHubOptions = {}): Plugin { const base = normalizeBase(options.base ?? '/__hub/') let viteConfig: ResolvedConfig | undefined let started: { close: () => Promise } | undefined return { - name: 'minimal-vite-devframe-hub', + name: 'vite-devframe-hub', apply: 'serve', configResolved(config) { @@ -124,8 +124,8 @@ export function minimalViteDevframeHub(options: MinimalViteDevframeHubOptions = if (scope === 'workspace') return join(cwd, '.devframe') if (scope === 'project') - return join(cwd, 'node_modules/.minimal-vite-devframe-hub') - return join(homedir(), '.minimal-vite-devframe-hub') + return join(cwd, 'node_modules/.vite-devframe-hub') + return join(homedir(), '.vite-devframe-hub') }, } @@ -139,15 +139,15 @@ export function minimalViteDevframeHub(options: MinimalViteDevframeHubOptions = // RPCs so the UI has something to read. A full hub kit would // likely standardise these (alongside the built-in // `hub:commands:execute`) but for the demo we keep them kit-local. - minimalViteHubMessagesList, - minimalViteHubTerminalsList, + viteHubMessagesList, + viteHubTerminalsList, ], }) // Seed a sample command directly on the hub so the UI // shows something even without any plugged-in devframes. context.commands.register({ - id: 'minimal-vite-devframe-hub:ping', + id: 'example:vite-devframe-hub:ping', title: 'Vite Hub · Ping', icon: 'ph:bell-duotone', category: 'kit', @@ -155,7 +155,7 @@ export function minimalViteDevframeHub(options: MinimalViteDevframeHubOptions = }) await context.messages.add({ level: 'success', - message: 'Minimal Vite Devframe Hub started', + message: 'Vite Devframe Hub started', description: `Side-car WS on port ${port}. ${options.devframes?.length ?? 0} devframe(s) registered.`, }) diff --git a/examples/minimal-vite-devframe-hub/tsconfig.json b/examples/vite-devframe-hub/tsconfig.json similarity index 100% rename from examples/minimal-vite-devframe-hub/tsconfig.json rename to examples/vite-devframe-hub/tsconfig.json diff --git a/examples/minimal-vite-devframe-hub/uno.config.ts b/examples/vite-devframe-hub/uno.config.ts similarity index 100% rename from examples/minimal-vite-devframe-hub/uno.config.ts rename to examples/vite-devframe-hub/uno.config.ts diff --git a/examples/minimal-vite-devframe-hub/vite.config.ts b/examples/vite-devframe-hub/vite.config.ts similarity index 94% rename from examples/minimal-vite-devframe-hub/vite.config.ts rename to examples/vite-devframe-hub/vite.config.ts index d9a2223e..60363386 100644 --- a/examples/minimal-vite-devframe-hub/vite.config.ts +++ b/examples/vite-devframe-hub/vite.config.ts @@ -10,14 +10,14 @@ import messagesDevframe from '@devframes/plugin-messages' import ogDevframe from '@devframes/plugin-og' import terminalsDevframe from '@devframes/plugin-terminals' import vue from '@vitejs/plugin-vue' -import { createDashboardView } from 'minimal-json-render/dashboard' +import { createDashboardView } from 'json-render/dashboard' import UnoCSS from 'unocss/vite' import { defineConfig } from 'vite' import { alias } from '../../alias' import demoDevframe from './src/devframe' import demoDevframeB from './src/devframe-b' -import { minimalViteDevframeHub } from './src/minimal-vite-devframe-hub' import tabbedToolDevframe from './src/tabbed-tool' +import { viteDevframeHub } from './src/vite-devframe-hub' export default defineConfig({ resolve: { alias }, @@ -33,7 +33,7 @@ export default defineConfig({ { // The host registers its own live objects as data-inspector sources — // the registry is process-global, so this works from any plugin hook. - name: 'minimal-vite-devframe-hub:data-sources', + name: 'vite-devframe-hub:data-sources', configureServer(server) { registerDataSource({ id: 'vite:server', @@ -58,7 +58,7 @@ export default defineConfig({ }) }, }, - minimalViteDevframeHub({ + viteDevframeHub({ devframes: [ demoDevframe, demoDevframeB, @@ -86,7 +86,7 @@ export default defineConfig({ onContextReady: async (context) => { const view = createDashboardView(context) context.docks.register(toJsonRenderDockEntry(view, { - id: 'minimal-json-render', + id: 'example:json-render', title: 'JSON Render', icon: 'ph:layout-duotone', category: 'app', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 084ae5ac..c9191679 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -502,7 +502,7 @@ importers: specifier: catalog:deps version: 8.21.1 - examples/minimal-json-render: + examples/json-render: dependencies: '@devframes/json-render': specifier: workspace:* @@ -521,11 +521,11 @@ importers: specifier: catalog:deps version: 3.2.0 - examples/minimal-next-devframe-hub: + examples/next-devframe-hub: dependencies: '@antfu/design': specifier: catalog:frontend - version: 0.3.2(@antfu/utils@9.3.0)(@iconify-json/catppuccin@1.2.17)(@tanstack/vue-virtual@3.13.30(vue@3.5.40(typescript@6.0.3)))(@unocss/core@66.7.5)(colorjs.io@0.7.0)(dompurify@3.4.12)(floating-vue@5.2.2(vue@3.5.40(typescript@6.0.3)))(playwright@1.61.1)(reka-ui@2.10.1(vue@3.5.40(typescript@6.0.3)))(splitpanes@4.1.2(vue@3.5.40(typescript@6.0.3)))(unocss@66.7.5(@unocss/postcss@66.7.5(postcss@8.5.16))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vue@3.5.40(typescript@6.0.3)) + version: 0.3.2(@antfu/utils@9.3.0)(@iconify-json/catppuccin@1.2.17)(@tanstack/vue-virtual@3.13.30(vue@3.5.40(typescript@6.0.3)))(@unocss/core@66.7.5)(colorjs.io@0.7.0)(dompurify@3.4.12)(floating-vue@5.2.2(vue@3.5.40(typescript@6.0.3)))(playwright@1.61.1)(reka-ui@2.10.1(vue@3.5.40(typescript@6.0.3)))(splitpanes@4.1.2(vue@3.5.40(typescript@6.0.3)))(unocss@66.7.5(@unocss/postcss@66.7.5(postcss@8.5.19))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vue@3.5.40(typescript@6.0.3)) '@devframes/hub': specifier: workspace:* version: link:../../packages/hub @@ -565,9 +565,9 @@ importers: dompurify: specifier: catalog:frontend version: 3.4.12 - minimal-json-render: + json-render: specifier: workspace:* - version: link:../minimal-json-render + version: link:../json-render next: specifier: catalog:frontend version: 16.2.11(@babel/core@7.29.0(supports-color@10.2.2))(@playwright/test@1.61.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -589,7 +589,7 @@ importers: version: 19.2.3(@types/react@19.2.17) '@unocss/postcss': specifier: catalog:frontend - version: 66.7.5(postcss@8.5.16) + version: 66.7.5(postcss@8.5.19) get-port-please: specifier: catalog:deps version: 3.2.0 @@ -598,7 +598,7 @@ importers: version: 2.0.3 unocss: specifier: catalog:frontend - version: 66.7.5(@unocss/postcss@66.7.5(postcss@8.5.16))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + version: 66.7.5(@unocss/postcss@66.7.5(postcss@8.5.19))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) vitest: specifier: catalog:testing version: 4.1.10(@types/node@26.1.1)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) @@ -606,79 +606,6 @@ importers: specifier: catalog:deps version: 8.21.1 - examples/minimal-vite-devframe-hub: - dependencies: - '@antfu/design': - specifier: catalog:frontend - version: 0.3.2(@antfu/utils@9.3.0)(@iconify-json/catppuccin@1.2.17)(@tanstack/vue-virtual@3.13.30(vue@3.5.40(typescript@6.0.3)))(@unocss/core@66.7.5)(colorjs.io@0.7.0)(dompurify@3.4.12)(floating-vue@5.2.2(vue@3.5.40(typescript@6.0.3)))(playwright@1.61.1)(reka-ui@2.10.1(vue@3.5.40(typescript@6.0.3)))(splitpanes@4.1.2(vue@3.5.40(typescript@6.0.3)))(unocss@66.7.5(@unocss/postcss@66.7.5(postcss@8.5.19))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vue@3.5.40(typescript@6.0.3)) - '@devframes/hub': - specifier: workspace:* - version: link:../../packages/hub - '@devframes/json-render': - specifier: workspace:* - version: link:../../packages/json-render - '@devframes/json-render-ui': - specifier: workspace:* - version: link:../../packages/json-render-ui - '@devframes/plugin-a11y': - specifier: workspace:* - version: link:../../plugins/a11y - '@devframes/plugin-code-server': - specifier: workspace:* - version: link:../../plugins/code-server - '@devframes/plugin-data-inspector': - specifier: workspace:* - version: link:../../plugins/data-inspector - '@devframes/plugin-git': - specifier: workspace:* - version: link:../../plugins/git - '@devframes/plugin-inspect': - specifier: workspace:* - version: link:../../plugins/inspect - '@devframes/plugin-messages': - specifier: workspace:* - version: link:../../plugins/messages - '@devframes/plugin-og': - specifier: workspace:* - version: link:../../plugins/og - '@devframes/plugin-terminals': - specifier: workspace:* - version: link:../../plugins/terminals - colorjs.io: - specifier: catalog:frontend - version: 0.7.0 - devframe: - specifier: workspace:* - version: link:../../packages/devframe - dompurify: - specifier: catalog:frontend - version: 3.4.12 - minimal-json-render: - specifier: workspace:* - version: link:../minimal-json-render - vue: - specifier: catalog:frontend - version: 3.5.40(typescript@6.0.3) - devDependencies: - '@iconify-json/ph': - specifier: catalog:frontend - version: 1.2.2 - '@vitejs/plugin-vue': - specifier: catalog:build - version: 6.0.8(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - get-port-please: - specifier: catalog:deps - version: 3.2.0 - pathe: - specifier: catalog:deps - version: 2.0.3 - unocss: - specifier: catalog:frontend - version: 66.7.5(@unocss/postcss@66.7.5(postcss@8.5.19))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - vite: - specifier: catalog:build - version: 8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) - examples/next-runtime-snapshot: dependencies: '@antfu/design': @@ -771,6 +698,79 @@ importers: specifier: catalog:deps version: 8.21.1 + examples/vite-devframe-hub: + dependencies: + '@antfu/design': + specifier: catalog:frontend + version: 0.3.2(@antfu/utils@9.3.0)(@iconify-json/catppuccin@1.2.17)(@tanstack/vue-virtual@3.13.30(vue@3.5.40(typescript@6.0.3)))(@unocss/core@66.7.5)(colorjs.io@0.7.0)(dompurify@3.4.12)(floating-vue@5.2.2(vue@3.5.40(typescript@6.0.3)))(playwright@1.61.1)(reka-ui@2.10.1(vue@3.5.40(typescript@6.0.3)))(splitpanes@4.1.2(vue@3.5.40(typescript@6.0.3)))(unocss@66.7.5(@unocss/postcss@66.7.5(postcss@8.5.19))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vue@3.5.40(typescript@6.0.3)) + '@devframes/hub': + specifier: workspace:* + version: link:../../packages/hub + '@devframes/json-render': + specifier: workspace:* + version: link:../../packages/json-render + '@devframes/json-render-ui': + specifier: workspace:* + version: link:../../packages/json-render-ui + '@devframes/plugin-a11y': + specifier: workspace:* + version: link:../../plugins/a11y + '@devframes/plugin-code-server': + specifier: workspace:* + version: link:../../plugins/code-server + '@devframes/plugin-data-inspector': + specifier: workspace:* + version: link:../../plugins/data-inspector + '@devframes/plugin-git': + specifier: workspace:* + version: link:../../plugins/git + '@devframes/plugin-inspect': + specifier: workspace:* + version: link:../../plugins/inspect + '@devframes/plugin-messages': + specifier: workspace:* + version: link:../../plugins/messages + '@devframes/plugin-og': + specifier: workspace:* + version: link:../../plugins/og + '@devframes/plugin-terminals': + specifier: workspace:* + version: link:../../plugins/terminals + colorjs.io: + specifier: catalog:frontend + version: 0.7.0 + devframe: + specifier: workspace:* + version: link:../../packages/devframe + dompurify: + specifier: catalog:frontend + version: 3.4.12 + json-render: + specifier: workspace:* + version: link:../json-render + vue: + specifier: catalog:frontend + version: 3.5.40(typescript@6.0.3) + devDependencies: + '@iconify-json/ph': + specifier: catalog:frontend + version: 1.2.2 + '@vitejs/plugin-vue': + specifier: catalog:build + version: 6.0.8(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) + get-port-please: + specifier: catalog:deps + version: 3.2.0 + pathe: + specifier: catalog:deps + version: 2.0.3 + unocss: + specifier: catalog:frontend + version: 66.7.5(@unocss/postcss@66.7.5(postcss@8.5.19))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + vite: + specifier: catalog:build + version: 8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) + packages/devframe: dependencies: '@valibot/to-json-schema': @@ -8339,11 +8339,6 @@ packages: resolution: {integrity: sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==} engines: {node: ^20.9.0 || >=22} - react-dom@19.2.7: - resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} - peerDependencies: - react: ^19.2.7 - react-dom@19.2.8: resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} peerDependencies: @@ -8352,10 +8347,6 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react@19.2.7: - resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} - engines: {node: '>=0.10.0'} - react@19.2.8: resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} engines: {node: '>=0.10.0'} @@ -10818,11 +10809,11 @@ snapshots: - encoding - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7)': + '@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.8)': dependencies: '@types/mdx': 2.0.14 '@types/react': 19.2.17 - react: 19.2.7 + react: 19.2.8 '@mermaid-js/mermaid-mindmap@9.3.0': dependencies: @@ -12282,12 +12273,12 @@ snapshots: '@storybook/addon-docs@10.5.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.0)(rollup@4.60.3)(storybook@10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': dependencies: - '@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@19.2.7) + '@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@19.2.8) '@storybook/csf-plugin': 10.5.3(esbuild@0.28.0)(rollup@4.60.3)(storybook@10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@storybook/react-dom-shim': 10.5.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)) - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) + '@storybook/icons': 2.0.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@storybook/react-dom-shim': 10.5.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(storybook@10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) storybook: 10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) ts-dedent: 2.2.0 optionalDependencies: @@ -12341,25 +12332,11 @@ snapshots: '@storybook/global@5.0.0': {} - '@storybook/icons@2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': - dependencies: - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) - '@storybook/icons@2.0.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - '@storybook/react-dom-shim@10.5.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))': - dependencies: - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) - storybook: 10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - optionalDependencies: - '@types/react': 19.2.17 - '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@storybook/react-dom-shim@10.5.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(storybook@10.5.3(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))': dependencies: react: 19.2.8 @@ -13044,7 +13021,6 @@ snapshots: css-tree: 3.2.1 postcss: 8.5.19 tinyglobby: 0.2.17 - optional: true '@unocss/preset-attributify@66.7.5': dependencies: @@ -17179,11 +17155,6 @@ snapshots: transitivePeerDependencies: - supports-color - react-dom@19.2.7(react@19.2.7): - dependencies: - react: 19.2.7 - scheduler: 0.27.0 - react-dom@19.2.8(react@19.2.8): dependencies: react: 19.2.8 @@ -17191,8 +17162,6 @@ snapshots: react-is@17.0.2: {} - react@19.2.7: {} - react@19.2.8: {} readable-stream@2.3.8: diff --git a/scripts/verify-typecheck-coverage.ts b/scripts/verify-typecheck-coverage.ts index e39bec3b..eee9cc22 100644 --- a/scripts/verify-typecheck-coverage.ts +++ b/scripts/verify-typecheck-coverage.ts @@ -33,7 +33,7 @@ const WORKSPACE_PATTERNS = ['packages/*', 'plugins/*', 'examples/*', 'storybook' */ const EXCEPTIONS: Record = { 'plugins/inspect': 'tsconfig.json is the only one with composite:true, which makes tsc reject valid cross-package imports (TS6307); also has a couple of unrelated spa/composables type bugs. See plans/README.md "Execution notes" for plan 001.', - 'examples/minimal-next-devframe-hub': 'packages/hub/src/node/host-terminals.ts types a child-process env as NodeJS.ProcessEnv, and Next.js\'s ambient types require a literal NODE_ENV on that interface once this app pulls hub into its program. See plans/README.md "Execution notes" for plan 001.', + 'examples/next-devframe-hub': 'packages/hub/src/node/host-terminals.ts types a child-process env as NodeJS.ProcessEnv, and Next.js\'s ambient types require a literal NODE_ENV on that interface once this app pulls hub into its program. See plans/README.md "Execution notes" for plan 001.', } function expandPattern(pattern: string): string[] { diff --git a/tsconfig.base.json b/tsconfig.base.json index e6c6a69f..f38f5d8f 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -151,8 +151,8 @@ "@devframes/json-render-ui": [ "./packages/json-render-ui/src/index.ts" ], - "minimal-json-render/dashboard": [ - "./examples/minimal-json-render/src/dashboard.ts" + "json-render/dashboard": [ + "./examples/json-render/src/dashboard.ts" ], "@devframes/plugin-code-server/client": [ "./plugins/code-server/src/client/index.ts" diff --git a/turbo.json b/turbo.json index bc62ce38..6de2f6f8 100644 --- a/turbo.json +++ b/turbo.json @@ -62,7 +62,7 @@ "dependsOn": ["devframe#build", "@devframes/hub#build"], "outputs": ["dist/**"] }, - "minimal-vite-devframe-hub#build": { + "vite-devframe-hub#build": { "outputLogs": "new-only", "dependsOn": [ "@devframes/hub#build", @@ -78,7 +78,7 @@ ], "outputs": ["dist/**"] }, - "minimal-next-devframe-hub#build": { + "next-devframe-hub#build": { "outputLogs": "new-only", "dependsOn": [ "@devframes/hub#build", diff --git a/vitest.config.ts b/vitest.config.ts index f08a2b1e..1015dfc3 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -22,7 +22,7 @@ export default defineConfig({ 'plugins/git', 'plugins/a11y', 'plugins/messages', - 'examples/minimal-next-devframe-hub', + 'examples/next-devframe-hub', 'packages/next', { test: {