@adonis-agora/agent 0.74.1 → 0.76.0

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 (124) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +16 -0
  3. package/dist/src/channels/handler.d.ts.map +1 -1
  4. package/dist/src/channels/handler.js +10 -0
  5. package/dist/src/channels/handler.js.map +1 -1
  6. package/dist/src/channels/texts.d.ts +2 -0
  7. package/dist/src/channels/texts.d.ts.map +1 -1
  8. package/dist/src/channels/texts.js.map +1 -1
  9. package/dist/src/genui/catalog.d.ts.map +1 -1
  10. package/dist/src/genui/catalog.js +3 -1
  11. package/dist/src/genui/catalog.js.map +1 -1
  12. package/dist/src/genui/channels.d.ts +32 -5
  13. package/dist/src/genui/channels.d.ts.map +1 -1
  14. package/dist/src/genui/channels.js +20 -9
  15. package/dist/src/genui/channels.js.map +1 -1
  16. package/dist/src/genui/index.d.ts.map +1 -1
  17. package/dist/src/genui/index.js +7 -7
  18. package/dist/src/genui/index.js.map +1 -1
  19. package/dist/src/genui/kit/bundle.d.ts +12 -0
  20. package/dist/src/genui/kit/bundle.d.ts.map +1 -1
  21. package/dist/src/genui/kit/bundle.js +124 -133
  22. package/dist/src/genui/kit/bundle.js.map +1 -1
  23. package/dist/src/genui/kit/discover.d.ts +8 -5
  24. package/dist/src/genui/kit/discover.d.ts.map +1 -1
  25. package/dist/src/genui/kit/discover.js +45 -18
  26. package/dist/src/genui/kit/discover.js.map +1 -1
  27. package/dist/src/genui/kit/docs.d.ts +3 -1
  28. package/dist/src/genui/kit/docs.d.ts.map +1 -1
  29. package/dist/src/genui/kit/docs.js +22 -5
  30. package/dist/src/genui/kit/docs.js.map +1 -1
  31. package/dist/src/genui/kit/files.d.ts +22 -10
  32. package/dist/src/genui/kit/files.d.ts.map +1 -1
  33. package/dist/src/genui/kit/files.js +117 -19
  34. package/dist/src/genui/kit/files.js.map +1 -1
  35. package/dist/src/genui/kit/index.d.ts +5 -3
  36. package/dist/src/genui/kit/index.d.ts.map +1 -1
  37. package/dist/src/genui/kit/index.js +4 -2
  38. package/dist/src/genui/kit/index.js.map +1 -1
  39. package/dist/src/genui/kit/plugin.d.ts +17 -9
  40. package/dist/src/genui/kit/plugin.d.ts.map +1 -1
  41. package/dist/src/genui/kit/plugin.js +196 -129
  42. package/dist/src/genui/kit/plugin.js.map +1 -1
  43. package/dist/src/genui/kit/styles.d.ts +83 -0
  44. package/dist/src/genui/kit/styles.d.ts.map +1 -0
  45. package/dist/src/genui/kit/styles.js +406 -0
  46. package/dist/src/genui/kit/styles.js.map +1 -0
  47. package/dist/src/genui/kit/vite-build.d.ts +33 -0
  48. package/dist/src/genui/kit/vite-build.d.ts.map +1 -0
  49. package/dist/src/genui/kit/vite-build.js +195 -0
  50. package/dist/src/genui/kit/vite-build.js.map +1 -0
  51. package/dist/src/genui/kit/write.d.ts +20 -8
  52. package/dist/src/genui/kit/write.d.ts.map +1 -1
  53. package/dist/src/genui/kit/write.js +54 -16
  54. package/dist/src/genui/kit/write.js.map +1 -1
  55. package/dist/src/genui/public.d.ts +5 -4
  56. package/dist/src/genui/public.d.ts.map +1 -1
  57. package/dist/src/genui/public.js +4 -3
  58. package/dist/src/genui/public.js.map +1 -1
  59. package/dist/src/genui/sandbox-jsx-frame-generated.d.ts +2 -0
  60. package/dist/src/genui/sandbox-jsx-frame-generated.d.ts.map +1 -0
  61. package/dist/src/genui/sandbox-jsx-frame-generated.js +4 -0
  62. package/dist/src/genui/sandbox-jsx-frame-generated.js.map +1 -0
  63. package/dist/src/genui/sandbox-kit.d.ts +50 -17
  64. package/dist/src/genui/sandbox-kit.d.ts.map +1 -1
  65. package/dist/src/genui/sandbox-kit.js +20 -10
  66. package/dist/src/genui/sandbox-kit.js.map +1 -1
  67. package/dist/src/genui/sandbox-styles.d.ts +113 -0
  68. package/dist/src/genui/sandbox-styles.d.ts.map +1 -0
  69. package/dist/src/genui/sandbox-styles.js +487 -0
  70. package/dist/src/genui/sandbox-styles.js.map +1 -0
  71. package/dist/src/genui/sandbox-theme.d.ts +13 -9
  72. package/dist/src/genui/sandbox-theme.d.ts.map +1 -1
  73. package/dist/src/genui/sandbox-theme.js +52 -60
  74. package/dist/src/genui/sandbox-theme.js.map +1 -1
  75. package/dist/src/genui/sandbox.d.ts +21 -15
  76. package/dist/src/genui/sandbox.d.ts.map +1 -1
  77. package/dist/src/genui/sandbox.js +66 -17
  78. package/dist/src/genui/sandbox.js.map +1 -1
  79. package/dist/src/genui/tools.d.ts +20 -0
  80. package/dist/src/genui/tools.d.ts.map +1 -1
  81. package/dist/src/genui/tools.js +19 -4
  82. package/dist/src/genui/tools.js.map +1 -1
  83. package/dist/src/hooks/genui_kit.d.ts +6 -2
  84. package/dist/src/hooks/genui_kit.d.ts.map +1 -1
  85. package/dist/src/hooks/genui_kit.js +21 -9
  86. package/dist/src/hooks/genui_kit.js.map +1 -1
  87. package/dist/src/index.d.ts +1 -1
  88. package/dist/src/index.js +1 -1
  89. package/dist/src/negotiated-tool-ui.d.ts.map +1 -1
  90. package/dist/src/negotiated-tool-ui.js +4 -0
  91. package/dist/src/negotiated-tool-ui.js.map +1 -1
  92. package/dist/src/react/core/genui/sandbox-assets.d.ts +4 -1
  93. package/dist/src/react/core/genui/sandbox-assets.d.ts.map +1 -1
  94. package/dist/src/react/core/genui/sandbox-assets.js +17 -5
  95. package/dist/src/react/core/genui/sandbox-assets.js.map +1 -1
  96. package/dist/src/react/core/genui/sandbox.d.ts +1 -1
  97. package/dist/src/react/core/genui/sandbox.d.ts.map +1 -1
  98. package/dist/src/react/core/genui/sandbox.js +20 -4
  99. package/dist/src/react/core/genui/sandbox.js.map +1 -1
  100. package/dist/src/react-native/genui/index.d.ts +20 -0
  101. package/dist/src/react-native/genui/index.d.ts.map +1 -0
  102. package/dist/src/react-native/genui/index.js +18 -0
  103. package/dist/src/react-native/genui/index.js.map +1 -0
  104. package/dist/src/react-native/genui/provider.d.ts +19 -0
  105. package/dist/src/react-native/genui/provider.d.ts.map +1 -0
  106. package/dist/src/react-native/genui/provider.js +23 -0
  107. package/dist/src/react-native/genui/provider.js.map +1 -0
  108. package/dist/src/react-native/genui/sandbox-assets.d.ts +57 -0
  109. package/dist/src/react-native/genui/sandbox-assets.d.ts.map +1 -0
  110. package/dist/src/react-native/genui/sandbox-assets.js +153 -0
  111. package/dist/src/react-native/genui/sandbox-assets.js.map +1 -0
  112. package/dist/src/react-native/genui/sandbox-host.d.ts +119 -0
  113. package/dist/src/react-native/genui/sandbox-host.d.ts.map +1 -0
  114. package/dist/src/react-native/genui/sandbox-host.js +188 -0
  115. package/dist/src/react-native/genui/sandbox-host.js.map +1 -0
  116. package/dist/src/react-native/genui/sandbox.d.ts +86 -0
  117. package/dist/src/react-native/genui/sandbox.d.ts.map +1 -0
  118. package/dist/src/react-native/genui/sandbox.js +376 -0
  119. package/dist/src/react-native/genui/sandbox.js.map +1 -0
  120. package/dist/src/vite/index.d.ts +10 -7
  121. package/dist/src/vite/index.d.ts.map +1 -1
  122. package/dist/src/vite/index.js +10 -7
  123. package/dist/src/vite/index.js.map +1 -1
  124. package/package.json +28 -2
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type GenerativeUIFallback, type GenuiProviderProps } from '../../react/core/genui/generative-ui.js';
3
+ import type { GenuiActionHandler } from './sandbox.js';
4
+ /** The item's persisted text, as a `<Text>` — the web default draws a `<span>`, which RN cannot. */
5
+ export declare const nativeGenuiFallback: GenerativeUIFallback;
6
+ /**
7
+ * `GenuiProvider` for React Native: the same provider (the same shared contexts — `GenerativeUI`
8
+ * and `useGenerativeUI` read it as on the web), with `fallback` defaulting to
9
+ * {@link nativeGenuiFallback} so an unknown or failing component never draws a DOM element.
10
+ */
11
+ export declare function GenuiProvider({ fallback, ...props }: GenuiProviderProps): import("react").JSX.Element;
12
+ /** Where UI actions go — a sandbox's `agent.send(…)`. Typically the chat's `sendUiAction`. */
13
+ export declare function GenuiActionProvider({ onAction, children, }: {
14
+ onAction: GenuiActionHandler;
15
+ children?: ReactNode;
16
+ }): import("react").JSX.Element;
17
+ /** The enclosing {@link GenuiActionProvider}'s handler, or `null` outside one. */
18
+ export declare function useGenuiAction(): GenuiActionHandler | null;
19
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/react-native/genui/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AAEnD,OAAO,EAEL,KAAK,oBAAoB,EAEzB,KAAK,kBAAkB,EACxB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,oGAAoG;AACpG,eAAO,MAAM,mBAAmB,EAAE,oBACyD,CAAC;AAE5F;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,+BAEvE;AAED,8FAA8F;AAC9F,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAEA;AAED,kFAAkF;AAClF,wBAAgB,cAAc,IAAI,kBAAkB,GAAG,IAAI,CAE1D"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useContext } from 'react';
3
+ import { Text } from 'react-native';
4
+ import { GenuiProvider as BaseGenuiProvider, GenuiActionContext, } from '../../react/core/genui/generative-ui.js';
5
+ /** The item's persisted text, as a `<Text>` — the web default draws a `<span>`, which RN cannot. */
6
+ export const nativeGenuiFallback = (problem) => problem.item.fallbackText !== undefined ? _jsx(Text, { children: problem.item.fallbackText }) : null;
7
+ /**
8
+ * `GenuiProvider` for React Native: the same provider (the same shared contexts — `GenerativeUI`
9
+ * and `useGenerativeUI` read it as on the web), with `fallback` defaulting to
10
+ * {@link nativeGenuiFallback} so an unknown or failing component never draws a DOM element.
11
+ */
12
+ export function GenuiProvider({ fallback, ...props }) {
13
+ return _jsx(BaseGenuiProvider, { ...props, fallback: fallback ?? nativeGenuiFallback });
14
+ }
15
+ /** Where UI actions go — a sandbox's `agent.send(…)`. Typically the chat's `sendUiAction`. */
16
+ export function GenuiActionProvider({ onAction, children, }) {
17
+ return _jsx(GenuiActionContext.Provider, { value: onAction, children: children });
18
+ }
19
+ /** The enclosing {@link GenuiActionProvider}'s handler, or `null` outside one. */
20
+ export function useGenuiAction() {
21
+ return useContext(GenuiActionContext);
22
+ }
23
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../../src/react-native/genui/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,UAAU,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EACL,aAAa,IAAI,iBAAiB,EAElC,kBAAkB,GAEnB,MAAM,yCAAyC,CAAC;AAIjD,oGAAoG;AACpG,MAAM,CAAC,MAAM,mBAAmB,GAAyB,CAAC,OAA4B,EAAE,EAAE,CACxF,OAAO,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,OAAO,CAAC,IAAI,CAAC,YAAY,GAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAE5F;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAsB;IACtE,OAAO,KAAC,iBAAiB,OAAK,KAAK,EAAE,QAAQ,EAAE,QAAQ,IAAI,mBAAmB,GAAI,CAAC;AACrF,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,mBAAmB,CAAC,EAClC,QAAQ,EACR,QAAQ,GAIT;IACC,OAAO,KAAC,kBAAkB,CAAC,QAAQ,IAAC,KAAK,EAAE,QAAQ,YAAG,QAAQ,GAA+B,CAAC;AAChG,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The sandbox's look, as a React Native app gives it. Like the server's `genui.sandbox` config
3
+ * (`GET <agent>/config`), but each asset may come inline (`runtime`, `source`) instead of by url.
4
+ */
5
+ export interface NativeSandboxConfig {
6
+ /** Pass the app's theme in. Default true. */
7
+ theme?: boolean;
8
+ /**
9
+ * Tailwind (v4 `@tailwindcss/browser`): its source inline (`runtime`), or a `url` to fetch it from
10
+ * (the agent's public asset — relative urls resolve against `baseUrl`); `css` is extra Tailwind
11
+ * directives (`@theme`, `@custom-variant`) the app's stylesheet declares.
12
+ */
13
+ tailwind?: {
14
+ runtime?: string;
15
+ url?: string;
16
+ css?: string;
17
+ };
18
+ /** The kit bundle (JSX views): its source inline, or a `url` to fetch it from. */
19
+ kit?: {
20
+ source?: string;
21
+ url?: string;
22
+ };
23
+ /** The app's compiled styles (`genuiSandboxKit({ styles })`): inline, or a `url` to fetch them from. */
24
+ css?: {
25
+ source?: string;
26
+ url?: string;
27
+ };
28
+ }
29
+ /**
30
+ * Where the config comes from: an object; a url answering `GET <agent>/config` (or the sandbox
31
+ * config itself); a loader (your own authenticated client); `false` — theme only. Default: `GET
32
+ * <baseUrl>/config` when there is a `baseUrl`, else theme only.
33
+ */
34
+ export type NativeSandboxConfigSource = NativeSandboxConfig | string | false | (() => NativeSandboxConfig | undefined | Promise<NativeSandboxConfig | undefined>);
35
+ export type FetchLike = (input: string, init?: {
36
+ headers?: Record<string, string>;
37
+ credentials?: 'omit' | 'same-origin' | 'include';
38
+ }) => Promise<{
39
+ ok: boolean;
40
+ text(): Promise<string>;
41
+ }>;
42
+ /** Fetch a text once per url, shared by every sandbox in the app; a failure is forgotten. */
43
+ export declare function loadNativeSandboxText(url: string, fetchImpl?: FetchLike | undefined, init?: Parameters<FetchLike>[1]): Promise<string | null>;
44
+ /** The sandbox's config: `undefined` (and `loading`) until it is known. */
45
+ export declare function useNativeSandboxConfig(source: NativeSandboxConfigSource | undefined, baseUrl: string | undefined, fetchImpl: FetchLike | undefined): {
46
+ config: NativeSandboxConfig | undefined;
47
+ loading: boolean;
48
+ };
49
+ /**
50
+ * An asset's text: inline if given, else fetched from its url (resolved against `baseUrl`).
51
+ * `undefined` while it loads, `null` when it could not be had (or there is none).
52
+ */
53
+ export declare function useNativeSandboxAsset(asset: {
54
+ inline?: string | undefined;
55
+ url?: string | undefined;
56
+ } | undefined, baseUrl: string | undefined, fetchImpl: FetchLike | undefined): string | null | undefined;
57
+ //# sourceMappingURL=sandbox-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-assets.d.ts","sourceRoot":"","sources":["../../../../src/react-native/genui/sandbox-assets.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,kFAAkF;IAClF,GAAG,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,wGAAwG;IACxG,GAAG,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GACjC,mBAAmB,GACnB,MAAM,GACN,KAAK,GACL,CAAC,MAAM,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAC;AAEvF,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAA;CAAE,KAC1F,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AA2CvD,6FAA6F;AAC7F,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,SAAS,GAAE,SAAS,GAAG,SAA0B,EACjD,IAAI,GAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAA2B,GACvD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBxB;AAiCD,2EAA2E;AAC3E,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,GAAG,SAAS,EAC7C,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,SAAS,GAAG,SAAS,GAC/B;IAAE,MAAM,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAwB/D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,EAC5E,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,SAAS,GAAG,SAAS,GAC/B,MAAM,GAAG,IAAI,GAAG,SAAS,CAuB3B"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * The theme / Tailwind / kit settings and assets of a React Native sandbox. A web host reads them
3
+ * from its own origin (`GET /agent/config`, then the asset urls it names); an app has no origin, so
4
+ * it passes them in, or names the agent by an absolute `baseUrl` — relative urls resolve against it.
5
+ */
6
+ import { useEffect, useState } from 'react';
7
+ import { resolveSandboxUrl } from './sandbox-host.js';
8
+ /** Largest config or asset text accepted (the kit bundle is the big one). */
9
+ const MAX_ASSET_CHARS = 8 * 1024 * 1024;
10
+ function defaultFetch() {
11
+ const f = globalThis.fetch;
12
+ return typeof f === 'function' ? f : undefined;
13
+ }
14
+ function toConfig(body) {
15
+ if (typeof body !== 'object' || body === null)
16
+ return undefined;
17
+ const record = body;
18
+ const sandbox = typeof record.genui?.sandbox === 'object' && record.genui.sandbox !== null
19
+ ? record.genui.sandbox
20
+ : typeof record.theme === 'boolean'
21
+ ? record
22
+ : undefined;
23
+ if (sandbox === undefined)
24
+ return undefined;
25
+ const config = { theme: sandbox.theme !== false };
26
+ const tailwind = sandbox.tailwind;
27
+ if (typeof tailwind === 'object' && tailwind !== null && typeof tailwind.url === 'string') {
28
+ config.tailwind = {
29
+ url: tailwind.url,
30
+ ...(typeof tailwind.css === 'string' ? { css: tailwind.css } : {}),
31
+ };
32
+ }
33
+ const kit = sandbox.kit;
34
+ if (typeof kit === 'object' && kit !== null && typeof kit.url === 'string') {
35
+ config.kit = { url: kit.url };
36
+ }
37
+ const css = sandbox.css;
38
+ if (typeof css === 'object' && css !== null && typeof css.url === 'string') {
39
+ config.css = { url: css.url };
40
+ }
41
+ return config;
42
+ }
43
+ const THEME_ONLY = Object.freeze({ theme: true });
44
+ const texts = new Map();
45
+ /** Fetch a text once per url, shared by every sandbox in the app; a failure is forgotten. */
46
+ export function loadNativeSandboxText(url, fetchImpl = defaultFetch(), init = { credentials: 'omit' }) {
47
+ if (fetchImpl === undefined)
48
+ return Promise.resolve(null);
49
+ let pending = texts.get(url);
50
+ if (pending === undefined) {
51
+ pending = Promise.resolve()
52
+ .then(() => fetchImpl(url, init))
53
+ .then((response) => (response.ok ? response.text() : null))
54
+ .then((text) => (typeof text === 'string' && text.length <= MAX_ASSET_CHARS ? text : null))
55
+ .catch(() => null)
56
+ .then((text) => {
57
+ if (text === null)
58
+ texts.delete(url);
59
+ return text;
60
+ });
61
+ texts.set(url, pending);
62
+ }
63
+ return pending;
64
+ }
65
+ async function loadConfig(source, baseUrl, fetchImpl) {
66
+ if (typeof source === 'function') {
67
+ try {
68
+ const loaded = await source();
69
+ return typeof loaded === 'object' && loaded !== null ? loaded : undefined;
70
+ }
71
+ catch {
72
+ return undefined;
73
+ }
74
+ }
75
+ const url = typeof source === 'string'
76
+ ? resolveSandboxUrl(source, baseUrl)
77
+ : baseUrl !== undefined
78
+ ? resolveSandboxUrl(`${baseUrl.replace(/\/+$/, '')}/config`, undefined)
79
+ : undefined;
80
+ if (url === undefined)
81
+ return undefined;
82
+ const text = await loadNativeSandboxText(url, fetchImpl, {
83
+ headers: { accept: 'application/json' },
84
+ });
85
+ if (text === null)
86
+ return undefined;
87
+ try {
88
+ return toConfig(JSON.parse(text));
89
+ }
90
+ catch {
91
+ return undefined;
92
+ }
93
+ }
94
+ /** The sandbox's config: `undefined` (and `loading`) until it is known. */
95
+ export function useNativeSandboxConfig(source, baseUrl, fetchImpl) {
96
+ const immediate = source === false || (source === undefined && baseUrl === undefined)
97
+ ? THEME_ONLY
98
+ : typeof source === 'object'
99
+ ? source
100
+ : undefined;
101
+ const [state, setState] = useState({
102
+ config: undefined,
103
+ done: false,
104
+ });
105
+ useEffect(() => {
106
+ if (immediate !== undefined)
107
+ return;
108
+ let cancelled = false;
109
+ setState({ config: undefined, done: false });
110
+ void loadConfig(source, baseUrl, fetchImpl).then((config) => {
111
+ if (!cancelled)
112
+ setState({ config: config ?? THEME_ONLY, done: true });
113
+ });
114
+ return () => {
115
+ cancelled = true;
116
+ };
117
+ }, [immediate, source, baseUrl, fetchImpl]);
118
+ if (immediate !== undefined)
119
+ return { config: immediate, loading: false };
120
+ return { config: state.config, loading: !state.done };
121
+ }
122
+ /**
123
+ * An asset's text: inline if given, else fetched from its url (resolved against `baseUrl`).
124
+ * `undefined` while it loads, `null` when it could not be had (or there is none).
125
+ */
126
+ export function useNativeSandboxAsset(asset, baseUrl, fetchImpl) {
127
+ const inline = asset?.inline;
128
+ const url = inline === undefined && asset?.url !== undefined
129
+ ? resolveSandboxUrl(asset.url, baseUrl)
130
+ : undefined;
131
+ const [state, setState] = useState({
132
+ url: undefined,
133
+ text: null,
134
+ });
135
+ useEffect(() => {
136
+ if (url === undefined)
137
+ return;
138
+ let cancelled = false;
139
+ void loadNativeSandboxText(url, fetchImpl).then((text) => {
140
+ if (!cancelled)
141
+ setState({ url, text });
142
+ });
143
+ return () => {
144
+ cancelled = true;
145
+ };
146
+ }, [url, fetchImpl]);
147
+ if (typeof inline === 'string')
148
+ return inline;
149
+ if (url === undefined)
150
+ return null;
151
+ return state.url === url ? state.text : undefined;
152
+ }
153
+ //# sourceMappingURL=sandbox-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-assets.js","sourceRoot":"","sources":["../../../../src/react-native/genui/sandbox-assets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * The host side of a sandbox drawn in a `react-native-webview`, as plain functions: what the
3
+ * WebView may load, what it may say, how the host talks back, the theme it gets. No React Native
4
+ * import here — the renderer (`sandbox.tsx`) wires these to the WebView, the tests call them as is.
5
+ */
6
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
7
+ import { type UiAction } from '../../genui/actions.js';
8
+ import { type SandboxPolicy } from '../../genui/sandbox.js';
9
+ import type { JsonSchema } from '../../genui/schema.js';
10
+ import type { SandboxRefusal } from '../../react/core/genui/sandbox.js';
11
+ /** Whether a URL is the inline sandbox document itself — everything else is a navigation away. */
12
+ export declare function isInlineDocumentUrl(url: unknown): boolean;
13
+ /**
14
+ * `onShouldStartLoadWithRequest`: the inline document loads, nothing else does — no link, no
15
+ * `location = …`, no `window.open`, no `tel:` / `mailto:` / app scheme. (Used with an
16
+ * `originWhitelist` that lets every URL through to it: `react-native-webview` hands a URL the
17
+ * whitelist refuses to `Linking.openURL` — the system browser or another app — instead of dropping it.)
18
+ */
19
+ export declare function shouldStartSandboxLoad(request: {
20
+ url?: unknown;
21
+ }): boolean;
22
+ /** Room for the envelope (`type`, `token`, keys) around a payload in one bridge message. */
23
+ export declare const NATIVE_SANDBOX_ENVELOPE_CHARS = 1024;
24
+ export type FrameMessage =
25
+ /** A message with this frame's token, parsed. */
26
+ {
27
+ kind: 'message';
28
+ data: Record<string, unknown> & {
29
+ type: string;
30
+ };
31
+ }
32
+ /** An `agent.send` with this frame's token, too long to even parse (`bytes`: at least). */
33
+ | {
34
+ kind: 'too-large';
35
+ bytes: number;
36
+ }
37
+ /** Anything else — not a string, too long, not JSON, not an object, no or another token. */
38
+ | {
39
+ kind: 'drop';
40
+ };
41
+ /**
42
+ * Read one `onMessage` string from the WebView. Its length is capped BEFORE it is parsed (the cap
43
+ * is the payload limit plus the envelope: a payload within the limit always fits, as its JSON has at
44
+ * most as many UTF-16 units as UTF-8 bytes); only a JSON object carrying `token` and a frame message
45
+ * type gets through. A send too long to parse is recognised by its envelope's exact prefix — which
46
+ * the bridge writes first — so it is refused as `too-large` rather than dropped unseen.
47
+ */
48
+ export declare function parseFrameMessage(raw: unknown, token: string, maxPayloadBytes: number): FrameMessage;
49
+ /**
50
+ * The script `injectJavaScript` runs to hand the frame one host message: a `message` event whose
51
+ * `source` is the frame's own window — its `parent` (a top-level document is its own parent), the
52
+ * only source the bridge and the JSX runtime listen to. The message is JSON (as a JS literal; the
53
+ * line separators JSON leaves raw are escaped), never code.
54
+ */
55
+ export declare function hostMessageScript(message: Record<string, unknown>): string;
56
+ /** The frame's height: what it measured, within 24 px and the policy's `maxHeight`. */
57
+ export declare function clampSandboxHeight(value: number, policy: SandboxPolicy): number;
58
+ /**
59
+ * The app's design tokens for the frame — what a web host reads off its page's `:root`. `vars` are
60
+ * CSS custom properties (`{ '--primary': '#2563eb' }` or `{ primary: '#2563eb' }`); `dark` sets the
61
+ * frame's `dark` class and `data-theme`; `colorScheme` (`'dark'`, `'light dark'`) is mirrored as
62
+ * `color-scheme` when given.
63
+ */
64
+ export interface NativeSandboxTheme {
65
+ vars: Record<string, string>;
66
+ dark?: boolean;
67
+ colorScheme?: string;
68
+ /** Light/dark attributes for the frame's root (`data-theme`, `data-bs-theme`…), as a web host mirrors its own. */
69
+ attributes?: Record<string, string>;
70
+ }
71
+ /** The theme as the frame takes it: `:root{…}`, light/dark, root attributes, Tailwind's `@theme`. */
72
+ export interface NativeThemeCss {
73
+ css: string;
74
+ dark: boolean;
75
+ attributes: Record<string, string>;
76
+ tailwind: string;
77
+ }
78
+ /** `vars` keyed `--name` (a bare `name` gets its dashes), invalid names and non-strings dropped. */
79
+ export declare function normalizeThemeVars(vars: Record<string, unknown>): Record<string, string>;
80
+ export declare function nativeThemeCss(theme: NativeSandboxTheme): NativeThemeCss;
81
+ /**
82
+ * A url the config names, made absolute against `baseUrl` (React Native has no page origin to
83
+ * resolve it against). Only `http:` / `https:` come out; anything else, or a relative url without
84
+ * an absolute `baseUrl`, is `undefined`.
85
+ */
86
+ export declare function resolveSandboxUrl(url: string, baseUrl: string | undefined): string | undefined;
87
+ /** The count and time of the accepted sends of one frame. */
88
+ export interface SendState {
89
+ count: number;
90
+ last: number;
91
+ }
92
+ export interface SendCheck {
93
+ payload: unknown;
94
+ state: SendState;
95
+ policy: SandboxPolicy;
96
+ /** The view is still being written: what it sends is not the user's yet. */
97
+ incomplete: boolean;
98
+ schema?: StandardSchemaV1 | JsonSchema;
99
+ confirm?: (action: UiAction) => boolean | Promise<boolean>;
100
+ hasHandler: boolean;
101
+ componentId?: string;
102
+ title?: string;
103
+ now?: number;
104
+ }
105
+ /**
106
+ * Everything the web host checks an `agent.send` for, in its order: a preview's send declined, the
107
+ * count, the interval, JSON, the size, `schema`, `confirm`, a handler. The interval clock starts at
108
+ * a send that passed the size check; the count grows only for a delivered action.
109
+ */
110
+ export declare function checkSandboxSend(check: SendCheck): Promise<{
111
+ ok: true;
112
+ action: UiAction;
113
+ } | {
114
+ ok: false;
115
+ refusal: SandboxRefusal;
116
+ }>;
117
+ /** A per-frame token. Not a secret from the frame's own code — it tells this frame's messages apart. */
118
+ export declare function sandboxToken(): string;
119
+ //# sourceMappingURL=sandbox-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-host.d.ts","sourceRoot":"","sources":["../../../../src/react-native/genui/sandbox-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ import { jsonByteLength, sandboxAction, validateUiActionContext, } from '../../genui/actions.js';
2
+ import { SANDBOX_DEFAULTS, SANDBOX_MESSAGE } from '../../genui/sandbox.js';
3
+ import { hostThemeCss, tailwindThemeCss } from '../../genui/sandbox-theme.js';
4
+ /**
5
+ * The only URLs the WebView may be at: the inline document (`source={{ html }}` loads as
6
+ * `about:blank`; `about:srcdoc` for engines that name it so), and in-page `#fragment` jumps.
7
+ */
8
+ const INLINE_DOCUMENT = /^about:(blank|srcdoc)(#.*)?$/i;
9
+ /** Whether a URL is the inline sandbox document itself — everything else is a navigation away. */
10
+ export function isInlineDocumentUrl(url) {
11
+ return typeof url === 'string' && INLINE_DOCUMENT.test(url);
12
+ }
13
+ /**
14
+ * `onShouldStartLoadWithRequest`: the inline document loads, nothing else does — no link, no
15
+ * `location = …`, no `window.open`, no `tel:` / `mailto:` / app scheme. (Used with an
16
+ * `originWhitelist` that lets every URL through to it: `react-native-webview` hands a URL the
17
+ * whitelist refuses to `Linking.openURL` — the system browser or another app — instead of dropping it.)
18
+ */
19
+ export function shouldStartSandboxLoad(request) {
20
+ return isInlineDocumentUrl(request.url);
21
+ }
22
+ /** Room for the envelope (`type`, `token`, keys) around a payload in one bridge message. */
23
+ export const NATIVE_SANDBOX_ENVELOPE_CHARS = 1024;
24
+ /** The frame → host message types a host acts on. */
25
+ const FRAME_TYPES = new Set([
26
+ SANDBOX_MESSAGE.ready,
27
+ SANDBOX_MESSAGE.resize,
28
+ SANDBOX_MESSAGE.send,
29
+ SANDBOX_MESSAGE.error,
30
+ ]);
31
+ /**
32
+ * Read one `onMessage` string from the WebView. Its length is capped BEFORE it is parsed (the cap
33
+ * is the payload limit plus the envelope: a payload within the limit always fits, as its JSON has at
34
+ * most as many UTF-16 units as UTF-8 bytes); only a JSON object carrying `token` and a frame message
35
+ * type gets through. A send too long to parse is recognised by its envelope's exact prefix — which
36
+ * the bridge writes first — so it is refused as `too-large` rather than dropped unseen.
37
+ */
38
+ export function parseFrameMessage(raw, token, maxPayloadBytes) {
39
+ if (typeof raw !== 'string')
40
+ return { kind: 'drop' };
41
+ if (raw.length > maxPayloadBytes + NATIVE_SANDBOX_ENVELOPE_CHARS) {
42
+ const prefix = `{"type":${JSON.stringify(SANDBOX_MESSAGE.send)},"token":${JSON.stringify(token)},"payload":`;
43
+ return raw.startsWith(prefix)
44
+ ? { kind: 'too-large', bytes: raw.length - prefix.length - 1 }
45
+ : { kind: 'drop' };
46
+ }
47
+ let data;
48
+ try {
49
+ data = JSON.parse(raw);
50
+ }
51
+ catch {
52
+ return { kind: 'drop' };
53
+ }
54
+ if (typeof data !== 'object' || data === null || Array.isArray(data))
55
+ return { kind: 'drop' };
56
+ const record = data;
57
+ if (typeof record.token !== 'string' || record.token !== token)
58
+ return { kind: 'drop' };
59
+ if (typeof record.type !== 'string' || !FRAME_TYPES.has(record.type))
60
+ return { kind: 'drop' };
61
+ return { kind: 'message', data: record };
62
+ }
63
+ /**
64
+ * The script `injectJavaScript` runs to hand the frame one host message: a `message` event whose
65
+ * `source` is the frame's own window — its `parent` (a top-level document is its own parent), the
66
+ * only source the bridge and the JSX runtime listen to. The message is JSON (as a JS literal; the
67
+ * line separators JSON leaves raw are escaped), never code.
68
+ */
69
+ export function hostMessageScript(message) {
70
+ const literal = JSON.stringify(message)
71
+ .split(String.fromCharCode(0x2028))
72
+ .join('\\u2028')
73
+ .split(String.fromCharCode(0x2029))
74
+ .join('\\u2029');
75
+ return `(function(){try{window.dispatchEvent(new MessageEvent('message',{data:${literal},source:window}))}catch(e){}})();true;`;
76
+ }
77
+ /** The frame's height: what it measured, within 24 px and the policy's `maxHeight`. */
78
+ export function clampSandboxHeight(value, policy) {
79
+ const max = policy.maxHeight ?? SANDBOX_DEFAULTS.maxHeight;
80
+ return Math.max(24, Math.min(max, Math.ceil(value)));
81
+ }
82
+ const MODE_ATTRIBUTE = /^data-([\w-]*-)?(theme|mode|scheme)$/;
83
+ const VAR_NAME = /^--[A-Za-z0-9_-]+$/;
84
+ /** `vars` keyed `--name` (a bare `name` gets its dashes), invalid names and non-strings dropped. */
85
+ export function normalizeThemeVars(vars) {
86
+ const out = {};
87
+ for (const [key, value] of Object.entries(vars)) {
88
+ const name = key.startsWith('--') ? key : `--${key}`;
89
+ if (!VAR_NAME.test(name))
90
+ continue;
91
+ if (typeof value === 'number')
92
+ out[name] = String(value);
93
+ else if (typeof value === 'string' && value.trim() !== '')
94
+ out[name] = value.trim();
95
+ }
96
+ return out;
97
+ }
98
+ export function nativeThemeCss(theme) {
99
+ const vars = normalizeThemeVars(theme.vars ?? {});
100
+ return {
101
+ css: hostThemeCss(vars, theme.colorScheme !== undefined ? { colorScheme: theme.colorScheme } : {}),
102
+ dark: theme.dark === true,
103
+ attributes: Object.fromEntries(Object.entries(theme.attributes ?? {}).filter(([name, value]) => MODE_ATTRIBUTE.test(name) && typeof value === 'string')),
104
+ tailwind: tailwindThemeCss(vars),
105
+ };
106
+ }
107
+ /**
108
+ * A url the config names, made absolute against `baseUrl` (React Native has no page origin to
109
+ * resolve it against). Only `http:` / `https:` come out; anything else, or a relative url without
110
+ * an absolute `baseUrl`, is `undefined`.
111
+ */
112
+ export function resolveSandboxUrl(url, baseUrl) {
113
+ const absolute = /^https?:\/\/[^/?#]+/i;
114
+ if (absolute.test(url))
115
+ return url;
116
+ if (baseUrl === undefined)
117
+ return undefined;
118
+ const base = absolute.exec(baseUrl);
119
+ if (base === null)
120
+ return undefined;
121
+ const origin = base[0];
122
+ if (url.startsWith('//')) {
123
+ const out = `${origin.slice(0, origin.indexOf(':'))}:${url}`;
124
+ return absolute.test(out) ? out : undefined;
125
+ }
126
+ if (url.startsWith('/'))
127
+ return `${origin}${url}`;
128
+ if (/^[a-z][a-z0-9+.-]*:/i.test(url))
129
+ return undefined;
130
+ const path = baseUrl.slice(origin.length).replace(/[?#].*$/, '');
131
+ const directory = path.endsWith('/') ? path : path.replace(/[^/]*$/, '') || '/';
132
+ return `${origin}${directory.startsWith('/') ? '' : '/'}${directory}${url}`;
133
+ }
134
+ /**
135
+ * Everything the web host checks an `agent.send` for, in its order: a preview's send declined, the
136
+ * count, the interval, JSON, the size, `schema`, `confirm`, a handler. The interval clock starts at
137
+ * a send that passed the size check; the count grows only for a delivered action.
138
+ */
139
+ export async function checkSandboxSend(check) {
140
+ const { state, policy } = check;
141
+ if (check.incomplete)
142
+ return { ok: false, refusal: { reason: 'declined' } };
143
+ const maxSends = policy.maxSends ?? SANDBOX_DEFAULTS.maxSends;
144
+ if (state.count >= maxSends)
145
+ return { ok: false, refusal: { reason: 'too-many', limit: maxSends } };
146
+ const now = check.now ?? Date.now();
147
+ const interval = policy.minSendIntervalMs ?? SANDBOX_DEFAULTS.minSendIntervalMs;
148
+ if (state.last > 0 && now - state.last < interval) {
149
+ return { ok: false, refusal: { reason: 'too-soon', waitMs: interval - (now - state.last) } };
150
+ }
151
+ const bytes = jsonByteLength(check.payload);
152
+ if (bytes === undefined)
153
+ return { ok: false, refusal: { reason: 'not-json' } };
154
+ const limit = policy.maxPayloadBytes ?? SANDBOX_DEFAULTS.maxPayloadBytes;
155
+ if (bytes > limit)
156
+ return { ok: false, refusal: { reason: 'too-large', bytes, limit } };
157
+ state.last = now;
158
+ let action = sandboxAction(check.payload, {
159
+ ...(check.componentId !== undefined ? { componentId: check.componentId } : {}),
160
+ ...(check.title !== undefined ? { title: check.title } : {}),
161
+ });
162
+ if (check.schema !== undefined) {
163
+ const checked = await validateUiActionContext(action, check.schema);
164
+ if (!checked.ok)
165
+ return { ok: false, refusal: { reason: 'invalid', issues: checked.issues } };
166
+ action = { ...action, context: checked.context };
167
+ }
168
+ if (check.confirm !== undefined && !(await check.confirm(action))) {
169
+ return { ok: false, refusal: { reason: 'declined' } };
170
+ }
171
+ if (!check.hasHandler)
172
+ return { ok: false, refusal: { reason: 'no-handler' } };
173
+ state.count += 1;
174
+ return { ok: true, action };
175
+ }
176
+ /** A per-frame token. Not a secret from the frame's own code — it tells this frame's messages apart. */
177
+ export function sandboxToken() {
178
+ const bytes = new Uint8Array(16);
179
+ const crypto = globalThis
180
+ .crypto;
181
+ if (typeof crypto?.getRandomValues === 'function')
182
+ crypto.getRandomValues(bytes);
183
+ else
184
+ for (let index = 0; index < bytes.length; index++)
185
+ bytes[index] = Math.floor(Math.random() * 256);
186
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');
187
+ }
188
+ //# sourceMappingURL=sandbox-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-host.js","sourceRoot":"","sources":["../../../../src/react-native/genui/sandbox-host.ts"],"names":[],"mappings":"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"}