devframe 0.8.2 → 0.9.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/_shared-BPmX9fqK.d.mts +41 -0
  2. package/dist/_shared-CbZ_yhbz.mjs +68 -0
  3. package/dist/adapters/build.d.mts +10 -12
  4. package/dist/adapters/build.mjs +26 -29
  5. package/dist/adapters/cac.d.mts +1 -1
  6. package/dist/adapters/cac.mjs +156 -1
  7. package/dist/adapters/dev.d.mts +38 -46
  8. package/dist/adapters/dev.mjs +2 -1
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +224 -0
  11. package/dist/adapters/initiate.mjs +2 -0
  12. package/dist/adapters/mcp.d.mts +24 -7
  13. package/dist/adapters/mcp.mjs +2 -2
  14. package/dist/{agent-tool-name-C3b5vEwJ.mjs → agent-tool-name-EgfoFO8C.mjs} +0 -3
  15. package/dist/cli/main.d.mts +0 -2
  16. package/dist/cli/main.mjs +4 -8
  17. package/dist/client/index.d.mts +71 -7
  18. package/dist/client/index.mjs +720 -1540
  19. package/dist/constants.d.mts +28 -7
  20. package/dist/constants.mjs +28 -7
  21. package/dist/{context-DoSozfvx.d.mts → context-B3YUu_95.d.mts} +19 -1
  22. package/dist/{host-h3-D2hYZvDK.mjs → context-CEe4PBz1.mjs} +25 -557
  23. package/dist/{context-CBg8iRbQ.mjs → context-xdynGSLP.mjs} +10 -1
  24. package/dist/dev--rAPzbvO.mjs +239 -0
  25. package/dist/{devframe-mQ4qZAuo.d.mts → devframe-DJMg0WLe.d.mts} +181 -134
  26. package/dist/{diagnostics-hwjXp_UV.mjs → diagnostics-CD8nlgll.mjs} +1 -3
  27. package/dist/{diagnostics-D7wM2cwM.mjs → diagnostics-DOQPnQmX.mjs} +51 -5
  28. package/dist/dist-eNI9qM_I.mjs +228 -0
  29. package/dist/host-agent-xLCSe65D.mjs +264 -0
  30. package/dist/host-h3-Crkzm42q.mjs +26 -0
  31. package/dist/{fetch-BKaD0Vb3.mjs → http-DYpK0cUi.mjs} +42 -11
  32. package/dist/{index-b64Uuhy2.d.mts → index-CB-fSUyn.d.mts} +2 -2
  33. package/dist/{index-Dbw1p5ch.d.mts → index-tdrk1bzV.d.mts} +3 -32
  34. package/dist/index.d.mts +12 -5
  35. package/dist/index.mjs +8 -1
  36. package/dist/{instance-registry-BnnA2Eoh.mjs → instance-registry-WvQkt42E.mjs} +9 -8
  37. package/dist/instance-shell-CMFyszWJ.mjs +486 -0
  38. package/dist/instance-shell-CljiKq1c.d.mts +255 -0
  39. package/dist/internal/index.d.mts +397 -0
  40. package/dist/internal/index.mjs +9 -0
  41. package/dist/node/auth.d.mts +2 -2
  42. package/dist/node/auth.mjs +1 -1
  43. package/dist/node/hub-internals.d.mts +2 -14
  44. package/dist/node/hub-internals.mjs +2 -2
  45. package/dist/node/index.d.mts +4 -268
  46. package/dist/node/index.mjs +3 -5
  47. package/dist/nostics-CzECRXpE.mjs +59 -0
  48. package/dist/nostics-SPGDgHEP.d.mts +33 -0
  49. package/dist/recipes/common-rpc-functions.d.mts +4 -4
  50. package/dist/recipes/interactive-auth.d.mts +3 -3
  51. package/dist/recipes/interactive-auth.mjs +8 -8
  52. package/dist/remote-assets-Bg4gCUZ_.d.mts +123 -0
  53. package/dist/remote-assets-nTTxY2MU.mjs +636 -0
  54. package/dist/rolldown-runtime-JspESFgx.mjs +35 -0
  55. package/dist/rpc/dump.d.mts +77 -1
  56. package/dist/rpc/dump.mjs +1 -1
  57. package/dist/rpc/index.d.mts +3 -3
  58. package/dist/rpc/index.mjs +4 -18
  59. package/dist/rpc/transports/sse-client.d.mts +2 -0
  60. package/dist/rpc/transports/sse-client.mjs +142 -0
  61. package/dist/rpc/transports/sse-server.d.mts +61 -0
  62. package/dist/rpc/transports/sse-server.mjs +209 -0
  63. package/dist/rpc/transports/ws-bun.d.mts +35 -0
  64. package/dist/rpc/transports/ws-bun.mjs +31 -0
  65. package/dist/rpc/transports/ws-client.d.mts +1 -1
  66. package/dist/rpc/transports/ws-client.mjs +10 -18
  67. package/dist/rpc/transports/ws-server.d.mts +2 -2
  68. package/dist/rpc/transports/ws-server.mjs +2 -235
  69. package/dist/rpc-core-Cc4lucI0.d.mts +48 -0
  70. package/dist/rpc-core-DMTe-hLo.mjs +81 -0
  71. package/dist/{serialization-C8Mnw9hK.mjs → serialization-BGzEwAdr.mjs} +2 -2
  72. package/dist/{shared-state-6kHolYZy.mjs → shared-state-fRRbRUtD.mjs} +1 -1
  73. package/dist/sse-client-CFBOIaUi.d.mts +37 -0
  74. package/dist/state-Cc1IeSmQ.mjs +1291 -0
  75. package/dist/{dump-CgZShDRB.mjs → static-BPZ1_OPA.mjs} +3 -266
  76. package/dist/storage-CYye7P7L.mjs +137 -0
  77. package/dist/types/index.d.mts +6 -4
  78. package/dist/types/index.mjs +1 -6
  79. package/dist/{types-CnJSgRVa.d.mts → types-Djq7CBXh.d.mts} +0 -7
  80. package/dist/utils/agent-tool-name.d.mts +0 -3
  81. package/dist/utils/agent-tool-name.mjs +0 -3
  82. package/dist/utils/events.d.mts +1 -1
  83. package/dist/utils/get-port.d.mts +17 -0
  84. package/dist/utils/get-port.mjs +2 -0
  85. package/dist/utils/launch-editor.mjs +1 -25
  86. package/dist/utils/nostics.d.mts +2 -0
  87. package/dist/utils/nostics.mjs +2 -0
  88. package/dist/utils/open.d.mts +2 -10
  89. package/dist/utils/open.mjs +56 -1
  90. package/dist/utils/remote-assets.d.mts +15 -0
  91. package/dist/utils/remote-assets.mjs +2 -0
  92. package/dist/utils/serve-static.d.mts +13 -5
  93. package/dist/utils/serve-static.mjs +119 -9
  94. package/dist/utils/shared-state.d.mts +1 -1
  95. package/dist/utils/shared-state.mjs +1 -1
  96. package/dist/utils/simple-schema.d.mts +101 -1
  97. package/dist/utils/streaming-channel.d.mts +1 -1
  98. package/dist/validation-CpXFB6Dz.mjs +266 -0
  99. package/dist/wire-codec-0K-o5MYW.mjs +56 -0
  100. package/dist/{ws-client-B6Tnr0ic.d.mts → ws-client-DhjNyQo3.d.mts} +7 -2
  101. package/dist/ws-server-BdSLrhxE.mjs +267 -0
  102. package/dist/{ws-server-uKQcClcJ.d.mts → ws-server-D1d3QM9f.d.mts} +90 -9
  103. package/package.json +13 -12
  104. package/skills/devframe/SKILL.md +91 -93
  105. package/dist/_shared-bWRzeSa0.mjs +0 -19
  106. package/dist/adapters/cli.d.mts +0 -11
  107. package/dist/adapters/cli.mjs +0 -6
  108. package/dist/cac-D4_9ok0z.mjs +0 -157
  109. package/dist/dev-Bc49u3qg.mjs +0 -439
  110. package/dist/diagnostics-reporter-CsIG85Q5.mjs +0 -38
  111. package/dist/helpers/vite.d.mts +0 -100
  112. package/dist/helpers/vite.mjs +0 -105
  113. package/dist/http-C4T68YV6.mjs +0 -38
  114. package/dist/index-vAX6bYuc.d.mts +0 -78
  115. package/dist/open-Deb5xmIT.mjs +0 -547
  116. package/dist/recipes/open-helpers.d.mts +0 -6
  117. package/dist/recipes/open-helpers.mjs +0 -6
  118. package/dist/server-CD8XmBXl.mjs +0 -167
  119. package/dist/server-UHWae43Q.d.mts +0 -149
  120. package/dist/simple-schema-BDzLeJDk.d.mts +0 -102
  121. package/dist/state-BeUHDDjk.mjs +0 -108
  122. package/dist/storage-CTNVbuFB.mjs +0 -1122
  123. package/dist/utils/promise.d.mts +0 -8
  124. package/dist/utils/promise.mjs +0 -15
  125. package/dist/utils/scope.d.mts +0 -11
  126. package/dist/utils/scope.mjs +0 -15
  127. package/skills/devframe/templates/spa-devframe.ts +0 -38
@@ -0,0 +1,41 @@
1
+ import { d as ConnectionMeta, l as McpRouteOptions, n as DevframeDefinition, r as DevframeDeploymentKind } from "./devframe-DJMg0WLe.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
+ * Resolve the `mcp` entry a `__connection.json` should advertise for a dev
29
+ * server started with the given `mcp` option (falling back to `def.cli?.mcp`,
30
+ * exactly like `createDevServer`), or `undefined` when the route is
31
+ * disabled.
32
+ *
33
+ * Hosted bridges that hand-roll their connection meta pass the side-car
34
+ * `port`: the advertised path becomes absolute (the side-car mounts at `/`)
35
+ * and the client dials `<page-host>:<port><path>`. Without `port` the path
36
+ * stays relative, resolved against `__connection.json`'s own location (the
37
+ * same-server default).
38
+ */
39
+ declare function resolveMcpConnectionMeta(def: DevframeDefinition, mcp: boolean | McpRouteOptions | undefined, port?: number): ConnectionMeta['mcp'];
40
+ //#endregion
41
+ export { resolveMcpConnectionMeta as a, resolveDevServerPort as i, normalizeBasePath as n, resolveBasePath as r, ResolveDevServerPortOptions as t };
@@ -0,0 +1,68 @@
1
+ import "./constants.mjs";
2
+ import { n as getPort } from "./dist-eNI9qM_I.mjs";
3
+ import { cleanDoubleSlashes, withLeadingSlash, withTrailingSlash, withoutLeadingSlash } from "ufo";
4
+ //#region src/adapters/_shared.ts
5
+ const DEFAULT_PORT = 9999;
6
+ /**
7
+ * Resolve the mount base path for a devframe's SPA. Hosted adapters
8
+ * (`vite`, `embedded`) default to `/__<id>/` so they don't collide
9
+ * with the host app; standalone adapters (`cli`, `build`)
10
+ * default to `/` because they own the origin.
11
+ *
12
+ * The devframe author can override with `basePath` on the definition.
13
+ */
14
+ function resolveBasePath(def, kind) {
15
+ if (def.basePath) return normalizeBasePath(def.basePath);
16
+ return kind === "standalone" ? "/" : `/__${def.id}/`;
17
+ }
18
+ function normalizeBasePath(base) {
19
+ return cleanDoubleSlashes(withTrailingSlash(withLeadingSlash(base)));
20
+ }
21
+ /**
22
+ * Resolve the listening port for `createDevServer` (and `createHandler`'s
23
+ * side-car tiers), honoring the definition's `cli.port` / `cli.portRange` /
24
+ * `cli.random` settings. Exposed separately so authors who run their own
25
+ * argv parsing can resolve a port up-front (to print it, log it, etc.)
26
+ * before starting the server.
27
+ */
28
+ async function resolveDevServerPort(def, options = {}) {
29
+ const host = options.host ?? def.cli?.host ?? "localhost";
30
+ const portOptions = {
31
+ port: options.defaultPort ?? def.cli?.port ?? DEFAULT_PORT,
32
+ host
33
+ };
34
+ if (def.cli?.portRange) portOptions.portRange = def.cli.portRange;
35
+ if (def.cli?.random) portOptions.random = def.cli.random;
36
+ return getPort(portOptions);
37
+ }
38
+ /**
39
+ * Normalize the `cli.mcp` / `mcp` option (`boolean | McpRouteOptions`) into
40
+ * concrete options, or `undefined` when the MCP route is disabled.
41
+ */
42
+ function resolveMcpConfig(mcp) {
43
+ if (!mcp) return void 0;
44
+ return mcp === true ? {} : mcp;
45
+ }
46
+ /**
47
+ * Resolve the `mcp` entry a `__connection.json` should advertise for a dev
48
+ * server started with the given `mcp` option (falling back to `def.cli?.mcp`,
49
+ * exactly like `createDevServer`), or `undefined` when the route is
50
+ * disabled.
51
+ *
52
+ * Hosted bridges that hand-roll their connection meta pass the side-car
53
+ * `port`: the advertised path becomes absolute (the side-car mounts at `/`)
54
+ * and the client dials `<page-host>:<port><path>`. Without `port` the path
55
+ * stays relative, resolved against `__connection.json`'s own location (the
56
+ * same-server default).
57
+ */
58
+ function resolveMcpConnectionMeta(def, mcp, port) {
59
+ const config = resolveMcpConfig(mcp ?? def.cli?.mcp);
60
+ if (!config) return void 0;
61
+ const route = withoutLeadingSlash(config.path ?? "__mcp");
62
+ return port != null ? {
63
+ path: withLeadingSlash(route),
64
+ port
65
+ } : { path: route };
66
+ }
67
+ //#endregion
68
+ export { resolveMcpConnectionMeta as i, resolveBasePath as n, resolveDevServerPort as r, normalizeBasePath as t };
@@ -1,16 +1,16 @@
1
- import { r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
1
+ import { n as DevframeDefinition } from "../devframe-DJMg0WLe.mjs";
2
+ import { o as StaticAssetsSource } from "../remote-assets-Bg4gCUZ_.mjs";
2
3
  //#region src/adapters/build.d.ts
3
4
  interface CreateBuildOptions {
4
5
  /** Output directory. Defaults to `dist-static`. */
5
6
  outDir?: string;
6
- /** Absolute URL base the output is served from (default: `/`). */
7
- base?: string;
8
7
  /**
9
- * Override the SPA dist directory to copy into `outDir`. When omitted
10
- * the adapter reads `devframe.cli?.distDir` — authors typically set this
11
- * once on the definition itself.
8
+ * Override the SPA dist to copy into `outDir` — a local directory or a
9
+ * remote-assets declaration (materialized in full at build time). When
10
+ * omitted the adapter reads `devframe.cli?.distDir` — authors typically
11
+ * set this once on the definition itself.
12
12
  */
13
- distDir?: string;
13
+ distDir?: StaticAssetsSource;
14
14
  /**
15
15
  * Pretty-print RPC dump JSON files. Defaults to `false` so payload
16
16
  * shards (which can be multiple MB for graph-heavy tools) ship
@@ -32,11 +32,9 @@ interface CreateBuildOptions {
32
32
  * - Copy the author's SPA dist into `<outDir>/`.
33
33
  * - Write `<outDir>/__connection.json` (`{ backend: 'static' }`) and the
34
34
  * sharded RPC dump under `<outDir>/__rpc-dump/` so the deployed SPA
35
- * discovers both via relative paths from `document.baseURI`.
36
- * - When `def.spa` is configured, also write `<outDir>/spa-loader.json`
37
- * describing the SPA's data-loader mode (`'query'` / `'upload'` /
38
- * `'none'`). The output is mount-path agnostic — the same bundle
39
- * works at `/`, `/devframe/`, or any base, no rewriting required.
35
+ * discovers both via relative paths from `document.baseURI`. The
36
+ * output is mount-path agnostic — the same bundle works at `/`,
37
+ * `/devframe/`, or any base, no rewriting required.
40
38
  */
41
39
  declare function createBuild(d: DevframeDefinition, options?: CreateBuildOptions): Promise<void>;
42
40
  //#endregion
@@ -1,15 +1,16 @@
1
- import { t as collectStaticRpcDump } from "../dump-CgZShDRB.mjs";
2
- import { n as colors } from "../diagnostics-reporter-CsIG85Q5.mjs";
1
+ import { s as colors } from "../nostics-CzECRXpE.mjs";
2
+ import { n as strictJsonStringify } from "../serialization-BGzEwAdr.mjs";
3
3
  import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
4
- import { n as strictJsonStringify } from "../serialization-C8Mnw9hK.mjs";
4
+ import { t as collectStaticRpcDump } from "../static-BPZ1_OPA.mjs";
5
5
  import { n as structuredCloneStringify } from "../structured-clone-CbAV5rFI.mjs";
6
- import { n as createHostContext, t as createH3DevframeHost } from "../host-h3-D2hYZvDK.mjs";
7
- import { t as diagnostics } from "../diagnostics-D7wM2cwM.mjs";
8
- import { n as resolveBasePath } from "../_shared-bWRzeSa0.mjs";
6
+ import { t as diagnostics } from "../diagnostics-DOQPnQmX.mjs";
7
+ import { t as createHostContext } from "../context-CEe4PBz1.mjs";
8
+ import { t as resolveStaticAssetsSource } from "../remote-assets-nTTxY2MU.mjs";
9
+ import { t as createH3DevframeHost } from "../host-h3-Crkzm42q.mjs";
9
10
  import { existsSync } from "node:fs";
11
+ import fs$1 from "node:fs/promises";
10
12
  import { dirname, resolve } from "pathe";
11
13
  import process from "node:process";
12
- import fs$1 from "node:fs/promises";
13
14
  //#region src/adapters/build.ts
14
15
  /**
15
16
  * Produce a self-contained static deploy of a devframe:
@@ -18,28 +19,33 @@ import fs$1 from "node:fs/promises";
18
19
  * - Copy the author's SPA dist into `<outDir>/`.
19
20
  * - Write `<outDir>/__connection.json` (`{ backend: 'static' }`) and the
20
21
  * sharded RPC dump under `<outDir>/__rpc-dump/` so the deployed SPA
21
- * discovers both via relative paths from `document.baseURI`.
22
- * - When `def.spa` is configured, also write `<outDir>/spa-loader.json`
23
- * describing the SPA's data-loader mode (`'query'` / `'upload'` /
24
- * `'none'`). The output is mount-path agnostic — the same bundle
25
- * works at `/`, `/devframe/`, or any base, no rewriting required.
22
+ * discovers both via relative paths from `document.baseURI`. The
23
+ * output is mount-path agnostic — the same bundle works at `/`,
24
+ * `/devframe/`, or any base, no rewriting required.
26
25
  */
27
26
  async function createBuild(d, options = {}) {
28
27
  if (d.capabilities?.build === false && !options.force) throw diagnostics.DF0042({ id: d.id });
29
28
  const outDir = resolve(options.outDir ?? "dist-static");
30
- const distDir = options.distDir ?? d.cli?.distDir;
31
- if (!distDir) throw new Error(`[devframe] createBuild: no distDir for "${d.id}". Set \`cli.distDir\` on the definition or pass it as an option.`);
29
+ const distSource = options.distDir ?? d.cli?.distDir;
30
+ if (!distSource) throw new Error(`[devframe] createBuild: no distDir for "${d.id}". Set \`cli.distDir\` on the definition or pass it as an option.`);
32
31
  if (existsSync(outDir)) await fs$1.rm(outDir, { recursive: true });
33
32
  await fs$1.mkdir(outDir, { recursive: true });
34
- console.log(colors.cyan`[devframe] copying SPA from ${distDir} -> ${outDir}`);
35
- await fs$1.cp(distDir, outDir, { recursive: true });
33
+ const host = createH3DevframeHost({
34
+ origin: "http://localhost",
35
+ appName: d.id
36
+ });
37
+ const resolved = resolveStaticAssetsSource(distSource, host.getStorageDir("project"));
38
+ if (typeof resolved === "string") {
39
+ console.log(colors.cyan`[devframe] copying SPA from ${resolved} -> ${outDir}`);
40
+ await fs$1.cp(resolved, outDir, { recursive: true });
41
+ } else {
42
+ console.log(colors.cyan`[devframe] materializing SPA from ${resolved.assets.package}@${resolved.assets.version} -> ${outDir}`);
43
+ await resolved.materialize(outDir);
44
+ }
36
45
  const ctx = await createHostContext({
37
46
  cwd: process.cwd(),
38
47
  mode: "build",
39
- host: createH3DevframeHost({
40
- origin: "http://localhost",
41
- appName: d.id
42
- })
48
+ host
43
49
  });
44
50
  await d.setup(ctx);
45
51
  await fs$1.mkdir(resolve(outDir, DEVFRAME_RPC_DUMP_DIRNAME), { recursive: true });
@@ -59,15 +65,6 @@ async function createBuild(d, options = {}) {
59
65
  await fs$1.writeFile(fullpath, file.serialization === "json" && indent != null ? JSON.stringify(JSON.parse(text), null, indent) : text, "utf-8");
60
66
  }
61
67
  await fs$1.writeFile(resolve(outDir, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME), JSON.stringify(dump.manifest, null, 2), "utf-8");
62
- if (d.spa) {
63
- const base = options.base ?? resolveBasePath(d, "standalone");
64
- const spaLoader = {
65
- version: 1,
66
- mode: d.spa.loader ?? "none",
67
- base
68
- };
69
- await fs$1.writeFile(resolve(outDir, "spa-loader.json"), JSON.stringify(spaLoader, null, 2), "utf-8");
70
- }
71
68
  console.log(colors.green`[devframe] built "${d.id}" -> ${outDir}`);
72
69
  }
73
70
  //#endregion
@@ -1,4 +1,4 @@
1
- import { Ft as InferCliFlags, It as defineCliFlags, Lt as parseCliFlags, Pt as CliFlagsSchema, r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
1
+ import { At as defineCliFlags, Ot as CliFlagsSchema, jt as parseCliFlags, kt as InferCliFlags, n as DevframeDefinition } from "../devframe-DJMg0WLe.mjs";
2
2
  import { CAC } from "cac";
3
3
  import { H3 } from "h3";
4
4
  //#region src/adapters/cac.d.ts
@@ -1,2 +1,157 @@
1
- import { n as defineCliFlags, r as parseCliFlags, t as createCac } from "../cac-D4_9ok0z.mjs";
1
+ import { s as colors } from "../nostics-CzECRXpE.mjs";
2
+ import { r as resolveDevServerPort } from "../_shared-CbZ_yhbz.mjs";
3
+ import { createBuild } from "./build.mjs";
4
+ import { t as createDevServer } from "../dev--rAPzbvO.mjs";
5
+ import process from "node:process";
6
+ import cac$1 from "cac";
7
+ //#region src/adapters/flags.ts
8
+ /**
9
+ * Identity helper that preserves the literal schema-map type — use this
10
+ * so `InferCliFlags<typeof myFlags>` resolves to the right object shape.
11
+ *
12
+ * ```ts
13
+ * const appFlags = defineCliFlags({
14
+ * depth: v.pipe(v.number(), v.integer()),
15
+ * config: v.optional(v.string()),
16
+ * })
17
+ *
18
+ * defineDevframe({
19
+ * cli: { flags: appFlags },
20
+ * setup(ctx, info) {
21
+ * const flags = info.flags as InferCliFlags<typeof appFlags>
22
+ * flags.depth // number
23
+ * flags.config // string | undefined
24
+ * },
25
+ * })
26
+ * ```
27
+ */
28
+ function defineCliFlags(flags) {
29
+ return flags;
30
+ }
31
+ /**
32
+ * Best-effort, dependency-free probe of a schema to decide whether the
33
+ * corresponding CAC option takes a value. Duck-types the `type` /
34
+ * `wrapped` / `inner` / `pipe` fields exposed by valibot and by devframe's
35
+ * built-in `s` builder, unwrapping `optional` / `nullable` / `nullish` /
36
+ * `pipe` wrappers then matching on the inner kind. Validators that don't
37
+ * expose these fields (e.g. zod) fall through to a value-taking option.
38
+ */
39
+ function getSchemaKind(schema) {
40
+ let current = schema;
41
+ while (current) {
42
+ const kind = current.type;
43
+ if (kind === "optional" || kind === "nullable" || kind === "nullish" || kind === "undefined") {
44
+ current = current.wrapped ?? current.inner;
45
+ continue;
46
+ }
47
+ if (kind === "pipe" && Array.isArray(current.pipe) && current.pipe.length > 0) {
48
+ current = current.pipe[0];
49
+ continue;
50
+ }
51
+ return kind ?? "unknown";
52
+ }
53
+ return "unknown";
54
+ }
55
+ /** Whether the CAC option for this schema should be a boolean flag. */
56
+ function isBooleanFlag(schema) {
57
+ return getSchemaKind(schema) === "boolean";
58
+ }
59
+ /** Validate the raw cac-parsed bag against a {@link CliFlagsSchema}. */
60
+ function parseCliFlags(schema, raw) {
61
+ const flags = {};
62
+ const issues = [];
63
+ for (const [key, fieldSchema] of Object.entries(schema)) {
64
+ const result = fieldSchema["~standard"].validate(raw[key]);
65
+ if (result instanceof Promise) {
66
+ issues.push(`--${toKebab(key)}: async flag validation is not supported`);
67
+ continue;
68
+ }
69
+ if (result.issues) issues.push(`--${toKebab(key)}: ${result.issues.map((i) => i.message).join(", ")}`);
70
+ else flags[key] = result.value;
71
+ }
72
+ for (const [key, value] of Object.entries(raw)) if (!(key in schema) && !(key in flags)) flags[key] = value;
73
+ return issues.length ? {
74
+ flags,
75
+ issues
76
+ } : { flags };
77
+ }
78
+ function toKebab(camel) {
79
+ return camel.replaceAll(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
80
+ }
81
+ /** Kebab-case a schema key for CAC option registration. */
82
+ function flagKeyToOption(camel) {
83
+ return toKebab(camel);
84
+ }
85
+ //#endregion
86
+ //#region src/adapters/cac.ts
87
+ /**
88
+ * Wrap a {@link DevframeDefinition} in a `cac`-powered command-line
89
+ * interface exposing `dev` / `build` / `mcp` subcommands.
90
+ *
91
+ * Requires the optional `cac` peer dependency.
92
+ */
93
+ function createCac(d, options = {}) {
94
+ const defaultPort = options.defaultPort ?? d.cli?.port ?? 9999;
95
+ const defaultHost = d.cli?.host ?? "localhost";
96
+ const cli = cac$1(d.cli?.command ?? d.id);
97
+ 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
+ if (d.cli?.flags) for (const [key, schema] of Object.entries(d.cli.flags)) {
99
+ const optionName = flagKeyToOption(key);
100
+ const description = schema.description ?? "";
101
+ if (isBooleanFlag(schema)) devCommand.option(`--${optionName}`, description);
102
+ else devCommand.option(`--${optionName} <value>`, description);
103
+ }
104
+ devCommand.action(async (_args, rawFlags) => {
105
+ const flags = resolveTypedFlags(d, rawFlags);
106
+ const host = flags.host ?? defaultHost;
107
+ const port = flags.port ?? await resolveDevServerPort(d, {
108
+ host,
109
+ defaultPort
110
+ });
111
+ const mcp = flags.mcp;
112
+ await createDevServer(d, {
113
+ host,
114
+ port,
115
+ flags,
116
+ mcp,
117
+ onReady: options.onReady
118
+ });
119
+ });
120
+ if (d.capabilities?.build !== false) cli.command("build", "Build a self-contained static deploy of the devframe").option("--out-dir <outDir>", "Output directory", { default: "dist-static" }).option("--pretty", "Pretty-print dump JSON (larger on disk)").action(async (flags) => {
121
+ await createBuild(d, {
122
+ outDir: flags.outDir,
123
+ pretty: flags.pretty
124
+ });
125
+ });
126
+ cli.command("mcp", "Start an MCP server exposing agent-facing tools (stdio)").action(async () => {
127
+ const { createMcpServer } = await import("./mcp.mjs");
128
+ await createMcpServer(d, {
129
+ transport: "stdio",
130
+ onReady: ({ transport }) => {
131
+ console.error(`[devframe] "${d.id}" MCP server ready (${transport})`);
132
+ }
133
+ });
134
+ });
135
+ d.cli?.configure?.(cli);
136
+ options.configureCli?.(cli);
137
+ cli.help();
138
+ cli.version("0.0.0");
139
+ return {
140
+ cli,
141
+ async parse(argv = process.argv) {
142
+ cli.parse(argv, { run: false });
143
+ await cli.runMatchedCommand();
144
+ }
145
+ };
146
+ }
147
+ function resolveTypedFlags(d, raw) {
148
+ if (!d.cli?.flags) return raw;
149
+ const { flags, issues } = parseCliFlags(d.cli.flags, raw);
150
+ if (issues?.length) {
151
+ for (const issue of issues) console.error(colors.red`[devframe] invalid flag — ${issue}`);
152
+ process.exit(1);
153
+ }
154
+ return flags;
155
+ }
156
+ //#endregion
2
157
  export { createCac, defineCliFlags, parseCliFlags };
@@ -1,7 +1,8 @@
1
- import { W as DevframeNodeRpcSession, _ as ConnectionMeta, d as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition, u as DevframeWsOptions } from "../devframe-mQ4qZAuo.mjs";
2
- import { n as DevframeNodeRpcSessionMeta } from "../ws-server-uKQcClcJ.mjs";
3
- import { n as StartedServer } from "../server-UHWae43Q.mjs";
4
- import { Peer } from "crossws";
1
+ import { R as DevframeNodeRpcSession, c as DevframeWsOptions, l as McpRouteOptions, n as DevframeDefinition, s as DevframeSseOptions, u as DevframeAuthHandler } from "../devframe-DJMg0WLe.mjs";
2
+ import { d as DevframeRpcConnection, n as WsOriginRegistry, u as DevframeNodeRpcSessionMeta } from "../ws-server-D1d3QM9f.mjs";
3
+ import { o as StaticAssetsSource } from "../remote-assets-Bg4gCUZ_.mjs";
4
+ import { c as StartedServer } from "../instance-shell-CljiKq1c.mjs";
5
+ import { a as resolveMcpConnectionMeta, i as resolveDevServerPort, t as ResolveDevServerPortOptions } from "../_shared-BPmX9fqK.mjs";
5
6
  import { H3 } from "h3";
6
7
  //#region src/adapters/dev.d.ts
7
8
  interface CreateDevServerOptions {
@@ -24,9 +25,9 @@ interface CreateDevServerOptions {
24
25
  * `def.cli?.distDir` is set, the dev server runs in **bridge mode** —
25
26
  * only `__connection.json` and the WS endpoint are mounted; the SPA
26
27
  * is expected to be hosted elsewhere (e.g. by a parent Vite/Nuxt
27
- * dev server via `viteDevBridge({ devMiddleware })`).
28
+ * dev server via `devframeViteBridge` from `@devframes/vite`).
28
29
  */
29
- distDir?: string;
30
+ distDir?: StaticAssetsSource;
30
31
  /**
31
32
  * Override the SPA mount path. Defaults to
32
33
  * `resolveBasePath(def, 'standalone')` (i.e. `def.basePath` or `/`).
@@ -35,9 +36,23 @@ interface CreateDevServerOptions {
35
36
  /**
36
37
  * Override how the browser reaches the RPC WebSocket (`def.cli?.ws`).
37
38
  * See {@link DevframeWsOptions}: same-server route (default), a dedicated
38
- * port, or a remote origin.
39
+ * port, or a remote origin. Pass `false` to serve no WebSocket at all —
40
+ * clients connect over the SSE endpoint instead (`backend: 'sse'`).
39
41
  */
40
- ws?: DevframeWsOptions;
42
+ ws?: DevframeWsOptions | false;
43
+ /**
44
+ * Extra origins to accept on the WS upgrade beyond the loopback default.
45
+ * Add your LAN/tunnel origin here when reaching the tool from another
46
+ * host. Pass `false` to disable origin checking entirely (not
47
+ * recommended). Default: loopback-only.
48
+ */
49
+ allowedOrigins?: readonly string[] | WsOriginRegistry | false;
50
+ /**
51
+ * Override the SSE RPC endpoint control (`def.cli?.sse`) — enabled by
52
+ * default at `<base>__sse`. Pass `false` to disable, or a
53
+ * {@link DevframeSseOptions} to rename the route.
54
+ */
55
+ sse?: boolean | DevframeSseOptions;
41
56
  /**
42
57
  * h3 app to mount the SPA + connection-meta routes on. When omitted
43
58
  * a fresh app is created. Pass a pre-configured app to attach custom
@@ -56,7 +71,7 @@ interface CreateDevServerOptions {
56
71
  * Override how authentication resolves, taking precedence over
57
72
  * `def.cli?.auth`. Pass `false` to skip the gate entirely (the standard
58
73
  * choice for a **hosted** deployment where the host manages auth — see
59
- * {@link viteDevBridge}); a {@link DevframeAuthHandler} to install a custom
74
+ * {@link devframeViteBridge} from `@devframes/vite`); a {@link DevframeAuthHandler} to install a custom
60
75
  * scheme; or `true` to force devframe's interactive OTP gate on. When
61
76
  * omitted, auth resolves from `flags.auth` / `def.cli?.auth` (the standalone
62
77
  * default: gated). The `--no-auth` flag (`flags.auth === false`) still forces
@@ -71,16 +86,16 @@ interface CreateDevServerOptions {
71
86
  */
72
87
  mcp?: boolean | McpRouteOptions;
73
88
  /**
74
- * Called once per new WS connection, right after its session is created.
75
- * Forwarded verbatim to the underlying `startHttpAndWs`.
89
+ * Called once per new RPC connection, right after its session is created.
90
+ * Forwarded verbatim to the underlying transport binding.
76
91
  */
77
- onPeerConnect?: (peer: Peer, session: DevframeNodeRpcSession) => void;
92
+ onPeerConnect?: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
78
93
  /**
79
- * Called once per closed WS connection, right after its session's
94
+ * Called once per closed RPC connection, right after its session's
80
95
  * disconnect bookkeeping runs. Forwarded verbatim to the underlying
81
- * `startHttpAndWs`.
96
+ * transport binding.
82
97
  */
83
- onPeerDisconnect?: (peer: Peer, meta: DevframeNodeRpcSessionMeta) => void;
98
+ onPeerDisconnect?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
84
99
  /**
85
100
  * Called once the WS server is bound. Devframe stays headless
86
101
  * otherwise — wire this if you want a startup banner.
@@ -90,21 +105,13 @@ interface CreateDevServerOptions {
90
105
  port: number;
91
106
  app: H3;
92
107
  }) => void | Promise<void>;
108
+ /**
109
+ * Proceed even when the definition declares `capabilities.dev: false`.
110
+ * `createDevServer` otherwise refuses such a definition (`DF0058`) — this
111
+ * only matters for a caller invoking it directly, bypassing the CLI.
112
+ */
113
+ force?: boolean;
93
114
  }
94
- interface ResolveDevServerPortOptions {
95
- /** Bind host (passed to `get-port-please` for in-use detection). */
96
- host?: string;
97
- /** Override the preferred port. Default: `def.cli?.port ?? 9999`. */
98
- defaultPort?: number;
99
- }
100
- /**
101
- * Resolve the listening port for {@link createDevServer}, honoring the
102
- * definition's `cli.port` / `cli.portRange` / `cli.random` settings.
103
- * Exposed separately so authors who run their own argv parsing can
104
- * resolve a port up-front (to print it, log it, etc.) before starting
105
- * the server.
106
- */
107
- declare function resolveDevServerPort(def: DevframeDefinition, options?: ResolveDevServerPortOptions): Promise<number>;
108
115
  /**
109
116
  * Start a devframe dev server for a {@link DevframeDefinition} —
110
117
  * h3 + WebSocket RPC + (optionally) the author's SPA mounted at the
@@ -114,7 +121,7 @@ declare function resolveDevServerPort(def: DevframeDefinition, options?: Resolve
114
121
  * server runs in **bridge mode**: only `__connection.json` and the WS
115
122
  * endpoint are mounted, with no SPA mount. The SPA is expected to be
116
123
  * hosted elsewhere (e.g. by a parent Vite/Nuxt dev server) — see
117
- * `viteDevBridge({ devMiddleware })`.
124
+ * `devframeViteBridge` from `@devframes/vite`.
118
125
  *
119
126
  * Returns the underlying {@link StartedServer} handle so callers can
120
127
  * close it gracefully (SIGINT, hot-reload, test teardown).
@@ -124,20 +131,5 @@ declare function resolveDevServerPort(def: DevframeDefinition, options?: Resolve
124
131
  * `dev` / `build` / `mcp` shell, reach for {@link createCac} instead.
125
132
  */
126
133
  declare function createDevServer(def: DevframeDefinition, options?: CreateDevServerOptions): Promise<StartedServer>;
127
- /**
128
- * Resolve the `mcp` entry a `__connection.json` should advertise for a dev
129
- * server started with the given `mcp` option (falling back to `def.cli?.mcp`,
130
- * exactly like {@link createDevServer}), or `undefined` when the route is
131
- * disabled.
132
- *
133
- * Hosted bridges that hand-roll their connection meta (`viteDevBridge`,
134
- * `@devframes/next`'s handler) pass the side-car `port`: the advertised path
135
- * becomes absolute (the side-car mounts at `/`) and the client dials
136
- * `<page-host>:<port><path>`. Without `port` the path stays relative, resolved
137
- * against `__connection.json`'s own location (the same-server default).
138
- *
139
- * @experimental
140
- */
141
- declare function resolveMcpConnectionMeta(def: DevframeDefinition, mcp: boolean | McpRouteOptions | undefined, port?: number): ConnectionMeta['mcp'];
142
134
  //#endregion
143
- export { CreateDevServerOptions, ResolveDevServerPortOptions, createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
135
+ export { CreateDevServerOptions, type ResolveDevServerPortOptions, createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
@@ -1,2 +1,3 @@
1
- import { n as resolveDevServerPort, r as resolveMcpConnectionMeta, t as createDevServer } from "../dev-Bc49u3qg.mjs";
1
+ import { i as resolveMcpConnectionMeta, r as resolveDevServerPort } from "../_shared-CbZ_yhbz.mjs";
2
+ import { t as createDevServer } from "../dev--rAPzbvO.mjs";
2
3
  export { createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
@@ -1,4 +1,4 @@
1
- import { b as DevframeNodeContext, r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
1
+ import { g as DevframeNodeContext, n as DevframeDefinition } from "../devframe-DJMg0WLe.mjs";
2
2
  //#region src/adapters/embedded.d.ts
3
3
  interface CreateEmbeddedOptions {
4
4
  /** Target context the devframe is registered into. Required. */