Skip to content

feat(hub)!: introduce @devframes/hub framework-neutral hub layer#24

Merged
antfu merged 10 commits into
mainfrom
antfu/devframe-hub-eval
May 28, 2026
Merged

feat(hub)!: introduce @devframes/hub framework-neutral hub layer#24
antfu merged 10 commits into
mainfrom
antfu/devframe-hub-eval

Conversation

@antfu
Copy link
Copy Markdown
Contributor

@antfu antfu commented May 22, 2026

Introduces @devframes/hub — the framework-neutral hub layer that lifts docks/terminals/messages/commands out of @vitejs/devtools-kit so any framework can build a hub kit on the same protocol. Hub-kit authors ship UI on top of the RPC + shared-state surface defined here; framework hosts only implement an adapter that calls mountDevframe().

mountDevframe() is the framework-neutral mount primitive. The built-in hub:commands:execute RPC dispatches any registered server command — host-specific capabilities (editor open, finder reveal, …) ship as kit-registered RPCs rather than as part of the hub surface.

Two minimal example apps act as protocol witnesses:

  • examples/minimal-vite-devframe-hub/ — Vite plugin + tiny DOM UI.
  • examples/minimal-next-devframe-hub/ — Next.js host wiring the same protocol through App Router.

The DF8xxx diagnostic range is reserved for hub-side codes with per-subsystem sub-ranges; nine error reference pages and docs/guide/hub.md document the surface.

The devframe package's internal identifiers (DEVTOOLS_MOUNT_PATH, the REMOTE_CONNECTION_KEY value, etc.) are renamed from devtools to devframe so the surface lines up with the package name. The previously-private devframe/node/internal subpath becomes devframe/node/hub-internals and is declared the stable public surface for first-party hub adapters.

Coordinated thinning of @vitejs/devtools-kit to re-export from @devframes/hub is a follow-up PR in the vitejs/devtools repo.

This PR was created with the help of an agent.

Lifts the docks/terminals/messages/commands subsystems out of
@vitejs/devtools-kit into a framework-neutral package so any framework
(Vite, Next.js, etc.) can build a hub kit on the same infrastructure.
Adds `mountDevframe` as the framework-neutral mount primitive,
`HubHostCapabilities` for optional host capabilities (e.g. `openPath`),
and built-in RPCs `hub:open-path` / `hub:commands:execute`.

Reserves the `DF8xxx` diagnostic range for hub-side codes with
sub-ranges per subsystem. New `examples/minimal-vite-devtools-kit/`
acts as a protocol witness — a ~150-line Vite plugin + tiny DOM UI
that exercises every hub subsystem end to end.
Copilot AI review requested due to automatic review settings May 22, 2026 03:05
@netlify
Copy link
Copy Markdown

netlify Bot commented May 22, 2026

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit 947ce24
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a14edd058e0af0008feacac
😎 Deploy Preview https://deploy-preview-24--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new framework-neutral @devframes/hub package that extracts and standardizes the multi-tool “hub” layer (docks/terminals/messages/commands + shared-state/RPC protocol) so different framework kits can build on the same infrastructure. This PR also adds a minimal Vite example that exercises the hub protocol end-to-end and documents the new surface + diagnostics.

Changes:

  • Added @devframes/hub package with node/client entrypoints, shared types/constants, built-in RPC/commands, and diagnostics in the DF8xxx range.
  • Wired workspace tooling (Turbo, TS path aliases, pnpm catalogs/lockfile) to build/consume the new package.
  • Added docs (hub guide + error reference pages) and a minimal Vite example as a protocol witness.

Reviewed changes

Copilot reviewed 61 out of 67 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
turbo.json Adds Turbo build pipelines for @devframes/hub and the minimal Vite example.
tsconfig.base.json Adds TS path aliases for @devframes/hub/* entrypoints.
pnpm-workspace.yaml Adds tinyexec to the dependency catalog.
pnpm-lock.yaml Locks new hub/example dependencies and workspace importers.
alias.ts Adds monorepo alias mappings for @devframes/hub/*.
AGENTS.md Documents hub package purpose and reserves DF8xxx diagnostic ranges.
packages/hub/package.json Defines the new published package exports and dependencies.
packages/hub/LICENSE.md Adds package-level MIT license.
packages/hub/tsconfig.json Hub package TS config (composite + DOM lib).
packages/hub/tsdown.config.ts Build configuration for hub multi-entry outputs.
packages/hub/src/index.ts Exposes hub’s public API (define helpers + types).
packages/hub/src/define.ts Adds defineCommand, defineDockEntry, defineJsonRenderSpec, and hub-context defineRpcFunction.
packages/hub/src/constants.ts Adds hub defaults and re-exports devframe constants.
packages/hub/src/utils/diagnostics-reporter.ts Adds ANSI diagnostics reporter wiring for hub diagnostics.
packages/hub/src/types/index.ts Hub types barrel + selective devframe type re-exports.
packages/hub/src/types/commands.ts Command palette types (server/client commands, keybindings, host).
packages/hub/src/types/docks.ts Dock entry types including remote-UI options and connection descriptor shape.
packages/hub/src/types/json-render.ts Json-render spec/renderer types.
packages/hub/src/types/messages.ts Message/toast queue types and host/client surfaces.
packages/hub/src/types/settings.ts Persisted hub user settings types.
packages/hub/src/types/terminals.ts Terminal session and child-process terminal types.
packages/hub/src/node/index.ts Hub node entrypoint barrel.
packages/hub/src/node/context.ts Implements createHubContext() wiring hosts, shared-state sync, and built-ins.
packages/hub/src/node/diagnostics.ts Defines DF8xxx diagnostics for hub subsystems.
packages/hub/src/node/host-commands.ts Implements commands registry + execution/list serialization.
packages/hub/src/node/host-docks.ts Implements dock registry, built-in dock entries, and remote-UI URL enrichment.
packages/hub/src/node/host-messages.ts Implements message queue + events + auto-delete + capacity eviction.
packages/hub/src/node/host-terminals.ts Implements terminal sessions + streaming channel integration + child-process terminals.
packages/hub/src/node/hub-builtins.ts Registers hub built-in command(s) like hub:open-path.
packages/hub/src/node/rpc-builtins.ts Adds hub built-in RPC(s) like hub:commands:execute.
packages/hub/src/node/mount-devframe.ts Adds framework-neutral mountDevframe() primitive.
packages/hub/src/node/utils.ts Adds createSimpleClientScript() helper for quick client-script entries.
packages/hub/src/client/index.ts Hub client entrypoint barrel + devframe client re-exports.
packages/hub/src/client/context.ts Adds global client-context getter and key export.
packages/hub/src/client/docks.ts Defines client-side dock/commands context types.
packages/hub/src/client/client-script.ts Defines dock client-script context shape.
packages/hub/src/client/remote.ts Adds remote-UI descriptor parsing and connectRemoteDevTools().
examples/minimal-vite-devtools-kit/package.json Adds minimal Vite example package and scripts.
examples/minimal-vite-devtools-kit/vite.config.ts Example Vite config wiring the minimal hub kit plugin.
examples/minimal-vite-devtools-kit/tsconfig.json Example TS config for Vite + DOM UI.
examples/minimal-vite-devtools-kit/index.html Minimal DOM UI shell.
examples/minimal-vite-devtools-kit/README.md Run instructions + protocol-witness explanation.
examples/minimal-vite-devtools-kit/src/minimal-hub-kit.ts Minimal Vite plugin that creates hub context and sidecar WS server.
examples/minimal-vite-devtools-kit/src/devframe.ts Demo devframe definition that registers commands/messages.
examples/minimal-vite-devtools-kit/src/client/main.ts Browser-side UI reading shared state and calling hub built-ins.
examples/minimal-vite-devtools-kit/src/client/style.css Styling for the minimal DOM UI.
docs/.vitepress/config.ts Adds hub guide to docs nav.
docs/guide/hub.md Documents hub concepts, protocol, host capabilities, and example.
docs/errors/DF8100.md Error reference for dock already registered.
docs/errors/DF8101.md Error reference for cannot change dock id.
docs/errors/DF8102.md Error reference for dock not registered.
docs/errors/DF8200.md Error reference for terminal session already registered.
docs/errors/DF8201.md Error reference for terminal session not registered.
docs/errors/DF8400.md Error reference for command already registered.
docs/errors/DF8401.md Error reference for cannot change command id.
docs/errors/DF8402.md Error reference for command not registered.
docs/errors/DF8500.md Error reference for missing host capability for built-in command.
tests/snapshots/tsnapi/@devframes/hub/index.snapshot.js Adds tsnapi public API snapshot for @devframes/hub.
tests/snapshots/tsnapi/@devframes/hub/index.snapshot.d.ts Adds tsnapi type snapshot for @devframes/hub.
tests/snapshots/tsnapi/@devframes/hub/node.snapshot.js Adds tsnapi public API snapshot for @devframes/hub/node.
tests/snapshots/tsnapi/@devframes/hub/node.snapshot.d.ts Adds tsnapi type snapshot for @devframes/hub/node.
tests/snapshots/tsnapi/@devframes/hub/client.snapshot.js Adds tsnapi public API snapshot for @devframes/hub/client.
tests/snapshots/tsnapi/@devframes/hub/client.snapshot.d.ts Adds tsnapi type snapshot for @devframes/hub/client.
tests/snapshots/tsnapi/@devframes/hub/constants.snapshot.js Adds tsnapi public API snapshot for @devframes/hub/constants.
tests/snapshots/tsnapi/@devframes/hub/constants.snapshot.d.ts Adds tsnapi type snapshot for @devframes/hub/constants.
tests/snapshots/tsnapi/@devframes/hub/types.snapshot.js Adds tsnapi public API snapshot for @devframes/hub/types.
tests/snapshots/tsnapi/@devframes/hub/types.snapshot.d.ts Adds tsnapi type snapshot for @devframes/hub/types.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +45 to +55
function buildRemoteUrl(baseUrl: string, payload: RemoteConnectionInfo, transport: 'fragment' | 'query'): string {
const encoded = base64UrlEncode(JSON.stringify(payload))
const param = `${REMOTE_CONNECTION_KEY}=${encoded}`
if (transport === 'fragment') {
// Replace any existing fragment bearing our key; otherwise append.
const hashIdx = baseUrl.indexOf('#')
if (hashIdx === -1)
return `${baseUrl}#${param}`
const before = baseUrl.slice(0, hashIdx)
return `${before}#${param}`
}
Comment on lines +134 to +138
const record = this.remoteDocks.get(view.id)
const endpoint = getInternalContext(this.context as DevToolsNodeContext).wsEndpoint
if (!record || !endpoint)
return view

Comment thread packages/hub/src/node/host-terminals.ts Outdated
Comment on lines +121 to +130
session.stream.pipeTo(writer).catch(() => {
// pipeTo rejection surfaces via writer.abort -> sink.error already.
})
this._boundStreams.set(session.id, {
dispose: () => {
if (sink && !sink.closed)
sink.close()
},
stream: session.stream,
})
Comment on lines +142 to +170
let controller: ReadableStreamDefaultController<string> | undefined
const stream = new ReadableStream<string>({
start(_controller) {
controller = _controller
},
})

function createChildProcess() {
const cp = exec(
executeOptions.command,
executeOptions.args || [],
{
nodeOptions: {
env: {
COLORS: 'true',
FORCE_COLOR: 'true',
...(executeOptions.env || {}),
},
cwd: executeOptions.cwd ?? process.cwd(),
stdio: 'pipe',
},
},
)

;(async () => {
for await (const chunk of cp) {
controller?.enqueue(chunk)
}
})()
Comment on lines +115 to +120
const docksSharedState = await context.rpc.sharedState.get('devframe:docks', { initialValue: [] })
const refreshDocks = debounce(() => {
docksSharedState.mutate(() => docks.values())
}, debounceMs)
docks.events.on('dock:entry:updated', refreshDocks)

Comment thread packages/hub/src/node/host-messages.ts
Comment thread packages/hub/src/node/host-commands.ts Outdated
@antfu antfu marked this pull request as draft May 22, 2026 03:17
@antfu antfu changed the title feat(hub): introduce @devframes/hub framework-neutral hub layer feat(hub)!: introduce @devframes/hub framework-neutral hub layer May 22, 2026
@antfu antfu requested a review from Copilot May 22, 2026 07:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 194 out of 210 changed files in this pull request and generated 9 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread vitest.config.ts
Comment on lines 1 to +7
import { defineConfig } from 'vitest/config'
import { alias } from './alias'

export default defineConfig({
resolve: {
alias,
},
Comment on lines +1 to +7
import { defineConfig } from 'vite'
import { alias } from '../../alias'
import demoDevframe from './src/devframe'
import { minimalViteDevframeHub } from './src/minimal-vite-devframe-hub'

export default defineConfig({
resolve: { alias },
Comment on lines +1 to +7
import { defineConfig } from 'vitest/config'
import { alias } from '../../alias'

export default defineConfig({
resolve: {
alias,
},
Comment thread packages/hub/src/types/terminals.ts Outdated
Comment on lines +1 to +5
import type { EventEmitter } from 'devframe/types'
import type { ChildProcess } from 'node:child_process'
import type { DevframeDockEntryIcon } from './docks'

export interface DevframeTerminalHost {
throw lastError
}

describe('devToolsTerminalHost stream lifecycle', () => {
import { describe, expect, it } from 'vitest'
import { DevframeMessagesHost } from '../host-messages'

describe('devToolsMessagesHost', () => {
} as unknown as HubNodeContext
}

describe('devToolsDockHost remote URL enrichment', () => {
import { describe, expect, it } from 'vitest'
import { DevframeCommandsHost } from '../host-commands'

describe('devToolsCommandsHost command id validation', () => {
Comment on lines +5 to +7
import { createHostContext, startHttpAndWs } from '../../../../devframe/src/node'
import { getInternalContext } from '../../../../devframe/src/node/internal'
import { createHubContext } from '../context'
antfu added 6 commits May 22, 2026 16:59
Host-specific behavior (editor open, finder reveal, ...) belongs in
kit-registered RPC functions, not in the framework-neutral hub surface.
Drop HubHostCapabilities, hub:open-path, hub-builtins.ts, and the DF8500
diagnostic; trim the docs and examples to match.
Address downstream feedback from @vitejs/devtools-kit:

- Drop the Vite-specific `~viteplus` category from the hub's
  framework-neutral surface; widen `DevframeDockEntryCategory` to
  `(string & {})` so kits register their own categories ad-hoc.
- Rename `DevframeDockHost` → `DevframeDocksHost` and
  `DevframeTerminalHost` → `DevframeTerminalsHost` so host class names
  match their `ctx.docks` / `ctx.terminals` property names.
- Rename `HubNodeContext` → `DevframeHubContext` to follow the
  `Devframe*` prefix pattern the rest of the codebase uses.
- Rename hub's `defineRpcFunction` → `defineHubRpcFunction` so the
  hub-context-typed factory can't be confused with devframe's or a
  kit's identically-named export.
This subpath is the bridge `@devframes/hub` (and any future first-party
hub adapter) uses to reach into devframe's remote-dock token machinery
and basePath resolver. Calling it "internal" while a published package
depends on it understates the contract: rename to `hub-internals` and
document it as the stable surface for first-party hub adapters.
# Conflicts:
#	examples/streaming-chat/src/devframe.ts
The error-reference Source links and one example README pointed at
github.com/vitejs/devframe, which does not exist. Repoint to the
canonical devframes/devframe repo, and fix the streaming-chat README
to cite vitejs/devtools#306 (the original AI-deltas issue thread).
@antfu antfu marked this pull request as ready for review May 28, 2026 01:34
Copilot AI review requested due to automatic review settings May 28, 2026 01:34
@antfu antfu merged commit a734694 into main May 28, 2026
12 of 13 checks passed
@antfu antfu deleted the antfu/devframe-hub-eval branch May 28, 2026 01:37
@abrahem79
Copy link
Copy Markdown

`if (!query) {
  console.error('Error: Please provide a query as a command-line argument.');
  process.exit(1);
}

const sessionId = await createChatSession(externalUserId);
const result = await submitQuery(sessionId, query);
console.log('Response:\\n', JSON.stringify(result, null, 2));`

Copy link
Copy Markdown

@abrahem79 abrahem79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants