You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,9 +12,9 @@ Monorepo (`pnpm` workspaces + `turbo`). ESM TypeScript; bundled with `tsdown`. P
12
12
|`packages/core`|`@vitejs/devtools`| Vite plugin, CLI, standalone/webcomponents client. Wraps devframe's createHostContext with the Vite plugin scan |
13
13
|`packages/kit`|`@vitejs/devtools-kit`| Vite-specific superset of devframe — adds PluginWithDevTools, ViteDevToolsNodeContext, and re-exports devframe's public types |
14
14
|`packages/ui`|`@vitejs/devtools-ui`| Shared UI components, composables, and UnoCSS preset (`presetDevToolsUI`). Private, not published |
15
-
|`packages/rolldown`|`@vitejs/devtools-rolldown`| Nuxt UI for Rolldown build data. Serves at `/.devtools-rolldown/`|
16
-
|`packages/vite`|`@vitejs/devtools-vite`| Nuxt UI for Vite DevTools (WIP). Serves at `/.devtools-vite/`|
17
-
|`packages/self-inspect`|`@vitejs/devtools-self-inspect`| Meta-introspection — DevTools for the DevTools. Serves at `/.devtools-self-inspect/`|
15
+
|`packages/rolldown`|`@vitejs/devtools-rolldown`| Nuxt UI for Rolldown build data. Serves at `/__devtools-rolldown/`|
16
+
|`packages/vite`|`@vitejs/devtools-vite`| Nuxt UI for Vite DevTools (WIP). Serves at `/__devtools-vite/`|
17
+
|`packages/self-inspect`|`@vitejs/devtools-self-inspect`| Meta-introspection — DevTools for the DevTools. Serves at `/__devtools-self-inspect/`|
@@ -63,7 +63,7 @@ pnpm -C docs run docs # docs dev server
63
63
- Use workspace aliases from `alias.ts`.
64
64
- RPC functions must use `defineRpcFunction` from kit; always namespace IDs (`my-plugin:fn-name`).
65
65
- Shared state via `devframe/utils/shared-state`; keep values serializable.
66
-
- Nuxt UI base paths: `/.devtools-rolldown/`, `/.devtools-vite/`, `/.devtools-self-inspect/`.
66
+
- Nuxt UI base paths: `/__devtools-rolldown/`, `/__devtools-vite/`, `/__devtools-self-inspect/`.
67
67
- Shared UI components/preset in `packages/ui`; use `presetDevToolsUI` from `@vitejs/devtools-ui/unocss`.
68
68
- Currently focused on Rolldown build-mode analysis; dev-mode support is deferred.
69
69
@@ -73,8 +73,8 @@ These apply to everything inside `packages/devframe` and to how host packages (`
73
73
74
74
-**Headless by default.** No default startup banners, no opinionated logging to stdout, no default styling. Provide hooks (`onReady`, `cli.configure`, etc.); let the application print its own branding. Structured diagnostics via `logs-sdk` are fine — ad-hoc `console.log`s baked into adapters are not.
75
75
-**File watching is the app's job, not devframe's.** Don't add a generic watcher primitive. Authors wire chokidar / fs.watch / watchman themselves and signal change via `ctx.rpc.sharedState.set(...)` or event-type RPCs. devframe stays out of the filesystem-observation business.
76
-
-**Mount path depends on adapter context.** Given `id: 'foo'`, the default mount path is `/.foo/` for *hosted* adapters (`vite`, `kit`, `embedded`) and `/` for *standalone* adapters (`cli`, `spa`, `build`). Authors override via `DevtoolDefinition.basePath`. Don't hardcode `DEVTOOLS_MOUNT_PATH` in adapter code paths that may run standalone.
77
-
-**SPAs own their basePath at runtime.** Build SPAs with relative asset paths (`vite.base: './'`); discover the effective base in the browser from the executing script's location / `document.baseURI`. `createBuild` / `createSpa` copy SPA output verbatim — no HTML rewriting, no build-time `--base` injection. The client (`connectDevtool`) resolves `.connection.json` relative to the runtime base automatically.
76
+
-**Mount path depends on adapter context.** Given `id: 'foo'`, the default mount path is `/__foo/` for *hosted* adapters (`vite`, `kit`, `embedded`) and `/` for *standalone* adapters (`cli`, `spa`, `build`). Authors override via `DevtoolDefinition.basePath`. Don't hardcode `DEVTOOLS_MOUNT_PATH` in adapter code paths that may run standalone.
77
+
-**SPAs own their basePath at runtime.** Build SPAs with relative asset paths (`vite.base: './'`); discover the effective base in the browser from the executing script's location / `document.baseURI`. `createBuild` / `createSpa` copy SPA output verbatim — no HTML rewriting, no build-time `--base` injection. The client (`connectDevtool`) resolves `__connection.json` relative to the runtime base automatically.
78
78
-**CLI flags compose from both sides.** The `cac` instance backing `createCli` is exposed both to the `DevtoolDefinition` (`cli.configure(cli)`) — for capabilities contributed by the tool itself — and to the `createCli` caller — for flags added at the final assembly stage. Parsed flag values are forwarded to `setup(ctx, { flags })`. Never hardcode domain-specific flags into `createCli`.
> Standalone CLI serves the SPA at `/` by default — no `/.devtools/` prefix. That prefix is reserved for *hosted* adapters where devframe mounts alongside an existing app. See [Mount paths](#mount-paths) below.
51
+
> Standalone CLI serves the SPA at `/` by default — no `/__devtools/` prefix. That prefix is reserved for *hosted* adapters where devframe mounts alongside an existing app. See [Mount paths](#mount-paths) below.
52
52
53
53
### Options
54
54
@@ -180,7 +180,7 @@ The basePath where a devtool's SPA is mounted depends on the adapter it's runnin
180
180
| Adapter kind | Default basePath | Reason |
181
181
|--------------|------------------|--------|
182
182
|`cli`, `spa`, `build` (standalone) |`/`| The devtool is the only thing on the origin. |
183
-
|`vite`, `kit`, `embedded` (hosted) |`/.<id>/`| The devtool shares the origin with a host app and must namespace itself. |
183
+
|`vite`, `kit`, `embedded` (hosted) |`/__<id>/`| The devtool shares the origin with a host app and must namespace itself. |
184
184
185
185
Override either side explicitly with `DevtoolDefinition.basePath`:
186
186
@@ -196,7 +196,7 @@ SPA authors should **build with relative asset paths** (`vite.base: './'`) rathe
196
196
197
197
## Vite
198
198
199
-
A thin Vite plugin that mounts a devtool's SPA into an existing Vite dev server as a *hosted* adapter — the mount path defaults to `/.<id>/` to avoid colliding with the app. It **does not** start an RPC WebSocket server — use `kit` or `cli` when you need RPC.
199
+
A thin Vite plugin that mounts a devtool's SPA into an existing Vite dev server as a *hosted* adapter — the mount path defaults to `/__<id>/` to avoid colliding with the app. It **does not** start an RPC WebSocket server — use `kit` or `cli` when you need RPC.
|`base`|`def.basePath ?? '/.<id>/'`| Mount path inside the Vite dev server. |
213
+
|`base`|`def.basePath ?? '/__<id>/'`| Mount path inside the Vite dev server. |
214
214
215
215
Use this adapter when a devtool's UI is purely static (no server calls) and you want to surface it during Vite `serve` without shipping a separate dev server. Set `DevtoolDefinition.basePath` on the definition if you want a custom path that stays consistent across adapters.
216
216
@@ -221,7 +221,7 @@ Produces a self-contained static deploy of a devtool:
221
221
1. Copies the author's SPA dist (`cli.distDir` or `options.distDir`) into `<outDir>`.
222
222
2. Runs `setup(ctx)` with `mode: 'build'`.
223
223
3. Collects RPC dumps for every `'static'` function and any `'query'` function with `dump.inputs` / `snapshot: true`.
224
-
4. Writes `<outDir>/.connection.json` (`{ backend: 'static' }`) and sharded dump files under `<outDir>/.rpc-dump/` — both at the SPA root so the deployed client discovers them via relative paths from `document.baseURI`.
224
+
4. Writes `<outDir>/__connection.json` (`{ backend: 'static' }`) and sharded dump files under `<outDir>/__rpc-dump/` — both at the SPA root so the deployed client discovers them via relative paths from `document.baseURI`.
225
225
5. When `def.spa` is set, also writes `<outDir>/spa-loader.json` describing how the SPA hydrates its data.
226
226
227
227
```ts
@@ -240,7 +240,7 @@ await createBuild(devtool, {
240
240
|`base`|`/`| Absolute URL base the output is served from. |
241
241
|`distDir`|`def.cli?.distDir`| Override the SPA dist directory. |
242
242
243
-
The resulting directory can be hosted by any static web server (`serve`, nginx, GitHub Pages, …). The client auto-detects `static` mode via `./.connection.json` resolved against `document.baseURI` and runs in read-only form.
243
+
The resulting directory can be hosted by any static web server (`serve`, nginx, GitHub Pages, …). The client auto-detects `static` mode via `./__connection.json` resolved against `document.baseURI` and runs in read-only form.
244
244
245
245
> [!TIP]
246
246
> `createBuild` copies the SPA verbatim. To deploy under a custom URL base, build your SPA with relative asset paths (`vite.base: './'`) — the client discovers the effective base at runtime. No HTML rewriting is performed at build time.
@@ -276,7 +276,7 @@ The returned object has the shape `{ name, devtools: { setup, capabilities } }`.
276
276
277
277
## Embedded
278
278
279
-
Register a devtool into an already-running context at runtime. Mirrors the internal plugin-scan that Kit runs at startup, but exposes it for callers that need dynamic, post-startup registration. The host decides the mount path; `embedded` is treated as a hosted adapter and inherits the `/.<id>/` default when one is needed.
279
+
Register a devtool into an already-running context at runtime. Mirrors the internal plugin-scan that Kit runs at startup, but exposes it for callers that need dynamic, post-startup registration. The host decides the mount path; `embedded` is treated as a hosted adapter and inherits the `/__<id>/` default when one is needed.
`connectDevtool` auto-detects the backend via `.devtools/.connection.json` and falls back through a sequence of base URLs. No arguments are needed when the client is hosted from the default mount path.
21
+
`connectDevtool` auto-detects the backend via `__devtools/__connection.json` and falls back through a sequence of base URLs. No arguments are needed when the client is hosted from the default mount path.
22
22
23
23
### Runtime basePath discovery
24
24
25
-
SPAs built for devframe are designed to be **base-agnostic**: the same artifact can be served at `/`, at `/.<id>/`, or at any custom subpath, without rebuilding. `connectDevtool` resolves `.connection.json` relative to the page at runtime by reading `document.baseURI` and the executing script's URL.
25
+
SPAs built for devframe are designed to be **base-agnostic**: the same artifact can be served at `/`, at `/__<id>/`, or at any custom subpath, without rebuilding. `connectDevtool` resolves `__connection.json` relative to the page at runtime by reading `document.baseURI` and the executing script's URL.
26
26
27
27
The practical consequence for SPA authors:
28
28
@@ -46,16 +46,16 @@ await connectDevtool({
46
46
47
47
| Option | Description |
48
48
|--------|-------------|
49
-
|`baseURL`| Mount path to probe for `.connection.json`. Accepts an array for fallback. Default: `'./'` — resolved relative to `document.baseURI` so the SPA finds its meta wherever it was deployed. Pass an explicit absolute path (e.g. `'/.devtools/'`) when calling from outside the SPA — for instance, an embedded webcomponent injected into a host app. |
49
+
|`baseURL`| Mount path to probe for `__connection.json`. Accepts an array for fallback. Default: `'./'` — resolved relative to `document.baseURI` so the SPA finds its meta wherever it was deployed. Pass an explicit absolute path (e.g. `'/__devtools/'`) when calling from outside the SPA — for instance, an embedded webcomponent injected into a host app. |
50
50
|`authToken`| Override the auth token. Defaults to a locally-persisted human-readable id. |
51
51
|`cacheOptions`|`true` to enable caching with defaults, or an options object. |
52
52
|`wsOptions`| Forwarded to the WebSocket transport (reconnect, heartbeat, etc.). |
53
53
|`rpcOptions`| Forwarded to `birpc`. |
54
-
|`connectionMeta`| Skip the `.connection.json` fetch with a pre-known descriptor. |
54
+
|`connectionMeta`| Skip the `__connection.json` fetch with a pre-known descriptor. |
55
55
56
56
## Modes
57
57
58
-
The client runs in one of two modes depending on what the server advertises in `.devtools/.connection.json`:
58
+
The client runs in one of two modes depending on what the server advertises in `__devtools/__connection.json`:
With caching on, `query` / `static` function responses are memoized per argument hash. Server-side broadcasts like `rpc:cache:invalidate` clear entries automatically — plugins that mutate state should broadcast that message after the change.
158
158
159
-
## Discovery (`.connection.json`)
159
+
## Discovery (`__connection.json`)
160
160
161
-
DevFrame writes a small JSON descriptor at `<base>/.connection.json` so the client knows where to connect:
161
+
DevFrame writes a small JSON descriptor at `<base>/__connection.json` so the client knows where to connect:
Copy file name to clipboardExpand all lines: devframe/docs/guide/devtool-definition.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ export default defineDevtool({
21
21
title: 'My Devtool',
22
22
icon: 'ph:gauge-duotone',
23
23
type: 'iframe',
24
-
url: '/.devtools/',
24
+
url: '/__devtools/',
25
25
})
26
26
},
27
27
})
@@ -35,7 +35,7 @@ export default defineDevtool({
35
35
|`name`|`string`|**Required.** Display name shown in the dock and agent manifests. |
36
36
|`icon`|`string \| { light, dark }`| Optional Iconify name or URL; supports light/dark pairs. |
37
37
|`version`|`string`| Optional version string surfaced to clients. |
38
-
|`basePath`|`string`| Optional mount path override. Defaults depend on the adapter: `/` for standalone (`cli` / `spa` / `build`), `/.<id>/` for hosted (`vite` / `kit` / `embedded`). |
38
+
|`basePath`|`string`| Optional mount path override. Defaults depend on the adapter: `/` for standalone (`cli` / `spa` / `build`), `/__<id>/` for hosted (`vite` / `kit` / `embedded`). |
39
39
|`capabilities`|`{ dev?, build?, spa? }`| Per-runtime feature flags. A `boolean` applies to the runtime as a whole; an object enables individual features. |
40
40
|`setup`|`(ctx, info?) => void \| Promise<void>`|**Required.** Server-side entry point. Runs in every runtime. The optional second argument carries runtime metadata — most notably the parsed CLI `flags` when running under `createCli`. |
41
41
|`setupBrowser`|`(ctx) => void \| Promise<void>`| Browser-only entry used by the SPA adapter. |
Copy file name to clipboardExpand all lines: devframe/docs/guide/index.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ DevFrame keeps its surface small and pushes UX decisions to the application cons
17
17
18
18
-**Headless.** No default startup banners, logging, or styling. Hook into `onReady`, `cli.configure`, and friends to print your own output.
19
19
-**App-owned file watching.** Wire your own watcher (chokidar, fs.watch, …) and signal change via `ctx.rpc.sharedState.set(...)` or event-type RPCs. DevFrame does not ship a watcher primitive.
20
-
-**Context-aware mount paths.** Standalone adapters (`cli`, `spa`, `build`) serve at `/` by default; hosted adapters (`vite`, `kit`, `embedded`) serve at `/.<id>/`. Override via `DevtoolDefinition.basePath`.
20
+
-**Context-aware mount paths.** Standalone adapters (`cli`, `spa`, `build`) serve at `/` by default; hosted adapters (`vite`, `kit`, `embedded`) serve at `/__<id>/`. Override via `DevtoolDefinition.basePath`.
21
21
-**SPAs own their base at runtime.** Build with relative asset paths (`vite.base: './'`); `connectDevtool` discovers the effective base from the executing script's location. No HTML rewrites at build time.
22
22
-**CLI flags compose.** The `cac` instance is exposed to both the devtool (`cli.configure`) and the caller of `createCli`, so capability flags and app flags merge cleanly.
node ./my-devtool.js mcp # stdio MCP server (experimental)
114
114
```
115
115
116
-
The CLI adapter serves the SPA at `/` by default. When the same devtool is embedded inside a host (`vite`, `kit`, `embedded`), the default becomes `/.my-devtool/`. Override either side via `defineDevtool({ basePath })`.
116
+
The CLI adapter serves the SPA at `/` by default. When the same devtool is embedded inside a host (`vite`, `kit`, `embedded`), the default becomes `/__my-devtool/`. Override either side via `defineDevtool({ basePath })`.
Copy file name to clipboardExpand all lines: devframe/docs/guide/nuxt.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -68,7 +68,7 @@ At build time the module:
68
68
return { provide: { rpc } }
69
69
```
70
70
71
-
At runtime the built SPA fetches `./.connection.json` (resolved against `document.baseURI`) and branches on the `backend` field — `websocket` in dev, `static` from a `createBuild` snapshot.
71
+
At runtime the built SPA fetches `./__connection.json` (resolved against `document.baseURI`) and branches on the `backend` field — `websocket` in dev, `static` from a `createBuild` snapshot.
Copy file name to clipboardExpand all lines: devframe/examples/devframe-files-inspector/README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,15 +8,15 @@ A simplified [node-modules-inspector](https://github.com/antfu/node-modules-insp
8
8
9
9
The Preact client showcases two patterns relevant to devframe authors:
10
10
11
-
1.**Runtime base discovery.** The client is built with `vite.base: './'` and reads `document.baseURI` at runtime to resolve its mount path. The same `dist/client` works under any base path (`/.devframe-files-inspector/`, `/`, `/custom/`, …) without rebuilding.
11
+
1.**Runtime base discovery.** The client is built with `vite.base: './'` and reads `document.baseURI` at runtime to resolve its mount path. The same `dist/client` works under any base path (`/__devframe-files-inspector/`, `/`, `/custom/`, …) without rebuilding.
12
12
2.**Two RPC types.**`:list-files` is a `query` with `dump.inputs: [[]]` (live in dev, baked in static). `:get-cwd` is a `static` RPC.
13
13
14
14
## Run
15
15
16
16
```sh
17
17
pnpm install
18
18
pnpm -C examples/devframe-files-inspector run build # build the Preact client
19
-
pnpm -C examples/devframe-files-inspector run dev # http://127.0.0.1:9876/.devframe-files-inspector/
19
+
pnpm -C examples/devframe-files-inspector run dev # http://127.0.0.1:9876/__devframe-files-inspector/
20
20
pnpm -C examples/devframe-files-inspector run cli:build # static deploy in ./dist/static
21
21
serve examples/devframe-files-inspector/dist/static # any static host works (relative paths)
22
22
pnpm -C examples/devframe-files-inspector run test# E2E tests
0 commit comments