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.
Files changed (104) hide show
  1. package/dist/{_shared-DmpWW-HH.d.mts → _shared-BPmX9fqK.d.mts} +2 -4
  2. package/dist/{_shared-CttmCMBi.mjs → _shared-CbZ_yhbz.mjs} +2 -4
  3. package/dist/adapters/build.d.mts +10 -12
  4. package/dist/adapters/build.mjs +26 -30
  5. package/dist/adapters/cac.d.mts +1 -1
  6. package/dist/adapters/cac.mjs +6 -7
  7. package/dist/adapters/dev.d.mts +22 -8
  8. package/dist/adapters/dev.mjs +2 -2
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +5 -4
  11. package/dist/adapters/initiate.mjs +1 -1
  12. package/dist/adapters/mcp.d.mts +1 -8
  13. package/dist/adapters/mcp.mjs +1 -1
  14. package/dist/{agent-tool-name-C3b5vEwJ.mjs → agent-tool-name-EgfoFO8C.mjs} +0 -3
  15. package/dist/cli/main.d.mts +0 -2
  16. package/dist/cli/main.mjs +4 -8
  17. package/dist/client/index.d.mts +5 -5
  18. package/dist/client/index.mjs +24 -1179
  19. package/dist/constants.d.mts +10 -2
  20. package/dist/constants.mjs +10 -2
  21. package/dist/{context-CSCwoABx.d.mts → context-B3YUu_95.d.mts} +19 -1
  22. package/dist/{context-Du11TLcO.mjs → context-CEe4PBz1.mjs} +23 -305
  23. package/dist/{context-C33rR7n0.mjs → context-xdynGSLP.mjs} +10 -1
  24. package/dist/{dev-BEveeA5H.mjs → dev--rAPzbvO.mjs} +16 -10
  25. package/dist/{devframe-Bdd9YXTy.d.mts → devframe-DJMg0WLe.d.mts} +97 -113
  26. package/dist/{diagnostics-hwjXp_UV.mjs → diagnostics-CD8nlgll.mjs} +1 -3
  27. package/dist/{diagnostics-DLYH5oD3.mjs → diagnostics-DOQPnQmX.mjs} +35 -5
  28. package/dist/{dist-D8jAMwxU.mjs → dist-eNI9qM_I.mjs} +1 -0
  29. package/dist/{host-agent-CpbAoqBx.mjs → host-agent-xLCSe65D.mjs} +41 -7
  30. package/dist/{host-h3-CzCZwtuV.mjs → host-h3-Crkzm42q.mjs} +2 -2
  31. package/dist/{http-DLr_cJZ7.mjs → http-DYpK0cUi.mjs} +5 -12
  32. package/dist/{index-CZRd2K1C.d.mts → index-CB-fSUyn.d.mts} +2 -2
  33. package/dist/{index-DSCq4M4q.d.mts → index-tdrk1bzV.d.mts} +1 -1
  34. package/dist/index.d.mts +7 -5
  35. package/dist/{instance-registry-BQqGoDO9.mjs → instance-registry-WvQkt42E.mjs} +1 -7
  36. package/dist/{instance-shell-KRdee1QF.mjs → instance-shell-CMFyszWJ.mjs} +9 -8
  37. package/dist/{instance-shell-DBTXTSjN.d.mts → instance-shell-CljiKq1c.d.mts} +3 -12
  38. package/dist/internal/index.d.mts +265 -18
  39. package/dist/internal/index.mjs +9 -7
  40. package/dist/node/auth.d.mts +2 -2
  41. package/dist/node/auth.mjs +1 -1
  42. package/dist/node/hub-internals.d.mts +2 -2
  43. package/dist/node/hub-internals.mjs +2 -2
  44. package/dist/node/index.d.mts +3 -3
  45. package/dist/node/index.mjs +2 -2
  46. package/dist/nostics-CzECRXpE.mjs +59 -0
  47. package/dist/nostics-SPGDgHEP.d.mts +33 -0
  48. package/dist/recipes/common-rpc-functions.d.mts +3 -3
  49. package/dist/recipes/interactive-auth.d.mts +2 -2
  50. package/dist/recipes/interactive-auth.mjs +3 -3
  51. package/dist/remote-assets-Bg4gCUZ_.d.mts +123 -0
  52. package/dist/remote-assets-nTTxY2MU.mjs +636 -0
  53. package/dist/rpc/dump.d.mts +1 -1
  54. package/dist/rpc/dump.mjs +1 -1
  55. package/dist/rpc/index.d.mts +2 -2
  56. package/dist/rpc/index.mjs +3 -3
  57. package/dist/rpc/transports/sse-client.d.mts +1 -1
  58. package/dist/rpc/transports/sse-client.mjs +1 -1
  59. package/dist/rpc/transports/sse-server.d.mts +2 -2
  60. package/dist/rpc/transports/sse-server.mjs +2 -2
  61. package/dist/rpc/transports/ws-bun.d.mts +2 -2
  62. package/dist/rpc/transports/ws-bun.mjs +1 -1
  63. package/dist/rpc/transports/ws-client.d.mts +1 -1
  64. package/dist/rpc/transports/ws-client.mjs +1 -1
  65. package/dist/rpc/transports/ws-server.d.mts +1 -1
  66. package/dist/rpc/transports/ws-server.mjs +1 -1
  67. package/dist/{rpc-core-CGctXToO.d.mts → rpc-core-Cc4lucI0.d.mts} +3 -3
  68. package/dist/{rpc-core-CqcJkAu9.mjs → rpc-core-DMTe-hLo.mjs} +1 -1
  69. package/dist/{serialization-BHY8M5NQ.mjs → serialization-BGzEwAdr.mjs} +1 -1
  70. package/dist/{sse-client-BsIK3hMD.d.mts → sse-client-CFBOIaUi.d.mts} +1 -1
  71. package/dist/state-Cc1IeSmQ.mjs +1291 -0
  72. package/dist/{static-CvjkO8QE.mjs → static-BPZ1_OPA.mjs} +2 -2
  73. package/dist/storage-CYye7P7L.mjs +137 -0
  74. package/dist/types/index.d.mts +6 -4
  75. package/dist/{types-CnJSgRVa.d.mts → types-Djq7CBXh.d.mts} +0 -7
  76. package/dist/utils/agent-tool-name.d.mts +0 -3
  77. package/dist/utils/agent-tool-name.mjs +0 -3
  78. package/dist/utils/events.d.mts +1 -1
  79. package/dist/utils/get-port.d.mts +17 -0
  80. package/dist/utils/get-port.mjs +2 -0
  81. package/dist/utils/nostics.d.mts +2 -0
  82. package/dist/utils/nostics.mjs +2 -0
  83. package/dist/utils/open.d.mts +2 -10
  84. package/dist/utils/open.mjs +56 -1
  85. package/dist/utils/remote-assets.d.mts +15 -0
  86. package/dist/utils/remote-assets.mjs +2 -0
  87. package/dist/utils/serve-static.d.mts +13 -5
  88. package/dist/utils/serve-static.mjs +119 -9
  89. package/dist/utils/shared-state.d.mts +1 -1
  90. package/dist/utils/streaming-channel.d.mts +1 -1
  91. package/dist/{validation-BiuDXTKW.mjs → validation-CpXFB6Dz.mjs} +1 -1
  92. package/dist/{wire-codec-9VhIKnyp.mjs → wire-codec-0K-o5MYW.mjs} +1 -3
  93. package/dist/{ws-client-CdNuATYa.d.mts → ws-client-DhjNyQo3.d.mts} +1 -1
  94. package/dist/{ws-server-Bk1hOG3X.mjs → ws-server-BdSLrhxE.mjs} +1 -1
  95. package/dist/{ws-server-Ces08fjP.d.mts → ws-server-D1d3QM9f.d.mts} +1 -1
  96. package/package.json +4 -4
  97. package/skills/devframe/SKILL.md +10 -11
  98. package/dist/diagnostics-reporter-CsIG85Q5.mjs +0 -38
  99. package/dist/helpers/vite.d.mts +0 -104
  100. package/dist/helpers/vite.mjs +0 -93
  101. package/dist/open-Dz4V4irZ.mjs +0 -547
  102. package/dist/state-BeUHDDjk.mjs +0 -108
  103. package/dist/storage-BcmVEJRc.mjs +0 -1122
  104. 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.1",
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",
@@ -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 / spa / vite / embedded / mcp), designing RPC
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` *(experimental)* |
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), `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.
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, `templates/spa-devframe.ts` for an SPA-ready shape, and `templates/vite-client.ts` for the author's client entry.
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 (experimental) |
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 (experimental)
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 / spa output) - read-only, resolves calls from the baked RPC dump.
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 four subcommands out of the box:
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
- | `spa` | Deployable SPA → `./dist-spa/` |
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`, `viteDevBridge`/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.
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 };
@@ -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 };
@@ -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 };