devframe 0.9.8 → 0.9.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 (121) hide show
  1. package/dist/_shared-CCzf9Hub.d.mts +83 -0
  2. package/dist/_shared-U8D-xzrp.mjs +115 -0
  3. package/dist/adapters/build.d.mts +6 -6
  4. package/dist/adapters/build.mjs +33 -36
  5. package/dist/adapters/cac.d.mts +12 -1
  6. package/dist/adapters/cac.mjs +8 -8
  7. package/dist/adapters/dev.d.mts +17 -17
  8. package/dist/adapters/dev.mjs +2 -2
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +31 -28
  11. package/dist/adapters/initiate.mjs +1 -1
  12. package/dist/adapters/mcp.d.mts +28 -14
  13. package/dist/adapters/mcp.mjs +76 -40
  14. package/dist/{agent-tool-name-EgfoFO8C.mjs → agent-tool-name-DGzeuWcO.mjs} +2 -2
  15. package/dist/cli/main.d.mts +1 -1
  16. package/dist/cli/main.mjs +41 -17
  17. package/dist/client/index.d.mts +36 -36
  18. package/dist/client/index.mjs +90 -52
  19. package/dist/{client-assets-C7SXgTWY.mjs → client-assets-DNdhagGm.mjs} +2 -2
  20. package/dist/constants.d.mts +8 -7
  21. package/dist/constants.mjs +7 -6
  22. package/dist/{context-omlma_1n.mjs → context-B29Oh0oA.mjs} +166 -93
  23. package/dist/{context-DftYyXaR.d.mts → context-BJiKJqyW.d.mts} +5 -5
  24. package/dist/{context-CLF4-8Pp.d.mts → context-CHW4BZOj.d.mts} +203 -134
  25. package/dist/{context-KUqAfawQ.mjs → context-jXO5vzjH.mjs} +3 -3
  26. package/dist/{crypto-token-XCqTSMg9.mjs → crypto-token-TVbGGFuj.mjs} +1 -1
  27. package/dist/{dev-CzkPCJwi.mjs → dev-CRYHx7iG.mjs} +73 -40
  28. package/dist/{diagnostics-BXWW3VK-.mjs → diagnostics-DZA6KQ_Z.mjs} +32 -19
  29. package/dist/{events-4daw0uK9.mjs → events-BV4Dj59a.mjs} +2 -2
  30. package/dist/{services-install-CqqQVls5.mjs → host-agent-CKqSTEX9.mjs} +15 -151
  31. package/dist/{host-h3-fRbF9yor.mjs → host-h3-BROI6SQ4.mjs} +2 -2
  32. package/dist/in-page-channel/index.d.mts +14 -14
  33. package/dist/in-page-channel/index.mjs +63 -54
  34. package/dist/{index-D3k0BIhe.d.mts → index-CNC390b_.d.mts} +4 -4
  35. package/dist/{index-BzyopqxV.d.mts → index-pIVt92jP.d.mts} +9 -9
  36. package/dist/index.d.mts +8 -8
  37. package/dist/index.mjs +2 -2
  38. package/dist/{instance-registry-BjlMQbFB.mjs → instance-registry-DCq762YJ.mjs} +9 -9
  39. package/dist/{instance-shell-Tcp5hGoq.d.mts → instance-shell-DZipaP9k.d.mts} +18 -18
  40. package/dist/{instance-shell-CpVW4zG0.mjs → instance-shell-DvYCwrDy.mjs} +223 -67
  41. package/dist/internal/index.d.mts +45 -26
  42. package/dist/internal/index.mjs +10 -10
  43. package/dist/node/auth.d.mts +2 -2
  44. package/dist/node/auth.mjs +2 -2
  45. package/dist/node/hub-internals.d.mts +2 -2
  46. package/dist/node/hub-internals.mjs +2 -2
  47. package/dist/node/index.d.mts +5 -5
  48. package/dist/node/index.mjs +2 -2
  49. package/dist/{nostics-SPGDgHEP.d.mts → nostics-0sKe5HIj.d.mts} +2 -2
  50. package/dist/{nostics-CzECRXpE.mjs → nostics-D0PvLZsn.mjs} +1 -1
  51. package/dist/origin-DGDH8BI9.d.mts +45 -0
  52. package/dist/origin-DZit9g29.mjs +80 -0
  53. package/dist/recipes/common-rpc-functions.d.mts +5 -5
  54. package/dist/recipes/common-rpc-functions.mjs +3 -3
  55. package/dist/recipes/interactive-auth.d.mts +6 -6
  56. package/dist/recipes/interactive-auth.mjs +6 -6
  57. package/dist/{remote-assets-DezQmPQU.mjs → remote-assets-DMFzLSoH.mjs} +27 -7
  58. package/dist/{remote-assets-B13_vRkJ.d.mts → remote-assets-eBvSKZMS.d.mts} +7 -7
  59. package/dist/{revoke-COLW0cOi.mjs → revoke-cqztiCX4.mjs} +1 -1
  60. package/dist/rpc/dump.d.mts +19 -12
  61. package/dist/rpc/dump.mjs +2 -2
  62. package/dist/rpc/index.d.mts +2 -2
  63. package/dist/rpc/index.mjs +2 -3
  64. package/dist/rpc/transports/sse-client.d.mts +1 -1
  65. package/dist/rpc/transports/sse-client.mjs +30 -14
  66. package/dist/rpc/transports/sse-server.d.mts +4 -4
  67. package/dist/rpc/transports/sse-server.mjs +7 -7
  68. package/dist/rpc/transports/ws-bun.d.mts +5 -5
  69. package/dist/rpc/transports/ws-bun.mjs +8 -2
  70. package/dist/rpc/transports/ws-client.d.mts +1 -1
  71. package/dist/rpc/transports/ws-client.mjs +2 -2
  72. package/dist/rpc/transports/ws-deno.d.mts +4 -4
  73. package/dist/rpc/transports/ws-deno.mjs +8 -2
  74. package/dist/rpc/transports/ws-server.d.mts +2 -1
  75. package/dist/rpc/transports/ws-server.mjs +232 -1
  76. package/dist/{rpc-core-DlHd276T.mjs → rpc-core-CvkU23bQ.mjs} +14 -2
  77. package/dist/{rpc-core-B3W3z9ff.d.mts → rpc-core-DsyDViQy.d.mts} +4 -4
  78. package/dist/serialization-DFg5sUt6.mjs +116 -0
  79. package/dist/services-install-Ben4yh52.mjs +154 -0
  80. package/dist/session-DPfj6zQG.mjs +16 -0
  81. package/dist/{shared-state--sduc6Xi.mjs → shared-state-CaxB1q0h.mjs} +2 -2
  82. package/dist/{simple-schema-DQPZrAaZ.mjs → simple-schema-Bi40l-P6.mjs} +2 -2
  83. package/dist/{sse-client-DwX021ST.d.mts → sse-client-BQ4jS3eO.d.mts} +4 -4
  84. package/dist/{state-CK9LjrnT.mjs → state-Mwt6--el.mjs} +17 -9
  85. package/dist/{storage-BXNVhKyR.mjs → storage-B70AXK64.mjs} +2 -2
  86. package/dist/types/index.d.mts +6 -6
  87. package/dist/{types-CMdPYhOx.d.mts → types-Dq4i156u.d.mts} +17 -17
  88. package/dist/utils/agent-tool-name.d.mts +2 -2
  89. package/dist/utils/agent-tool-name.mjs +2 -2
  90. package/dist/utils/colors.d.mts +1 -1
  91. package/dist/utils/crypto-token.d.mts +1 -1
  92. package/dist/utils/crypto-token.mjs +1 -1
  93. package/dist/utils/events.d.mts +1 -1
  94. package/dist/utils/nostics.d.mts +1 -1
  95. package/dist/utils/nostics.mjs +1 -1
  96. package/dist/utils/open.mjs +1 -1
  97. package/dist/utils/origin.d.mts +2 -0
  98. package/dist/utils/origin.mjs +80 -0
  99. package/dist/utils/remote-assets.d.mts +2 -2
  100. package/dist/utils/remote-assets.mjs +1 -1
  101. package/dist/utils/serve-static.d.mts +4 -4
  102. package/dist/utils/serve-static.mjs +56 -19
  103. package/dist/utils/shared-state.d.mts +1 -1
  104. package/dist/utils/shared-state.mjs +1 -1
  105. package/dist/utils/simple-schema.d.mts +5 -5
  106. package/dist/utils/simple-schema.mjs +2 -2
  107. package/dist/utils/streaming-channel.d.mts +1 -1
  108. package/dist/utils/streaming-channel.mjs +2 -2
  109. package/dist/utils/when.d.mts +5 -5
  110. package/dist/{validation-YrZH6atx.mjs → validation-CfV1s0SF.mjs} +2 -2
  111. package/dist/{wire-codec-0K-o5MYW.mjs → wire-codec-BHGt0sSs.mjs} +3 -3
  112. package/dist/{static-DV_qUSRS.mjs → write-BuLCrn9h.mjs} +153 -137
  113. package/dist/{ws-client-7_lZi-B9.d.mts → ws-client-Xpxt0oPA.d.mts} +3 -3
  114. package/dist/{ws-server-VyHlanzy.d.mts → ws-server-D2nv68Hg.d.mts} +13 -37
  115. package/package.json +3 -6
  116. package/skills/devframe/SKILL.md +5 -3
  117. package/dist/_shared-BM3PdYli.mjs +0 -68
  118. package/dist/_shared-mtXpcJIv.d.mts +0 -41
  119. package/dist/diagnostics-CD8nlgll.mjs +0 -39
  120. package/dist/serialization-BGzEwAdr.mjs +0 -77
  121. package/dist/ws-server-Y_AumUQH.mjs +0 -294
@@ -1,8 +1,8 @@
1
- import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-BzyopqxV.mjs";
2
- import { _ as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-CMdPYhOx.mjs";
3
- import { Q as DevframeServiceScopeOf, X as DevframeServiceMeta, _t as DevframeRpcServerFunctions, b as StreamSink, d as RpcSharedStateHost, dt as ScopedRpcFn, ft as ScopedServerFunctions, gt as DevframeRpcClientFunctions, k as SharedState, mt as SettingsForNamespace, nt as DevframeServicesState, ot as DevframeSettings, pt as ScopedSharedStates, t as ConnectionMeta, u as RpcSharedStateGetOptions, y as StreamReader, zt as EventEmitter } from "../context-CLF4-8Pp.mjs";
4
- import { t as SseRpcChannelOptions } from "../sse-client-DwX021ST.mjs";
5
- import { t as WsRpcChannelOptions } from "../ws-client-7_lZi-B9.mjs";
1
+ import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-pIVt92jP.mjs";
2
+ import { _ as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-Dq4i156u.mjs";
3
+ import { Q as DevframeServiceMeta, Vt as EventEmitter, b as StreamSink, ct as DevframeSettings, d as RpcSharedStateHost, et as DevframeServiceScopeOf, gt as SettingsForNamespace, ht as ScopedSharedStates, it as DevframeServicesState, k as SharedState, mt as ScopedServerFunctions, pt as ScopedRpcFn, t as ConnectionMeta, u as RpcSharedStateGetOptions, vt as DevframeRpcClientFunctions, y as StreamReader, yt as DevframeRpcServerFunctions } from "../context-CHW4BZOj.mjs";
4
+ import { t as SseRpcChannelOptions } from "../sse-client-BQ4jS3eO.mjs";
5
+ import { t as WsRpcChannelOptions } from "../ws-client-Xpxt0oPA.mjs";
6
6
  import { BirpcOptions, BirpcReturn } from "birpc";
7
7
  //#region src/client/connection.d.ts
8
8
  interface DevframeConnection {
@@ -50,15 +50,15 @@ declare function setupDevframeConnection(options?: SetupDevframeConnectionOption
50
50
  * trust handshake, so a viewer never has to reason about the two dimensions
51
51
  * separately.
52
52
  *
53
- * - `connecting` — establishing the WebSocket / running the initial trust
53
+ * - `connecting`: establishing the WebSocket / running the initial trust
54
54
  * handshake. Calls issued here queue until the socket opens.
55
- * - `connected` — socket open and trusted; RPC calls will be served.
56
- * - `unauthorized` — socket open but the server rejected trust (no valid token,
55
+ * - `connected`: socket open and trusted; RPC calls will be served.
56
+ * - `unauthorized`: socket open but the server rejected trust (no valid token,
57
57
  * or an auth-enforcing host refused it). Calls fail fast with an auth error;
58
58
  * the UI should prompt for re-authentication or a reload.
59
- * - `disconnected` — the socket closed (dropped mid-session, or never opened).
59
+ * - `disconnected`: the socket closed (dropped mid-session, or never opened).
60
60
  * Pending and new calls fail fast until the page reconnects.
61
- * - `error` — a fatal connection error (e.g. the WebSocket errored, or the
61
+ * - `error`: a fatal connection error (e.g. the WebSocket errored, or the
62
62
  * connection meta could not be loaded).
63
63
  *
64
64
  * A `static` backend has no live socket, so it reports `connected` for its
@@ -67,9 +67,9 @@ declare function setupDevframeConnection(options?: SetupDevframeConnectionOption
67
67
  type DevframeConnectionStatus = 'connecting' | 'connected' | 'unauthorized' | 'disconnected' | 'error';
68
68
  /**
69
69
  * What kind of failure a {@link DevframeConnectionError} describes:
70
- * - `connection` — the transport dropped, errored, or never opened.
71
- * - `auth` — the server rejected trust for this client.
72
- * - `timeout` — a call exceeded its {@link DevframeRpcClientOptions.callTimeout}.
70
+ * - `connection`: the transport dropped, errored, or never opened.
71
+ * - `auth`: the server rejected trust for this client.
72
+ * - `timeout`: a call exceeded its {@link DevframeRpcClientOptions.callTimeout}.
73
73
  */
74
74
  type DevframeConnectionErrorKind = 'connection' | 'auth' | 'timeout';
75
75
  /**
@@ -199,7 +199,7 @@ declare function createScopedClientContext<NS extends string = string>(rpc: Devf
199
199
  //#endregion
200
200
  //#region src/client/rpc-services.d.ts
201
201
  /**
202
- * A typed handle on one advertised wire service — the service's
202
+ * A typed handle on one advertised wire service: the service's
203
203
  * advertisement meta plus an RPC surface scoped to its namespace, so
204
204
  * `handle.rpc.call('fn-name', …)` targets `<scope>:fn-name`. Service
205
205
  * packages type the calls by augmenting `DevframeRpcServerFunctions` with
@@ -214,7 +214,7 @@ interface DevframeServiceClientHandle<NS extends string = string> extends Devfra
214
214
  /**
215
215
  * Client-side view of the server's wire-service registry, mirrored through
216
216
  * the reactive `devframe:services` shared state. The accessors are
217
- * synchronous snapshots — before the first sync lands (or on a server with
217
+ * synchronous snapshots; before the first sync lands (or on a server with
218
218
  * no services) they read as empty. For reactive UI (e.g. hiding an
219
219
  * "open in editor" button until the service appears), subscribe to the
220
220
  * shared state itself via {@link DevframeServicesClient.state}.
@@ -223,14 +223,14 @@ interface DevframeServicesClient {
223
223
  /** Whether the service package is advertised as installed. */
224
224
  has: (pkg: string) => boolean;
225
225
  /**
226
- * A typed handle on an advertised service — its meta plus a scoped RPC
227
- * surface — or `undefined` while it isn't available (never throws).
226
+ * A typed handle on an advertised service (its meta plus a scoped RPC
227
+ * surface), or `undefined` while it isn't available (never throws).
228
228
  */
229
229
  get: <PKG extends string>(pkg: PKG) => DevframeServiceClientHandle<DevframeServiceScopeOf<PKG>> | undefined;
230
230
  /** Package names of every advertised service. */
231
231
  keys: () => string[];
232
232
  /**
233
- * The mirrored `devframe:services` shared state — subscribe to its
233
+ * The mirrored `devframe:services` shared state; subscribe to its
234
234
  * `updated` event for reactivity.
235
235
  */
236
236
  state: () => Promise<SharedState<DevframeServicesState>>;
@@ -257,7 +257,7 @@ interface RpcClientEvents {
257
257
  */
258
258
  'connection:error': (error: Error) => void;
259
259
  /**
260
- * An RPC call rejected — either from the server, or because the connection
260
+ * An RPC call rejected, either from the server, or because the connection
261
261
  * was down / timed out. Useful for a global error feed or toast surface.
262
262
  */
263
263
  'rpc:error': (error: Error, method: string) => void;
@@ -271,7 +271,7 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
271
271
  * Query-param name on the page URL carrying a one-time authentication code
272
272
  * (OTP) for "magic link" auth (e.g. a link the dev server prints). When
273
273
  * present, the client exchanges the code for a token and removes the parameter
274
- * from the URL. Set `false` to disable — e.g. integrations that drive their
274
+ * from the URL. Set `false` to disable, e.g. integrations that drive their
275
275
  * own authentication via `authenticateWithUrlOtp`.
276
276
  *
277
277
  * @default 'devframe_otp'
@@ -281,7 +281,7 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
281
281
  * Fall back to a native browser `prompt()` for the one-time authentication
282
282
  * code when the server refuses trust and no other credential succeeds (a
283
283
  * stored token, an injected token, or a magic-link OTP). The prompt fires
284
- * only on a **top-level, unframed** page — a framed plugin (e.g. mounted in
284
+ * only on a **top-level, unframed** page; a framed plugin (e.g. mounted in
285
285
  * a hub dock) never prompts, since a hub pre-authorizes it and browsers
286
286
  * block `prompt()` in cross-origin frames anyway.
287
287
  *
@@ -294,20 +294,20 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
294
294
  /**
295
295
  * Which live transport to connect over:
296
296
  *
297
- * - `'auto'` (default) — trust the server's advertisement: its declared
297
+ * - `'auto'` (default) trusts the server's advertisement: its declared
298
298
  * primary (`backend`), preferring the WebSocket when both endpoints are
299
299
  * present. A server that couldn't bind a socket advertises SSE as its
300
300
  * primary, so no client-side fallback probing is needed.
301
- * - `'websocket'` / `'sse'` — pin one transport; connecting fails with a
301
+ * - `'websocket'` / `'sse'` pins one transport; connecting fails with a
302
302
  * clear error when the server doesn't advertise it. Reach for
303
- * `transport: 'sse'` when an intermediary silently strips WS upgrades —
303
+ * `transport: 'sse'` when an intermediary silently strips WS upgrades,
304
304
  * something the server cannot detect.
305
305
  *
306
306
  * A `static` backend ignores this option (there is no live transport).
307
307
  */
308
308
  transport?: 'auto' | 'websocket' | 'sse';
309
309
  wsOptions?: Partial<WsRpcChannelOptions>;
310
- /** Channel overrides for the SSE transport — the `wsOptions` counterpart. */
310
+ /** Channel overrides for the SSE transport, the `wsOptions` counterpart. */
311
311
  sseOptions?: Partial<SseRpcChannelOptions>;
312
312
  rpcOptions?: Partial<BirpcOptions<DevframeRpcServerFunctions, DevframeRpcClientFunctions, boolean>>;
313
313
  cacheOptions?: boolean | Partial<RpcCacheOptions>;
@@ -315,8 +315,8 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
315
315
  * Reject a pending `rpc.call(...)` if the server hasn't answered within this
316
316
  * many milliseconds, with a {@link DevframeConnectionError} of kind
317
317
  * `'timeout'`. Guards against a live-but-unresponsive server hanging the UI.
318
- * Omit (or `0`) to wait indefinitely. Calls always fail fast — regardless of
319
- * this option — once the socket closes or trust is refused.
318
+ * Omit (or `0`) to wait indefinitely. Calls always fail fast, regardless of
319
+ * this option, once the socket closes or trust is refused.
320
320
  */
321
321
  callTimeout?: number;
322
322
  }
@@ -344,7 +344,7 @@ interface DevframeRpcClient {
344
344
  */
345
345
  readonly connectionError: Error | null;
346
346
  /**
347
- * The transport this client is actually connected over — `'websocket'`,
347
+ * The transport this client is actually connected over: `'websocket'`,
348
348
  * `'sse'`, or `'static'`. Reflects the resolution of the `transport`
349
349
  * option against the server's advertisement.
350
350
  */
@@ -404,7 +404,7 @@ interface DevframeRpcClient {
404
404
  sharedState: RpcSharedStateHost;
405
405
  /**
406
406
  * The server's advertised wire services (mirrored `devframe:services`
407
- * shared state) — feature-detect a capability with
407
+ * shared state); feature-detect a capability with
408
408
  * `rpc.services.has('@devframes/service-x')` and get a scoped, typed RPC
409
409
  * handle with `rpc.services.get(...)`. See {@link DevframeServicesClient}.
410
410
  */
@@ -437,11 +437,11 @@ interface DevframeRpcClient {
437
437
  * a `websocket` backend closes the underlying `WebSocket`, which the server observes as a
438
438
  * normal disconnect. Mirrors {@link WsRpcTransport.close} on the server side.
439
439
  *
440
- * There is no corresponding "reconnect" — a closed client is done. Discard it and call
440
+ * There is no corresponding "reconnect"; a closed client is done. Discard it and call
441
441
  * {@link getDevframeRpcClient} again to reconnect.
442
442
  *
443
- * Optional so a `DevframeRpcClientMode` implemented before this method existed — a custom
444
- * transport, a hand-typed mock — still satisfies the interface; an absent `close` is treated
443
+ * Optional so a `DevframeRpcClientMode` implemented before this method existed (a custom
444
+ * transport, a hand-typed mock) still satisfies the interface; an absent `close` is treated
445
445
  * as nothing to close.
446
446
  */
447
447
  close?: () => void;
@@ -449,7 +449,7 @@ interface DevframeRpcClient {
449
449
  interface DevframeRpcClientMode {
450
450
  /**
451
451
  * The transport this mode speaks. Optional so a mode implemented before
452
- * this field existed — a custom transport, a hand-typed mock — still
452
+ * this field existed (a custom transport, a hand-typed mock) still
453
453
  * satisfies the interface; an absent value reads as `'websocket'`.
454
454
  */
455
455
  readonly transport?: 'websocket' | 'sse' | 'static';
@@ -472,7 +472,7 @@ interface DevframeRpcClientMode {
472
472
  }
473
473
  /**
474
474
  * Resolve the requested `transport` option against what the server
475
- * advertises. `'auto'` trusts the advertisement — the server's declared
475
+ * advertises. `'auto'` trusts the advertisement: the server's declared
476
476
  * primary (`backend`), preferring the WebSocket when both endpoints are
477
477
  * present; an explicit `'websocket'` / `'sse'` pins that transport and
478
478
  * throws when the server doesn't advertise it.
@@ -502,7 +502,7 @@ declare function consumeOtpFromUrl(param?: string): string | undefined;
502
502
  *
503
503
  * Higher-level integrations (e.g. Vite DevTools) that want to drive their own
504
504
  * authentication UI can disable `connectDevframe`'s built-in handling with
505
- * `otpParam: false` and call this — or {@link consumeOtpFromUrl} — themselves.
505
+ * `otpParam: false` and call this (or {@link consumeOtpFromUrl}) themselves.
506
506
  */
507
507
  declare function authenticateWithUrlOtp(rpc: Pick<DevframeRpcClient, 'isTrusted' | 'requestTrustWithCode'>, options?: {
508
508
  param?: string;
@@ -523,7 +523,7 @@ interface WsUrlLocation {
523
523
  * The object / relative-path forms connect to the page's own origin (only the
524
524
  * `http`→`ws` protocol swap is applied), resolving the path against where
525
525
  * `__connection.json` was loaded. This is deliberately host-agnostic so the
526
- * connection survives a reverse proxy that changes the domain or port — the
526
+ * connection survives a reverse proxy that changes the domain or port, since the
527
527
  * client trusts its own location, never a server-baked hostname. An explicit
528
528
  * `port`/`host` (or a full `ws(s)://` URL string) opts into a cross-origin
529
529
  * endpoint, e.g. a side-car server on its own port.
@@ -1,8 +1,8 @@
1
- import { t as DEVFRAME_EVENTS } from "../events-4daw0uK9.mjs";
1
+ import { t as DEVFRAME_EVENTS } from "../events-BV4Dj59a.mjs";
2
2
  import { t as hash } from "../hash-DdPnc4k3.mjs";
3
3
  import { colors } from "../utils/colors.mjs";
4
4
  import { createEventEmitter } from "../utils/events.mjs";
5
- import { t as createSharedState } from "../shared-state--sduc6Xi.mjs";
5
+ import { t as createSharedState } from "../shared-state-CaxB1q0h.mjs";
6
6
  import { i as structuredCloneStringify, n as structuredCloneParse, t as structuredCloneDeserialize } from "../structured-clone-CgtQ61SA.mjs";
7
7
  import { createStreamReader, createStreamSink } from "../utils/streaming-channel.mjs";
8
8
  import { defineDiagnostics } from "nostics";
@@ -10,6 +10,7 @@ import { ansiFormatter } from "nostics/formatters/ansi";
10
10
  import { withBase, withProtocol } from "ufo";
11
11
  import { createBirpc } from "birpc";
12
12
  //#region src/constants.ts
13
+ /** Devframe runtime routes and static output conventions. */
13
14
  const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
14
15
  /**
15
16
  * Global key holding the serializable connection prepared by
@@ -110,7 +111,7 @@ function devframeReporter(d, { method = "warn" } = {}) {
110
111
  * ANSI console reporter pre-wired ahead of any `reporters` passed in. Every
111
112
  * `diagnostics.ts` in devframe core, `@devframes/hub`, `@devframes/json-render`,
112
113
  * and the built-in plugins defines its codes through this instead of
113
- * `nostics`'s own `defineDiagnostics` — the reporter registration lives
114
+ * `nostics`'s own `defineDiagnostics`; the reporter registration lives
114
115
  * here, once, so none of them need to build their own reporter (`colors`,
115
116
  * `ansiFormatter`) or take a direct dependency on `nostics` themselves.
116
117
  */
@@ -126,7 +127,7 @@ const diagnostics = defineDiagnostics$1({
126
127
  docsBase: "https://devfra.me/errors",
127
128
  codes: {
128
129
  DF0019: {
129
- why: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\` — MCP requires JSON-serializable data.`,
130
+ why: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\`; MCP requires JSON-serializable data.`,
130
131
  fix: "Set `jsonSerializable: true` if the payload is JSON-safe, or remove `agent` to keep it RPC-only."
131
132
  },
132
133
  DF0020: {
@@ -207,7 +208,7 @@ async function validateRpcArgs(name, argsSchema, args) {
207
208
  /**
208
209
  * Validate a handler's resolved return value against its declared schema.
209
210
  * Throws `DF0039` when the value fails the schema, otherwise returns the
210
- * original value unchanged (guard-only, never rewriting the payload — see
211
+ * original value unchanged (guard-only, never rewriting the payload; see
211
212
  * {@link validateRpcArgs}). Passes through when no return schema is set.
212
213
  *
213
214
  * @internal
@@ -350,16 +351,16 @@ function assertAgentJsonSerializable(fn) {
350
351
  * instances, or `undefined` inside an array (silently becomes `null`).
351
352
  *
352
353
  * Native pass-throughs (no extra work needed):
353
- * - circular references — `JSON.stringify` raises `TypeError`.
354
- * - `BigInt` at top level — caught here for a friendlier error path.
354
+ * - circular references: `JSON.stringify` raises `TypeError`.
355
+ * - `BigInt` at top level: caught here for a friendlier error path.
355
356
  *
356
357
  * Lenient cases (allowed without throwing):
357
- * - `undefined` as an object property — legitimate optional field;
358
+ * - `undefined` as an object property: legitimate optional field;
358
359
  * JSON.stringify just omits it.
359
- * - `undefined` at the root — legitimate "action returned nothing".
360
- * - `Symbol` / `Function` values — semantically "drop me" in JSON.
360
+ * - `undefined` at the root: legitimate "action returned nothing".
361
+ * - `Symbol` / `Function` values: semantically "drop me" in JSON.
361
362
  *
362
- * `fnName` is used only for the diagnostic message — pass the RPC
363
+ * `fnName` is used only for the diagnostic message; pass the RPC
363
364
  * function name when calling from a wire serializer / dump writer so
364
365
  * the error points at the offending function.
365
366
  */
@@ -371,19 +372,21 @@ function strictJsonStringify(value, fnName = "") {
371
372
  if (Array.isArray(holder)) throw nonJsonAt(fnName, "undefined", holder, key);
372
373
  return val;
373
374
  }
374
- if (original === null) return val;
375
- if (typeof original === "bigint") throw nonJsonAt(fnName, "BigInt", holder, key);
376
- if (typeof original === "object") {
377
- if (original instanceof Map) throw nonJsonAt(fnName, "Map", holder, key);
378
- if (original instanceof Set) throw nonJsonAt(fnName, "Set", holder, key);
379
- if (original instanceof Date) throw nonJsonAt(fnName, "Date", holder, key);
380
- if (Array.isArray(original)) return val;
381
- const proto = Object.getPrototypeOf(original);
382
- if (proto !== null && proto !== Object.prototype) throw nonJsonAt(fnName, original.constructor?.name ?? "class instance", holder, key);
383
- }
375
+ if (original !== null) assertJsonSafe(original, holder, key, fnName);
384
376
  return val;
385
377
  });
386
378
  }
379
+ /** Throw `DF0020` when `original` is a type JSON can't round-trip losslessly. */
380
+ function assertJsonSafe(original, holder, key, fnName) {
381
+ if (typeof original === "bigint") throw nonJsonAt(fnName, "BigInt", holder, key);
382
+ if (typeof original !== "object") return;
383
+ if (original instanceof Map) throw nonJsonAt(fnName, "Map", holder, key);
384
+ if (original instanceof Set) throw nonJsonAt(fnName, "Set", holder, key);
385
+ if (original instanceof Date) throw nonJsonAt(fnName, "Date", holder, key);
386
+ if (Array.isArray(original)) return;
387
+ const proto = Object.getPrototypeOf(original);
388
+ if (proto !== null && proto !== Object.prototype) throw nonJsonAt(fnName, original.constructor?.name ?? "class instance", holder, key);
389
+ }
387
390
  function nonJsonAt(fnName, type, parent, key) {
388
391
  const path = formatPath(parent, key);
389
392
  return diagnostics.DF0020({
@@ -506,6 +509,10 @@ async function setupDevframeConnection(options = {}) {
506
509
  if (options.connectionMeta) {
507
510
  const connection = {
508
511
  connectionMeta: options.connectionMeta,
512
+ /**
513
+ * Preserve the established connectionMeta behavior: an explicitly
514
+ * supplied descriptor resolves from the caller's explicit base.
515
+ */
509
516
  metaBaseUrl: resolveMetaBaseUrl(bases[0] ?? "./"),
510
517
  authToken: readStoredAuthToken(options.authToken ?? options.connectionMeta.authToken)
511
518
  };
@@ -526,9 +533,15 @@ async function setupDevframeConnection(options = {}) {
526
533
  const response = await fetch(metaPath);
527
534
  if (!response.ok) throw new Error(`Failed to fetch connection meta from ${metaUrl}: ${response.status}`);
528
535
  const connectionMeta = await response.json();
536
+ const loadedFrom = response.url || metaUrl;
529
537
  const connection = {
530
538
  connectionMeta,
531
- metaBaseUrl: response.url || metaUrl,
539
+ /**
540
+ * A served `baseUrl` re-points relative resolution (RPC dump shards,
541
+ * transport paths) at the meta that owns them: a static hub build's
542
+ * per-frame meta directs each frame SPA at the hub's own dump.
543
+ */
544
+ metaBaseUrl: connectionMeta.baseUrl ? new URL(connectionMeta.baseUrl, loadedFrom).href : loadedFrom,
532
545
  authToken: readStoredAuthToken(options.authToken ?? connectionMeta.authToken)
533
546
  };
534
547
  storeConnection(connection);
@@ -605,7 +618,7 @@ function consumeOtpFromUrl(param = DEVFRAME_OTP_URL_PARAM) {
605
618
  *
606
619
  * Higher-level integrations (e.g. Vite DevTools) that want to drive their own
607
620
  * authentication UI can disable `connectDevframe`'s built-in handling with
608
- * `otpParam: false` and call this — or {@link consumeOtpFromUrl} — themselves.
621
+ * `otpParam: false` and call this (or {@link consumeOtpFromUrl}) themselves.
609
622
  */
610
623
  async function authenticateWithUrlOtp(rpc, options = {}) {
611
624
  const code = consumeOtpFromUrl(options.param ?? "devframe_otp");
@@ -763,7 +776,7 @@ const EMPTY_WIRE_DEFS = /* @__PURE__ */ new Map();
763
776
  * JSON (methods declared `jsonSerializable: true`) and `s:`-prefixed
764
777
  * structured-clone (everything else, including all error envelopes), with a
765
778
  * request-id → method map so a response independently picks the same
766
- * encoder as its request. One codec per connection — request-id spaces
779
+ * encoder as its request. One codec per connection; request-id spaces
767
780
  * don't collide across connections.
768
781
  *
769
782
  * @internal
@@ -791,9 +804,32 @@ function createRpcWireCodec(definitions = EMPTY_WIRE_DEFS) {
791
804
  //#endregion
792
805
  //#region src/rpc/transports/sse-client.ts
793
806
  function NOOP$1() {}
807
+ /** Split the next complete SSE frame (up to a blank line) off the buffer. */
808
+ function takeFrame(buffer) {
809
+ const boundary = buffer.search(/\n\n|\r\n\r\n/);
810
+ if (boundary < 0) return void 0;
811
+ return {
812
+ frame: buffer.slice(0, boundary),
813
+ rest: buffer.slice(boundary + (buffer[boundary] === "\r" ? 4 : 2))
814
+ };
815
+ }
816
+ /** Parse one SSE frame's lines into its event name and data lines. */
817
+ function parseFrame(frame) {
818
+ let event = "message";
819
+ const data = [];
820
+ for (const rawLine of frame.split(/\r?\n/)) {
821
+ if (rawLine.startsWith(":")) continue;
822
+ if (rawLine.startsWith("event:")) event = rawLine.slice(6).trimStart();
823
+ else if (rawLine.startsWith("data:")) data.push(rawLine.slice(5).replace(/^ /, ""));
824
+ }
825
+ return {
826
+ event,
827
+ data
828
+ };
829
+ }
794
830
  /**
795
831
  * Build a birpc `ChannelOptions` object backed by an SSE stream (server →
796
- * client) and HTTP `POST` (client → server) — the WebSocket-free counterpart
832
+ * client) and HTTP `POST` (client → server): the WebSocket-free counterpart
797
833
  * to `createWsRpcChannel`, wire-compatible with `attachSseRpcTransport`.
798
834
  *
799
835
  * The stream is consumed via `fetch` streaming (not `EventSource`), so it
@@ -801,7 +837,7 @@ function NOOP$1() {}
801
837
  * (`event: session`) carries the session id; every `POST` echoes it in the
802
838
  * `x-birpc-session` header. A response to a client-initiated request comes
803
839
  * back in the `POST`'s own body and is re-injected into the channel; a
804
- * dropped stream terminates the channel — there is no reconnect, matching
840
+ * dropped stream terminates the channel; there is no reconnect, matching
805
841
  * the WS channel's closed-is-done semantics.
806
842
  */
807
843
  function createSseRpcChannel(options) {
@@ -852,17 +888,10 @@ function createSseRpcChannel(options) {
852
888
  if (done) break;
853
889
  buffer += decoder.decode(value, { stream: true });
854
890
  for (;;) {
855
- const boundary = buffer.search(/\n\n|\r\n\r\n/);
856
- if (boundary < 0) break;
857
- const frame = buffer.slice(0, boundary);
858
- buffer = buffer.slice(boundary + (buffer[boundary] === "\r" ? 4 : 2));
859
- let event = "message";
860
- const data = [];
861
- for (const rawLine of frame.split(/\r?\n/)) {
862
- if (rawLine.startsWith(":")) continue;
863
- if (rawLine.startsWith("event:")) event = rawLine.slice(6).trimStart();
864
- else if (rawLine.startsWith("data:")) data.push(rawLine.slice(5).replace(/^ /, ""));
865
- }
891
+ const taken = takeFrame(buffer);
892
+ if (!taken) break;
893
+ buffer = taken.rest;
894
+ const { event, data } = parseFrame(taken.frame);
866
895
  if (data.length > 0) dispatch(event, data.join("\n"));
867
896
  }
868
897
  }
@@ -955,8 +984,8 @@ function promiseWithResolver() {
955
984
  //#endregion
956
985
  //#region src/client/rpc-live.ts
957
986
  /**
958
- * The transport-independent half of a live RPC client mode — connection
959
- * status, pending-call guarding, and the trust handshake — shared by the
987
+ * The transport-independent half of a live RPC client mode (connection
988
+ * status, pending-call guarding, and the trust handshake), shared by the
960
989
  * WebSocket and SSE modes. Each transport supplies only its channel.
961
990
  */
962
991
  function createLiveRpcClientMode(options) {
@@ -984,7 +1013,7 @@ function createLiveRpcClientMode(options) {
984
1013
  }
985
1014
  /**
986
1015
  * Wrap an in-flight call promise so it settles on server response, on an
987
- * optional wall-clock timeout, or when the connection drops — never hangs.
1016
+ * optional wall-clock timeout, or when the connection drops, so it never hangs.
988
1017
  */
989
1018
  function guardCall(promise, method) {
990
1019
  return new Promise((resolve, reject) => {
@@ -1053,6 +1082,11 @@ function createLiveRpcClientMode(options) {
1053
1082
  currentAuthToken = token;
1054
1083
  const result = await serverRpc.$call("anonymous:devframe:auth", {
1055
1084
  authToken: token,
1085
+ /**
1086
+ * Sent raw; the server parses it into a display label (see
1087
+ * `describeUA` in `node/auth/state.ts`) so `ua-parser-modern` stays
1088
+ * out of the browser bundle.
1089
+ */
1056
1090
  ua: navigator.userAgent,
1057
1091
  origin: location.origin
1058
1092
  });
@@ -1175,7 +1209,7 @@ function resolveSseUrl(sse, metaBaseUrl, loc) {
1175
1209
  return new URL(str, base).href;
1176
1210
  }
1177
1211
  /**
1178
- * The SSE-backed live client mode — picked by `connectDevframe` when the
1212
+ * The SSE-backed live client mode, picked by `connectDevframe` when the
1179
1213
  * server advertises SSE as its primary transport (`backend: 'sse'`) or when
1180
1214
  * the caller pins `transport: 'sse'`. Same status machine, call guarding,
1181
1215
  * and trust handshake as the WebSocket mode, over `createSseRpcChannel`.
@@ -1218,13 +1252,11 @@ function createSseRpcClientMode(options) {
1218
1252
  * the original `name`, and re-attaches any custom own properties.
1219
1253
  */
1220
1254
  function reviveDumpError(stored) {
1221
- const cause = stored.cause instanceof Error ? stored.cause : isPlainErrorShape(stored.cause) ? reviveDumpError(stored.cause) : stored.cause;
1222
- const error = cause !== void 0 ? new Error(stored.message, { cause }) : new Error(stored.message);
1223
- error.name = stored.name;
1224
- for (const key of Object.keys(stored)) {
1225
- if (key === "name" || key === "message" || key === "cause") continue;
1226
- error[key] = stored[key];
1227
- }
1255
+ const { name, message, cause: rawCause, ...extras } = stored;
1256
+ const cause = rawCause instanceof Error ? rawCause : isPlainErrorShape(rawCause) ? reviveDumpError(rawCause) : rawCause;
1257
+ const error = cause !== void 0 ? new Error(message, { cause }) : new Error(message);
1258
+ error.name = name;
1259
+ Object.assign(error, extras);
1228
1260
  return error;
1229
1261
  }
1230
1262
  function isPlainErrorShape(value) {
@@ -1305,15 +1337,21 @@ async function createStaticRpcClientMode(options) {
1305
1337
  return {
1306
1338
  transport: "static",
1307
1339
  isTrusted: true,
1340
+ /**
1341
+ * A static backend has no live socket; every call is a local fetch, so it
1342
+ * is "connected" for its whole life.
1343
+ */
1308
1344
  status: "connected",
1309
1345
  connectionError: null,
1310
1346
  requestTrust: async () => true,
1311
1347
  requestTrustWithToken: async () => true,
1348
+ /** Static backends are always trusted, so there's nothing to exchange. */
1312
1349
  requestTrustWithCode: async () => null,
1313
1350
  ensureTrusted: async () => true,
1314
1351
  call: (...args) => staticCaller.call(args[0], args.slice(1)),
1315
1352
  callEvent: (...args) => staticCaller.callEvent(args[0], args.slice(1)),
1316
1353
  callOptional: (...args) => staticCaller.callOptional(args[0], args.slice(1)),
1354
+ /** No live socket to close; every call is a local fetch. */
1317
1355
  close: () => {}
1318
1356
  };
1319
1357
  }
@@ -1426,7 +1464,7 @@ const EMPTY_DEFS = /* @__PURE__ */ new Map();
1426
1464
  * Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
1427
1465
  * Pass the result straight to `createRpcClient`'s `channel` option.
1428
1466
  *
1429
- * Also returns `close()`, closing the underlying socket — mirroring the server transport's
1467
+ * Also returns `close()`, closing the underlying socket, mirroring the server transport's
1430
1468
  * existing `WsRpcTransport.close()`. `birpc`'s own `ChannelOptions` has no teardown of its own.
1431
1469
  */
1432
1470
  function createWsRpcChannel(options) {
@@ -1488,7 +1526,7 @@ function createWsRpcChannel(options) {
1488
1526
  * The object / relative-path forms connect to the page's own origin (only the
1489
1527
  * `http`→`ws` protocol swap is applied), resolving the path against where
1490
1528
  * `__connection.json` was loaded. This is deliberately host-agnostic so the
1491
- * connection survives a reverse proxy that changes the domain or port — the
1529
+ * connection survives a reverse proxy that changes the domain or port, since the
1492
1530
  * client trusts its own location, never a server-baked hostname. An explicit
1493
1531
  * `port`/`host` (or a full `ws(s)://` URL string) opts into a cross-origin
1494
1532
  * endpoint, e.g. a side-car server on its own port.
@@ -1643,7 +1681,7 @@ function createScopedClientContext(rpc, namespace) {
1643
1681
  //#region src/client/rpc.ts
1644
1682
  /**
1645
1683
  * Resolve the requested `transport` option against what the server
1646
- * advertises. `'auto'` trusts the advertisement — the server's declared
1684
+ * advertises. `'auto'` trusts the advertisement: the server's declared
1647
1685
  * primary (`backend`), preferring the WebSocket when both endpoints are
1648
1686
  * present; an explicit `'websocket'` / `'sse'` pins that transport and
1649
1687
  * throws when the server doesn't advertise it.
@@ -1663,7 +1701,7 @@ function resolveClientTransport(requested, meta) {
1663
1701
  if (meta.backend === "sse" && hasSse) return "sse";
1664
1702
  if (hasWebsocket) return "websocket";
1665
1703
  if (hasSse) return "sse";
1666
- throw new Error("[devframe] This server advertises no RPC transport (backend \"none\") — nothing to connect to. Enable the WebSocket or SSE endpoint on the server, or use its static/MCP surfaces instead.");
1704
+ throw new Error("[devframe] This server advertises no RPC transport (backend \"none\"), so there is nothing to connect to. Enable the WebSocket or SSE endpoint on the server, or use its static/MCP surfaces instead.");
1667
1705
  }
1668
1706
  async function getDevframeRpcClient(options = {}) {
1669
1707
  const { baseURL = "./", rpcOptions = {}, cacheOptions = false } = options;
@@ -1,9 +1,9 @@
1
1
  //#region src/client-assets.ts
2
2
  /**
3
- * Resolve a definition's client assets source — the built SPA served as its
3
+ * Resolve a definition's client assets source: the built SPA served as its
4
4
  * UI. Prefers the top-level {@link DevframeDefinition.clientAssets} and falls
5
5
  * back to the deprecated `cli.distDir`, so both the new and legacy shapes
6
- * resolve. Returns `undefined` when neither is set (bridge mode — the SPA is
6
+ * resolve. Returns `undefined` when neither is set (bridge mode, where the SPA is
7
7
  * hosted elsewhere).
8
8
  *
9
9
  * Internal: exposed to first-party integrations via `devframe/internal`, not
@@ -1,8 +1,8 @@
1
1
  //#region src/events.d.ts
2
2
  /**
3
- * Centralized registry of the core devframe event names — the node-side host
3
+ * Centralized registry of the core devframe event names: the node-side host
4
4
  * bus events, the client RPC connection events, and the server→client
5
- * broadcast notifications — so these names live in one place instead of
5
+ * broadcast notifications, so these names live in one place instead of
6
6
  * scattered string literals.
7
7
  *
8
8
  * **Keep this in sync with [`docs/content/8.references/3.events.md`](../../../docs/content/8.references/3.events.md)**
@@ -77,6 +77,7 @@ declare const DEVFRAME_EVENTS: {
77
77
  };
78
78
  //#endregion
79
79
  //#region src/constants.d.ts
80
+ /** Devframe runtime routes and static output conventions. */
80
81
  declare const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
81
82
  /**
82
83
  * Global key holding the serializable connection prepared by
@@ -87,7 +88,7 @@ declare const DEVFRAME_CONNECTION_KEY = "__DEVFRAME_CONNECTION__";
87
88
  /**
88
89
  * Route the WebSocket RPC endpoint is bound to, relative to a devframe's
89
90
  * base path. Sits next to `__connection.json` so the deployed SPA can reach
90
- * it on the same origin it loaded from — the dev server shares one port for
91
+ * it on the same origin it loaded from: the dev server shares one port for
91
92
  * both HTTP and WS, and a host server (Vite, etc.) can mount the WS upgrade
92
93
  * handler here without colliding with its own routes (HMR, asset serving).
93
94
  */
@@ -97,7 +98,7 @@ declare const DEVFRAME_WS_ROUTE = "__ws";
97
98
  * path. A single method-dispatched route: `GET` opens the event stream
98
99
  * (server→client), `POST` carries RPC frames (client→server). Sits next to
99
100
  * `__connection.json` so the deployed SPA reaches it on the same origin it
100
- * loaded from — the transport for hosts and proxies where the WebSocket
101
+ * loaded from; the transport for hosts and proxies where the WebSocket
101
102
  * upgrade isn't available.
102
103
  */
103
104
  declare const DEVFRAME_SSE_ROUTE = "__sse";
@@ -111,7 +112,7 @@ declare const DEVFRAME_SSE_SESSION_HEADER = "x-birpc-session";
111
112
  /**
112
113
  * Route the Streamable-HTTP MCP endpoint is bound to, relative to a
113
114
  * devframe's base path. Sits next to `__connection.json` and the WS route
114
- * so an MCP client reaches it on the same origin the SPA loaded from — the
115
+ * so an MCP client reaches it on the same origin the SPA loaded from; the
115
116
  * dev server shares one port for HTTP, WS, and MCP. Opt-in via `cli.mcp`.
116
117
  */
117
118
  declare const DEVFRAME_MCP_ROUTE = "__mcp";
@@ -156,7 +157,7 @@ declare const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin
156
157
  /**
157
158
  * `postMessage` type the remote-assets fallback page posts to `window.parent`
158
159
  * on load. That page is what a devframe serves (with a 502) when its client
159
- * assets can be reached neither locally nor through their CDN provider — the
160
+ * assets can be reached neither locally nor through their CDN provider; the
160
161
  * message lets an embedding viewer replace the bare page with its own UI
161
162
  * (`@devframes/hub-ui` does, in its iframe view). Payload shape:
162
163
  * `RemoteAssetsErrorMessage` (`devframe/types`).
@@ -164,7 +165,7 @@ declare const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin
164
165
  declare const DEVFRAME_REMOTE_ASSETS_ERROR_MESSAGE_TYPE: string;
165
166
  /**
166
167
  * Prefix that marks an RPC method as callable before a connection is
167
- * trusted. This is the *only* rule the pre-trust gate applies — there is no
168
+ * trusted. This is the *only* rule the pre-trust gate applies; there is no
168
169
  * per-method allowlist. Any handshake method a host adapter needs to reach
169
170
  * before authentication must be named `anonymous:<rest>` (e.g.
170
171
  * `anonymous:devframe:auth`).