devframe 0.9.20 → 0.10.1

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 (102) hide show
  1. package/dist/_shared-B2PZsp-J.mjs +191 -0
  2. package/dist/{_shared-BIUet_Jh.d.mts → _shared-D1ebaX_J.d.mts} +13 -14
  3. package/dist/adapters/build.d.mts +3 -4
  4. package/dist/adapters/build.mjs +4 -5
  5. package/dist/adapters/cac.d.mts +3 -4
  6. package/dist/adapters/cac.mjs +3 -3
  7. package/dist/adapters/dev.d.mts +8 -8
  8. package/dist/adapters/dev.mjs +2 -2
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +8 -8
  11. package/dist/adapters/initiate.mjs +1 -1
  12. package/dist/adapters/mcp.d.mts +4 -142
  13. package/dist/adapters/mcp.mjs +1 -597
  14. package/dist/agentic-DLqHMOyN.d.mts +30 -0
  15. package/dist/browser-agent-Pu-FLk6I.mjs +26 -0
  16. package/dist/browser-agent-rpc-BXhoSh1z.mjs +70 -0
  17. package/dist/cli/main.mjs +12 -260
  18. package/dist/client/index.d.mts +6 -6
  19. package/dist/client/index.mjs +12 -87
  20. package/dist/constants.d.mts +2 -1
  21. package/dist/constants.mjs +2 -1
  22. package/dist/{context-BLHBDQcZ.d.mts → context--tVkJw3W.d.mts} +127 -47
  23. package/dist/{context-BLXXjoBW.mjs → context-BqpgC5tq.mjs} +55 -5
  24. package/dist/{context-jXO5vzjH.mjs → context-CHpyLX8W.mjs} +1 -1
  25. package/dist/{context-BA5FPz7K.d.mts → context-D3qBv0IX.d.mts} +1 -1
  26. package/dist/{dev-BdKKOH8S.mjs → dev-BTbLJekh.mjs} +16 -24
  27. package/dist/{diagnostics-DZA6KQ_Z.mjs → diagnostics-Cx4_VjlG.mjs} +11 -3
  28. package/dist/dist-CO98PBnQ.mjs +265 -0
  29. package/dist/{host-agent-C3MBpNCd.mjs → host-agent-mIbQ6Qi5.mjs} +14 -13
  30. package/dist/import-runtime-module-BzlEQ9PI.mjs +24 -0
  31. package/dist/in-page-channel/index.d.mts +16 -12
  32. package/dist/in-page-channel/index.mjs +42 -14
  33. package/dist/index-Bia1vKjL.d.mts +218 -0
  34. package/dist/index-CeEtxDmK.d.mts +78 -0
  35. package/dist/{index-r6NstVmM.d.mts → index-D-2IdY1I.d.mts} +2 -2
  36. package/dist/{index-CiA6C705.d.mts → index-DuEm0sDH.d.mts} +1 -1
  37. package/dist/index.d.mts +4 -11
  38. package/dist/index.mjs +1 -10
  39. package/dist/{instance-registry-DCq762YJ.mjs → instance-registry-DtvYxc0Y.mjs} +1 -1
  40. package/dist/{instance-shell-C6Vg97lg.d.mts → instance-shell-CXnpSuK7.d.mts} +31 -5
  41. package/dist/{instance-shell-yfrM3_vK.mjs → instance-shell-wC2sfEU_.mjs} +7 -7
  42. package/dist/interactive-auth-BCa_iamv.mjs +384 -0
  43. package/dist/internal/index.d.mts +66 -22
  44. package/dist/internal/index.mjs +143 -8
  45. package/dist/mrmime-40h5OOIp.mjs +448 -0
  46. package/dist/node/auth.d.mts +2 -2
  47. package/dist/node/hub-internals.d.mts +2 -2
  48. package/dist/node/hub-internals.mjs +2 -2
  49. package/dist/node/index.d.mts +2 -4
  50. package/dist/node/index.mjs +2 -2
  51. package/dist/{nostics-0sKe5HIj.d.mts → nostics-DWvukRwa.d.mts} +11 -2
  52. package/dist/{origin-D_eBKEzr.mjs → origin-DZit9g29.mjs} +1 -21
  53. package/dist/recipes/interactive-auth.d.mts +2 -2
  54. package/dist/recipes/interactive-auth.mjs +1 -231
  55. package/dist/{remote-assets-D0StJVLp.mjs → remote-assets-B9MeWmW6.mjs} +2 -2
  56. package/dist/rpc/client.d.mts +1 -1
  57. package/dist/rpc/client.mjs +1 -1
  58. package/dist/rpc/dump.d.mts +2 -1
  59. package/dist/rpc/index.d.mts +3 -2
  60. package/dist/rpc/server.d.mts +1 -1
  61. package/dist/rpc/server.mjs +1 -1
  62. package/dist/rpc/transports/sse-client.d.mts +1 -1
  63. package/dist/rpc/transports/sse-server.d.mts +3 -3
  64. package/dist/rpc/transports/sse-server.mjs +1 -1
  65. package/dist/rpc/transports/ws-bun.d.mts +2 -2
  66. package/dist/rpc/transports/ws-bun.mjs +1 -1
  67. package/dist/rpc/transports/ws-client.d.mts +1 -1
  68. package/dist/rpc/transports/ws-deno.d.mts +2 -2
  69. package/dist/rpc/transports/ws-deno.mjs +1 -1
  70. package/dist/rpc/transports/ws-server.d.mts +1 -1
  71. package/dist/rpc/transports/ws-server.mjs +1 -1
  72. package/dist/{rpc-core-BlL-Ip8n.d.mts → rpc-core-B6n9MQsc.d.mts} +4 -4
  73. package/dist/{rpc-core-CvkU23bQ.mjs → rpc-core-BXyMjbKG.mjs} +1 -1
  74. package/dist/{services-install-Ben4yh52.mjs → services-install-D5YUwFXW.mjs} +17 -1
  75. package/dist/{sse-client-BcbYwXdD.d.mts → sse-client-DNdscfu_.d.mts} +2 -2
  76. package/dist/{storage-B70AXK64.mjs → storage-CHD1IkqU.mjs} +1 -1
  77. package/dist/tool-input-BAQXvvqL.mjs +393 -0
  78. package/dist/types/index.d.mts +4 -4
  79. package/dist/{types-D2vGd7-2.d.mts → types-BmDbfHCx.d.mts} +2 -3
  80. package/dist/utils/debounce.d.mts +50 -0
  81. package/dist/utils/debounce.mjs +88 -0
  82. package/dist/utils/events.d.mts +1 -1
  83. package/dist/utils/launch-editor.d.mts +8 -0
  84. package/dist/utils/launch-editor.mjs +36 -1
  85. package/dist/utils/nostics.d.mts +2 -2
  86. package/dist/utils/remote-assets.mjs +1 -1
  87. package/dist/utils/serve-static.mjs +1 -1
  88. package/dist/utils/shared-state.d.mts +1 -1
  89. package/dist/utils/simple-schema.d.mts +3 -2
  90. package/dist/utils/streaming-channel.d.mts +1 -1
  91. package/dist/utils/url.d.mts +31 -0
  92. package/dist/utils/url.mjs +58 -0
  93. package/dist/{ws-client-CNpP6Ium.d.mts → ws-client-6Mrz6eC4.d.mts} +2 -2
  94. package/dist/{ws-server-BB8jhxeT.d.mts → ws-server-y2R76aSW.d.mts} +2 -2
  95. package/package.json +10 -11
  96. package/dist/_shared-U8D-xzrp.mjs +0 -115
  97. package/dist/agent-tool-name-DGzeuWcO.mjs +0 -31
  98. package/dist/client-assets-DNdhagGm.mjs +0 -16
  99. package/dist/nostics-DD6gsDZA.mjs +0 -108
  100. package/dist/recipes/common-rpc-functions.d.mts +0 -70
  101. package/dist/recipes/common-rpc-functions.mjs +0 -115
  102. package/dist/simple-schema-Bi40l-P6.mjs +0 -154
@@ -1,10 +1,10 @@
1
- import { d as RpcFunctionsCollectorBase } from "./index-CiA6C705.mjs";
2
- import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-D2vGd7-2.mjs";
1
+ import { i as BirpcReturn } from "./index-Bia1vKjL.mjs";
2
+ import { d as RpcFunctionsCollectorBase } from "./index-DuEm0sDH.mjs";
3
+ import { t as StandardSchemaV1 } from "./index-CeEtxDmK.mjs";
4
+ import { g as RpcFunctionDefinitionAny, h as RpcFunctionDefinition } from "./types-BmDbfHCx.mjs";
3
5
  import { n as DevframeRpcConnection, t as DevframeNodeRpcSessionMeta } from "./session-r6PDixP6.mjs";
4
6
  import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-eBvSKZMS.mjs";
5
- import { m as defineDiagnostics } from "./nostics-0sKe5HIj.mjs";
6
- import { BirpcReturn } from "birpc";
7
- import { StandardSchemaV1 } from "@standard-schema/spec";
7
+ import { h as defineDiagnostics } from "./nostics-DWvukRwa.mjs";
8
8
  import { CAC } from "cac";
9
9
  //#region src/types/events.d.ts
10
10
  interface EventsMap {
@@ -500,11 +500,23 @@ interface DevframeHost {
500
500
  */
501
501
  type DevframeStorageScope = 'workspace' | 'project' | 'global';
502
502
  //#endregion
503
+ //#region src/client/browser-agent.d.ts
504
+ interface BrowserAgentToolManifest {
505
+ id: string;
506
+ title?: string;
507
+ description: string;
508
+ safety: 'read' | 'action' | 'destructive';
509
+ tags?: readonly string[];
510
+ inputSchema?: unknown;
511
+ }
512
+ //#endregion
503
513
  //#region src/types/rpc-augments.d.ts
504
514
  /**
505
515
  * To be extended
506
516
  */
507
517
  interface DevframeRpcClientFunctions {
518
+ /** Invoke a tool registered in this browser document. @internal */
519
+ 'devframe:agent:invoke-client-tool': (id: string, args: Record<string, unknown>) => Promise<unknown>;
508
520
  /**
509
521
  * Server→client notification that this connection's auth token has been
510
522
  * revoked. The client drops to untrusted on receipt. Broadcast by
@@ -556,6 +568,8 @@ interface DevframeRpcClientFunctions {
556
568
  * To be extended
557
569
  */
558
570
  interface DevframeRpcServerFunctions {
571
+ /** Replace this connection's browser-agent tool manifest, tagged with the calling tab's stable client id. @internal */
572
+ 'devframe:agent:sync-client-tools': (clientId: string, tools: BrowserAgentToolManifest[]) => Promise<void>;
559
573
  /**
560
574
  * Authenticate a connection with a previously-issued bearer token; resolves
561
575
  * whether the connection is now trusted. The interactive handler is provided
@@ -1204,17 +1218,20 @@ interface DevframeSseOptions {
1204
1218
  type McpAuthorization = string | ((request: Request) => boolean | Promise<boolean>) | false;
1205
1219
  /**
1206
1220
  * The route-based MCP setting accepted everywhere a host mounts a devframe
1207
- * (`cli.mcp`, `initDevframe` / `initHub` / `createDevServer` options, the
1208
- * framework kits):
1221
+ * (`initDevframe` / `initHub` / `createDevServer` options, `createCac` /
1222
+ * `--mcp`, the framework kits):
1209
1223
  *
1210
1224
  * - `'auto'`, the default: mount the route when the devframe exposes an
1211
1225
  * agent surface (an `agent`-flagged RPC function, or a tool / resource /
1212
- * provider registered on `ctx.agent`). An empty agent surface mounts
1213
- * nothing and loads no MCP code.
1214
- * - `true`: always mount at the default `__mcp` route.
1215
- * - `false`: never mount.
1216
- * - {@link McpRouteOptions}: always mount, with a custom route path, origin
1217
- * allow-list, or {@link McpAuthorization} identity check.
1226
+ * provider registered on `ctx.agent`) AND the optional `@devframes/agentic`
1227
+ * peer (the MCP adapter and SDK) is installed. An empty agent surface
1228
+ * mounts nothing and loads no MCP code; a non-empty one without the peer
1229
+ * warns once (DF0078) and mounts nothing.
1230
+ * - `true`: always mount at the default `__mcp` route; a missing
1231
+ * `@devframes/agentic` throws DF0079.
1232
+ * - `false`: never mount, and never probe or warn.
1233
+ * - {@link McpRouteOptions}: always mount (like `true`), with a custom route
1234
+ * path, origin allow-list, or {@link McpAuthorization} identity check.
1218
1235
  *
1219
1236
  * A mounted route trusts same-machine callers by default (the loopback
1220
1237
  * origin gate), exactly like `mcp: true`.
@@ -1298,36 +1315,6 @@ interface DevframeCliOptions {
1298
1315
  * @default true
1299
1316
  */
1300
1317
  auth?: boolean | DevframeAuthHandler;
1301
- /**
1302
- * Expose a route-based MCP server alongside the standalone dev server,
1303
- * speaking the MCP Streamable-HTTP transport at `/__mcp` (relative to the
1304
- * base path). It surfaces the same `ctx.agent` tools + shared-state
1305
- * resources as the stdio `mcp` command, but against the live server.
1306
- *
1307
- * Defaults to `'auto'`: the route mounts once the devframe exposes an
1308
- * agent surface (an `agent`-flagged RPC, a registered tool / resource).
1309
- * See {@link McpSetting} for the full contract, and
1310
- * {@link McpRouteOptions} for the route path, origin allow-list, and
1311
- * {@link McpAuthorization} identity check.
1312
- *
1313
- * The `--mcp` / `--no-mcp` CLI flags override this per run. Whether to expose
1314
- * MCP is a hosting decision, so programmatic hosts pass it to
1315
- * `initDevframe` / `initHub` / `createDevServer` instead.
1316
- *
1317
- * @deprecated Whether to expose MCP is a hosting decision, not a capability
1318
- * of the tool. Pass `mcp` to `createCac` (or the programmatic host) instead.
1319
- * This field is still read as a fallback, and will be removed in a future
1320
- * release.
1321
- */
1322
- mcp?: McpSetting;
1323
- /**
1324
- * Author's SPA dist, served as the devframe's UI.
1325
- *
1326
- * @deprecated Moved to the top-level {@link DevframeDefinition.clientAssets}.
1327
- * Set `clientAssets` on the definition instead. This field is still read as a
1328
- * fallback when `clientAssets` is unset, so existing definitions keep working.
1329
- */
1330
- distDir?: StaticAssetsSource;
1331
1318
  /**
1332
1319
  * How the browser reaches the RPC WebSocket. Defaults to sharing the HTTP
1333
1320
  * port on the `__ws` route. See {@link DevframeWsOptions} for the
@@ -1427,6 +1414,11 @@ interface DevframeDockDefaults {
1427
1414
  * host wiring; a URL or bare specifier passes through untouched.
1428
1415
  */
1429
1416
  clientScript?: {
1417
+ /**
1418
+ * Initialize after RPC trust without waiting for dock activation.
1419
+ * @default false
1420
+ */
1421
+ eager?: boolean;
1430
1422
  /** An absolute filesystem path, a served URL, or a bare npm specifier. */
1431
1423
  importFrom: string;
1432
1424
  /**
@@ -1545,8 +1537,7 @@ interface DevframeDefinition {
1545
1537
  * ship inside the node package.
1546
1538
  *
1547
1539
  * Consumed by every adapter that serves the UI (`dev`, `build`, `vite`,
1548
- * `next`, and the hub install path). When unset, the deprecated
1549
- * {@link DevframeCliOptions.distDir} is read as a fallback.
1540
+ * `next`, and the hub install path).
1550
1541
  */
1551
1542
  clientAssets?: StaticAssetsSource;
1552
1543
  /** RPC-level configuration for this devframe (see {@link DevframeRpcOptions}). */
@@ -1583,6 +1574,95 @@ type DevframeSnapshotRpcEntry = string | {
1583
1574
  inputs: DevframeSnapshotRpcInputs;
1584
1575
  };
1585
1576
  //#endregion
1577
+ //#region src/types/mcp.d.ts
1578
+ /**
1579
+ * The MCP adapter surface, typed here so `devframe` (which probes for and
1580
+ * lazily loads `@devframes/agentic`) and `@devframes/agentic/mcp` (which
1581
+ * implements it) share one contract without a type-level dependency cycle.
1582
+ * None of these shapes reference the MCP SDK: the SDK is an implementation
1583
+ * detail of `@devframes/agentic`, freely swappable behind this surface.
1584
+ * The h3-bound `mountMcpHttp` shapes live in `node/agentic.ts` (exported via
1585
+ * `devframe/internal`) instead: `devframe/types` must stay lib-neutral, and
1586
+ * h3's declarations are not.
1587
+ */
1588
+ interface CreateMcpServerOptions {
1589
+ /**
1590
+ * Transport to use. `createMcpServer` itself runs `'stdio'` (a standalone
1591
+ * process with its own host context); the Streamable-HTTP transport is
1592
+ * served route-based by the dev server instead; see `mountMcpHttp` and
1593
+ * the `mcp` option on `createDevServer` / `createCac`'s `--mcp` flag.
1594
+ */
1595
+ transport?: 'stdio';
1596
+ /**
1597
+ * Expose shared-state keys as MCP resources.
1598
+ * - `true` (default): every key the host publishes
1599
+ * - `false`: none
1600
+ * - `(key) => boolean`: filter
1601
+ */
1602
+ exposeSharedState?: boolean | ((key: string) => boolean);
1603
+ /** Override the name reported in the MCP handshake. */
1604
+ serverName?: string;
1605
+ /** Override the version reported in the MCP handshake. Defaults to `definition.version ?? '0.0.0'`. */
1606
+ serverVersion?: string;
1607
+ /** Called once the transport is connected. */
1608
+ onReady?: (info: {
1609
+ transport: 'stdio';
1610
+ }) => void;
1611
+ }
1612
+ interface McpServerHandle {
1613
+ stop: () => Promise<void>;
1614
+ }
1615
+ interface CreateMcpFetchHandlerOptions {
1616
+ /** Name reported in the MCP handshake. */
1617
+ serverName: string;
1618
+ /** Version reported in the MCP handshake. */
1619
+ serverVersion: string;
1620
+ /** Expose shared-state keys as MCP resources; see {@link CreateMcpServerOptions.exposeSharedState}. */
1621
+ exposeSharedState: boolean | ((key: string) => boolean);
1622
+ /**
1623
+ * Optional identity check, layered on top of the origin gate and checked
1624
+ * **after** it: a bearer token string (matched in constant time against
1625
+ * `Authorization: Bearer <token>`), a `(request) => boolean` callback, or
1626
+ * `false` (the default) for origin-only, trusting same-machine callers. A
1627
+ * callback governs identity only and cannot relax the origin gate. See
1628
+ * {@link McpAuthorization}.
1629
+ */
1630
+ authorization?: McpAuthorization;
1631
+ /**
1632
+ * Origin allow-list beyond the loopback default. `false` disables the
1633
+ * origin gate entirely. Default: loopback-only.
1634
+ *
1635
+ * Unlike the WS transport, the MCP route does **not** allow `Origin`-less
1636
+ * requests: a route-based endpoint is reachable by any local process, so a
1637
+ * request must carry an `Origin` that passes the gate. Native clients
1638
+ * (e.g. `devframe connect`) send their loopback origin explicitly.
1639
+ */
1640
+ allowedOrigins?: readonly string[] | false;
1641
+ }
1642
+ /** Connection facts a host knows about a request beyond the `Request` itself. */
1643
+ interface McpConnectionInfo {
1644
+ /**
1645
+ * The connecting peer's remote address (a node socket's `remoteAddress`),
1646
+ * used to prove a same-machine caller when the endpoint relies on the
1647
+ * loopback origin default with no identity check. A host that can resolve a
1648
+ * trustworthy peer address (the h3/node mount) supplies it; when it's
1649
+ * omitted the origin gate stays the only locality signal.
1650
+ */
1651
+ remoteAddress?: string;
1652
+ }
1653
+ interface McpFetchHandler {
1654
+ /**
1655
+ * WHATWG-`fetch` handler for the MCP endpoint. Hand every method
1656
+ * (POST/GET/DELETE) on the endpoint's path to it; routing by path is the
1657
+ * host's job. Pass {@link McpConnectionInfo} when the host can resolve the
1658
+ * peer address so the default trust boundary can enforce same-machine
1659
+ * locality.
1660
+ */
1661
+ fetch: (request: Request, connection?: McpConnectionInfo) => Promise<Response>;
1662
+ /** Tear down the handler (aborts in-flight exchanges, drops the change bridge). */
1663
+ dispose: () => Promise<void>;
1664
+ }
1665
+ //#endregion
1586
1666
  //#region src/utils/shared-state.d.ts
1587
1667
  type ImmutablePrimitive = undefined | null | boolean | string | number | Function;
1588
1668
  type Immutable<T> = T extends ImmutablePrimitive ? T : T extends Array<infer U> ? ImmutableArray<U> : T extends Map<infer K, infer V> ? ImmutableMap<K, V> : T extends Set<infer M> ? ImmutableSet<M> : ImmutableObject<T>;
@@ -2089,7 +2169,7 @@ interface ConnectionMeta {
2089
2169
  sse?: string | ConnectionMetaSse;
2090
2170
  /**
2091
2171
  * Present when the dev server exposes a route-based MCP endpoint
2092
- * (`cli.mcp`). Advertises the MCP Streamable-HTTP route so in-browser
2172
+ * (the host's `mcp` setting). Advertises the MCP Streamable-HTTP route so in-browser
2093
2173
  * tooling (e.g. an MCP inspector) can discover it without guessing the
2094
2174
  * path. `path` is relative to `__connection.json`'s location, like the
2095
2175
  * WebSocket `path`. `port` is set when the endpoint lives on a side-car
@@ -2184,4 +2264,4 @@ interface ConnectionMeta {
2184
2264
  */
2185
2265
  interface DevframeConnectionConfigsRegistry {}
2186
2266
  //#endregion
2187
- 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 };
2267
+ export { DevframeServiceDefinition as $, SharedStateEvents as A, DevframeAuthHandler as At, DevframeDefinition as B, AgentTool as Bt, createStreamSink as C, DevframeRpcClientFunctions as Ct, ImmutableObject as D, DevframeStorageScope as Dt, ImmutableMap as E, DevframeHost as Et, CreateMcpServerOptions as F, AgentHandle as Ft, DevframeSetupInfo as G, DevframeAgentHostEvents as Gt, DevframeDockDefaults as H, AgentToolProvider as Ht, McpConnectionInfo as I, AgentManifest as It, DevframeSseOptions as J, EventsMap as Jt, DevframeSnapshotRpcEntry as K, EventEmitter as Kt, McpFetchHandler as L, AgentResource as Lt, SharedStatePatch as M, InferCliFlags as Mt, createSharedState as N, defineCliFlags as Nt, ImmutableSet as O, DevframeDiagnosticsHost as Ot, CreateMcpFetchHandlerOptions as P, parseCliFlags as Pt, McpSetting as Q, McpServerHandle as R, AgentResourceContent as Rt, createStreamReader as S, DevframeViewHost as St, ImmutableArray as T, DevframeRpcSharedStates as Tt, DevframeDuplicationStrategy as U, AgentToolProviderHandle as Ut, DevframeDeploymentKind as V, AgentToolInput as Vt, DevframeRpcOptions as W, DevframeAgentHost as Wt, McpAuthorization as X, DevframeWsOptions as Y, McpRouteOptions as Z, CreateStreamSinkOptions as _, ScopedClientFunctions as _t, DevframeConnectionConfigsRegistry as a, DevframeServiceScopeOf as at, StreamSink as b, ScopedSharedStates as bt, RpcBroadcastOptions as c, DevframeServicesScopeRegistry as ct, RpcSharedStateHost as d, DevframeScopedNodeRpc as dt, DevframeServiceDescriptor as et, RpcStreamingChannel as f, DevframeScopedStreamingHost as ft, CreateStreamReaderOptions as g, ScopedBroadcastOptions as gt, BufferedChunk as h, DevframeSettingsStore as ht, DevframeCapabilities as i, DevframeServiceOf as it, SharedStateOptions as j, CliFlagsSchema as jt, SharedState as k, DevframeDiagnosticsLogger as kt, RpcFunctionsHost as l, DevframeServicesState as lt, RpcStreamingHost as m, DevframeSettingsRegistry as mt, ConnectionMetaSse as n, DevframeServiceInput as nt, DevframeNodeContext as o, DevframeServicesHost as ot, RpcStreamingChannelOptions as p, DevframeSettings as pt, DevframeSnapshotRpcInputs as q, EventUnsubscribe as qt, ConnectionMetaWebsocket as r, DevframeServiceMeta as rt, DevframeNodeRpcSession as s, DevframeServicesRegistry as st, ConnectionMeta as t, DevframeServiceId as tt, RpcSharedStateGetOptions as u, DevframeScopedNodeContext as ut, StreamErrorPayload as v, ScopedRpcFn as vt, Immutable as w, DevframeRpcServerFunctions as wt, StreamSinkEvents as x, SettingsForNamespace as xt, StreamReader as y, ScopedServerFunctions as yt, DevframeCliOptions as z, AgentResourceInput as zt };
@@ -4,11 +4,11 @@ import { RpcFunctionsCollectorBase } from "./rpc/index.mjs";
4
4
  import { defineRpcFunction } from "./index.mjs";
5
5
  import { t as DEVFRAME_EVENTS } from "./events-BV4Dj59a.mjs";
6
6
  import { DEVFRAME_SERVICES_STATE_KEY } from "./constants.mjs";
7
- import { t as diagnostics$1 } from "./diagnostics-DZA6KQ_Z.mjs";
8
- import { i as createEventEmitter, t as DevframeAgentHost } from "./host-agent-C3MBpNCd.mjs";
9
- import { n as createDebug, t as resolveStaticAssetsSource } from "./remote-assets-D0StJVLp.mjs";
10
- import { i as satisfiesVersionRange, n as expandResolveFrom, r as importServicePackage, t as deepMergeOptionSets } from "./services-install-Ben4yh52.mjs";
11
- import { t as createStorage } from "./storage-B70AXK64.mjs";
7
+ import { t as diagnostics$1 } from "./diagnostics-Cx4_VjlG.mjs";
8
+ import { r as createEventEmitter, t as DevframeAgentHost } from "./host-agent-mIbQ6Qi5.mjs";
9
+ import { n as createDebug, t as resolveStaticAssetsSource } from "./remote-assets-B9MeWmW6.mjs";
10
+ import { a as satisfiesVersionRange, n as expandResolveFrom, r as importServicePackage, t as deepMergeOptionSets } from "./services-install-D5YUwFXW.mjs";
11
+ import { t as createStorage } from "./storage-CHD1IkqU.mjs";
12
12
  import { join } from "pathe";
13
13
  import { createSharedState } from "devframe/utils/shared-state";
14
14
  import process from "node:process";
@@ -32,6 +32,46 @@ var DevframeDiagnosticsHost = class {
32
32
  }
33
33
  };
34
34
  //#endregion
35
+ //#region src/node/client-agent.ts
36
+ const states = /* @__PURE__ */ new WeakMap();
37
+ function getState(context) {
38
+ let state = states.get(context);
39
+ if (state) return state;
40
+ const sessions = /* @__PURE__ */ new Map();
41
+ state = {
42
+ sessions,
43
+ notifyChanged: context.agent.registerToolProvider(() => {
44
+ const tools = /* @__PURE__ */ new Map();
45
+ for (const { session, tools: manifests } of sessions.values()) for (const manifest of manifests) {
46
+ if (tools.has(manifest.id)) continue;
47
+ tools.set(manifest.id, {
48
+ ...manifest,
49
+ handler: (args) => session.rpc.$callRaw({
50
+ method: "devframe:agent:invoke-client-tool",
51
+ args: [manifest.id, args]
52
+ })
53
+ });
54
+ }
55
+ return [...tools.values()];
56
+ }).notifyChanged
57
+ };
58
+ states.set(context, state);
59
+ return state;
60
+ }
61
+ function syncClientAgentTools(context, session, clientId, tools) {
62
+ const state = getState(context);
63
+ state.sessions.set(session.meta, {
64
+ session,
65
+ clientId,
66
+ tools
67
+ });
68
+ state.notifyChanged();
69
+ }
70
+ function removeClientAgentSession(context, meta) {
71
+ const state = states.get(context);
72
+ if (state?.sessions.delete(meta)) state.notifyChanged();
73
+ }
74
+ //#endregion
35
75
  //#region src/node/rpc-shared-state.ts
36
76
  const debug$2 = createDebug("devframe:rpc:state:changed");
37
77
  const debugSubscribe = createDebug("devframe:rpc:state:subscribe");
@@ -764,6 +804,7 @@ var RpcFunctionsHostImpl = class extends RpcFunctionsCollectorBase {
764
804
  */
765
805
  _emitSessionDisconnected(meta) {
766
806
  this.streaming._onSessionDisconnected(meta);
807
+ removeClientAgentSession(this.context, meta);
767
808
  }
768
809
  async invokeLocal(method, ...args) {
769
810
  if (!this.definitions.has(method)) throw diagnostics$1.DF0006({ name: String(method) });
@@ -1124,6 +1165,15 @@ const BUILTIN_AGENT_RPC = [
1124
1165
  return await ctx.agent.read(id);
1125
1166
  } };
1126
1167
  }
1168
+ }),
1169
+ defineRpcFunction({
1170
+ name: "devframe:agent:sync-client-tools",
1171
+ type: "action",
1172
+ jsonSerializable: true,
1173
+ setup: (context) => ({ handler(clientId, tools) {
1174
+ const session = context.rpc.getCurrentRpcSession();
1175
+ if (session) syncClientAgentTools(context, session, clientId, tools);
1176
+ } })
1127
1177
  })
1128
1178
  ];
1129
1179
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { n as randomToken } from "./crypto-token-TVbGGFuj.mjs";
2
- import { t as createStorage } from "./storage-B70AXK64.mjs";
2
+ import { t as createStorage } from "./storage-CHD1IkqU.mjs";
3
3
  import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "./revoke-cqztiCX4.mjs";
4
4
  import { join } from "pathe";
5
5
  //#region src/node/hub-internals/context.ts
@@ -1,4 +1,4 @@
1
- import { k as SharedState, o as DevframeNodeContext } from "./context-BLHBDQcZ.mjs";
1
+ import { k as SharedState, o as DevframeNodeContext } from "./context--tVkJw3W.mjs";
2
2
  //#region src/node/hub-internals/context.d.ts
3
3
  interface InternalAnonymousAuthStorage {
4
4
  trusted: Record<string, {
@@ -1,17 +1,15 @@
1
- import { t as resolveClientAssets } from "./client-assets-DNdhagGm.mjs";
2
1
  import { DEVFRAME_CONNECTION_META_FILENAME } from "./constants.mjs";
3
- import { t as diagnostics } from "./diagnostics-DZA6KQ_Z.mjs";
4
- import { t as createHostContext } from "./context-BLXXjoBW.mjs";
5
- import { t as resolveStaticAssetsSource } from "./remote-assets-D0StJVLp.mjs";
6
- import { a as resolveMcpConfig, i as resolveDevServerPort, n as normalizeBasePath, r as resolveBasePath, s as importRuntimeModule, t as loadAutoMcpAdapter } from "./_shared-U8D-xzrp.mjs";
2
+ import { t as diagnostics } from "./diagnostics-Cx4_VjlG.mjs";
3
+ import { t as createHostContext } from "./context-BqpgC5tq.mjs";
4
+ import { t as resolveStaticAssetsSource } from "./remote-assets-B9MeWmW6.mjs";
5
+ import { a as resolveMcpConfig, c as joinURL, d as withoutLeadingSlash, i as resolveDevServerPort, l as withBase, n as normalizeBasePath, r as resolveBasePath, s as importAgenticMcp, t as loadAutoMcpAdapter } from "./_shared-B2PZsp-J.mjs";
7
6
  import { t as createH3DevframeHost } from "./host-h3-BROI6SQ4.mjs";
8
- import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, t as createInstanceShell } from "./instance-shell-yfrM3_vK.mjs";
7
+ import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, t as createInstanceShell } from "./instance-shell-wC2sfEU_.mjs";
9
8
  import { open } from "./utils/open.mjs";
10
9
  import { mountStaticHandler } from "./utils/serve-static.mjs";
11
10
  import { resolve } from "pathe";
12
11
  import { createServer } from "node:http";
13
12
  import process from "node:process";
14
- import { joinURL, withBase, withoutLeadingSlash } from "ufo";
15
13
  import { H3, toNodeHandler } from "h3";
16
14
  //#region src/adapters/initiate.ts
17
15
  const INSTANCE_INTERNALS = /* @__PURE__ */ new WeakMap();
@@ -38,7 +36,7 @@ function getInstanceInternals(handler) {
38
36
  */
39
37
  function initDevframe(def, options) {
40
38
  const base = normalizeBasePath(options.base);
41
- const distDir = options.distDir === false ? void 0 : options.distDir ?? resolveClientAssets(def);
39
+ const distDir = options.distDir === false ? void 0 : options.distDir ?? def.clientAssets;
42
40
  const app = options.app ?? new H3();
43
41
  const host = options.host ?? def.cli?.host ?? "localhost";
44
42
  const shell = createInstanceShell({
@@ -88,7 +86,7 @@ function initDevframe(def, options) {
88
86
  for (const input of def.services ?? []) context.services.install(input, { resolveFrom: def.importMetaUrl });
89
87
  await context.services.ready();
90
88
  await def.setup(context, setupInfo);
91
- const mcp = await mountMcpRoute(app, context, def, base, options.mcp ?? def.cli?.mcp ?? "auto");
89
+ const mcp = await mountMcpRoute(app, context, def, base, options.mcp ?? "auto");
92
90
  return {
93
91
  context,
94
92
  ...mcp?.meta ? { mcp: mcp.meta } : {},
@@ -119,11 +117,14 @@ function initDevframe(def, options) {
119
117
  }
120
118
  /**
121
119
  * Mount the route-based MCP server at `<base>__mcp`, before the SPA static
122
- * catch-all so the exact route wins. The MCP SDK is pulled in dynamically
123
- * only when the route mounts, keeping it out of consumer bundles: `'auto'`
124
- * mounts once `setup()` left a non-empty agent surface (an empty surface
125
- * loads no MCP code); an explicit setting mounts unconditionally. The
126
- * resolved config is origin-only unless it opts into a bearer/callback.
120
+ * catch-all so the exact route wins. The adapter (from the optional
121
+ * `@devframes/agentic` peer) is pulled in dynamically only when the route
122
+ * mounts, keeping it and the MCP SDK out of consumer bundles: `'auto'`
123
+ * mounts once `setup()` left a non-empty agent surface AND the peer is
124
+ * installed (an empty surface loads no MCP code; a non-empty one without the
125
+ * peer warns once and mounts nothing); an explicit setting mounts
126
+ * unconditionally, throwing DF0079 when the peer is absent. The resolved
127
+ * config is origin-only unless it opts into a bearer/callback.
127
128
  */
128
129
  async function mountMcpRoute(app, context, def, base, setting) {
129
130
  let module;
@@ -134,16 +135,7 @@ async function mountMcpRoute(app, context, def, base, setting) {
134
135
  } else config = resolveMcpConfig(setting);
135
136
  if (!config) return void 0;
136
137
  const route = withoutLeadingSlash(config.path ?? "__mcp");
137
- if (!module) try {
138
- module = await importRuntimeModule("devframe/adapters/mcp");
139
- } catch (error) {
140
- const reason = error instanceof Error ? error.message : String(error);
141
- throw diagnostics.DF0017({
142
- transport: "http",
143
- reason,
144
- cause: error
145
- });
146
- }
138
+ module ??= await importAgenticMcp();
147
139
  const mounted = module.mountMcpHttp(app, context, joinURL(base, route), {
148
140
  serverName: `${def.id} (devframe)`,
149
141
  serverVersion: def.version ?? "0.0.0",
@@ -68,8 +68,8 @@ const diagnostics = defineDiagnostics({
68
68
  fix: "Discovery tooling (`devframe connect`) will not see this instance. Check that the registry directory is writable, point `DEVFRAME_INSTANCES_DIR` at a writable directory, or set `DEVFRAME_DISABLE_INSTANCE_REGISTRY=1` to opt out of registration."
69
69
  },
70
70
  DF0046: {
71
- why: (p) => `\`devframe connect\` requires the optional peer dependency @modelcontextprotocol/client: ${p.reason}`,
72
- fix: "Install it next to devframe (e.g. `npm install @modelcontextprotocol/client`) and run `devframe connect` again."
71
+ why: (p) => `\`devframe connect\` requires the optional peer dependency @devframes/agentic: ${p.reason}`,
72
+ fix: "Install it next to devframe (e.g. `npm install @devframes/agentic`) and run `devframe connect` again."
73
73
  },
74
74
  DF0047: {
75
75
  why: (p) => `Agent tool "${p.id}" is hidden from the MCP surface: its wire name "${p.name}" collides with the tool "${p.existing}".`,
@@ -89,7 +89,7 @@ const diagnostics = defineDiagnostics({
89
89
  },
90
90
  DF0051: {
91
91
  why: (p) => `The devframe instance on port ${p.port} has no MCP endpoint.`,
92
- fix: "Restart the instance with the --mcp flag (or set `cli.mcp: true` on its definition) to expose its tools, then list instances again."
92
+ fix: "Restart the instance with the --mcp flag to expose its tools, then list instances again."
93
93
  },
94
94
  DF0052: {
95
95
  why: (p) => `Failed to listen on ${p.host}:${p.port}: ${p.reason}`,
@@ -174,6 +174,14 @@ const diagnostics = defineDiagnostics({
174
174
  DF0076: {
175
175
  why: (p) => `\`attach\` / \`handleUpgrade\` drive a raw \`node:http\` upgrade into crossws's Node adapter, which refuses to run on ${p.runtime}.`,
176
176
  fix: "On Bun/Deno, serve the advertised `__ws` route from `Bun.serve` / `Deno.serve` with `attachBunWsTransport` / `attachDenoWsTransport` (see the hub-deno example), or connect over the SSE endpoint instead."
177
+ },
178
+ DF0078: {
179
+ why: "This devframe exposes agent tools, but the MCP endpoint stays off: the optional peer \"@devframes/agentic\" is not installed.",
180
+ fix: "Install `@devframes/agentic` next to devframe to serve the MCP endpoint, or set `mcp: false` to opt out silently."
181
+ },
182
+ DF0079: {
183
+ why: (p) => `The \`mcp\` option is enabled, but the optional peer "@devframes/agentic" could not be loaded: ${p.reason}`,
184
+ fix: "Install `@devframes/agentic` next to devframe (the MCP adapter and the MCP SDK live there), or remove the explicit `mcp` setting."
177
185
  }
178
186
  }
179
187
  });