devframe 0.8.2 → 0.9.0-beta.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 (103) hide show
  1. package/dist/_shared-CttmCMBi.mjs +70 -0
  2. package/dist/_shared-DmpWW-HH.d.mts +43 -0
  3. package/dist/adapters/build.d.mts +1 -1
  4. package/dist/adapters/build.mjs +6 -5
  5. package/dist/adapters/cac.d.mts +1 -1
  6. package/dist/adapters/cac.mjs +157 -1
  7. package/dist/adapters/dev.d.mts +20 -42
  8. package/dist/adapters/dev.mjs +2 -1
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +223 -0
  11. package/dist/adapters/initiate.mjs +2 -0
  12. package/dist/adapters/mcp.d.mts +26 -2
  13. package/dist/adapters/mcp.mjs +2 -2
  14. package/dist/cli/main.mjs +2 -2
  15. package/dist/client/index.d.mts +70 -6
  16. package/dist/client/index.mjs +743 -408
  17. package/dist/constants.d.mts +19 -6
  18. package/dist/constants.mjs +19 -6
  19. package/dist/{context-CBg8iRbQ.mjs → context-C33rR7n0.mjs} +1 -1
  20. package/dist/{context-DoSozfvx.d.mts → context-CSCwoABx.d.mts} +1 -1
  21. package/dist/{host-h3-D2hYZvDK.mjs → context-Du11TLcO.mjs} +5 -255
  22. package/dist/dev-BEveeA5H.mjs +233 -0
  23. package/dist/{devframe-mQ4qZAuo.d.mts → devframe-Bdd9YXTy.d.mts} +88 -25
  24. package/dist/{diagnostics-D7wM2cwM.mjs → diagnostics-DLYH5oD3.mjs} +16 -0
  25. package/dist/dist-D8jAMwxU.mjs +227 -0
  26. package/dist/helpers/vite.d.mts +43 -39
  27. package/dist/helpers/vite.mjs +26 -38
  28. package/dist/host-agent-CpbAoqBx.mjs +230 -0
  29. package/dist/host-h3-CzCZwtuV.mjs +26 -0
  30. package/dist/{fetch-BKaD0Vb3.mjs → http-DLr_cJZ7.mjs} +42 -4
  31. package/dist/{index-b64Uuhy2.d.mts → index-CZRd2K1C.d.mts} +2 -2
  32. package/dist/{index-Dbw1p5ch.d.mts → index-DSCq4M4q.d.mts} +2 -31
  33. package/dist/index.d.mts +9 -4
  34. package/dist/index.mjs +8 -1
  35. package/dist/{instance-registry-BnnA2Eoh.mjs → instance-registry-BQqGoDO9.mjs} +9 -2
  36. package/dist/instance-shell-DBTXTSjN.d.mts +264 -0
  37. package/dist/instance-shell-KRdee1QF.mjs +485 -0
  38. package/dist/internal/index.d.mts +150 -0
  39. package/dist/internal/index.mjs +7 -0
  40. package/dist/node/auth.d.mts +2 -2
  41. package/dist/node/hub-internals.d.mts +2 -14
  42. package/dist/node/hub-internals.mjs +2 -2
  43. package/dist/node/index.d.mts +3 -267
  44. package/dist/node/index.mjs +3 -5
  45. package/dist/recipes/common-rpc-functions.d.mts +3 -3
  46. package/dist/recipes/interactive-auth.d.mts +3 -3
  47. package/dist/recipes/interactive-auth.mjs +6 -6
  48. package/dist/rolldown-runtime-JspESFgx.mjs +35 -0
  49. package/dist/rpc/dump.d.mts +77 -1
  50. package/dist/rpc/dump.mjs +1 -1
  51. package/dist/rpc/index.d.mts +2 -2
  52. package/dist/rpc/index.mjs +3 -17
  53. package/dist/rpc/transports/sse-client.d.mts +2 -0
  54. package/dist/rpc/transports/sse-client.mjs +142 -0
  55. package/dist/rpc/transports/sse-server.d.mts +61 -0
  56. package/dist/rpc/transports/sse-server.mjs +209 -0
  57. package/dist/rpc/transports/ws-bun.d.mts +35 -0
  58. package/dist/rpc/transports/ws-bun.mjs +31 -0
  59. package/dist/rpc/transports/ws-client.d.mts +1 -1
  60. package/dist/rpc/transports/ws-client.mjs +10 -18
  61. package/dist/rpc/transports/ws-server.d.mts +2 -2
  62. package/dist/rpc/transports/ws-server.mjs +2 -235
  63. package/dist/rpc-core-CGctXToO.d.mts +48 -0
  64. package/dist/rpc-core-CqcJkAu9.mjs +81 -0
  65. package/dist/{serialization-C8Mnw9hK.mjs → serialization-BHY8M5NQ.mjs} +1 -1
  66. package/dist/{shared-state-6kHolYZy.mjs → shared-state-fRRbRUtD.mjs} +1 -1
  67. package/dist/sse-client-BsIK3hMD.d.mts +37 -0
  68. package/dist/{dump-CgZShDRB.mjs → static-CvjkO8QE.mjs} +2 -265
  69. package/dist/{storage-CTNVbuFB.mjs → storage-BcmVEJRc.mjs} +2 -2
  70. package/dist/types/index.d.mts +3 -3
  71. package/dist/types/index.mjs +1 -6
  72. package/dist/utils/events.d.mts +1 -1
  73. package/dist/utils/launch-editor.mjs +1 -25
  74. package/dist/utils/open.mjs +1 -1
  75. package/dist/utils/serve-static.mjs +1 -1
  76. package/dist/utils/shared-state.d.mts +1 -1
  77. package/dist/utils/shared-state.mjs +1 -1
  78. package/dist/utils/simple-schema.d.mts +101 -1
  79. package/dist/utils/streaming-channel.d.mts +1 -1
  80. package/dist/validation-BiuDXTKW.mjs +266 -0
  81. package/dist/wire-codec-9VhIKnyp.mjs +58 -0
  82. package/dist/{ws-client-B6Tnr0ic.d.mts → ws-client-CdNuATYa.d.mts} +6 -1
  83. package/dist/ws-server-Bk1hOG3X.mjs +267 -0
  84. package/dist/{ws-server-uKQcClcJ.d.mts → ws-server-Ces08fjP.d.mts} +89 -8
  85. package/package.json +10 -9
  86. package/skills/devframe/SKILL.md +84 -85
  87. package/dist/_shared-bWRzeSa0.mjs +0 -19
  88. package/dist/adapters/cli.d.mts +0 -11
  89. package/dist/adapters/cli.mjs +0 -6
  90. package/dist/cac-D4_9ok0z.mjs +0 -157
  91. package/dist/dev-Bc49u3qg.mjs +0 -439
  92. package/dist/http-C4T68YV6.mjs +0 -38
  93. package/dist/index-vAX6bYuc.d.mts +0 -78
  94. package/dist/recipes/open-helpers.d.mts +0 -6
  95. package/dist/recipes/open-helpers.mjs +0 -6
  96. package/dist/server-CD8XmBXl.mjs +0 -167
  97. package/dist/server-UHWae43Q.d.mts +0 -149
  98. package/dist/simple-schema-BDzLeJDk.d.mts +0 -102
  99. package/dist/utils/promise.d.mts +0 -8
  100. package/dist/utils/promise.mjs +0 -15
  101. package/dist/utils/scope.d.mts +0 -11
  102. package/dist/utils/scope.mjs +0 -15
  103. package/dist/{open-Deb5xmIT.mjs → open-Dz4V4irZ.mjs} +1 -1
@@ -0,0 +1,70 @@
1
+ import "./constants.mjs";
2
+ import { n as getPort } from "./dist-D8jAMwxU.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`, `spa`, `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
+ * @experimental
59
+ */
60
+ function resolveMcpConnectionMeta(def, mcp, port) {
61
+ const config = resolveMcpConfig(mcp ?? def.cli?.mcp);
62
+ if (!config) return void 0;
63
+ const route = withoutLeadingSlash(config.path ?? "__mcp");
64
+ return port != null ? {
65
+ path: withLeadingSlash(route),
66
+ port
67
+ } : { path: route };
68
+ }
69
+ //#endregion
70
+ export { resolveMcpConnectionMeta as i, resolveBasePath as n, resolveDevServerPort as r, normalizeBasePath as t };
@@ -0,0 +1,43 @@
1
+ import { _ as ConnectionMeta, f as McpRouteOptions, i as DevframeDeploymentKind, r as DevframeDefinition } from "./devframe-Bdd9YXTy.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`, `spa`, `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
+ * @experimental
40
+ */
41
+ declare function resolveMcpConnectionMeta(def: DevframeDefinition, mcp: boolean | McpRouteOptions | undefined, port?: number): ConnectionMeta['mcp'];
42
+ //#endregion
43
+ export { resolveMcpConnectionMeta as a, resolveDevServerPort as i, normalizeBasePath as n, resolveBasePath as r, ResolveDevServerPortOptions as t };
@@ -1,4 +1,4 @@
1
- import { r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
1
+ import { r as DevframeDefinition } from "../devframe-Bdd9YXTy.mjs";
2
2
  //#region src/adapters/build.d.ts
3
3
  interface CreateBuildOptions {
4
4
  /** Output directory. Defaults to `dist-static`. */
@@ -1,11 +1,12 @@
1
- import { t as collectStaticRpcDump } from "../dump-CgZShDRB.mjs";
2
1
  import { n as colors } from "../diagnostics-reporter-CsIG85Q5.mjs";
2
+ import { n as strictJsonStringify } from "../serialization-BHY8M5NQ.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-CvjkO8QE.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-DLYH5oD3.mjs";
7
+ import { t as createHostContext } from "../context-Du11TLcO.mjs";
8
+ import { n as resolveBasePath } from "../_shared-CttmCMBi.mjs";
9
+ import { t as createH3DevframeHost } from "../host-h3-CzCZwtuV.mjs";
9
10
  import { existsSync } from "node:fs";
10
11
  import { dirname, resolve } from "pathe";
11
12
  import process from "node:process";
@@ -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 { Ft as CliFlagsSchema, It as InferCliFlags, Lt as defineCliFlags, Rt as parseCliFlags, r as DevframeDefinition } from "../devframe-Bdd9YXTy.mjs";
2
2
  import { CAC } from "cac";
3
3
  import { H3 } from "h3";
4
4
  //#region src/adapters/cac.d.ts
@@ -1,2 +1,158 @@
1
- import { n as defineCliFlags, r as parseCliFlags, t as createCac } from "../cac-D4_9ok0z.mjs";
1
+ import { n as colors } from "../diagnostics-reporter-CsIG85Q5.mjs";
2
+ import { r as resolveDevServerPort } from "../_shared-CttmCMBi.mjs";
3
+ import { createBuild } from "./build.mjs";
4
+ import { t as createDevServer } from "../dev-BEveeA5H.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) [experimental]");
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("--base <base>", "URL base", { default: "/" }).option("--pretty", "Pretty-print dump JSON (larger on disk)").action(async (flags) => {
121
+ await createBuild(d, {
122
+ outDir: flags.outDir,
123
+ base: flags.base,
124
+ pretty: flags.pretty
125
+ });
126
+ });
127
+ cli.command("mcp", "Start an MCP server exposing agent-facing tools (stdio) [experimental]").action(async () => {
128
+ const { createMcpServer } = await import("./mcp.mjs");
129
+ await createMcpServer(d, {
130
+ transport: "stdio",
131
+ onReady: ({ transport }) => {
132
+ console.error(`[devframe] "${d.id}" MCP server ready (${transport})`);
133
+ }
134
+ });
135
+ });
136
+ d.cli?.configure?.(cli);
137
+ options.configureCli?.(cli);
138
+ cli.help();
139
+ cli.version("0.0.0");
140
+ return {
141
+ cli,
142
+ async parse(argv = process.argv) {
143
+ cli.parse(argv, { run: false });
144
+ await cli.runMatchedCommand();
145
+ }
146
+ };
147
+ }
148
+ function resolveTypedFlags(d, raw) {
149
+ if (!d.cli?.flags) return raw;
150
+ const { flags, issues } = parseCliFlags(d.cli.flags, raw);
151
+ if (issues?.length) {
152
+ for (const issue of issues) console.error(colors.red`[devframe] invalid flag — ${issue}`);
153
+ process.exit(1);
154
+ }
155
+ return flags;
156
+ }
157
+ //#endregion
2
158
  export { createCac, defineCliFlags, parseCliFlags };
@@ -1,7 +1,7 @@
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 { G as DevframeNodeRpcSession, d as DevframeWsOptions, f as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition, u as DevframeSseOptions } from "../devframe-Bdd9YXTy.mjs";
2
+ import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "../ws-server-Ces08fjP.mjs";
3
+ import { c as StartedServer } from "../instance-shell-DBTXTSjN.mjs";
4
+ import { a as resolveMcpConnectionMeta, i as resolveDevServerPort, t as ResolveDevServerPortOptions } from "../_shared-DmpWW-HH.mjs";
5
5
  import { H3 } from "h3";
6
6
  //#region src/adapters/dev.d.ts
7
7
  interface CreateDevServerOptions {
@@ -35,9 +35,16 @@ interface CreateDevServerOptions {
35
35
  /**
36
36
  * Override how the browser reaches the RPC WebSocket (`def.cli?.ws`).
37
37
  * See {@link DevframeWsOptions}: same-server route (default), a dedicated
38
- * port, or a remote origin.
38
+ * port, or a remote origin. Pass `false` to serve no WebSocket at all —
39
+ * clients connect over the SSE endpoint instead (`backend: 'sse'`).
39
40
  */
40
- ws?: DevframeWsOptions;
41
+ ws?: DevframeWsOptions | false;
42
+ /**
43
+ * Override the SSE RPC endpoint control (`def.cli?.sse`) — enabled by
44
+ * default at `<base>__sse`. Pass `false` to disable, or a
45
+ * {@link DevframeSseOptions} to rename the route.
46
+ */
47
+ sse?: boolean | DevframeSseOptions;
41
48
  /**
42
49
  * h3 app to mount the SPA + connection-meta routes on. When omitted
43
50
  * a fresh app is created. Pass a pre-configured app to attach custom
@@ -71,16 +78,16 @@ interface CreateDevServerOptions {
71
78
  */
72
79
  mcp?: boolean | McpRouteOptions;
73
80
  /**
74
- * Called once per new WS connection, right after its session is created.
75
- * Forwarded verbatim to the underlying `startHttpAndWs`.
81
+ * Called once per new RPC connection, right after its session is created.
82
+ * Forwarded verbatim to the underlying transport binding.
76
83
  */
77
- onPeerConnect?: (peer: Peer, session: DevframeNodeRpcSession) => void;
84
+ onPeerConnect?: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
78
85
  /**
79
- * Called once per closed WS connection, right after its session's
86
+ * Called once per closed RPC connection, right after its session's
80
87
  * disconnect bookkeeping runs. Forwarded verbatim to the underlying
81
- * `startHttpAndWs`.
88
+ * transport binding.
82
89
  */
83
- onPeerDisconnect?: (peer: Peer, meta: DevframeNodeRpcSessionMeta) => void;
90
+ onPeerDisconnect?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
84
91
  /**
85
92
  * Called once the WS server is bound. Devframe stays headless
86
93
  * otherwise — wire this if you want a startup banner.
@@ -91,20 +98,6 @@ interface CreateDevServerOptions {
91
98
  app: H3;
92
99
  }) => void | Promise<void>;
93
100
  }
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
101
  /**
109
102
  * Start a devframe dev server for a {@link DevframeDefinition} —
110
103
  * h3 + WebSocket RPC + (optionally) the author's SPA mounted at the
@@ -124,20 +117,5 @@ declare function resolveDevServerPort(def: DevframeDefinition, options?: Resolve
124
117
  * `dev` / `build` / `mcp` shell, reach for {@link createCac} instead.
125
118
  */
126
119
  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
120
  //#endregion
143
- export { CreateDevServerOptions, ResolveDevServerPortOptions, createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
121
+ 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-CttmCMBi.mjs";
2
+ import { t as createDevServer } from "../dev-BEveeA5H.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 { r as DevframeDefinition, x as DevframeNodeContext } from "../devframe-Bdd9YXTy.mjs";
2
2
  //#region src/adapters/embedded.d.ts
3
3
  interface CreateEmbeddedOptions {
4
4
  /** Target context the devframe is registered into. Required. */
@@ -0,0 +1,223 @@
1
+ import { B as DevframeStorageScope, G as DevframeNodeRpcSession, _ as ConnectionMeta, d as DevframeWsOptions, f as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition, u as DevframeSseOptions, x as DevframeNodeContext } from "../devframe-Bdd9YXTy.mjs";
2
+ import { d as DevframeRpcConnection, n as WsOriginRegistry, u as DevframeNodeRpcSessionMeta } from "../ws-server-Ces08fjP.mjs";
3
+ import { c as StartedServer, f as DevframeInstanceRecord } from "../instance-shell-DBTXTSjN.mjs";
4
+ import { Buffer } from "node:buffer";
5
+ import { IncomingMessage, Server, ServerResponse } from "node:http";
6
+ import { Duplex } from "node:stream";
7
+ import { H3 } from "h3";
8
+ //#region src/adapters/initiate.d.ts
9
+ interface InitDevframeOptions {
10
+ /**
11
+ * Mount base the handler answers under (e.g. `/__my-tool/`) — required so
12
+ * the mount path is explicit at the call site. A handler is by definition
13
+ * mounted *inside* a host app's origin; the resolved value is echoed back
14
+ * as {@link DevframeInstance.base} so route/middleware code references it
15
+ * instead of repeating the string. `resolveBasePath(def, 'hosted')` gives
16
+ * the conventional `def.basePath ?? /__<id>/`.
17
+ */
18
+ base: string;
19
+ /**
20
+ * Override `def.cli?.distDir`. When neither is set — or `false` is passed
21
+ * to suppress the definition's own `distDir` — the handler runs in
22
+ * **bridge mode**: only `__connection.json`, the WS endpoint, and the MCP
23
+ * route (when enabled) are served; the SPA is hosted elsewhere.
24
+ */
25
+ distDir?: string | false;
26
+ /**
27
+ * Share the host's `node:http` server for the WebSocket RPC endpoint: the
28
+ * upgrade listener binds to `<base>__ws` on this server, so no extra port
29
+ * is needed and the socket follows the app through proxies/HTTPS. Hosts
30
+ * whose handlers never see upgrades (Next.js route handlers, Nitro,
31
+ * Rsbuild) ask for a side-car instead with `ws: { sidecar: true }`; hosts
32
+ * that own their upgrade routing wire {@link DevframeInstance.attach} /
33
+ * {@link DevframeInstance.handleUpgrade} themselves.
34
+ */
35
+ server?: Server;
36
+ /**
37
+ * Explicit control over how the browser reaches the RPC WebSocket —
38
+ * advertised in `__connection.json`. The **local binding** resolves in
39
+ * precedence order `ws.port` (pinned side-car) > `server` (shared upgrade)
40
+ * > `ws.sidecar` (auto-port side-car) > none (the host drives the socket
41
+ * through {@link DevframeInstance.attach}). `ws.url` controls the
42
+ * advertisement* only: the browser dials it verbatim (a tunnel/relay),
43
+ * while the local binding keeps following the options above — and on its
44
+ * own it means an external server owns both the transport and its auth.
45
+ * Pass `false` to serve no WebSocket at all — clients connect over the
46
+ * SSE endpoint instead (`backend: 'sse'`).
47
+ */
48
+ ws?: DevframeWsOptions | false;
49
+ /**
50
+ * SSE RPC endpoint control — enabled by default at `<base>__sse` as the
51
+ * more portable transport alongside the WebSocket. Pass `false` to
52
+ * disable, or a {@link DevframeSseOptions} to rename the route.
53
+ */
54
+ sse?: boolean | DevframeSseOptions;
55
+ /**
56
+ * Bind host for a side-car WebSocket server (default: `def.cli?.host ??
57
+ * 'localhost'`). Irrelevant for the `server` / `ws.url` tiers.
58
+ */
59
+ host?: string;
60
+ /**
61
+ * Authentication for the RPC endpoint. A handler mounted inside an app
62
+ * server is reachable by anything that can open its socket, so it **gates
63
+ * by default**: when unset (or `true`), devframe's interactive OTP handler
64
+ * is wired and its code/link banner prints once the public origin is known
65
+ * (derived from the first request, or `origin`). Pass a
66
+ * {@link DevframeAuthHandler} for a custom scheme, or `false` to opt out
67
+ * for a single-user localhost setup that owns the trust boundary another
68
+ * way. Ignored for the `ws.url` tier — the server behind that URL owns auth.
69
+ */
70
+ auth?: boolean | DevframeAuthHandler;
71
+ /**
72
+ * Expose a route-based MCP server (Streamable-HTTP) at `<base>__mcp` and
73
+ * advertise it in `__connection.json`. Overrides `def.cli?.mcp`;
74
+ * `undefined` falls through to it. See {@link McpRouteOptions}.
75
+ */
76
+ mcp?: boolean | McpRouteOptions;
77
+ /**
78
+ * Public origin the host app is reachable at (e.g. `http://localhost:3000`),
79
+ * or a getter for hosts that resolve it late. When omitted (or the getter
80
+ * returns a falsy value), it is derived lazily from the first request the
81
+ * handler serves — used for the auth banner's magic link and absolute dock
82
+ * URLs.
83
+ */
84
+ origin?: string | (() => string);
85
+ /**
86
+ * Publish this instance in the global registry (`~/.devframe/instances/`)
87
+ * so discovery tooling (`devframe connect`, the inspect plugin's Instances
88
+ * tab) finds it without port guessing. Registration is a dynamic import
89
+ * that fires once the public origin resolves and is torn down on
90
+ * {@link DevframeInstance.close}. Defaults to off; pass `true` to enable, or
91
+ * an object to override individual record fields (`id`, `name`, `mcp`, …).
92
+ */
93
+ register?: boolean | Partial<DevframeInstanceRecord>;
94
+ /** Parsed flag bag forwarded to `def.setup(ctx, { flags })`. */
95
+ flags?: Record<string, unknown>;
96
+ /**
97
+ * Extra origins to accept on the WS upgrade beyond the loopback default.
98
+ * Add your LAN/tunnel origin here when reaching the tool from another
99
+ * host. Pass `false` to disable origin checking entirely (not
100
+ * recommended). Default: loopback-only.
101
+ */
102
+ allowedOrigins?: readonly string[] | WsOriginRegistry | false;
103
+ /**
104
+ * h3 app to mount the handler's routes on. When omitted a fresh internal
105
+ * app is created — the common middleware case. An adapter that owns the
106
+ * whole server (e.g. `createDevServer`) passes its own app so callers can
107
+ * compose custom routes ahead of devframe's.
108
+ */
109
+ app?: H3;
110
+ /**
111
+ * Override where persisted devframe state lives, per
112
+ * `DevframeHost.getStorageDir`. Defaults to the standalone host layout
113
+ * (`.devframe/`, `node_modules/.<id>/devframe/`, `~/.<id>/devframe/`).
114
+ */
115
+ getStorageDir?: (scope: DevframeStorageScope) => string;
116
+ /**
117
+ * Destroy upgrade requests on a shared `server` that don't match the WS
118
+ * route, instead of leaving them for the host's own upgrade handlers.
119
+ * Enable when devframe's adapter owns the server outright (nothing else
120
+ * handles its upgrades) so off-route clients are rejected promptly.
121
+ * Default: `false` (coexist-friendly).
122
+ */
123
+ destroyUnmatchedUpgrades?: boolean;
124
+ /**
125
+ * Called once per new RPC connection, right after its session is created.
126
+ * Forwarded verbatim to the underlying transport.
127
+ */
128
+ onPeerConnect?: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
129
+ /**
130
+ * Called once per closed RPC connection, right after the transport's own
131
+ * disconnect bookkeeping runs.
132
+ */
133
+ onPeerDisconnect?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
134
+ }
135
+ interface DevframeInstance {
136
+ /**
137
+ * The normalized mount base this instance answers under (leading and
138
+ * trailing slash, e.g. `/__my-tool/`). Reference it when wiring the mount
139
+ * — route guards, middleware path checks — instead of repeating the
140
+ * string.
141
+ */
142
+ base: string;
143
+ /**
144
+ * Web-standard request handler — mount it on a catch-all route under
145
+ * {@link DevframeInstance.base} (Next.js route handler, SvelteKit
146
+ * `+server.ts`, Hono `c.req.raw`, Nitro `toWebRequest(event)`, …).
147
+ * Requests outside the base 404.
148
+ */
149
+ handler: (request: Request) => Promise<Response>;
150
+ /**
151
+ * Connect/Express-style middleware over the same surface — for
152
+ * `viteServer.middlewares.use(handler.nodeMiddleware)` or any other
153
+ * node middleware stack. Mount it un-prefixed: paths outside the base
154
+ * call `next()` so the rest of the stack keeps working.
155
+ */
156
+ nodeMiddleware: (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => void;
157
+ /**
158
+ * Route a host server's `upgrade` events to the RPC socket, returning a
159
+ * detach function — the manual counterpart to the `server` option, for
160
+ * hosts that get their `node:http` server only after the instance exists.
161
+ * Available on the default tier; a configured transport (`server`,
162
+ * `ws.port`, `ws.sidecar`, `ws.url`) already owns the socket and reports
163
+ * `DF0055` / `DF0056` instead.
164
+ */
165
+ attach: (server: Server) => () => void;
166
+ /**
167
+ * Complete a single `upgrade` event on the RPC socket, for hosts that
168
+ * already own an `upgrade` listener: `server.on('upgrade',
169
+ * instance.handleUpgrade)`. Same availability as
170
+ * {@link DevframeInstance.attach}.
171
+ */
172
+ handleUpgrade: (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
173
+ /**
174
+ * Resolves once `def.setup` has run and the WebSocket binding is live.
175
+ * `handler`/`nodeMiddleware` await it internally, so hosts never race
176
+ * initialization — await it yourself only when you need the timing.
177
+ */
178
+ ready: Promise<void>;
179
+ /** The node context, once initialized — for advanced wiring (own WS transport, extra RPC registration). */
180
+ context: Promise<DevframeNodeContext>;
181
+ /**
182
+ * The `ConnectionMeta` this handler serves at `<base>__connection.json`.
183
+ * Only readable after initialization (`DF0054` otherwise).
184
+ */
185
+ connectionMeta: () => ConnectionMeta;
186
+ /** Tear down: WS transport/side-car, MCP sessions. */
187
+ close: () => Promise<void>;
188
+ }
189
+ /**
190
+ * Live internals of a handler, for the first-party adapters built on it
191
+ * (`createDevServer` exposes the transport's `ws`/`rpcGroup` through its
192
+ * `StartedServer` contract).
193
+ *
194
+ * @internal
195
+ */
196
+ interface DevframeInstanceInternals {
197
+ /** The bound HTTP+WS server handle backing the side-car / shared-server WS tiers. */
198
+ readonly started?: StartedServer;
199
+ /** The resolved auth handler when the gate is active. */
200
+ readonly authHandler?: DevframeAuthHandler;
201
+ }
202
+ /** @internal */
203
+ declare function getInstanceInternals(handler: object): DevframeInstanceInternals;
204
+ /**
205
+ * Serve a devframe through one framework-agnostic, web-standard handler —
206
+ * the SPA, `__connection.json` discovery, the WebSocket RPC endpoint, the
207
+ * auth gate, and the optional MCP route, all under a single mount base.
208
+ * Mount `handler` on any framework's catch-all route (or `nodeMiddleware` on
209
+ * a connect stack) and the devframe is live inside that app.
210
+ *
211
+ * The factory is synchronous and kicks off initialization eagerly;
212
+ * `handler`/`nodeMiddleware` await readiness internally. Nothing binds a port
213
+ * on its own: the WebSocket resolves in precedence order — `ws.port` (pinned
214
+ * side-car) > `server` (shared upgrade at `<base>__ws`) > `ws.sidecar`
215
+ * (auto-port side-car) > the host driving upgrades itself through
216
+ * {@link DevframeInstance.attach} — while `ws.url`, when set, overrides the
217
+ * advertised* endpoint (the tunnel pattern) and on its own hands the whole
218
+ * transport to an external server. `__connection.json` reflects whichever
219
+ * combination is active.
220
+ */
221
+ declare function initDevframe(def: DevframeDefinition, options: InitDevframeOptions): DevframeInstance;
222
+ //#endregion
223
+ export { DevframeInstance, DevframeInstanceInternals, InitDevframeOptions, getInstanceInternals, initDevframe };
@@ -0,0 +1,2 @@
1
+ import { n as getInstanceInternals, r as initDevframe } from "../dev-BEveeA5H.mjs";
2
+ export { getInstanceInternals, initDevframe };