devframe 0.1.21 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +40 -18
  2. package/dist/{_shared-iZy45oG3.mjs → _shared-BrKv3CYt.mjs} +5 -5
  3. package/dist/adapters/build.d.mts +5 -5
  4. package/dist/adapters/build.mjs +13 -12
  5. package/dist/adapters/cli.d.mts +4 -4
  6. package/dist/adapters/cli.mjs +5 -5
  7. package/dist/adapters/dev.d.mts +21 -12
  8. package/dist/adapters/dev.mjs +1 -1
  9. package/dist/adapters/embedded.d.mts +5 -5
  10. package/dist/adapters/embedded.mjs +2 -2
  11. package/dist/adapters/mcp.d.mts +3 -3
  12. package/dist/adapters/mcp.mjs +5 -5
  13. package/dist/chunk-e9Ob2GDo.mjs +26 -0
  14. package/dist/client/index.d.mts +8 -5
  15. package/dist/client/index.mjs +12 -12
  16. package/dist/colors-DS7k8ljB.mjs +123 -0
  17. package/dist/{context-BJ4r2SmR.mjs → context-BBi2IQDm.mjs} +19 -37
  18. package/dist/{context-internal-saIAfNVw.d.mts → context-DRa0wGsC.d.mts} +2 -2
  19. package/dist/{dev-CdAy400a.mjs → dev-CewNNE2R.mjs} +24 -28
  20. package/dist/{devtool-CNvLs2_Y.d.mts → devframe-R5Ex5K5L.d.mts} +41 -66
  21. package/dist/{diagnostics-DxPnRoXO.mjs → diagnostics-Cg9ycFIM.mjs} +7 -2
  22. package/dist/hash-CIBte1yS.mjs +263 -0
  23. package/dist/helpers/vite.d.mts +65 -0
  24. package/dist/helpers/vite.mjs +94 -0
  25. package/dist/{human-id-BLoGo_e5.mjs → human-id-adtUWQLr.mjs} +12 -3
  26. package/dist/{index-CuLRIMto.d.mts → index-DB2Ie0Or.d.mts} +2 -3
  27. package/dist/index.d.mts +4 -5
  28. package/dist/index.mjs +2 -5
  29. package/dist/launch-editor-CX_n_0SS.mjs +581 -0
  30. package/dist/node/auth.d.mts +44 -0
  31. package/dist/node/auth.mjs +55 -0
  32. package/dist/node/index.d.mts +13 -55
  33. package/dist/node/index.mjs +6 -62
  34. package/dist/node/internal.d.mts +16 -0
  35. package/dist/node/internal.mjs +50 -0
  36. package/dist/{open-Dede_w9r.mjs → open-B2ah1IKK.mjs} +38 -24
  37. package/dist/recipes/open-helpers.d.mts +4 -9
  38. package/dist/recipes/open-helpers.mjs +7 -12
  39. package/dist/revoke-DIMz1r7-.mjs +35 -0
  40. package/dist/rpc/index.d.mts +3 -3
  41. package/dist/rpc/index.mjs +4 -4
  42. package/dist/rpc/transports/ws-client.d.mts +1 -1
  43. package/dist/rpc/transports/ws-client.mjs +2 -1
  44. package/dist/rpc/transports/ws-server.d.mts +1 -1
  45. package/dist/rpc/transports/ws-server.mjs +2 -1
  46. package/dist/{rpc-INbWfHoX.mjs → rpc-DAzoVCR0.mjs} +5 -4
  47. package/dist/{serialization-DwKi05Pn.mjs → serialization-CwO31axa.mjs} +1 -2
  48. package/dist/{server-CBsxXIH5.mjs → server-DOk4grlJ.mjs} +4 -4
  49. package/dist/{server-BAqOajx_.d.mts → server-DzKz023G.d.mts} +8 -7
  50. package/dist/shared-state-q9-1EOSX.mjs +928 -0
  51. package/dist/{static-dump-D5VH8Iqk.mjs → static-dump-C67bCuse.mjs} +1 -1
  52. package/dist/{context-internal-Dx_NoSv1.mjs → storage-CNvfBGQ5.mjs} +5 -87
  53. package/dist/structured-clone-CD2l4fI3.mjs +221 -0
  54. package/dist/types/index.d.mts +4 -4
  55. package/dist/types/index.mjs +3 -3
  56. package/dist/utils/colors.d.mts +28 -0
  57. package/dist/utils/colors.mjs +2 -0
  58. package/dist/utils/events.d.mts +1 -1
  59. package/dist/utils/hash.d.mts +7 -0
  60. package/dist/utils/hash.mjs +2 -0
  61. package/dist/utils/human-id.d.mts +6 -8
  62. package/dist/utils/human-id.mjs +1 -2
  63. package/dist/utils/launch-editor.d.mts +13 -0
  64. package/dist/utils/launch-editor.mjs +2 -0
  65. package/dist/utils/open.d.mts +16 -0
  66. package/dist/utils/open.mjs +2 -0
  67. package/dist/utils/serve-static.d.mts +40 -0
  68. package/dist/utils/serve-static.mjs +173 -0
  69. package/dist/utils/shared-state.d.mts +1 -1
  70. package/dist/utils/shared-state.mjs +1 -35
  71. package/dist/utils/streaming-channel.d.mts +1 -1
  72. package/dist/utils/structured-clone.d.mts +21 -0
  73. package/dist/utils/structured-clone.mjs +2 -0
  74. package/dist/utils/when.d.mts +33 -50
  75. package/dist/utils/when.mjs +21 -3
  76. package/dist/{ws-client-CjPuPFbA.d.mts → ws-client-Bavoya6-.d.mts} +1 -1
  77. package/dist/{ws-server-C7LnhOHi.d.mts → ws-server-DjvlwLuM.d.mts} +1 -1
  78. package/package.json +38 -18
  79. package/skills/devframe/SKILL.md +64 -39
  80. package/skills/devframe/templates/{counter-devtool.ts → counter-devframe.ts} +4 -4
  81. package/skills/devframe/templates/{spa-devtool.ts → spa-devframe.ts} +5 -5
  82. package/skills/devframe/templates/vite-client.ts +2 -2
  83. package/dist/adapters/vite.d.mts +0 -33
  84. package/dist/adapters/vite.mjs +0 -32
  85. package/dist/internal/index.d.mts +0 -16
  86. package/dist/internal/index.mjs +0 -3
  87. package/dist/utils/state.d.mts +0 -50
  88. package/dist/utils/state.mjs +0 -26
  89. package/dist/{define-Bb4zh-Dc.mjs → define-CW9gLnyG.mjs} +0 -0
  90. package/dist/{host-h3-9jeHcltx.mjs → host-h3-Dz8YnFgu.mjs} +1 -1
  91. /package/dist/{transports-DSV5_5QM.mjs → transports-BnCs4rj9.mjs} +0 -0
  92. /package/dist/{types-C5OVe4AC.d.mts → types-4rdUEi2R.d.mts} +0 -0
@@ -1,50 +1,53 @@
1
1
  ---
2
2
  name: devframe
3
3
  description: >
4
- Use when building one devtool integration with devframe — the
5
- portable, framework-neutral container for a single tool. Covers
6
- DevtoolDefinition, picking the right deployment adapter
4
+ Use when building a devtool with devframe — the
5
+ framework- and build-tool-agnostic foundation for defining a
6
+ devtool once and serving it in many places. Covers
7
+ DevframeDefinition, picking the right deployment adapter
7
8
  (cli / build / spa / vite / embedded / mcp), designing RPC
8
- contracts, exposing an agent-native surface over MCP, and wiring
9
- the author's SPA client. Hub-only concerns (docks, terminals,
10
- commands, the unified messages dock) belong to
11
- `@vitejs/devtools-kit`see the `vite-devtools-kit` skill for
12
- those. Triggers on `devframe` imports, `defineDevtool`,
13
- `createCli`, `createMcpServer`, `connectDevtool`, and on
14
- migrations of existing inspectors (eslint-config-inspector,
15
- unocss-inspector, node-modules-inspector-style tools) to devframe.
9
+ contracts, exposing an agent-native surface over MCP, and
10
+ wiring the author's SPA client. For host-level features (docks,
11
+ terminals, palette, etc.), the devframe can be mounted into a
12
+ host that provides them Vite DevTools is one supported target,
13
+ reached via the `vite` adapter. Triggers on `devframe` imports,
14
+ `defineDevframe`, `createCli`, `createMcpServer`,
15
+ `connectDevframe`, and on migrations of existing inspectors
16
+ (eslint-config-inspector, unocss-inspector,
17
+ node-modules-inspector-style tools) to devframe.
16
18
  ---
17
19
 
18
20
  # devframe skill
19
21
 
20
- **Devframe is the container for one devtool integration, portable across viewers.** A devtool built on devframe is a single `DevtoolDefinition` plus an author-provided SPA — the same definition deploys as a standalone CLI, a static report, an embedded SPA, an MCP server, or as a dock entry inside the Vite DevTools hub via `createPluginFromDevframe`.
22
+ **Devframe is an asset: define your devtool once, serve it anywhere.** A devtool built on devframe is a single `DevframeDefinition` plus an author-provided SPA — the same definition deploys through a set of pluggable adapters (standalone CLI, static report, embedded SPA, MCP server, mounted into a host, etc.). Devframe is framework- and build-tool-agnostic; it has no Vite dependency and makes no UI-framework assumption.
21
23
 
22
- Devframe deliberately stops at the boundary of one tool. Anything that only matters across multiple integrationsdocks, terminals, command palette, cross-tool toastslives in `@vitejs/devtools-kit`, the hub layer. `devframe` must not depend on Vite, any `@vitejs/*` package, or hub-only concepts; it's the lowest-level layer in the monorepo.
24
+ Devframe describes one tool. If you need host-level features (cross-tool palette, integrated terminals, dock aggregation), mount the devframe into a host that provides them [Vite DevTools](https://devtools.vite.dev/) is the canonical example, reached via the `vite` adapter or build your own host adapter. `devframe` itself must not depend on Vite or any `@vitejs/*` package.
23
25
 
24
26
  Full reference: [devfra.me/](https://devfra.me/).
25
27
 
26
28
  ## When to use devframe
27
29
 
28
- All adapter factories share the shape `createXxx(devtoolDef, options?)`.
30
+ All adapter factories share the shape `createXxx(devframeDef, options?)`.
29
31
 
30
32
  | Author goal | Factory | Entry |
31
33
  |-------------|---------|-------|
32
34
  | Standalone CLI for local use | `createCli(def, options?)` | `devframe/adapters/cli` |
33
35
  | Run the dev server programmatically (any CLI framework) | `createDevServer(def, options?)` | `devframe/adapters/dev` |
34
- | Mount a SPA in an existing Vite dev server | `createVitePlugin(def, options?)` | `devframe/adapters/vite` |
35
36
  | Self-contained static deploy with baked data | `createBuild(def, options?)` | `devframe/adapters/build` |
36
- | Integrate into Vite DevTools | `createPluginFromDevframe(def, options?)` | `@vitejs/devtools-kit/node` |
37
+ | Mount into a host (Vite DevTools or any compatible host) | `createPluginFromDevframe(def, options?)` | `@vitejs/devtools-kit/node` |
37
38
  | Register dynamically at runtime | `createEmbedded(def, { ctx })` | `devframe/adapters/embedded` |
38
39
  | Expose to coding agents (MCP) | `createMcpServer(def, options?)` | `devframe/adapters/mcp` *(experimental)* |
39
40
 
40
- The same `DevtoolDefinition` runs under every adapter — pick based on deployment, not on what the tool does.
41
+ The same `DevframeDefinition` runs under every adapter — pick based on deployment, not on what the tool does.
41
42
 
42
- ## Minimum viable devtool
43
+ For Vite-based hosts that don't use the kit (Nuxt, Astro, SolidStart, plain Vite apps), `devframe/helpers/vite` exports `viteDevBridge(def, options?)` — a Vite plugin that mounts the SPA (static mode) or starts the RPC + WS bridge alongside the host's dev server (`devMiddleware: true`). Not an adapter; just a Vite integration helper.
44
+
45
+ ## Minimum viable devframe
43
46
 
44
47
  ```ts
45
- import { defineDevtool, defineRpcFunction } from 'devframe'
48
+ import { defineDevframe, defineRpcFunction } from 'devframe'
46
49
 
47
- export default defineDevtool({
50
+ export default defineDevframe({
48
51
  id: 'my-inspector',
49
52
  name: 'My Inspector',
50
53
  icon: 'ph:magnifying-glass-duotone',
@@ -59,18 +62,18 @@ export default defineDevtool({
59
62
  })
60
63
  ```
61
64
 
62
- `setup(ctx)` registers RPC functions, shared state, diagnostics, and any other devframe-level wiring. It does **not** receive `docks` / `terminals` / `messages` / `commands` those are hub features. When mounted into Vite DevTools via `createPluginFromDevframe(d)`, the kit auto-derives an iframe dock entry from `id` / `name` / `icon` / `basePath`; for richer hub-side behaviour (custom-render, terminals, palette commands) pass `options.setup` to `createPluginFromDevframe`.
65
+ `setup(ctx)` registers RPC functions, shared state, diagnostics, and any other devframe-level wiring. Host adapters can augment `ctx` with extra surfacesfor example, mounting into Vite DevTools via `createPluginFromDevframe(d)` exposes `docks`, `terminals`, `messages`, and `commands` on the augmented context, and the kit auto-derives an iframe dock entry from `id` / `name` / `icon` / `basePath`. For richer host-side behaviour (custom-render, terminals, palette commands) pass `options.setup` to `createPluginFromDevframe`.
63
66
 
64
- See `templates/counter-devtool.ts` for a runnable counter example, `templates/spa-devtool.ts` for an SPA-ready shape, and `templates/vite-client.ts` for the author's client entry.
67
+ See `templates/counter-devframe.ts` for a runnable counter example, `templates/spa-devframe.ts` for an SPA-ready shape, and `templates/vite-client.ts` for the author's client entry.
65
68
 
66
69
  ## Namespacing
67
70
 
68
- **Always prefix** RPC names, dock IDs, command IDs, shared-state keys, and agent tool IDs with the devtool `id`:
71
+ **Always prefix** RPC names, dock IDs, command IDs, shared-state keys, and agent tool IDs with the devframe `id`:
69
72
 
70
73
  ```ts
71
74
  'my-inspector:get-modules' // ✓
72
75
  'my-inspector:state' // ✓
73
- 'get-modules' // ✗ — may collide with other devtools sharing the host
76
+ 'get-modules' // ✗ — may collide with other devframes sharing the host
74
77
  ```
75
78
 
76
79
  ## DevToolsNodeContext at a glance
@@ -86,7 +89,7 @@ See `templates/counter-devtool.ts` for a runnable counter example, `templates/sp
86
89
  | `ctx.host` | Runtime abstraction — `mountStatic`, `resolveOrigin`, `getStorageDir` |
87
90
  | `ctx.mode` | `'dev'` or `'build'` — gate setup work per runtime |
88
91
 
89
- > Hub-only hosts (`ctx.docks`, `ctx.terminals`, `ctx.messages`, `ctx.commands`) only exist when the devtool is mounted into Vite DevTools via `createPluginFromDevframe`. See the [`vite-devtools-kit` skill](../../skills/vite-devtools-kit) for those.
92
+ > Hosts can augment `ctx` with additional surfaces (e.g. Vite DevTools' `docks`, `terminals`, `messages`, `commands`, `createJsonRenderer`). Consult the host's docs for Vite DevTools, see the [`vite-devtools-kit` skill](../../skills/vite-devtools-kit).
90
93
 
91
94
  ## RPC contracts
92
95
 
@@ -238,9 +241,9 @@ Readable.fromWeb(reader.readable).pipe(targetNodeWritable)
238
241
 
239
242
  For chat-style UIs that combine both: keep the **conversation log** in shared state (survives reconnects), and use a streaming channel for **active responses**. The action that starts a response appends a placeholder to shared state; on producer close, commit the joined content back to shared state. Working example: [`devframe/examples/devframe-streaming-chat`](https://github.com/vitejs/devtools/tree/main/devframe/examples/devframe-streaming-chat).
240
243
 
241
- ## Mounting into Vite DevTools
244
+ ## Mounting into a host (Vite DevTools example)
242
245
 
243
- A portable devframe definition is dropped into the Vite DevTools hub via `createPluginFromDevframe`:
246
+ A portable devframe can be mounted into any host that ships an adapter for it. Vite DevTools is one supported target — `createPluginFromDevframe` is the Vite-DevTools-specific bridge; other hosts can implement equivalent factories. Example:
244
247
 
245
248
  ```ts
246
249
  // vite.config.ts
@@ -263,11 +266,11 @@ export default {
263
266
  }
264
267
  ```
265
268
 
266
- The kit auto-derives an iframe dock entry from `id` / `name` / `icon` / `basePath`. For dock variations (custom-render, launcher, action, json-render), terminals, palette commands, and toasts, use the `options.setup` hook — those APIs live on the kit-augmented context, not on the devframe-level `setup`. See the [`vite-devtools-kit` skill](../../skills/vite-devtools-kit) for the hub-side reference.
269
+ The kit auto-derives an iframe dock entry from `id` / `name` / `icon` / `basePath`. For dock variations (custom-render, launcher, action, json-render), terminals, palette commands, and toasts, use the `options.setup` hook — those APIs live on the host-augmented context, not on the devframe-level `setup`. See the [`vite-devtools-kit` skill](../../skills/vite-devtools-kit) for the Vite-DevTools-specific reference.
267
270
 
268
271
  ## When clauses
269
272
 
270
- Gate kit-side dock / command visibility with VS Code-style expressions evaluated by the external `whenexpr` package. The runtime + types ship from `devframe/utils/when`, but the consumers (`when` field on docks and commands) live in the kit:
273
+ Gate kit-side dock / command visibility with VS Code-style expressions. The runtime + types ship bundled from `devframe/utils/when` no separate install. The consumers (`when` field on docks and commands) live in the kit:
271
274
 
272
275
  ```ts
273
276
  when: 'clientType == embedded'
@@ -275,7 +278,7 @@ when: 'dockOpen && !paletteOpen'
275
278
  when: 'my-inspector.ready && count >= 10'
276
279
  ```
277
280
 
278
- Built-in context: `clientType` (`'embedded' | 'standalone'`), `dockOpen`, `paletteOpen`, `dockSelectedId`. Plugins can add namespaced keys (`.` or `:` separators). Both the types (`WhenExpression<Ctx, S>`) and runtime (`evaluateWhen`, `resolveContextValue`) are re-exported from `devframe/utils/when`.
281
+ Built-in context: `clientType` (`'embedded' | 'standalone'`), `dockOpen`, `paletteOpen`, `dockSelectedId`. Plugins can add namespaced keys (`.` or `:` separators). Both the types (`WhenExpression<Ctx, S>`) and runtime (`evaluateWhen`, `resolveContextValue`) come from `devframe/utils/when`.
279
282
 
280
283
  ## Agent-native surface (experimental)
281
284
 
@@ -319,25 +322,25 @@ Expose via MCP:
319
322
  ```ts
320
323
  import { createMcpServer } from 'devframe/adapters/mcp'
321
324
 
322
- await createMcpServer(devtool, { transport: 'stdio' })
325
+ await createMcpServer(devframe, { transport: 'stdio' })
323
326
  ```
324
327
 
325
- `@modelcontextprotocol/sdk` is a peer dependency. The CLI adapter also exposes `my-devtool mcp` — route host logs to stderr (stdout is the MCP transport). Safety classifications (`'read' | 'action' | 'destructive'`) drive MCP hint annotations that agent clients use to prompt for confirmation.
328
+ `@modelcontextprotocol/sdk` is a peer dependency. The CLI adapter also exposes `my-devframe mcp` — route host logs to stderr (stdout is the MCP transport). Safety classifications (`'read' | 'action' | 'destructive'`) drive MCP hint annotations that agent clients use to prompt for confirmation.
326
329
 
327
330
  ## Author SPA
328
331
 
329
332
  Authors bring their own SPA (any framework or plain HTML). Client entry:
330
333
 
331
334
  ```ts
332
- import { connectDevtool } from 'devframe/client'
335
+ import { connectDevframe } from 'devframe/client'
333
336
 
334
- const rpc = await connectDevtool()
337
+ const rpc = await connectDevframe()
335
338
  // await rpc.ensureTrusted() // WS mode only — blocks until server accepts
336
339
 
337
340
  const data = await rpc.call('my-inspector:get-stats', { limit: 10 })
338
341
  ```
339
342
 
340
- `connectDevtool` auto-detects the backend via `/.devtools/.connection.json`:
343
+ `connectDevframe` auto-detects the backend via `/.devtools/.connection.json`:
341
344
 
342
345
  - **websocket** (dev mode) — full read/write, requires auth handshake. Listen for token updates on the `vite-devtools-auth` BroadcastChannel.
343
346
  - **static** (build / spa output) — read-only, resolves calls from the baked RPC dump.
@@ -366,7 +369,7 @@ At runtime, static clients look up the argument hash in the dump; misses resolve
366
369
 
367
370
  ## CLI adapter subcommands
368
371
 
369
- `createCli(devtool).parse()` gives the tool four subcommands out of the box:
372
+ `createCli(devframe).parse()` gives the tool four subcommands out of the box:
370
373
 
371
374
  | Subcommand | Action |
372
375
  |------------|--------|
@@ -377,27 +380,49 @@ At runtime, static clients look up the argument hash in the dump; misses resolve
377
380
 
378
381
  **Bring your own CLI framework?** `createCli` is just a cac wrapper around three peer factories — `createDevServer` (`devframe/adapters/dev`), `createBuild` (`devframe/adapters/build`), and `createMcpServer` (`devframe/adapters/mcp`). Use them directly with commander/yargs/oclif when `createCli`'s baked-in command structure doesn't fit. `createDevServer` returns a `StartedServer` handle (`origin`, `port`, `app`, `wss`, `close()`) so you can wire SIGINT / hot-reload teardown into the surrounding program. `parseCliFlags(schema, raw)` and `defineCliFlags(...)` (both from `devframe/adapters/cli`) validate an arbitrary flag bag against a `CliFlagsSchema` — typed flags aren't tied to cac.
379
382
 
383
+ ## Bundled utilities
384
+
385
+ Devframe re-exports a curated set of helpers under `devframe/utils/*`. They are bundled — never add the underlying packages to a devtool's own `package.json`:
386
+
387
+ | Import | Wraps | Use for |
388
+ |--------|-------|---------|
389
+ | `colors` from `devframe/utils/colors` | `ansis` | Terminal ANSI colors (`c.red`, `c.green`, tagged templates) |
390
+ | `open` from `devframe/utils/open` | `open` | Open URLs / files in the OS default handler |
391
+ | `launchEditor` from `devframe/utils/launch-editor` | `launch-editor` | Open `file:line:column` in the user's editor (optional `editor` arg) |
392
+ | `hash` from `devframe/utils/hash` | `ohash` | Stable structural hash — cache keys, dedup |
393
+ | `structuredClone{Serialize,Deserialize,Stringify,Parse}` from `devframe/utils/structured-clone` | `structured-clone-es` | JSON-safe round-trip of `Map` / `Set` / `Date` / `BigInt` / cycles |
394
+ | `humanId` from `devframe/utils/human-id` | `human-id` | Human-readable IDs (`bright-orange-tiger`) |
395
+ | `nanoid` from `devframe/utils/nanoid` | (vendored) | URL-safe random IDs |
396
+ | `promiseWithResolver` from `devframe/utils/promise` | — | Externally-controlled `Promise` |
397
+ | `createEventEmitter` from `devframe/utils/events` | — | Typed event bus |
398
+ | `createSharedState` from `devframe/utils/shared-state` | (immer internal) | Immutable state container (see `ctx.rpc.sharedState`) |
399
+ | `createStreamSink` / `createStreamReader` from `devframe/utils/streaming-channel` | — | Low-level streaming primitives |
400
+ | `evaluateWhen` / `WhenExpression` from `devframe/utils/when` | `whenexpr` | When-clause expressions |
401
+
402
+ For "open file in editor" + "reveal in finder", prefer the prebuilt `openHelpers` RPC recipe — it wires the two utilities into named RPC functions ready to register.
403
+
380
404
  ## Testing
381
405
 
382
406
  - Unit-test host classes with fake contexts.
383
- - Run `templates/counter-devtool.ts` under each adapter for integration coverage.
407
+ - Run `templates/counter-devframe.ts` under each adapter for integration coverage.
384
408
  - Snapshot the build-static RPC dump (`<outDir>/.devtools/.rpc-dump/index.json`) to catch accidental drift in `static` function outputs.
385
409
 
386
410
  ## Further reading
387
411
 
388
412
  Devframe-level pages (one-tool, portable surface):
389
413
 
390
- - [Devtool Definition](https://devfra.me/devtool-definition) — fields, runtime flags, multi-adapter wiring
414
+ - [Devframe Definition](https://devfra.me/devframe-definition) — fields, runtime flags, multi-adapter wiring
391
415
  - [Adapters](https://devfra.me/adapters) — full reference for all deployment adapters
392
416
  - [RPC](https://devfra.me/rpc) — types, schema, broadcasts, dumps
393
417
  - [Shared State](https://devfra.me/shared-state) — patches, events, client-side mutation
394
418
  - [Streaming](https://devfra.me/streaming) — chunked feeds, uploads, replay, Web/Node Streams interop
395
419
  - [When Clauses](https://devfra.me/when-clauses) — syntax, context, type-safe wrappers
396
420
  - [Structured Diagnostics](https://devfra.me/diagnostics) — coded errors via `ctx.diagnostics`, register custom codes
421
+ - [Utilities](https://devfra.me/utilities) — bundled `devframe/utils/*` helpers (colors, hash, launchEditor, structured-clone, …)
397
422
  - [Client](https://devfra.me/client) — auth handshake, modes, discovery
398
423
  - [Agent-Native](https://devfra.me/agent-native) — agent field, tools/resources, MCP + Claude Desktop
399
424
 
400
- Hub-only surfaces (Vite DevTools Kit only available when mounted into the hub):
425
+ Host-specific extras (when mounting into Vite DevTools — other hosts have their own equivalents):
401
426
 
402
427
  - [Vite DevTools Kit overview](https://devtools.vite.dev/kit/)
403
428
  - [Dock System](https://devtools.vite.dev/kit/dock-system) — every entry type + remote docks
@@ -1,11 +1,11 @@
1
- // Smallest possible devtool. The dock entry is auto-derived from
1
+ // Smallest possible devframe. The dock entry is auto-derived from
2
2
  // `id` / `name` / `icon` when this definition is mounted into Vite
3
- // DevTools via `createPluginFromDevframe(devtool)`.
4
- import { defineDevtool, defineRpcFunction } from 'devframe'
3
+ // DevTools via `createPluginFromDevframe(devframe)`.
4
+ import { defineDevframe, defineRpcFunction } from 'devframe'
5
5
 
6
6
  let counter = 0
7
7
 
8
- export default defineDevtool({
8
+ export default defineDevframe({
9
9
  id: 'counter',
10
10
  name: 'Counter',
11
11
  icon: 'ph:counter-duotone',
@@ -1,10 +1,10 @@
1
- // Devtool with setupBrowser + SPA query-loader — deployable as a static site.
2
- // When mounted into Vite DevTools via `createPluginFromDevframe`, the kit
3
- // auto-derives an iframe dock from `id` / `name` / `icon`.
4
- import { defineDevtool, defineRpcFunction } from 'devframe'
1
+ // Devframe with setupBrowser + SPA query-loader — deployable as a static site.
2
+ // Host adapters (e.g. the `vite` adapter for Vite DevTools) auto-derive their
3
+ // mount entry from `id` / `name` / `icon`.
4
+ import { defineDevframe, defineRpcFunction } from 'devframe'
5
5
  import * as v from 'valibot'
6
6
 
7
- export default defineDevtool({
7
+ export default defineDevframe({
8
8
  id: 'my-inspector',
9
9
  name: 'My Inspector',
10
10
  icon: 'ph:magnifying-glass-duotone',
@@ -1,8 +1,8 @@
1
1
  // Minimum SPA client that talks to a devframe-hosted RPC.
2
- import { connectDevtool } from 'devframe/client'
2
+ import { connectDevframe } from 'devframe/client'
3
3
 
4
4
  async function main() {
5
- const rpc = await connectDevtool()
5
+ const rpc = await connectDevframe()
6
6
  // The method names below are just examples — replace with your own.
7
7
  const data = await rpc.call('my-inspector:getStats' as any)
8
8
  document.getElementById('root')!.textContent = JSON.stringify(data)
@@ -1,33 +0,0 @@
1
- import { r as DevtoolDefinition } from "../devtool-CNvLs2_Y.mjs";
2
-
3
- //#region src/adapters/vite.d.ts
4
- interface CreateVitePluginOptions {
5
- /**
6
- * Mount base. Defaults to `def.basePath ?? '/__<id>/'` for this hosted
7
- * adapter — the devtool shares the origin with the host Vite app.
8
- */
9
- base?: string;
10
- }
11
- interface DevframeVitePlugin {
12
- name: string;
13
- apply: 'serve';
14
- configureServer: (server: {
15
- middlewares: {
16
- use: (path: string, handler: any) => void;
17
- };
18
- }) => void;
19
- }
20
- /**
21
- * Plain Vite plugin — mounts a devframe devtool's SPA into a user's
22
- * Vite dev server at `options.base` (default: `def.basePath ?? '/__<id>/'`).
23
- * Use this for tools that want the Vite dev experience without
24
- * pulling the full Vite DevTools Kit.
25
- *
26
- * Note: this does not yet spin up the RPC WS server — for the full
27
- * RPC path, use `createPluginFromDevframe` from
28
- * `@vitejs/devtools-kit/node` alongside `@vitejs/devtools`, or the
29
- * standalone `createCli`.
30
- */
31
- declare function createVitePlugin(d: DevtoolDefinition, options?: CreateVitePluginOptions): DevframeVitePlugin;
32
- //#endregion
33
- export { CreateVitePluginOptions, DevframeVitePlugin, createVitePlugin };
@@ -1,32 +0,0 @@
1
- import { n as resolveBasePath } from "../_shared-iZy45oG3.mjs";
2
- import { resolve } from "pathe";
3
- import sirv from "sirv";
4
- //#region src/adapters/vite.ts
5
- /**
6
- * Plain Vite plugin — mounts a devframe devtool's SPA into a user's
7
- * Vite dev server at `options.base` (default: `def.basePath ?? '/__<id>/'`).
8
- * Use this for tools that want the Vite dev experience without
9
- * pulling the full Vite DevTools Kit.
10
- *
11
- * Note: this does not yet spin up the RPC WS server — for the full
12
- * RPC path, use `createPluginFromDevframe` from
13
- * `@vitejs/devtools-kit/node` alongside `@vitejs/devtools`, or the
14
- * standalone `createCli`.
15
- */
16
- function createVitePlugin(d, options = {}) {
17
- const base = options.base ?? resolveBasePath(d, "hosted");
18
- const distDir = d.cli?.distDir;
19
- return {
20
- name: `devframe:${d.id}`,
21
- apply: "serve",
22
- configureServer(server) {
23
- if (!distDir) return;
24
- server.middlewares.use(base, sirv(resolve(distDir), {
25
- dev: true,
26
- single: true
27
- }));
28
- }
29
- };
30
- }
31
- //#endregion
32
- export { createVitePlugin };
@@ -1,16 +0,0 @@
1
- import { i as DevtoolDeploymentKind, r as DevtoolDefinition } from "../devtool-CNvLs2_Y.mjs";
2
- import { a as internalContextMap, i as getInternalContext, n as InternalAnonymousAuthStorage, r as RemoteTokenRecord, t as DevToolsInternalContext } from "../context-internal-saIAfNVw.mjs";
3
-
4
- //#region src/adapters/_shared.d.ts
5
- /**
6
- * Resolve the mount base path for a devtool's SPA. Hosted adapters
7
- * (`vite`, `kit`, `embedded`) default to `/__<id>/` so they don't
8
- * collide with the host app; standalone adapters (`cli`, `spa`,
9
- * `build`) default to `/` because they own the origin.
10
- *
11
- * The devtool author can override with `basePath` on the definition.
12
- */
13
- declare function resolveBasePath(def: DevtoolDefinition, kind: DevtoolDeploymentKind): string;
14
- declare function normalizeBasePath(base: string): string;
15
- //#endregion
16
- export { type DevToolsInternalContext, type InternalAnonymousAuthStorage, type RemoteTokenRecord, getInternalContext, internalContextMap, normalizeBasePath, resolveBasePath };
@@ -1,3 +0,0 @@
1
- import { n as internalContextMap, t as getInternalContext } from "../context-internal-Dx_NoSv1.mjs";
2
- import { n as resolveBasePath, t as normalizeBasePath } from "../_shared-iZy45oG3.mjs";
3
- export { getInternalContext, internalContextMap, normalizeBasePath, resolveBasePath };
@@ -1,50 +0,0 @@
1
- import { ct as EventEmitter } from "../devtool-CNvLs2_Y.mjs";
2
- import { Objectish, Patch } from "immer";
3
-
4
- //#region src/utils/state.d.ts
5
- type ImmutablePrimitive = undefined | null | boolean | string | number | Function;
6
- type Immutable<T> = T extends ImmutablePrimitive ? T : T extends Array<infer U> ? ImmutableArray<U> : T extends Map<infer K, infer V> ? ImmutableMap<K, V> : T extends Set<infer M> ? ImmutableSet<M> : ImmutableObject<T>;
7
- type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
8
- type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
9
- type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
10
- type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
11
- /**
12
- * State host that is immutable by default with explicit mutate.
13
- */
14
- interface SharedState<T> {
15
- /**
16
- * Get the current state. Immutable.
17
- */
18
- get: () => Immutable<T>;
19
- /**
20
- * Subscribe to state changes.
21
- */
22
- on: EventEmitter<SharedStateEvents<T>>['on'];
23
- /**
24
- * Mutate the state.
25
- */
26
- mutate: (fn: (state: T) => void) => void;
27
- /**
28
- * Apply patches to the state.
29
- */
30
- patch: (patches: Patch[]) => void;
31
- }
32
- interface SharedStateEvents<T> {
33
- updated: (state: T) => void;
34
- patches: (patches: Patch[]) => void;
35
- }
36
- interface SharedStateOptions<T> {
37
- /**
38
- * Initial state.
39
- */
40
- initialState: T;
41
- /**
42
- * Enable patches.
43
- *
44
- * @default false
45
- */
46
- enablePatches?: boolean;
47
- }
48
- declare function createSharedState<T extends Objectish>(options: SharedStateOptions<T>): SharedState<T>;
49
- //#endregion
50
- export { Immutable, ImmutableArray, ImmutableMap, ImmutableObject, ImmutableSet, SharedState, SharedStateEvents, SharedStateOptions, createSharedState };
@@ -1,26 +0,0 @@
1
- import { createEventEmitter } from "./events.mjs";
2
- import { applyPatches, produce, produceWithPatches } from "immer";
3
- //#region src/utils/state.ts
4
- function createSharedState(options) {
5
- const { enablePatches = false } = options;
6
- const events = createEventEmitter();
7
- let state = options.initialState;
8
- return {
9
- on: events.on,
10
- get: () => state,
11
- patch: (patches) => {
12
- state = applyPatches(state, patches);
13
- events.emit("updated", state);
14
- },
15
- mutate: (fn) => {
16
- if (enablePatches) {
17
- const [newState, patches] = produceWithPatches(state, fn);
18
- state = newState;
19
- events.emit("patches", patches);
20
- } else state = produce(state, fn);
21
- events.emit("updated", state);
22
- }
23
- };
24
- }
25
- //#endregion
26
- export { createSharedState };
@@ -1,6 +1,6 @@
1
- import { join } from "pathe";
2
1
  import { homedir } from "node:os";
3
2
  import process from "node:process";
3
+ import { join } from "pathe";
4
4
  //#region src/node/host-h3.ts
5
5
  /**
6
6
  * h3-backed {@link DevToolsHost} — used by the standalone CLI adapter.