Skip to content

Commit a734694

Browse files
authored
feat(hub)!: introduce @devframes/hub framework-neutral hub layer (#24)
1 parent 6b58132 commit a734694

214 files changed

Lines changed: 5191 additions & 617 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ecosystem-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- run: pnpm install --frozen-lockfile
2828
- run: pnpm test:ecosystem
2929
env:
30-
ECOSYSTEM_DEVTOOLS_REF: ${{ inputs.ref }}
30+
ECOSYSTEM_DEVFRAME_REF: ${{ inputs.ref }}
3131
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3232
- if: failure()
3333
uses: actions/upload-artifact@v4

AGENTS.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
**`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.
66

7+
**`@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. See `examples/minimal-vite-devframe-hub/` for a working ~120-line Vite host demonstrating the protocol end to end.
8+
79
## Stack & Structure
810

911
ESM TypeScript library. Bundled with `tsdown`. Tested with `vitest`. pnpm workspaces with catalog dependencies (`pnpm-workspace.yaml`); workspace globs reserve `playground`, `docs`, `packages/*`, `examples/*` for future additions.
@@ -50,6 +52,16 @@ All node-side warnings and errors use structured diagnostics via [`nostics`](htt
5052

5153
Prefix: **`DF`**. Codes are sequential 4-digit numbers (e.g. `DF0033`). Check the existing diagnostics file to find the next available number.
5254

55+
Range allocation:
56+
- `DF00xx–DF07xx``devframe` core (RPC, host, storage, streams, …)
57+
- `DF80xx–DF89xx``@devframes/hub`. Sub-ranges:
58+
- `DF80xx` — hub context / lifecycle
59+
- `DF81xx` — docks
60+
- `DF82xx` — terminals
61+
- `DF83xx` — messages
62+
- `DF84xx` — commands
63+
- `DF85xx` — built-in RPC commands
64+
5365
### Adding a new error
5466

5567
1. **Define the code** in the appropriate `diagnostics.ts`:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</p>
1616

1717
<p align="center">
18-
Framework-neutral foundation for building generic DevTools.
18+
Framework-neutral foundation for building devframes.
1919
</p>
2020

2121
<p align="center">

alias.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const alias = {
1414
'devframe/rpc': r('devframe/src/rpc'),
1515
'devframe/types': r('devframe/src/types/index.ts'),
1616
'devframe/node/auth': r('devframe/src/node/auth/index.ts'),
17-
'devframe/node/internal': r('devframe/src/node/internal/index.ts'),
17+
'devframe/node/hub-internals': r('devframe/src/node/hub-internals/index.ts'),
1818
'devframe/node': r('devframe/src/node/index.ts'),
1919
'devframe/constants': r('devframe/src/constants.ts'),
2020
'devframe/utils/colors': r('devframe/src/utils/colors.ts'),
@@ -36,6 +36,11 @@ export const alias = {
3636
'devframe/helpers/vite': r('devframe/src/helpers/vite.ts'),
3737
'devframe/adapters/embedded': r('devframe/src/adapters/embedded.ts'),
3838
'devframe/adapters/mcp': r('devframe/src/adapters/mcp/index.ts'),
39+
'@devframes/hub/client': r('hub/src/client/index.ts'),
40+
'@devframes/hub/constants': r('hub/src/constants.ts'),
41+
'@devframes/hub/node': r('hub/src/node/index.ts'),
42+
'@devframes/hub/types': r('hub/src/types/index.ts'),
43+
'@devframes/hub': r('hub/src/index.ts'),
3944
'@devframes/nuxt/runtime/plugin.client': r('nuxt/src/runtime/plugin.client.ts'),
4045
'@devframes/nuxt': r('nuxt/src/index.ts'),
4146
'devframe/recipes/open-helpers': r('devframe/src/recipes/open-helpers.ts'),

docs/.vitepress/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ function guideItems(prefix: string): DefaultTheme.NavItemWithLink[] {
2828
{ text: 'Structured Diagnostics', link: `${prefix}/guide/diagnostics` },
2929
{ text: 'Client', link: `${prefix}/guide/client` },
3030
{ text: 'Standalone CLI', link: `${prefix}/guide/standalone-cli` },
31+
{ text: 'Hub (multi-tool)', link: `${prefix}/guide/hub` },
3132
{ text: 'Agent-Native (experimental)', link: `${prefix}/guide/agent-native` },
3233
]
3334
}
@@ -98,7 +99,7 @@ export function devframeNav(prefix = ''): DefaultTheme.NavItem[] {
9899

99100
export default withMermaid(defineConfig({
100101
title: 'Devframe',
101-
description: 'Framework-neutral foundation for building generic DevTools — RPC layer, hosts, and adapters.',
102+
description: 'Framework-neutral foundation for building generic devframes — RPC layer, hosts, and adapters.',
102103
head: [
103104
['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }],
104105
['link', { rel: 'apple-touch-icon', href: '/logo.svg' }],

docs/adapters/cli.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ Running the resulting binary:
2626
my-devframe # dev server at http://localhost:9999/
2727
my-devframe --port 8080
2828
my-devframe build --out-dir dist-static
29-
my-devframe build --out-dir dist-static --base /devtools/
29+
my-devframe build --out-dir dist-static --base /devframe/
3030
my-devframe mcp # stdio MCP server (experimental)
3131
```
3232

33-
Standalone CLI serves the SPA at `/` by default. The `/__devtools/` prefix is for *hosted* adapters where devframe mounts alongside an existing app — see [Mount paths](./#mount-paths).
33+
Standalone CLI serves the SPA at `/` by default. The `/__devframe/` prefix is for *hosted* adapters where devframe mounts alongside an existing app — see [Mount paths](./#mount-paths).
3434

3535
## Options
3636

docs/adapters/embedded.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ await createEmbedded(devframe, { ctx: existingCtx })
1515

1616
| Option | Required | Description |
1717
|--------|----------|-------------|
18-
| `ctx` || Target `DevToolsNodeContext` the devframe is registered into. |
18+
| `ctx` || Target `DevframeNodeContext` the devframe is registered into. |
1919

2020
Useful when a host loads devframes based on runtime conditions (feature flags, user opt-in, dynamic discovery) rather than static config.

docs/errors/DF0006.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ Register the function with `ctx.rpc.register(defineRpcFunction({ name }))` befor
1818

1919
## Source
2020

21-
- [`packages/devframe/src/node/host-functions.ts`](https://github.com/vitejs/devtools/blob/main/devframe/packages/devframe/src/node/host-functions.ts)`RpcFunctionsHost.invokeLocal()` throws `DF0006` when the requested method has not been registered on this host.
21+
- [`packages/devframe/src/node/host-functions.ts`](https://github.com/devframes/devframe/blob/main/packages/devframe/src/node/host-functions.ts)`RpcFunctionsHost.invokeLocal()` throws `DF0006` when the requested method has not been registered on this host.

docs/errors/DF0007.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ outline: deep
66

77
## Message
88

9-
> AsyncLocalStorage is not set, it likely to be an internal bug of the DevTools foundation
9+
> AsyncLocalStorage is not set, it likely to be an internal bug of the Devframe foundation
1010
1111
## Cause
1212

@@ -18,4 +18,4 @@ Only call `getCurrentRpcSession()` from RPC handlers executed by the server. Rep
1818

1919
## Source
2020

21-
- [`packages/devframe/src/node/host-functions.ts`](https://github.com/vitejs/devtools/blob/main/devframe/packages/devframe/src/node/host-functions.ts)`getCurrentRpcSession()` throws `DF0007` when called outside the RPC dispatch async context.
21+
- [`packages/devframe/src/node/host-functions.ts`](https://github.com/devframes/devframe/blob/main/packages/devframe/src/node/host-functions.ts)`getCurrentRpcSession()` throws `DF0007` when called outside the RPC dispatch async context.

docs/errors/DF0008.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ outline: deep
1010
1111
## Cause
1212

13-
`DevToolsViewHost.hostStatic()` was asked to mount a directory that doesn't exist on disk.
13+
`DevframeViewHost.hostStatic()` was asked to mount a directory that doesn't exist on disk.
1414

1515
## Fix
1616

1717
Verify the `distDir` path resolves correctly (run your SPA build first, and check the resolved absolute path).
1818

1919
## Source
2020

21-
- [`packages/devframe/src/node/host-views.ts`](https://github.com/vitejs/devtools/blob/main/devframe/packages/devframe/src/node/host-views.ts)`DevToolsViewHost.hostStatic()` throws `DF0008` when the resolved `distDir` does not exist on disk.
21+
- [`packages/devframe/src/node/host-views.ts`](https://github.com/devframes/devframe/blob/main/packages/devframe/src/node/host-views.ts)`DevframeViewHost.hostStatic()` throws `DF0008` when the resolved `distDir` does not exist on disk.

0 commit comments

Comments
 (0)