Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,44 @@ function listErrorCodes(prefix: string): string[] {
function guideGroups(prefix: string) {
return [
{
text: 'Fundamentals',
text: 'Introduction',
items: [
{ text: 'Introduction', link: `${prefix}/guide/` },
],
},
{
text: 'Define your tool',
items: [
{ text: 'Devframe Definition', link: `${prefix}/guide/devframe-definition` },
{ text: 'RPC', link: `${prefix}/guide/rpc` },
{ text: 'Shared State', link: `${prefix}/guide/shared-state` },
{ text: 'Client Assets', link: `${prefix}/guide/client-assets` },
{ text: 'Structured Diagnostics', link: `${prefix}/guide/diagnostics` },
{ text: 'Agent-Native', link: `${prefix}/guide/agent-native` },
{ text: 'JSON-Render', link: `${prefix}/guide/json-render` },
{ text: 'Streaming', link: `${prefix}/guide/streaming` },
{ text: 'Client Assets', link: `${prefix}/guide/client-assets` },
{ text: 'Scoped Context', link: `${prefix}/guide/scoped-context` },
{ text: 'Standalone CLI', link: `${prefix}/guide/standalone-cli` },
{ text: 'JSON-Render', link: `${prefix}/guide/json-render` },
{ text: 'Structured Diagnostics', link: `${prefix}/guide/diagnostics` },
{ text: 'When Clauses', link: `${prefix}/guide/when-clauses` },
],
},
{
text: 'Client & Security',
text: 'Mount anywhere',
items: [
{ text: 'The Standard Handler', link: `${prefix}/adapters/initiate` },
{ text: 'Adapters', link: `${prefix}/adapters/` },
{ text: 'Standalone CLI', link: `${prefix}/guide/standalone-cli` },
{ text: 'Client', link: `${prefix}/guide/client` },
{ text: 'Transports', link: `${prefix}/guide/transports` },
{ text: 'Security', link: `${prefix}/guide/security` },
],
},
{
text: 'Hub',
text: 'Visual & agentic',
items: [
{ text: 'Agent-Native', link: `${prefix}/guide/agent-native` },
],
},
{
text: 'Compose a hub',
items: [
{ text: 'Hub', link: `${prefix}/guide/hub` },
{ text: 'Client Scripts & Context', link: `${prefix}/guide/client-context` },
Expand All @@ -54,28 +67,21 @@ function guideGroups(prefix: string) {
],
},
{
text: 'Customization',
text: 'Customize the UI',
items: [
{ text: 'Build Your Own JSON-Render Frontend', link: `${prefix}/guide/build-your-own-json-render-frontend` },
{ text: 'Build Your Own Hub UI', link: `${prefix}/guide/build-your-own-hub-ui` },
],
},
{
text: 'References',
items: [
{ text: 'When Clauses', link: `${prefix}/guide/when-clauses` },
{ text: 'Examples', link: `${prefix}/examples/` },
],
},
] satisfies { text: string, items: DefaultTheme.NavItemWithLink[] }[]
}

function adaptersItems(prefix: string) {
return [
{ text: 'Overview', link: `${prefix}/adapters/` },
{ text: 'Initiate (middleware)', link: `${prefix}/adapters/initiate` },
{ text: 'Dev', link: `${prefix}/adapters/dev` },
{ text: 'The Standard Handler', link: `${prefix}/adapters/initiate` },
{ text: 'CLI', link: `${prefix}/adapters/cac` },
{ text: 'Dev', link: `${prefix}/adapters/dev` },
{ text: 'Build', link: `${prefix}/adapters/build` },
{ text: 'Vite DevTools', link: `${prefix}/adapters/vite` },
{ text: 'Embedded', link: `${prefix}/adapters/embedded` },
Expand Down
7 changes: 5 additions & 2 deletions docs/adapters/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ outline: deep

# Adapters

An adapter takes a `DevframeDefinition` and deploys it into a specific runtime — a standalone CLI, a Vite plugin, a static snapshot, an embedded host, or an MCP server. Each adapter ships at its own entry point (`devframe/adapters/<name>`); the bundler pulls in only the ones you use.
The lowest-level way to serve a devframe is [the standard handler](./initiate): `initDevframe(def, { base })` returns a Web Standard `(request: Request) => Promise<Response>` that mounts on any catch-all route. Every serving path below is built on it.

Adapters package that same foundation into familiar entry points, so you rarely wire the handler by hand. Each adapter takes a `DevframeDefinition` and deploys it into a specific runtime — a standalone CLI, a dev server, a Vite plugin, a static snapshot, an embedded host, or an MCP server. Each ships at its own entry point (`devframe/adapters/<name>`), so the bundler pulls in only the ones you use.

Every adapter factory has the shape `createXxx(devframeDef, options?)`. Some adapters draw on an optional peer dependency, installed only when you opt into that adapter: `cac` pulls in [`cac`](https://github.com/cacjs/cac), and `mcp` pulls in [`@modelcontextprotocol/server`](https://github.com/modelcontextprotocol/typescript-sdk).

## Comparison

| Adapter | Entry | Factory | Best for |
| Entry point | Module | Factory | Best for |
|---------|-------|---------|----------|
| [Standard Handler](./initiate) | `devframe/initiate` | `initDevframe(def, { base })` | Mounting the raw `Request → Response` handler into any host |
| [`cac`](./cac) | `devframe/adapters/cac` | `createCac(def, options?)` | Standalone tools run via `node ./my-tool.js` |
| [`dev`](./dev) | `devframe/adapters/dev` | `createDevServer(def, options?)` | Run the dev server programmatically — drive it from any CLI framework |
| [`build`](./build) | `devframe/adapters/build` | `createBuild(def, options?)` | Offline reports, CI artifacts, deployable SPA snapshots |
Expand Down
4 changes: 2 additions & 2 deletions docs/adapters/initiate.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Initiate (standard middleware)
# The Standard Handler

Serve a devframe from inside any app that can mount a catch-all route: `initDevframe(def, { base })` returns a live instance whose `.handler` — a web-standard `(request: Request) => Promise<Response>` — carries the whole surface (the SPA, `__connection.json` discovery, the WebSocket RPC endpoint, the auth gate, and the optional MCP route) under one mount base.
`initDevframe()` is the boundary the whole project is built on: it turns a `DevframeDefinition` into a live instance whose `.handler` — a Web Standard `(request: Request) => Promise<Response>` — carries the entire surface (the SPA, `__connection.json` discovery, the WebSocket RPC endpoint, the auth gate, and the optional MCP route) under one mount base. Every other serving path — the [adapters](./), the [framework packages](/frameworks/), and the [hub](../guide/hub-initiate) — is assembled from it. Mount it from inside any app that can serve a catch-all route.

```ts
import { initDevframe } from 'devframe/initiate'
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/hub-initiate.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const hub = initHub({
})
```

`base` is required so the mount path is explicit; pass the exported `DEVFRAMES_HUB_BASE` for the conventional `/__devframes/`. The instance echoes the normalized value back as `hub.base`, so route guards and middleware reference it instead of repeating the string. Every mounted devframe runs its `setup()` against the **shared hub context**: one merged RPC registry (frames can call each other's functions), one shared-state store, one WebSocket transport, one Auth. The instance mirrors `initDevframe`'s surface — `base`, `handler`, `nodeMiddleware`, `attach`, `handleUpgrade`, `ready`, `context`, `connectionMeta()`, `close()` — and the same mount snippets apply; see [the initiate adapter](../adapters/initiate#mount-the-handler).
`base` is required so the mount path is explicit; pass the exported `DEVFRAMES_HUB_BASE` for the conventional `/__devframes/`. The instance echoes the normalized value back as `hub.base`, so route guards and middleware reference it instead of repeating the string. Every mounted devframe runs its `setup()` against the **shared hub context**: one merged RPC registry (frames can call each other's functions), one shared-state store, one WebSocket transport, one Auth. The instance mirrors `initDevframe`'s surface — `base`, `handler`, `nodeMiddleware`, `attach`, `handleUpgrade`, `ready`, `context`, `connectionMeta()`, `close()` — and the same mount snippets apply; see [The Standard Handler](../adapters/initiate#mount-the-handler).

## The shared socket

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ctx.commands.register({
})
```

`args` takes positional valibot schemas (a single `v.object(...)` is unwrapped into the tool's input object); omit it for a zero-argument tool. `safety` defaults to `'action'`. `when` clauses evaluate client-side only and are not enforced for agent calls — opt in a `when`-gated command only if running it outside its UI context is safe.
`args` takes positional [Standard Schema](https://standardschema.dev/) schemas (valibot above; a single `v.object(...)` is unwrapped into the tool's input object); omit it for a zero-argument tool. `safety` defaults to `'action'`. `when` clauses evaluate client-side only and are not enforced for agent calls — opt in a `when`-gated command only if running it outside its UI context is safe.

## Cross-iframe dock activation

Expand Down
Loading
Loading