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
@@ -1,10 +1,11 @@
1
- import { d as RpcFunctionsCollectorBase } from "./index-DSCq4M4q.mjs";
2
- import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-CnJSgRVa.mjs";
3
- import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "./ws-server-Ces08fjP.mjs";
1
+ import { d as RpcFunctionsCollectorBase } from "./index-tdrk1bzV.mjs";
2
+ import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-Djq7CBXh.mjs";
3
+ import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "./ws-server-D1d3QM9f.mjs";
4
+ import { m as defineDiagnostics } from "./nostics-SPGDgHEP.mjs";
5
+ import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-Bg4gCUZ_.mjs";
4
6
  import { CAC } from "cac";
5
7
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
8
  import { BirpcReturn } from "birpc";
7
- import { Diagnostic, DiagnosticDefinition, defineDiagnostics } from "nostics";
8
9
  //#region src/adapters/flags.d.ts
9
10
  /**
10
11
  * Schema map for typed CLI flags. Keys are flag names in camelCase —
@@ -119,9 +120,6 @@ interface EventEmitter<Events extends EventsMap> {
119
120
  * Serializable description of an agent-exposed tool. This is the shape
120
121
  * returned by the agent host manifest and surfaced over the wire by
121
122
  * the `devframe:agent:list-tools` introspection RPC.
122
- *
123
- * @experimental The agent-native surface is experimental and may change
124
- * without a major version bump until it stabilizes.
125
123
  */
126
124
  interface AgentTool {
127
125
  /** Stable identifier. For RPC-backed tools, matches the RPC name. */
@@ -159,8 +157,6 @@ interface AgentTool {
159
157
  /**
160
158
  * Input accepted by `DevframeAgentHost.registerTool()`. Handler is
161
159
  * stripped from the serializable `AgentTool` projection.
162
- *
163
- * @experimental
164
160
  */
165
161
  interface AgentToolInput {
166
162
  id: string;
@@ -191,8 +187,6 @@ interface AgentToolInput {
191
187
  /**
192
188
  * Serializable description of an agent-readable resource. Resources
193
189
  * surface structured or textual snapshots of devframe state.
194
- *
195
- * @experimental
196
190
  */
197
191
  interface AgentResource {
198
192
  id: string;
@@ -205,8 +199,6 @@ interface AgentResource {
205
199
  }
206
200
  /**
207
201
  * Input accepted by `DevframeAgentHost.registerResource()`.
208
- *
209
- * @experimental
210
202
  */
211
203
  interface AgentResourceInput {
212
204
  id: string;
@@ -220,8 +212,6 @@ interface AgentResourceInput {
220
212
  }
221
213
  /**
222
214
  * Payload returned by `AgentResourceInput.read`. Either `text` or `json` must be set.
223
- *
224
- * @experimental
225
215
  */
226
216
  interface AgentResourceContent {
227
217
  text?: string;
@@ -231,8 +221,6 @@ interface AgentResourceContent {
231
221
  }
232
222
  /**
233
223
  * Unified view of the agent-exposed surface.
234
- *
235
- * @experimental
236
224
  */
237
225
  interface AgentManifest {
238
226
  tools: readonly AgentTool[];
@@ -240,8 +228,6 @@ interface AgentManifest {
240
228
  }
241
229
  /**
242
230
  * Handle returned by `registerTool` / `registerResource`.
243
- *
244
- * @experimental
245
231
  */
246
232
  interface AgentHandle {
247
233
  unregister: () => void;
@@ -256,14 +242,10 @@ interface AgentHandle {
256
242
  * Providers should namespace tool ids like any other tool; on an id
257
243
  * collision the earlier source wins (registered tools, then RPC tools,
258
244
  * then providers in registration order).
259
- *
260
- * @experimental
261
245
  */
262
246
  type AgentToolProvider = () => readonly AgentToolInput[];
263
247
  /**
264
248
  * Handle returned by `registerToolProvider`.
265
- *
266
- * @experimental
267
249
  */
268
250
  interface AgentToolProviderHandle extends AgentHandle {
269
251
  /**
@@ -275,8 +257,6 @@ interface AgentToolProviderHandle extends AgentHandle {
275
257
  }
276
258
  /**
277
259
  * Events emitted by `DevframeAgentHost`.
278
- *
279
- * @experimental
280
260
  */
281
261
  interface DevframeAgentHostEvents {
282
262
  'agent:tool:registered': (tool: AgentTool) => void;
@@ -294,9 +274,6 @@ interface DevframeAgentHostEvents {
294
274
  * RPC functions flagged with `agent` and plugin-registered tools /
295
275
  * resources. Consumed by protocol adapters such as the devframe MCP
296
276
  * adapter.
297
- *
298
- * @experimental The agent-native surface is experimental and may change
299
- * without a major version bump until it stabilizes.
300
277
  */
301
278
  interface DevframeAgentHost {
302
279
  readonly events: EventEmitter<DevframeAgentHostEvents>;
@@ -859,14 +836,6 @@ interface RpcStreamingHost {
859
836
  }
860
837
  //#endregion
861
838
  //#region src/types/diagnostics.d.ts
862
- /**
863
- * A diagnostics definition object built with `defineDiagnostics`. Typed as
864
- * `unknown` because each integration's definition has a distinct narrow shape
865
- * (e.g. specific code keys like `DF0001` / `MYP0001`), and TypeScript's mapped
866
- * types don't allow assigning a narrow-keyed result to a generically-keyed
867
- * one. The host stores them in a heterogeneous registry.
868
- */
869
- type DevframeDiagnosticsDefinition = ReturnType<typeof defineDiagnostics<any, any>>;
870
839
  /**
871
840
  * The shared diagnostics lookup exposed by the host. A `Proxy` that resolves
872
841
  * any registered code name to its `nostics` handle (a callable that builds
@@ -875,16 +844,6 @@ type DevframeDiagnosticsDefinition = ReturnType<typeof defineDiagnostics<any, an
875
844
  * integrations.
876
845
  */
877
846
  type DevframeDiagnosticsLogger = Record<string, any>;
878
- /**
879
- * Options accepted by the host's `defineDiagnostics()` factory — mirrors
880
- * `nostics`'s shape but the host pre-wires its ANSI console reporter, so
881
- * plugins typically omit `reporters`.
882
- */
883
- interface DevframeDefineDiagnosticsOptions<Codes extends Record<string, DiagnosticDefinition>> {
884
- docsBase?: string | ((code: keyof Codes) => string | undefined);
885
- codes: Codes;
886
- reporters?: ReadonlyArray<(d: Diagnostic, o?: any) => void>;
887
- }
888
847
  /**
889
848
  * Host for structured diagnostics — a thin layer over `nostics` that lets
890
849
  * integrations register their own coded errors/warnings into a shared
@@ -927,21 +886,25 @@ interface DevframeDiagnosticsHost {
927
886
  register: (definitions: Record<string, unknown>) => void;
928
887
  /**
929
888
  * Build a typed diagnostics object with the host's ANSI console reporter
930
- * pre-wired. Mirrors `nostics`'s `defineDiagnostics` so integrations don't
931
- * need to take a direct dependency on `nostics`.
889
+ * pre-wired. The same `devframe/utils/nostics` `defineDiagnostics` every
890
+ * built-in plugin's module-level `diagnostics.ts` uses, so integrations
891
+ * don't need to take a direct dependency on `nostics`.
932
892
  */
933
- defineDiagnostics: <const Codes extends Record<string, DiagnosticDefinition>>(options: DevframeDefineDiagnosticsOptions<Codes>) => ReturnType<typeof defineDiagnostics<Codes, any>>;
893
+ defineDiagnostics: typeof defineDiagnostics;
934
894
  }
935
895
  //#endregion
936
896
  //#region src/types/host.d.ts
937
897
  interface DevframeHost {
938
898
  /**
939
- * Serve a static directory at the given URL base. Called by
940
- * `DevframeViewHost.hostStatic`. Implementations map this to whatever
899
+ * Serve static assets at the given URL base — a local directory, or a
900
+ * resolved {@link RemoteAssetsStore} back-proxy. Called by
901
+ * `DevframeViewHost.hostStatic` (which normalizes `RemoteAssets`
902
+ * declarations into stores first). Implementations map this to whatever
941
903
  * the underlying runtime expects (Vite middleware, h3 handler, no-op
942
- * for build snapshots).
904
+ * for build snapshots) — the shared engine in
905
+ * `devframe/utils/serve-static` accepts either shape.
943
906
  */
944
- mountStatic: (base: string, distDir: string) => void | Promise<void>;
907
+ mountStatic: (base: string, source: string | RemoteAssetsStore) => void | Promise<void>;
945
908
  /**
946
909
  * Serve the host's connection meta (`__connection.json`) at the given URL
947
910
  * base, so a devframe SPA mounted there can discover the RPC/WS endpoint
@@ -1006,14 +969,17 @@ interface DevframeViewHost {
1006
969
  */
1007
970
  buildStaticDirs: {
1008
971
  baseUrl: string;
1009
- distDir: string;
972
+ source: StaticAssetsSource;
1010
973
  }[];
1011
974
  /**
1012
975
  * Helper to host static files
1013
976
  * - In `dev` mode, it will register middleware to `viteServer.middlewares` to host the static files
1014
977
  * - In `build` mode, it will copy the static files to the dist directory
978
+ *
979
+ * Accepts a local dist directory, or a {@link StaticAssetsSource} remote
980
+ * declaration served through devframe's caching CDN back-proxy.
1015
981
  */
1016
- hostStatic: (baseUrl: string, distDir: string) => void;
982
+ hostStatic: (baseUrl: string, source: StaticAssetsSource) => void;
1017
983
  }
1018
984
  //#endregion
1019
985
  //#region src/types/scope.d.ts
@@ -1303,8 +1269,6 @@ interface DevframeNodeContext {
1303
1269
  diagnostics: DevframeDiagnosticsHost;
1304
1270
  /**
1305
1271
  * Agent host — aggregates the agent-exposed surface of this devtool.
1306
- *
1307
- * @experimental
1308
1272
  */
1309
1273
  agent: DevframeAgentHost;
1310
1274
  /**
@@ -1316,6 +1280,22 @@ interface DevframeNodeContext {
1316
1280
  * absorb setup-order differences between provider and consumer.
1317
1281
  */
1318
1282
  services: DevframeServicesHost;
1283
+ /**
1284
+ * This context's own {@link ConnectionMeta.configs} — static, boot-time
1285
+ * config a host publishes once through the connection handshake and every
1286
+ * client reads read-only. A plain, **non-reactive** object: mutate it
1287
+ * during `setup(ctx)` (a plugin sets its keys, a hub aggregates across
1288
+ * every installed devframe), never during the session — it's serialized
1289
+ * once, after setup, and changing it afterwards reaches no client.
1290
+ *
1291
+ * ```ts
1292
+ * ctx.staticConfig.dock = {
1293
+ * ...ctx.staticConfig.dock,
1294
+ * categoryOrder: { ...ctx.staticConfig.dock?.categoryOrder, ...myOrder },
1295
+ * }
1296
+ * ```
1297
+ */
1298
+ staticConfig: Partial<DevframeConnectionConfigsRegistry>;
1319
1299
  /**
1320
1300
  * Create a namespace-scoped view of this context. The returned
1321
1301
  * `ctx.scope('my-plugin')` auto-namespaces every RPC id, shared-state
@@ -1406,7 +1386,7 @@ interface ConnectionMeta {
1406
1386
  * tooling (e.g. an MCP inspector) can discover it without guessing the
1407
1387
  * path. `path` is relative to `__connection.json`'s location, like the
1408
1388
  * WebSocket `path`. `port` is set when the endpoint lives on a side-car
1409
- * server on its own port (bridge mode — `viteDevBridge`,
1389
+ * server on its own port (bridge mode — `devframeViteBridge`,
1410
1390
  * `@devframes/next`): the client combines the page hostname with `port`
1411
1391
  * and resolves `path` against that origin, mirroring
1412
1392
  * {@link ConnectionMetaWebsocket.port}.
@@ -1457,16 +1437,38 @@ interface ConnectionMeta {
1457
1437
  * token same-origin until the requesting origin has been verified.
1458
1438
  */
1459
1439
  viewerOriginToken?: string;
1440
+ /**
1441
+ * Static, host-declared configuration — baked in once at connect time and
1442
+ * fixed for the life of the server (e.g. a hub's UI rebrand, or its
1443
+ * aggregated dock-bar layout preferences). Read-only from the browser: a
1444
+ * client only ever reads `rpc.connectionMeta.configs`, never writes to it.
1445
+ *
1446
+ * Contrast this with {@link DevframeSettingsRegistry} (`ctx.scope(ns).settings`)
1447
+ * and a hub's `devframe:user-settings` shared-state key — both are
1448
+ * mutable, user-editable, and synced bidirectionally over RPC for the
1449
+ * life of the session. `configs` is the opposite: one-way, immutable,
1450
+ * decided by whoever assembled the server.
1451
+ *
1452
+ * Each key is owned by one package, contributed via declaration merging:
1453
+ *
1454
+ * ```ts
1455
+ * declare module 'devframe/types' {
1456
+ * interface DevframeConnectionConfigsRegistry {
1457
+ * 'my-key': { some: 'shape' }
1458
+ * }
1459
+ * }
1460
+ * ```
1461
+ */
1462
+ configs?: Partial<DevframeConnectionConfigsRegistry>;
1460
1463
  }
1461
- //#endregion
1462
- //#region src/types/utils.d.ts
1463
- type Thenable<T> = T | Promise<T>;
1464
- type EntriesToObject<T extends readonly [string, any][]> = { [K in T[number] as K[0]]: K[1]; };
1465
- type PartialWithoutId<T extends {
1466
- id: string;
1467
- }> = Partial<Omit<T, 'id'>> & {
1468
- id: string;
1469
- };
1464
+ /**
1465
+ * Augmentation point for {@link ConnectionMeta.configs}. Empty by default —
1466
+ * a package that wants to publish static, boot-time config through the
1467
+ * connection handshake augments this interface with its own key (see
1468
+ * {@link ConnectionMeta.configs} for the pattern). `@devframes/hub`
1469
+ * augments it with `dock`; `@devframes/hub-ui` augments it with `ui`.
1470
+ */
1471
+ interface DevframeConnectionConfigsRegistry {}
1470
1472
  //#endregion
1471
1473
  //#region src/node/auth/handler.d.ts
1472
1474
  /**
@@ -1519,12 +1521,11 @@ interface DevframeAuthHandler {
1519
1521
  }
1520
1522
  //#endregion
1521
1523
  //#region src/types/devframe.d.ts
1522
- type DevframeRuntime = 'cli' | 'build' | 'spa' | 'vite' | 'embedded';
1523
1524
  /**
1524
1525
  * Classification of how a devframe is being deployed. Hosted adapters
1525
1526
  * (`vite`, `embedded`) share their origin with a host app and must
1526
1527
  * namespace their mount path under `/__<id>/`. Standalone adapters
1527
- * (`cli`, `spa`, `build`) own the origin and default to `/`.
1528
+ * (`cli`, `build`) own the origin and default to `/`.
1528
1529
  */
1529
1530
  type DevframeDeploymentKind = 'standalone' | 'hosted';
1530
1531
  /**
@@ -1601,9 +1602,6 @@ interface DevframeSseOptions {
1601
1602
  * the MCP Streamable-HTTP transport over the same origin as the SPA,
1602
1603
  * exposing the definition's `ctx.agent` tools + shared-state resources to
1603
1604
  * external MCP clients connected to the *running* server.
1604
- *
1605
- * @experimental The agent-native surface is experimental and may change
1606
- * without a major version bump until it stabilizes.
1607
1605
  */
1608
1606
  interface McpRouteOptions {
1609
1607
  /**
@@ -1645,7 +1643,7 @@ interface DevframeCliOptions {
1645
1643
  /**
1646
1644
  * Authentication for the standalone dev server.
1647
1645
  *
1648
- * - `undefined` / `true` — the standalone adapters (`cli` / `spa` /
1646
+ * - `undefined` / `true` — the standalone adapters (`cli` /
1649
1647
  * served `build`) auto-wire devframe's interactive OTP auth
1650
1648
  * (`createInteractiveAuth`): an untrusted client can only reach
1651
1649
  * `anonymous:` methods until it exchanges the printed one-time code.
@@ -1676,12 +1674,15 @@ interface DevframeCliOptions {
1676
1674
  * - {@link McpRouteOptions} — customise the route path / allowed origins.
1677
1675
  *
1678
1676
  * The `--mcp` / `--no-mcp` CLI flags override this per run.
1679
- *
1680
- * @experimental
1681
1677
  */
1682
1678
  mcp?: boolean | McpRouteOptions;
1683
- /** Author's SPA dist directory (served as the devframe's UI). */
1684
- distDir?: string;
1679
+ /**
1680
+ * Author's SPA dist — served as the devframe's UI. A local directory, or
1681
+ * a {@link StaticAssetsSource} remote declaration (`{ package, version }`)
1682
+ * served through devframe's caching CDN back-proxy so the assets need not
1683
+ * ship inside the node package.
1684
+ */
1685
+ distDir?: StaticAssetsSource;
1685
1686
  /**
1686
1687
  * How the browser reaches the RPC WebSocket. Defaults to sharing the HTTP
1687
1688
  * port on the `__ws` route. See {@link DevframeWsOptions} for the
@@ -1697,7 +1698,7 @@ interface DevframeCliOptions {
1697
1698
  sse?: boolean | DevframeSseOptions;
1698
1699
  /**
1699
1700
  * Capability-side CAC hook. Called with the CAC instance after the
1700
- * adapter registers its built-in commands (`build` / `spa` / `mcp`)
1701
+ * adapter registers its built-in commands (`build` / `mcp`)
1701
1702
  * but before `createCac`'s own `configureCli` caller. Use this to
1702
1703
  * contribute tool-specific flags and subcommands from the definition
1703
1704
  * itself.
@@ -1738,7 +1739,7 @@ interface DevframeCliOptions {
1738
1739
  *
1739
1740
  * Every field is optional. `title` / `icon` default to the definition's
1740
1741
  * `name` / `icon` when omitted here; the rest are unset by default.
1741
- * Standalone adapters (`cli` / `spa` / `build`) ignore this entirely.
1742
+ * Standalone adapters (`cli` / `build`) ignore this entirely.
1742
1743
  */
1743
1744
  interface DevframeDockDefaults {
1744
1745
  /** Dock entry title. Defaults to the definition's `name`. */
@@ -1775,22 +1776,6 @@ interface DevframeDockDefaults {
1775
1776
  /** Id of the dock group this entry collapses under, if any. */
1776
1777
  groupId?: string;
1777
1778
  }
1778
- interface DevframeSpaOptions {
1779
- base?: string;
1780
- /**
1781
- * How the deployed SPA loads its data.
1782
- * - `'query'` — read from URL search params.
1783
- * - `'upload'` — accept a file drag-drop.
1784
- * - `'none'` — use the baked RPC dump only.
1785
- */
1786
- loader?: 'query' | 'upload' | 'none';
1787
- }
1788
- interface DevframeBrowserContext {
1789
- /**
1790
- * The connected RPC client (may be write-disabled in static/spa modes).
1791
- */
1792
- rpc: unknown;
1793
- }
1794
1779
  /**
1795
1780
  * Runtime information threaded into `setup(ctx, info)`. Adapters
1796
1781
  * populate the fields that make sense for their deployment. In
@@ -1819,47 +1804,46 @@ interface DevframeDefinition {
1819
1804
  * Default dock attributes applied when a hub mounts this devframe as an
1820
1805
  * iframe dock entry. Consulted only by the hub install path (`ctx.install`),
1821
1806
  * which merge these beneath the per-mount `dock` overrides; standalone
1822
- * adapters (`cli` / `spa` / `build`) ignore it.
1807
+ * adapters (`cli` / `build`) ignore it.
1823
1808
  *
1824
1809
  * @see {@link DevframeDockDefaults}
1825
1810
  */
1826
1811
  dock?: DevframeDockDefaults;
1827
1812
  /**
1828
1813
  * Mount path override. Defaults depend on the adapter:
1829
- * `/` for standalone (`cli` / `spa` / `build`), `/__<id>/` for hosted
1814
+ * `/` for standalone (`cli` / `build`), `/__<id>/` for hosted
1830
1815
  * (`vite` / `embedded`).
1831
1816
  */
1832
1817
  basePath?: string;
1833
1818
  /**
1834
1819
  * How a hub reacts when another devframe sharing this one's `id` is
1835
1820
  * mounted onto the same hub. Consulted only by hub adapters
1836
- * (`ctx.install`); standalone adapters (`cli` / `spa` / `build`)
1821
+ * (`ctx.install`); standalone adapters (`cli` / `build`)
1837
1822
  * ignore it.
1838
1823
  *
1839
1824
  * @default 'warn'
1840
1825
  */
1841
1826
  duplicationStrategy?: DevframeDuplicationStrategy;
1842
1827
  /**
1843
- * Declares which runtimes meaningfully support this devframe. Consulted
1844
- * by adapters that can act on a plain `false` before doing any work:
1845
- * `createCac` skips registering the `build` subcommand entirely when
1846
- * `capabilities.build` is `false` — useful for a devframe whose value is
1847
- * inherently live (e.g. it manages real files on disk), so a static
1848
- * export would only ever produce a broken, write-less shell of the tool.
1849
- * The `Record<string, boolean>` shape is reserved for finer-grained
1850
- * sub-capabilities and currently unconsumed by any adapter.
1828
+ * Declares which runtimes meaningfully support this devframe. Adapters
1829
+ * act on a `false` before doing any work:
1830
+ *
1831
+ * - `build: false` — `createCac` skips registering the `build` subcommand,
1832
+ * and `createBuild` refuses (throws `DF0042`) unless `{ force: true }`.
1833
+ * Useful for a devframe whose value is inherently live (e.g. it manages
1834
+ * real files on disk), so a static export would only ever produce a
1835
+ * broken, write-less shell of the tool.
1836
+ * - `dev: false` — `createDevServer` refuses (throws `DF0058`) unless
1837
+ * `{ force: true }`. Useful for a devframe that only makes sense as a
1838
+ * static export (e.g. a report generator with nothing to serve live).
1851
1839
  */
1852
1840
  capabilities?: {
1853
- dev?: boolean | Record<string, boolean>;
1854
- build?: boolean | Record<string, boolean>;
1855
- spa?: boolean | Record<string, boolean>;
1841
+ dev?: boolean;
1842
+ build?: boolean;
1856
1843
  };
1857
1844
  /** Server-side setup — the primary entrypoint. Runs in every runtime. */
1858
1845
  setup: (ctx: DevframeNodeContext, info?: DevframeSetupInfo) => void | Promise<void>;
1859
- /** Browser-only setup for the SPA adapter (bundled into the client). */
1860
- setupBrowser?: (ctx: DevframeBrowserContext) => void | Promise<void>;
1861
1846
  cli?: DevframeCliOptions;
1862
- spa?: DevframeSpaOptions;
1863
1847
  }
1864
1848
  //#endregion
1865
- export { DevframeRpcClientFunctions as $, DevframeSettingsRegistry as A, DevframeAgentHost as At, DevframeStorageScope as B, DevframeServiceOf as C, AgentResource as Ct, DevframeScopedNodeRpc as D, AgentToolInput as Dt, DevframeScopedNodeContext as E, AgentTool as Et, ScopedServerFunctions as F, CliFlagsSchema as Ft, DevframeNodeRpcSession as G, DevframeDiagnosticsDefinition as H, ScopedSharedStates as I, InferCliFlags as It, RpcSharedStateGetOptions as J, RpcBroadcastOptions as K, SettingsForNamespace as L, defineCliFlags as Lt, ScopedBroadcastOptions as M, EventEmitter as Mt, ScopedClientFunctions as N, EventUnsubscribe as Nt, DevframeScopedStreamingHost as O, AgentToolProvider as Ot, ScopedRpcFn as P, EventsMap as Pt, RpcStreamingHost as Q, DevframeViewHost as R, parseCliFlags as Rt, DevframeServiceId as S, AgentManifest as St, DevframeServicesRegistry as T, AgentResourceInput as Tt, DevframeDiagnosticsHost as U, DevframeDefineDiagnosticsOptions as V, DevframeDiagnosticsLogger as W, RpcStreamingChannel as X, RpcSharedStateHost as Y, RpcStreamingChannelOptions as Z, ConnectionMeta as _, SharedStateEvents as _t, DevframeDockDefaults as a, StreamErrorPayload as at, DevframeCapabilities as b, createSharedState as bt, DevframeSetupInfo as c, StreamSinkEvents as ct, DevframeWsOptions as d, Immutable as dt, DevframeRpcServerFunctions as et, McpRouteOptions as f, ImmutableArray as ft, Thenable as g, SharedState as gt, PartialWithoutId as h, ImmutableSet as ht, DevframeDeploymentKind as i, CreateStreamSinkOptions as it, DevframeSettingsStore as j, DevframeAgentHostEvents as jt, DevframeSettings as k, AgentToolProviderHandle as kt, DevframeSpaOptions as l, createStreamReader as lt, EntriesToObject as m, ImmutableObject as mt, DevframeCliOptions as n, BufferedChunk as nt, DevframeDuplicationStrategy as o, StreamReader as ot, DevframeAuthHandler as p, ImmutableMap as pt, RpcFunctionsHost as q, DevframeDefinition as r, CreateStreamReaderOptions as rt, DevframeRuntime as s, StreamSink as st, DevframeBrowserContext as t, DevframeRpcSharedStates as tt, DevframeSseOptions as u, createStreamSink as ut, ConnectionMetaSse as v, SharedStateOptions as vt, DevframeServicesHost as w, AgentResourceContent as wt, DevframeNodeContext as x, AgentHandle as xt, ConnectionMetaWebsocket as y, SharedStatePatch as yt, DevframeHost as z };
1849
+ export { StreamReader as $, ScopedServerFunctions as A, defineCliFlags as At, RpcFunctionsHost as B, DevframeScopedStreamingHost as C, DevframeAgentHost as Ct, ScopedBroadcastOptions as D, EventsMap as Dt, DevframeSettingsStore as E, EventUnsubscribe as Et, DevframeStorageScope as F, RpcStreamingHost as G, RpcSharedStateHost as H, DevframeDiagnosticsHost as I, DevframeRpcSharedStates as J, DevframeRpcClientFunctions as K, DevframeDiagnosticsLogger as L, SettingsForNamespace as M, DevframeViewHost as N, ScopedClientFunctions as O, CliFlagsSchema as Ot, DevframeHost as P, StreamErrorPayload as Q, DevframeNodeRpcSession as R, DevframeScopedNodeRpc as S, AgentToolProviderHandle as St, DevframeSettingsRegistry as T, EventEmitter as Tt, RpcStreamingChannel as U, RpcSharedStateGetOptions as V, RpcStreamingChannelOptions as W, CreateStreamReaderOptions as X, BufferedChunk as Y, CreateStreamSinkOptions as Z, DevframeServiceId as _, AgentResourceContent as _t, DevframeDuplicationStrategy as a, ImmutableArray as at, DevframeServicesRegistry as b, AgentToolInput as bt, DevframeWsOptions as c, ImmutableSet as ct, ConnectionMeta as d, SharedStateOptions as dt, StreamSink as et, ConnectionMetaSse as f, SharedStatePatch as ft, DevframeNodeContext as g, AgentResource as gt, DevframeConnectionConfigsRegistry as h, AgentManifest as ht, DevframeDockDefaults as i, Immutable as it, ScopedSharedStates as j, parseCliFlags as jt, ScopedRpcFn as k, InferCliFlags as kt, McpRouteOptions as l, SharedState as lt, DevframeCapabilities as m, AgentHandle as mt, DevframeDefinition as n, createStreamReader as nt, DevframeSetupInfo as o, ImmutableMap as ot, ConnectionMetaWebsocket as p, createSharedState as pt, DevframeRpcServerFunctions as q, DevframeDeploymentKind as r, createStreamSink as rt, DevframeSseOptions as s, ImmutableObject as st, DevframeCliOptions as t, StreamSinkEvents as tt, DevframeAuthHandler as u, SharedStateEvents as ut, DevframeServiceOf as v, AgentResourceInput as vt, DevframeSettings as w, DevframeAgentHostEvents as wt, DevframeScopedNodeContext as x, AgentToolProvider as xt, DevframeServicesHost as y, AgentTool as yt, RpcBroadcastOptions as z };
@@ -1,9 +1,7 @@
1
- import { t as devframeReporter } from "./diagnostics-reporter-CsIG85Q5.mjs";
2
- import { defineDiagnostics } from "nostics";
1
+ import { i as defineDiagnostics } from "./nostics-CzECRXpE.mjs";
3
2
  //#region src/rpc/diagnostics.ts
4
3
  const diagnostics = defineDiagnostics({
5
4
  docsBase: "https://devfra.me/errors",
6
- reporters: [devframeReporter],
7
5
  codes: {
8
6
  DF0019: {
9
7
  why: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\` — MCP requires JSON-serializable data.`,
@@ -1,9 +1,7 @@
1
- import { t as devframeReporter } from "./diagnostics-reporter-CsIG85Q5.mjs";
2
- import { defineDiagnostics } from "nostics";
1
+ import { i as defineDiagnostics } from "./nostics-CzECRXpE.mjs";
3
2
  //#region src/node/diagnostics.ts
4
3
  const diagnostics = defineDiagnostics({
5
4
  docsBase: "https://devfra.me/errors",
6
- reporters: [devframeReporter],
7
5
  codes: {
8
6
  DF0006: { why: (p) => `RPC function "${p.name}" is not registered` },
9
7
  DF0007: { why: "AsyncLocalStorage is not set, it likely to be an internal bug of the Devframe foundation" },
@@ -38,7 +36,7 @@ const diagnostics = defineDiagnostics({
38
36
  },
39
37
  DF0033: {
40
38
  why: (p) => `Failed to start dev RPC bridge for "${p.id}": ${p.reason}`,
41
- fix: "Verify the bridge port is free and the devframe setup function does not throw. Pin a port via `cli.port` / `cli.portRange` on the definition, or via `devMiddleware.port` on `viteDevBridge`."
39
+ fix: "Verify the bridge port is free and the devframe setup function does not throw. Pin a port via `cli.port` / `cli.portRange` on the definition, or via `port` on `devframeViteBridge` (`@devframes/vite`)."
42
40
  },
43
41
  DF0034: {
44
42
  why: (p) => `Scoped RPC registration for namespace "${p.namespace}" received an already-namespaced function name "${p.name}".`,
@@ -90,7 +88,7 @@ const diagnostics = defineDiagnostics({
90
88
  },
91
89
  DF0052: {
92
90
  why: (p) => `Failed to listen on ${p.host}:${p.port}: ${p.reason}`,
93
- fix: "The port is likely already taken by another process (often a previous devframe instance). Free it, or pick another via `--port`, `cli.port` / `cli.portRange` on the definition, or `devMiddleware.port` on `viteDevBridge`. The original node error is available as `error.cause`."
91
+ fix: "The port is likely already taken by another process (often a previous devframe instance). Free it, or pick another via `--port`, `cli.port` / `cli.portRange` on the definition, or `port` on `devframeViteBridge` (`@devframes/vite`). The original node error is available as `error.cause`."
94
92
  },
95
93
  DF0054: {
96
94
  why: (p) => `connectionMeta() was called before initDevframe("${p.id}") finished initializing.`,
@@ -107,6 +105,38 @@ const diagnostics = defineDiagnostics({
107
105
  DF0057: {
108
106
  why: () => "This instance disables its WebSocket transport (`ws: false`), so there is no socket to drive upgrades into.",
109
107
  fix: "Clients connect over the SSE endpoint instead — no upgrade wiring is needed. Remove `ws: false` if the instance should serve a WebSocket after all."
108
+ },
109
+ DF0058: {
110
+ why: (p) => `"${p.id}" declares \`capabilities.dev: false\` — it does not support a live dev server (its value is a static export only).`,
111
+ fix: "Pass `{ force: true }` to `createDevServer()` to run it anyway, or drop `capabilities.dev: false` on the definition."
112
+ },
113
+ DF0059: {
114
+ why: (p) => `Failed to fetch the file listing for "${p.package}@${p.version}" from ${p.provider}: ${p.reason}`,
115
+ fix: "Requests fall back to probing the provider per file. Check network access to the provider, or install the assets package locally so no listing is needed."
116
+ },
117
+ DF0060: {
118
+ why: (p) => `Failed to fetch a remote asset of "${p.package}" (${p.url}): ${p.reason}`,
119
+ fix: "Install the assets package locally (`npm install <package>`) to serve it with zero network, or check network access to the configured provider."
120
+ },
121
+ DF0061: {
122
+ why: (p) => `The locally installed "${p.package}@${p.installed}" is a different major version than the required "${p.required}".`,
123
+ fix: "Align the installed assets package with the version its node package declares — they are published in lockstep."
124
+ },
125
+ DF0062: {
126
+ why: (p) => `The locally installed "${p.package}@${p.installed}" differs from the required "${p.required}" — serving the installed one.`,
127
+ fix: "Install the exact declared version to serve byte-identical assets."
128
+ },
129
+ DF0063: {
130
+ why: (p) => `Failed to persist a remote asset into the cache at "${p.filepath}": ${p.reason}`,
131
+ fix: "The response was still served; only caching failed. Check that the cache directory is writable and has free space."
132
+ },
133
+ DF0064: {
134
+ why: (p) => `Failed to materialize the remote assets of "${p.package}@${p.version}": ${p.reason}`,
135
+ fix: "Static builds need every asset file up front. Install the assets package locally, or ensure the provider (and its file-listing API) is reachable during the build."
136
+ },
137
+ DF0065: {
138
+ why: (p) => `Invalid remote-assets ${p.field} "${p.value}".`,
139
+ fix: "A remote-assets `package` must be a valid npm package name and `version` an exact semver version (e.g. `1.2.3`) — they are interpolated into CDN URLs and the cache path."
110
140
  }
111
141
  }
112
142
  });
@@ -1,4 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-JspESFgx.mjs";
2
+ import "node:fs/promises";
2
3
  import { createServer } from "node:net";
3
4
  import { networkInterfaces } from "node:os";
4
5
  //#region ../../node_modules/.pnpm/get-port-please@3.2.0/node_modules/get-port-please/dist/index.mjs
@@ -1,5 +1,43 @@
1
- import { t as diagnostics } from "./diagnostics-DLYH5oD3.mjs";
2
- import { i as createEventEmitter } from "./storage-BcmVEJRc.mjs";
1
+ import { t as diagnostics } from "./diagnostics-DOQPnQmX.mjs";
2
+ //#region src/utils/events.ts
3
+ /**
4
+ * Create event emitter.
5
+ */
6
+ function createEventEmitter() {
7
+ const _listeners = {};
8
+ function emit(event, ...args) {
9
+ const callbacks = _listeners[event] || [];
10
+ for (let i = 0, length = callbacks.length; i < length; i++) {
11
+ const callback = callbacks[i];
12
+ if (callback) callback(...args);
13
+ }
14
+ }
15
+ function emitOnce(event, ...args) {
16
+ emit(event, ...args);
17
+ delete _listeners[event];
18
+ }
19
+ function on(event, cb) {
20
+ (_listeners[event] ||= []).push(cb);
21
+ return () => {
22
+ _listeners[event] = _listeners[event]?.filter((i) => cb !== i);
23
+ };
24
+ }
25
+ function once(event, cb) {
26
+ const unsubscribe = on(event, ((...args) => {
27
+ unsubscribe();
28
+ return cb(...args);
29
+ }));
30
+ return unsubscribe;
31
+ }
32
+ return {
33
+ _listeners,
34
+ emit,
35
+ emitOnce,
36
+ on,
37
+ once
38
+ };
39
+ }
40
+ //#endregion
3
41
  //#region src/node/agent-args.ts
4
42
  /**
5
43
  * Map the args payload an agent surface receives (MCP sends an object
@@ -14,8 +52,6 @@ import { i as createEventEmitter } from "./storage-BcmVEJRc.mjs";
14
52
  * - without schemas, `arg0`/`arg1`/… keys are collected when present
15
53
  * - an empty object becomes a zero-argument call
16
54
  * - anything else follows the {@link AgentArgsFallback}
17
- *
18
- * @experimental
19
55
  */
20
56
  function coerceAgentPositionalArgs(args, schemas, fallback = "wrap") {
21
57
  if (Array.isArray(args)) return args;
@@ -43,8 +79,6 @@ function coerceAgentPositionalArgs(args, schemas, fallback = "wrap") {
43
79
  * devframe. Auto-discovers RPC functions with an `agent` field from
44
80
  * `ctx.rpc.definitions`, and accepts plugin-registered tools /
45
81
  * resources via `registerTool` / `registerResource`.
46
- *
47
- * @experimental
48
82
  */
49
83
  var DevframeAgentHost = class {
50
84
  context;
@@ -227,4 +261,4 @@ function inferSafety(type) {
227
261
  return "action";
228
262
  }
229
263
  //#endregion
230
- export { coerceAgentPositionalArgs as n, DevframeAgentHost as t };
264
+ export { coerceAgentPositionalArgs as n, createEventEmitter as r, DevframeAgentHost as t };
@@ -8,8 +8,8 @@ import { homedir } from "node:os";
8
8
  function createH3DevframeHost(options) {
9
9
  const workspaceRoot = options.workspaceRoot ?? process.cwd();
10
10
  return {
11
- mountStatic(base, distDir) {
12
- return options.mount?.(base, distDir);
11
+ mountStatic(base, source) {
12
+ return options.mount?.(base, source);
13
13
  },
14
14
  resolveOrigin() {
15
15
  return typeof options.origin === "function" ? options.origin() : options.origin;
@@ -1,10 +1,10 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-JspESFgx.mjs";
2
- import { i as isAllowedOrigin } from "./ws-server-Bk1hOG3X.mjs";
3
- import { t as diagnostics } from "./diagnostics-DLYH5oD3.mjs";
4
- import { t as createHostContext } from "./context-Du11TLcO.mjs";
5
- import { t as toAgentToolName } from "./agent-tool-name-C3b5vEwJ.mjs";
2
+ import { t as Diagnostic } from "./nostics-CzECRXpE.mjs";
3
+ import { i as isAllowedOrigin } from "./ws-server-BdSLrhxE.mjs";
4
+ import { t as diagnostics } from "./diagnostics-DOQPnQmX.mjs";
5
+ import { t as createHostContext } from "./context-CEe4PBz1.mjs";
6
+ import { t as toAgentToolName } from "./agent-tool-name-EgfoFO8C.mjs";
6
7
  import { randomUUID } from "node:crypto";
7
- import { Diagnostic } from "nostics";
8
8
  import { join } from "pathe";
9
9
  import process from "node:process";
10
10
  import { homedir } from "node:os";
@@ -190,9 +190,6 @@ function buildMcpServerFromContext(ctx, options) {
190
190
  /**
191
191
  * Build an MCP server over the agent surface of a devframe definition.
192
192
  * Currently supports `stdio` transport only.
193
- *
194
- * @experimental The agent-native surface is experimental and may change
195
- * without a major version bump until it stabilizes.
196
193
  */
197
194
  async function createMcpServer(definition, options = {}) {
198
195
  const transport = options.transport ?? "stdio";
@@ -463,8 +460,6 @@ function parseResourceUri(uri) {
463
460
  * loopback-default DNS-rebinding protection that — unlike the WS upgrade's
464
461
  * `isAllowedOrigin` — also rejects `Origin`-less requests, so a route-based
465
462
  * endpoint isn't reachable by an arbitrary local process.
466
- *
467
- * @experimental
468
463
  */
469
464
  function createMcpFetchHandler(ctx, options) {
470
465
  const sessions = /* @__PURE__ */ new Map();
@@ -547,8 +542,6 @@ var http_exports = /* @__PURE__ */ __exportAll({ mountMcpHttp: () => mountMcpHtt
547
542
  * legitimate MCP 404 (unknown session) isn't swallowed by h3's
548
543
  * "Response-with-404 falls through to the next handler" rule (which would
549
544
  * otherwise hand the request to the SPA static catch-all).
550
- *
551
- * @experimental
552
545
  */
553
546
  function mountMcpHttp(app, ctx, path, options) {
554
547
  const handler = createMcpFetchHandler(ctx, options);