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
@@ -0,0 +1,83 @@
1
+ import { F as DevframeDefinition, G as McpAuthorization, I as DevframeDeploymentKind, q as McpSetting, t as ConnectionMeta, zt as DevframeAgentHost } from "./context-CHW4BZOj.mjs";
2
+ //#region src/adapters/_shared.d.ts
3
+ /**
4
+ * Resolve the mount base path for a devframe's SPA. Hosted adapters
5
+ * (`vite`, `embedded`) default to `/__<id>/` so they don't collide
6
+ * with the host app; standalone adapters (`cli`, `build`)
7
+ * default to `/` because they own the origin.
8
+ *
9
+ * The devframe author can override with `basePath` on the definition.
10
+ */
11
+ declare function resolveBasePath(def: DevframeDefinition, kind: DevframeDeploymentKind): string;
12
+ declare function normalizeBasePath(base: string): string;
13
+ interface ResolveDevServerPortOptions {
14
+ /** Bind host (passed to `get-port-please` for in-use detection). */
15
+ host?: string;
16
+ /** Override the preferred port. Default: `def.cli?.port ?? 9999`. */
17
+ defaultPort?: number;
18
+ }
19
+ /**
20
+ * Resolve the listening port for `createDevServer` (and `createHandler`'s
21
+ * side-car tiers), honoring the definition's `cli.port` / `cli.portRange` /
22
+ * `cli.random` settings. Exposed separately so authors who run their own
23
+ * argv parsing can resolve a port up-front (to print it, log it, etc.)
24
+ * before starting the server.
25
+ */
26
+ declare function resolveDevServerPort(def: DevframeDefinition, options?: ResolveDevServerPortOptions): Promise<number>;
27
+ /**
28
+ * A fully-resolved MCP route configuration: the concrete authorization policy
29
+ * (never the `mcp: true` shorthand), plus the optional route path and origin
30
+ * allow-list. Every route mount consumes this shape.
31
+ */
32
+ interface ResolvedMcpConfig {
33
+ /** Route segment, relative to the base. Default resolved by the caller. */
34
+ path?: string;
35
+ /** Origin allow-list, or `false` to disable the origin gate. */
36
+ allowedOrigins?: readonly string[] | false;
37
+ /** The resolved identity policy: a bearer token, callback, or `false`. */
38
+ authorization: McpAuthorization;
39
+ }
40
+ /**
41
+ * Normalize an *explicit* `mcp` setting into a fully-resolved config, or
42
+ * `undefined` when the MCP route is disabled. `'auto'` also resolves to
43
+ * `undefined` here: whether it mounts depends on the live agent surface,
44
+ * which only the mounting adapter can consult (through
45
+ * {@link loadAutoMcpAdapter}) - static resolvers like
46
+ * `resolveMcpConnectionMeta` treat it as unadvertisable.
47
+ *
48
+ * An enabled route trusts same-machine callers by default: the authorization
49
+ * resolves to origin-only (`false`) unless the object config opts into a
50
+ * bearer/callback identity check. An empty-string bearer is treated as no
51
+ * bearer (origin-only) rather than a usable credential.
52
+ */
53
+ declare function resolveMcpConfig(mcp: McpSetting | undefined): ResolvedMcpConfig | undefined;
54
+ /**
55
+ * Resolve the `mcp: 'auto'` default at mount time: import the MCP adapter
56
+ * when the devframe's agent surface is non-empty, or return `undefined`
57
+ * (mount nothing) when the surface is empty - the zero-cost path, loading
58
+ * no MCP code at all. The adapter (and the MCP SDK behind it) loads through
59
+ * `importRuntimeModule`, so it never enters a consumer's bundle graph.
60
+ *
61
+ * Generic like `importRuntimeModule`: the caller names the module type
62
+ * (`typeof import('devframe/adapters/mcp')`) so this shared helper carries
63
+ * no type-level dependency on the MCP adapter.
64
+ */
65
+ declare function loadAutoMcpAdapter<T>(agent: Pick<DevframeAgentHost, 'hasSurface'>): Promise<T | undefined>;
66
+ /**
67
+ * Resolve the `mcp` entry a `__connection.json` should advertise for a dev
68
+ * server started with the given `mcp` option (falling back to `def.cli?.mcp`,
69
+ * exactly like `createDevServer`), or `undefined` when the route is
70
+ * disabled. `'auto'` (the omitted default) resolves at mount time against
71
+ * the live agent surface, so hand-rolled meta advertises it only for an
72
+ * explicit setting; the adapters advertise the actually-mounted route
73
+ * themselves.
74
+ *
75
+ * Hosted bridges that hand-roll their connection meta pass the side-car
76
+ * `port`: the advertised path becomes absolute (the side-car mounts at `/`)
77
+ * and the client dials `<page-host>:<port><path>`. Without `port` the path
78
+ * stays relative, resolved against `__connection.json`'s own location (the
79
+ * same-server default).
80
+ */
81
+ declare function resolveMcpConnectionMeta(def: DevframeDefinition, mcp: McpSetting | undefined, port?: number): ConnectionMeta['mcp'];
82
+ //#endregion
83
+ export { resolveBasePath as a, resolveMcpConnectionMeta as c, normalizeBasePath as i, ResolvedMcpConfig as n, resolveDevServerPort as o, loadAutoMcpAdapter as r, resolveMcpConfig as s, ResolveDevServerPortOptions as t };
@@ -0,0 +1,115 @@
1
+ import "./constants.mjs";
2
+ import { r as importServicePackage } from "./services-install-Ben4yh52.mjs";
3
+ import { n as getPort } from "./dist-CZXfGEkd.mjs";
4
+ import { cleanDoubleSlashes, withLeadingSlash, withTrailingSlash, withoutLeadingSlash } from "ufo";
5
+ //#region src/node/import-runtime-module.ts
6
+ /**
7
+ * Resolve and import a package at runtime without adding it to a consumer's
8
+ * bundle graph. First-party adapters use this for modules whose code is
9
+ * needed only when the matching feature is enabled (optional peers, and the
10
+ * MCP adapter with the SDK behind it).
11
+ *
12
+ * @internal
13
+ */
14
+ async function importRuntimeModule(specifier) {
15
+ return await importServicePackage(specifier, [import.meta.url]);
16
+ }
17
+ //#endregion
18
+ //#region src/adapters/_shared.ts
19
+ const DEFAULT_PORT = 9999;
20
+ /**
21
+ * Resolve the mount base path for a devframe's SPA. Hosted adapters
22
+ * (`vite`, `embedded`) default to `/__<id>/` so they don't collide
23
+ * with the host app; standalone adapters (`cli`, `build`)
24
+ * default to `/` because they own the origin.
25
+ *
26
+ * The devframe author can override with `basePath` on the definition.
27
+ */
28
+ function resolveBasePath(def, kind) {
29
+ if (def.basePath) return normalizeBasePath(def.basePath);
30
+ return kind === "standalone" ? "/" : `/__${def.id}/`;
31
+ }
32
+ function normalizeBasePath(base) {
33
+ return cleanDoubleSlashes(withTrailingSlash(withLeadingSlash(base)));
34
+ }
35
+ /**
36
+ * Resolve the listening port for `createDevServer` (and `createHandler`'s
37
+ * side-car tiers), honoring the definition's `cli.port` / `cli.portRange` /
38
+ * `cli.random` settings. Exposed separately so authors who run their own
39
+ * argv parsing can resolve a port up-front (to print it, log it, etc.)
40
+ * before starting the server.
41
+ */
42
+ async function resolveDevServerPort(def, options = {}) {
43
+ const host = options.host ?? def.cli?.host ?? "localhost";
44
+ const portOptions = {
45
+ port: options.defaultPort ?? def.cli?.port ?? DEFAULT_PORT,
46
+ host
47
+ };
48
+ if (def.cli?.portRange) portOptions.portRange = def.cli.portRange;
49
+ if (def.cli?.random) portOptions.random = def.cli.random;
50
+ return getPort(portOptions);
51
+ }
52
+ /**
53
+ * Normalize an *explicit* `mcp` setting into a fully-resolved config, or
54
+ * `undefined` when the MCP route is disabled. `'auto'` also resolves to
55
+ * `undefined` here: whether it mounts depends on the live agent surface,
56
+ * which only the mounting adapter can consult (through
57
+ * {@link loadAutoMcpAdapter}) - static resolvers like
58
+ * `resolveMcpConnectionMeta` treat it as unadvertisable.
59
+ *
60
+ * An enabled route trusts same-machine callers by default: the authorization
61
+ * resolves to origin-only (`false`) unless the object config opts into a
62
+ * bearer/callback identity check. An empty-string bearer is treated as no
63
+ * bearer (origin-only) rather than a usable credential.
64
+ */
65
+ function resolveMcpConfig(mcp) {
66
+ if (!mcp || mcp === "auto") return void 0;
67
+ if (mcp === true) return { authorization: false };
68
+ const authorization = typeof mcp.authorization === "string" && mcp.authorization.length === 0 ? false : mcp.authorization ?? false;
69
+ return {
70
+ ...mcp.path !== void 0 ? { path: mcp.path } : {},
71
+ ...mcp.allowedOrigins !== void 0 ? { allowedOrigins: mcp.allowedOrigins } : {},
72
+ authorization
73
+ };
74
+ }
75
+ /**
76
+ * Resolve the `mcp: 'auto'` default at mount time: import the MCP adapter
77
+ * when the devframe's agent surface is non-empty, or return `undefined`
78
+ * (mount nothing) when the surface is empty - the zero-cost path, loading
79
+ * no MCP code at all. The adapter (and the MCP SDK behind it) loads through
80
+ * `importRuntimeModule`, so it never enters a consumer's bundle graph.
81
+ *
82
+ * Generic like `importRuntimeModule`: the caller names the module type
83
+ * (`typeof import('devframe/adapters/mcp')`) so this shared helper carries
84
+ * no type-level dependency on the MCP adapter.
85
+ */
86
+ async function loadAutoMcpAdapter(agent) {
87
+ if (!agent.hasSurface()) return void 0;
88
+ return await importRuntimeModule("devframe/adapters/mcp");
89
+ }
90
+ /**
91
+ * Resolve the `mcp` entry a `__connection.json` should advertise for a dev
92
+ * server started with the given `mcp` option (falling back to `def.cli?.mcp`,
93
+ * exactly like `createDevServer`), or `undefined` when the route is
94
+ * disabled. `'auto'` (the omitted default) resolves at mount time against
95
+ * the live agent surface, so hand-rolled meta advertises it only for an
96
+ * explicit setting; the adapters advertise the actually-mounted route
97
+ * themselves.
98
+ *
99
+ * Hosted bridges that hand-roll their connection meta pass the side-car
100
+ * `port`: the advertised path becomes absolute (the side-car mounts at `/`)
101
+ * and the client dials `<page-host>:<port><path>`. Without `port` the path
102
+ * stays relative, resolved against `__connection.json`'s own location (the
103
+ * same-server default).
104
+ */
105
+ function resolveMcpConnectionMeta(def, mcp, port) {
106
+ const config = resolveMcpConfig(mcp ?? def.cli?.mcp);
107
+ if (!config) return void 0;
108
+ const route = withoutLeadingSlash(config.path ?? "__mcp");
109
+ return port != null ? {
110
+ path: withLeadingSlash(route),
111
+ port
112
+ } : { path: route };
113
+ }
114
+ //#endregion
115
+ export { resolveMcpConfig as a, resolveDevServerPort as i, normalizeBasePath as n, resolveMcpConnectionMeta as o, resolveBasePath as r, importRuntimeModule as s, loadAutoMcpAdapter as t };
@@ -1,14 +1,14 @@
1
- import { F as DevframeDefinition, V as DevframeSnapshotRpcEntry, o as DevframeNodeContext } from "../context-CLF4-8Pp.mjs";
2
- import { o as StaticAssetsSource } from "../remote-assets-B13_vRkJ.mjs";
1
+ import { F as DevframeDefinition, V as DevframeSnapshotRpcEntry, o as DevframeNodeContext } from "../context-CHW4BZOj.mjs";
2
+ import { o as StaticAssetsSource } from "../remote-assets-eBvSKZMS.mjs";
3
3
  //#region src/adapters/build.d.ts
4
4
  interface CreateBuildOptions {
5
5
  /** Output directory. Defaults to `dist-static`. */
6
6
  outDir?: string;
7
7
  /**
8
- * Override the SPA dist to copy into `outDir` — a local directory or a
8
+ * Override the SPA dist to copy into `outDir`: a local directory or a
9
9
  * remote-assets declaration (materialized in full at build time). When
10
10
  * omitted the adapter reads `devframe.clientAssets` (or the deprecated
11
- * `devframe.cli?.distDir`) — authors typically set this once on the
11
+ * `devframe.cli?.distDir`); authors typically set this once on the
12
12
  * definition itself.
13
13
  */
14
14
  distDir?: StaticAssetsSource;
@@ -21,7 +21,7 @@ interface CreateBuildOptions {
21
21
  /**
22
22
  * Proceed even when the definition declares `capabilities.build: false`.
23
23
  * `createCac` already skips registering the `build` subcommand for such
24
- * a definition — this only matters for a caller invoking `createBuild`
24
+ * a definition; this only matters for a caller invoking `createBuild`
25
25
  * directly, bypassing the CLI.
26
26
  */
27
27
  force?: boolean;
@@ -34,7 +34,7 @@ interface CreateBuildOptions {
34
34
  * - Write `<outDir>/__connection.json` (`{ backend: 'static' }`) and the
35
35
  * sharded RPC dump under `<outDir>/__rpc-dump/` so the deployed SPA
36
36
  * discovers both via relative paths from `document.baseURI`. The
37
- * output is mount-path agnostic — the same bundle works at `/`,
37
+ * output is mount-path agnostic, so the same bundle works at `/`,
38
38
  * `/devframe/`, or any base, no rewriting required.
39
39
  */
40
40
  declare function createBuild(d: DevframeDefinition, options?: CreateBuildOptions): Promise<void>;
@@ -1,17 +1,15 @@
1
- import { s as colors } from "../nostics-CzECRXpE.mjs";
2
- import { n as strictJsonStringify } from "../serialization-BGzEwAdr.mjs";
3
- import { t as resolveClientAssets } from "../client-assets-C7SXgTWY.mjs";
4
- import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
5
- import { t as collectStaticRpcDump } from "../static-DV_qUSRS.mjs";
6
- import { n as structuredCloneStringify } from "../structured-clone-CbAV5rFI.mjs";
7
- import { t as diagnostics } from "../diagnostics-BXWW3VK-.mjs";
8
- import { t as createHostContext } from "../context-omlma_1n.mjs";
9
- import { t as resolveStaticAssetsSource } from "../remote-assets-DezQmPQU.mjs";
10
- import { t as createH3DevframeHost } from "../host-h3-fRbF9yor.mjs";
1
+ import { s as colors } from "../nostics-D0PvLZsn.mjs";
2
+ import { t as resolveClientAssets } from "../client-assets-DNdhagGm.mjs";
3
+ import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
4
+ import { n as collectStaticRpcDump, t as writeStaticRpcDump } from "../write-BuLCrn9h.mjs";
5
+ import { t as diagnostics } from "../diagnostics-DZA6KQ_Z.mjs";
6
+ import { t as createHostContext } from "../context-B29Oh0oA.mjs";
7
+ import { t as resolveStaticAssetsSource } from "../remote-assets-DMFzLSoH.mjs";
8
+ import { t as createH3DevframeHost } from "../host-h3-BROI6SQ4.mjs";
9
+ import fs from "node:fs/promises";
10
+ import { resolve } from "pathe";
11
11
  import process from "node:process";
12
- import { dirname, resolve } from "pathe";
13
12
  import { existsSync } from "node:fs";
14
- import fs$1 from "node:fs/promises";
15
13
  //#region src/adapters/build.ts
16
14
  /**
17
15
  * Produce a self-contained static deploy of a devframe:
@@ -21,7 +19,7 @@ import fs$1 from "node:fs/promises";
21
19
  * - Write `<outDir>/__connection.json` (`{ backend: 'static' }`) and the
22
20
  * sharded RPC dump under `<outDir>/__rpc-dump/` so the deployed SPA
23
21
  * discovers both via relative paths from `document.baseURI`. The
24
- * output is mount-path agnostic — the same bundle works at `/`,
22
+ * output is mount-path agnostic, so the same bundle works at `/`,
25
23
  * `/devframe/`, or any base, no rewriting required.
26
24
  */
27
25
  async function createBuild(d, options = {}) {
@@ -29,20 +27,13 @@ async function createBuild(d, options = {}) {
29
27
  const outDir = resolve(options.outDir ?? "dist-static");
30
28
  const distSource = options.distDir ?? resolveClientAssets(d);
31
29
  if (!distSource) throw new Error(`[devframe] createBuild: no client assets for "${d.id}". Set \`clientAssets\` on the definition or pass it as an option.`);
32
- if (existsSync(outDir)) await fs$1.rm(outDir, { recursive: true });
33
- await fs$1.mkdir(outDir, { recursive: true });
30
+ if (existsSync(outDir)) await fs.rm(outDir, { recursive: true });
31
+ await fs.mkdir(outDir, { recursive: true });
34
32
  const host = createH3DevframeHost({
35
33
  origin: "http://localhost",
36
34
  appName: d.id
37
35
  });
38
- const resolved = resolveStaticAssetsSource(distSource, host.getStorageDir("project"), d.importMetaUrl);
39
- if (typeof resolved === "string") {
40
- console.log(colors.cyan`[devframe] copying SPA from ${resolved} -> ${outDir}`);
41
- await fs$1.cp(resolved, outDir, { recursive: true });
42
- } else {
43
- console.log(colors.cyan`[devframe] materializing SPA from ${resolved.assets.package}@${resolved.assets.version} -> ${outDir}`);
44
- await resolved.materialize(outDir);
45
- }
36
+ await materializeSpa(resolveStaticAssetsSource(distSource, host.getStorageDir("project"), d.importMetaUrl), outDir);
46
37
  const ctx = await createHostContext({
47
38
  cwd: process.cwd(),
48
39
  mode: "build",
@@ -53,24 +44,30 @@ async function createBuild(d, options = {}) {
53
44
  await ctx.services.ready();
54
45
  await d.setup(ctx);
55
46
  applySnapshotRpc(ctx, d.rpc?.snapshot);
56
- await fs$1.mkdir(resolve(outDir, DEVFRAME_RPC_DUMP_DIRNAME), { recursive: true });
47
+ await writeConnectionMeta(ctx, outDir);
48
+ console.log(colors.cyan`[devframe] writing RPC dump to ${resolve(outDir, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME)}`);
49
+ const dump = await collectStaticRpcDump(ctx.rpc.definitions.values(), ctx);
50
+ await writeStaticRpcDump(dump, outDir, { pretty: options.pretty });
51
+ console.log(colors.green`[devframe] built "${d.id}" -> ${outDir}`);
52
+ }
53
+ /** Copy a local SPA dist, or materialize a remote assets source, into `outDir`. */
54
+ async function materializeSpa(resolved, outDir) {
55
+ if (typeof resolved === "string") {
56
+ console.log(colors.cyan`[devframe] copying SPA from ${resolved} -> ${outDir}`);
57
+ await fs.cp(resolved, outDir, { recursive: true });
58
+ return;
59
+ }
60
+ console.log(colors.cyan`[devframe] materializing SPA from ${resolved.assets.package}@${resolved.assets.version} -> ${outDir}`);
61
+ await resolved.materialize(outDir);
62
+ }
63
+ /** Write `__connection.json` with the JSON-serializable method allow-list. */
64
+ async function writeConnectionMeta(ctx, outDir) {
57
65
  const jsonSerializableMethods = [];
58
66
  for (const def of ctx.rpc.definitions.values()) if (def.jsonSerializable === true) jsonSerializableMethods.push(def.name);
59
- await fs$1.writeFile(resolve(outDir, DEVFRAME_CONNECTION_META_FILENAME), JSON.stringify({
67
+ await fs.writeFile(resolve(outDir, DEVFRAME_CONNECTION_META_FILENAME), JSON.stringify({
60
68
  backend: "static",
61
69
  jsonSerializableMethods
62
70
  }, null, 2), "utf-8");
63
- console.log(colors.cyan`[devframe] writing RPC dump to ${resolve(outDir, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME)}`);
64
- const dump = await collectStaticRpcDump(ctx.rpc.definitions.values(), ctx);
65
- const indent = options.pretty ? 2 : void 0;
66
- for (const [filepath, file] of Object.entries(dump.files)) {
67
- const fullpath = resolve(outDir, filepath);
68
- await fs$1.mkdir(dirname(fullpath), { recursive: true });
69
- const text = file.serialization === "structured-clone" ? structuredCloneStringify(file.data) : strictJsonStringify(file.data, file.fnName);
70
- await fs$1.writeFile(fullpath, file.serialization === "json" && indent != null ? JSON.stringify(JSON.parse(text), null, indent) : text, "utf-8");
71
- }
72
- await fs$1.writeFile(resolve(outDir, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME), JSON.stringify(dump.manifest, null, 2), "utf-8");
73
- console.log(colors.green`[devframe] built "${d.id}" -> ${outDir}`);
74
71
  }
75
72
  /**
76
73
  * Attach a `dump` to each {@link DevframeRpcOptions.snapshot} target so the
@@ -1,10 +1,21 @@
1
- import { Dt as parseCliFlags, Et as defineCliFlags, F as DevframeDefinition, Tt as InferCliFlags, wt as CliFlagsSchema } from "../context-CLF4-8Pp.mjs";
1
+ import { Dt as InferCliFlags, Et as CliFlagsSchema, F as DevframeDefinition, Ot as defineCliFlags, kt as parseCliFlags, q as McpSetting } from "../context-CHW4BZOj.mjs";
2
2
  import { CAC } from "cac";
3
3
  import { H3 } from "h3";
4
4
  //#region src/adapters/cac.d.ts
5
5
  interface CreateCacOptions {
6
6
  /** Default port for `dev` (default: 9999). */
7
7
  defaultPort?: number;
8
+ /**
9
+ * Expose a route-based MCP server alongside the dev server, speaking the
10
+ * MCP Streamable-HTTP transport at `<base>__mcp`. Whether to expose MCP is
11
+ * a hosting decision made at the CLI assembly stage, so it lives here rather
12
+ * than on the definition. When unset, falls back to the definition's
13
+ * deprecated `cli.mcp`, then to the `'auto'` default (mount once the agent
14
+ * surface is non-empty). See {@link McpSetting}.
15
+ *
16
+ * The `--mcp` / `--no-mcp` flags override this per run.
17
+ */
18
+ mcp?: McpSetting;
8
19
  /**
9
20
  * Final CAC hook invoked after devframe's built-in subcommands and
10
21
  * after the definition's `cli.configure`. Use this to add app-level
@@ -1,13 +1,12 @@
1
- import { s as colors } from "../nostics-CzECRXpE.mjs";
2
- import { r as resolveDevServerPort } from "../_shared-BM3PdYli.mjs";
3
- import { a as importRuntimeModule } from "../instance-shell-CpVW4zG0.mjs";
1
+ import { s as colors } from "../nostics-D0PvLZsn.mjs";
2
+ import { i as resolveDevServerPort, s as importRuntimeModule } from "../_shared-U8D-xzrp.mjs";
4
3
  import { createBuild } from "./build.mjs";
5
- import { t as createDevServer } from "../dev-CzkPCJwi.mjs";
4
+ import { t as createDevServer } from "../dev-CRYHx7iG.mjs";
6
5
  import process from "node:process";
7
6
  import cac$1 from "cac";
8
7
  //#region src/adapters/flags.ts
9
8
  /**
10
- * Identity helper that preserves the literal schema-map type — use this
9
+ * Identity helper that preserves the literal schema-map type; use this
11
10
  * so `InferCliFlags<typeof myFlags>` resolves to the right object shape.
12
11
  *
13
12
  * ```ts
@@ -96,7 +95,7 @@ function createCac(d, options = {}) {
96
95
  const defaultHost = d.cli?.host ?? "localhost";
97
96
  const command = d.cli?.command ?? d.id;
98
97
  const cli = cac$1(command);
99
- const devCommand = cli.command("[...args]", "Start a local dev server").option("--port <port>", "Port to listen on").option("--host <host>", "Host to bind to", { default: defaultHost }).option("--open", "Open the browser on start").option("--no-open", "Do not open the browser").option("--no-auth", "Disable the interactive authentication gate").option("--mcp", "Expose an MCP server over HTTP at /__mcp (use --no-mcp to disable)");
98
+ const devCommand = cli.command("[...args]", "Start a local dev server").option("--port <port>", "Port to listen on").option("--host <host>", "Host to bind to", { default: defaultHost }).option("--open", "Open the browser on start").option("--no-open", "Do not open the browser").option("--no-auth", "Disable the interactive authentication gate").option("--mcp", "Force the MCP route on (use --no-mcp to disable; default mounts it once agent tools exist)");
100
99
  if (d.cli?.flags) for (const [key, schema] of Object.entries(d.cli.flags)) {
101
100
  const optionName = flagKeyToOption(key);
102
101
  const description = schema.description ?? "";
@@ -110,7 +109,7 @@ function createCac(d, options = {}) {
110
109
  host,
111
110
  defaultPort
112
111
  });
113
- const mcp = flags.mcp;
112
+ const mcp = flags.mcp ?? options.mcp;
114
113
  await createDevServer(d, {
115
114
  host,
116
115
  port,
@@ -129,6 +128,7 @@ function createCac(d, options = {}) {
129
128
  const { createMcpServer } = await importRuntimeModule("devframe/adapters/mcp");
130
129
  await createMcpServer(d, {
131
130
  transport: "stdio",
131
+ /** Deliberately go to stderr: stdout is the MCP transport. */
132
132
  onReady: ({ transport }) => {
133
133
  console.error(`[devframe] "${d.id}" MCP server ready (${transport})`);
134
134
  }
@@ -150,7 +150,7 @@ function resolveTypedFlags(d, raw) {
150
150
  if (!d.cli?.flags) return raw;
151
151
  const { flags, issues } = parseCliFlags(d.cli.flags, raw);
152
152
  if (issues?.length) {
153
- for (const issue of issues) console.error(colors.red`[devframe] invalid flag — ${issue}`);
153
+ for (const issue of issues) console.error(colors.red`[devframe] invalid flag: ${issue}`);
154
154
  process.exit(1);
155
155
  }
156
156
  return flags;
@@ -1,8 +1,8 @@
1
- import { d as DevframeRpcConnection, n as WsOriginRegistry, u as DevframeNodeRpcSessionMeta } from "../ws-server-VyHlanzy.mjs";
2
- import { Ct as DevframeAuthHandler, F as DevframeDefinition, G as McpRouteOptions, U as DevframeSseOptions, W as DevframeWsOptions, s as DevframeNodeRpcSession } from "../context-CLF4-8Pp.mjs";
3
- import { o as StaticAssetsSource } from "../remote-assets-B13_vRkJ.mjs";
4
- import { c as StartedServer } from "../instance-shell-Tcp5hGoq.mjs";
5
- import { a as resolveMcpConnectionMeta, i as resolveDevServerPort, t as ResolveDevServerPortOptions } from "../_shared-mtXpcJIv.mjs";
1
+ import { c as DevframeNodeRpcSessionMeta, l as DevframeRpcConnection, n as WsOriginRegistry } from "../ws-server-D2nv68Hg.mjs";
2
+ import { F as DevframeDefinition, Tt as DevframeAuthHandler, U as DevframeSseOptions, W as DevframeWsOptions, q as McpSetting, s as DevframeNodeRpcSession } from "../context-CHW4BZOj.mjs";
3
+ import { o as StaticAssetsSource } from "../remote-assets-eBvSKZMS.mjs";
4
+ import { c as StartedServer } from "../instance-shell-DZipaP9k.mjs";
5
+ import { c as resolveMcpConnectionMeta, o as resolveDevServerPort, t as ResolveDevServerPortOptions } from "../_shared-CCzf9Hub.mjs";
6
6
  import { H3 } from "h3";
7
7
  //#region src/adapters/dev.d.ts
8
8
  interface CreateDevServerOptions {
@@ -23,7 +23,7 @@ interface CreateDevServerOptions {
23
23
  /**
24
24
  * Override the definition's `clientAssets` (or deprecated `cli.distDir`).
25
25
  * When neither this option nor the definition's client assets are set, the
26
- * dev server runs in **bridge mode** — only `__connection.json` and the WS
26
+ * dev server runs in **bridge mode**: only `__connection.json` and the WS
27
27
  * endpoint are mounted; the SPA is expected to be hosted elsewhere (e.g. by
28
28
  * a parent Vite/Nuxt dev server via `devframeViteBridge` from
29
29
  * `@devframes/vite`).
@@ -37,7 +37,7 @@ interface CreateDevServerOptions {
37
37
  /**
38
38
  * Override how the browser reaches the RPC WebSocket (`def.cli?.ws`).
39
39
  * See {@link DevframeWsOptions}: same-server route (default), a dedicated
40
- * port, or a remote origin. Pass `false` to serve no WebSocket at all —
40
+ * port, or a remote origin. Pass `false` to serve no WebSocket at all;
41
41
  * clients connect over the SSE endpoint instead (`backend: 'sse'`).
42
42
  */
43
43
  ws?: DevframeWsOptions | false;
@@ -49,7 +49,7 @@ interface CreateDevServerOptions {
49
49
  */
50
50
  allowedOrigins?: readonly string[] | WsOriginRegistry | false;
51
51
  /**
52
- * Override the SSE RPC endpoint control (`def.cli?.sse`) — enabled by
52
+ * Override the SSE RPC endpoint control (`def.cli?.sse`), enabled by
53
53
  * default at `<base>__sse`. Pass `false` to disable, or a
54
54
  * {@link DevframeSseOptions} to rename the route.
55
55
  */
@@ -71,7 +71,7 @@ interface CreateDevServerOptions {
71
71
  /**
72
72
  * Override how authentication resolves, taking precedence over
73
73
  * `def.cli?.auth`. Pass `false` to skip the gate entirely (the standard
74
- * choice for a **hosted** deployment where the host manages auth — see
74
+ * choice for a **hosted** deployment where the host manages auth; see
75
75
  * {@link devframeViteBridge} from `@devframes/vite`); a {@link DevframeAuthHandler} to install a custom
76
76
  * scheme; or `true` to force devframe's interactive OTP gate on. When
77
77
  * omitted, auth resolves from `flags.auth` / `def.cli?.auth` (the standalone
@@ -81,11 +81,11 @@ interface CreateDevServerOptions {
81
81
  auth?: boolean | DevframeAuthHandler;
82
82
  /**
83
83
  * Expose a route-based MCP server on the dev server (Streamable-HTTP).
84
- * Overrides `def.cli?.mcp`; `undefined` falls through to it. `false`
85
- * disables the route regardless of the definition default. See
86
- * {@link McpRouteOptions}.
84
+ * Overrides `def.cli?.mcp`; `undefined` falls through to it, then to the
85
+ * `'auto'` default (mount once the agent surface is non-empty). `false`
86
+ * disables the route regardless. See {@link McpSetting}.
87
87
  */
88
- mcp?: boolean | McpRouteOptions;
88
+ mcp?: McpSetting;
89
89
  /**
90
90
  * Called once per new RPC connection, right after its session is created.
91
91
  * Forwarded verbatim to the underlying transport binding.
@@ -99,7 +99,7 @@ interface CreateDevServerOptions {
99
99
  onPeerDisconnect?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
100
100
  /**
101
101
  * Called once the WS server is bound. Devframe stays headless
102
- * otherwise — wire this if you want a startup banner.
102
+ * otherwise, so wire this if you want a startup banner.
103
103
  */
104
104
  onReady?: (info: {
105
105
  origin: string;
@@ -108,20 +108,20 @@ interface CreateDevServerOptions {
108
108
  }) => void | Promise<void>;
109
109
  /**
110
110
  * Proceed even when the definition declares `capabilities.dev: false`.
111
- * `createDevServer` otherwise refuses such a definition (`DF0058`) — this
111
+ * `createDevServer` otherwise refuses such a definition (`DF0058`); this
112
112
  * only matters for a caller invoking it directly, bypassing the CLI.
113
113
  */
114
114
  force?: boolean;
115
115
  }
116
116
  /**
117
- * Start a devframe dev server for a {@link DevframeDefinition} —
117
+ * Start a devframe dev server for a {@link DevframeDefinition}:
118
118
  * h3 + WebSocket RPC + (optionally) the author's SPA mounted at the
119
119
  * resolved base path.
120
120
  *
121
121
  * When `distDir` is omitted (and the definition's client assets are unset) the
122
122
  * server runs in **bridge mode**: only `__connection.json` and the WS
123
123
  * endpoint are mounted, with no SPA mount. The SPA is expected to be
124
- * hosted elsewhere (e.g. by a parent Vite/Nuxt dev server) — see
124
+ * hosted elsewhere (e.g. by a parent Vite/Nuxt dev server); see
125
125
  * `devframeViteBridge` from `@devframes/vite`.
126
126
  *
127
127
  * Returns the underlying {@link StartedServer} handle so callers can
@@ -1,3 +1,3 @@
1
- import { i as resolveMcpConnectionMeta, r as resolveDevServerPort } from "../_shared-BM3PdYli.mjs";
2
- import { t as createDevServer } from "../dev-CzkPCJwi.mjs";
1
+ import { i as resolveDevServerPort, o as resolveMcpConnectionMeta } from "../_shared-U8D-xzrp.mjs";
2
+ import { t as createDevServer } from "../dev-CRYHx7iG.mjs";
3
3
  export { createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
@@ -1,4 +1,4 @@
1
- import { F as DevframeDefinition, o as DevframeNodeContext } from "../context-CLF4-8Pp.mjs";
1
+ import { F as DevframeDefinition, o as DevframeNodeContext } from "../context-CHW4BZOj.mjs";
2
2
  //#region src/adapters/embedded.d.ts
3
3
  interface CreateEmbeddedOptions {
4
4
  /** Target context the devframe is registered into. Required. */