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 { d as RpcFunctionsCollectorBase } from "./index-BzyopqxV.mjs";
2
- import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-CMdPYhOx.mjs";
3
- import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "./ws-server-VyHlanzy.mjs";
4
- import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-B13_vRkJ.mjs";
5
- import { m as defineDiagnostics } from "./nostics-SPGDgHEP.mjs";
1
+ import { d as RpcFunctionsCollectorBase } from "./index-pIVt92jP.mjs";
2
+ import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-Dq4i156u.mjs";
3
+ import { c as DevframeNodeRpcSessionMeta, l as DevframeRpcConnection } from "./ws-server-D2nv68Hg.mjs";
4
+ import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-eBvSKZMS.mjs";
5
+ import { m as defineDiagnostics } from "./nostics-0sKe5HIj.mjs";
6
6
  import { BirpcReturn } from "birpc";
7
7
  import { StandardSchemaV1 } from "@standard-schema/spec";
8
8
  import { CAC } from "cac";
@@ -91,15 +91,15 @@ interface AgentTool {
91
91
  title: string;
92
92
  /** Human-readable description shown to the agent. */
93
93
  description: string;
94
- /** Safety classification — drives MCP hint annotations downstream. */
94
+ /** Safety classification; drives MCP hint annotations downstream. */
95
95
  safety: 'read' | 'action' | 'destructive';
96
96
  /** Free-form tags for grouping/filtering. */
97
97
  tags?: readonly string[];
98
- /** Present for `kind === 'rpc'` — points to the RPC function name. */
98
+ /** Present for `kind === 'rpc'`; points to the RPC function name. */
99
99
  rpcName?: string;
100
100
  /**
101
101
  * Positional Standard Schemas describing a `kind: 'tool'` entry's
102
- * arguments — carried on the tool itself (mirroring how `rpcName` defers
102
+ * arguments, carried on the tool itself (mirroring how `rpcName` defers
103
103
  * an RPC-backed tool's schemas to `ctx.rpc.definitions`) so consumers
104
104
  * (e.g. the MCP adapter) convert Standard Schema → JSON Schema on demand,
105
105
  * same as RPC `args`.
@@ -126,7 +126,7 @@ interface AgentToolInput {
126
126
  safety?: 'read' | 'action' | 'destructive';
127
127
  tags?: readonly string[];
128
128
  /**
129
- * Positional Standard Schemas describing the tool's arguments — the same
129
+ * Positional Standard Schemas describing the tool's arguments, the same
130
130
  * shape RPC definitions carry (any [Standard Schema](https://standardschema.dev/)
131
131
  * validator: valibot, zod, arktype, devframe's built-in `s` builder, …).
132
132
  * Each is advertised under `arg0` / `arg1` / … on the tool's JSON-Schema
@@ -166,7 +166,7 @@ interface AgentResourceInput {
166
166
  name: string;
167
167
  description?: string;
168
168
  mimeType?: string;
169
- /** Optional URI override — if omitted, a `devframe://resource/<id>` URI is generated. */
169
+ /** Optional URI override; if omitted, a `devframe://resource/<id>` URI is generated. */
170
170
  uri?: string;
171
171
  /** Snapshot reader. Called on each read. */
172
172
  read: () => Promise<AgentResourceContent> | AgentResourceContent;
@@ -195,7 +195,7 @@ interface AgentHandle {
195
195
  }
196
196
  /**
197
197
  * A lazy source of agent tools, queried at `list()` / `getTool()` /
198
- * `invoke()` time — the same on-demand projection the host applies to
198
+ * `invoke()` time, the same on-demand projection the host applies to
199
199
  * `agent`-flagged RPC definitions. Use a provider when tools *derive from*
200
200
  * other state (a command registry, a plugin catalog): the underlying state
201
201
  * stays the single source of truth and nothing needs to be kept in sync.
@@ -225,7 +225,7 @@ interface DevframeAgentHostEvents {
225
225
  'agent:resource:registered': (resource: AgentResource) => void;
226
226
  'agent:resource:unregistered': (id: string) => void;
227
227
  /**
228
- * Fires when the unified manifest changes — including when a new
228
+ * Fires when the unified manifest changes, including when a new
229
229
  * RPC function with an `agent` field is registered on `ctx.rpc`.
230
230
  */
231
231
  'agent:manifest:changed': () => void;
@@ -247,7 +247,7 @@ interface DevframeAgentHost {
247
247
  /** Unregister a previously registered tool by id. */
248
248
  unregisterTool: (id: string) => boolean;
249
249
  /**
250
- * Register a lazy tool source, queried on demand — see
250
+ * Register a lazy tool source, queried on demand; see
251
251
  * {@link AgentToolProvider}.
252
252
  */
253
253
  registerToolProvider: (provider: AgentToolProvider) => AgentToolProviderHandle;
@@ -261,6 +261,13 @@ interface DevframeAgentHost {
261
261
  * tools/resources registered on the host.
262
262
  */
263
263
  list: () => AgentManifest;
264
+ /**
265
+ * Whether the devframe exposes anything to agents: an `agent`-flagged RPC
266
+ * function, a registered tool or resource, or a provider currently
267
+ * yielding at least one tool. The `mcp: 'auto'` default consults this to
268
+ * decide whether a route is worth mounting.
269
+ */
270
+ hasSurface: () => boolean;
264
271
  /**
265
272
  * Invoke any tool by id. Routes to the underlying RPC handler for
266
273
  * `kind === 'rpc'`, or to the registered handler for `kind === 'tool'`.
@@ -276,7 +283,7 @@ interface DevframeAgentHost {
276
283
  //#endregion
277
284
  //#region src/adapters/flags.d.ts
278
285
  /**
279
- * Schema map for typed CLI flags. Keys are flag names in camelCase —
286
+ * Schema map for typed CLI flags. Keys are flag names in camelCase, so
280
287
  * this matches CAC's parsed-flag output ( `--no-open` → `noOpen` ). Each
281
288
  * value is any [Standard Schema](https://standardschema.dev/) validator
282
289
  * (valibot, zod, arktype, devframe's built-in `s`, …) used to both (a)
@@ -285,7 +292,7 @@ interface DevframeAgentHost {
285
292
  */
286
293
  type CliFlagsSchema = Record<string, StandardSchemaV1>;
287
294
  /**
288
- * Identity helper that preserves the literal schema-map type — use this
295
+ * Identity helper that preserves the literal schema-map type; use this
289
296
  * so `InferCliFlags<typeof myFlags>` resolves to the right object shape.
290
297
  *
291
298
  * ```ts
@@ -321,14 +328,14 @@ declare function parseCliFlags(schema: CliFlagsSchema, raw: Record<string, unkno
321
328
  * the handshake RPC functions, the resolver gate, the connect-time trust
322
329
  * hook, and the startup banner.
323
330
  *
324
- * `initDevframe` / `initHub` accept one of these directly via their `auth` option —
325
- * see {@link https://devfra.me | devframe}'s server docs — or a host can
331
+ * `initDevframe` / `initHub` accept one of these directly via their `auth` option
332
+ * (see {@link https://devfra.me | devframe}'s server docs), or a host can
326
333
  * wire the four pieces itself against a lower-level transport.
327
334
  */
328
335
  interface DevframeAuthHandler {
329
336
  /**
330
337
  * `anonymous:devframe:auth` + `anonymous:devframe:auth:exchange` (the
331
- * handshake) and `devframe:auth:revoke` (self-revoke) — register these on
338
+ * handshake) and `devframe:auth:revoke` (self-revoke); register these on
332
339
  * the RPC host (e.g. `rpcHost.register(fn)` for each).
333
340
  */
334
341
  rpcFunctions: RpcFunctionDefinitionAny[];
@@ -343,18 +350,18 @@ interface DevframeAuthHandler {
343
350
  * Connect-time trust: reads a bearer token off the connection's initial
344
351
  * request (a static/pre-shared token from `clientAuthTokens`, or a token
345
352
  * minted by the code exchange) and, when valid, marks the session
346
- * trusted immediately — before the client's own handshake call.
353
+ * trusted immediately, before the client's own handshake call.
347
354
  */
348
355
  onConnect: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
349
356
  /**
350
357
  * Print the current one-time code and its magic-link URL. Devframe stays
351
- * headless — call this yourself once the server is listening. Safe to
358
+ * headless, so call this yourself once the server is listening. Safe to
352
359
  * call repeatedly; it only prints once per code.
353
360
  */
354
361
  printBanner: () => void;
355
362
  /**
356
363
  * Rewrite a URL the CLI is about to open in the browser (`--open`) so the
357
- * tab lands already authenticated — e.g. appending the current OTP as a
364
+ * tab lands already authenticated, e.g. appending the current OTP as a
358
365
  * query param. Called with the fully-resolved target URL; return it
359
366
  * unchanged to opt out. Optional: a handler that doesn't need this (e.g.
360
367
  * one gated by a pre-shared bearer token instead of an interactive code)
@@ -373,7 +380,7 @@ interface DevframeAuthHandler {
373
380
  */
374
381
  type DevframeDiagnosticsLogger = Record<string, any>;
375
382
  /**
376
- * Host for structured diagnostics — a thin layer over `nostics` that lets
383
+ * Host for structured diagnostics: a thin layer over `nostics` that lets
377
384
  * integrations register their own coded errors/warnings into a shared
378
385
  * registry without taking a direct dependency on `nostics`.
379
386
  *
@@ -398,9 +405,9 @@ type DevframeDiagnosticsLogger = Record<string, any>;
398
405
  interface DevframeDiagnosticsHost {
399
406
  /**
400
407
  * Proxy-backed lookup of every registered diagnostic handle by code name.
401
- * Resolves to a `nostics` `DiagnosticHandle` — a callable that builds a
408
+ * Resolves to a `nostics` `DiagnosticHandle`: a callable that builds a
402
409
  * diagnostic and routes it through registered reporters; prefix with
403
- * `throw` to raise. Loosely typed — for autocompletion, keep a reference
410
+ * `throw` to raise. Loosely typed; for autocompletion, keep a reference
404
411
  * to the typed result of `defineDiagnostics()` instead.
405
412
  */
406
413
  readonly logger: DevframeDiagnosticsLogger;
@@ -408,7 +415,7 @@ interface DevframeDiagnosticsHost {
408
415
  * Register additional diagnostic definitions with this host. After
409
416
  * registration, codes from the new definition are reachable via
410
417
  * `host.logger.CODE`. Plugins that want shared output formatting should
411
- * build their diagnostics via `host.defineDiagnostics()` first — that
418
+ * build their diagnostics via `host.defineDiagnostics()` first; that
412
419
  * factory pre-wires the host's ANSI console reporter.
413
420
  */
414
421
  register: (definitions: Record<string, unknown>) => void;
@@ -424,12 +431,12 @@ interface DevframeDiagnosticsHost {
424
431
  //#region src/types/host.d.ts
425
432
  interface DevframeHost {
426
433
  /**
427
- * Serve static assets at the given URL base — a local directory, or a
434
+ * Serve static assets at the given URL base: a local directory, or a
428
435
  * resolved {@link RemoteAssetsStore} back-proxy. Called by
429
436
  * `DevframeViewHost.hostStatic` (which normalizes `RemoteAssets`
430
437
  * declarations into stores first). Implementations map this to whatever
431
438
  * the underlying runtime expects (Vite middleware, h3 handler, no-op
432
- * for build snapshots) — the shared engine in
439
+ * for build snapshots); the shared engine in
433
440
  * `devframe/utils/serve-static` accepts either shape.
434
441
  */
435
442
  mountStatic: (base: string, source: string | RemoteAssetsStore) => void | Promise<void>;
@@ -440,7 +447,7 @@ interface DevframeHost {
440
447
  *
441
448
  * Called by `ctx.install` for each mounted devframe (alongside
442
449
  * `mountStatic`). Without it, an embedded SPA can only discover the
443
- * endpoint by inheriting it from a same-origin parent window — which fails
450
+ * endpoint by inheriting it from a same-origin parent window, which fails
444
451
  * for cross-origin or sandboxed iframes. Implementations serve the same
445
452
  * meta they expose at the hub's own base.
446
453
  *
@@ -465,15 +472,15 @@ interface DevframeHost {
465
472
  * collide between, say, the Vite host (`.vite/devframe`) and a
466
473
  * standalone CLI host (`.<appName>/devframe`).
467
474
  *
468
- * - `workspace` — state shared with the whole team through version
475
+ * - `workspace`: state shared with the whole team through version
469
476
  * control (saved queries, shared presets). Conventionally
470
477
  * `${workspaceRoot}/.devframe/`; hosts must place it somewhere
471
478
  * committable.
472
- * - `project` — per-checkout private state (caches, personal
479
+ * - `project`: per-checkout private state (caches, personal
473
480
  * settings). Typically under
474
481
  * `${cwd}/node_modules/.<appName>/devframe/`, which version
475
482
  * control ignores.
476
- * - `global` — per-user state (auth tokens, machine-wide
483
+ * - `global`: per-user state (auth tokens, machine-wide
477
484
  * preferences). Typically under
478
485
  * `${homedir()}/.<appName>/devframe/`.
479
486
  *
@@ -553,7 +560,7 @@ interface DevframeRpcServerFunctions {
553
560
  * an auto-trust noop when `auth: false`.
554
561
  *
555
562
  * Named with the `anonymous:` prefix (see `isAnonymousRpcMethod`) so it is
556
- * reachable before the connection is trusted — this is the *only* rule the
563
+ * reachable before the connection is trusted; this is the *only* rule the
557
564
  * pre-trust gate applies, no per-method allowlist.
558
565
  *
559
566
  * @internal
@@ -665,7 +672,7 @@ interface DevframeRpcServerFunctions {
665
672
  */
666
673
  interface DevframeRpcSharedStates {
667
674
  /**
668
- * Wire-service advertisements — package name → `{ package, version,
675
+ * Wire-service advertisements: package name → `{ package, version,
669
676
  * scope, meta }` for every installed {@link import('./services').DevframeServiceDefinition}.
670
677
  * Written by the node services host at the `ready()` barrier; clients read
671
678
  * it through `client.services` (or subscribe to it directly for
@@ -758,9 +765,9 @@ interface DevframeSettingsStore<T extends Record<string, any> = Record<string, a
758
765
  /**
759
766
  * The two settings scopes available on a scoped context.
760
767
  *
761
- * - `project` — per-workspace state, persisted under the host's
768
+ * - `project`: per-workspace state, persisted under the host's
762
769
  * `workspace` storage dir. Project-local settings.
763
- * - `global` — per-user state, persisted under the host's `global`
770
+ * - `global`: per-user state, persisted under the host's `global`
764
771
  * storage dir. Machine-wide preferences.
765
772
  */
766
773
  interface DevframeSettings<T extends Record<string, any> = Record<string, any>> {
@@ -914,7 +921,7 @@ interface DevframeServicesScopeRegistry {}
914
921
  /** Resolved RPC scope namespace for a service package name, or `string`. */
915
922
  type DevframeServiceScopeOf<PKG> = PKG extends keyof DevframeServicesScopeRegistry ? DevframeServicesScopeRegistry[PKG] & string : string;
916
923
  /**
917
- * A **wire service** — a shared server-side capability (e.g. open-in-editor,
924
+ * A **wire service**: a shared server-side capability (e.g. open-in-editor,
918
925
  * syntax highlighting) packaged so any devframe host can install it once and
919
926
  * every plugin/client can consume it without re-implementing or re-bundling
920
927
  * it. Contrast with plain {@link DevframeServicesHost.provide}, which shares
@@ -925,16 +932,16 @@ type DevframeServiceScopeOf<PKG> = PKG extends keyof DevframeServicesScopeRegist
925
932
  * feature-detect it (`ctx.services.has(pkg)`) and degrade gracefully.
926
933
  *
927
934
  * Ship one per npm package (`@devframes/service-<slug>` for first-party),
928
- * with the package's default export being the `create<X>Service` factory —
935
+ * with the package's default export being the `create<X>Service` factory,
929
936
  * never a pre-built instance.
930
937
  */
931
938
  interface DevframeServiceDefinition<API = unknown, Options = any> {
932
939
  /**
933
- * The npm package name this service ships in — also its registry key
940
+ * The npm package name this service ships in, also its registry key
934
941
  * (`ctx.services.has('@devframes/service-x')` on both node and client).
935
942
  */
936
943
  package: string;
937
- /** Semver of the service — advertised to clients, checked against descriptor ranges. */
944
+ /** Semver of the service, advertised to clients and checked against descriptor ranges. */
938
945
  version: string;
939
946
  /**
940
947
  * RPC namespace the service's functions register under, following the
@@ -944,7 +951,7 @@ interface DevframeServiceDefinition<API = unknown, Options = any> {
944
951
  scope: string;
945
952
  /**
946
953
  * Extra advertised metadata (feature flags, defaults, …). Must be
947
- * JSON-serializable — it is mirrored to every client.
954
+ * JSON-serializable, since it is mirrored to every client.
948
955
  */
949
956
  meta?: Record<string, unknown>;
950
957
  /**
@@ -961,18 +968,18 @@ interface DevframeServiceDefinition<API = unknown, Options = any> {
961
968
  mergeOptions?: (sets: Options[]) => Options;
962
969
  /**
963
970
  * Construct the service: register its RPC functions on the pre-scoped
964
- * context and return its **node API** — the in-process surface other
971
+ * context and return its **node API**: the in-process surface other
965
972
  * plugins get from `ctx.services.get(package)` (no RPC hop server-side).
966
973
  * `info.options` carries every installer's option sets merged at the
967
974
  * `ready()` barrier (via {@link mergeOptions} when present, otherwise a
968
- * shallow merge in declaration order — later sets win).
975
+ * shallow merge in declaration order, later sets win).
969
976
  */
970
977
  setup: (ctx: DevframeScopedNodeContext, info: {
971
978
  options?: Options;
972
979
  }) => API | Promise<API>;
973
980
  }
974
981
  /**
975
- * Declarative reference to a service package — the form a
982
+ * Declarative reference to a service package: the form a
976
983
  * {@link DevframeServiceInput} takes when the installer doesn't hold the
977
984
  * factory itself (e.g. `DevframeDefinition.services`). The host imports the
978
985
  * package's default-export factory and installs the resulting definition at
@@ -983,13 +990,13 @@ interface DevframeServiceDescriptor<Options = any> {
983
990
  package: string;
984
991
  /**
985
992
  * Accepted semver range for the installed service. An unsatisfied range
986
- * warns (`DF0069`) — or throws (`DF0068`) when {@link required} — while the
993
+ * warns (`DF0069`), or throws (`DF0068`) when {@link required}, while the
987
994
  * service still installs; the advertised meta carries the real version.
988
995
  */
989
996
  version?: string;
990
997
  /**
991
998
  * Fail hard when the service can't be imported or its version range isn't
992
- * satisfied. By default a missing service is skipped silently — clients see
999
+ * satisfied. By default a missing service is skipped silently; clients see
993
1000
  * `has() === false` and degrade.
994
1001
  *
995
1002
  * @default false
@@ -1002,7 +1009,7 @@ interface DevframeServiceDescriptor<Options = any> {
1002
1009
  * What can be passed to `ctx.services.install()` (and listed in
1003
1010
  * `DevframeDefinition.services`): a declarative {@link DevframeServiceDescriptor}
1004
1011
  * (the host imports the factory) or a ready {@link DevframeServiceDefinition}
1005
- * (the installer already called the factory — its `options` join the merge).
1012
+ * (the installer already called the factory, so its `options` join the merge).
1006
1013
  */
1007
1014
  type DevframeServiceInput<API = unknown, Options = any> = DevframeServiceDescriptor<Options> | DevframeServiceDefinition<API, Options>;
1008
1015
  /**
@@ -1010,7 +1017,7 @@ type DevframeServiceInput<API = unknown, Options = any> = DevframeServiceDescrip
1010
1017
  * `devframe:services` shared state.
1011
1018
  */
1012
1019
  interface DevframeServiceMeta {
1013
- /** npm package name — the registry key. */
1020
+ /** npm package name, the registry key. */
1014
1021
  package: string;
1015
1022
  /** Installed version of the service. */
1016
1023
  version: string;
@@ -1033,7 +1040,7 @@ interface DevframeServicesHost {
1033
1040
  get: <ID extends DevframeServiceId>(id: ID) => DevframeServiceOf<ID> | undefined;
1034
1041
  has: (id: DevframeServiceId) => boolean;
1035
1042
  /**
1036
- * Run `callback` with the service as soon as it is available — immediately
1043
+ * Run `callback` with the service as soon as it is available: immediately
1037
1044
  * when already provided, otherwise on `provide`. Survives provider/consumer
1038
1045
  * setup-order differences. The callback also re-fires if the service is
1039
1046
  * revoked and provided again. Returns an unsubscribe function.
@@ -1043,7 +1050,7 @@ interface DevframeServicesHost {
1043
1050
  keys: () => string[];
1044
1051
  /**
1045
1052
  * Install a **wire service** (see {@link DevframeServiceDefinition}). The
1046
- * common path is declarative — list services on `DevframeDefinition.services`
1053
+ * common path is declarative: list services on `DevframeDefinition.services`
1047
1054
  * (or `initHub({ services })`) and the adapter installs them for you before
1048
1055
  * `setup` runs. Call `install()` directly only for the dynamic escape hatch:
1049
1056
  * a service configured at runtime from data unknown until then.
@@ -1051,7 +1058,7 @@ interface DevframeServicesHost {
1051
1058
  * Before the pre-setup ready fires, installs are queued and their option
1052
1059
  * sets deep-merged, constructing each service **once**. After it, an install
1053
1060
  * constructs immediately; installing an already-installed package returns
1054
- * the existing API (a warning — `DF0066` — when the late install carried
1061
+ * the existing API (a warning, `DF0066`, when the late install carried
1055
1062
  * options, since they're ignored). The returned promise resolves with the
1056
1063
  * node API (or `undefined` when an optional descriptor's package can't be
1057
1064
  * imported).
@@ -1065,7 +1072,7 @@ interface DevframeServicesHost {
1065
1072
  resolveFrom?: string | null;
1066
1073
  }) => Promise<API | undefined>;
1067
1074
  /**
1068
- * Construct every queued service — importing descriptor packages, merging
1075
+ * Construct every queued service, importing descriptor packages, merging
1069
1076
  * option sets, `provide()`-ing each node API under its package name, and
1070
1077
  * advertising it to clients via the `devframe:services` shared state.
1071
1078
  * Idempotent. **Internal**: the adapters call it once, before running any
@@ -1089,28 +1096,28 @@ type DevframeDeploymentKind = 'standalone' | 'hosted';
1089
1096
  * How a hub deduplicates devframes that share an `id` when more than one
1090
1097
  * is mounted onto the same hub. See {@link DevframeDefinition.duplicationStrategy}.
1091
1098
  *
1092
- * - `'warn'` (default) — keep the first registration, drop later
1099
+ * - `'warn'` (default): keep the first registration, drop later
1093
1100
  * duplicates, and emit a warning diagnostic (`DF8105`).
1094
- * - `'silent'` — drop later duplicates without warning.
1095
- * - `'throw'` — throw when a duplicate is mounted.
1096
- * - `'duplicate'` — let every instance coexist under a disambiguated
1101
+ * - `'silent'`: drop later duplicates without warning.
1102
+ * - `'throw'`: throw when a duplicate is mounted.
1103
+ * - `'duplicate'`: let every instance coexist under a disambiguated
1097
1104
  * dock id.
1098
1105
  */
1099
1106
  type DevframeDuplicationStrategy = 'warn' | 'silent' | 'throw' | 'duplicate';
1100
1107
  /**
1101
- * Controls where the browser opens the RPC WebSocket — advertised in
1108
+ * Controls where the browser opens the RPC WebSocket, advertised in
1102
1109
  * `__connection.json` and used to bind the dev server. The three shapes map
1103
1110
  * to the three connection scenarios; precedence is `url` > `port` > `route`:
1104
1111
  *
1105
- * 1. **Same server, different route** (default) — leave `port`/`url` unset.
1112
+ * 1. **Same server, different route** (default): leave `port`/`url` unset.
1106
1113
  * The socket shares the HTTP server's port and binds to `route`
1107
1114
  * (`__ws`). The client connects to its own origin, so the link
1108
1115
  * survives a reverse proxy that rewrites the host/port/subpath.
1109
1116
  *
1110
- * 2. **Different port** — set `port`. The socket binds on its own port on the
1117
+ * 2. **Different port**: set `port`. The socket binds on its own port on the
1111
1118
  * same host; the client targets `ws(s)://<page-host>:<port>/<route>`.
1112
1119
  *
1113
- * 3. **Remote, different origin** — set `url` to a full `ws://`/`wss://`
1120
+ * 3. **Remote, different origin**: set `url` to a full `ws://`/`wss://`
1114
1121
  * endpoint (e.g. a public tunnel or relay). The client uses it verbatim.
1115
1122
  */
1116
1123
  interface DevframeWsOptions {
@@ -1139,7 +1146,7 @@ interface DevframeWsOptions {
1139
1146
  url?: string;
1140
1147
  }
1141
1148
  /**
1142
- * Controls the SSE RPC endpoint — the WebSocket-free transport for hosts
1149
+ * Controls the SSE RPC endpoint, the WebSocket-free transport for hosts
1143
1150
  * and proxies where the upgrade isn't available. It rides whatever HTTP
1144
1151
  * surface serves the instance (the same one serving `__connection.json`),
1145
1152
  * so a relative `route` always resolves; there is no port plumbing of its
@@ -1153,9 +1160,43 @@ interface DevframeSseOptions {
1153
1160
  */
1154
1161
  route?: string;
1155
1162
  }
1163
+ /**
1164
+ * An **optional** identity check layered on top of the origin gate. The
1165
+ * route-based MCP endpoint trusts same-machine callers by default (the
1166
+ * loopback origin gate is enough), so this is opt-in hardening for the cases
1167
+ * where a same-machine process is not a trust boundary, like a LAN/tunnel
1168
+ * origin, a shared/CI box, or a destructive tool surface:
1169
+ *
1170
+ * - a non-empty **bearer token string**: the request must carry
1171
+ * `Authorization: Bearer <token>`, compared in constant time. Back it with
1172
+ * an environment variable rather than a literal;
1173
+ * - a **callback** `(request) => boolean | Promise<boolean>`: a custom
1174
+ * identity check (validate a signed header, an mTLS-derived claim, …). It
1175
+ * only governs identity and cannot relax the origin gate;
1176
+ * - `false`, the default: **origin-only**, trusting same-machine callers.
1177
+ */
1178
+ type McpAuthorization = string | ((request: Request) => boolean | Promise<boolean>) | false;
1179
+ /**
1180
+ * The route-based MCP setting accepted everywhere a host mounts a devframe
1181
+ * (`cli.mcp`, `initDevframe` / `initHub` / `createDevServer` options, the
1182
+ * framework kits):
1183
+ *
1184
+ * - `'auto'`, the default: mount the route when the devframe exposes an
1185
+ * agent surface (an `agent`-flagged RPC function, or a tool / resource /
1186
+ * provider registered on `ctx.agent`). An empty agent surface mounts
1187
+ * nothing and loads no MCP code.
1188
+ * - `true`: always mount at the default `__mcp` route.
1189
+ * - `false`: never mount.
1190
+ * - {@link McpRouteOptions}: always mount, with a custom route path, origin
1191
+ * allow-list, or {@link McpAuthorization} identity check.
1192
+ *
1193
+ * A mounted route trusts same-machine callers by default (the loopback
1194
+ * origin gate), exactly like `mcp: true`.
1195
+ */
1196
+ type McpSetting = boolean | 'auto' | McpRouteOptions;
1156
1197
  /**
1157
1198
  * Configuration for the route-based MCP server mounted alongside the dev
1158
- * server (opt-in via {@link DevframeCliOptions.mcp}). The endpoint speaks
1199
+ * server (via {@link DevframeCliOptions.mcp}). The endpoint speaks
1159
1200
  * the MCP Streamable-HTTP transport over the same origin as the SPA,
1160
1201
  * exposing the definition's `ctx.agent` tools + shared-state resources to
1161
1202
  * external MCP clients connected to the *running* server.
@@ -1166,6 +1207,16 @@ interface McpRouteOptions {
1166
1207
  * Default: `__mcp` (i.e. `/__mcp` standalone, `/__<id>/__mcp` hosted).
1167
1208
  */
1168
1209
  path?: string;
1210
+ /**
1211
+ * Optional identity check, layered on top of the origin gate and checked
1212
+ * **after** it. Defaults to origin-only (`false`): the route trusts
1213
+ * same-machine callers, since the loopback origin gate already keeps
1214
+ * arbitrary remote/browser callers out. Set a bearer token or a callback to
1215
+ * harden the route when a same-machine process is not your trust boundary
1216
+ * (LAN/tunnel origin, shared/CI host, destructive tools). See
1217
+ * {@link McpAuthorization}.
1218
+ */
1219
+ authorization?: McpAuthorization;
1169
1220
  /**
1170
1221
  * Extra `Origin` header values to accept beyond the loopback default
1171
1222
  * (`localhost`/`127.0.0.1`/`::1` and any `Origin`-less native client).
@@ -1173,10 +1224,12 @@ interface McpRouteOptions {
1173
1224
  * host, mirroring the WS transport's origin gate. Pass `false` to disable
1174
1225
  * origin checking entirely (not recommended). Default: loopback-only.
1175
1226
  *
1176
- * This is the endpoint's DNS-rebinding protection — the shared
1227
+ * This is the endpoint's DNS-rebinding protection: the shared
1177
1228
  * `isAllowedOrigin` gate the WS upgrade already uses, applied as external
1178
1229
  * middleware (the approach the MCP SDK now recommends over its own
1179
- * deprecated `allowedHosts`/`allowedOrigins` transport flags).
1230
+ * deprecated `allowedHosts`/`allowedOrigins` transport flags). When you
1231
+ * widen it past loopback, layer on {@link McpRouteOptions.authorization} to
1232
+ * prove identity too.
1180
1233
  */
1181
1234
  allowedOrigins?: readonly string[] | false;
1182
1235
  }
@@ -1200,16 +1253,16 @@ interface DevframeCliOptions {
1200
1253
  /**
1201
1254
  * Authentication for the standalone dev server.
1202
1255
  *
1203
- * - `undefined` / `true` — the standalone adapters (`cli` /
1256
+ * - `undefined` / `true`: the standalone adapters (`cli` /
1204
1257
  * served `build`) auto-wire devframe's interactive OTP auth
1205
1258
  * (`createInteractiveAuth`): an untrusted client can only reach
1206
1259
  * `anonymous:` methods until it exchanges the printed one-time code.
1207
1260
  * The adapter prints the code + magic-link banner once the server is
1208
1261
  * listening.
1209
- * - `false` — no gate, for trusted single-user localhost tools where an
1262
+ * - `false`: no gate, for trusted single-user localhost tools where an
1210
1263
  * auth round-trip only gets in the way (the built-in plugins set this).
1211
1264
  * The `--no-auth` CLI flag maps here for one-off runs.
1212
- * - A {@link DevframeAuthHandler} — a custom handler (e.g. a tuned
1265
+ * - A {@link DevframeAuthHandler}: a custom handler (e.g. a tuned
1213
1266
  * `createInteractiveAuth`, or an entirely different scheme) passed
1214
1267
  * straight through to the RPC transport binding.
1215
1268
  *
@@ -1220,21 +1273,29 @@ interface DevframeCliOptions {
1220
1273
  */
1221
1274
  auth?: boolean | DevframeAuthHandler;
1222
1275
  /**
1223
- * Expose a route-based MCP server alongside the dev server, speaking the
1224
- * MCP Streamable-HTTP transport at `/__mcp` (relative to the base path).
1225
- * It surfaces the same `ctx.agent` tools + shared-state resources as the
1226
- * stdio `mcp` command, but against the live, running server.
1276
+ * Expose a route-based MCP server alongside the standalone dev server,
1277
+ * speaking the MCP Streamable-HTTP transport at `/__mcp` (relative to the
1278
+ * base path). It surfaces the same `ctx.agent` tools + shared-state
1279
+ * resources as the stdio `mcp` command, but against the live server.
1280
+ *
1281
+ * Defaults to `'auto'`: the route mounts once the devframe exposes an
1282
+ * agent surface (an `agent`-flagged RPC, a registered tool / resource).
1283
+ * See {@link McpSetting} for the full contract, and
1284
+ * {@link McpRouteOptions} for the route path, origin allow-list, and
1285
+ * {@link McpAuthorization} identity check.
1227
1286
  *
1228
- * - `false` / omitted (default) — no MCP route is mounted.
1229
- * - `true` — mount at the default `__mcp` route with the loopback-only
1230
- * origin gate.
1231
- * - {@link McpRouteOptions} — customise the route path / allowed origins.
1287
+ * The `--mcp` / `--no-mcp` CLI flags override this per run. Whether to expose
1288
+ * MCP is a hosting decision, so programmatic hosts pass it to
1289
+ * `initDevframe` / `initHub` / `createDevServer` instead.
1232
1290
  *
1233
- * The `--mcp` / `--no-mcp` CLI flags override this per run.
1291
+ * @deprecated Whether to expose MCP is a hosting decision, not a capability
1292
+ * of the tool. Pass `mcp` to `createCac` (or the programmatic host) instead.
1293
+ * This field is still read as a fallback, and will be removed in a future
1294
+ * release.
1234
1295
  */
1235
- mcp?: boolean | McpRouteOptions;
1296
+ mcp?: McpSetting;
1236
1297
  /**
1237
- * Author's SPA dist — served as the devframe's UI.
1298
+ * Author's SPA dist, served as the devframe's UI.
1238
1299
  *
1239
1300
  * @deprecated Moved to the top-level {@link DevframeDefinition.clientAssets}.
1240
1301
  * Set `clientAssets` on the definition instead. This field is still read as a
@@ -1245,11 +1306,11 @@ interface DevframeCliOptions {
1245
1306
  * How the browser reaches the RPC WebSocket. Defaults to sharing the HTTP
1246
1307
  * port on the `__ws` route. See {@link DevframeWsOptions} for the
1247
1308
  * different-port and remote-origin variants. Pass `false` to serve no
1248
- * WebSocket at all — clients connect over SSE instead (`backend: 'sse'`).
1309
+ * WebSocket at all; clients connect over SSE instead (`backend: 'sse'`).
1249
1310
  */
1250
1311
  ws?: DevframeWsOptions | false;
1251
1312
  /**
1252
- * How the browser reaches the SSE RPC endpoint — enabled by default
1313
+ * How the browser reaches the SSE RPC endpoint, enabled by default
1253
1314
  * alongside the WebSocket as the more portable transport. Pass `false`
1254
1315
  * to disable, or a {@link DevframeSseOptions} to change its route.
1255
1316
  */
@@ -1291,7 +1352,7 @@ interface DevframeCliOptions {
1291
1352
  }
1292
1353
  /**
1293
1354
  * Default dock attributes for the iframe entry a hub synthesizes when it
1294
- * mounts this devframe. Framework-neutral metadata only — the hub layer
1355
+ * mounts this devframe. Framework-neutral metadata only; the hub layer
1295
1356
  * (`ctx.install`) merges these beneath its per-mount `dock` overrides,
1296
1357
  * which in turn sit beneath the locked, derived `id` / `type` / `url`.
1297
1358
  *
@@ -1325,7 +1386,7 @@ interface DevframeDockDefaults {
1325
1386
  /**
1326
1387
  * Render-only visibility expression, same syntax as {@link when}. Hides the
1327
1388
  * entry's own dock-bar button when it evaluates to `false` while leaving it
1328
- * registered and reachable (activation, RPC lookups, etc.) — unlike `when`,
1389
+ * registered and reachable (activation, RPC lookups, etc.), unlike `when`,
1329
1390
  * which is the general relevance switch for the entry as a whole.
1330
1391
  */
1331
1392
  visibility?: string;
@@ -1372,13 +1433,13 @@ interface DevframeDefinition {
1372
1433
  * everything against the plugin's own installed packages rather than the
1373
1434
  * consuming app's.
1374
1435
  *
1375
- * - **Remote assets** — becomes the default `resolveFrom` for any remote
1436
+ * - **Remote assets**: becomes the default `resolveFrom` for any remote
1376
1437
  * {@link StaticAssetsSource} the devframe hosts (its `clientAssets`, and
1377
1438
  * every `ctx.views.hostStatic` call) that doesn't set one explicitly, so a
1378
1439
  * locally installed copy of the assets package is served with zero
1379
1440
  * network. A per-asset `resolveFrom` still wins, and an explicit
1380
1441
  * `resolveFrom: null` still opts out.
1381
- * - **Service dependencies** — becomes the base the host resolves declared
1442
+ * - **Service dependencies**: becomes the base the host resolves declared
1382
1443
  * {@link DevframeServiceInput | services} from, so a plugin can ship a
1383
1444
  * service package as its own dependency instead of asking users to install
1384
1445
  * it.
@@ -1424,12 +1485,13 @@ interface DevframeDefinition {
1424
1485
  * Declares which runtimes meaningfully support this devframe. Adapters
1425
1486
  * act on a `false` before doing any work:
1426
1487
  *
1427
- * - `build: false` — `createCac` skips registering the `build` subcommand,
1428
- * and `createBuild` refuses (throws `DF0042`) unless `{ force: true }`.
1429
- * Useful for a devframe whose value is inherently live (e.g. it manages
1430
- * real files on disk), so a static export would only ever produce a
1431
- * broken, write-less shell of the tool.
1432
- * - `dev: false` — `createDevServer` refuses (throws `DF0058`) unless
1488
+ * - `build: false`: `createCac` skips registering the `build` subcommand,
1489
+ * `createBuild` refuses (throws `DF0042`) unless `{ force: true }`, and
1490
+ * a hub static build (`buildHub`) silently skips the devframe - no dock,
1491
+ * no SPA copy, no RPCs in the dump. Useful for a devframe whose value is
1492
+ * inherently live (e.g. it manages real files on disk), so a static
1493
+ * export would only ever produce a broken, write-less shell of the tool.
1494
+ * - `dev: false`: `createDevServer` refuses (throws `DF0058`) unless
1433
1495
  * `{ force: true }`. Useful for a devframe that only makes sense as a
1434
1496
  * static export (e.g. a report generator with nothing to serve live).
1435
1497
  */
@@ -1440,18 +1502,18 @@ interface DevframeDefinition {
1440
1502
  /**
1441
1503
  * Wire services this devframe consumes (see `DevframeServiceDefinition`).
1442
1504
  * Each entry is either a declarative descriptor
1443
- * (`{ package, version?, required?, options? }` — the host imports the
1505
+ * (`{ package, version?, required?, options? }`, where the host imports the
1444
1506
  * package's default-export factory, resolving it against **this plugin's
1445
1507
  * own dependencies**) or a ready `DevframeServiceDefinition` (the factory
1446
1508
  * was already called). The adapter queues these before `setup(ctx)` runs
1447
1509
  * and constructs each service once at the `ctx.services.ready()` barrier,
1448
1510
  * merging option sets across every declarer. Missing services are skipped
1449
- * unless marked `required` — clients feature-detect via
1511
+ * unless marked `required`; clients feature-detect via
1450
1512
  * `client.services.has(pkg)` and degrade.
1451
1513
  */
1452
1514
  services?: DevframeServiceInput[];
1453
1515
  /**
1454
- * Author's SPA dist — served as the devframe's UI. A local directory, or
1516
+ * Author's SPA dist, served as the devframe's UI. A local directory, or
1455
1517
  * a {@link StaticAssetsSource} remote declaration (`{ package, version }`)
1456
1518
  * served through devframe's caching CDN back-proxy so the assets need not
1457
1519
  * ship inside the node package.
@@ -1463,20 +1525,20 @@ interface DevframeDefinition {
1463
1525
  clientAssets?: StaticAssetsSource;
1464
1526
  /** RPC-level configuration for this devframe (see {@link DevframeRpcOptions}). */
1465
1527
  rpc?: DevframeRpcOptions;
1466
- /** Server-side setup — the primary entrypoint. Runs in every runtime. */
1528
+ /** Server-side setup: the primary entrypoint. Runs in every runtime. */
1467
1529
  setup: (ctx: DevframeNodeContext, info?: DevframeSetupInfo) => void | Promise<void>;
1468
1530
  cli?: DevframeCliOptions;
1469
1531
  }
1470
1532
  interface DevframeRpcOptions {
1471
1533
  /**
1472
1534
  * Opt an RPC function into the static-build snapshot **without owning its
1473
- * definition** — the mechanism a devframe uses to bake a wire service's
1535
+ * definition**, the mechanism a devframe uses to bake a wire service's
1474
1536
  * RPC (e.g. `@devframes/service-git`'s `status`/`log`/`show`) into its
1475
1537
  * `build` export, since the service itself defines no `dump`/`snapshot`.
1476
1538
  *
1477
1539
  * Each entry is either a bare method id (bakes the no-argument call, like
1478
1540
  * `snapshot: true`) or `{ method, inputs }` where `inputs` is the list of
1479
- * argument-tuples to bake — or an async provider given the node context
1541
+ * argument-tuples to bake, or an async provider given the node context
1480
1542
  * (so it can enumerate at build time, e.g. read commit hashes via the
1481
1543
  * service's node API). `createBuild` resolves these after setup and
1482
1544
  * executes the target's own handler per tuple; the first tuple's result
@@ -1576,7 +1638,7 @@ interface BufferedChunk<T> {
1576
1638
  interface StreamSinkEvents<T> {
1577
1639
  /** Fired for each `write()`. The RPC layer subscribes and broadcasts. */
1578
1640
  chunk: (seq: number, chunk: T) => void;
1579
- /** Terminal — fired exactly once per sink lifetime. */
1641
+ /** Terminal; fired exactly once per sink lifetime. */
1580
1642
  end: (error?: StreamErrorPayload) => void;
1581
1643
  }
1582
1644
  interface CreateStreamSinkOptions {
@@ -1610,17 +1672,17 @@ interface StreamSink<T> {
1610
1672
  close: () => void;
1611
1673
  /** External-cancel path. Aborts the signal so handlers can short-circuit. */
1612
1674
  abort: (reason?: unknown) => void;
1613
- /** `WritableStream<T>` adapter — same in-memory state as the imperative API. */
1675
+ /** `WritableStream<T>` adapter; same in-memory state as the imperative API. */
1614
1676
  readonly writable: WritableStream<T>;
1615
1677
  /**
1616
- * Internal — RPC layer subscribes to receive chunk/end notifications.
1678
+ * Internal: RPC layer subscribes to receive chunk/end notifications.
1617
1679
  * Not part of the public contract; do not call directly.
1618
1680
  *
1619
1681
  * @internal
1620
1682
  */
1621
1683
  readonly events: EventEmitter<StreamSinkEvents<T>>;
1622
1684
  /**
1623
- * Internal — replay buffer. RPC layer reads on (re)subscribe to feed
1685
+ * Internal replay buffer. RPC layer reads on (re)subscribe to feed
1624
1686
  * missed chunks before going live.
1625
1687
  *
1626
1688
  * @internal
@@ -1640,12 +1702,12 @@ interface CreateStreamReaderOptions {
1640
1702
  * RPC-agnostic.
1641
1703
  */
1642
1704
  onOverflow?: (dropped: number) => void;
1643
- /** Called when the consumer cancels — the RPC layer sends `:cancel` upstream. */
1705
+ /** Called when the consumer cancels; the RPC layer sends `:cancel` upstream. */
1644
1706
  onCancel?: () => void;
1645
1707
  }
1646
1708
  /**
1647
1709
  * Client-side consumer handle. Both an `AsyncIterable<T>` (for `for await`)
1648
- * and exposes `readable: ReadableStream<T>` (for `pipeTo`). Pick one — they
1710
+ * and exposes `readable: ReadableStream<T>` (for `pipeTo`). Pick one; they
1649
1711
  * share a single internal queue, so concurrent draining will race.
1650
1712
  */
1651
1713
  interface StreamReader<T> extends AsyncIterable<T> {
@@ -1663,13 +1725,13 @@ interface StreamReader<T> extends AsyncIterable<T> {
1663
1725
  _end: (error?: StreamErrorPayload) => void;
1664
1726
  }
1665
1727
  /**
1666
- * Build a server-side stream sink. RPC-agnostic — the RPC host wires
1728
+ * Build a server-side stream sink. RPC-agnostic; the RPC host wires
1667
1729
  * `events.on('chunk' | 'end')` to broadcast, and reads `buffer` to replay
1668
1730
  * for late or reconnecting subscribers.
1669
1731
  */
1670
1732
  declare function createStreamSink<T>(options?: CreateStreamSinkOptions): StreamSink<T>;
1671
1733
  /**
1672
- * Build a client-side stream reader. RPC-agnostic — the RPC host calls
1734
+ * Build a client-side stream reader. RPC-agnostic; the RPC host calls
1673
1735
  * `_push(seq, chunk)` on each incoming chunk and `_end(error?)` on the
1674
1736
  * terminal frame. Consumers iterate with `for await` or pipe `readable`.
1675
1737
  */
@@ -1747,7 +1809,7 @@ interface RpcStreamingChannelOptions {
1747
1809
  * replay-on-resubscribe. `0` (default) disables replay; on reconnect
1748
1810
  * the consumer only sees chunks that arrive after subscribing.
1749
1811
  *
1750
- * The buffer is per stream id, not per channel — each `channel.start()`
1812
+ * The buffer is per stream id, not per channel; each `channel.start()`
1751
1813
  * gets its own.
1752
1814
  */
1753
1815
  replayWindow?: number;
@@ -1797,7 +1859,7 @@ interface RpcStreamingChannel<T = unknown> {
1797
1859
  /** All active outbound stream ids on this channel. */
1798
1860
  ids: () => string[];
1799
1861
  /**
1800
- * Open an inbound stream — the server side of a client-to-server
1862
+ * Open an inbound stream: the server side of a client-to-server
1801
1863
  * upload. Allocates an id, returns a `StreamReader<T>` that fills as
1802
1864
  * the client writes chunks. Typical pattern is to call this from an
1803
1865
  * action handler, kick off background processing, and return the id
@@ -1848,7 +1910,7 @@ interface DevframeCapabilities {
1848
1910
  views?: boolean;
1849
1911
  }
1850
1912
  /**
1851
- * Framework- and build-tool-agnostic node context — RPC + diagnostics +
1913
+ * Framework- and build-tool-agnostic node context: RPC + diagnostics +
1852
1914
  * agent + the view-host (HTTP file-serving). Host adapters can wrap this
1853
1915
  * to add their own surfaces; for example, `@vitejs/devtools-kit`'s
1854
1916
  * `createKitContext` adds `docks`, `terminals`, `messages`, and
@@ -1862,10 +1924,10 @@ interface DevframeNodeContext {
1862
1924
  /**
1863
1925
  * Lifecycle distinction surfaced to plugin authors:
1864
1926
  *
1865
- * - `'dev'` — long-running, interactive session. Connections come and
1927
+ * - `'dev'`: long-running, interactive session. Connections come and
1866
1928
  * go; broadcasts and shared-state mutations are debounced
1867
1929
  * to keep the UI responsive.
1868
- * - `'build'` — one-shot batch run. The context is set up, the devtool
1930
+ * - `'build'`: one-shot batch run. The context is set up, the devtool
1869
1931
  * collects what it needs, and a snapshot is written. No
1870
1932
  * live UI, no WS server.
1871
1933
  *
@@ -1875,23 +1937,23 @@ interface DevframeNodeContext {
1875
1937
  */
1876
1938
  readonly mode: 'dev' | 'build';
1877
1939
  /**
1878
- * Host runtime abstraction — exposes `mountStatic` / `resolveOrigin` /
1940
+ * Host runtime abstraction, exposing `mountStatic` / `resolveOrigin` /
1879
1941
  * `getStorageDir`.
1880
1942
  */
1881
1943
  host: DevframeHost;
1882
1944
  rpc: RpcFunctionsHost;
1883
1945
  views: DevframeViewHost;
1884
1946
  /**
1885
- * Structured diagnostics host — wraps `nostics` and lets integrations
1947
+ * Structured diagnostics host; wraps `nostics` and lets integrations
1886
1948
  * register their own coded errors/warnings into the shared lookup.
1887
1949
  */
1888
1950
  diagnostics: DevframeDiagnosticsHost;
1889
1951
  /**
1890
- * Agent host — aggregates the agent-exposed surface of this devtool.
1952
+ * Agent host; aggregates the agent-exposed surface of this devtool.
1891
1953
  */
1892
1954
  agent: DevframeAgentHost;
1893
1955
  /**
1894
- * Cross-plugin services — a typed, namespaced registry through which one
1956
+ * Cross-plugin services: a typed, namespaced registry through which one
1895
1957
  * integration exposes a capability (e.g. a data-source registry) and
1896
1958
  * others consume it without a hard package dependency. Ids follow the RPC
1897
1959
  * namespacing rule (`<plugin-id>:<service>`); types come from augmenting
@@ -1900,11 +1962,11 @@ interface DevframeNodeContext {
1900
1962
  */
1901
1963
  services: DevframeServicesHost;
1902
1964
  /**
1903
- * This context's own {@link ConnectionMeta.configs} — static, boot-time
1965
+ * This context's own {@link ConnectionMeta.configs}: static, boot-time
1904
1966
  * config a host publishes once through the connection handshake and every
1905
1967
  * client reads read-only. A plain, **non-reactive** object: mutate it
1906
1968
  * during `setup(ctx)` (a plugin sets its keys, a hub aggregates across
1907
- * every installed devframe), never during the session — it's serialized
1969
+ * every installed devframe), never during the session, since it's serialized
1908
1970
  * once, after setup, and changing it afterwards reaches no client.
1909
1971
  *
1910
1972
  * ```ts
@@ -1935,7 +1997,7 @@ interface DevframeNodeContext {
1935
1997
  * where `__connection.json` was loaded, and the connection is made to the
1936
1998
  * page's own origin (only the `http`→`ws` / `https`→`wss` protocol swap is
1937
1999
  * applied). This survives reverse proxies that change the host/port, because
1938
- * the client never trusts a server-baked hostname — it reuses its own.
2000
+ * the client never trusts a server-baked hostname; it reuses its own.
1939
2001
  *
1940
2002
  * Set `port` (and/or `host`) only when the WS endpoint genuinely lives on a
1941
2003
  * different origin than the page, e.g. a side-car server on its own port.
@@ -1953,7 +2015,7 @@ interface ConnectionMetaWebsocket {
1953
2015
  host?: string;
1954
2016
  }
1955
2017
  /**
1956
- * Object form of {@link ConnectionMeta.sse} — the same proxy-safe shape and
2018
+ * Object form of {@link ConnectionMeta.sse}: the same proxy-safe shape and
1957
2019
  * resolution rules as {@link ConnectionMetaWebsocket}, producing an
1958
2020
  * `http(s)://` endpoint instead of a `ws(s)://` one. Set `port` (and/or
1959
2021
  * `host`) only when the SSE endpoint genuinely lives on a different origin
@@ -1981,10 +2043,10 @@ interface ConnectionMeta {
1981
2043
  /**
1982
2044
  * WebSocket endpoint, resolved by the client into a `ws(s)://` URL:
1983
2045
  *
1984
- * - {@link ConnectionMetaWebsocket} — the proxy-flexible default; a
2046
+ * - {@link ConnectionMetaWebsocket}: the proxy-flexible default; a
1985
2047
  * same-origin path relative to `__connection.json`.
1986
- * - `number` — a port on the page's hostname (`ws(s)://<host>:<port>`).
1987
- * - `string` — a full `ws://`/`wss://` URL used verbatim, an `http(s)://`
2048
+ * - `number`: a port on the page's hostname (`ws(s)://<host>:<port>`).
2049
+ * - `string`: a full `ws://`/`wss://` URL used verbatim, an `http(s)://`
1988
2050
  * URL with its protocol swapped, or a path resolved same-origin.
1989
2051
  */
1990
2052
  websocket?: number | string | ConnectionMetaWebsocket;
@@ -1993,9 +2055,9 @@ interface ConnectionMeta {
1993
2055
  * resolved by the client into an `http(s)://` URL with the same
1994
2056
  * proxy-safe rules as {@link ConnectionMeta.websocket}:
1995
2057
  *
1996
- * - {@link ConnectionMetaSse} — the proxy-flexible default; a
2058
+ * - {@link ConnectionMetaSse}: the proxy-flexible default; a
1997
2059
  * same-origin path relative to `__connection.json`.
1998
- * - `string` — a full `http(s)://` URL used verbatim, or a path
2060
+ * - `string`: a full `http(s)://` URL used verbatim, or a path
1999
2061
  * resolved same-origin.
2000
2062
  */
2001
2063
  sse?: string | ConnectionMetaSse;
@@ -2005,7 +2067,7 @@ interface ConnectionMeta {
2005
2067
  * tooling (e.g. an MCP inspector) can discover it without guessing the
2006
2068
  * path. `path` is relative to `__connection.json`'s location, like the
2007
2069
  * WebSocket `path`. `port` is set when the endpoint lives on a side-car
2008
- * server on its own port (bridge mode — `devframeViteBridge`,
2070
+ * server on its own port (bridge mode: `devframeViteBridge`,
2009
2071
  * `@devframes/next`): the client combines the page hostname with `port`
2010
2072
  * and resolves `path` against that origin, mirroring
2011
2073
  * {@link ConnectionMetaWebsocket.port}.
@@ -2024,18 +2086,25 @@ interface ConnectionMeta {
2024
2086
  */
2025
2087
  jsonSerializableMethods?: string[];
2026
2088
  /**
2027
- * Absolute URL of the `__connection.json` this meta was loaded from.
2028
- * Annotated by the client (not served) when it publishes the meta on a
2029
- * shared window for same-origin inheritance: a relative `websocket.path`
2030
- * resolves against this, so a child SPA mounted at another base (e.g. a hub
2031
- * mounting several devframes at `/__foo/`, `/__bar/`, …) inherits a dialable
2032
- * endpoint rather than resolving the path against its own mount.
2089
+ * URL of the `__connection.json` that owns this meta's relative paths.
2090
+ * Two producers write it:
2091
+ *
2092
+ * - The client annotates it (absolute) when it publishes the meta on a
2093
+ * shared window for same-origin inheritance: a relative
2094
+ * `websocket.path` resolves against this, so a child SPA mounted at
2095
+ * another base (e.g. a hub mounting several devframes at `/__foo/`,
2096
+ * `/__bar/`, …) inherits a dialable endpoint rather than resolving the
2097
+ * path against its own mount.
2098
+ * - A static hub build serves it (base-absolute, e.g.
2099
+ * `/__devframes/__connection.json`) in each **per-frame** meta, so a
2100
+ * frame SPA that fetched its own copy still resolves the shared RPC
2101
+ * dump from the hub base. Resolved against the fetched URL.
2033
2102
  */
2034
2103
  baseUrl?: string;
2035
2104
  /**
2036
2105
  * A pre-issued bearer token embedded in the meta so a client trusts the
2037
2106
  * server on connect without any prompt or `localStorage` lookup. Only a
2038
- * **hub** serving a **per-frame** connection meta populates this — it
2107
+ * **hub** serving a **per-frame** connection meta populates this; it
2039
2108
  * authenticates once at the top level and bakes the resulting token into
2040
2109
  * the meta each plugin iframe fetches, so a cross-origin frame (which
2041
2110
  * cannot read the hub's `localStorage`) is still pre-authorized. The
@@ -2043,7 +2112,7 @@ interface ConnectionMeta {
2043
2112
  *
2044
2113
  * > [!WARNING]
2045
2114
  * > A token in a fetchable JSON is only as protected as the URL serving
2046
- * > it. Emit it exclusively from hub-controlled, per-frame meta — never
2115
+ * > it. Emit it exclusively from hub-controlled, per-frame meta, never
2047
2116
  * > from a publicly reachable static `__connection.json`.
2048
2117
  */
2049
2118
  authToken?: string;
@@ -2057,13 +2126,13 @@ interface ConnectionMeta {
2057
2126
  */
2058
2127
  viewerOriginToken?: string;
2059
2128
  /**
2060
- * Static, host-declared configuration — baked in once at connect time and
2129
+ * Static, host-declared configuration, baked in once at connect time and
2061
2130
  * fixed for the life of the server (e.g. a hub's UI rebrand, or its
2062
2131
  * aggregated dock-bar layout preferences). Read-only from the browser: a
2063
2132
  * client only ever reads `rpc.connectionMeta.configs`, never writes to it.
2064
2133
  *
2065
2134
  * Contrast this with {@link DevframeSettingsRegistry} (`ctx.scope(ns).settings`)
2066
- * and a hub's `devframe:user-settings` shared-state key — both are
2135
+ * and a hub's `devframe:user-settings` shared-state key; both are
2067
2136
  * mutable, user-editable, and synced bidirectionally over RPC for the
2068
2137
  * life of the session. `configs` is the opposite: one-way, immutable,
2069
2138
  * decided by whoever assembled the server.
@@ -2081,7 +2150,7 @@ interface ConnectionMeta {
2081
2150
  configs?: Partial<DevframeConnectionConfigsRegistry>;
2082
2151
  }
2083
2152
  /**
2084
- * Augmentation point for {@link ConnectionMeta.configs}. Empty by default —
2153
+ * Augmentation point for {@link ConnectionMeta.configs}. Empty by default;
2085
2154
  * a package that wants to publish static, boot-time config through the
2086
2155
  * connection handshake augments this interface with its own key (see
2087
2156
  * {@link ConnectionMeta.configs} for the pattern). `@devframes/hub`
@@ -2089,4 +2158,4 @@ interface ConnectionMeta {
2089
2158
  */
2090
2159
  interface DevframeConnectionConfigsRegistry {}
2091
2160
  //#endregion
2092
- export { DevframeServicesHost as $, SharedStateEvents as A, AgentResource as At, DevframeSetupInfo as B, EventUnsubscribe as Bt, createStreamSink as C, DevframeAuthHandler as Ct, ImmutableObject as D, parseCliFlags as Dt, ImmutableMap as E, defineCliFlags as Et, DevframeDefinition as F, AgentToolProvider as Ft, McpRouteOptions as G, DevframeSnapshotRpcInputs as H, DevframeDeploymentKind as I, AgentToolProviderHandle as It, DevframeServiceId as J, DevframeServiceDefinition as K, DevframeDockDefaults as L, DevframeAgentHost as Lt, SharedStatePatch as M, AgentResourceInput as Mt, createSharedState as N, AgentTool as Nt, ImmutableSet as O, AgentHandle as Ot, DevframeCliOptions as P, AgentToolInput as Pt, DevframeServiceScopeOf as Q, DevframeDuplicationStrategy as R, DevframeAgentHostEvents as Rt, createStreamReader as S, DevframeDiagnosticsLogger as St, ImmutableArray as T, InferCliFlags as Tt, DevframeSseOptions as U, DevframeSnapshotRpcEntry as V, EventsMap as Vt, DevframeWsOptions as W, DevframeServiceMeta as X, DevframeServiceInput as Y, DevframeServiceOf as Z, CreateStreamSinkOptions as _, DevframeRpcServerFunctions as _t, DevframeConnectionConfigsRegistry as a, DevframeScopedStreamingHost as at, StreamSink as b, DevframeStorageScope as bt, RpcBroadcastOptions as c, DevframeSettingsStore as ct, RpcSharedStateHost as d, ScopedRpcFn as dt, DevframeServicesRegistry as et, RpcStreamingChannel as f, ScopedServerFunctions as ft, CreateStreamReaderOptions as g, DevframeRpcClientFunctions as gt, BufferedChunk as h, DevframeViewHost as ht, DevframeCapabilities as i, DevframeScopedNodeRpc as it, SharedStateOptions as j, AgentResourceContent as jt, SharedState as k, AgentManifest as kt, RpcFunctionsHost as l, ScopedBroadcastOptions as lt, RpcStreamingHost as m, SettingsForNamespace as mt, ConnectionMetaSse as n, DevframeServicesState as nt, DevframeNodeContext as o, DevframeSettings as ot, RpcStreamingChannelOptions as p, ScopedSharedStates as pt, DevframeServiceDescriptor as q, ConnectionMetaWebsocket as r, DevframeScopedNodeContext as rt, DevframeNodeRpcSession as s, DevframeSettingsRegistry as st, ConnectionMeta as t, DevframeServicesScopeRegistry as tt, RpcSharedStateGetOptions as u, ScopedClientFunctions as ut, StreamErrorPayload as v, DevframeRpcSharedStates as vt, Immutable as w, CliFlagsSchema as wt, StreamSinkEvents as x, DevframeDiagnosticsHost as xt, StreamReader as y, DevframeHost as yt, DevframeRpcOptions as z, EventEmitter as zt };
2161
+ export { DevframeServiceOf as $, SharedStateEvents as A, AgentHandle as At, DevframeSetupInfo as B, DevframeAgentHostEvents as Bt, createStreamSink as C, DevframeDiagnosticsHost as Ct, ImmutableObject as D, InferCliFlags as Dt, ImmutableMap as E, CliFlagsSchema as Et, DevframeDefinition as F, AgentTool as Ft, McpAuthorization as G, DevframeSnapshotRpcInputs as H, EventUnsubscribe as Ht, DevframeDeploymentKind as I, AgentToolInput as It, DevframeServiceDefinition as J, McpRouteOptions as K, DevframeDockDefaults as L, AgentToolProvider as Lt, SharedStatePatch as M, AgentResource as Mt, createSharedState as N, AgentResourceContent as Nt, ImmutableSet as O, defineCliFlags as Ot, DevframeCliOptions as P, AgentResourceInput as Pt, DevframeServiceMeta as Q, DevframeDuplicationStrategy as R, AgentToolProviderHandle as Rt, createStreamReader as S, DevframeStorageScope as St, ImmutableArray as T, DevframeAuthHandler as Tt, DevframeSseOptions as U, EventsMap as Ut, DevframeSnapshotRpcEntry as V, EventEmitter as Vt, DevframeWsOptions as W, DevframeServiceId as X, DevframeServiceDescriptor as Y, DevframeServiceInput as Z, CreateStreamSinkOptions as _, DevframeViewHost as _t, DevframeConnectionConfigsRegistry as a, DevframeScopedNodeContext as at, StreamSink as b, DevframeRpcSharedStates as bt, RpcBroadcastOptions as c, DevframeSettings as ct, RpcSharedStateHost as d, ScopedBroadcastOptions as dt, DevframeServiceScopeOf as et, RpcStreamingChannel as f, ScopedClientFunctions as ft, CreateStreamReaderOptions as g, SettingsForNamespace as gt, BufferedChunk as h, ScopedSharedStates as ht, DevframeCapabilities as i, DevframeServicesState as it, SharedStateOptions as j, AgentManifest as jt, SharedState as k, parseCliFlags as kt, RpcFunctionsHost as l, DevframeSettingsRegistry as lt, RpcStreamingHost as m, ScopedServerFunctions as mt, ConnectionMetaSse as n, DevframeServicesRegistry as nt, DevframeNodeContext as o, DevframeScopedNodeRpc as ot, RpcStreamingChannelOptions as p, ScopedRpcFn as pt, McpSetting as q, ConnectionMetaWebsocket as r, DevframeServicesScopeRegistry as rt, DevframeNodeRpcSession as s, DevframeScopedStreamingHost as st, ConnectionMeta as t, DevframeServicesHost as tt, RpcSharedStateGetOptions as u, DevframeSettingsStore as ut, StreamErrorPayload as v, DevframeRpcClientFunctions as vt, Immutable as w, DevframeDiagnosticsLogger as wt, StreamSinkEvents as x, DevframeHost as xt, StreamReader as y, DevframeRpcServerFunctions as yt, DevframeRpcOptions as z, DevframeAgentHost as zt };