devframe 0.1.20 → 0.1.22
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.
- package/README.md +41 -18
- package/dist/{_shared-S-Ujqz_L.mjs → _shared-DcJX9-Az.mjs} +4 -4
- package/dist/adapters/build.d.mts +7 -7
- package/dist/adapters/build.mjs +15 -14
- package/dist/adapters/cli.d.mts +2 -2
- package/dist/adapters/cli.mjs +5 -5
- package/dist/adapters/dev.d.mts +18 -9
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +6 -6
- package/dist/adapters/embedded.mjs +3 -3
- package/dist/adapters/mcp.d.mts +3 -3
- package/dist/adapters/mcp.mjs +6 -5
- package/dist/adapters/vite.d.mts +46 -12
- package/dist/adapters/vite.mjs +81 -17
- package/dist/chunk-e9Ob2GDo.mjs +26 -0
- package/dist/client/index.d.mts +19 -144
- package/dist/client/index.mjs +20 -20
- package/dist/colors-Bl4W18Mh.mjs +123 -0
- package/dist/constants.d.mts +12 -15
- package/dist/constants.mjs +12 -29
- package/dist/context-DBd794Rn.d.mts +51 -0
- package/dist/context-DUibxhrR.mjs +1034 -0
- package/dist/{dev-B8i_CBlQ.mjs → dev-BGpTpYiR.mjs} +20 -21
- package/dist/{devtool-Bm6zZAw5.d.mts → devframe-DulcIxwu.d.mts} +59 -569
- package/dist/diagnostics-BFhNNmST.mjs +56 -0
- package/dist/hash-BHZbo80D.mjs +126 -0
- package/dist/{human-id-CHS0s28X.mjs → human-id-adtUWQLr.mjs} +12 -4
- package/dist/{index-BCo03GEF.d.mts → index-DB2Ie0Or.d.mts} +2 -3
- package/dist/index.d.mts +4 -6
- package/dist/index.mjs +2 -8
- package/dist/launch-editor-KA_21J1T.mjs +581 -0
- package/dist/node/auth.d.mts +44 -0
- package/dist/node/auth.mjs +55 -0
- package/dist/node/index.d.mts +14 -187
- package/dist/node/index.mjs +6 -61
- package/dist/node/internal.d.mts +16 -0
- package/dist/node/internal.mjs +50 -0
- package/dist/{open-BtOOEldu.mjs → open-DmFp0qZA.mjs} +15 -6
- package/dist/recipes/open-helpers.d.mts +4 -9
- package/dist/recipes/open-helpers.mjs +7 -12
- package/dist/revoke-DIMz1r7-.mjs +35 -0
- package/dist/rpc/index.d.mts +3 -3
- package/dist/rpc/index.mjs +4 -4
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +2 -1
- package/dist/rpc/transports/ws-server.d.mts +1 -1
- package/dist/rpc/transports/ws-server.mjs +2 -1
- package/dist/{rpc-INbWfHoX.mjs → rpc-CkZuoz-m.mjs} +3 -2
- package/dist/{serialization-DwKi05Pn.mjs → serialization-CwO31axa.mjs} +1 -2
- package/dist/{server-qRRM8t3v.mjs → server-ma8-ZVyX.mjs} +1 -1
- package/dist/{server-DksyT-um.d.mts → server-zKEDxgqD.d.mts} +4 -3
- package/dist/shared-state-DCDs0e7y.mjs +928 -0
- package/dist/{static-dump-C1aVSwxY.mjs → static-dump-D7AvjrgL.mjs} +1 -1
- package/dist/storage-CNC38eU-.mjs +117 -0
- package/dist/structured-clone-DcDc2Dds.mjs +221 -0
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +11 -2
- package/dist/utils/colors.d.mts +28 -0
- package/dist/utils/colors.mjs +2 -0
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/hash.d.mts +7 -0
- package/dist/utils/hash.mjs +2 -0
- package/dist/utils/human-id.d.mts +6 -8
- package/dist/utils/human-id.mjs +1 -2
- package/dist/utils/launch-editor.d.mts +13 -0
- package/dist/utils/launch-editor.mjs +2 -0
- package/dist/utils/open.d.mts +16 -0
- package/dist/utils/open.mjs +2 -0
- package/dist/utils/serve-static.d.mts +30 -0
- package/dist/utils/serve-static.mjs +152 -0
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -35
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/utils/structured-clone.d.mts +21 -0
- package/dist/utils/structured-clone.mjs +2 -0
- package/dist/utils/when.d.mts +384 -2
- package/dist/utils/when.mjs +20 -2
- package/dist/{ws-client-DQySVfF_.d.mts → ws-client-Bavoya6-.d.mts} +1 -1
- package/dist/{ws-server-VQqESKAs.d.mts → ws-server-DjvlwLuM.d.mts} +1 -1
- package/package.json +23 -13
- package/skills/devframe/SKILL.md +93 -117
- package/skills/devframe/templates/{counter-devtool.ts → counter-devframe.ts} +5 -10
- package/skills/devframe/templates/{spa-devtool.ts → spa-devframe.ts} +5 -10
- package/skills/devframe/templates/vite-client.ts +2 -2
- package/dist/adapters/kit.d.mts +0 -23
- package/dist/adapters/kit.mjs +0 -16
- package/dist/context-BfvbAyGk.mjs +0 -7215
- package/dist/main-DpINGndA.mjs +0 -601
- package/dist/utils/state.d.mts +0 -50
- package/dist/utils/state.mjs +0 -26
- package/dist/when-aBBXAEh5.d.mts +0 -401
- package/dist/{define-Bb4zh-Dc.mjs → define-CW9gLnyG.mjs} +0 -0
- package/dist/{host-h3-BMvrFzIJ.mjs → host-h3-Dz8YnFgu.mjs} +2 -2
- /package/dist/{transports-BPUzHhI2.mjs → transports-BnCs4rj9.mjs} +0 -0
- /package/dist/{types-ag029cAe.d.mts → types-4rdUEi2R.d.mts} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devframe",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.22",
|
|
5
5
|
"description": "Framework for building generic DevTools",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -24,12 +24,13 @@
|
|
|
24
24
|
"./adapters/cli": "./dist/adapters/cli.mjs",
|
|
25
25
|
"./adapters/dev": "./dist/adapters/dev.mjs",
|
|
26
26
|
"./adapters/embedded": "./dist/adapters/embedded.mjs",
|
|
27
|
-
"./adapters/kit": "./dist/adapters/kit.mjs",
|
|
28
27
|
"./adapters/mcp": "./dist/adapters/mcp.mjs",
|
|
29
28
|
"./adapters/vite": "./dist/adapters/vite.mjs",
|
|
30
29
|
"./client": "./dist/client/index.mjs",
|
|
31
30
|
"./constants": "./dist/constants.mjs",
|
|
32
31
|
"./node": "./dist/node/index.mjs",
|
|
32
|
+
"./node/auth": "./dist/node/auth.mjs",
|
|
33
|
+
"./node/internal": "./dist/node/internal.mjs",
|
|
33
34
|
"./recipes/open-helpers": "./dist/recipes/open-helpers.mjs",
|
|
34
35
|
"./rpc": "./dist/rpc/index.mjs",
|
|
35
36
|
"./rpc/client": "./dist/rpc/client.mjs",
|
|
@@ -37,13 +38,18 @@
|
|
|
37
38
|
"./rpc/transports/ws-client": "./dist/rpc/transports/ws-client.mjs",
|
|
38
39
|
"./rpc/transports/ws-server": "./dist/rpc/transports/ws-server.mjs",
|
|
39
40
|
"./types": "./dist/types/index.mjs",
|
|
41
|
+
"./utils/colors": "./dist/utils/colors.mjs",
|
|
40
42
|
"./utils/events": "./dist/utils/events.mjs",
|
|
43
|
+
"./utils/hash": "./dist/utils/hash.mjs",
|
|
41
44
|
"./utils/human-id": "./dist/utils/human-id.mjs",
|
|
45
|
+
"./utils/launch-editor": "./dist/utils/launch-editor.mjs",
|
|
42
46
|
"./utils/nanoid": "./dist/utils/nanoid.mjs",
|
|
47
|
+
"./utils/open": "./dist/utils/open.mjs",
|
|
43
48
|
"./utils/promise": "./dist/utils/promise.mjs",
|
|
49
|
+
"./utils/serve-static": "./dist/utils/serve-static.mjs",
|
|
44
50
|
"./utils/shared-state": "./dist/utils/shared-state.mjs",
|
|
45
|
-
"./utils/state": "./dist/utils/state.mjs",
|
|
46
51
|
"./utils/streaming-channel": "./dist/utils/streaming-channel.mjs",
|
|
52
|
+
"./utils/structured-clone": "./dist/utils/structured-clone.mjs",
|
|
47
53
|
"./utils/when": "./dist/utils/when.mjs",
|
|
48
54
|
"./package.json": "./package.json"
|
|
49
55
|
},
|
|
@@ -62,46 +68,50 @@
|
|
|
62
68
|
},
|
|
63
69
|
"dependencies": {
|
|
64
70
|
"@valibot/to-json-schema": "^1.7.0",
|
|
65
|
-
"ansis": "^4.2.0",
|
|
66
71
|
"birpc": "^4.0.0",
|
|
67
72
|
"cac": "^7.0.0",
|
|
68
73
|
"h3": "^1.15.11",
|
|
69
|
-
"immer": "^11.1.7",
|
|
70
|
-
"launch-editor": "^2.13.2",
|
|
71
74
|
"logs-sdk": "^0.0.6",
|
|
72
|
-
"
|
|
75
|
+
"mrmime": "^2.0.1",
|
|
73
76
|
"pathe": "^2.0.3",
|
|
74
|
-
"sirv": "^3.0.2",
|
|
75
|
-
"structured-clone-es": "^2.0.0",
|
|
76
77
|
"valibot": "^1.4.0",
|
|
77
78
|
"ws": "^8.20.0"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
82
|
+
"ansis": "^4.2.0",
|
|
83
|
+
"immer": "^11.1.8",
|
|
81
84
|
"launch-editor": "^2.13.2",
|
|
82
|
-
"
|
|
85
|
+
"ohash": "^2.0.11",
|
|
86
|
+
"open": "^11.0.0",
|
|
87
|
+
"structured-clone-es": "^2.0.0",
|
|
88
|
+
"tsdown": "^0.22.0",
|
|
83
89
|
"whenexpr": "^0.1.2"
|
|
84
90
|
},
|
|
85
91
|
"inlinedDependencies": {
|
|
86
|
-
"
|
|
92
|
+
"ansis": "4.2.0",
|
|
87
93
|
"bundle-name": "4.1.0",
|
|
88
94
|
"default-browser": "5.4.0",
|
|
89
95
|
"default-browser-id": "5.0.1",
|
|
90
96
|
"define-lazy-prop": "3.0.0",
|
|
91
97
|
"get-port-please": "3.2.0",
|
|
92
98
|
"human-id": "4.1.3",
|
|
99
|
+
"immer": "11.1.8",
|
|
93
100
|
"is-docker": "3.0.0",
|
|
94
101
|
"is-in-ssh": "1.0.0",
|
|
95
102
|
"is-inside-container": "1.0.0",
|
|
96
103
|
"is-wsl": "3.1.0",
|
|
97
|
-
"
|
|
104
|
+
"launch-editor": "2.13.2",
|
|
98
105
|
"obug": "2.1.1",
|
|
106
|
+
"ohash": "2.0.11",
|
|
99
107
|
"open": "11.0.0",
|
|
100
108
|
"p-limit": "7.3.0",
|
|
101
109
|
"perfect-debounce": "2.1.0",
|
|
110
|
+
"picocolors": "1.1.1",
|
|
102
111
|
"powershell-utils": "0.1.0",
|
|
103
112
|
"run-applescript": "7.1.0",
|
|
104
|
-
"
|
|
113
|
+
"shell-quote": "1.8.3",
|
|
114
|
+
"structured-clone-es": "2.0.0",
|
|
105
115
|
"ua-parser-modern": "0.1.1",
|
|
106
116
|
"whenexpr": "0.1.2",
|
|
107
117
|
"wsl-utils": "0.3.1",
|
package/skills/devframe/SKILL.md
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devframe
|
|
3
3
|
description: >
|
|
4
|
-
Use when building
|
|
5
|
-
|
|
6
|
-
picking the right adapter
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
author's SPA client.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
Use when building one devtool integration with devframe — the
|
|
5
|
+
portable, framework-neutral container for a single tool. Covers
|
|
6
|
+
DevframeDefinition, picking the right deployment adapter
|
|
7
|
+
(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, `defineDevframe`,
|
|
13
|
+
`createCli`, `createMcpServer`, `connectDevframe`, and on
|
|
14
|
+
migrations of existing inspectors (eslint-config-inspector,
|
|
15
|
+
unocss-inspector, node-modules-inspector-style tools) to devframe.
|
|
13
16
|
---
|
|
14
17
|
|
|
15
18
|
# devframe skill
|
|
16
19
|
|
|
17
|
-
A devtool built on devframe is a
|
|
20
|
+
**Devframe is the container for one devtool integration, portable across viewers.** A devtool built on devframe is a single `DevframeDefinition` 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`.
|
|
21
|
+
|
|
22
|
+
Devframe deliberately stops at the boundary of one tool. Anything that only matters across multiple integrations — docks, terminals, command palette, cross-tool toasts — lives 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.
|
|
18
23
|
|
|
19
24
|
Full reference: [devfra.me/](https://devfra.me/).
|
|
20
25
|
|
|
21
26
|
## When to use devframe
|
|
22
27
|
|
|
23
|
-
All adapter factories share the shape `createXxx(
|
|
28
|
+
All adapter factories share the shape `createXxx(devframeDef, options?)`.
|
|
24
29
|
|
|
25
30
|
| Author goal | Factory | Entry |
|
|
26
31
|
|-------------|---------|-------|
|
|
@@ -28,18 +33,18 @@ All adapter factories share the shape `createXxx(devtoolDef, options?)`.
|
|
|
28
33
|
| Run the dev server programmatically (any CLI framework) | `createDevServer(def, options?)` | `devframe/adapters/dev` |
|
|
29
34
|
| Mount a SPA in an existing Vite dev server | `createVitePlugin(def, options?)` | `devframe/adapters/vite` |
|
|
30
35
|
| Self-contained static deploy with baked data | `createBuild(def, options?)` | `devframe/adapters/build` |
|
|
31
|
-
| Integrate into Vite DevTools | `
|
|
36
|
+
| Integrate into Vite DevTools | `createPluginFromDevframe(def, options?)` | `@vitejs/devtools-kit/node` |
|
|
32
37
|
| Register dynamically at runtime | `createEmbedded(def, { ctx })` | `devframe/adapters/embedded` |
|
|
33
38
|
| Expose to coding agents (MCP) | `createMcpServer(def, options?)` | `devframe/adapters/mcp` *(experimental)* |
|
|
34
39
|
|
|
35
|
-
The same `
|
|
40
|
+
The same `DevframeDefinition` runs under every adapter — pick based on deployment, not on what the tool does.
|
|
36
41
|
|
|
37
|
-
## Minimum viable
|
|
42
|
+
## Minimum viable devframe
|
|
38
43
|
|
|
39
44
|
```ts
|
|
40
|
-
import {
|
|
45
|
+
import { defineDevframe, defineRpcFunction } from 'devframe'
|
|
41
46
|
|
|
42
|
-
export default
|
|
47
|
+
export default defineDevframe({
|
|
43
48
|
id: 'my-inspector',
|
|
44
49
|
name: 'My Inspector',
|
|
45
50
|
icon: 'ph:magnifying-glass-duotone',
|
|
@@ -50,46 +55,39 @@ export default defineDevtool({
|
|
|
50
55
|
type: 'static',
|
|
51
56
|
handler: () => ({ count: 42 }),
|
|
52
57
|
}))
|
|
53
|
-
ctx.docks.register({
|
|
54
|
-
id: 'my-inspector',
|
|
55
|
-
title: 'My Inspector',
|
|
56
|
-
icon: 'ph:magnifying-glass-duotone',
|
|
57
|
-
type: 'iframe',
|
|
58
|
-
url: '/.devtools/',
|
|
59
|
-
})
|
|
60
58
|
},
|
|
61
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`.
|
|
63
|
+
|
|
64
|
+
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
65
|
|
|
66
66
|
## Namespacing
|
|
67
67
|
|
|
68
|
-
**Always prefix** RPC names, dock IDs, command IDs, shared-state keys, and agent tool IDs with the
|
|
68
|
+
**Always prefix** RPC names, dock IDs, command IDs, shared-state keys, and agent tool IDs with the devframe `id`:
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
71
|
'my-inspector:get-modules' // ✓
|
|
72
72
|
'my-inspector:state' // ✓
|
|
73
|
-
'get-modules' // ✗ — may collide with other
|
|
73
|
+
'get-modules' // ✗ — may collide with other devframes sharing the host
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
## DevToolsNodeContext at a glance
|
|
77
77
|
|
|
78
|
-
`setup(ctx)` receives the
|
|
78
|
+
`setup(ctx)` receives the framework-neutral server-side surface. Each host corresponds to a [docs](https://devfra.me/) page:
|
|
79
79
|
|
|
80
80
|
| Host | Purpose |
|
|
81
81
|
|------|---------|
|
|
82
|
-
| `ctx.rpc` | Register RPC functions, broadcast, shared state |
|
|
83
|
-
| `ctx.docks` | Dock entries (iframe / action / custom-render / launcher / json-render) |
|
|
82
|
+
| `ctx.rpc` | Register RPC functions, broadcast, shared state, streaming channels |
|
|
84
83
|
| `ctx.views` | Serve static files via `hostStatic(base, distDir)` |
|
|
85
|
-
| `ctx.commands` | Command palette entries with keybindings + `when` gating |
|
|
86
|
-
| `ctx.messages` | Structured message entries, toasts, file / element positions |
|
|
87
84
|
| `ctx.diagnostics` | Structured diagnostics host (logs-sdk) — register custom error codes |
|
|
88
|
-
| `ctx.terminals` | Spawn and stream child processes |
|
|
89
85
|
| `ctx.agent` | Expose tools + resources to coding agents (experimental) |
|
|
90
86
|
| `ctx.host` | Runtime abstraction — `mountStatic`, `resolveOrigin`, `getStorageDir` |
|
|
91
87
|
| `ctx.mode` | `'dev'` or `'build'` — gate setup work per runtime |
|
|
92
88
|
|
|
89
|
+
> Hub-only hosts (`ctx.docks`, `ctx.terminals`, `ctx.messages`, `ctx.commands`, `ctx.createJsonRenderer`) only exist when the devframe is mounted into Vite DevTools via `createPluginFromDevframe`. See the [`vite-devtools-kit` skill](../../skills/vite-devtools-kit) for those.
|
|
90
|
+
|
|
93
91
|
## RPC contracts
|
|
94
92
|
|
|
95
93
|
```ts
|
|
@@ -240,84 +238,36 @@ Readable.fromWeb(reader.readable).pipe(targetNodeWritable)
|
|
|
240
238
|
|
|
241
239
|
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).
|
|
242
240
|
|
|
243
|
-
##
|
|
241
|
+
## Mounting into Vite DevTools
|
|
244
242
|
|
|
245
|
-
|
|
243
|
+
A portable devframe definition is dropped into the Vite DevTools hub via `createPluginFromDevframe`:
|
|
246
244
|
|
|
247
245
|
```ts
|
|
248
|
-
//
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
246
|
+
// vite.config.ts
|
|
247
|
+
import { createPluginFromDevframe } from '@vitejs/devtools-kit/node'
|
|
248
|
+
import myInspector from './my-inspector'
|
|
249
|
+
|
|
250
|
+
export default {
|
|
251
|
+
plugins: [
|
|
252
|
+
createPluginFromDevframe(myInspector, {
|
|
253
|
+
// Optional kit-only setup — runs after the auto-derived dock entry.
|
|
254
|
+
setup(kitCtx) {
|
|
255
|
+
kitCtx.commands.register({
|
|
256
|
+
id: 'my-inspector:clear-cache',
|
|
257
|
+
title: 'Clear Cache',
|
|
258
|
+
handler: () => { /* ... */ },
|
|
259
|
+
})
|
|
260
|
+
},
|
|
261
|
+
}),
|
|
262
|
+
],
|
|
263
|
+
}
|
|
258
264
|
```
|
|
259
265
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
### Remote docks
|
|
263
|
-
|
|
264
|
-
Set `remote: true` on an iframe dock to turn a hosted URL into a live DevFrame client. DevFrame injects an auth-approved connection descriptor into the iframe URL; on the hosted page, `connectDevtool()` parses it and returns a fully connected client — no extra wiring. Dev-mode only.
|
|
265
|
-
|
|
266
|
-
## Commands
|
|
267
|
-
|
|
268
|
-
```ts
|
|
269
|
-
import { defineCommand } from 'devframe'
|
|
270
|
-
|
|
271
|
-
ctx.commands.register(defineCommand({
|
|
272
|
-
id: 'my-inspector:clear-cache',
|
|
273
|
-
title: 'Clear Cache',
|
|
274
|
-
icon: 'ph:trash-duotone',
|
|
275
|
-
keybindings: [{ key: 'Mod+Shift+C' }],
|
|
276
|
-
when: 'clientType == embedded',
|
|
277
|
-
handler: async () => clearCache(),
|
|
278
|
-
}))
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
- Two-level hierarchy (parent + `children`) max.
|
|
282
|
-
- Use `Mod` for platform-aware modifier (Cmd on macOS, Ctrl elsewhere).
|
|
283
|
-
- `ctx.commands.execute(id, ...args)` runs a command programmatically.
|
|
284
|
-
- `when` is a whenexpr expression — see below.
|
|
285
|
-
|
|
286
|
-
## Logs & notifications
|
|
287
|
-
|
|
288
|
-
```ts
|
|
289
|
-
// Fire-and-forget
|
|
290
|
-
ctx.messages.add({ message: 'Scan complete', level: 'success', notify: true })
|
|
291
|
-
|
|
292
|
-
// With handle for in-place updates
|
|
293
|
-
const handle = await ctx.messages.add({
|
|
294
|
-
id: 'my-inspector:build',
|
|
295
|
-
message: 'Building…',
|
|
296
|
-
level: 'info',
|
|
297
|
-
status: 'loading',
|
|
298
|
-
})
|
|
299
|
-
await handle.update({ message: 'Built', level: 'success', status: 'idle' })
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
`notify: true` also renders a toast. `filePosition: { file, line, column }` makes the entry click-to-editor. `elementPosition: { selector, boundingBox }` highlights a DOM element. Re-adding with the same `id` updates the existing entry (deduplication pattern).
|
|
303
|
-
|
|
304
|
-
## Terminals
|
|
305
|
-
|
|
306
|
-
```ts
|
|
307
|
-
const session = await ctx.terminals.startChildProcess(
|
|
308
|
-
{ command: 'vite', args: ['build', '--watch'], cwd: process.cwd() },
|
|
309
|
-
{ id: 'my-inspector:build', title: 'Build', icon: 'ph:terminal-duotone' },
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
await session.terminate()
|
|
313
|
-
await session.restart()
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
Color is enabled automatically (`FORCE_COLOR=true`). Output streams into the built-in Terminals panel and is buffered for late-joining clients.
|
|
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.
|
|
317
267
|
|
|
318
268
|
## When clauses
|
|
319
269
|
|
|
320
|
-
Gate dock / command visibility with VS Code-style expressions
|
|
270
|
+
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:
|
|
321
271
|
|
|
322
272
|
```ts
|
|
323
273
|
when: 'clientType == embedded'
|
|
@@ -325,7 +275,7 @@ when: 'dockOpen && !paletteOpen'
|
|
|
325
275
|
when: 'my-inspector.ready && count >= 10'
|
|
326
276
|
```
|
|
327
277
|
|
|
328
|
-
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`)
|
|
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`) come from `devframe/utils/when`.
|
|
329
279
|
|
|
330
280
|
## Agent-native surface (experimental)
|
|
331
281
|
|
|
@@ -369,25 +319,25 @@ Expose via MCP:
|
|
|
369
319
|
```ts
|
|
370
320
|
import { createMcpServer } from 'devframe/adapters/mcp'
|
|
371
321
|
|
|
372
|
-
await createMcpServer(
|
|
322
|
+
await createMcpServer(devframe, { transport: 'stdio' })
|
|
373
323
|
```
|
|
374
324
|
|
|
375
|
-
`@modelcontextprotocol/sdk` is a peer dependency. The CLI adapter also exposes `my-
|
|
325
|
+
`@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.
|
|
376
326
|
|
|
377
327
|
## Author SPA
|
|
378
328
|
|
|
379
329
|
Authors bring their own SPA (any framework or plain HTML). Client entry:
|
|
380
330
|
|
|
381
331
|
```ts
|
|
382
|
-
import {
|
|
332
|
+
import { connectDevframe } from 'devframe/client'
|
|
383
333
|
|
|
384
|
-
const rpc = await
|
|
334
|
+
const rpc = await connectDevframe()
|
|
385
335
|
// await rpc.ensureTrusted() // WS mode only — blocks until server accepts
|
|
386
336
|
|
|
387
337
|
const data = await rpc.call('my-inspector:get-stats', { limit: 10 })
|
|
388
338
|
```
|
|
389
339
|
|
|
390
|
-
`
|
|
340
|
+
`connectDevframe` auto-detects the backend via `/.devtools/.connection.json`:
|
|
391
341
|
|
|
392
342
|
- **websocket** (dev mode) — full read/write, requires auth handshake. Listen for token updates on the `vite-devtools-auth` BroadcastChannel.
|
|
393
343
|
- **static** (build / spa output) — read-only, resolves calls from the baked RPC dump.
|
|
@@ -416,7 +366,7 @@ At runtime, static clients look up the argument hash in the dump; misses resolve
|
|
|
416
366
|
|
|
417
367
|
## CLI adapter subcommands
|
|
418
368
|
|
|
419
|
-
`createCli(
|
|
369
|
+
`createCli(devframe).parse()` gives the tool four subcommands out of the box:
|
|
420
370
|
|
|
421
371
|
| Subcommand | Action |
|
|
422
372
|
|------------|--------|
|
|
@@ -427,26 +377,52 @@ At runtime, static clients look up the argument hash in the dump; misses resolve
|
|
|
427
377
|
|
|
428
378
|
**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.
|
|
429
379
|
|
|
380
|
+
## Bundled utilities
|
|
381
|
+
|
|
382
|
+
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`:
|
|
383
|
+
|
|
384
|
+
| Import | Wraps | Use for |
|
|
385
|
+
|--------|-------|---------|
|
|
386
|
+
| `colors` from `devframe/utils/colors` | `ansis` | Terminal ANSI colors (`c.red`, `c.green`, tagged templates) |
|
|
387
|
+
| `open` from `devframe/utils/open` | `open` | Open URLs / files in the OS default handler |
|
|
388
|
+
| `launchEditor` from `devframe/utils/launch-editor` | `launch-editor` | Open `file:line:column` in the user's editor (optional `editor` arg) |
|
|
389
|
+
| `hash` from `devframe/utils/hash` | `ohash` | Stable structural hash — cache keys, dedup |
|
|
390
|
+
| `structuredClone{Serialize,Deserialize,Stringify,Parse}` from `devframe/utils/structured-clone` | `structured-clone-es` | JSON-safe round-trip of `Map` / `Set` / `Date` / `BigInt` / cycles |
|
|
391
|
+
| `humanId` from `devframe/utils/human-id` | `human-id` | Human-readable IDs (`bright-orange-tiger`) |
|
|
392
|
+
| `nanoid` from `devframe/utils/nanoid` | (vendored) | URL-safe random IDs |
|
|
393
|
+
| `promiseWithResolver` from `devframe/utils/promise` | — | Externally-controlled `Promise` |
|
|
394
|
+
| `createEventEmitter` from `devframe/utils/events` | — | Typed event bus |
|
|
395
|
+
| `createSharedState` from `devframe/utils/shared-state` | (immer internal) | Immutable state container (see `ctx.rpc.sharedState`) |
|
|
396
|
+
| `createStreamSink` / `createStreamReader` from `devframe/utils/streaming-channel` | — | Low-level streaming primitives |
|
|
397
|
+
| `evaluateWhen` / `WhenExpression` from `devframe/utils/when` | `whenexpr` | When-clause expressions |
|
|
398
|
+
|
|
399
|
+
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.
|
|
400
|
+
|
|
430
401
|
## Testing
|
|
431
402
|
|
|
432
403
|
- Unit-test host classes with fake contexts.
|
|
433
|
-
- Run `templates/counter-
|
|
404
|
+
- Run `templates/counter-devframe.ts` under each adapter for integration coverage.
|
|
434
405
|
- Snapshot the build-static RPC dump (`<outDir>/.devtools/.rpc-dump/index.json`) to catch accidental drift in `static` function outputs.
|
|
435
406
|
|
|
436
407
|
## Further reading
|
|
437
408
|
|
|
438
|
-
|
|
409
|
+
Devframe-level pages (one-tool, portable surface):
|
|
439
410
|
|
|
440
|
-
- [
|
|
441
|
-
- [Adapters](https://devfra.me/adapters) — full reference for all
|
|
411
|
+
- [Devframe Definition](https://devfra.me/devframe-definition) — fields, runtime flags, multi-adapter wiring
|
|
412
|
+
- [Adapters](https://devfra.me/adapters) — full reference for all deployment adapters
|
|
442
413
|
- [RPC](https://devfra.me/rpc) — types, schema, broadcasts, dumps
|
|
443
414
|
- [Shared State](https://devfra.me/shared-state) — patches, events, client-side mutation
|
|
444
415
|
- [Streaming](https://devfra.me/streaming) — chunked feeds, uploads, replay, Web/Node Streams interop
|
|
445
|
-
- [Dock System](https://devfra.me/dock-system) — every entry type + remote docks
|
|
446
|
-
- [Commands](https://devfra.me/commands) — palette, keybindings, sub-commands
|
|
447
416
|
- [When Clauses](https://devfra.me/when-clauses) — syntax, context, type-safe wrappers
|
|
448
|
-
- [Messages & Notifications](https://devfra.me/messages) — entry fields, positional hints
|
|
449
417
|
- [Structured Diagnostics](https://devfra.me/diagnostics) — coded errors via `ctx.diagnostics`, register custom codes
|
|
450
|
-
- [
|
|
418
|
+
- [Utilities](https://devfra.me/utilities) — bundled `devframe/utils/*` helpers (colors, hash, launchEditor, structured-clone, …)
|
|
451
419
|
- [Client](https://devfra.me/client) — auth handshake, modes, discovery
|
|
452
420
|
- [Agent-Native](https://devfra.me/agent-native) — agent field, tools/resources, MCP + Claude Desktop
|
|
421
|
+
|
|
422
|
+
Hub-only surfaces (Vite DevTools Kit — only available when mounted into the hub):
|
|
423
|
+
|
|
424
|
+
- [Vite DevTools Kit overview](https://devtools.vite.dev/kit/)
|
|
425
|
+
- [Dock System](https://devtools.vite.dev/kit/dock-system) — every entry type + remote docks
|
|
426
|
+
- [Commands](https://devtools.vite.dev/kit/commands) — palette, keybindings, sub-commands
|
|
427
|
+
- [Messages & Notifications](https://devtools.vite.dev/kit/messages) — entry fields, positional hints
|
|
428
|
+
- [Terminals](https://devtools.vite.dev/kit/terminals) — child processes, external sessions
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
// Smallest possible
|
|
2
|
-
|
|
1
|
+
// Smallest possible devframe. The dock entry is auto-derived from
|
|
2
|
+
// `id` / `name` / `icon` when this definition is mounted into Vite
|
|
3
|
+
// DevTools via `createPluginFromDevframe(devframe)`.
|
|
4
|
+
import { defineDevframe, defineRpcFunction } from 'devframe'
|
|
3
5
|
|
|
4
6
|
let counter = 0
|
|
5
7
|
|
|
6
|
-
export default
|
|
8
|
+
export default defineDevframe({
|
|
7
9
|
id: 'counter',
|
|
8
10
|
name: 'Counter',
|
|
9
11
|
icon: 'ph:counter-duotone',
|
|
@@ -18,12 +20,5 @@ export default defineDevtool({
|
|
|
18
20
|
type: 'action',
|
|
19
21
|
handler: () => ({ count: ++counter }),
|
|
20
22
|
}))
|
|
21
|
-
ctx.docks.register({
|
|
22
|
-
id: 'counter',
|
|
23
|
-
title: 'Counter',
|
|
24
|
-
icon: 'ph:counter-duotone',
|
|
25
|
-
type: 'iframe',
|
|
26
|
-
url: '/counter/',
|
|
27
|
-
})
|
|
28
23
|
},
|
|
29
24
|
})
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
1
|
+
// Devframe 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 { defineDevframe, defineRpcFunction } from 'devframe'
|
|
3
5
|
import * as v from 'valibot'
|
|
4
6
|
|
|
5
|
-
export default
|
|
7
|
+
export default defineDevframe({
|
|
6
8
|
id: 'my-inspector',
|
|
7
9
|
name: 'My Inspector',
|
|
8
10
|
icon: 'ph:magnifying-glass-duotone',
|
|
@@ -16,13 +18,6 @@ export default defineDevtool({
|
|
|
16
18
|
return { url, verdict: 'ok' as const }
|
|
17
19
|
},
|
|
18
20
|
}))
|
|
19
|
-
ctx.docks.register({
|
|
20
|
-
id: 'my-inspector',
|
|
21
|
-
title: 'My Inspector',
|
|
22
|
-
icon: 'ph:magnifying-glass-duotone',
|
|
23
|
-
type: 'iframe',
|
|
24
|
-
url: '/my-inspector/',
|
|
25
|
-
})
|
|
26
21
|
},
|
|
27
22
|
setupBrowser() {
|
|
28
23
|
// Browser-side implementation — used by the SPA adapter so the
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Minimum SPA client that talks to a devframe-hosted RPC.
|
|
2
|
-
import {
|
|
2
|
+
import { connectDevframe } from 'devframe/client'
|
|
3
3
|
|
|
4
4
|
async function main() {
|
|
5
|
-
const rpc = await
|
|
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)
|
package/dist/adapters/kit.d.mts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { r as DevtoolDefinition } from "../devtool-Bm6zZAw5.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/adapters/kit.d.ts
|
|
4
|
-
interface CreateKitPluginOptions {
|
|
5
|
-
/**
|
|
6
|
-
* Optional plugin name override. Defaults to `devframe:<devtool-id>`.
|
|
7
|
-
*/
|
|
8
|
-
name?: string;
|
|
9
|
-
}
|
|
10
|
-
interface KitPlugin {
|
|
11
|
-
name: string;
|
|
12
|
-
devtools: {
|
|
13
|
-
setup: DevtoolDefinition['setup'];
|
|
14
|
-
capabilities?: DevtoolDefinition['capabilities'];
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Produce a Vite plugin object that Kit's plugin-scan picks up via
|
|
19
|
-
* `Plugin.devtools`.
|
|
20
|
-
*/
|
|
21
|
-
declare function createKitPlugin(d: DevtoolDefinition, options?: CreateKitPluginOptions): KitPlugin;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { CreateKitPluginOptions, KitPlugin, createKitPlugin };
|
package/dist/adapters/kit.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
//#region src/adapters/kit.ts
|
|
2
|
-
/**
|
|
3
|
-
* Produce a Vite plugin object that Kit's plugin-scan picks up via
|
|
4
|
-
* `Plugin.devtools`.
|
|
5
|
-
*/
|
|
6
|
-
function createKitPlugin(d, options = {}) {
|
|
7
|
-
return {
|
|
8
|
-
name: options.name ?? `devframe:${d.id}`,
|
|
9
|
-
devtools: {
|
|
10
|
-
setup: d.setup,
|
|
11
|
-
capabilities: d.capabilities
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
export { createKitPlugin };
|