devframe 0.8.0 → 0.8.2
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/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +2 -2
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +1 -1
- package/dist/adapters/cli.d.mts +1 -1
- package/dist/adapters/cli.mjs +1 -1
- package/dist/adapters/dev.d.mts +15 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/mcp.d.mts +11 -5
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/{cac-B-R_tDGJ.mjs → cac-D4_9ok0z.mjs} +1 -1
- package/dist/cli/main.mjs +4 -3
- package/dist/client/index.d.mts +37 -8
- package/dist/client/index.mjs +41 -15
- package/dist/constants.d.mts +13 -6
- package/dist/constants.mjs +13 -6
- package/dist/{context-C9Cgm1hP.mjs → context-CBg8iRbQ.mjs} +3 -2
- package/dist/{context-7BbaIUSI.d.mts → context-DoSozfvx.d.mts} +1 -1
- package/dist/{revoke-BtQDKTp7.mjs → crypto-token-XCqTSMg9.mjs} +1 -35
- package/dist/{dev-D4M7Veo7.mjs → dev-Bc49u3qg.mjs} +7 -5
- package/dist/{devframe-Dsjn_Xtq.d.mts → devframe-mQ4qZAuo.d.mts} +10 -1
- package/dist/{diagnostics-B5-qHeqD.mjs → diagnostics-D7wM2cwM.mjs} +4 -0
- package/dist/{fetch-BZyK4v6W.mjs → fetch-BKaD0Vb3.mjs} +7 -6
- package/dist/helpers/vite.d.mts +15 -14
- package/dist/helpers/vite.mjs +8 -8
- package/dist/{host-h3-Kz7t5Xab.mjs → host-h3-D2hYZvDK.mjs} +2 -2
- package/dist/{http-BghOqfTD.mjs → http-C4T68YV6.mjs} +1 -1
- package/dist/{index-CeBbry0R.d.mts → index-b64Uuhy2.d.mts} +11 -6
- package/dist/index.d.mts +2 -2
- package/dist/{instance-registry-D6fxYu36.mjs → instance-registry-BnnA2Eoh.mjs} +1 -1
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/auth.mjs +2 -2
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +1 -1
- package/dist/node/index.d.mts +23 -3
- package/dist/node/index.mjs +5 -5
- package/dist/recipes/common-rpc-functions.d.mts +1 -1
- package/dist/recipes/interactive-auth.d.mts +2 -2
- package/dist/recipes/interactive-auth.mjs +11 -3
- package/dist/revoke-DZbJ7Cl0.mjs +35 -0
- package/dist/rpc/transports/ws-server.d.mts +2 -2
- package/dist/rpc/transports/ws-server.mjs +75 -7
- package/dist/{server-CcAPxuoT.mjs → server-CD8XmBXl.mjs} +25 -6
- package/dist/{server-VLQJouOO.d.mts → server-UHWae43Q.d.mts} +21 -3
- package/dist/{state-WX3HT5a3.mjs → state-BeUHDDjk.mjs} +13 -6
- package/dist/{storage-Dzoc3NVC.mjs → storage-CTNVbuFB.mjs} +1 -1
- package/dist/types/index.d.mts +2 -2
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/{ws-server-D_Vjtums.d.mts → ws-server-uKQcClcJ.d.mts} +36 -7
- package/package.json +2 -2
- package/skills/devframe/SKILL.md +3 -2
package/dist/adapters/build.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { n as colors } from "../diagnostics-reporter-CsIG85Q5.mjs";
|
|
|
3
3
|
import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
|
|
4
4
|
import { n as strictJsonStringify } from "../serialization-C8Mnw9hK.mjs";
|
|
5
5
|
import { n as structuredCloneStringify } from "../structured-clone-CbAV5rFI.mjs";
|
|
6
|
-
import { n as createHostContext, t as createH3DevframeHost } from "../host-h3-
|
|
7
|
-
import { t as diagnostics } from "../diagnostics-
|
|
6
|
+
import { n as createHostContext, t as createH3DevframeHost } from "../host-h3-D2hYZvDK.mjs";
|
|
7
|
+
import { t as diagnostics } from "../diagnostics-D7wM2cwM.mjs";
|
|
8
8
|
import { n as resolveBasePath } from "../_shared-bWRzeSa0.mjs";
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { dirname, resolve } from "pathe";
|
package/dist/adapters/cac.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as InferCliFlags, It as defineCliFlags, Lt as parseCliFlags, Pt as CliFlagsSchema, r as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { Ft as InferCliFlags, It as defineCliFlags, Lt as parseCliFlags, Pt as CliFlagsSchema, r as DevframeDefinition } from "../devframe-mQ4qZAuo.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,2 @@
|
|
|
1
|
-
import { n as defineCliFlags, r as parseCliFlags, t as createCac } from "../cac-
|
|
1
|
+
import { n as defineCliFlags, r as parseCliFlags, t as createCac } from "../cac-D4_9ok0z.mjs";
|
|
2
2
|
export { createCac, defineCliFlags, parseCliFlags };
|
package/dist/adapters/cli.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as InferCliFlags, It as defineCliFlags, Lt as parseCliFlags, Pt as CliFlagsSchema } from "../devframe-
|
|
1
|
+
import { Ft as InferCliFlags, It as defineCliFlags, Lt as parseCliFlags, Pt as CliFlagsSchema } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import { CacHandle, CreateCacOptions, createCac } from "./cac.mjs";
|
|
3
3
|
//#region src/adapters/cli.d.ts
|
|
4
4
|
/** @deprecated Use `createCac` from `devframe/adapters/cac` instead. */
|
package/dist/adapters/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as defineCliFlags, r as parseCliFlags, t as createCac } from "../cac-
|
|
1
|
+
import { n as defineCliFlags, r as parseCliFlags, t as createCac } from "../cac-D4_9ok0z.mjs";
|
|
2
2
|
//#region src/adapters/cli.ts
|
|
3
3
|
/** @deprecated Use `createCac` from `devframe/adapters/cac` instead. */
|
|
4
4
|
const createCli = createCac;
|
package/dist/adapters/dev.d.mts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { _ as ConnectionMeta, d as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition, u as DevframeWsOptions } from "../devframe-
|
|
2
|
-
import { n as
|
|
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";
|
|
3
5
|
import { H3 } from "h3";
|
|
4
6
|
//#region src/adapters/dev.d.ts
|
|
5
7
|
interface CreateDevServerOptions {
|
|
@@ -68,6 +70,17 @@ interface CreateDevServerOptions {
|
|
|
68
70
|
* {@link McpRouteOptions}.
|
|
69
71
|
*/
|
|
70
72
|
mcp?: boolean | McpRouteOptions;
|
|
73
|
+
/**
|
|
74
|
+
* Called once per new WS connection, right after its session is created.
|
|
75
|
+
* Forwarded verbatim to the underlying `startHttpAndWs`.
|
|
76
|
+
*/
|
|
77
|
+
onPeerConnect?: (peer: Peer, session: DevframeNodeRpcSession) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Called once per closed WS connection, right after its session's
|
|
80
|
+
* disconnect bookkeeping runs. Forwarded verbatim to the underlying
|
|
81
|
+
* `startHttpAndWs`.
|
|
82
|
+
*/
|
|
83
|
+
onPeerDisconnect?: (peer: Peer, meta: DevframeNodeRpcSessionMeta) => void;
|
|
71
84
|
/**
|
|
72
85
|
* Called once the WS server is bound. Devframe stays headless
|
|
73
86
|
* otherwise — wire this if you want a startup banner.
|
package/dist/adapters/dev.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as resolveDevServerPort, r as resolveMcpConnectionMeta, t as createDevServer } from "../dev-
|
|
1
|
+
import { n as resolveDevServerPort, r as resolveMcpConnectionMeta, t as createDevServer } from "../dev-Bc49u3qg.mjs";
|
|
2
2
|
export { createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as DevframeNodeContext, r as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { b as DevframeNodeContext, r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
//#region src/adapters/embedded.d.ts
|
|
3
3
|
interface CreateEmbeddedOptions {
|
|
4
4
|
/** Target context the devframe is registered into. Required. */
|
package/dist/adapters/mcp.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as DevframeNodeContext, r as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { b as DevframeNodeContext, r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import "@modelcontextprotocol/server";
|
|
3
3
|
//#region src/adapters/mcp/build-server.d.ts
|
|
4
4
|
interface CreateMcpServerOptions {
|
|
@@ -47,7 +47,12 @@ interface CreateMcpFetchHandlerOptions {
|
|
|
47
47
|
exposeSharedState: boolean | ((key: string) => boolean);
|
|
48
48
|
/**
|
|
49
49
|
* Origin allow-list beyond the loopback default. `false` disables the
|
|
50
|
-
* origin gate entirely. Default: loopback-only
|
|
50
|
+
* origin gate entirely. Default: loopback-only.
|
|
51
|
+
*
|
|
52
|
+
* Unlike the WS transport, the MCP route does **not** allow `Origin`-less
|
|
53
|
+
* requests: a route-based endpoint is reachable by any local process, so a
|
|
54
|
+
* request must carry an `Origin` that passes the gate. Native clients
|
|
55
|
+
* (e.g. `devframe connect`) send their loopback origin explicitly.
|
|
51
56
|
*/
|
|
52
57
|
allowedOrigins?: readonly string[] | false;
|
|
53
58
|
}
|
|
@@ -71,9 +76,10 @@ interface McpFetchHandler {
|
|
|
71
76
|
* and MCP server (built from the shared, live `ctx` via
|
|
72
77
|
* `buildMcpServerFromContext`), correlated by the `Mcp-Session-Id` header: an
|
|
73
78
|
* `initialize` POST spins up a session; later requests route to it; a `DELETE`
|
|
74
|
-
* (or client disconnect) tears it down. The origin gate
|
|
75
|
-
* loopback-default DNS-rebinding protection
|
|
76
|
-
*
|
|
79
|
+
* (or client disconnect) tears it down. The origin gate guards every request:
|
|
80
|
+
* loopback-default DNS-rebinding protection that — unlike the WS upgrade's
|
|
81
|
+
* `isAllowedOrigin` — also rejects `Origin`-less requests, so a route-based
|
|
82
|
+
* endpoint isn't reachable by an arbitrary local process.
|
|
77
83
|
*
|
|
78
84
|
* @experimental
|
|
79
85
|
*/
|
package/dist/adapters/mcp.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createMcpServer, t as createMcpFetchHandler } from "../fetch-
|
|
1
|
+
import { n as createMcpServer, t as createMcpFetchHandler } from "../fetch-BKaD0Vb3.mjs";
|
|
2
2
|
export { createMcpFetchHandler, createMcpServer };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as colors } from "./diagnostics-reporter-CsIG85Q5.mjs";
|
|
2
2
|
import { createBuild } from "./adapters/build.mjs";
|
|
3
|
-
import { n as resolveDevServerPort, t as createDevServer } from "./dev-
|
|
3
|
+
import { n as resolveDevServerPort, t as createDevServer } from "./dev-Bc49u3qg.mjs";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import cac$1 from "cac";
|
|
6
6
|
//#region src/adapters/flags.ts
|
package/dist/cli/main.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as diagnostics } from "../diagnostics-
|
|
2
|
-
import { n as probeDevframeOrigin, t as listLiveDevframeInstances } from "../instance-registry-
|
|
1
|
+
import { t as diagnostics } from "../diagnostics-D7wM2cwM.mjs";
|
|
2
|
+
import { n as probeDevframeOrigin, t as listLiveDevframeInstances } from "../instance-registry-BnnA2Eoh.mjs";
|
|
3
3
|
import { t as toAgentToolName } from "../agent-tool-name-C3b5vEwJ.mjs";
|
|
4
4
|
import { Diagnostic } from "nostics";
|
|
5
5
|
import process from "node:process";
|
|
@@ -200,7 +200,8 @@ async function call(sdk, options, args) {
|
|
|
200
200
|
});
|
|
201
201
|
}
|
|
202
202
|
async function withInstanceClient(sdk, url, fn) {
|
|
203
|
-
const
|
|
203
|
+
const origin = new URL(url).origin;
|
|
204
|
+
const transport = new sdk.StreamableHTTPClientTransport(new URL(url), { requestInit: { headers: { origin } } });
|
|
204
205
|
const client = new sdk.Client({
|
|
205
206
|
name: "devframe-connect",
|
|
206
207
|
version: "0.0.0"
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as DevframeRpcServerFunctions, F as ScopedSharedStates, I as SettingsForNamespace, J as RpcSharedStateHost, N as ScopedRpcFn, O as DevframeSettings, P as ScopedServerFunctions, Q as DevframeRpcClientFunctions, _ as ConnectionMeta, at as StreamReader, ht as SharedState, jt as EventEmitter, ot as StreamSink, q as RpcSharedStateGetOptions } from "../devframe-
|
|
1
|
+
import { $ as DevframeRpcServerFunctions, F as ScopedSharedStates, I as SettingsForNamespace, J as RpcSharedStateHost, N as ScopedRpcFn, O as DevframeSettings, P as ScopedServerFunctions, Q as DevframeRpcClientFunctions, _ as ConnectionMeta, at as StreamReader, ht as SharedState, jt as EventEmitter, ot as StreamSink, q as RpcSharedStateGetOptions } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import { _ as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-CnJSgRVa.mjs";
|
|
3
3
|
import { E as RpcCacheOptions, T as RpcCacheManager } from "../index-Dbw1p5ch.mjs";
|
|
4
4
|
import { t as WsRpcChannelOptions } from "../ws-client-B6Tnr0ic.mjs";
|
|
@@ -26,6 +26,12 @@ interface SetupDevframeConnectionOptions {
|
|
|
26
26
|
/** Override the locally stored auth token. */
|
|
27
27
|
authToken?: string;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Allow an external viewer to connect by registering its browser origin with
|
|
31
|
+
* the Devframe host. Returns `false` if the host did not provide an origin
|
|
32
|
+
* registration token.
|
|
33
|
+
*/
|
|
34
|
+
declare function registerDevframeViewerOrigin(connection: DevframeConnection, origin?: any): Promise<boolean>;
|
|
29
35
|
/**
|
|
30
36
|
* Return connection information previously prepared in this window or an
|
|
31
37
|
* accessible parent window.
|
|
@@ -377,15 +383,16 @@ declare function getDevframeRpcClient(options?: DevframeRpcClientOptions): Promi
|
|
|
377
383
|
//#endregion
|
|
378
384
|
//#region src/client/otp.d.ts
|
|
379
385
|
/**
|
|
380
|
-
* Read a one-time authentication code (OTP) from the current page URL's
|
|
381
|
-
*
|
|
386
|
+
* Read a one-time authentication code (OTP) from the current page URL's
|
|
387
|
+
* fragment, without side effects. Returns `undefined` when the parameter is
|
|
388
|
+
* absent.
|
|
382
389
|
*/
|
|
383
390
|
declare function readOtpFromUrl(param?: string): string | undefined;
|
|
384
391
|
/**
|
|
385
|
-
* Read the one-time code from the page URL and remove it from the
|
|
386
|
-
* (and the current history entry), so the single-use code isn't
|
|
387
|
-
* URL, browser history, or a `Referer`. Returns the code, or
|
|
388
|
-
* absent.
|
|
392
|
+
* Read the one-time code from the page URL fragment and remove it from the
|
|
393
|
+
* address bar (and the current history entry), so the single-use code isn't
|
|
394
|
+
* left in the URL, browser history, or a `Referer`. Returns the code, or
|
|
395
|
+
* `undefined` when absent.
|
|
389
396
|
*/
|
|
390
397
|
declare function consumeOtpFromUrl(param?: string): string | undefined;
|
|
391
398
|
/**
|
|
@@ -402,6 +409,28 @@ declare function authenticateWithUrlOtp(rpc: Pick<DevframeRpcClient, 'isTrusted'
|
|
|
402
409
|
param?: string;
|
|
403
410
|
}): Promise<boolean>;
|
|
404
411
|
//#endregion
|
|
412
|
+
//#region src/client/rpc-ws.d.ts
|
|
413
|
+
/** Minimal subset of `window.location` needed to resolve a WS URL. */
|
|
414
|
+
interface WsUrlLocation {
|
|
415
|
+
protocol: string;
|
|
416
|
+
host: string;
|
|
417
|
+
hostname: string;
|
|
418
|
+
href: string;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Resolve a {@link ConnectionMeta.websocket} descriptor into a concrete
|
|
422
|
+
* `ws(s)://` URL.
|
|
423
|
+
*
|
|
424
|
+
* The object / relative-path forms connect to the page's own origin (only the
|
|
425
|
+
* `http`→`ws` protocol swap is applied), resolving the path against where
|
|
426
|
+
* `__connection.json` was loaded. This is deliberately host-agnostic so the
|
|
427
|
+
* connection survives a reverse proxy that changes the domain or port — the
|
|
428
|
+
* client trusts its own location, never a server-baked hostname. An explicit
|
|
429
|
+
* `port`/`host` (or a full `ws(s)://` URL string) opts into a cross-origin
|
|
430
|
+
* endpoint, e.g. a side-car server on its own port.
|
|
431
|
+
*/
|
|
432
|
+
declare function resolveWsUrl(websocket: ConnectionMeta['websocket'], metaBaseUrl: string, loc: WsUrlLocation): string;
|
|
433
|
+
//#endregion
|
|
405
434
|
//#region src/client/settings.d.ts
|
|
406
435
|
/**
|
|
407
436
|
* Build the client-side `settings` surface for a scope namespace. Mirrors
|
|
@@ -412,4 +441,4 @@ declare function createClientSettings<T extends Record<string, any> = Record<str
|
|
|
412
441
|
//#region src/client/index.d.ts
|
|
413
442
|
declare const connectDevframe: typeof getDevframeRpcClient;
|
|
414
443
|
//#endregion
|
|
415
|
-
export { DevframeClientRpcHost, DevframeConnection, DevframeConnectionError, DevframeConnectionErrorKind, DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientCall, DevframeRpcClientCallEvent, DevframeRpcClientCallOptional, DevframeRpcClientMode, DevframeRpcClientOptions, DevframeRpcContext, DevframeScopedClientContext, DevframeScopedClientRpc, DevframeScopedClientStreamingHost, RpcClientEvents, RpcStreamingClientHost, SetupDevframeConnectionOptions, StreamingSubscribeOptions, authenticateWithUrlOtp, connectDevframe, consumeOtpFromUrl, createClientSettings, createRpcStreamingClientHost, createScopedClientContext, getDevframeConnection, getDevframeRpcClient, isCallableStatus, readOtpFromUrl, setupDevframeConnection };
|
|
444
|
+
export { DevframeClientRpcHost, DevframeConnection, DevframeConnectionError, DevframeConnectionErrorKind, DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientCall, DevframeRpcClientCallEvent, DevframeRpcClientCallOptional, DevframeRpcClientMode, DevframeRpcClientOptions, DevframeRpcContext, DevframeScopedClientContext, DevframeScopedClientRpc, DevframeScopedClientStreamingHost, RpcClientEvents, RpcStreamingClientHost, SetupDevframeConnectionOptions, StreamingSubscribeOptions, type WsUrlLocation, authenticateWithUrlOtp, connectDevframe, consumeOtpFromUrl, createClientSettings, createRpcStreamingClientHost, createScopedClientContext, getDevframeConnection, getDevframeRpcClient, isCallableStatus, readOtpFromUrl, registerDevframeViewerOrigin, resolveWsUrl, setupDevframeConnection };
|
package/dist/client/index.mjs
CHANGED
|
@@ -20,11 +20,14 @@ const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
|
|
|
20
20
|
const DEVFRAME_CONNECTION_KEY = "__DEVFRAME_CONNECTION__";
|
|
21
21
|
const DEVFRAME_RPC_DUMP_MANIFEST_FILENAME = "__rpc-dump/index.json";
|
|
22
22
|
/**
|
|
23
|
-
* Page-URL
|
|
24
|
-
* "magic link" auth. A host can print a link like
|
|
25
|
-
* the client reads the code, exchanges it for a
|
|
26
|
-
* from the URL.
|
|
27
|
-
*
|
|
23
|
+
* Page-URL **fragment** parameter carrying a one-time authentication code (OTP)
|
|
24
|
+
* for "magic link" auth. A host can print a link like
|
|
25
|
+
* `<origin>/#devframe_otp=<code>`; the client reads the code, exchanges it for a
|
|
26
|
+
* token, and strips the parameter from the URL. The code rides the fragment
|
|
27
|
+
* (never the query string) so the browser never transmits it to the server,
|
|
28
|
+
* keeping it out of access logs and `Referer` headers. See `buildOtpAuthUrl`
|
|
29
|
+
* (node) and the `authenticateWithUrlOtp` / `consumeOtpFromUrl` client utilities
|
|
30
|
+
* (or `connectDevframe`'s `otpParam`).
|
|
28
31
|
*/
|
|
29
32
|
const DEVFRAME_OTP_URL_PARAM = "devframe_otp";
|
|
30
33
|
/**
|
|
@@ -35,6 +38,10 @@ const DEVFRAME_OTP_URL_PARAM = "devframe_otp";
|
|
|
35
38
|
* trusted before its own `anonymous:devframe:auth` handshake call arrives.
|
|
36
39
|
*/
|
|
37
40
|
const DEVFRAME_AUTH_TOKEN_QUERY_PARAM = "devframe_auth_token";
|
|
41
|
+
/** External viewer origin requested during connection bootstrap. */
|
|
42
|
+
const DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM = "devframe_viewer_origin";
|
|
43
|
+
/** Token that authorizes an external viewer origin registration. */
|
|
44
|
+
const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin_token";
|
|
38
45
|
//#endregion
|
|
39
46
|
//#region src/utils/diagnostics-reporter.ts
|
|
40
47
|
const formatAnsi = ansiFormatter(colors);
|
|
@@ -428,6 +435,21 @@ function storeAuthToken(token) {
|
|
|
428
435
|
}
|
|
429
436
|
//#endregion
|
|
430
437
|
//#region src/client/connection.ts
|
|
438
|
+
/**
|
|
439
|
+
* Allow an external viewer to connect by registering its browser origin with
|
|
440
|
+
* the Devframe host. Returns `false` if the host did not provide an origin
|
|
441
|
+
* registration token.
|
|
442
|
+
*/
|
|
443
|
+
async function registerDevframeViewerOrigin(connection, origin = globalThis.location?.origin) {
|
|
444
|
+
const token = connection.connectionMeta.viewerOriginToken;
|
|
445
|
+
if (!token || !origin) return false;
|
|
446
|
+
const url = new URL(connection.metaBaseUrl);
|
|
447
|
+
url.searchParams.set(DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM, origin);
|
|
448
|
+
url.searchParams.set(DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM, token);
|
|
449
|
+
const response = await fetch(url, { cache: "no-store" });
|
|
450
|
+
if (!response.ok) throw new Error(`Failed to register external viewer origin (${response.status}).`);
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
431
453
|
function resolveMetaBaseUrl(baseURL) {
|
|
432
454
|
const metaPath = withBase(DEVFRAME_CONNECTION_META_FILENAME, baseURL);
|
|
433
455
|
try {
|
|
@@ -530,12 +552,14 @@ function isCallableStatus(status) {
|
|
|
530
552
|
//#endregion
|
|
531
553
|
//#region src/client/otp.ts
|
|
532
554
|
/**
|
|
533
|
-
* Read a one-time authentication code (OTP) from the current page URL's
|
|
534
|
-
*
|
|
555
|
+
* Read a one-time authentication code (OTP) from the current page URL's
|
|
556
|
+
* fragment, without side effects. Returns `undefined` when the parameter is
|
|
557
|
+
* absent.
|
|
535
558
|
*/
|
|
536
559
|
function readOtpFromUrl(param = DEVFRAME_OTP_URL_PARAM) {
|
|
537
560
|
try {
|
|
538
|
-
|
|
561
|
+
const hash = globalThis.location?.hash?.replace(/^#/, "") ?? "";
|
|
562
|
+
return new URLSearchParams(hash).get(param) || void 0;
|
|
539
563
|
} catch {
|
|
540
564
|
return;
|
|
541
565
|
}
|
|
@@ -543,16 +567,18 @@ function readOtpFromUrl(param = DEVFRAME_OTP_URL_PARAM) {
|
|
|
543
567
|
function stripParamFromUrl(param) {
|
|
544
568
|
try {
|
|
545
569
|
const url = new URL(globalThis.location.href);
|
|
546
|
-
|
|
547
|
-
|
|
570
|
+
const fragment = new URLSearchParams(url.hash.replace(/^#/, ""));
|
|
571
|
+
if (!fragment.has(param)) return;
|
|
572
|
+
fragment.delete(param);
|
|
573
|
+
url.hash = fragment.toString();
|
|
548
574
|
globalThis.history?.replaceState(globalThis.history.state, "", url.href);
|
|
549
575
|
} catch {}
|
|
550
576
|
}
|
|
551
577
|
/**
|
|
552
|
-
* Read the one-time code from the page URL and remove it from the
|
|
553
|
-
* (and the current history entry), so the single-use code isn't
|
|
554
|
-
* URL, browser history, or a `Referer`. Returns the code, or
|
|
555
|
-
* absent.
|
|
578
|
+
* Read the one-time code from the page URL fragment and remove it from the
|
|
579
|
+
* address bar (and the current history entry), so the single-use code isn't
|
|
580
|
+
* left in the URL, browser history, or a `Referer`. Returns the code, or
|
|
581
|
+
* `undefined` when absent.
|
|
556
582
|
*/
|
|
557
583
|
function consumeOtpFromUrl(param = DEVFRAME_OTP_URL_PARAM) {
|
|
558
584
|
const code = readOtpFromUrl(param);
|
|
@@ -2588,4 +2614,4 @@ async function getDevframeRpcClient(options = {}) {
|
|
|
2588
2614
|
//#region src/client/index.ts
|
|
2589
2615
|
const connectDevframe = getDevframeRpcClient;
|
|
2590
2616
|
//#endregion
|
|
2591
|
-
export { DevframeConnectionError, authenticateWithUrlOtp, connectDevframe, consumeOtpFromUrl, createClientSettings, createRpcStreamingClientHost, createScopedClientContext, getDevframeConnection, getDevframeRpcClient, isCallableStatus, readOtpFromUrl, setupDevframeConnection };
|
|
2617
|
+
export { DevframeConnectionError, authenticateWithUrlOtp, connectDevframe, consumeOtpFromUrl, createClientSettings, createRpcStreamingClientHost, createScopedClientContext, getDevframeConnection, getDevframeRpcClient, isCallableStatus, readOtpFromUrl, registerDevframeViewerOrigin, resolveWsUrl, setupDevframeConnection };
|
package/dist/constants.d.mts
CHANGED
|
@@ -35,11 +35,14 @@ declare const DEVFRAME_RPC_DUMP_DIRNAME = "__rpc-dump";
|
|
|
35
35
|
*/
|
|
36
36
|
declare const REMOTE_CONNECTION_KEY = "devframe-remote-connection";
|
|
37
37
|
/**
|
|
38
|
-
* Page-URL
|
|
39
|
-
* "magic link" auth. A host can print a link like
|
|
40
|
-
* the client reads the code, exchanges it for a
|
|
41
|
-
* from the URL.
|
|
42
|
-
*
|
|
38
|
+
* Page-URL **fragment** parameter carrying a one-time authentication code (OTP)
|
|
39
|
+
* for "magic link" auth. A host can print a link like
|
|
40
|
+
* `<origin>/#devframe_otp=<code>`; the client reads the code, exchanges it for a
|
|
41
|
+
* token, and strips the parameter from the URL. The code rides the fragment
|
|
42
|
+
* (never the query string) so the browser never transmits it to the server,
|
|
43
|
+
* keeping it out of access logs and `Referer` headers. See `buildOtpAuthUrl`
|
|
44
|
+
* (node) and the `authenticateWithUrlOtp` / `consumeOtpFromUrl` client utilities
|
|
45
|
+
* (or `connectDevframe`'s `otpParam`).
|
|
43
46
|
*/
|
|
44
47
|
declare const DEVFRAME_OTP_URL_PARAM = "devframe_otp";
|
|
45
48
|
/**
|
|
@@ -50,6 +53,10 @@ declare const DEVFRAME_OTP_URL_PARAM = "devframe_otp";
|
|
|
50
53
|
* trusted before its own `anonymous:devframe:auth` handshake call arrives.
|
|
51
54
|
*/
|
|
52
55
|
declare const DEVFRAME_AUTH_TOKEN_QUERY_PARAM = "devframe_auth_token";
|
|
56
|
+
/** External viewer origin requested during connection bootstrap. */
|
|
57
|
+
declare const DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM = "devframe_viewer_origin";
|
|
58
|
+
/** Token that authorizes an external viewer origin registration. */
|
|
59
|
+
declare const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin_token";
|
|
53
60
|
/**
|
|
54
61
|
* Prefix that marks an RPC method as callable before a connection is
|
|
55
62
|
* trusted. This is the *only* rule the pre-trust gate applies — there is no
|
|
@@ -66,4 +73,4 @@ declare const ANONYMOUS_RPC_PREFIX = "anonymous:";
|
|
|
66
73
|
*/
|
|
67
74
|
declare function isAnonymousRpcMethod(name: string): boolean;
|
|
68
75
|
//#endregion
|
|
69
|
-
export { ANONYMOUS_RPC_PREFIX, DEVFRAME_AUTH_TOKEN_QUERY_PARAM, DEVFRAME_CONNECTION_KEY, DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_DIRNAME, DEVFRAME_DOCK_IMPORTS_FILENAME, DEVFRAME_DOCK_IMPORTS_VIRTUAL_ID, DEVFRAME_MCP_ROUTE, DEVFRAME_MOUNT_PATH, DEVFRAME_MOUNT_PATH_NO_TRAILING_SLASH, DEVFRAME_OTP_URL_PARAM, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME, DEVFRAME_WS_ROUTE, REMOTE_CONNECTION_KEY, isAnonymousRpcMethod };
|
|
76
|
+
export { ANONYMOUS_RPC_PREFIX, DEVFRAME_AUTH_TOKEN_QUERY_PARAM, DEVFRAME_CONNECTION_KEY, DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_DIRNAME, DEVFRAME_DOCK_IMPORTS_FILENAME, DEVFRAME_DOCK_IMPORTS_VIRTUAL_ID, DEVFRAME_MCP_ROUTE, DEVFRAME_MOUNT_PATH, DEVFRAME_MOUNT_PATH_NO_TRAILING_SLASH, DEVFRAME_OTP_URL_PARAM, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME, DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM, DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM, DEVFRAME_WS_ROUTE, REMOTE_CONNECTION_KEY, isAnonymousRpcMethod };
|
package/dist/constants.mjs
CHANGED
|
@@ -35,11 +35,14 @@ const DEVFRAME_RPC_DUMP_DIRNAME = "__rpc-dump";
|
|
|
35
35
|
*/
|
|
36
36
|
const REMOTE_CONNECTION_KEY = "devframe-remote-connection";
|
|
37
37
|
/**
|
|
38
|
-
* Page-URL
|
|
39
|
-
* "magic link" auth. A host can print a link like
|
|
40
|
-
* the client reads the code, exchanges it for a
|
|
41
|
-
* from the URL.
|
|
42
|
-
*
|
|
38
|
+
* Page-URL **fragment** parameter carrying a one-time authentication code (OTP)
|
|
39
|
+
* for "magic link" auth. A host can print a link like
|
|
40
|
+
* `<origin>/#devframe_otp=<code>`; the client reads the code, exchanges it for a
|
|
41
|
+
* token, and strips the parameter from the URL. The code rides the fragment
|
|
42
|
+
* (never the query string) so the browser never transmits it to the server,
|
|
43
|
+
* keeping it out of access logs and `Referer` headers. See `buildOtpAuthUrl`
|
|
44
|
+
* (node) and the `authenticateWithUrlOtp` / `consumeOtpFromUrl` client utilities
|
|
45
|
+
* (or `connectDevframe`'s `otpParam`).
|
|
43
46
|
*/
|
|
44
47
|
const DEVFRAME_OTP_URL_PARAM = "devframe_otp";
|
|
45
48
|
/**
|
|
@@ -50,6 +53,10 @@ const DEVFRAME_OTP_URL_PARAM = "devframe_otp";
|
|
|
50
53
|
* trusted before its own `anonymous:devframe:auth` handshake call arrives.
|
|
51
54
|
*/
|
|
52
55
|
const DEVFRAME_AUTH_TOKEN_QUERY_PARAM = "devframe_auth_token";
|
|
56
|
+
/** External viewer origin requested during connection bootstrap. */
|
|
57
|
+
const DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM = "devframe_viewer_origin";
|
|
58
|
+
/** Token that authorizes an external viewer origin registration. */
|
|
59
|
+
const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin_token";
|
|
53
60
|
/**
|
|
54
61
|
* Prefix that marks an RPC method as callable before a connection is
|
|
55
62
|
* trusted. This is the *only* rule the pre-trust gate applies — there is no
|
|
@@ -68,4 +75,4 @@ function isAnonymousRpcMethod(name) {
|
|
|
68
75
|
return name.startsWith(ANONYMOUS_RPC_PREFIX);
|
|
69
76
|
}
|
|
70
77
|
//#endregion
|
|
71
|
-
export { ANONYMOUS_RPC_PREFIX, DEVFRAME_AUTH_TOKEN_QUERY_PARAM, DEVFRAME_CONNECTION_KEY, DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_DIRNAME, DEVFRAME_DOCK_IMPORTS_FILENAME, DEVFRAME_DOCK_IMPORTS_VIRTUAL_ID, DEVFRAME_MCP_ROUTE, DEVFRAME_MOUNT_PATH, DEVFRAME_MOUNT_PATH_NO_TRAILING_SLASH, DEVFRAME_OTP_URL_PARAM, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME, DEVFRAME_WS_ROUTE, REMOTE_CONNECTION_KEY, isAnonymousRpcMethod };
|
|
78
|
+
export { ANONYMOUS_RPC_PREFIX, DEVFRAME_AUTH_TOKEN_QUERY_PARAM, DEVFRAME_CONNECTION_KEY, DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_DIRNAME, DEVFRAME_DOCK_IMPORTS_FILENAME, DEVFRAME_DOCK_IMPORTS_VIRTUAL_ID, DEVFRAME_MCP_ROUTE, DEVFRAME_MOUNT_PATH, DEVFRAME_MOUNT_PATH_NO_TRAILING_SLASH, DEVFRAME_OTP_URL_PARAM, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME, DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM, DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM, DEVFRAME_WS_ROUTE, REMOTE_CONNECTION_KEY, isAnonymousRpcMethod };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { n as randomToken } from "./crypto-token-XCqTSMg9.mjs";
|
|
2
|
+
import { t as createStorage } from "./storage-CTNVbuFB.mjs";
|
|
3
|
+
import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "./revoke-DZbJ7Cl0.mjs";
|
|
3
4
|
import { join } from "pathe";
|
|
4
5
|
//#region src/node/hub-internals/context.ts
|
|
5
6
|
const internalContextMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as DevframeNodeContext, ht as SharedState } from "./devframe-
|
|
1
|
+
import { b as DevframeNodeContext, ht as SharedState } from "./devframe-mQ4qZAuo.mjs";
|
|
2
2
|
//#region src/node/hub-internals/context.d.ts
|
|
3
3
|
interface InternalAnonymousAuthStorage {
|
|
4
4
|
trusted: Record<string, {
|
|
@@ -42,38 +42,4 @@ function timingSafeEqual(a, b) {
|
|
|
42
42
|
return mismatch === 0;
|
|
43
43
|
}
|
|
44
44
|
//#endregion
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Flip `isTrusted` to false on any live WS clients connected with `token`
|
|
48
|
-
* and broadcast the `auth:revoked` event so they can react.
|
|
49
|
-
*
|
|
50
|
-
* Shared between persisted-auth revocation and remote-dock token revocation.
|
|
51
|
-
*/
|
|
52
|
-
async function revokeActiveConnectionsForToken(context, token) {
|
|
53
|
-
const rpcHost = context.rpc;
|
|
54
|
-
if (!rpcHost?._rpcGroup) return;
|
|
55
|
-
const affectedSessionIds = /* @__PURE__ */ new Set();
|
|
56
|
-
for (const client of rpcHost._rpcGroup.clients) if (client.$meta.clientAuthToken === token) {
|
|
57
|
-
affectedSessionIds.add(client.$meta.id);
|
|
58
|
-
client.$meta.isTrusted = false;
|
|
59
|
-
client.$meta.clientAuthToken = void 0;
|
|
60
|
-
}
|
|
61
|
-
if (affectedSessionIds.size === 0) return;
|
|
62
|
-
await rpcHost.broadcast({
|
|
63
|
-
method: "devframe:auth:revoked",
|
|
64
|
-
args: [],
|
|
65
|
-
filter: (client) => affectedSessionIds.has(client.$meta.id)
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Revoke an auth token: remove from storage and notify all connected clients
|
|
70
|
-
* using this token that they are no longer trusted.
|
|
71
|
-
*/
|
|
72
|
-
async function revokeAuthToken(context, storage, token) {
|
|
73
|
-
storage.mutate((state) => {
|
|
74
|
-
delete state.trusted[token];
|
|
75
|
-
});
|
|
76
|
-
await revokeActiveConnectionsForToken(context, token);
|
|
77
|
-
}
|
|
78
|
-
//#endregion
|
|
79
|
-
export { timingSafeEqual as a, randomToken as i, revokeAuthToken as n, randomDigits as r, revokeActiveConnectionsForToken as t };
|
|
45
|
+
export { randomToken as n, timingSafeEqual as r, randomDigits as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DEVFRAME_CONNECTION_META_FILENAME } from "./constants.mjs";
|
|
2
|
-
import { n as createHostContext, t as createH3DevframeHost } from "./host-h3-
|
|
3
|
-
import { t as diagnostics } from "./diagnostics-
|
|
4
|
-
import { r as registerDevframeInstance } from "./instance-registry-
|
|
5
|
-
import { i as normalizeHttpServerUrl, t as startHttpAndWs } from "./server-
|
|
2
|
+
import { n as createHostContext, t as createH3DevframeHost } from "./host-h3-D2hYZvDK.mjs";
|
|
3
|
+
import { t as diagnostics } from "./diagnostics-D7wM2cwM.mjs";
|
|
4
|
+
import { r as registerDevframeInstance } from "./instance-registry-BnnA2Eoh.mjs";
|
|
5
|
+
import { i as normalizeHttpServerUrl, t as startHttpAndWs } from "./server-CD8XmBXl.mjs";
|
|
6
6
|
import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-bWRzeSa0.mjs";
|
|
7
7
|
import { t as open } from "./open-Deb5xmIT.mjs";
|
|
8
8
|
import { mountStaticHandler } from "./utils/serve-static.mjs";
|
|
@@ -295,7 +295,7 @@ async function createDevServer(def, options = {}) {
|
|
|
295
295
|
const mcpPath = joinURL(basePath, mcpRoute);
|
|
296
296
|
let mountMcpHttp;
|
|
297
297
|
try {
|
|
298
|
-
({mountMcpHttp} = await import("./http-
|
|
298
|
+
({mountMcpHttp} = await import("./http-C4T68YV6.mjs"));
|
|
299
299
|
} catch (error) {
|
|
300
300
|
const reason = error instanceof Error ? error.message : String(error);
|
|
301
301
|
throw diagnostics.DF0017({
|
|
@@ -339,6 +339,8 @@ async function createDevServer(def, options = {}) {
|
|
|
339
339
|
path: bindPath,
|
|
340
340
|
wsPort,
|
|
341
341
|
auth: resolvedAuth,
|
|
342
|
+
onPeerConnect: options.onPeerConnect,
|
|
343
|
+
onPeerDisconnect: options.onPeerDisconnect,
|
|
342
344
|
onReady: async (info) => {
|
|
343
345
|
authHandler?.printBanner();
|
|
344
346
|
await options.onReady?.(info);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-CnJSgRVa.mjs";
|
|
2
2
|
import { w as RpcFunctionsCollectorBase } from "./index-Dbw1p5ch.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { n as DevframeNodeRpcSessionMeta } from "./ws-server-uKQcClcJ.mjs";
|
|
4
4
|
import { CAC } from "cac";
|
|
5
5
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
6
6
|
import { Peer } from "crossws";
|
|
@@ -1414,6 +1414,15 @@ interface ConnectionMeta {
|
|
|
1414
1414
|
* > from a publicly reachable static `__connection.json`.
|
|
1415
1415
|
*/
|
|
1416
1416
|
authToken?: string;
|
|
1417
|
+
/**
|
|
1418
|
+
* Session-scoped token that lets a trusted external viewer register its
|
|
1419
|
+
* browser origin before opening the WebSocket. The host includes it in the
|
|
1420
|
+
* connection metadata, which the viewer obtains through the host page.
|
|
1421
|
+
*
|
|
1422
|
+
* Treat this as a bearer credential. Keep connection metadata containing the
|
|
1423
|
+
* token same-origin until the requesting origin has been verified.
|
|
1424
|
+
*/
|
|
1425
|
+
viewerOriginToken?: string;
|
|
1417
1426
|
}
|
|
1418
1427
|
//#endregion
|
|
1419
1428
|
//#region src/types/utils.d.ts
|
|
@@ -87,6 +87,10 @@ const diagnostics = defineDiagnostics({
|
|
|
87
87
|
DF0051: {
|
|
88
88
|
why: (p) => `The devframe instance on port ${p.port} has no MCP endpoint.`,
|
|
89
89
|
fix: "Restart the instance with the --mcp flag (or set `cli.mcp: true` on its definition) to expose its tools, then list instances again."
|
|
90
|
+
},
|
|
91
|
+
DF0052: {
|
|
92
|
+
why: (p) => `Failed to listen on ${p.host}:${p.port}: ${p.reason}`,
|
|
93
|
+
fix: "The port is likely already taken by another process (often a previous devframe instance). Free it, or pick another via `--port`, `cli.port` / `cli.portRange` on the definition, or `devMiddleware.port` on `viteDevBridge`. The original node error is available as `error.cause`."
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
96
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isAllowedOrigin } from "./rpc/transports/ws-server.mjs";
|
|
2
|
-
import { n as createHostContext } from "./host-h3-
|
|
3
|
-
import { t as diagnostics } from "./diagnostics-
|
|
2
|
+
import { n as createHostContext } from "./host-h3-D2hYZvDK.mjs";
|
|
3
|
+
import { t as diagnostics } from "./diagnostics-D7wM2cwM.mjs";
|
|
4
4
|
import { t as toAgentToolName } from "./agent-tool-name-C3b5vEwJ.mjs";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
import { Diagnostic } from "nostics";
|
|
@@ -457,9 +457,10 @@ function parseResourceUri(uri) {
|
|
|
457
457
|
* and MCP server (built from the shared, live `ctx` via
|
|
458
458
|
* `buildMcpServerFromContext`), correlated by the `Mcp-Session-Id` header: an
|
|
459
459
|
* `initialize` POST spins up a session; later requests route to it; a `DELETE`
|
|
460
|
-
* (or client disconnect) tears it down. The origin gate
|
|
461
|
-
* loopback-default DNS-rebinding protection
|
|
462
|
-
*
|
|
460
|
+
* (or client disconnect) tears it down. The origin gate guards every request:
|
|
461
|
+
* loopback-default DNS-rebinding protection that — unlike the WS upgrade's
|
|
462
|
+
* `isAllowedOrigin` — also rejects `Origin`-less requests, so a route-based
|
|
463
|
+
* endpoint isn't reachable by an arbitrary local process.
|
|
463
464
|
*
|
|
464
465
|
* @experimental
|
|
465
466
|
*/
|
|
@@ -503,7 +504,7 @@ function createMcpFetchHandler(ctx, options) {
|
|
|
503
504
|
}
|
|
504
505
|
async function handle(req) {
|
|
505
506
|
const origin = req.headers.get("origin") ?? void 0;
|
|
506
|
-
if (allowedOrigins !== false && !isAllowedOrigin(origin, allowedOrigins ?? [])) return new Response("Forbidden: origin
|
|
507
|
+
if (allowedOrigins !== false && (origin === void 0 || !isAllowedOrigin(origin, allowedOrigins ?? []))) return new Response("Forbidden: origin required", { status: 403 });
|
|
507
508
|
const sessionId = req.headers.get("mcp-session-id") ?? void 0;
|
|
508
509
|
let session = sessionId ? sessions.get(sessionId) : void 0;
|
|
509
510
|
if (!session && req.method === "POST") {
|
package/dist/helpers/vite.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { d as McpRouteOptions, p as DevframeAuthHandler, r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
//#region src/helpers/vite.d.ts
|
|
3
3
|
interface ViteDevBridgeOptions {
|
|
4
4
|
/**
|
|
@@ -31,16 +31,17 @@ interface ViteDevBridgeOptions {
|
|
|
31
31
|
flags?: Record<string, unknown>;
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
|
-
* Whether the bridged devframe runs its own auth gate.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
34
|
+
* Whether the bridged devframe runs its own auth gate. The side-car RPC
|
|
35
|
+
* server is reachable by anything that can open its socket, so it **gates by
|
|
36
|
+
* default**: when unset, authentication resolves through `createDevServer`
|
|
37
|
+
* (devframe's interactive OTP gate unless the definition's `cli.auth` opts
|
|
38
|
+
* out), and the side-car prints its code/link banner to stdout. Pass a
|
|
39
|
+
* {@link DevframeAuthHandler} to install a custom scheme, or `false` to opt
|
|
40
|
+
* out for a single-user localhost host that owns the trust boundary another
|
|
41
|
+
* way. Only applies in bridge mode (`devMiddleware`); the static-mount mode
|
|
41
42
|
* starts no RPC server.
|
|
42
43
|
*
|
|
43
|
-
* @default
|
|
44
|
+
* @default gated (devframe's interactive OTP, unless `cli.auth` opts out)
|
|
44
45
|
*/
|
|
45
46
|
auth?: boolean | DevframeAuthHandler;
|
|
46
47
|
/**
|
|
@@ -84,11 +85,11 @@ interface DevframeVitePlugin {
|
|
|
84
85
|
* host-served SPA can discover the WS endpoint via
|
|
85
86
|
* {@link connectDevframe}.
|
|
86
87
|
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
88
|
+
* The side-car RPC server **gates by default** (devframe's interactive OTP
|
|
89
|
+
* unless the definition's `cli.auth` opts out), printing its code/link banner
|
|
90
|
+
* to stdout, so a bridged devframe isn't silently reachable by anything that
|
|
91
|
+
* can open its socket. Pass `options.auth: false` to opt out for a single-user
|
|
92
|
+
* localhost host, or a {@link DevframeAuthHandler} for a custom scheme.
|
|
92
93
|
*
|
|
93
94
|
* Use bridge mode when integrating with frameworks that own the SPA
|
|
94
95
|
* (Nuxt, Astro, SolidStart, plain Vite apps). For the all-in-one
|