Skip to content

Commit e018de5

Browse files
authored
docs: split guide lookup tables into grouped reference pages (#313)
1 parent d25c4b5 commit e018de5

19 files changed

Lines changed: 400 additions & 236 deletions

AGENTS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,18 @@ Callouts (`> [!NOTE]`, `> [!TIP]`, `> [!INFO]`, `::: tip`, etc.) interrupt the r
211211

212212
Trim filler intros, redundant cross-links (one link per page is enough - sidebars handle navigation), and code samples that demonstrate more than the point being made. Lead each page with one sentence that says what the reader can build with this. Strip out promises about future work, marketing language ("powerful", "seamless"), and exposition that the surrounding code already conveys.
213213

214+
### 4. Guides teach, references list
215+
216+
The docs separate learning material from lookup material, following the [Divio documentation system](https://docs.divio.com/documentation-system/):
217+
218+
- **Guide pages (`docs/content/1.guide/`) are learning-oriented** - prose, code examples, and explanation. A lookup table (definition fields, options, enums, statuses, event names, route tables) belongs on a references page, with the guide keeping a one-or-two-sentence prose summary of the essentials plus a link to the reference section. Comparison and decision tables ("X vs Y", trade-off matrices) are explanation and stay in the guides; navigational link tables stay on `index.md` pages.
219+
- **The references section (`docs/content/8.references/`) holds the lookup tables**, grouped: [Node-Side API](docs/content/8.references/4.node-api.md), [Browser-Side API](docs/content/8.references/5.browser-api.md), and [Hub API](docs/content/8.references/6.hub-api.md), alongside the terms, when-clauses, and events pages. Each reference section opens with one line naming what the table lists and linking the guide page that teaches it. A new lookup table goes into the matching reference page (and the references `index.md`), not into a guide.
220+
- **The adapters, frameworks, helpers, and plugins sections are per-package reference pages** - each page is the reference for its own adapter/kit/package, so its options and RPC tables stay in place.
221+
214222
### What goes where
215223

216224
- Critical security / data-loss hazard → `[!WARNING]` callout.
217225
- Experimental API / stability caveat → `[!WARNING]` callout at the top of the page.
218226
- Bad-practice contrast → inline `// ✗ Bad` / `// ✓ Good` comments inside code blocks.
227+
- Lookup table for a guide topic → the matching `docs/content/8.references/` page; the guide keeps a prose summary + link.
219228
- Anything else worth saying → prose.

docs/content/1.guide/10.standalone-cli.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,7 @@ version.on('updated', () => fetchPayload().then(setData))
279279

280280
## Use your own CLI framework
281281

282-
Own a CLI framework (commander, yargs, oclif)? Use the three factories `createCac` wraps, against one `DevframeDefinition`:
283-
284-
| Building block | Entry |
285-
|----------------|-------|
286-
| `createDevServer(def, opts?)` | `devframe/adapters/dev` |
287-
| `createBuild(def, opts?)` | `devframe/adapters/build` |
288-
| `createMcpServer(def, opts?)` | `devframe/adapters/mcp` |
282+
Own a CLI framework (commander, yargs, oclif)? Use the three factories `createCac` wraps against one `DevframeDefinition`: `createDevServer` (`devframe/adapters/dev`), `createBuild` (`devframe/adapters/build`), and `createMcpServer` (`devframe/adapters/mcp`) — see the [CLI adapter](/adapters/cac#use-your-own-cli-framework).
289283

290284
```ts [src/cli.ts]
291285
import process from 'node:process'

docs/content/1.guide/11.client.md

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,7 @@ await registerDevframeViewerOrigin(connection)
5757

5858
### Options
5959

60-
| Option | Description |
61-
|--------|-------------|
62-
| `connection` | Connection prepared by `setupDevframeConnection()`. |
63-
| `baseURL` | Mount path to probe for `__connection.json` (array = fallback). Default `'./'` (relative to `document.baseURI`); use an absolute path (`'/__devframe/'`) from outside the SPA. |
64-
| `authToken` | Override the auth token (default: a locally-persisted id). |
65-
| `cacheOptions` | `true` for default caching, or an options object. |
66-
| `callTimeout` | Ms before a pending `rpc.call` rejects with a `'timeout'` `DevframeConnectionError`; `0`/omit = wait forever. |
67-
| `wsOptions` | Transport overrides — `onConnected` / `onError` / `onDisconnected` hooks, socket URL. |
68-
| `rpcOptions` | Forwarded to `birpc`. |
69-
| `connectionMeta` | Descriptor that skips the `__connection.json` fetch. |
60+
`baseURL` points at the mount path to probe for `__connection.json` (default `'./'`, relative to `document.baseURI`); `connection` adopts one prepared by `setupDevframeConnection()`. The rest cover auth (`authToken`), [caching](#caching) (`cacheOptions`), timeouts (`callTimeout`), transport hooks (`wsOptions`), `birpc` passthrough (`rpcOptions`), and discovery override (`connectionMeta`) — every option is in the [Browser-Side API reference](/references/browser-api#connectdevframe-options).
7061

7162
## Modes
7263

@@ -256,14 +247,7 @@ const displayUrl = stripRemoteConnectionFromUrl(viewerUrl)
256247

257248
## Events
258249

259-
Emitted over `rpc.events`:
260-
261-
| Event | Fires when |
262-
|-------|------------|
263-
| `rpc:is-trusted:updated` | Trust granted, denied, or revoked. Carries the new `isTrusted` boolean. |
264-
| `connection:status` | The [connection status](#handling-connection-and-auth-errors) changes. Carries `(status, previous)`. |
265-
| `connection:error` | A connection-level failure — socket error or trust refused. Carries the `Error`. |
266-
| `rpc:error` | An `rpc.call` rejects, from the node side or a down connection. Carries `(error, method)`. |
250+
Four events arrive over `rpc.events`: `rpc:is-trusted:updated` when trust is granted, denied, or revoked; `connection:status` when the [connection status](#handling-connection-and-auth-errors) changes; `connection:error` on a connection-level failure; and `rpc:error` when an `rpc.call` rejects. Payloads are in the [Browser-Side API reference](/references/browser-api#rpc-client-events).
267251

268252
```ts
269253
rpc.events.on('rpc:is-trusted:updated', (isTrusted) => {
@@ -280,15 +264,7 @@ rpc.events.on('rpc:is-trusted:updated', (isTrusted) => {
280264

281265
### Connection status
282266

283-
`rpc.status` collapses transport and trust into one value; `rpc.connectionError` holds the last connection-level `Error` (`null` when healthy):
284-
285-
| Status | Meaning |
286-
|--------|---------|
287-
| `connecting` | Establishing socket / handshake. Calls queue until open. |
288-
| `connected` | Socket open and trusted; calls are served. |
289-
| `unauthorized` | Socket open, trust refused. Prompt for [authentication](#authenticating-with-a-one-time-code). |
290-
| `disconnected` | Socket closed (dropped mid-session or never opened). |
291-
| `error` | Fatal — the socket errored or connection meta couldn't load. |
267+
`rpc.status` collapses transport and trust into one value; `rpc.connectionError` holds the last connection-level `Error` (`null` when healthy). It moves through `connecting` (calls queue until open), `connected` (calls are served), `unauthorized` (socket open, trust refused — prompt for [authentication](#authenticating-with-a-one-time-code)), `disconnected`, and `error`; each value's meaning is in the [Browser-Side API reference](/references/browser-api#connection-statuses).
292268

293269
A `static` backend has no live socket, so `rpc.status` stays `connected`.
294270

docs/content/1.guide/12.in-page-channel.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,7 @@ Without an `initialValue`, a panel's `get` resolves once the first replay arrive
123123

124124
## Errors and fallbacks
125125

126-
Every failure mode is a coded `InPageChannelError` (`error.code`) with a message that explains itself:
127-
128-
| Code | When | What to do |
129-
|------|------|------------|
130-
| `timeout` | A call outlived `callTimeoutMs` (default 15s), or `whenConnected(ms)` expired | The message carries the endpoint status — `connecting` usually means the page script isn't loaded in this context |
131-
| `closed` | The endpoint was closed with calls pending | Expected during teardown |
132-
| `not-serializable` | A `jsonSerializable: true` payload contained a non-JSON value | The message names the offending path (e.g. `its arguments[0].nodes[2]` is a Map) |
133-
| `not-cloneable` | The port refused to clone a payload (`DataCloneError`) | Strip functions/DOM nodes/reactivity proxies — or declare `jsonSerializable: true` for the precise error above |
134-
| `invalid-args` | Incoming arguments failed their Standard-Schema validation | The message lists the schema issues |
135-
| `state-uninitialized` | The page script read a shared state before providing its `initialValue` | Initialize on first access |
126+
Every failure mode is a coded `InPageChannelError` (`error.code`) with a message that explains itself: `timeout` (a call or `whenConnected(ms)` outlived its deadline), `closed` (endpoint torn down with calls pending), `not-serializable` / `not-cloneable` (a payload the port can't carry — the message names the offending path), `invalid-args` (Standard-Schema validation failed), and `state-uninitialized` (a shared state read before its `initialValue`). Causes and fixes per code are in the [Browser-Side API reference](/references/browser-api#in-page-channel-error-codes).
136127

137128
The panel endpoint's connection lifecycle is explicit, so a panel renders a useful fallback instead of hanging:
138129

docs/content/1.guide/14.security.md

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,9 @@ Pass `clientAuthTokens` for CI/shared machines to skip the prompt, or a custom `
5151

5252
### Auth methods
5353

54-
| RPC method | Direction | Shape |
55-
|------------|-----------|-------|
56-
| `anonymous:devframe:auth` | client → server | `{ authToken, ua, origin }``{ isTrusted }` — re-authenticate a stored token |
57-
| `anonymous:devframe:auth:exchange` | client → server | `{ code, ua, origin }``{ authToken \| null }` — exchange a code for a token |
58-
| `devframe:auth:revoke` | client → server | self-revoke the caller's own token |
59-
| `devframe:auth:revoked` | server → client | event — token revoked |
60-
61-
Node primitives (`devframe/node/auth`):
62-
63-
| Function | Role |
64-
|----------|------|
65-
| `getTempAuthCode()` / `refreshTempAuthCode()` | read / rotate the one-time code |
66-
| `exchangeTempAuthCode(code, session, { ua, origin }, storage)` | verify a code, mint + store the token, trust the session, return it (or `null`) |
67-
| `verifyAuthToken(token, session, storage)` | trust a session presenting a known token |
68-
| `buildOtpAuthUrl(origin, code?)` | build a magic-link URL embedding the code |
69-
| `revokeAuthToken(context, storage, token)` | delete a token and disconnect sessions using it |
54+
The two `anonymous:`-prefixed handshake methods re-authenticate a stored token (`anonymous:devframe:auth`) and exchange a one-time code for a token (`anonymous:devframe:auth:exchange`); `devframe:auth:revoke` self-revokes, and the `devframe:auth:revoked` event drops affected RPC clients to untrusted. Wire shapes are in the [Node-Side API reference](/references/node-api#auth-methods).
55+
56+
Node primitives in `devframe/node/auth``getTempAuthCode` / `refreshTempAuthCode`, `exchangeTempAuthCode`, `verifyAuthToken`, `buildOtpAuthUrl`, and `revokeAuthToken` — implement the same flow for a host framework wiring its own gate; signatures are in the [reference](/references/node-api#node-auth-primitives).
7057

7158
RPC client methods (`devframe/client`): `requestTrustWithCode(code)`, `requestTrustWithToken(token)`, and `ensureTrusted(timeout?)` / `isTrusted` (the trust gate).
7259

docs/content/1.guide/15.agent-native.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,4 @@ Prefer coded diagnostics anywhere agent-reachable: agents act on `fix` and follo
183183

184184
## CLI
185185

186-
| Command | Description |
187-
|---------|-------------|
188-
| `<your-app> mcp` | Start the MCP server on `stdio`. |
189-
| `<your-app> dev --mcp` | Serve the agent-consumable API on `/__mcp`. |
190-
| `devframe connect` | Discover running devframes and proxy their tools — see [MCP adapter](/adapters/mcp#discovery-devframe-connect). |
186+
`<your-app> mcp` starts the MCP server on `stdio`; `<your-app> dev --mcp` serves the agent-consumable API on `/__mcp`; `devframe connect` discovers running devframes and proxies their tools ([MCP adapter](/adapters/mcp#discovery-devframe-connect)). The command table is in the [Node-Side API reference](/references/node-api#mcp-cli-commands).

docs/content/1.guide/16.hub.md

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,7 @@ _Orchestrating multiple devtools (from [A Playground](https://github.com/devfram
1313

1414
## What the hub adds
1515

16-
`DevframeHubContext` adds four subsystems to `DevframeNodeContext`:
17-
18-
| Subsystem | API | Purpose |
19-
|---|---|---|
20-
| `ctx.docks` | `register / update / values / activate` | Dock entries (iframes, launchers, custom-render) and groups; `activate(dockId, params?)` sets the active dock ([Cross-iframe dock activation](#cross-iframe-dock-activation)). |
21-
| `ctx.terminals` | `register / startChildProcess` | Aggregate terminal sessions, streaming output ([Terminals](/plugins/terminals#hub-aggregation)). |
22-
| `ctx.messages` | `add / update / remove / clear` | Server-side toast/notification queue (FIFO, capped at 1000). |
23-
| `ctx.commands` | `register / execute / list` | Hierarchical command palette with keybindings and `when` clauses. |
16+
`DevframeHubContext` adds four subsystems to `DevframeNodeContext`: `ctx.docks` registers dock entries and groups and [activates docks](#cross-iframe-dock-activation); `ctx.terminals` aggregates terminal sessions with streaming output ([Terminals](/plugins/terminals#hub-aggregation)); `ctx.messages` is the server-side toast/notification queue; `ctx.commands` is the hierarchical command palette with keybindings and `when` clauses. Each subsystem's API is in the [Hub API reference](/references/hub-api#hub-subsystems).
2417

2518
Data-driven UI panels are an opt-in [JSON-Render](/guide/json-render) package (a `json-render` dock type).
2619

@@ -69,13 +62,7 @@ It mirrors into the `devframe:docks:active` shared-state slot; the [terminals do
6962

7063
## Process-control launchers
7164

72-
A `type: 'launcher'` dock entry is a one-click action tile. Three optional `launcher` fields make it a live process controller:
73-
74-
| Field | Purpose |
75-
|---|---|
76-
| `command` | Bound command id; out-of-process hub UI providers dispatch via `hub:commands:execute` (register a handler via `ctx.commands`). |
77-
| `terminalSessionId` | Tracked session id; a "view in terminal" action calls `hub:docks:activate` with the terminals dock id and `{ sessionId }`. |
78-
| `digest` | Latest progress line, shown inline; patch via `docks.update()`. |
65+
A `type: 'launcher'` dock entry is a one-click action tile. Three optional `launcher` fields make it a live process controller: `command` binds a command id dispatched via `hub:commands:execute`, `terminalSessionId` links a tracked session for a "view in terminal" action, and `digest` shows the latest progress line inline ([Hub API reference](/references/hub-api#launcher-fields)).
7966

8067
`onLaunch` lets a same-process host framework invoke directly; provide `command`, `onLaunch`, or both.
8168

@@ -173,14 +160,7 @@ export default { skipTrailingSlashRedirect: true }
173160

174161
### Duplicate devframes
175162

176-
When a devframe shares an already-mounted `id`, `duplicationStrategy` decides:
177-
178-
| Strategy | Behavior |
179-
|---|---|
180-
| `'warn'` (default) | Keep the first, drop the later, emit `DF8105`. |
181-
| `'silent'` | Drop the later one without warning. |
182-
| `'throw'` | Throw `DF8105`. |
183-
| `'duplicate'` | Every instance coexists under a disambiguated dock id (`my-tool`, `my-tool-2`, …). |
163+
When a devframe shares an already-mounted `id`, `duplicationStrategy` decides: `'warn'` (the default) keeps the first and drops the later with [`DF8105`](/errors/DF8105), `'silent'` drops it quietly, `'throw'` raises, and `'duplicate'` lets every instance coexist under disambiguated dock ids ([Hub API reference](/references/hub-api#duplication-strategies)).
184164

185165
```ts
186166
defineDevframe({
@@ -222,35 +202,13 @@ Group and members stay independent top-level entries in `devframe:docks`. Activa
222202

223203
#### Known categories
224204

225-
`DEFAULT_CATEGORIES_ORDER` (from `@devframes/hub`, `/node`, `/client`, `/constants`) names the default buckets:
226-
227-
| Category | Weight | Typical use |
228-
|---|---|---|
229-
| `framework` | `-100` | Framework internals. |
230-
| `default` | `0` | Uncategorized. |
231-
| `app` | `100` | App tools. |
232-
| `ui` | `150` | Components, styling. |
233-
| `data` | `250` | State, storage, queries. |
234-
| `web` | `300` | Network, platform, a11y. |
235-
| `performance` | `350` | Profiling, metrics. |
236-
| `advanced` | `400` | Power-user tools. |
237-
| `docs` | `500` | Documentation. |
238-
| `~builtin` | `1000` | Built-in views; always last. |
205+
`DEFAULT_CATEGORIES_ORDER` (from `@devframes/hub`, `/node`, `/client`, `/constants`) names the default buckets, running from `framework` (weight `-100`) through `default`, `app`, `ui`, `data`, `web`, `performance`, `advanced`, and `docs` to `~builtin` (always last). The weight table is in the [Hub API reference](/references/hub-api#dock-categories).
239206

240207
Framework kits can interleave category ids or override weights; an unknown category sorts as `0`.
241208

242-
## The protocol — what the hub UI provider sees
243-
244-
A hub UI provider imports no hub classes; it reads these shared-state keys and RPC methods:
209+
## The hub UI protocol
245210

246-
| Channel | Type | What it carries |
247-
|---|---|---|
248-
| `devframe:docks` shared state | `DevframeDockEntry[]` | Every registered dock entry. |
249-
| `devframe:commands` shared state | `DevframeServerCommandEntry[]` | Serializable command list (handlers stripped). |
250-
| `devframe:user-settings` shared state | `DevframeDocksUserSettings` | Persisted project-scope hub settings. |
251-
| `devframe:docks:active` shared state | `DevframeDocksActiveState` | Most recent [dock activation](#cross-iframe-dock-activation) request. |
252-
| `hub:commands:execute` RPC | `(id, ...args) => unknown` | Server-side command dispatch. |
253-
| `hub:docks:activate` RPC | `({ dockId, params? }) => void` | Switch the active dock. |
211+
A hub UI provider imports no hub classes; it renders from four shared-state slots — `devframe:docks` (every registered dock entry), `devframe:commands` (the serializable command list), `devframe:user-settings` (persisted hub settings), and `devframe:docks:active` (the most recent [dock activation](#cross-iframe-dock-activation) request) — and dispatches through two RPC methods, `hub:commands:execute` and `hub:docks:activate`. Types and payloads are in the [Hub API reference](/references/hub-api#hub-ui-protocol).
254212

255213
Broadcast notifications (`devframe:docks:activate`, `devframe:terminals:updated`, `devframe:messages:updated`) arrive via `rpc.client.register(...)`; the client runtime registers `devframe:docks:activate` for you ([Events Reference](/references/events)).
256214

0 commit comments

Comments
 (0)