devframe 0.9.11 → 0.9.13

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 (55) hide show
  1. package/dist/adapters/build.d.mts +4 -5
  2. package/dist/adapters/build.mjs +2 -2
  3. package/dist/adapters/cac.d.mts +4 -4
  4. package/dist/adapters/cac.mjs +1 -1
  5. package/dist/adapters/dev.d.mts +4 -4
  6. package/dist/adapters/dev.mjs +1 -1
  7. package/dist/adapters/embedded.d.mts +3 -4
  8. package/dist/adapters/initiate.d.mts +7 -8
  9. package/dist/adapters/initiate.mjs +1 -1
  10. package/dist/adapters/mcp.d.mts +4 -4
  11. package/dist/adapters/mcp.mjs +9 -15
  12. package/dist/cli/main.d.mts +2 -3
  13. package/dist/client/index.d.mts +133 -35
  14. package/dist/client/index.mjs +231 -57
  15. package/dist/constants.d.mts +20 -21
  16. package/dist/{context-Bq27SDK-.mjs → context-Cdj9z9m2.mjs} +39 -21
  17. package/dist/{dev-B32EVw5w.mjs → dev-SPZzBTrH.mjs} +2 -2
  18. package/dist/in-page-channel/index.d.mts +75 -37
  19. package/dist/in-page-channel/index.mjs +56 -22
  20. package/dist/index.d.mts +4 -4
  21. package/dist/{instance-shell-BWh0JQuo.d.mts → instance-shell-BUyYrKlu.d.mts} +9 -2
  22. package/dist/{instance-shell-DvYCwrDy.mjs → instance-shell-xuu6jg51.mjs} +7 -2
  23. package/dist/internal/index.d.mts +12 -12
  24. package/dist/internal/index.mjs +1 -1
  25. package/dist/node/index.d.mts +5 -5
  26. package/dist/node/index.mjs +1 -1
  27. package/dist/nostics-DD6gsDZA.mjs +108 -0
  28. package/dist/recipes/common-rpc-functions.d.mts +6 -7
  29. package/dist/recipes/interactive-auth.d.mts +36 -11
  30. package/dist/recipes/interactive-auth.mjs +47 -4
  31. package/dist/rpc/client.d.mts +2 -3
  32. package/dist/rpc/dump.d.mts +16 -17
  33. package/dist/rpc/dump.mjs +1 -1
  34. package/dist/rpc/server.d.mts +2 -3
  35. package/dist/rpc/transports/sse-server.d.mts +4 -5
  36. package/dist/rpc/transports/ws-bun.d.mts +5 -6
  37. package/dist/rpc/transports/ws-deno.d.mts +4 -5
  38. package/dist/{shared-state-CaxB1q0h.mjs → shared-state-eQVYHNqA.mjs} +4 -1
  39. package/dist/utils/agent-tool-name.d.mts +2 -3
  40. package/dist/utils/colors.d.mts +4 -5
  41. package/dist/utils/crypto-token.d.mts +4 -5
  42. package/dist/utils/events.d.mts +2 -3
  43. package/dist/utils/hash.d.mts +2 -3
  44. package/dist/utils/launch-editor.d.mts +2 -3
  45. package/dist/utils/nanoid.d.mts +2 -3
  46. package/dist/utils/open.d.mts +2 -3
  47. package/dist/utils/remote-assets.d.mts +2 -3
  48. package/dist/utils/serve-static.d.mts +6 -7
  49. package/dist/utils/shared-state.mjs +1 -1
  50. package/dist/utils/simple-schema.d.mts +17 -18
  51. package/dist/utils/streaming-channel.mjs +4 -1
  52. package/dist/utils/structured-clone.d.mts +5 -6
  53. package/dist/utils/when.d.mts +6 -7
  54. package/dist/{write-BuLCrn9h.mjs → write-D2AJqVT8.mjs} +1 -1
  55. package/package.json +4 -4
@@ -9,9 +9,9 @@ import { BirpcReturn } from "birpc";
9
9
  * channel-name constant declared next to it.
10
10
  */
11
11
  interface InPageChannelProtocol {
12
- /** Functions implemented by the page script, callable by panels. */
12
+ /** Functions and events received by the page script. */
13
13
  pageScript?: Record<string, (...args: any[]) => any>;
14
- /** Functions implemented by panels, callable by the page script. */
14
+ /** Functions and events received by panels. */
15
15
  panel?: Record<string, (...args: any[]) => any>;
16
16
  /**
17
17
  * Shared-state slots. The page script is the authority: it owns the
@@ -26,6 +26,16 @@ type PanelFunctions<P extends InPageChannelProtocol> = SideFunctions<NonNullable
26
26
  type SharedStates<P extends InPageChannelProtocol> = P['sharedStates'] extends Record<string, object> ? P['sharedStates'] : Record<string, never>;
27
27
  type FnArgs<F> = F extends ((...args: infer A) => any) ? A : never;
28
28
  type FnReturn<F> = F extends ((...args: any[]) => infer R) ? Awaited<R> : never;
29
+ /**
30
+ * Page-script functions whose resolved return type marks an event.
31
+ * @internal
32
+ */
33
+ type PageScriptFunctionsEvents<P extends InPageChannelProtocol> = { [K in keyof PageScriptFunctions<P> as FnReturn<PageScriptFunctions<P>[K]> extends void ? K : never]: PageScriptFunctions<P>[K]; };
34
+ /**
35
+ * Panel functions whose resolved return type marks an event.
36
+ * @internal
37
+ */
38
+ type PanelFunctionsEvents<P extends InPageChannelProtocol> = { [K in keyof PanelFunctions<P> as FnReturn<PanelFunctions<P>[K]> extends void ? K : never]: PanelFunctions<P>[K]; };
29
39
  /**
30
40
  * Converts a protocol function to its accepted endpoint handler.
31
41
  *
@@ -38,46 +48,69 @@ type ProtocolHandler<F> = F extends ((...args: any[]) => any) ? (...args: FnArgs
38
48
  * fan-out), `action` performs, `query` requests data (the default).
39
49
  */
40
50
  type InPageFunctionType = 'action' | 'event' | 'query';
41
- /**
42
- * An in-page channel function definition: the `defineRpcFunction` authoring
43
- * shape (`name`, `type`, Standard-Schema `args`/`returns`,
44
- * `jsonSerializable`, `handler`) narrowed to the browser: there is no
45
- * `dump`/`snapshot`/`cacheable`/`agent`. When `jsonSerializable` is `true`,
46
- * payloads are strictly validated at the receiving endpoint and misshapen
47
- * values reject the call with a descriptive `InPageChannelError` instead of
48
- * a cryptic `DataCloneError` in the port.
49
- */
50
- type InPageFunctionDefinition<NAME extends string, TYPE extends InPageFunctionType = 'query', ARGS extends any[] = [], RETURN = void, AS extends RpcArgsSchema | undefined = undefined, RS extends RpcReturnSchema | undefined = undefined> = [AS, RS] extends [undefined, undefined] ? {
51
+ interface InPageFunctionDefinitionBase<NAME extends string> {
51
52
  name: NAME;
52
- type?: TYPE;
53
+ jsonSerializable?: boolean;
54
+ }
55
+ interface InPageEventFunctionDefinition<NAME extends string, HANDLER> extends InPageFunctionDefinitionBase<NAME> {
56
+ type: 'event';
57
+ handler?: HANDLER;
58
+ }
59
+ interface InPageQueryFunctionDefinition<NAME extends string, HANDLER> extends InPageFunctionDefinitionBase<NAME> {
60
+ type?: 'query';
61
+ handler: HANDLER;
62
+ }
63
+ interface InPageActionFunctionDefinition<NAME extends string, HANDLER> extends InPageFunctionDefinitionBase<NAME> {
64
+ type: 'action';
65
+ handler: HANDLER;
66
+ }
67
+ type InPageFunctionDefinitionForType<NAME extends string, TYPE extends InPageFunctionType, HANDLER> = TYPE extends 'event' ? InPageEventFunctionDefinition<NAME, HANDLER> : TYPE extends 'action' ? InPageActionFunctionDefinition<NAME, HANDLER> : InPageQueryFunctionDefinition<NAME, HANDLER>;
68
+ type InPageFunctionDefinitionSchemas<AS extends RpcArgsSchema | undefined, RS extends RpcReturnSchema | undefined> = [AS, RS] extends [undefined, undefined] ? {
53
69
  args?: AS;
54
70
  returns?: RS;
55
- jsonSerializable?: boolean;
56
- handler: (...args: ARGS) => RETURN;
57
71
  } : {
58
- name: NAME;
59
- type?: TYPE;
60
72
  /** Standard Schema array validating (and typing) the arguments. */
61
73
  args: AS;
62
74
  /** Standard Schema typing the resolved return value. */
63
75
  returns: RS;
64
- jsonSerializable?: boolean;
65
- handler: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>;
66
76
  };
77
+ type InPageFunctionDefinitionHandler<ARGS extends any[], RETURN, AS extends RpcArgsSchema | undefined, RS extends RpcReturnSchema | undefined> = [AS, RS] extends [undefined, undefined] ? (...args: ARGS) => RETURN : (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>;
78
+ /**
79
+ * An in-page channel function definition: the `defineRpcFunction` authoring
80
+ * shape (`name`, `type`, Standard-Schema `args`/`returns`,
81
+ * `jsonSerializable`, `handler`) narrowed to the browser: there is no
82
+ * `dump`/`snapshot`/`cacheable`/`agent`. When `jsonSerializable` is `true`,
83
+ * payloads are strictly validated at the receiving endpoint and misshapen
84
+ * values reject the call with a descriptive `InPageChannelError` instead of
85
+ * a cryptic `DataCloneError` in the port. Event definitions may omit their
86
+ * handler when runtime listeners subscribe through `channel.on()`.
87
+ */
88
+ type InPageFunctionDefinition<NAME extends string, TYPE extends InPageFunctionType = 'query', ARGS extends any[] = [], RETURN = void, AS extends RpcArgsSchema | undefined = undefined, RS extends RpcReturnSchema | undefined = undefined> = InPageFunctionDefinitionForType<NAME, TYPE, InPageFunctionDefinitionHandler<ARGS, RETURN, AS, RS>> & InPageFunctionDefinitionSchemas<AS, RS>;
67
89
  /**
68
90
  * Function metadata with its handler constrained by a protocol function.
69
91
  *
70
92
  * @internal
71
93
  */
72
- interface InPageFunctionOption<F> {
73
- type?: InPageFunctionType;
94
+ interface InPageFunctionOptionBase {
74
95
  /** Optional Standard Schema array validating the arguments. */
75
96
  args?: RpcArgsSchema;
76
97
  /** Optional Standard Schema validating the resolved return value. */
77
98
  returns?: RpcReturnSchema;
78
99
  jsonSerializable?: boolean;
100
+ }
101
+ interface InPageEventFunctionOption<F> extends InPageFunctionOptionBase {
102
+ type: 'event';
103
+ handler?: ProtocolHandler<F>;
104
+ }
105
+ interface InPageQueryFunctionOption<F> extends InPageFunctionOptionBase {
106
+ type?: 'query';
79
107
  handler: ProtocolHandler<F>;
80
108
  }
109
+ interface InPageActionFunctionOption<F> extends InPageFunctionOptionBase {
110
+ type: 'action';
111
+ handler: ProtocolHandler<F>;
112
+ }
113
+ type InPageFunctionOption<F> = InPageEventFunctionOption<F> | InPageQueryFunctionOption<F> | InPageActionFunctionOption<F>;
81
114
  /**
82
115
  * Functions implemented by {@link createPageScriptChannel}.
83
116
  *
@@ -140,7 +173,7 @@ interface InPageChannelCommonOptions {
140
173
  }
141
174
  /** Options for {@link createPageScriptChannel}. */
142
175
  interface CreatePageScriptChannelOptions<Protocol extends InPageChannelProtocol = InPageChannelProtocol> extends InPageChannelCommonOptions {
143
- /** Implementations of the protocol's page-script functions. */
176
+ /** Every page-script function declaration; event handlers may use `channel.on()`. */
144
177
  functions: CreatePageScriptChannelOptionsFunctions<Protocol>;
145
178
  /**
146
179
  * Window whose `message` events carry panel hellos. Defaults to the
@@ -151,7 +184,7 @@ interface CreatePageScriptChannelOptions<Protocol extends InPageChannelProtocol
151
184
  }
152
185
  /** Options for {@link connectPanelChannel}. */
153
186
  interface ConnectPanelChannelOptions<Protocol extends InPageChannelProtocol = InPageChannelProtocol> extends InPageChannelCommonOptions {
154
- /** Implementations of the protocol's panel functions. */
187
+ /** Every panel function declaration; event handlers may use `channel.on()`. */
155
188
  functions: ConnectPanelChannelOptionsFunctions<Protocol>;
156
189
  /**
157
190
  * The panel's own window (listens for the handshake grant). Defaults to
@@ -181,7 +214,7 @@ interface ConnectPanelChannelOptions<Protocol extends InPageChannelProtocol = In
181
214
  */
182
215
  helloIntervalMs?: number;
183
216
  /**
184
- * Maximum `callEvent` payloads buffered while `connecting`, flushed on
217
+ * Maximum `emit` payloads buffered while `connecting`, flushed on
185
218
  * connect; when full, the oldest is dropped with a console warning.
186
219
  * @default 64
187
220
  */
@@ -228,11 +261,12 @@ interface PageScriptChannel<P extends InPageChannelProtocol> {
228
261
  /** Currently connected panels. */
229
262
  readonly panels: readonly PanelPeer<P>[];
230
263
  readonly events: Pick<EventEmitter<PageScriptChannelEvents<P>>, 'on' | 'once'>;
231
- /**
232
- * Fan a fire-and-forget event out to every connected panel; panels that
233
- * don't implement the function ignore it.
234
- */
235
- callEvent: <K extends keyof PanelFunctions<P> & string>(name: K, ...args: FnArgs<PanelFunctions<P>[K]>) => void;
264
+ /** Fan an event out to every connected panel. */
265
+ emit: <K extends keyof PanelFunctionsEvents<P> & string>(name: K, ...args: FnArgs<PanelFunctionsEvents<P>[K]>) => void;
266
+ /** @deprecated Use `emit()` instead. */
267
+ callEvent: <K extends keyof PanelFunctionsEvents<P> & string>(name: K, ...args: FnArgs<PanelFunctionsEvents<P>[K]>) => void;
268
+ /** Subscribe to an event emitted by a panel. Returns an unsubscribe function. */
269
+ on: <K extends keyof PageScriptFunctionsEvents<P> & string>(name: K, listener: (...args: FnArgs<PageScriptFunctionsEvents<P>[K]>) => void) => () => void;
236
270
  /** Page-script-authoritative shared states, replayed to joining panels. */
237
271
  readonly sharedState: InPageSharedStateHost<P>;
238
272
  /** Adopt a pre-established port as a panel peer (bring-your-own transport). */
@@ -270,10 +304,14 @@ interface PanelChannel<P extends InPageChannelProtocol> {
270
304
  */
271
305
  call: <K extends keyof PageScriptFunctions<P> & string>(name: K, ...args: FnArgs<PageScriptFunctions<P>[K]>) => Promise<FnReturn<PageScriptFunctions<P>[K]>>;
272
306
  /**
273
- * Fire-and-forget to the page script. While `connecting` the event is
274
- * buffered (up to `eventBufferLimit`) and flushed on connect.
307
+ * Emit an event to the page script. While `connecting` the event is buffered
308
+ * (up to `eventBufferLimit`) and flushed on connect.
275
309
  */
276
- callEvent: <K extends keyof PageScriptFunctions<P> & string>(name: K, ...args: FnArgs<PageScriptFunctions<P>[K]>) => void;
310
+ emit: <K extends keyof PageScriptFunctionsEvents<P> & string>(name: K, ...args: FnArgs<PageScriptFunctionsEvents<P>[K]>) => void;
311
+ /** @deprecated Use `emit()` instead. */
312
+ callEvent: <K extends keyof PageScriptFunctionsEvents<P> & string>(name: K, ...args: FnArgs<PageScriptFunctionsEvents<P>[K]>) => void;
313
+ /** Subscribe to an event emitted by the page script. Returns an unsubscribe function. */
314
+ on: <K extends keyof PanelFunctionsEvents<P> & string>(name: K, listener: (...args: FnArgs<PanelFunctionsEvents<P>[K]>) => void) => () => void;
277
315
  /** Shared states mirrored from the page-script authority. */
278
316
  readonly sharedState: InPageSharedStateHost<P>;
279
317
  /** Tear the endpoint down permanently. */
@@ -294,7 +332,7 @@ type InPageChannelErrorCode = 'timeout' |
294
332
  /** A shared-state key was first accessed without its initial value. */
295
333
  'state-uninitialized';
296
334
  /** A coded in-page channel error; every failure mode carries a stable `code`. */
297
- declare class InPageChannelError extends Error {
335
+ export declare class InPageChannelError extends Error {
298
336
  readonly code: InPageChannelErrorCode;
299
337
  name: string;
300
338
  constructor(code: InPageChannelErrorCode, message: string, options?: {
@@ -312,7 +350,7 @@ declare class InPageChannelError extends Error {
312
350
  * panels all handshake the same way, and a panel reload is simply a new
313
351
  * handshake. No server is involved at any point.
314
352
  */
315
- declare function createPageScriptChannel<P extends InPageChannelProtocol>(options: CreatePageScriptChannelOptions<P>): PageScriptChannel<P>;
353
+ export declare function createPageScriptChannel<P extends InPageChannelProtocol>(options: CreatePageScriptChannelOptions<P>): PageScriptChannel<P>;
316
354
  //#endregion
317
355
  //#region src/in-page-channel/panel.d.ts
318
356
  /**
@@ -327,7 +365,7 @@ declare function createPageScriptChannel<P extends InPageChannelProtocol>(option
327
365
  * (e.g. the panel opened standalone), the endpoint stays `connecting` and
328
366
  * the UI can key a fallback state off `status` / `whenConnected()`.
329
367
  */
330
- declare function connectPanelChannel<P extends InPageChannelProtocol>(options: ConnectPanelChannelOptions<P>): PanelChannel<P>;
368
+ export declare function connectPanelChannel<P extends InPageChannelProtocol>(options: ConnectPanelChannelOptions<P>): PanelChannel<P>;
331
369
  //#endregion
332
370
  //#region src/in-page-channel/index.d.ts
333
371
  /**
@@ -338,6 +376,6 @@ declare function connectPanelChannel<P extends InPageChannelProtocol>(options: C
338
376
  * shared protocol file carries only the contract type and the channel-name
339
377
  * constant.
340
378
  */
341
- declare function defineChannelFunction<NAME extends string, TYPE extends InPageFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(definition: InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>): InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>;
379
+ export declare function defineChannelFunction<NAME extends string, TYPE extends InPageFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(definition: InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>): InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>;
342
380
  //#endregion
343
- export { type ConnectPanelChannelOptions, type CreatePageScriptChannelOptions, InPageChannelError, type InPageChannelErrorCode, type InPageChannelProtocol, type InPageChannelStatus, type InPageFunctionDefinition, type PageScriptChannel, type PanelChannel, type PanelPeer, connectPanelChannel, createPageScriptChannel, defineChannelFunction };
381
+ export type { ConnectPanelChannelOptions, CreatePageScriptChannelOptions, InPageChannelErrorCode, InPageChannelProtocol, InPageChannelStatus, InPageFunctionDefinition, PageScriptChannel, PanelChannel, PanelPeer };
@@ -1,8 +1,17 @@
1
- import { t as DEVFRAME_EVENTS } from "../events-BV4Dj59a.mjs";
1
+ import { n as DEVFRAME_EVENTS, t as defineDiagnostics } from "../nostics-DD6gsDZA.mjs";
2
2
  import { createEventEmitter } from "../utils/events.mjs";
3
- import { t as createSharedState } from "../shared-state-CaxB1q0h.mjs";
3
+ import { t as createSharedState } from "../shared-state-eQVYHNqA.mjs";
4
4
  import { nanoid } from "../utils/nanoid.mjs";
5
5
  import { createBirpc } from "birpc";
6
+ //#region src/in-page-channel/diagnostics.ts
7
+ const diagnostics = /* #__PURE__ */ defineDiagnostics({
8
+ docsBase: "https://devfra.me/errors",
9
+ codes: { DF0077: {
10
+ why: (p) => `In-page channel function "${p.name}" is not registered on this endpoint.`,
11
+ fix: "Declare the function in this endpoint's `functions` option before subscribing with `on()`."
12
+ } }
13
+ });
14
+ //#endregion
6
15
  //#region src/in-page-channel/protocol.ts
7
16
  /**
8
17
  * Wire protocol of the in-page channel handshake and its port-level control
@@ -167,19 +176,39 @@ function deserializeResult(codec, result) {
167
176
  * then serialize hook + `jsonSerializable` enforcement on the result.
168
177
  */
169
178
  function createLocalFunctionRegistry(codec) {
170
- const wrapped = /* @__PURE__ */ new Map();
179
+ const definitions = /* @__PURE__ */ new Map();
180
+ const listeners = /* @__PURE__ */ new Map();
171
181
  return {
172
182
  register(definition) {
173
- wrapped.set(definition.name, async (...rawArgs) => {
183
+ definitions.set(definition.name, definition);
184
+ },
185
+ on(name, listener) {
186
+ if (!definitions.has(name)) throw diagnostics.DF0077({ name });
187
+ let registered = listeners.get(name);
188
+ if (!registered) {
189
+ registered = /* @__PURE__ */ new Set();
190
+ listeners.set(name, registered);
191
+ }
192
+ registered.add(listener);
193
+ return () => {
194
+ registered.delete(listener);
195
+ if (registered.size === 0) listeners.delete(name);
196
+ };
197
+ },
198
+ resolve(name) {
199
+ const definition = definitions.get(name);
200
+ const registered = listeners.get(name);
201
+ if (!definition && !registered?.size) return void 0;
202
+ return async (...rawArgs) => {
174
203
  const args = codec.deserialize ? rawArgs.map(codec.deserialize) : rawArgs;
175
- if (definition.jsonSerializable) assertJsonSerializable(args, "its arguments", definition.name);
176
- if (definition.args?.length) await validateArgs(definition.name, definition.args, args);
177
- const result = await definition.handler(...args);
178
- if (definition.jsonSerializable) assertJsonSerializable(result, "its return value", definition.name);
204
+ if (definition?.jsonSerializable) assertJsonSerializable(args, "its arguments", definition.name);
205
+ if (definition?.args?.length) await validateArgs(definition.name, definition.args, args);
206
+ const result = await definition?.handler?.(...args);
207
+ for (const listener of [...listeners.get(name) ?? []]) listener(...args);
208
+ if (definition?.jsonSerializable) assertJsonSerializable(result, "its return value", definition.name);
179
209
  return codec.serialize && result !== void 0 ? codec.serialize(result) : result;
180
- });
181
- },
182
- resolve: (name) => wrapped.get(name)
210
+ };
211
+ }
183
212
  };
184
213
  }
185
214
  function wrapPostError(error) {
@@ -449,7 +478,7 @@ function createPageScriptChannel(options) {
449
478
  let closed = false;
450
479
  let heartbeatTimer;
451
480
  const registry = createLocalFunctionRegistry(codec);
452
- for (const [fnName, definition] of Object.entries(options.functions ?? {})) registry.register({
481
+ for (const [fnName, definition] of Object.entries(options.functions)) registry.register({
453
482
  ...definition,
454
483
  name: fnName
455
484
  });
@@ -550,6 +579,15 @@ function createPageScriptChannel(options) {
550
579
  }
551
580
  };
552
581
  win?.addEventListener("message", onWindowMessage);
582
+ const emit = (fnName, ...args) => {
583
+ const wireArgs = serializeArgs(codec, args);
584
+ for (const peer of peers.values()) peer.attached.rpc.$callRaw({
585
+ method: fnName,
586
+ args: wireArgs,
587
+ event: true,
588
+ optional: true
589
+ }).catch(() => {});
590
+ };
553
591
  return {
554
592
  name,
555
593
  instanceId,
@@ -560,15 +598,9 @@ function createPageScriptChannel(options) {
560
598
  on: events.on,
561
599
  once: events.once
562
600
  },
563
- callEvent: (fnName, ...args) => {
564
- const wireArgs = serializeArgs(codec, args);
565
- for (const peer of peers.values()) peer.attached.rpc.$callRaw({
566
- method: fnName,
567
- args: wireArgs,
568
- event: true,
569
- optional: true
570
- }).catch(() => {});
571
- },
601
+ emit,
602
+ callEvent: emit,
603
+ on: (fnName, listener) => registry.on(fnName, listener),
572
604
  sharedState: stateHost,
573
605
  addPanelPort: (port) => addPeer(port, `transport:${nanoid(8)}`),
574
606
  close: () => {
@@ -615,7 +647,7 @@ function connectPanelChannel(options) {
615
647
  const canHandshake = !!win && targets.length > 0;
616
648
  const events = createEventEmitter();
617
649
  const registry = createLocalFunctionRegistry(codec);
618
- for (const [fnName, definition] of Object.entries(options.functions ?? {})) registry.register({
650
+ for (const [fnName, definition] of Object.entries(options.functions)) registry.register({
619
651
  ...definition,
620
652
  name: fnName
621
653
  });
@@ -794,7 +826,9 @@ function connectPanelChannel(options) {
794
826
  });
795
827
  },
796
828
  call: (fnName, ...args) => enqueueCall(fnName, serializeArgs(codec, args)),
829
+ emit: (fnName, ...args) => sendEvent(fnName, serializeArgs(codec, args)),
797
830
  callEvent: (fnName, ...args) => sendEvent(fnName, serializeArgs(codec, args)),
831
+ on: (fnName, listener) => registry.on(fnName, listener),
798
832
  sharedState: stateHost,
799
833
  close: () => {
800
834
  if (status === "closed") return;
package/dist/index.d.mts CHANGED
@@ -5,17 +5,17 @@ import { $ as DevframeServiceOf, At as AgentHandle, B as DevframeSetupInfo, Bt a
5
5
  import { a as RemoteAssetsStore, i as RemoteAssetsProviderCustom, n as RemoteAssetsErrorMessage, o as StaticAssetsSource, r as RemoteAssetsProvider, t as RemoteAssets } from "./remote-assets-eBvSKZMS.mjs";
6
6
  import { i as DevframeDefineDiagnosticsOptions } from "./nostics-0sKe5HIj.mjs";
7
7
  //#region src/define.d.ts
8
- declare const defineRpcFunction: <NAME extends string, TYPE extends RpcFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(definition: RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevframeNodeContext>) => RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevframeNodeContext>;
8
+ export declare const defineRpcFunction: <NAME extends string, TYPE extends RpcFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(definition: RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevframeNodeContext>) => RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevframeNodeContext>;
9
9
  /**
10
10
  * Identity helper that types a devframe definition, the primary authoring
11
11
  * entry point. Import it from the package root: `import { defineDevframe } from 'devframe'`.
12
12
  */
13
- declare function defineDevframe(d: DevframeDefinition): DevframeDefinition;
13
+ export declare function defineDevframe(d: DevframeDefinition): DevframeDefinition;
14
14
  /**
15
15
  * @deprecated Read {@link DevframeDefinition.clientAssets} from the definition
16
16
  * directly. This helper is internal machinery that was never meant to be part
17
17
  * of the public API and is scheduled for removal.
18
18
  */
19
- declare function resolveClientAssets(d: DevframeDefinition): StaticAssetsSource | undefined;
19
+ export declare function resolveClientAssets(d: DevframeDefinition): StaticAssetsSource | undefined;
20
20
  //#endregion
21
- export { type AgentHandle, type AgentManifest, type AgentResource, type AgentResourceContent, type AgentResourceInput, type AgentTool, type AgentToolInput, type AgentToolProvider, type AgentToolProviderHandle, type ConnectionMeta, type ConnectionMetaSse, type ConnectionMetaWebsocket, type DevframeAgentHost, type DevframeAgentHostEvents, type DevframeCapabilities, type DevframeCliOptions, type DevframeConnectionConfigsRegistry, type DevframeDefineDiagnosticsOptions, type DevframeDefinition, type DevframeDeploymentKind, type DevframeDiagnosticsHost, type DevframeDiagnosticsLogger, type DevframeDockDefaults, type DevframeDuplicationStrategy, type DevframeHost, type DevframeNodeContext, type DevframeNodeRpcSession, type DevframeNodeRpcSessionMeta, type DevframeRpcClientFunctions, type DevframeRpcConnection, type DevframeRpcConnectionRequest, type DevframeRpcOptions, type DevframeRpcServerFunctions, type DevframeRpcSharedStates, type DevframeRpcTransportKind, type DevframeScopedNodeContext, type DevframeScopedNodeRpc, type DevframeScopedStreamingHost, type DevframeServiceDefinition, type DevframeServiceDescriptor, type DevframeServiceId, type DevframeServiceInput, type DevframeServiceMeta, type DevframeServiceOf, type DevframeServiceScopeOf, type DevframeServicesHost, type DevframeServicesRegistry, type DevframeServicesScopeRegistry, type DevframeServicesState, type DevframeSettings, type DevframeSettingsRegistry, type DevframeSettingsStore, type DevframeSetupInfo, type DevframeSnapshotRpcEntry, type DevframeSnapshotRpcInputs, type DevframeSseOptions, type DevframeStorageScope, type DevframeViewHost, type DevframeWsOptions, type EventEmitter, type EventUnsubscribe, type EventsMap, type McpAuthorization, type McpRouteOptions, type McpSetting, type RemoteAssets, type RemoteAssetsErrorMessage, type RemoteAssetsProvider, type RemoteAssetsProviderCustom, type RemoteAssetsStore, type RpcBroadcastOptions, type RpcFunctionAgentOptions, type RpcFunctionsHost, type RpcSharedStateGetOptions, type RpcSharedStateHost, type RpcStreamingChannel, type RpcStreamingChannelOptions, type RpcStreamingHost, type ScopedBroadcastOptions, type ScopedClientFunctions, type ScopedRpcFn, type ScopedServerFunctions, type ScopedSharedStates, type SettingsForNamespace, type StaticAssetsSource, defineDevframe, defineRpcFunction, resolveClientAssets };
21
+ export type { AgentHandle, AgentManifest, AgentResource, AgentResourceContent, AgentResourceInput, AgentTool, AgentToolInput, AgentToolProvider, AgentToolProviderHandle, ConnectionMeta, ConnectionMetaSse, ConnectionMetaWebsocket, DevframeAgentHost, DevframeAgentHostEvents, DevframeCapabilities, DevframeCliOptions, DevframeConnectionConfigsRegistry, DevframeDefineDiagnosticsOptions, DevframeDefinition, DevframeDeploymentKind, DevframeDiagnosticsHost, DevframeDiagnosticsLogger, DevframeDockDefaults, DevframeDuplicationStrategy, DevframeHost, DevframeNodeContext, DevframeNodeRpcSession, DevframeNodeRpcSessionMeta, DevframeRpcClientFunctions, DevframeRpcConnection, DevframeRpcConnectionRequest, DevframeRpcOptions, DevframeRpcServerFunctions, DevframeRpcSharedStates, DevframeRpcTransportKind, DevframeScopedNodeContext, DevframeScopedNodeRpc, DevframeScopedStreamingHost, DevframeServiceDefinition, DevframeServiceDescriptor, DevframeServiceId, DevframeServiceInput, DevframeServiceMeta, DevframeServiceOf, DevframeServiceScopeOf, DevframeServicesHost, DevframeServicesRegistry, DevframeServicesScopeRegistry, DevframeServicesState, DevframeSettings, DevframeSettingsRegistry, DevframeSettingsStore, DevframeSetupInfo, DevframeSnapshotRpcEntry, DevframeSnapshotRpcInputs, DevframeSseOptions, DevframeStorageScope, DevframeViewHost, DevframeWsOptions, EventEmitter, EventUnsubscribe, EventsMap, McpAuthorization, McpRouteOptions, McpSetting, RemoteAssets, RemoteAssetsErrorMessage, RemoteAssetsProvider, RemoteAssetsProviderCustom, RemoteAssetsStore, RpcBroadcastOptions, RpcFunctionAgentOptions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, RpcStreamingChannel, RpcStreamingChannelOptions, RpcStreamingHost, ScopedBroadcastOptions, ScopedClientFunctions, ScopedRpcFn, ScopedServerFunctions, ScopedSharedStates, SettingsForNamespace, StaticAssetsSource };
@@ -150,8 +150,15 @@ interface CreateInstanceShellOptions<TContext extends DevframeNodeContext> {
150
150
  app?: H3;
151
151
  /** Public origin, or a getter. Derived from the first request when omitted. */
152
152
  origin?: string | (() => string);
153
- /** Resolved auth intent: `undefined`/`true` gates, `false` opts out, a handler installs a scheme. */
154
- auth?: boolean | DevframeAuthHandler;
153
+ /**
154
+ * Resolved auth intent: `undefined`/`true` gates with {@link createInteractiveAuth}'s
155
+ * defaults, `false` opts out, a handler installs a custom scheme outright.
156
+ * A function gates too, but builds the handler itself from the now-ready
157
+ * `ctx` - the seam a wrapping host (e.g. `@devframes/hub`'s UI slot) uses to
158
+ * hand `createInteractiveAuth` a branded `banner` while still leaving `auth`
159
+ * itself unset for the caller.
160
+ */
161
+ auth?: boolean | DevframeAuthHandler | ((ctx: TContext) => DevframeAuthHandler);
155
162
  /** Host `node:http` server to share the WS upgrade with. */
156
163
  server?: Server;
157
164
  /** Explicit WebSocket control; see {@link DevframeWsOptions}. `false` disables the socket (SSE-only). */
@@ -366,11 +366,16 @@ function createInstanceShell(options) {
366
366
  };
367
367
  /**
368
368
  * Auth resolution: gate by default, `false` opts out, a handler object
369
- * installs a custom scheme. The `external` tier has no local transport to
370
- * gate (the server behind `ws.url` owns auth) so it resolves to nothing.
369
+ * installs a custom scheme, a function builds one from `ctx`. The `external`
370
+ * tier has no local transport to gate (the server behind `ws.url` owns
371
+ * auth) so it resolves to nothing.
371
372
  */
372
373
  function resolveAuth() {
373
374
  if (options.auth === false) return false;
375
+ if (typeof options.auth === "function") {
376
+ authHandler = options.auth(ctx);
377
+ return authHandler;
378
+ }
374
379
  if (typeof options.auth === "object") {
375
380
  authHandler = options.auth;
376
381
  return options.auth;
@@ -1,7 +1,7 @@
1
1
  import { v as RpcFunctionDefinitionAny } from "../types-Dq4i156u.mjs";
2
2
  import { At as AgentHandle, Bt as DevframeAgentHostEvents, F as DevframeDefinition, Ft as AgentTool, It as AgentToolInput, Lt as AgentToolProvider, Mt as AgentResource, Nt as AgentResourceContent, Pt as AgentResourceInput, Rt as AgentToolProviderHandle, Vt as EventEmitter, jt as AgentManifest, o as DevframeNodeContext, xt as DevframeHost, zt as DevframeAgentHost$1 } from "../context-BBWPLDHh.mjs";
3
3
  import { a as RemoteAssetsStore, o as StaticAssetsSource } from "../remote-assets-eBvSKZMS.mjs";
4
- import { a as InstanceShellInit, c as StartedServer, d as samePath, f as DevframeInstanceRecord, h as registerDevframeInstance, i as InstanceShellApi, l as createInstanceShell, m as listLiveDevframeInstances, n as InstanceRegisterConfig, o as InstanceShellInternals, p as DevframeInstanceRegistration, r as InstanceShell, s as InstanceWsTier, t as CreateInstanceShellOptions, u as resolveInstanceRegister } from "../instance-shell-BWh0JQuo.mjs";
4
+ import { a as InstanceShellInit, c as StartedServer, d as samePath, f as DevframeInstanceRecord, h as registerDevframeInstance, i as InstanceShellApi, l as createInstanceShell, m as listLiveDevframeInstances, n as InstanceRegisterConfig, o as InstanceShellInternals, p as DevframeInstanceRegistration, r as InstanceShell, s as InstanceWsTier, t as CreateInstanceShellOptions, u as resolveInstanceRegister } from "../instance-shell-BUyYrKlu.mjs";
5
5
  import { a as resolveBasePath, i as normalizeBasePath, n as ResolvedMcpConfig, r as loadAutoMcpAdapter, s as resolveMcpConfig } from "../_shared-DEAMiPfH.mjs";
6
6
  import { n as CreateContextRpcServerOptions, r as createContextRpcServer, t as ContextRpcServer } from "../rpc-core-DiCr5etS.mjs";
7
7
  //#region src/client-assets.d.ts
@@ -15,7 +15,7 @@ import { n as CreateContextRpcServerOptions, r as createContextRpcServer, t as C
15
15
  * Internal: exposed to first-party integrations via `devframe/internal`, not
16
16
  * part of the stable public API.
17
17
  */
18
- declare function resolveClientAssets(d: DevframeDefinition): StaticAssetsSource | undefined;
18
+ export declare function resolveClientAssets(d: DevframeDefinition): StaticAssetsSource | undefined;
19
19
  //#endregion
20
20
  //#region src/node/agent-args.d.ts
21
21
  /**
@@ -43,7 +43,7 @@ type AgentArgsFallback = 'wrap' | 'drop';
43
43
  * - an empty object becomes a zero-argument call
44
44
  * - anything else follows the {@link AgentArgsFallback}
45
45
  */
46
- declare function coerceAgentPositionalArgs(args: unknown, schemas: readonly unknown[] | undefined, fallback?: AgentArgsFallback): unknown[];
46
+ export declare function coerceAgentPositionalArgs(args: unknown, schemas: readonly unknown[] | undefined, fallback?: AgentArgsFallback): unknown[];
47
47
  //#endregion
48
48
  //#region src/node/diagnostics.d.ts
49
49
  /**
@@ -51,7 +51,7 @@ declare function coerceAgentPositionalArgs(args: unknown, schemas: readonly unkn
51
51
  * owns DF0037–DF0041), so this file alone doesn't show the next free
52
52
  * number; check `docs/content/6.errors/` for the full allocation before adding one.
53
53
  */
54
- declare const diagnostics: import("nostics").Diagnostics<{
54
+ export declare const diagnostics: import("nostics").Diagnostics<{
55
55
  readonly DF0006: {
56
56
  readonly why: (p: {
57
57
  name: string;
@@ -363,7 +363,7 @@ declare const diagnostics: import("nostics").Diagnostics<{
363
363
  * `ctx.rpc.definitions`, and accepts plugin-registered tools /
364
364
  * resources via `registerTool` / `registerResource`.
365
365
  */
366
- declare class DevframeAgentHost implements DevframeAgentHost$1 {
366
+ export declare class DevframeAgentHost implements DevframeAgentHost$1 {
367
367
  readonly context: DevframeNodeContext;
368
368
  readonly events: EventEmitter<DevframeAgentHostEvents>;
369
369
  private readonly tools;
@@ -393,7 +393,7 @@ declare class DevframeAgentHost implements DevframeAgentHost$1 {
393
393
  }
394
394
  //#endregion
395
395
  //#region src/node/host-h3.d.ts
396
- interface CreateH3DevframeHostOptions {
396
+ export interface CreateH3DevframeHostOptions {
397
397
  /**
398
398
  * Host the standalone server listens on, e.g. `http://localhost:9999`.
399
399
  * Consumed by `resolveOrigin` for dock entries that need an absolute URL.
@@ -427,7 +427,7 @@ interface CreateH3DevframeHostOptions {
427
427
  /**
428
428
  * h3-backed {@link DevframeHost}, used by the standalone CLI adapter.
429
429
  */
430
- declare function createH3DevframeHost(options: CreateH3DevframeHostOptions): DevframeHost;
430
+ export declare function createH3DevframeHost(options: CreateH3DevframeHostOptions): DevframeHost;
431
431
  //#endregion
432
432
  //#region src/node/import-runtime-module.d.ts
433
433
  /**
@@ -438,10 +438,10 @@ declare function createH3DevframeHost(options: CreateH3DevframeHostOptions): Dev
438
438
  *
439
439
  * @internal
440
440
  */
441
- declare function importRuntimeModule<T = unknown>(specifier: string): Promise<T>;
441
+ export declare function importRuntimeModule<T = unknown>(specifier: string): Promise<T>;
442
442
  //#endregion
443
443
  //#region src/node/utils.d.ts
444
- declare function normalizeHttpServerUrl(host: string, port: number | string): string;
444
+ export declare function normalizeHttpServerUrl(host: string, port: number | string): string;
445
445
  //#endregion
446
446
  //#region src/rpc/wire-codec.d.ts
447
447
  /**
@@ -464,7 +464,7 @@ interface RpcWireCodec {
464
464
  *
465
465
  * @internal
466
466
  */
467
- declare function createRpcWireCodec(definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>): RpcWireCodec;
467
+ export declare function createRpcWireCodec(definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>): RpcWireCodec;
468
468
  /**
469
469
  * Peek at a wire frame's birpc envelope without engaging a codec's
470
470
  * request-id bookkeeping; used by the SSE transport to route a frame
@@ -473,9 +473,9 @@ declare function createRpcWireCodec(definitions?: ReadonlyMap<string, Pick<RpcFu
473
473
  *
474
474
  * @internal
475
475
  */
476
- declare function peekRpcWireFrame(raw: string): {
476
+ export declare function peekRpcWireFrame(raw: string): {
477
477
  t?: string;
478
478
  i?: string;
479
479
  };
480
480
  //#endregion
481
- export { type AgentArgsFallback, type ContextRpcServer, type CreateContextRpcServerOptions, CreateH3DevframeHostOptions, type CreateInstanceShellOptions, DevframeAgentHost, type DevframeInstanceRecord, type DevframeInstanceRegistration, type InstanceRegisterConfig, type InstanceShell, type InstanceShellApi, type InstanceShellInit, type InstanceShellInternals, type InstanceWsTier, type ResolvedMcpConfig, type RpcWireCodec, type StartedServer, coerceAgentPositionalArgs, createContextRpcServer, createH3DevframeHost, createInstanceShell, createRpcWireCodec, diagnostics, importRuntimeModule, listLiveDevframeInstances, loadAutoMcpAdapter, normalizeBasePath, normalizeHttpServerUrl, peekRpcWireFrame, registerDevframeInstance, resolveBasePath, resolveClientAssets, resolveInstanceRegister, resolveMcpConfig, samePath };
481
+ export { type AgentArgsFallback, type ContextRpcServer, type CreateContextRpcServerOptions, type CreateInstanceShellOptions, type DevframeInstanceRecord, type DevframeInstanceRegistration, type InstanceRegisterConfig, type InstanceShell, type InstanceShellApi, type InstanceShellInit, type InstanceShellInternals, type InstanceWsTier, type ResolvedMcpConfig, type RpcWireCodec, type StartedServer, createContextRpcServer, createInstanceShell, listLiveDevframeInstances, loadAutoMcpAdapter, normalizeBasePath, registerDevframeInstance, resolveBasePath, resolveInstanceRegister, resolveMcpConfig, samePath };
@@ -5,6 +5,6 @@ import { n as coerceAgentPositionalArgs, t as DevframeAgentHost } from "../host-
5
5
  import { a as resolveMcpConfig, n as normalizeBasePath, r as resolveBasePath, s as importRuntimeModule, t as loadAutoMcpAdapter } from "../_shared-U8D-xzrp.mjs";
6
6
  import { t as createH3DevframeHost } from "../host-h3-BROI6SQ4.mjs";
7
7
  import { i as registerDevframeInstance, n as listLiveDevframeInstances } from "../instance-registry-DCq762YJ.mjs";
8
- import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, r as samePath, t as createInstanceShell } from "../instance-shell-DvYCwrDy.mjs";
8
+ import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, r as samePath, t as createInstanceShell } from "../instance-shell-xuu6jg51.mjs";
9
9
  import { t as createContextRpcServer } from "../rpc-core-CvkU23bQ.mjs";
10
10
  export { DevframeAgentHost, coerceAgentPositionalArgs, createContextRpcServer, createH3DevframeHost, createInstanceShell, createRpcWireCodec, diagnostics, importRuntimeModule, listLiveDevframeInstances, loadAutoMcpAdapter, normalizeBasePath, normalizeHttpServerUrl, peekRpcWireFrame, registerDevframeInstance, resolveBasePath, resolveClientAssets, resolveInstanceRegister, resolveMcpConfig, samePath };
@@ -3,7 +3,7 @@ import { v as RpcFunctionDefinitionAny } from "../types-Dq4i156u.mjs";
3
3
  import { k as SharedState, l as RpcFunctionsHost, o as DevframeNodeContext, xt as DevframeHost } from "../context-BBWPLDHh.mjs";
4
4
  import { BirpcGroup } from "birpc";
5
5
  //#region src/node/context.d.ts
6
- interface CreateHostContextOptions {
6
+ export interface CreateHostContextOptions {
7
7
  cwd: string;
8
8
  workspaceRoot?: string;
9
9
  mode: 'dev' | 'build';
@@ -32,15 +32,15 @@ interface CreateHostContextOptions {
32
32
  * `createKitContext` attaches `docks`, `terminals`, `messages`, and
33
33
  * `commands` when mounted into Vite DevTools.
34
34
  */
35
- declare function createHostContext(options: CreateHostContextOptions): Promise<DevframeNodeContext>;
35
+ export declare function createHostContext(options: CreateHostContextOptions): Promise<DevframeNodeContext>;
36
36
  //#endregion
37
37
  //#region src/node/storage.d.ts
38
- interface CreateStorageOptions<T extends object> {
38
+ export interface CreateStorageOptions<T extends object> {
39
39
  filepath: string;
40
40
  initialValue: T;
41
41
  mergeInitialValue?: false | ((initialValue: T, savedValue: T) => T);
42
42
  debounce?: number;
43
43
  }
44
- declare function createStorage<T extends object>(options: CreateStorageOptions<T>): SharedState<T>;
44
+ export declare function createStorage<T extends object>(options: CreateStorageOptions<T>): SharedState<T>;
45
45
  //#endregion
46
- export { CreateHostContextOptions, CreateStorageOptions, type RpcFunctionsHost, createHostContext, createStorage };
46
+ export type { RpcFunctionsHost };
@@ -1,3 +1,3 @@
1
- import { t as createHostContext } from "../context-Bq27SDK-.mjs";
1
+ import { t as createHostContext } from "../context-Cdj9z9m2.mjs";
2
2
  import { t as createStorage } from "../storage-B70AXK64.mjs";
3
3
  export { createHostContext, createStorage };