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.
- package/dist/_shared-CttmCMBi.mjs +70 -0
- package/dist/_shared-DmpWW-HH.d.mts +43 -0
- package/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +6 -5
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +157 -1
- package/dist/adapters/dev.d.mts +20 -42
- package/dist/adapters/dev.mjs +2 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +223 -0
- package/dist/adapters/initiate.mjs +2 -0
- package/dist/adapters/mcp.d.mts +26 -2
- package/dist/adapters/mcp.mjs +2 -2
- package/dist/cli/main.mjs +2 -2
- package/dist/client/index.d.mts +70 -6
- package/dist/client/index.mjs +743 -408
- package/dist/constants.d.mts +19 -6
- package/dist/constants.mjs +19 -6
- package/dist/{context-CBg8iRbQ.mjs → context-C33rR7n0.mjs} +1 -1
- package/dist/{context-DoSozfvx.d.mts → context-CSCwoABx.d.mts} +1 -1
- package/dist/{host-h3-D2hYZvDK.mjs → context-Du11TLcO.mjs} +5 -255
- package/dist/dev-BEveeA5H.mjs +233 -0
- package/dist/{devframe-mQ4qZAuo.d.mts → devframe-Bdd9YXTy.d.mts} +88 -25
- package/dist/{diagnostics-D7wM2cwM.mjs → diagnostics-DLYH5oD3.mjs} +16 -0
- package/dist/dist-D8jAMwxU.mjs +227 -0
- package/dist/helpers/vite.d.mts +43 -39
- package/dist/helpers/vite.mjs +26 -38
- package/dist/host-agent-CpbAoqBx.mjs +230 -0
- package/dist/host-h3-CzCZwtuV.mjs +26 -0
- package/dist/{fetch-BKaD0Vb3.mjs → http-DLr_cJZ7.mjs} +42 -4
- package/dist/{index-b64Uuhy2.d.mts → index-CZRd2K1C.d.mts} +2 -2
- package/dist/{index-Dbw1p5ch.d.mts → index-DSCq4M4q.d.mts} +2 -31
- package/dist/index.d.mts +9 -4
- package/dist/index.mjs +8 -1
- package/dist/{instance-registry-BnnA2Eoh.mjs → instance-registry-BQqGoDO9.mjs} +9 -2
- package/dist/instance-shell-DBTXTSjN.d.mts +264 -0
- package/dist/instance-shell-KRdee1QF.mjs +485 -0
- package/dist/internal/index.d.mts +150 -0
- package/dist/internal/index.mjs +7 -0
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/hub-internals.d.mts +2 -14
- package/dist/node/hub-internals.mjs +2 -2
- package/dist/node/index.d.mts +3 -267
- package/dist/node/index.mjs +3 -5
- package/dist/recipes/common-rpc-functions.d.mts +3 -3
- package/dist/recipes/interactive-auth.d.mts +3 -3
- package/dist/recipes/interactive-auth.mjs +6 -6
- package/dist/rolldown-runtime-JspESFgx.mjs +35 -0
- package/dist/rpc/dump.d.mts +77 -1
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +3 -17
- package/dist/rpc/transports/sse-client.d.mts +2 -0
- package/dist/rpc/transports/sse-client.mjs +142 -0
- package/dist/rpc/transports/sse-server.d.mts +61 -0
- package/dist/rpc/transports/sse-server.mjs +209 -0
- package/dist/rpc/transports/ws-bun.d.mts +35 -0
- package/dist/rpc/transports/ws-bun.mjs +31 -0
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +10 -18
- package/dist/rpc/transports/ws-server.d.mts +2 -2
- package/dist/rpc/transports/ws-server.mjs +2 -235
- package/dist/rpc-core-CGctXToO.d.mts +48 -0
- package/dist/rpc-core-CqcJkAu9.mjs +81 -0
- package/dist/{serialization-C8Mnw9hK.mjs → serialization-BHY8M5NQ.mjs} +1 -1
- package/dist/{shared-state-6kHolYZy.mjs → shared-state-fRRbRUtD.mjs} +1 -1
- package/dist/sse-client-BsIK3hMD.d.mts +37 -0
- package/dist/{dump-CgZShDRB.mjs → static-CvjkO8QE.mjs} +2 -265
- package/dist/{storage-CTNVbuFB.mjs → storage-BcmVEJRc.mjs} +2 -2
- package/dist/types/index.d.mts +3 -3
- package/dist/types/index.mjs +1 -6
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/launch-editor.mjs +1 -25
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/serve-static.mjs +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/simple-schema.d.mts +101 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/validation-BiuDXTKW.mjs +266 -0
- package/dist/wire-codec-9VhIKnyp.mjs +58 -0
- package/dist/{ws-client-B6Tnr0ic.d.mts → ws-client-CdNuATYa.d.mts} +6 -1
- package/dist/ws-server-Bk1hOG3X.mjs +267 -0
- package/dist/{ws-server-uKQcClcJ.d.mts → ws-server-Ces08fjP.d.mts} +89 -8
- package/package.json +10 -9
- package/skills/devframe/SKILL.md +84 -85
- package/dist/_shared-bWRzeSa0.mjs +0 -19
- package/dist/adapters/cli.d.mts +0 -11
- package/dist/adapters/cli.mjs +0 -6
- package/dist/cac-D4_9ok0z.mjs +0 -157
- package/dist/dev-Bc49u3qg.mjs +0 -439
- package/dist/http-C4T68YV6.mjs +0 -38
- package/dist/index-vAX6bYuc.d.mts +0 -78
- package/dist/recipes/open-helpers.d.mts +0 -6
- package/dist/recipes/open-helpers.mjs +0 -6
- package/dist/server-CD8XmBXl.mjs +0 -167
- package/dist/server-UHWae43Q.d.mts +0 -149
- package/dist/simple-schema-BDzLeJDk.d.mts +0 -102
- package/dist/utils/promise.d.mts +0 -8
- package/dist/utils/promise.mjs +0 -15
- package/dist/utils/scope.d.mts +0 -11
- package/dist/utils/scope.mjs +0 -15
- 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 };
|
package/dist/adapters/build.mjs
CHANGED
|
@@ -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 {
|
|
4
|
+
import { t as collectStaticRpcDump } from "../static-CvjkO8QE.mjs";
|
|
5
5
|
import { n as structuredCloneStringify } from "../structured-clone-CbAV5rFI.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import { t as
|
|
8
|
-
import { n as resolveBasePath } from "../_shared-
|
|
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";
|
package/dist/adapters/cac.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as
|
|
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
|
package/dist/adapters/cac.mjs
CHANGED
|
@@ -1,2 +1,158 @@
|
|
|
1
|
-
import { n as
|
|
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 };
|
package/dist/adapters/dev.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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
|
|
75
|
-
* Forwarded verbatim to the underlying
|
|
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?: (
|
|
84
|
+
onPeerConnect?: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
|
|
78
85
|
/**
|
|
79
|
-
* Called once per closed
|
|
86
|
+
* Called once per closed RPC connection, right after its session's
|
|
80
87
|
* disconnect bookkeeping runs. Forwarded verbatim to the underlying
|
|
81
|
-
*
|
|
88
|
+
* transport binding.
|
|
82
89
|
*/
|
|
83
|
-
onPeerDisconnect?: (
|
|
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 };
|
package/dist/adapters/dev.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
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 };
|