devframe 0.9.0-beta.1 → 0.9.0-beta.10
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/dist/{_shared-DmpWW-HH.d.mts → _shared-BPmX9fqK.d.mts} +2 -4
- package/dist/{_shared-CttmCMBi.mjs → _shared-CbZ_yhbz.mjs} +2 -4
- package/dist/adapters/build.d.mts +10 -12
- package/dist/adapters/build.mjs +26 -30
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +6 -7
- package/dist/adapters/dev.d.mts +22 -8
- package/dist/adapters/dev.mjs +2 -2
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +5 -4
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +1 -8
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/{agent-tool-name-C3b5vEwJ.mjs → agent-tool-name-EgfoFO8C.mjs} +0 -3
- package/dist/cli/main.d.mts +0 -2
- package/dist/cli/main.mjs +4 -8
- package/dist/client/index.d.mts +5 -5
- package/dist/client/index.mjs +24 -1179
- package/dist/constants.d.mts +10 -2
- package/dist/constants.mjs +10 -2
- package/dist/{context-CSCwoABx.d.mts → context-B3YUu_95.d.mts} +19 -1
- package/dist/{context-Du11TLcO.mjs → context-CEe4PBz1.mjs} +23 -305
- package/dist/{context-C33rR7n0.mjs → context-xdynGSLP.mjs} +10 -1
- package/dist/{dev-BEveeA5H.mjs → dev--rAPzbvO.mjs} +16 -10
- package/dist/{devframe-Bdd9YXTy.d.mts → devframe-DJMg0WLe.d.mts} +97 -113
- package/dist/{diagnostics-hwjXp_UV.mjs → diagnostics-CD8nlgll.mjs} +1 -3
- package/dist/{diagnostics-DLYH5oD3.mjs → diagnostics-DOQPnQmX.mjs} +35 -5
- package/dist/{dist-D8jAMwxU.mjs → dist-eNI9qM_I.mjs} +1 -0
- package/dist/{host-agent-CpbAoqBx.mjs → host-agent-xLCSe65D.mjs} +41 -7
- package/dist/{host-h3-CzCZwtuV.mjs → host-h3-Crkzm42q.mjs} +2 -2
- package/dist/{http-DLr_cJZ7.mjs → http-DYpK0cUi.mjs} +5 -12
- package/dist/{index-CZRd2K1C.d.mts → index-CB-fSUyn.d.mts} +2 -2
- package/dist/{index-DSCq4M4q.d.mts → index-tdrk1bzV.d.mts} +1 -1
- package/dist/index.d.mts +7 -5
- package/dist/{instance-registry-BQqGoDO9.mjs → instance-registry-WvQkt42E.mjs} +1 -7
- package/dist/{instance-shell-KRdee1QF.mjs → instance-shell-CMFyszWJ.mjs} +9 -8
- package/dist/{instance-shell-DBTXTSjN.d.mts → instance-shell-CljiKq1c.d.mts} +3 -12
- package/dist/internal/index.d.mts +265 -18
- package/dist/internal/index.mjs +9 -7
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/auth.mjs +1 -1
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +2 -2
- package/dist/node/index.d.mts +3 -3
- package/dist/node/index.mjs +2 -2
- package/dist/nostics-CzECRXpE.mjs +59 -0
- package/dist/nostics-SPGDgHEP.d.mts +33 -0
- package/dist/recipes/common-rpc-functions.d.mts +3 -3
- package/dist/recipes/interactive-auth.d.mts +2 -2
- package/dist/recipes/interactive-auth.mjs +3 -3
- package/dist/remote-assets-Bg4gCUZ_.d.mts +123 -0
- package/dist/remote-assets-nTTxY2MU.mjs +636 -0
- package/dist/rpc/dump.d.mts +1 -1
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +3 -3
- package/dist/rpc/transports/sse-client.d.mts +1 -1
- package/dist/rpc/transports/sse-client.mjs +1 -1
- package/dist/rpc/transports/sse-server.d.mts +2 -2
- package/dist/rpc/transports/sse-server.mjs +2 -2
- package/dist/rpc/transports/ws-bun.d.mts +2 -2
- package/dist/rpc/transports/ws-bun.mjs +1 -1
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +1 -1
- package/dist/rpc/transports/ws-server.d.mts +1 -1
- package/dist/rpc/transports/ws-server.mjs +1 -1
- package/dist/{rpc-core-CGctXToO.d.mts → rpc-core-Cc4lucI0.d.mts} +3 -3
- package/dist/{rpc-core-CqcJkAu9.mjs → rpc-core-DMTe-hLo.mjs} +1 -1
- package/dist/{serialization-BHY8M5NQ.mjs → serialization-BGzEwAdr.mjs} +1 -1
- package/dist/{sse-client-BsIK3hMD.d.mts → sse-client-CFBOIaUi.d.mts} +1 -1
- package/dist/state-Cc1IeSmQ.mjs +1291 -0
- package/dist/{static-CvjkO8QE.mjs → static-BPZ1_OPA.mjs} +2 -2
- package/dist/storage-CYye7P7L.mjs +137 -0
- package/dist/types/index.d.mts +6 -4
- package/dist/{types-CnJSgRVa.d.mts → types-Djq7CBXh.d.mts} +0 -7
- package/dist/utils/agent-tool-name.d.mts +0 -3
- package/dist/utils/agent-tool-name.mjs +0 -3
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/get-port.d.mts +17 -0
- package/dist/utils/get-port.mjs +2 -0
- package/dist/utils/nostics.d.mts +2 -0
- package/dist/utils/nostics.mjs +2 -0
- package/dist/utils/open.d.mts +2 -10
- package/dist/utils/open.mjs +56 -1
- package/dist/utils/remote-assets.d.mts +15 -0
- package/dist/utils/remote-assets.mjs +2 -0
- package/dist/utils/serve-static.d.mts +13 -5
- package/dist/utils/serve-static.mjs +119 -9
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/{validation-BiuDXTKW.mjs → validation-CpXFB6Dz.mjs} +1 -1
- package/dist/{wire-codec-9VhIKnyp.mjs → wire-codec-0K-o5MYW.mjs} +1 -3
- package/dist/{ws-client-CdNuATYa.d.mts → ws-client-DhjNyQo3.d.mts} +1 -1
- package/dist/{ws-server-Bk1hOG3X.mjs → ws-server-BdSLrhxE.mjs} +1 -1
- package/dist/{ws-server-Ces08fjP.d.mts → ws-server-D1d3QM9f.d.mts} +1 -1
- package/package.json +4 -4
- package/skills/devframe/SKILL.md +10 -11
- package/dist/diagnostics-reporter-CsIG85Q5.mjs +0 -38
- package/dist/helpers/vite.d.mts +0 -104
- package/dist/helpers/vite.mjs +0 -93
- package/dist/open-Dz4V4irZ.mjs +0 -547
- package/dist/state-BeUHDDjk.mjs +0 -108
- package/dist/storage-BcmVEJRc.mjs +0 -1122
- package/skills/devframe/templates/spa-devframe.ts +0 -38
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devframe",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.9.0-beta.
|
|
4
|
+
"version": "0.9.0-beta.10",
|
|
5
5
|
"description": "Framework for building one portable devtool integration that runs in any viewer.",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"./adapters/mcp": "./dist/adapters/mcp.mjs",
|
|
28
28
|
"./client": "./dist/client/index.mjs",
|
|
29
29
|
"./constants": "./dist/constants.mjs",
|
|
30
|
-
"./helpers/vite": "./dist/helpers/vite.mjs",
|
|
31
30
|
"./initiate": "./dist/adapters/initiate.mjs",
|
|
32
31
|
"./internal": "./dist/internal/index.mjs",
|
|
33
32
|
"./node": "./dist/node/index.mjs",
|
|
@@ -49,10 +48,13 @@
|
|
|
49
48
|
"./utils/colors": "./dist/utils/colors.mjs",
|
|
50
49
|
"./utils/crypto-token": "./dist/utils/crypto-token.mjs",
|
|
51
50
|
"./utils/events": "./dist/utils/events.mjs",
|
|
51
|
+
"./utils/get-port": "./dist/utils/get-port.mjs",
|
|
52
52
|
"./utils/hash": "./dist/utils/hash.mjs",
|
|
53
53
|
"./utils/launch-editor": "./dist/utils/launch-editor.mjs",
|
|
54
54
|
"./utils/nanoid": "./dist/utils/nanoid.mjs",
|
|
55
|
+
"./utils/nostics": "./dist/utils/nostics.mjs",
|
|
55
56
|
"./utils/open": "./dist/utils/open.mjs",
|
|
57
|
+
"./utils/remote-assets": "./dist/utils/remote-assets.mjs",
|
|
56
58
|
"./utils/simple-schema": "./dist/utils/simple-schema.mjs",
|
|
57
59
|
"./utils/serve-static": "./dist/utils/serve-static.mjs",
|
|
58
60
|
"./utils/shared-state": "./dist/utils/shared-state.mjs",
|
|
@@ -90,7 +92,6 @@
|
|
|
90
92
|
"@standard-schema/spec": "^1.1.0",
|
|
91
93
|
"birpc": "^4.1.0",
|
|
92
94
|
"crossws": "^0.4.10",
|
|
93
|
-
"destr": "^2.0.5",
|
|
94
95
|
"h3": "^2.0.1-rc.26",
|
|
95
96
|
"mrmime": "^2.0.1",
|
|
96
97
|
"nostics": "^1.2.0",
|
|
@@ -107,7 +108,6 @@
|
|
|
107
108
|
"mlly": "^1.8.2",
|
|
108
109
|
"obug": "^2.1.4",
|
|
109
110
|
"ohash": "^2.0.11",
|
|
110
|
-
"open": "^11.0.0",
|
|
111
111
|
"p-limit": "^7.3.1",
|
|
112
112
|
"perfect-debounce": "^2.1.0",
|
|
113
113
|
"structured-clone-es": "^2.0.1",
|
package/skills/devframe/SKILL.md
CHANGED
|
@@ -5,7 +5,7 @@ description: >
|
|
|
5
5
|
framework- and build-tool-agnostic foundation for defining a
|
|
6
6
|
devtool once and serving it in many places. Covers
|
|
7
7
|
DevframeDefinition, picking the right deployment adapter
|
|
8
|
-
(cli / build /
|
|
8
|
+
(cli / build / vite / embedded / mcp), designing RPC
|
|
9
9
|
contracts, exposing an agent-native surface over MCP, and
|
|
10
10
|
wiring the author's SPA client. For host-level features (docks,
|
|
11
11
|
terminals, palette, etc.), the devframe can be mounted into a
|
|
@@ -36,11 +36,11 @@ All adapter factories share the shape `createXxx(devframeDef, options?)`.
|
|
|
36
36
|
| Self-contained static deploy with baked data | `createBuild(def, options?)` | `devframe/adapters/build` |
|
|
37
37
|
| Mount into a host (Vite DevTools or any compatible host) | `createPluginFromDevframe(def, options?)` | `@vitejs/devtools-kit/node` |
|
|
38
38
|
| Register dynamically at runtime | `createEmbedded(def, { ctx })` | `devframe/adapters/embedded` |
|
|
39
|
-
| Expose to coding agents (MCP) | `createMcpServer(def, options?)` | `devframe/adapters/mcp`
|
|
39
|
+
| Expose to coding agents (MCP) | `createMcpServer(def, options?)` | `devframe/adapters/mcp` |
|
|
40
40
|
|
|
41
41
|
The same `DevframeDefinition` runs under every adapter - pick based on deployment, not on what the tool does.
|
|
42
42
|
|
|
43
|
-
For Vite-based hosts that don't use the kit (Nuxt, Astro, SolidStart, plain Vite apps),
|
|
43
|
+
For Vite-based hosts that don't use the kit (Nuxt, Astro, SolidStart, plain Vite apps), `@devframes/vite` exports `devframeVitePlugin(def, options?)` (static SPA mount) and `devframeViteBridge(def, options?)` (RPC + WS bridge alongside the host's dev server) - plus `devframeVite(def, { bridge, ...options })` as a convenience wrapper over both. Not an adapter; just a Vite integration helper.
|
|
44
44
|
|
|
45
45
|
## Minimum viable devframe
|
|
46
46
|
|
|
@@ -85,7 +85,7 @@ export default defineDevframe({
|
|
|
85
85
|
|
|
86
86
|
`setup(ctx)` registers RPC functions, shared state, diagnostics, and any other devframe-level wiring. Host adapters can augment `ctx` with extra surfaces - for 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`.
|
|
87
87
|
|
|
88
|
-
See `templates/counter-devframe.ts` for a runnable counter example
|
|
88
|
+
See `templates/counter-devframe.ts` for a runnable counter example and `templates/vite-client.ts` for the author's client entry.
|
|
89
89
|
|
|
90
90
|
## Scoped context (preferred)
|
|
91
91
|
|
|
@@ -243,7 +243,7 @@ A [scoped context](#scoped-context-preferred) applies this prefix for you - `ctx
|
|
|
243
243
|
| `ctx.rpc` | Register RPC functions, broadcast, shared state, streaming channels |
|
|
244
244
|
| `ctx.views` | Serve static files via `hostStatic(base, distDir)` |
|
|
245
245
|
| `ctx.diagnostics` | Structured diagnostics host (nostics) - register custom error codes |
|
|
246
|
-
| `ctx.agent` | Expose tools + resources to coding agents
|
|
246
|
+
| `ctx.agent` | Expose tools + resources to coding agents |
|
|
247
247
|
| `ctx.host` | Runtime abstraction - `mountStatic`, `resolveOrigin`, `getStorageDir` |
|
|
248
248
|
| `ctx.mode` | `'dev'` or `'build'` - gate setup work per runtime |
|
|
249
249
|
|
|
@@ -440,7 +440,7 @@ when: 'my-inspector.ready && count >= 10'
|
|
|
440
440
|
|
|
441
441
|
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`.
|
|
442
442
|
|
|
443
|
-
## Agent-native surface
|
|
443
|
+
## Agent-native surface
|
|
444
444
|
|
|
445
445
|
Opt an RPC function into the agent surface with an `agent` field - default-deny otherwise. Agent-exposed functions **must declare `jsonSerializable: true`** (registration throws `DF0019` otherwise):
|
|
446
446
|
|
|
@@ -504,7 +504,7 @@ const data = await my.rpc.call('get-stats', { limit: 10 })
|
|
|
504
504
|
`connectDevframe` auto-detects the backend via `/.devframe/.connection.json`:
|
|
505
505
|
|
|
506
506
|
- **websocket** (dev mode) - full read/write, requires auth handshake. Listen for token updates on the `devframe-auth` BroadcastChannel.
|
|
507
|
-
- **static** (build
|
|
507
|
+
- **static** (build output) - read-only, resolves calls from the baked RPC dump.
|
|
508
508
|
|
|
509
509
|
Use `my.rpc.sharedState(key)` for observable state, `my.rpc.register(defineRpcFunction(...))` to receive server broadcasts, `my.rpc.callOptional(...)` when a missing handler should resolve to `undefined` instead of throwing, and `my.settings.{project,global}` for persisted per-workspace / per-user settings synced from the server.
|
|
510
510
|
|
|
@@ -530,14 +530,13 @@ At runtime, static clients look up the argument hash in the dump; misses resolve
|
|
|
530
530
|
|
|
531
531
|
## CLI adapter subcommands
|
|
532
532
|
|
|
533
|
-
`createCac(devframe).parse()` gives the tool
|
|
533
|
+
`createCac(devframe).parse()` gives the tool three subcommands out of the box:
|
|
534
534
|
|
|
535
535
|
| Subcommand | Action |
|
|
536
536
|
|------------|--------|
|
|
537
537
|
| *(default)* | Dev server on port 9999 (or `--port`) - WebSocket RPC, `cli.distDir` served at `/.devframe/` |
|
|
538
538
|
| `build` | Static snapshot → `./dist-static/` (configurable via `--out-dir`) |
|
|
539
|
-
| `
|
|
540
|
-
| `mcp` | stdio MCP server (experimental) |
|
|
539
|
+
| `mcp` | stdio MCP server |
|
|
541
540
|
|
|
542
541
|
**Bring your own CLI framework?** `createCac` (`devframe/adapters/cac`) 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 `createCac`'s baked-in command structure doesn't fit. `cac` is an optional peer dependency pulled in only through `devframe/adapters/cac`, so bring-your-own-CLI tools run without installing it. `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/cac`) validate an arbitrary flag bag against a `CliFlagsSchema` - the helpers are framework-agnostic.
|
|
543
542
|
|
|
@@ -572,7 +571,7 @@ RPC handlers run with the full privileges of the host process, so the boundary t
|
|
|
572
571
|
- **Tokens are secrets.** The bearer token rides the WS URL (`?devframe_auth_token=…`) - serve over `wss://`/`https://` beyond loopback. Never log the token or code, never bake them into build output. Revoke via `revokeAuthToken(...)`; clients drop to untrusted on `devframe:auth:revoked`.
|
|
573
572
|
- **Authorize handlers.** Any trusted client can call any registered function - validate inputs, and mark state-changing functions `type: 'destructive'` so MCP/agent clients prompt first.
|
|
574
573
|
- **Origin-lock remote docks** (`originLock`, on by default) so a dock's session token is honored only on a connection whose `Origin` matches the dock - the connect-time gate enforces it.
|
|
575
|
-
- **The MCP route requires an Origin.** The route-based MCP server (`cli.mcp`, `
|
|
574
|
+
- **The MCP route requires an Origin.** The route-based MCP server (`cli.mcp`, `devframeViteBridge`/Next handler `mcp`, `createMcpFetchHandler`) rejects `Origin`-less requests - a request must carry a loopback (or allow-listed) `Origin`, so it isn't reachable by an arbitrary local process. `devframe connect` sends each instance's own loopback origin automatically.
|
|
576
575
|
|
|
577
576
|
See [Security](https://devfra.me/security) for the full reference.
|
|
578
577
|
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { ansiFormatter } from "nostics/formatters/ansi";
|
|
2
|
-
//#region src/utils/colors.ts
|
|
3
|
-
function makeColor(open, close) {
|
|
4
|
-
const o = `\x1B[${open}m`;
|
|
5
|
-
const c = `\x1B[${close}m`;
|
|
6
|
-
return ((arg, ...values) => {
|
|
7
|
-
if (Array.isArray(arg) && "raw" in arg) {
|
|
8
|
-
const strings = arg;
|
|
9
|
-
let out = "";
|
|
10
|
-
for (let i = 0; i < strings.length; i++) {
|
|
11
|
-
out += strings[i];
|
|
12
|
-
if (i < values.length) out += String(values[i]);
|
|
13
|
-
}
|
|
14
|
-
return `${o}${out}${c}`;
|
|
15
|
-
}
|
|
16
|
-
return `${o}${String(arg)}${c}`;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
const colors = {
|
|
20
|
-
blue: makeColor(34, 39),
|
|
21
|
-
cyan: makeColor(36, 39),
|
|
22
|
-
gray: makeColor(90, 39),
|
|
23
|
-
green: makeColor(32, 39),
|
|
24
|
-
red: makeColor(31, 39),
|
|
25
|
-
yellow: makeColor(33, 39),
|
|
26
|
-
bold: makeColor(1, 22),
|
|
27
|
-
dim: makeColor(2, 22),
|
|
28
|
-
reset: makeColor(0, 0),
|
|
29
|
-
underline: makeColor(4, 24)
|
|
30
|
-
};
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/utils/diagnostics-reporter.ts
|
|
33
|
-
const formatAnsi = ansiFormatter(colors);
|
|
34
|
-
function devframeReporter(d, { method = "warn" } = {}) {
|
|
35
|
-
console[method](formatAnsi(d));
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
|
-
export { colors as n, devframeReporter as t };
|
package/dist/helpers/vite.d.mts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { f as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition } from "../devframe-Bdd9YXTy.mjs";
|
|
2
|
-
import { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
3
|
-
//#region src/helpers/vite.d.ts
|
|
4
|
-
interface ViteDevBridgeOptions {
|
|
5
|
-
/**
|
|
6
|
-
* Mount base. Defaults to `def.basePath ?? '/__<id>/'` for this hosted
|
|
7
|
-
* adapter — the devframe shares the origin with the host Vite app.
|
|
8
|
-
*
|
|
9
|
-
* Relative spellings like `'./'` (common for base-agnostic Nuxt builds)
|
|
10
|
-
* are normalized to absolute paths so they compose with Vite's connect
|
|
11
|
-
* router.
|
|
12
|
-
*/
|
|
13
|
-
base?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Dev-time middleware mode. When set, the host app owns the SPA and
|
|
16
|
-
* devframe serves the RPC surface through the Vite dev server itself —
|
|
17
|
-
* `<base>__connection.json` for discovery and the WebSocket upgrade at
|
|
18
|
-
* `<base>__ws` on Vite's own HTTP server (zero extra ports, proxy/HTTPS
|
|
19
|
-
* friendly). When Vite runs in middleware mode (no `httpServer`) — or a
|
|
20
|
-
* `port` is pinned — the socket falls back to a side-car server on its
|
|
21
|
-
* own port instead.
|
|
22
|
-
*
|
|
23
|
-
* - `false` (default) — static-mount the SPA at `base` with SPA
|
|
24
|
-
* fallback. No RPC server is started.
|
|
25
|
-
* - `true` — bridge mode with all defaults.
|
|
26
|
-
* - object — bridge mode with explicit overrides.
|
|
27
|
-
*/
|
|
28
|
-
devMiddleware?: boolean | {
|
|
29
|
-
/**
|
|
30
|
-
* Pin a side-car port for the RPC socket instead of sharing Vite's
|
|
31
|
-
* server. Default: share Vite's HTTP server (side-car only when Vite
|
|
32
|
-
* has none).
|
|
33
|
-
*/
|
|
34
|
-
port?: number;
|
|
35
|
-
/** Override the side-car bind host. Default: `def.cli?.host ?? 'localhost'`. */
|
|
36
|
-
host?: string;
|
|
37
|
-
/** Flag bag forwarded to `def.setup(ctx, { flags })`. */
|
|
38
|
-
flags?: Record<string, unknown>;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Whether the bridged devframe runs its own auth gate. The RPC endpoint is
|
|
42
|
-
* reachable by anything that can open its socket, so it **gates by
|
|
43
|
-
* default**: when unset, authentication resolves through devframe's
|
|
44
|
-
* interactive OTP gate (unless the definition's `cli.auth` opts out), and
|
|
45
|
-
* the bridge prints its code/link banner to stdout. Pass a
|
|
46
|
-
* {@link DevframeAuthHandler} to install a custom scheme, or `false` to opt
|
|
47
|
-
* out for a single-user localhost host that owns the trust boundary another
|
|
48
|
-
* way. Only applies in bridge mode (`devMiddleware`); the static-mount mode
|
|
49
|
-
* starts no RPC server.
|
|
50
|
-
*
|
|
51
|
-
* @default gated (devframe's interactive OTP, unless `cli.auth` opts out)
|
|
52
|
-
*/
|
|
53
|
-
auth?: boolean | DevframeAuthHandler;
|
|
54
|
-
/**
|
|
55
|
-
* Expose the bridge's route-based MCP server (Streamable-HTTP) at
|
|
56
|
-
* `<base>__mcp` — on the Vite app's own origin — and advertise it in the
|
|
57
|
-
* bridge's `__connection.json`. Overrides `def.cli?.mcp`, `undefined`
|
|
58
|
-
* falls through to it, `false` disables the route regardless. Only applies
|
|
59
|
-
* in bridge mode (`devMiddleware`); the static-mount mode starts no server.
|
|
60
|
-
*
|
|
61
|
-
* @experimental
|
|
62
|
-
*/
|
|
63
|
-
mcp?: boolean | McpRouteOptions;
|
|
64
|
-
}
|
|
65
|
-
/** The slice of a Vite dev server the bridge plugin touches. */
|
|
66
|
-
interface DevframeViteDevServerLike {
|
|
67
|
-
middlewares: {
|
|
68
|
-
use: ((path: string, handler: (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => void) => void) & ((handler: (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => void) => void);
|
|
69
|
-
};
|
|
70
|
-
httpServer?: Server | null;
|
|
71
|
-
}
|
|
72
|
-
interface DevframeVitePlugin {
|
|
73
|
-
name: string;
|
|
74
|
-
apply: 'serve';
|
|
75
|
-
configureServer: (server: DevframeViteDevServerLike) => void | Promise<void>;
|
|
76
|
-
closeBundle?: () => void | Promise<void>;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Bridge a devframe into an existing Vite dev server. Returns a Vite
|
|
80
|
-
* plugin with two modes, picked via `options.devMiddleware`:
|
|
81
|
-
*
|
|
82
|
-
* - **static-mount mode** (default) — mounts `def.cli.distDir` at
|
|
83
|
-
* `options.base` with SPA fallback enabled. No RPC server is started.
|
|
84
|
-
*
|
|
85
|
-
* - **bridge mode** (`devMiddleware: true | {…}`) — skips the static
|
|
86
|
-
* mount; the host app owns the SPA. Devframe serves discovery
|
|
87
|
-
* (`<base>__connection.json`), the WebSocket RPC upgrade
|
|
88
|
-
* (`<base>__ws`, shared on Vite's own HTTP server), and the optional
|
|
89
|
-
* MCP route through {@link initDevframe}'s node middleware, so the
|
|
90
|
-
* host-served SPA can discover the endpoint via {@link connectDevframe}.
|
|
91
|
-
*
|
|
92
|
-
* The bridge **gates by default** (devframe's interactive OTP unless the
|
|
93
|
-
* definition's `cli.auth` opts out), printing its code/link banner to stdout,
|
|
94
|
-
* so a bridged devframe isn't silently reachable by anything that can open
|
|
95
|
-
* its socket. Pass `options.auth: false` to opt out for a single-user
|
|
96
|
-
* localhost host, or a {@link DevframeAuthHandler} for a custom scheme.
|
|
97
|
-
*
|
|
98
|
-
* Use bridge mode when integrating with frameworks that own the SPA
|
|
99
|
-
* (Nuxt, Astro, SolidStart, plain Vite apps). For the all-in-one
|
|
100
|
-
* `dev` / `build` / `mcp` shell, reach for {@link createCac} instead.
|
|
101
|
-
*/
|
|
102
|
-
declare function viteDevBridge(d: DevframeDefinition, options?: ViteDevBridgeOptions): DevframeVitePlugin;
|
|
103
|
-
//#endregion
|
|
104
|
-
export { DevframeViteDevServerLike, DevframeVitePlugin, ViteDevBridgeOptions, viteDevBridge };
|
package/dist/helpers/vite.mjs
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { t as diagnostics } from "../diagnostics-DLYH5oD3.mjs";
|
|
2
|
-
import { n as resolveBasePath, t as normalizeBasePath } from "../_shared-CttmCMBi.mjs";
|
|
3
|
-
import { serveStaticNodeMiddleware } from "../utils/serve-static.mjs";
|
|
4
|
-
import { r as initDevframe } from "../dev-BEveeA5H.mjs";
|
|
5
|
-
import { resolve } from "pathe";
|
|
6
|
-
//#region src/helpers/vite.ts
|
|
7
|
-
/**
|
|
8
|
-
* Bridge a devframe into an existing Vite dev server. Returns a Vite
|
|
9
|
-
* plugin with two modes, picked via `options.devMiddleware`:
|
|
10
|
-
*
|
|
11
|
-
* - **static-mount mode** (default) — mounts `def.cli.distDir` at
|
|
12
|
-
* `options.base` with SPA fallback enabled. No RPC server is started.
|
|
13
|
-
*
|
|
14
|
-
* - **bridge mode** (`devMiddleware: true | {…}`) — skips the static
|
|
15
|
-
* mount; the host app owns the SPA. Devframe serves discovery
|
|
16
|
-
* (`<base>__connection.json`), the WebSocket RPC upgrade
|
|
17
|
-
* (`<base>__ws`, shared on Vite's own HTTP server), and the optional
|
|
18
|
-
* MCP route through {@link initDevframe}'s node middleware, so the
|
|
19
|
-
* host-served SPA can discover the endpoint via {@link connectDevframe}.
|
|
20
|
-
*
|
|
21
|
-
* The bridge **gates by default** (devframe's interactive OTP unless the
|
|
22
|
-
* definition's `cli.auth` opts out), printing its code/link banner to stdout,
|
|
23
|
-
* so a bridged devframe isn't silently reachable by anything that can open
|
|
24
|
-
* its socket. Pass `options.auth: false` to opt out for a single-user
|
|
25
|
-
* localhost host, or a {@link DevframeAuthHandler} for a custom scheme.
|
|
26
|
-
*
|
|
27
|
-
* Use bridge mode when integrating with frameworks that own the SPA
|
|
28
|
-
* (Nuxt, Astro, SolidStart, plain Vite apps). For the all-in-one
|
|
29
|
-
* `dev` / `build` / `mcp` shell, reach for {@link createCac} instead.
|
|
30
|
-
*/
|
|
31
|
-
function viteDevBridge(d, options = {}) {
|
|
32
|
-
const base = normalizeMountBase(options.base ?? resolveBasePath(d, "hosted"));
|
|
33
|
-
if (!options.devMiddleware) {
|
|
34
|
-
const distDir = d.cli?.distDir;
|
|
35
|
-
return {
|
|
36
|
-
name: `devframe:${d.id}`,
|
|
37
|
-
apply: "serve",
|
|
38
|
-
configureServer(server) {
|
|
39
|
-
if (!distDir) return;
|
|
40
|
-
server.middlewares.use(base, serveStaticNodeMiddleware(resolve(distDir)));
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
const mw = options.devMiddleware === true ? {} : options.devMiddleware;
|
|
45
|
-
let instance;
|
|
46
|
-
return {
|
|
47
|
-
name: `devframe:${d.id}`,
|
|
48
|
-
apply: "serve",
|
|
49
|
-
async configureServer(server) {
|
|
50
|
-
await instance?.close().catch(() => {});
|
|
51
|
-
instance = void 0;
|
|
52
|
-
try {
|
|
53
|
-
const created = initDevframe(d, {
|
|
54
|
-
base,
|
|
55
|
-
distDir: false,
|
|
56
|
-
flags: mw.flags,
|
|
57
|
-
host: mw.host,
|
|
58
|
-
...mw.port != null ? { ws: { port: mw.port } } : server.httpServer ? { server: server.httpServer } : { ws: { sidecar: true } },
|
|
59
|
-
auth: options.auth,
|
|
60
|
-
mcp: options.mcp
|
|
61
|
-
});
|
|
62
|
-
server.middlewares.use(created.nodeMiddleware);
|
|
63
|
-
await created.ready;
|
|
64
|
-
instance = created;
|
|
65
|
-
} catch (e) {
|
|
66
|
-
diagnostics.DF0033({
|
|
67
|
-
id: d.id,
|
|
68
|
-
reason: String(e),
|
|
69
|
-
cause: e
|
|
70
|
-
}, { method: "warn" });
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
server.httpServer?.once("close", () => {
|
|
74
|
-
instance?.close().catch(() => {});
|
|
75
|
-
});
|
|
76
|
-
},
|
|
77
|
-
async closeBundle() {
|
|
78
|
-
await instance?.close().catch(() => {});
|
|
79
|
-
instance = void 0;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Make `base` safe for `server.middlewares.use(path, …)`. Vite's connect
|
|
85
|
-
* router matches by absolute URL prefix, so relative spellings like
|
|
86
|
-
* `'./'` (commonly used for base-agnostic Nuxt builds) collapse to the
|
|
87
|
-
* origin root before the shared leading/trailing-slash normalization.
|
|
88
|
-
*/
|
|
89
|
-
function normalizeMountBase(base) {
|
|
90
|
-
return normalizeBasePath(base.replace(/^\.\/?/, "/"));
|
|
91
|
-
}
|
|
92
|
-
//#endregion
|
|
93
|
-
export { viteDevBridge };
|