devframe 0.9.12 → 0.9.14

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 (67) hide show
  1. package/dist/{_shared-DEAMiPfH.d.mts → _shared-Bf2FcfJ4.d.mts} +1 -1
  2. package/dist/adapters/build.d.mts +5 -6
  3. package/dist/adapters/build.mjs +2 -2
  4. package/dist/adapters/cac.d.mts +5 -5
  5. package/dist/adapters/cac.mjs +1 -1
  6. package/dist/adapters/dev.d.mts +6 -6
  7. package/dist/adapters/dev.mjs +1 -1
  8. package/dist/adapters/embedded.d.mts +4 -5
  9. package/dist/adapters/initiate.d.mts +10 -11
  10. package/dist/adapters/initiate.mjs +1 -1
  11. package/dist/adapters/mcp.d.mts +5 -5
  12. package/dist/adapters/mcp.mjs +1 -1
  13. package/dist/cli/main.d.mts +2 -3
  14. package/dist/client/index.d.mts +144 -36
  15. package/dist/client/index.mjs +223 -34
  16. package/dist/constants.d.mts +20 -21
  17. package/dist/{context-BBWPLDHh.d.mts → context-B7411Bem.d.mts} +25 -5
  18. package/dist/{context-_temOGDB.d.mts → context-CIsx_QnV.d.mts} +1 -1
  19. package/dist/{context-DwGevWqT.mjs → context-Cdj9z9m2.mjs} +9 -2
  20. package/dist/{dev-CZ1fu4J1.mjs → dev-DpfkCVqo.mjs} +2 -2
  21. package/dist/in-page-channel/index.d.mts +76 -38
  22. package/dist/in-page-channel/index.mjs +56 -22
  23. package/dist/{index-1ezCLThh.d.mts → index--pZ3fdAq.d.mts} +23 -3
  24. package/dist/index.d.mts +5 -5
  25. package/dist/{instance-shell-xuu6jg51.mjs → instance-shell-370Oee9K.mjs} +4 -12
  26. package/dist/{instance-shell-BUyYrKlu.d.mts → instance-shell-B-FE8NY5.d.mts} +5 -5
  27. package/dist/internal/index.d.mts +15 -15
  28. package/dist/internal/index.mjs +1 -1
  29. package/dist/node/auth.d.mts +3 -3
  30. package/dist/node/auth.mjs +2 -2
  31. package/dist/node/hub-internals.d.mts +2 -2
  32. package/dist/node/index.d.mts +6 -6
  33. package/dist/node/index.mjs +1 -1
  34. package/dist/nostics-DD6gsDZA.mjs +108 -0
  35. package/dist/recipes/common-rpc-functions.d.mts +7 -8
  36. package/dist/recipes/interactive-auth.d.mts +32 -22
  37. package/dist/recipes/interactive-auth.mjs +58 -18
  38. package/dist/rpc/client.d.mts +2 -3
  39. package/dist/rpc/dump.d.mts +16 -17
  40. package/dist/rpc/dump.mjs +1 -1
  41. package/dist/rpc/server.d.mts +2 -3
  42. package/dist/rpc/transports/sse-server.d.mts +4 -5
  43. package/dist/rpc/transports/ws-bun.d.mts +6 -7
  44. package/dist/rpc/transports/ws-deno.d.mts +5 -6
  45. package/dist/{rpc-core-DiCr5etS.d.mts → rpc-core-D7WvbvK0.d.mts} +2 -2
  46. package/dist/{shared-state-CaxB1q0h.mjs → shared-state-eQVYHNqA.mjs} +4 -1
  47. package/dist/{state-Mwt6--el.mjs → state-W4wI6X5X.mjs} +14 -1
  48. package/dist/types/index.d.mts +1 -1
  49. package/dist/utils/agent-tool-name.d.mts +2 -3
  50. package/dist/utils/colors.d.mts +4 -5
  51. package/dist/utils/crypto-token.d.mts +4 -5
  52. package/dist/utils/events.d.mts +3 -4
  53. package/dist/utils/hash.d.mts +2 -3
  54. package/dist/utils/launch-editor.d.mts +2 -3
  55. package/dist/utils/nanoid.d.mts +2 -3
  56. package/dist/utils/open.d.mts +2 -3
  57. package/dist/utils/remote-assets.d.mts +2 -3
  58. package/dist/utils/serve-static.d.mts +6 -7
  59. package/dist/utils/shared-state.d.mts +1 -1
  60. package/dist/utils/shared-state.mjs +1 -1
  61. package/dist/utils/simple-schema.d.mts +17 -18
  62. package/dist/utils/streaming-channel.d.mts +1 -1
  63. package/dist/utils/streaming-channel.mjs +4 -1
  64. package/dist/utils/structured-clone.d.mts +5 -6
  65. package/dist/utils/when.d.mts +6 -7
  66. package/dist/{write-BuLCrn9h.mjs → write-D2AJqVT8.mjs} +1 -1
  67. package/package.json +4 -4
@@ -1,3 +1,3 @@
1
- import { Tt as DevframeAuthHandler } from "../context-BBWPLDHh.mjs";
2
- import { a as verifyAuthToken, i as refreshTempAuthCode, n as exchangeTempAuthCode, o as revokeActiveConnectionsForToken, r as getTempAuthCode, s as revokeAuthToken, t as buildOtpAuthUrl } from "../index-1ezCLThh.mjs";
3
- export { DevframeAuthHandler, buildOtpAuthUrl, exchangeTempAuthCode, getTempAuthCode, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
1
+ import { Tt as DevframeAuthHandler } from "../context-B7411Bem.mjs";
2
+ import { a as getTempAuthCodeInfo, c as revokeActiveConnectionsForToken, i as getTempAuthCode, l as revokeAuthToken, n as describeUA, o as refreshTempAuthCode, r as exchangeTempAuthCode, s as verifyAuthToken, t as buildOtpAuthUrl } from "../index--pZ3fdAq.mjs";
3
+ export { DevframeAuthHandler, buildOtpAuthUrl, describeUA, exchangeTempAuthCode, getTempAuthCode, getTempAuthCodeInfo, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
@@ -1,3 +1,3 @@
1
1
  import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "../revoke-cqztiCX4.mjs";
2
- import { a as verifyAuthToken, i as refreshTempAuthCode, n as exchangeTempAuthCode, r as getTempAuthCode, t as buildOtpAuthUrl } from "../state-Mwt6--el.mjs";
3
- export { buildOtpAuthUrl, exchangeTempAuthCode, getTempAuthCode, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
2
+ import { a as getTempAuthCodeInfo, i as getTempAuthCode, n as describeUA, o as refreshTempAuthCode, r as exchangeTempAuthCode, s as verifyAuthToken, t as buildOtpAuthUrl } from "../state-W4wI6X5X.mjs";
3
+ export { buildOtpAuthUrl, describeUA, exchangeTempAuthCode, getTempAuthCode, getTempAuthCodeInfo, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
@@ -1,3 +1,3 @@
1
- import { a as internalContextMap, i as getInternalContext, n as InternalAnonymousAuthStorage, r as RemoteTokenRecord, t as DevframeInternalContext } from "../context-_temOGDB.mjs";
2
- import { a as resolveBasePath, i as normalizeBasePath } from "../_shared-DEAMiPfH.mjs";
1
+ import { a as internalContextMap, i as getInternalContext, n as InternalAnonymousAuthStorage, r as RemoteTokenRecord, t as DevframeInternalContext } from "../context-CIsx_QnV.mjs";
2
+ import { a as resolveBasePath, i as normalizeBasePath } from "../_shared-Bf2FcfJ4.mjs";
3
3
  export { type DevframeInternalContext, type InternalAnonymousAuthStorage, type RemoteTokenRecord, getInternalContext, internalContextMap, normalizeBasePath, resolveBasePath };
@@ -1,9 +1,9 @@
1
1
  import "../index-pIVt92jP.mjs";
2
2
  import { v as RpcFunctionDefinitionAny } from "../types-Dq4i156u.mjs";
3
- import { k as SharedState, l as RpcFunctionsHost, o as DevframeNodeContext, xt as DevframeHost } from "../context-BBWPLDHh.mjs";
3
+ import { k as SharedState, l as RpcFunctionsHost, o as DevframeNodeContext, xt as DevframeHost } from "../context-B7411Bem.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-DwGevWqT.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 };
@@ -0,0 +1,108 @@
1
+ import { colors } from "./utils/colors.mjs";
2
+ import { defineDiagnostics } from "nostics";
3
+ import { ansiFormatter } from "nostics/formatters/ansi";
4
+ //#region src/events.ts
5
+ /**
6
+ * Centralized registry of the core devframe event names: the node-side host
7
+ * bus events, the client RPC connection events, and the server→client
8
+ * broadcast notifications, so these names live in one place instead of
9
+ * scattered string literals.
10
+ *
11
+ * **Keep this in sync with [`docs/content/8.references/3.events.md`](../../../docs/content/8.references/3.events.md)**
12
+ * (the "Core devframe events" section): every name here appears in that page's
13
+ * tables, and every name there resolves to an entry here. Add, rename, or
14
+ * remove a name in both places in the same change, and reference
15
+ * `DEVFRAME_EVENTS.*` from call sites instead of re-typing a literal.
16
+ *
17
+ * This map covers **notifications** (events, broadcasts). The request/response
18
+ * RPC endpoints of the shared-state, streaming, and auth-handshake protocols
19
+ * (`devframe:rpc:server-state:*`, `devframe:streaming:subscribe`,
20
+ * `anonymous:devframe:auth`, …) are defined at their handlers and typed in
21
+ * `types/rpc-augments.ts`; they aren't events and stay out of this map.
22
+ *
23
+ * The `EventEmitter` maps (`RpcClientEvents`, `DevframeAgentHostEvents`) and the
24
+ * `DevframeRpcClientFunctions` augmentation declare these names as type-level
25
+ * keys (a literal is unavoidable in a type position); those declarations mirror
26
+ * this map and move with it.
27
+ */
28
+ const DEVFRAME_EVENTS = {
29
+ /**
30
+ * Node-side host `EventEmitter` events. The agent host (`ctx.agent.events`)
31
+ * emits these as its tool/resource surface changes; protocol adapters (e.g.
32
+ * MCP) subscribe to re-publish their manifest.
33
+ */
34
+ bus: {
35
+ agentManifestChanged: "agent:manifest:changed",
36
+ agentToolRegistered: "agent:tool:registered",
37
+ agentToolUnregistered: "agent:tool:unregistered",
38
+ agentResourceRegistered: "agent:resource:registered",
39
+ agentResourceUnregistered: "agent:resource:unregistered"
40
+ },
41
+ /**
42
+ * Client-side RPC connection `EventEmitter` events (`rpc.events`) a UI
43
+ * subscribes to for connection lifecycle and error surfacing.
44
+ */
45
+ client: {
46
+ isTrustedUpdated: "rpc:is-trusted:updated",
47
+ error: "rpc:error",
48
+ connectionStatus: "connection:status",
49
+ connectionError: "connection:error"
50
+ },
51
+ /**
52
+ * Broadcast notifications the server pushes to clients (server → client),
53
+ * `devframe:` prefix. The paired request methods (subscribe/get/set/…) are
54
+ * RPC endpoints, not events, and are omitted deliberately.
55
+ */
56
+ broadcast: {
57
+ authRevoked: "devframe:auth:revoked",
58
+ clientStateUpdated: "devframe:rpc:client-state:updated",
59
+ clientStatePatch: "devframe:rpc:client-state:patch",
60
+ streamingChunk: "devframe:streaming:chunk",
61
+ streamingEnd: "devframe:streaming:end",
62
+ streamingUploadCancel: "devframe:streaming:upload-cancel"
63
+ },
64
+ /**
65
+ * In-page channel notifications the page script pushes to its panels
66
+ * (page script → panel), `devframe:` prefix. The paired request methods
67
+ * (`devframe:in-page:page-state:subscribe`/`set`/`patch`) are call
68
+ * endpoints, not events, and are defined at their handlers
69
+ * (`in-page-channel/state.ts`).
70
+ */
71
+ inPageChannel: {
72
+ panelStateUpdated: "devframe:in-page:panel-state:updated",
73
+ panelStatePatch: "devframe:in-page:panel-state:patch"
74
+ },
75
+ /** `postMessage` channels the runtime posts across window boundaries. */
76
+ postMessage: {
77
+ remoteAssetsError: "devframe:remote-assets-error",
78
+ inPageChannel: "devframe:in-page-channel"
79
+ }
80
+ };
81
+ //#endregion
82
+ //#region src/utils/nostics.ts
83
+ const formatAnsi = ansiFormatter(colors);
84
+ /**
85
+ * The reporter every {@link defineDiagnostics} call below wires in ahead of
86
+ * any caller-supplied ones: prints the diagnostic through devframe's own
87
+ * ANSI colors via `console[method]` (default `'warn'`).
88
+ */
89
+ function devframeReporter(d, { method = "warn" } = {}) {
90
+ console[method](formatAnsi(d));
91
+ }
92
+ /**
93
+ * Drop-in replacement for `nostics`'s `defineDiagnostics()` with devframe's
94
+ * ANSI console reporter pre-wired ahead of any `reporters` passed in. Every
95
+ * `diagnostics.ts` in devframe core, `@devframes/hub`, `@devframes/json-render`,
96
+ * and the built-in plugins defines its codes through this instead of
97
+ * `nostics`'s own `defineDiagnostics`; the reporter registration lives
98
+ * here, once, so none of them need to build their own reporter (`colors`,
99
+ * `ansiFormatter`) or take a direct dependency on `nostics` themselves.
100
+ */
101
+ function defineDiagnostics$1(options) {
102
+ return defineDiagnostics({
103
+ ...options,
104
+ reporters: [devframeReporter, ...options.reporters ?? []]
105
+ });
106
+ }
107
+ //#endregion
108
+ export { DEVFRAME_EVENTS as n, defineDiagnostics$1 as t };
@@ -1,6 +1,6 @@
1
1
  import "../index-pIVt92jP.mjs";
2
2
  import { E as Thenable, S as RpcFunctionSetupResult, c as RpcDump, g as RpcFunctionAgentOptions } from "../types-Dq4i156u.mjs";
3
- import "../context-BBWPLDHh.mjs";
3
+ import "../context-B7411Bem.mjs";
4
4
  import { SimpleSchema } from "../utils/simple-schema.mjs";
5
5
  //#region src/recipes/common-rpc-functions.d.ts
6
6
  /**
@@ -10,9 +10,9 @@ import { SimpleSchema } from "../utils/simple-schema.mjs";
10
10
  * is restricted to this union, so the RPC surface can't be used to spawn an
11
11
  * arbitrary command.
12
12
  */
13
- type KnownEditor = 'atom' | 'subl' | 'sublime' | 'sublime_text' | 'wstorm' | 'charm' | 'zed' | 'notepad++' | 'vim' | 'mvim' | 'joe' | 'gvim' | 'emacs' | 'emacsclient' | 'rmate' | 'mate' | 'code' | 'code-insiders' | 'codium' | 'vscodium' | 'trae' | 'antigravity' | 'cursor' | 'appcode' | 'clion' | 'idea' | 'phpstorm' | 'pycharm' | 'rubymine' | 'webstorm' | 'goland' | 'rider';
13
+ export type KnownEditor = 'atom' | 'subl' | 'sublime' | 'sublime_text' | 'wstorm' | 'charm' | 'zed' | 'notepad++' | 'vim' | 'mvim' | 'joe' | 'gvim' | 'emacs' | 'emacsclient' | 'rmate' | 'mate' | 'code' | 'code-insiders' | 'codium' | 'vscodium' | 'trae' | 'antigravity' | 'cursor' | 'appcode' | 'clion' | 'idea' | 'phpstorm' | 'pycharm' | 'rubymine' | 'webstorm' | 'goland' | 'rider';
14
14
  /** Runtime list of every {@link KnownEditor}. */
15
- declare const KNOWN_EDITORS: KnownEditor[];
15
+ export declare const KNOWN_EDITORS: KnownEditor[];
16
16
  /**
17
17
  * Prebuilt RPC action that opens a file in the user's configured editor.
18
18
  *
@@ -38,7 +38,7 @@ declare const KNOWN_EDITORS: KnownEditor[];
38
38
  * host-level installation shared by every plugin and feature-detectable from
39
39
  * clients, with workspace-root path containment on top of the editor gating.
40
40
  */
41
- declare const openInEditor: {
41
+ export declare const openInEditor: {
42
42
  name: "devframe:open-in-editor";
43
43
  type?: "action" | undefined;
44
44
  cacheable?: boolean;
@@ -68,7 +68,7 @@ declare const openInEditor: {
68
68
  * host-level installation shared by every plugin and feature-detectable from
69
69
  * clients, with workspace-root path containment.
70
70
  */
71
- declare const openInFinder: {
71
+ export declare const openInFinder: {
72
72
  name: "devframe:open-in-finder";
73
73
  type?: "action" | undefined;
74
74
  cacheable?: boolean;
@@ -95,7 +95,7 @@ declare const openInFinder: {
95
95
  *
96
96
  * @deprecated Use the `@devframes/service-open` wire service instead.
97
97
  */
98
- declare const commonRpcFunctions: readonly [{
98
+ export declare const commonRpcFunctions: readonly [{
99
99
  name: "devframe:open-in-editor";
100
100
  type?: "action" | undefined;
101
101
  cacheable?: boolean;
@@ -124,5 +124,4 @@ declare const commonRpcFunctions: readonly [{
124
124
  __cache?: WeakMap<object, Thenable<RpcFunctionSetupResult<[string], Thenable<void>>>> | undefined;
125
125
  __promise?: Thenable<RpcFunctionSetupResult<[string], Thenable<void>>> | undefined;
126
126
  }];
127
- //#endregion
128
- export { KNOWN_EDITORS, KnownEditor, commonRpcFunctions, openInEditor, openInFinder };
127
+ //#endregion
@@ -1,8 +1,8 @@
1
- import { Tt as DevframeAuthHandler, o as DevframeNodeContext, s as DevframeNodeRpcSession } from "../context-BBWPLDHh.mjs";
2
- import "../index-1ezCLThh.mjs";
1
+ import { Tt as DevframeAuthHandler, o as DevframeNodeContext, s as DevframeNodeRpcSession } from "../context-B7411Bem.mjs";
2
+ import "../index--pZ3fdAq.mjs";
3
3
  import { ColorFn } from "../utils/colors.mjs";
4
4
  //#region src/recipes/interactive-auth.d.ts
5
- interface CreateInteractiveAuthOptions {
5
+ export interface CreateInteractiveAuthOptions {
6
6
  /**
7
7
  * Static, pre-shared bearer tokens that are always trusted, for CI runs
8
8
  * or shared machines where the interactive code prompt would only get in
@@ -11,20 +11,18 @@ interface CreateInteractiveAuthOptions {
11
11
  */
12
12
  clientAuthTokens?: string[];
13
13
  /**
14
- * Print the current code + magic-link URL. Devframe stays headless, so
15
- * there is no default banner printed automatically; call
16
- * `auth.printBanner()` yourself once the server is listening. Defaults to
17
- * {@link createAuthBanner}'s output; pass its result here directly to
18
- * rebrand the box (title / colors), or your own function to replace the
19
- * format outright.
14
+ * Print the current code + magic-link URL. Runs when an untrusted browser
15
+ * client asks for a code (`anonymous:devframe:auth:request-code`, sent by
16
+ * the client's `requestAuthCode()`) or when the host calls
17
+ * `auth.printBanner()` itself. Defaults to {@link createAuthBanner}'s
18
+ * output; pass its result here directly to rebrand the box (title /
19
+ * colors), or your own function to replace the format outright.
20
20
  */
21
21
  banner?: AuthBannerFunction;
22
22
  /**
23
23
  * Called once a code exchange succeeds, so a host rendering its own
24
- * banner can retract it. Fires after the rotated code is printed, so
25
- * such a host drops that follow-up too and calls `auth.printBanner()`
26
- * when it next wants a code on screen. Connect-time trust from a static
27
- * or remote-dock token doesn't call this.
24
+ * banner can retract it. Connect-time trust from a static or
25
+ * remote-dock token doesn't call this.
28
26
  */
29
27
  onTrusted?: (info: {
30
28
  session: DevframeNodeRpcSession;
@@ -36,20 +34,33 @@ interface CreateInteractiveAuthOptions {
36
34
  */
37
35
  serverUrl?: () => string;
38
36
  }
39
- /** Signature of `options.banner`: render the current auth code + magic-link URL. */
40
- type AuthBannerFunction = (info: {
37
+ /** The browser client whose `anonymous:devframe:auth:request-code` call triggered a banner print. */
38
+ export interface AuthBannerRequester {
39
+ /** Short display label parsed from the client's user agent (e.g. `Chrome 120 | macOS 14 desktop`). */
40
+ ua: string;
41
+ /** The requesting page's `location.origin`. */
42
+ origin: string;
43
+ }
44
+ /** What `options.banner` receives on each print. */
45
+ export interface AuthBannerInfo {
41
46
  code: string;
42
47
  url: string;
43
- }) => void;
48
+ /** Epoch-ms timestamp the code stops being redeemable at. */
49
+ expireAt: number;
50
+ /** Present when a browser client requested the print; absent for a host's own `printBanner()` call. */
51
+ requester?: AuthBannerRequester;
52
+ }
53
+ /** Signature of `options.banner`: render the current auth code + magic-link URL. */
54
+ export type AuthBannerFunction = (info: AuthBannerInfo) => void;
44
55
  /** Palette for {@link createAuthBanner}'s box - one color per part, so a host can rebrand a subset. */
45
- interface CreateAuthBannerColorsOptions {
56
+ export interface CreateAuthBannerColorsOptions {
46
57
  border: ColorFn;
47
58
  title: ColorFn;
48
59
  label: ColorFn;
49
60
  code: ColorFn;
50
61
  url: ColorFn;
51
62
  }
52
- interface CreateAuthBannerOptions {
63
+ export interface CreateAuthBannerOptions {
53
64
  /** Box title. Defaults to `'Devframe'` - set to your product name for branding. */
54
65
  title?: string;
55
66
  /** Palette overrides; unset colors fall back to dim/bold/cyan defaults. */
@@ -62,7 +73,7 @@ interface CreateAuthBannerOptions {
62
73
  * yourself to rebrand the box (`title` / `colors`) and pass the result as
63
74
  * `options.banner`.
64
75
  */
65
- declare function createAuthBanner(options?: CreateAuthBannerOptions): AuthBannerFunction;
76
+ export declare function createAuthBanner(options?: CreateAuthBannerOptions): AuthBannerFunction;
66
77
  /**
67
78
  * Package the interactive OTP auth protocol devframe's primitives
68
79
  * (`exchangeTempAuthCode`, `verifyAuthToken`, `revokeAuthToken`,
@@ -84,6 +95,5 @@ declare function createAuthBanner(options?: CreateAuthBannerOptions): AuthBanner
84
95
  * // the whole handler to `initDevframe` / `initHub` via their `auth` option.
85
96
  * ```
86
97
  */
87
- declare function createInteractiveAuth(context: DevframeNodeContext, options?: CreateInteractiveAuthOptions): DevframeAuthHandler;
88
- //#endregion
89
- export { AuthBannerFunction, CreateAuthBannerColorsOptions, CreateAuthBannerOptions, CreateInteractiveAuthOptions, createAuthBanner, createInteractiveAuth };
98
+ export declare function createInteractiveAuth(context: DevframeNodeContext, options?: CreateInteractiveAuthOptions): DevframeAuthHandler;
99
+ //#endregion
@@ -1,7 +1,7 @@
1
1
  import { s as colors } from "../nostics-D0PvLZsn.mjs";
2
2
  import { n as defineRpcFunction } from "../define-BLWPsH6y.mjs";
3
3
  import { isAnonymousRpcMethod } from "../constants.mjs";
4
- import { a as verifyAuthToken, n as exchangeTempAuthCode, r as getTempAuthCode, t as buildOtpAuthUrl } from "../state-Mwt6--el.mjs";
4
+ import { a as getTempAuthCodeInfo, n as describeUA, o as refreshTempAuthCode, r as exchangeTempAuthCode, s as verifyAuthToken, t as buildOtpAuthUrl } from "../state-W4wI6X5X.mjs";
5
5
  import { t as getInternalContext } from "../context-jXO5vzjH.mjs";
6
6
  import { t as s } from "../simple-schema-Bi40l-P6.mjs";
7
7
  //#region src/recipes/interactive-auth.ts
@@ -16,28 +16,48 @@ function createAuthBanner(options = {}) {
16
16
  const title = options.title ?? "Devframe";
17
17
  const palette = {
18
18
  border: colors.dim,
19
- title: colors.bold,
19
+ title: (x) => colors.gray(colors.bold(x)),
20
20
  label: colors.dim,
21
- code: colors.bold,
21
+ code: (f) => colors.green(colors.bold(f)),
22
22
  url: colors.cyan,
23
23
  ...options.colors
24
24
  };
25
25
  return (info) => {
26
- const rows = [[
27
- "auth code",
28
- info.code,
29
- palette.code
30
- ], [
31
- "or open",
32
- info.url,
33
- palette.url
34
- ]];
26
+ const rows = [
27
+ [
28
+ "auth code",
29
+ info.code,
30
+ palette.code
31
+ ],
32
+ [
33
+ "or open",
34
+ info.url,
35
+ palette.url
36
+ ],
37
+ [
38
+ "expires at",
39
+ new Date(info.expireAt).toLocaleTimeString(),
40
+ palette.label
41
+ ]
42
+ ];
43
+ if (info.requester) {
44
+ rows.push([
45
+ "ua",
46
+ info.requester.ua,
47
+ palette.label
48
+ ]);
49
+ rows.push([
50
+ "origin",
51
+ info.requester.origin,
52
+ palette.label
53
+ ]);
54
+ }
35
55
  const labelWidth = Math.max(...rows.map(([label]) => label.length));
36
56
  const contentWidth = Math.max(...rows.map(([, value]) => labelWidth + 2 + value.length));
37
- const titleBarLength = title.length + 3;
57
+ const titleBarLength = title.length + 2;
38
58
  const lineWidth = Math.max(contentWidth, titleBarLength - 2);
39
59
  const top = [
40
- palette.border(`╭─`),
60
+ palette.border(`╭`),
41
61
  palette.title(title),
42
62
  palette.border(`${"─".repeat(Math.max(lineWidth + 2 - titleBarLength, 0))}╮`)
43
63
  ].join(" ");
@@ -83,14 +103,16 @@ function createInteractiveAuth(context, options = {}) {
83
103
  }
84
104
  const banner = options.banner ?? createAuthBanner();
85
105
  let bannerPrintedForCode;
86
- function printBanner() {
87
- const code = getTempAuthCode();
106
+ function printBanner(info) {
107
+ const { code, expireAt } = getTempAuthCodeInfo();
88
108
  if (code === bannerPrintedForCode) return;
89
109
  bannerPrintedForCode = code;
90
110
  const url = buildOtpAuthUrl(resolveServerUrl(), code);
91
111
  banner({
92
112
  code,
93
- url
113
+ url,
114
+ expireAt,
115
+ ...info?.requester ? { requester: info.requester } : {}
94
116
  });
95
117
  }
96
118
  const anonymousAuth = defineRpcFunction({
@@ -129,7 +151,6 @@ function createInteractiveAuth(context, options = {}) {
129
151
  const session = context.rpc.getCurrentRpcSession();
130
152
  if (!session) return { authToken: null };
131
153
  const authToken = exchangeTempAuthCode(params.code, session, params, storage);
132
- printBanner();
133
154
  if (authToken) options.onTrusted?.({
134
155
  session,
135
156
  authToken
@@ -137,6 +158,24 @@ function createInteractiveAuth(context, options = {}) {
137
158
  return { authToken };
138
159
  }
139
160
  });
161
+ const anonymousAuthRequestCode = defineRpcFunction({
162
+ name: "anonymous:devframe:auth:request-code",
163
+ type: "action",
164
+ jsonSerializable: true,
165
+ args: [s.object({
166
+ ua: s.string(),
167
+ origin: s.string(),
168
+ reissue: s.optional(s.boolean())
169
+ })],
170
+ returns: s.void(),
171
+ handler(params) {
172
+ if (params.reissue) refreshTempAuthCode();
173
+ printBanner({ requester: {
174
+ ua: describeUA(params.ua),
175
+ origin: params.origin
176
+ } });
177
+ }
178
+ });
140
179
  const revoke = defineRpcFunction({
141
180
  name: "devframe:auth:revoke",
142
181
  type: "action",
@@ -180,6 +219,7 @@ function createInteractiveAuth(context, options = {}) {
180
219
  rpcFunctions: [
181
220
  anonymousAuth,
182
221
  anonymousAuthExchange,
222
+ anonymousAuthRequestCode,
183
223
  revoke
184
224
  ],
185
225
  authorize,
@@ -1,8 +1,7 @@
1
1
  import { BirpcOptions, BirpcReturn, ChannelOptions } from "birpc";
2
2
  //#region src/rpc/client.d.ts
3
- declare function createRpcClient<ServerFunctions extends object = Record<string, never>, ClientFunctions extends object = Record<string, never>>(functions: ClientFunctions, options: {
3
+ export declare function createRpcClient<ServerFunctions extends object = Record<string, never>, ClientFunctions extends object = Record<string, never>>(functions: ClientFunctions, options: {
4
4
  channel: ChannelOptions;
5
5
  rpcOptions?: Partial<BirpcOptions<ServerFunctions, ClientFunctions, boolean>>;
6
6
  }): BirpcReturn<ServerFunctions, ClientFunctions, false>;
7
- //#endregion
8
- export { createRpcClient };
7
+ //#endregion
@@ -1,6 +1,6 @@
1
1
  import { h as RpcDumpStore, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny } from "../types-Dq4i156u.mjs";
2
2
  //#region src/rpc/dump/collect.d.ts
3
- declare function dumpFunctions<T extends readonly RpcFunctionDefinitionAny[]>(definitions: T, context?: any, options?: RpcDumpCollectionOptions): Promise<RpcDumpStore<RpcDefinitionsToFunctions<T>>>;
3
+ export declare function dumpFunctions<T extends readonly RpcFunctionDefinitionAny[]>(definitions: T, context?: any, options?: RpcDumpCollectionOptions): Promise<RpcDumpStore<RpcDefinitionsToFunctions<T>>>;
4
4
  /**
5
5
  * Creates a client that serves pre-computed results from a dump store.
6
6
  * Uses argument hashing to match calls to stored records.
@@ -11,12 +11,12 @@ declare function dumpFunctions<T extends readonly RpcFunctionDefinitionAny[]>(de
11
11
  * await client.greet('Alice')
12
12
  * ```
13
13
  */
14
- declare function createClientFromDump<T extends Record<string, any>>(store: RpcDumpStore<T>, options?: RpcDumpClientOptions): BirpcReturn<T>;
14
+ export declare function createClientFromDump<T extends Record<string, any>>(store: RpcDumpStore<T>, options?: RpcDumpClientOptions): BirpcReturn<T>;
15
15
  /**
16
16
  * Filters function definitions to only those with dump definitions.
17
17
  * Note: Only checks the definition itself, not setup results.
18
18
  */
19
- declare function getDefinitionsWithDumps<T extends readonly RpcFunctionDefinitionAny[]>(definitions: T): RpcFunctionDefinitionAny[];
19
+ export declare function getDefinitionsWithDumps<T extends readonly RpcFunctionDefinitionAny[]>(definitions: T): RpcFunctionDefinitionAny[];
20
20
  //#endregion
21
21
  //#region src/rpc/dump/error.d.ts
22
22
  /**
@@ -27,32 +27,32 @@ declare function getDefinitionsWithDumps<T extends readonly RpcFunctionDefinitio
27
27
  *
28
28
  * Non-`Error` throws are wrapped as `{ name: 'Error', message: String(thrown) }`.
29
29
  */
30
- declare function serializeDumpError(error: unknown): RpcDumpRecordError;
30
+ export declare function serializeDumpError(error: unknown): RpcDumpRecordError;
31
31
  /**
32
32
  * Inverse of {@link serializeDumpError}: rebuild a thrown `Error` from
33
33
  * the plain object stored in a dump record. Preserves `cause`, restores
34
34
  * the original `name`, and re-attaches any custom own properties.
35
35
  */
36
- declare function reviveDumpError(stored: RpcDumpRecordError): Error;
36
+ export declare function reviveDumpError(stored: RpcDumpRecordError): Error;
37
37
  //#endregion
38
38
  //#region src/rpc/dump/static.d.ts
39
- type StaticRpcDumpSerialization = 'json' | 'structured-clone';
40
- interface StaticRpcDumpManifestStaticEntry {
39
+ export type StaticRpcDumpSerialization = 'json' | 'structured-clone';
40
+ export interface StaticRpcDumpManifestStaticEntry {
41
41
  type: 'static';
42
42
  path: string;
43
43
  /** Encoder used when this entry's file was written. Default: `'json'`. */
44
44
  serialization?: StaticRpcDumpSerialization;
45
45
  }
46
- interface StaticRpcDumpManifestQueryEntry {
46
+ export interface StaticRpcDumpManifestQueryEntry {
47
47
  type: 'query';
48
48
  records: Record<string, string>;
49
49
  fallback?: string;
50
50
  /** Encoder used when each record/fallback file was written. Default: `'json'`. */
51
51
  serialization?: StaticRpcDumpSerialization;
52
52
  }
53
- type StaticRpcDumpManifestValue = StaticRpcDumpManifestStaticEntry | StaticRpcDumpManifestQueryEntry | any;
54
- type StaticRpcDumpManifest = Record<string, StaticRpcDumpManifestValue>;
55
- interface StaticRpcDumpFile {
53
+ export type StaticRpcDumpManifestValue = StaticRpcDumpManifestStaticEntry | StaticRpcDumpManifestQueryEntry | any;
54
+ export type StaticRpcDumpManifest = Record<string, StaticRpcDumpManifestValue>;
55
+ export interface StaticRpcDumpFile {
56
56
  /** Whether this file was written via `JSON.stringify` or `structured-clone-es.stringify`. */
57
57
  serialization: StaticRpcDumpSerialization;
58
58
  /** Function name the file belongs to, used to scope `DF0019` errors during write. */
@@ -60,14 +60,14 @@ interface StaticRpcDumpFile {
60
60
  /** Payload to encode. */
61
61
  data: unknown;
62
62
  }
63
- interface StaticRpcDumpCollection {
63
+ export interface StaticRpcDumpCollection {
64
64
  manifest: StaticRpcDumpManifest;
65
65
  files: Record<string, StaticRpcDumpFile>;
66
66
  }
67
- declare function collectStaticRpcDump(definitions: Iterable<RpcFunctionDefinitionAny>, context: any): Promise<StaticRpcDumpCollection>;
67
+ export declare function collectStaticRpcDump(definitions: Iterable<RpcFunctionDefinitionAny>, context: any): Promise<StaticRpcDumpCollection>;
68
68
  //#endregion
69
69
  //#region src/rpc/dump/write.d.ts
70
- interface WriteStaticRpcDumpOptions {
70
+ export interface WriteStaticRpcDumpOptions {
71
71
  /**
72
72
  * Pretty-print RPC dump JSON files. Defaults to `false` so payload
73
73
  * shards (which can be multiple MB for graph-heavy tools) ship
@@ -80,6 +80,5 @@ interface WriteStaticRpcDumpOptions {
80
80
  * the `__rpc-dump/index.json` manifest, under `outDir`. Shared by the build
81
81
  * adapter (`createBuild`) and `@devframes/hub`'s `buildHub`.
82
82
  */
83
- declare function writeStaticRpcDump(dump: StaticRpcDumpCollection, outDir: string, options?: WriteStaticRpcDumpOptions): Promise<void>;
84
- //#endregion
85
- export { StaticRpcDumpCollection, StaticRpcDumpFile, StaticRpcDumpManifest, StaticRpcDumpManifestQueryEntry, StaticRpcDumpManifestStaticEntry, StaticRpcDumpManifestValue, StaticRpcDumpSerialization, WriteStaticRpcDumpOptions, collectStaticRpcDump, createClientFromDump, dumpFunctions, getDefinitionsWithDumps, reviveDumpError, serializeDumpError, writeStaticRpcDump };
83
+ export declare function writeStaticRpcDump(dump: StaticRpcDumpCollection, outDir: string, options?: WriteStaticRpcDumpOptions): Promise<void>;
84
+ //#endregion
package/dist/rpc/dump.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getDefinitionsWithDumps, i as dumpFunctions, n as collectStaticRpcDump, o as reviveDumpError, r as createClientFromDump, s as serializeDumpError, t as writeStaticRpcDump } from "../write-BuLCrn9h.mjs";
1
+ import { a as getDefinitionsWithDumps, i as dumpFunctions, n as collectStaticRpcDump, o as reviveDumpError, r as createClientFromDump, s as serializeDumpError, t as writeStaticRpcDump } from "../write-D2AJqVT8.mjs";
2
2
  export { collectStaticRpcDump, createClientFromDump, dumpFunctions, getDefinitionsWithDumps, reviveDumpError, serializeDumpError, writeStaticRpcDump };
@@ -1,7 +1,6 @@
1
1
  import { BirpcGroup, EventOptions } from "birpc";
2
2
  //#region src/rpc/server.d.ts
3
- declare function createRpcServer<ClientFunctions extends object = Record<string, never>, ServerFunctions extends object = Record<string, never>>(functions: ServerFunctions, options?: {
3
+ export declare function createRpcServer<ClientFunctions extends object = Record<string, never>, ServerFunctions extends object = Record<string, never>>(functions: ServerFunctions, options?: {
4
4
  rpcOptions?: EventOptions<ClientFunctions, ServerFunctions, false>;
5
5
  }): BirpcGroup<ClientFunctions, ServerFunctions, false>;
6
- //#endregion
7
- export { createRpcServer };
6
+ //#endregion
@@ -2,7 +2,7 @@ import { v as RpcFunctionDefinitionAny } from "../../types-Dq4i156u.mjs";
2
2
  import { c as DevframeNodeRpcSessionMeta, l as DevframeRpcConnection, n as WsOriginRegistry } from "../../ws-server-D2nv68Hg.mjs";
3
3
  import { BirpcGroup } from "birpc";
4
4
  //#region src/rpc/transports/sse-server.d.ts
5
- interface SseRpcTransportOptions {
5
+ export interface SseRpcTransportOptions {
6
6
  /**
7
7
  * Same contract as `WsRpcTransportOptions.allowedOrigins`: extra origins
8
8
  * to accept beyond the loopback default, a live origin registry, or
@@ -28,7 +28,7 @@ interface SseRpcTransportOptions {
28
28
  /** Mint a session id. Default: `crypto.randomUUID`. */
29
29
  generateSessionId?: () => string;
30
30
  }
31
- interface SseRpcTransport {
31
+ export interface SseRpcTransport {
32
32
  /**
33
33
  * Web-standard handler for the SSE route: `GET` opens the event stream,
34
34
  * `POST` carries RPC frames (session id in the `x-birpc-session` header),
@@ -56,6 +56,5 @@ interface SseRpcTransport {
56
56
  * - server-initiated calls/events stream down as `event: message`
57
57
  * frames, and the client's replies up via `POST` get a bare `202`.
58
58
  */
59
- declare function attachSseRpcTransport<ClientFunctions extends object, ServerFunctions extends object>(rpcGroup: BirpcGroup<ClientFunctions, ServerFunctions, false>, options?: SseRpcTransportOptions): SseRpcTransport;
60
- //#endregion
61
- export { SseRpcTransport, SseRpcTransportOptions, attachSseRpcTransport };
59
+ export declare function attachSseRpcTransport<ClientFunctions extends object, ServerFunctions extends object>(rpcGroup: BirpcGroup<ClientFunctions, ServerFunctions, false>, options?: SseRpcTransportOptions): SseRpcTransport;
60
+ //#endregion
@@ -1,7 +1,7 @@
1
1
  import { n as WsOriginRegistry } from "../../ws-server-D2nv68Hg.mjs";
2
- import { t as ContextRpcServer } from "../../rpc-core-DiCr5etS.mjs";
2
+ import { t as ContextRpcServer } from "../../rpc-core-D7WvbvK0.mjs";
3
3
  //#region src/rpc/transports/ws-bun.d.ts
4
- interface AttachBunWsTransportOptions {
4
+ export interface AttachBunWsTransportOptions {
5
5
  /** Same contract as `WsRpcTransportOptions.allowedOrigins`. */
6
6
  allowedOrigins?: readonly string[] | WsOriginRegistry | false;
7
7
  }
@@ -10,13 +10,13 @@ interface AttachBunWsTransportOptions {
10
10
  * crossws Bun adapter produces, typed loosely so devframe carries no
11
11
  * dependency on Bun's own types.
12
12
  */
13
- interface BunWsTierWebSocket {
13
+ export interface BunWsTierWebSocket {
14
14
  open?: (ws: unknown) => unknown;
15
15
  message: (ws: unknown, message: unknown) => unknown;
16
16
  close?: (ws: unknown, code?: number, reason?: string) => unknown;
17
17
  drain?: (ws: unknown) => unknown;
18
18
  }
19
- interface BunWsTier {
19
+ export interface BunWsTier {
20
20
  /** Complete a WS upgrade request; `Bun.serve`'s server as 2nd argument. */
21
21
  handleUpgrade: (request: Request, server: unknown) => Promise<Response | undefined>;
22
22
  /** The handlers to spread into `Bun.serve({ websocket })`. */
@@ -30,6 +30,5 @@ interface BunWsTier {
30
30
  * app's own origin, with no side-car server. Load it dynamically so the Bun
31
31
  * adapter never enters a Node-only bundle path.
32
32
  */
33
- declare function attachBunWsTransport(core: ContextRpcServer, options?: AttachBunWsTransportOptions): Promise<BunWsTier>;
34
- //#endregion
35
- export { AttachBunWsTransportOptions, BunWsTier, BunWsTierWebSocket, attachBunWsTransport };
33
+ export declare function attachBunWsTransport(core: ContextRpcServer, options?: AttachBunWsTransportOptions): Promise<BunWsTier>;
34
+ //#endregion