@toon-protocol/views 0.2.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 (206) hide show
  1. package/dist/a2ui/A2UIRenderer.d.ts +47 -0
  2. package/dist/a2ui/A2UIRenderer.d.ts.map +1 -0
  3. package/dist/a2ui/A2UIRenderer.js +106 -0
  4. package/dist/a2ui/A2UIRenderer.js.map +1 -0
  5. package/dist/a2ui/binding.d.ts +46 -0
  6. package/dist/a2ui/binding.d.ts.map +1 -0
  7. package/dist/a2ui/binding.js +111 -0
  8. package/dist/a2ui/binding.js.map +1 -0
  9. package/dist/a2ui/index.d.ts +17 -0
  10. package/dist/a2ui/index.d.ts.map +1 -0
  11. package/dist/a2ui/index.js +17 -0
  12. package/dist/a2ui/index.js.map +1 -0
  13. package/dist/a2ui/types.d.ts +101 -0
  14. package/dist/a2ui/types.d.ts.map +1 -0
  15. package/dist/a2ui/types.js +64 -0
  16. package/dist/a2ui/types.js.map +1 -0
  17. package/dist/a2ui/validate.d.ts +55 -0
  18. package/dist/a2ui/validate.d.ts.map +1 -0
  19. package/dist/a2ui/validate.js +117 -0
  20. package/dist/a2ui/validate.js.map +1 -0
  21. package/dist/app/index.html +246 -0
  22. package/dist/app-bridge/ext-apps-bridge.d.ts +16 -0
  23. package/dist/app-bridge/ext-apps-bridge.d.ts.map +1 -0
  24. package/dist/app-bridge/ext-apps-bridge.js +66 -0
  25. package/dist/app-bridge/ext-apps-bridge.js.map +1 -0
  26. package/dist/app-bridge/types.d.ts +41 -0
  27. package/dist/app-bridge/types.d.ts.map +1 -0
  28. package/dist/app-bridge/types.js +10 -0
  29. package/dist/app-bridge/types.js.map +1 -0
  30. package/dist/app-entry.d.ts +13 -0
  31. package/dist/app-entry.d.ts.map +1 -0
  32. package/dist/app-entry.js +45 -0
  33. package/dist/app-entry.js.map +1 -0
  34. package/dist/atoms/defi.d.ts +3 -0
  35. package/dist/atoms/defi.d.ts.map +1 -0
  36. package/dist/atoms/defi.js +80 -0
  37. package/dist/atoms/defi.js.map +1 -0
  38. package/dist/atoms/fallback.d.ts +4 -0
  39. package/dist/atoms/fallback.d.ts.map +1 -0
  40. package/dist/atoms/fallback.js +15 -0
  41. package/dist/atoms/fallback.js.map +1 -0
  42. package/dist/atoms/forge.d.ts +3 -0
  43. package/dist/atoms/forge.d.ts.map +1 -0
  44. package/dist/atoms/forge.js +50 -0
  45. package/dist/atoms/forge.js.map +1 -0
  46. package/dist/atoms/interactive.d.ts +3 -0
  47. package/dist/atoms/interactive.d.ts.map +1 -0
  48. package/dist/atoms/interactive.js +99 -0
  49. package/dist/atoms/interactive.js.map +1 -0
  50. package/dist/atoms/layout.d.ts +3 -0
  51. package/dist/atoms/layout.d.ts.map +1 -0
  52. package/dist/atoms/layout.js +22 -0
  53. package/dist/atoms/layout.js.map +1 -0
  54. package/dist/atoms/media.d.ts +3 -0
  55. package/dist/atoms/media.d.ts.map +1 -0
  56. package/dist/atoms/media.js +92 -0
  57. package/dist/atoms/media.js.map +1 -0
  58. package/dist/atoms/onboard.d.ts +3 -0
  59. package/dist/atoms/onboard.d.ts.map +1 -0
  60. package/dist/atoms/onboard.js +26 -0
  61. package/dist/atoms/onboard.js.map +1 -0
  62. package/dist/atoms/registry.d.ts +35 -0
  63. package/dist/atoms/registry.d.ts.map +1 -0
  64. package/dist/atoms/registry.js +77 -0
  65. package/dist/atoms/registry.js.map +1 -0
  66. package/dist/atoms/social.d.ts +3 -0
  67. package/dist/atoms/social.d.ts.map +1 -0
  68. package/dist/atoms/social.js +52 -0
  69. package/dist/atoms/social.js.map +1 -0
  70. package/dist/atoms/types.d.ts +72 -0
  71. package/dist/atoms/types.d.ts.map +1 -0
  72. package/dist/atoms/types.js +11 -0
  73. package/dist/atoms/types.js.map +1 -0
  74. package/dist/catalog.d.ts +27 -0
  75. package/dist/catalog.d.ts.map +1 -0
  76. package/dist/catalog.js +121 -0
  77. package/dist/catalog.js.map +1 -0
  78. package/dist/components/mono-id.d.ts +16 -0
  79. package/dist/components/mono-id.d.ts.map +1 -0
  80. package/dist/components/mono-id.js +18 -0
  81. package/dist/components/mono-id.js.map +1 -0
  82. package/dist/components/ui/avatar.d.ts +12 -0
  83. package/dist/components/ui/avatar.d.ts.map +1 -0
  84. package/dist/components/ui/avatar.js +25 -0
  85. package/dist/components/ui/avatar.js.map +1 -0
  86. package/dist/components/ui/badge.d.ts +10 -0
  87. package/dist/components/ui/badge.d.ts.map +1 -0
  88. package/dist/components/ui/badge.js +26 -0
  89. package/dist/components/ui/badge.js.map +1 -0
  90. package/dist/components/ui/button.d.ts +11 -0
  91. package/dist/components/ui/button.d.ts.map +1 -0
  92. package/dist/components/ui/button.js +37 -0
  93. package/dist/components/ui/button.js.map +1 -0
  94. package/dist/components/ui/input.d.ts +4 -0
  95. package/dist/components/ui/input.d.ts.map +1 -0
  96. package/dist/components/ui/input.js +8 -0
  97. package/dist/components/ui/input.js.map +1 -0
  98. package/dist/components/ui/separator.d.ts +5 -0
  99. package/dist/components/ui/separator.d.ts.map +1 -0
  100. package/dist/components/ui/separator.js +9 -0
  101. package/dist/components/ui/separator.js.map +1 -0
  102. package/dist/components/ui/textarea.d.ts +4 -0
  103. package/dist/components/ui/textarea.d.ts.map +1 -0
  104. package/dist/components/ui/textarea.js +8 -0
  105. package/dist/components/ui/textarea.js.map +1 -0
  106. package/dist/examples.d.ts +39 -0
  107. package/dist/examples.d.ts.map +1 -0
  108. package/dist/examples.js +168 -0
  109. package/dist/examples.js.map +1 -0
  110. package/dist/filters.d.ts +40 -0
  111. package/dist/filters.d.ts.map +1 -0
  112. package/dist/filters.js +84 -0
  113. package/dist/filters.js.map +1 -0
  114. package/dist/index.d.ts +18 -0
  115. package/dist/index.d.ts.map +1 -0
  116. package/dist/index.js +18 -0
  117. package/dist/index.js.map +1 -0
  118. package/dist/lib/cn.d.ts +4 -0
  119. package/dist/lib/cn.d.ts.map +1 -0
  120. package/dist/lib/cn.js +7 -0
  121. package/dist/lib/cn.js.map +1 -0
  122. package/dist/lib/utils.d.ts +3 -0
  123. package/dist/lib/utils.d.ts.map +1 -0
  124. package/dist/lib/utils.js +6 -0
  125. package/dist/lib/utils.js.map +1 -0
  126. package/dist/main.d.ts +3 -0
  127. package/dist/main.d.ts.map +1 -0
  128. package/dist/main.js +7 -0
  129. package/dist/main.js.map +1 -0
  130. package/dist/mcp-ui/ConsentPrompt.d.ts +41 -0
  131. package/dist/mcp-ui/ConsentPrompt.d.ts.map +1 -0
  132. package/dist/mcp-ui/ConsentPrompt.js +45 -0
  133. package/dist/mcp-ui/ConsentPrompt.js.map +1 -0
  134. package/dist/mcp-ui/SandboxedAppRenderer.d.ts +54 -0
  135. package/dist/mcp-ui/SandboxedAppRenderer.d.ts.map +1 -0
  136. package/dist/mcp-ui/SandboxedAppRenderer.js +74 -0
  137. package/dist/mcp-ui/SandboxedAppRenderer.js.map +1 -0
  138. package/dist/mcp-ui/index.d.ts +18 -0
  139. package/dist/mcp-ui/index.d.ts.map +1 -0
  140. package/dist/mcp-ui/index.js +18 -0
  141. package/dist/mcp-ui/index.js.map +1 -0
  142. package/dist/mcp-ui/sandbox.d.ts +62 -0
  143. package/dist/mcp-ui/sandbox.d.ts.map +1 -0
  144. package/dist/mcp-ui/sandbox.js +78 -0
  145. package/dist/mcp-ui/sandbox.js.map +1 -0
  146. package/dist/parsers/media.d.ts +68 -0
  147. package/dist/parsers/media.d.ts.map +1 -0
  148. package/dist/parsers/media.js +124 -0
  149. package/dist/parsers/media.js.map +1 -0
  150. package/dist/parsers/nip34.d.ts +75 -0
  151. package/dist/parsers/nip34.d.ts.map +1 -0
  152. package/dist/parsers/nip34.js +142 -0
  153. package/dist/parsers/nip34.js.map +1 -0
  154. package/dist/parsers/social.d.ts +89 -0
  155. package/dist/parsers/social.d.ts.map +1 -0
  156. package/dist/parsers/social.js +136 -0
  157. package/dist/parsers/social.js.map +1 -0
  158. package/dist/render/node-shims/node-builtins.d.ts +30 -0
  159. package/dist/render/node-shims/node-builtins.d.ts.map +1 -0
  160. package/dist/render/node-shims/node-builtins.js +38 -0
  161. package/dist/render/node-shims/node-builtins.js.map +1 -0
  162. package/dist/render/resolve.d.ts +72 -0
  163. package/dist/render/resolve.d.ts.map +1 -0
  164. package/dist/render/resolve.js +115 -0
  165. package/dist/render/resolve.js.map +1 -0
  166. package/dist/runtime.d.ts +17 -0
  167. package/dist/runtime.d.ts.map +1 -0
  168. package/dist/runtime.js +218 -0
  169. package/dist/runtime.js.map +1 -0
  170. package/dist/server/apps-server.d.ts +32 -0
  171. package/dist/server/apps-server.d.ts.map +1 -0
  172. package/dist/server/apps-server.js +163 -0
  173. package/dist/server/apps-server.js.map +1 -0
  174. package/dist/server/backend.d.ts +148 -0
  175. package/dist/server/backend.d.ts.map +1 -0
  176. package/dist/server/backend.js +11 -0
  177. package/dist/server/backend.js.map +1 -0
  178. package/dist/server/daemon-backend.d.ts +113 -0
  179. package/dist/server/daemon-backend.d.ts.map +1 -0
  180. package/dist/server/daemon-backend.js +79 -0
  181. package/dist/server/daemon-backend.js.map +1 -0
  182. package/dist/server/daemon-main.d.ts +25 -0
  183. package/dist/server/daemon-main.d.ts.map +1 -0
  184. package/dist/server/daemon-main.js +165 -0
  185. package/dist/server/daemon-main.js.map +1 -0
  186. package/dist/server/fake-backend.d.ts +53 -0
  187. package/dist/server/fake-backend.d.ts.map +1 -0
  188. package/dist/server/fake-backend.js +157 -0
  189. package/dist/server/fake-backend.js.map +1 -0
  190. package/dist/server/fake-main.d.ts +15 -0
  191. package/dist/server/fake-main.d.ts.map +1 -0
  192. package/dist/server/fake-main.js +39 -0
  193. package/dist/server/fake-main.js.map +1 -0
  194. package/dist/spec.d.ts +67 -0
  195. package/dist/spec.d.ts.map +1 -0
  196. package/dist/spec.js +221 -0
  197. package/dist/spec.js.map +1 -0
  198. package/dist/tool-names.d.ts +27 -0
  199. package/dist/tool-names.d.ts.map +1 -0
  200. package/dist/tool-names.js +32 -0
  201. package/dist/tool-names.js.map +1 -0
  202. package/dist/types.d.ts +39 -0
  203. package/dist/types.d.ts.map +1 -0
  204. package/dist/types.js +20 -0
  205. package/dist/types.js.map +1 -0
  206. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filters.js","sourceRoot":"","sources":["../src/filters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @toon-protocol/views — shared kind→atom registry, NIP parsers, filter
3
+ * builders, and the ViewSpec composition language. Consumed by `rig` and the
4
+ * `toon-mcp` apps surface.
5
+ *
6
+ * The React atoms + iframe runtime (atoms/, runtime, app-bridge, app-entry) are
7
+ * built separately into the MCP-app bundle and are not part of this Node barrel.
8
+ */
9
+ export * from './types.js';
10
+ export * from './filters.js';
11
+ export * from './spec.js';
12
+ export * from './catalog.js';
13
+ export * from './tool-names.js';
14
+ export * from './examples.js';
15
+ export * from './parsers/nip34.js';
16
+ export * from './parsers/social.js';
17
+ export * from './parsers/media.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @toon-protocol/views — shared kind→atom registry, NIP parsers, filter
3
+ * builders, and the ViewSpec composition language. Consumed by `rig` and the
4
+ * `toon-mcp` apps surface.
5
+ *
6
+ * The React atoms + iframe runtime (atoms/, runtime, app-bridge, app-entry) are
7
+ * built separately into the MCP-app bundle and are not part of this Node barrel.
8
+ */
9
+ export * from './types.js';
10
+ export * from './filters.js';
11
+ export * from './spec.js';
12
+ export * from './catalog.js';
13
+ export * from './tool-names.js';
14
+ export * from './examples.js';
15
+ export * from './parsers/nip34.js';
16
+ export * from './parsers/social.js';
17
+ export * from './parsers/media.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ClassValue } from 'clsx';
2
+ /** Tailwind-aware className combiner (clsx + tailwind-merge). */
3
+ export declare function cn(...inputs: ClassValue[]): string;
4
+ //# sourceMappingURL=cn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../../src/lib/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAG7C,iEAAiE;AACjE,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAElD"}
package/dist/lib/cn.js ADDED
@@ -0,0 +1,7 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ /** Tailwind-aware className combiner (clsx + tailwind-merge). */
4
+ export function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+ //# sourceMappingURL=cn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.js","sourceRoot":"","sources":["../../src/lib/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,iEAAiE;AACjE,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
@@ -0,0 +1,6 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }
6
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ /** Browser bundle entry: mount the MCP-app runtime into #root. */
2
+ import './globals.css';
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,eAAe,CAAC"}
package/dist/main.js ADDED
@@ -0,0 +1,7 @@
1
+ /** Browser bundle entry: mount the MCP-app runtime into #root. */
2
+ import './globals.css';
3
+ import { mount } from './app-entry.js';
4
+ const root = document.getElementById('root');
5
+ if (root)
6
+ mount(root);
7
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AAC7C,IAAI,IAAI;IAAE,KAAK,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * ConsentPrompt — the TRUSTED authorization surface for branch 3 (sandboxed
3
+ * mcp-ui, low trust) of the NIP-on-TOON render trust gradient (toon-meta#58,
4
+ * toon-client#90).
5
+ *
6
+ * ── The consent invariant ───────────────────────────────────────────────────
7
+ * A sandboxed widget may only *request* an action; it may never *perform* one,
8
+ * and it may never draw, style, or spoof the authorization UI. This component IS
9
+ * that authorization UI. It is rendered by the trusted client OUTSIDE the
10
+ * widget's iframe, using only the client's own audited primitives (`Button`,
11
+ * `Badge`, `Separator`). It is non-themeable by construction:
12
+ *
13
+ * 1. Its ONLY input is a `ConsentRequest` from `@toon-protocol/client`, whose
14
+ * type has nowhere to carry styling/markup — only a tool name, plain
15
+ * arguments, and a client-fixed `trust: 'low'`.
16
+ * 2. The tool name and arguments are rendered as TEXT (`{value}` /
17
+ * `JSON.stringify`), never as HTML — no `dangerouslySetInnerHTML`, ever.
18
+ * 3. The grant/deny buttons and all chrome use fixed, client-owned classes;
19
+ * the widget supplies no className, style, color, or label.
20
+ *
21
+ * A widget that could paint this surface would collapse the whole trust gradient
22
+ * to its lowest tier, so this file must never accept presentation input from
23
+ * widget-controlled data. (See `consent.ts` in `@toon-protocol/client`.)
24
+ */
25
+ import { type FC } from 'react';
26
+ import { type ConsentRequest, type ConsentDecision } from '@toon-protocol/client/render';
27
+ export interface ConsentPromptProps {
28
+ /**
29
+ * The request to authorize, built by the trusted client
30
+ * (`buildConsentRequest`) from a widget intent. Carries no presentation data.
31
+ */
32
+ request: ConsentRequest;
33
+ /** Resolve the prompt with the user's decision. */
34
+ onResolve: (decision: ConsentDecision) => void;
35
+ }
36
+ /**
37
+ * The host-rendered authorization prompt. Always drawn outside the widget
38
+ * iframe, in fixed trusted chrome the widget cannot influence.
39
+ */
40
+ export declare const ConsentPrompt: FC<ConsentPromptProps>;
41
+ //# sourceMappingURL=ConsentPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentPrompt.d.ts","sourceRoot":"","sources":["../../src/mcp-ui/ConsentPrompt.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAKzF,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB,mDAAmD;IACnD,SAAS,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;CAChD;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAuEhD,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ConsentPrompt — the TRUSTED authorization surface for branch 3 (sandboxed
4
+ * mcp-ui, low trust) of the NIP-on-TOON render trust gradient (toon-meta#58,
5
+ * toon-client#90).
6
+ *
7
+ * ── The consent invariant ───────────────────────────────────────────────────
8
+ * A sandboxed widget may only *request* an action; it may never *perform* one,
9
+ * and it may never draw, style, or spoof the authorization UI. This component IS
10
+ * that authorization UI. It is rendered by the trusted client OUTSIDE the
11
+ * widget's iframe, using only the client's own audited primitives (`Button`,
12
+ * `Badge`, `Separator`). It is non-themeable by construction:
13
+ *
14
+ * 1. Its ONLY input is a `ConsentRequest` from `@toon-protocol/client`, whose
15
+ * type has nowhere to carry styling/markup — only a tool name, plain
16
+ * arguments, and a client-fixed `trust: 'low'`.
17
+ * 2. The tool name and arguments are rendered as TEXT (`{value}` /
18
+ * `JSON.stringify`), never as HTML — no `dangerouslySetInnerHTML`, ever.
19
+ * 3. The grant/deny buttons and all chrome use fixed, client-owned classes;
20
+ * the widget supplies no className, style, color, or label.
21
+ *
22
+ * A widget that could paint this surface would collapse the whole trust gradient
23
+ * to its lowest tier, so this file must never accept presentation input from
24
+ * widget-controlled data. (See `consent.ts` in `@toon-protocol/client`.)
25
+ */
26
+ import {} from 'react';
27
+ import {} from '@toon-protocol/client/render';
28
+ import { Button } from '@/components/ui/button.js';
29
+ import { Badge } from '@/components/ui/badge.js';
30
+ import { Separator } from '@/components/ui/separator.js';
31
+ /**
32
+ * The host-rendered authorization prompt. Always drawn outside the widget
33
+ * iframe, in fixed trusted chrome the widget cannot influence.
34
+ */
35
+ export const ConsentPrompt = ({ request, onResolve }) => {
36
+ // Render arguments as inspectable TEXT — never as markup. A widget cannot
37
+ // inject HTML/script through them because they are stringified, not dangerously
38
+ // set.
39
+ const argsText = JSON.stringify(request.arguments, null, 2);
40
+ return (_jsxs("div", { role: "alertdialog", "aria-modal": "true", "aria-label": "Authorize action requested by an untrusted widget", "data-consent-prompt": true, "data-trust": request.trust,
41
+ // Fixed, client-owned chrome. No className/style is ever taken from the
42
+ // widget — the props type cannot supply one.
43
+ className: "flex flex-col gap-3 rounded-lg border border-destructive/40 bg-card p-4 text-card-foreground shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: "destructive", "data-consent-trust-badge": true, children: "untrusted widget" }), _jsx("span", { className: "text-sm font-semibold", children: "Authorize action" })] }), _jsx("p", { className: "text-sm text-muted-foreground", children: "A sandboxed widget is requesting to run an action on your behalf. This prompt is drawn by your client \u2014 the widget cannot change how it looks." }), _jsx(Separator, {}), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Tool" }), _jsx("code", { "data-consent-tool": true, className: "rounded bg-muted px-1.5 py-0.5 text-xs", children: request.toolName })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Arguments" }), _jsx("pre", { "data-consent-args": true, className: "max-h-40 overflow-auto rounded bg-muted px-2 py-1.5 text-xs whitespace-pre-wrap break-words", children: argsText })] }), _jsx(Separator, {}), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", "data-consent-deny": true, onClick: () => onResolve('deny'), children: "Deny" }), _jsx(Button, { variant: "destructive", size: "sm", "data-consent-grant": true, onClick: () => onResolve('grant'), children: "Authorize" })] })] }));
44
+ };
45
+ //# sourceMappingURL=ConsentPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentPrompt.js","sourceRoot":"","sources":["../../src/mcp-ui/ConsentPrompt.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAW,MAAM,OAAO,CAAC;AAChC,OAAO,EAA6C,MAAM,8BAA8B,CAAC;AACzF,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAYzD;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2B,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE;IAC9E,0EAA0E;IAC1E,gFAAgF;IAChF,OAAO;IACP,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAE5D,OAAO,CACL,eACE,IAAI,EAAC,aAAa,gBACP,MAAM,gBACN,mDAAmD,6CAElD,OAAO,CAAC,KAAK;QACzB,wEAAwE;QACxE,6CAA6C;QAC7C,SAAS,EAAC,wGAAwG,aAElH,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,KAAK,IAAC,OAAO,EAAC,aAAa,mEAEpB,EACR,eAAM,SAAS,EAAC,uBAAuB,iCAAwB,IAC3D,EAEN,YAAG,SAAS,EAAC,+BAA+B,oKAGxC,EAEJ,KAAC,SAAS,KAAG,EAEb,eAAK,SAAS,EAAC,qBAAqB,aAClC,eAAM,SAAS,EAAC,2CAA2C,qBAAY,EAEvE,0CAAwB,SAAS,EAAC,wCAAwC,YACvE,OAAO,CAAC,QAAQ,GACZ,IACH,EAEN,eAAK,SAAS,EAAC,qBAAqB,aAClC,eAAM,SAAS,EAAC,2CAA2C,0BAAiB,EAC5E,yCAEE,SAAS,EAAC,6FAA6F,YAEtG,QAAQ,GACL,IACF,EAEN,KAAC,SAAS,KAAG,EAEb,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,6BAET,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,qBAGzB,EACT,KAAC,MAAM,IACL,OAAO,EAAC,aAAa,EACrB,IAAI,EAAC,IAAI,8BAET,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,0BAG1B,IACL,IACF,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SandboxedAppRenderer — branch 3 of the NIP-on-TOON render trust gradient
3
+ * (sandboxed mcp-ui, LOW trust). toon-meta#58, toon-client#90.
4
+ *
5
+ * Renders an untrusted raw widget (the `kind:31036` renderer's HTML, carried as
6
+ * a `UIResource` with `m: text/html;profile=mcp-app`) inside a hardened,
7
+ * sandboxed iframe via `@mcp-ui/client`'s `AppRenderer`. The widget may only
8
+ * *request* actions over the mcp-ui bridge; this component enforces the consent
9
+ * invariant by routing every requested action to a HOST-rendered, non-themeable
10
+ * {@link ConsentPrompt} drawn OUTSIDE the iframe.
11
+ *
12
+ * Data flow of a widget-requested action:
13
+ *
14
+ * widget (iframe) --tools/call--> AppRenderer.onCallTool (this file)
15
+ * │ │
16
+ * │ classifyIntent (trusted client)
17
+ * │ ├─ 'auto' → forward to onCallTool callback
18
+ * │ └─ 'requires-consent' → render ConsentPrompt OUTSIDE
19
+ * │ the iframe; await user
20
+ * │ ▼
21
+ * └──────── result / "denied" error ◄─┘ (widget NEVER performs the action)
22
+ *
23
+ * The widget cannot draw, style, suppress, or auto-approve the prompt: the
24
+ * prompt is React state owned by THIS component, rendered with the client's own
25
+ * audited primitives, and its only data input (`ConsentRequest`) carries no
26
+ * presentation fields. See `ConsentPrompt.tsx` and `consent.ts`.
27
+ */
28
+ import { type FC } from 'react';
29
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
30
+ import { type UiResource } from '@toon-protocol/client/render';
31
+ /** A host callback that actually performs an authorized tool call. */
32
+ export type PerformTool = (toolName: string, args: Record<string, unknown>) => Promise<CallToolResult>;
33
+ export interface SandboxedAppRendererProps {
34
+ /**
35
+ * The untrusted widget to render, extracted from the branch-3 `kind:31036`
36
+ * renderer by `@toon-protocol/client`'s `extractUiResource`.
37
+ */
38
+ resource: UiResource;
39
+ /**
40
+ * URL of the mcp-ui sandbox proxy HTML. Required by `@mcp-ui/client`'s
41
+ * `AppRenderer` so the widget runs in an opaque, cross-origin frame.
42
+ */
43
+ sandboxUrl: URL;
44
+ /** Logical tool name for the rendered widget (mcp-ui bookkeeping). */
45
+ toolName?: string;
46
+ /**
47
+ * Perform an AUTHORIZED tool call. Invoked only after the consent gate passes
48
+ * (auto-forward for read-only tools, or an explicit user grant otherwise).
49
+ * Wire this to the trusted client's tool runner.
50
+ */
51
+ onPerform: PerformTool;
52
+ }
53
+ export declare const SandboxedAppRenderer: FC<SandboxedAppRendererProps>;
54
+ //# sourceMappingURL=SandboxedAppRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SandboxedAppRenderer.d.ts","sourceRoot":"","sources":["../../src/mcp-ui/SandboxedAppRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAyB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAEvD,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC1F,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,8BAA8B,CAAC;AAItC,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,QAAQ,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,UAAU,EAAE,GAAG,CAAC;IAChB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE,WAAW,CAAC;CACxB;AAgBD,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAmE9D,CAAC"}
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SandboxedAppRenderer — branch 3 of the NIP-on-TOON render trust gradient
4
+ * (sandboxed mcp-ui, LOW trust). toon-meta#58, toon-client#90.
5
+ *
6
+ * Renders an untrusted raw widget (the `kind:31036` renderer's HTML, carried as
7
+ * a `UIResource` with `m: text/html;profile=mcp-app`) inside a hardened,
8
+ * sandboxed iframe via `@mcp-ui/client`'s `AppRenderer`. The widget may only
9
+ * *request* actions over the mcp-ui bridge; this component enforces the consent
10
+ * invariant by routing every requested action to a HOST-rendered, non-themeable
11
+ * {@link ConsentPrompt} drawn OUTSIDE the iframe.
12
+ *
13
+ * Data flow of a widget-requested action:
14
+ *
15
+ * widget (iframe) --tools/call--> AppRenderer.onCallTool (this file)
16
+ * │ │
17
+ * │ classifyIntent (trusted client)
18
+ * │ ├─ 'auto' → forward to onCallTool callback
19
+ * │ └─ 'requires-consent' → render ConsentPrompt OUTSIDE
20
+ * │ the iframe; await user
21
+ * │ ▼
22
+ * └──────── result / "denied" error ◄─┘ (widget NEVER performs the action)
23
+ *
24
+ * The widget cannot draw, style, suppress, or auto-approve the prompt: the
25
+ * prompt is React state owned by THIS component, rendered with the client's own
26
+ * audited primitives, and its only data input (`ConsentRequest`) carries no
27
+ * presentation fields. See `ConsentPrompt.tsx` and `consent.ts`.
28
+ */
29
+ import { useCallback, useState } from 'react';
30
+ import { AppRenderer } from '@mcp-ui/client';
31
+ import { buildConsentRequest, classifyIntent, } from '@toon-protocol/client/render';
32
+ import { ConsentPrompt } from './ConsentPrompt.js';
33
+ import { assertSafeSandbox, BRANCH3_SANDBOX_PERMISSIONS } from './sandbox.js';
34
+ /** A `CallToolResult` representing a host-side denial (the widget never acts). */
35
+ function deniedResult(toolName) {
36
+ return {
37
+ isError: true,
38
+ content: [{ type: 'text', text: `Action "${toolName}" was not authorized by the user.` }],
39
+ };
40
+ }
41
+ export const SandboxedAppRenderer = ({ resource, sandboxUrl, toolName = 'mcp-app-widget', onPerform, }) => {
42
+ const [pending, setPending] = useState(null);
43
+ // Belt-and-braces: never render with a sandbox that re-enables an escape token.
44
+ assertSafeSandbox(BRANCH3_SANDBOX_PERMISSIONS);
45
+ /**
46
+ * The iframe → host intent channel. `@mcp-ui/client` calls this for every
47
+ * `tools/call` the widget requests. We classify it; auto-forward read-only
48
+ * intents; and for everything else render the host consent prompt and await
49
+ * the user's decision before performing (or denying) the action.
50
+ */
51
+ const onCallTool = useCallback(async (params) => {
52
+ const intent = {
53
+ toolName: params.name,
54
+ arguments: (params.arguments ?? {}),
55
+ };
56
+ if (classifyIntent(intent) === 'auto') {
57
+ return onPerform(intent.toolName, intent.arguments);
58
+ }
59
+ // requires-consent: surface a HOST-rendered prompt outside the iframe and
60
+ // block on the user's decision. The widget cannot resolve this itself.
61
+ const decision = await new Promise((resolve) => {
62
+ setPending({ request: buildConsentRequest(intent), resolve });
63
+ });
64
+ setPending(null);
65
+ if (decision !== 'grant')
66
+ return deniedResult(intent.toolName);
67
+ return onPerform(intent.toolName, intent.arguments);
68
+ }, [onPerform]);
69
+ return (_jsxs("div", { "data-branch": "mcp-ui", "data-trust": "low", className: "flex flex-col gap-3", children: [_jsx(AppRenderer, { toolName: toolName, html: resource.html, sandbox: { url: sandboxUrl, permissions: BRANCH3_SANDBOX_PERMISSIONS }, onCallTool: onCallTool,
70
+ // Open-link requests are likewise just *requests*; deny by default —
71
+ // the widget cannot navigate the host.
72
+ onOpenLink: async () => ({}) }), pending !== null && (_jsx(ConsentPrompt, { request: pending.request, onResolve: pending.resolve }))] }));
73
+ };
74
+ //# sourceMappingURL=SandboxedAppRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SandboxedAppRenderer.js","sourceRoot":"","sources":["../../src/mcp-ui/SandboxedAppRenderer.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAW,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACL,mBAAmB,EACnB,cAAc,GAIf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAmC9E,kFAAkF;AAClF,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,QAAQ,mCAAmC,EAAE,CAAC;KAC1F,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAkC,CAAC,EAClE,QAAQ,EACR,UAAU,EACV,QAAQ,GAAG,gBAAgB,EAC3B,SAAS,GACV,EAAE,EAAE;IACH,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAC;IAEpE,gFAAgF;IAChF,iBAAiB,CAAC,2BAA2B,CAAC,CAAC;IAE/C;;;;;OAKG;IACH,MAAM,UAAU,GAAG,WAAW,CAC5B,KAAK,EAAE,MAAiC,EAA2B,EAAE;QACnE,MAAM,MAAM,GAAG;YACb,QAAQ,EAAE,MAAM,CAAC,IAAI;YACrB,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAA4B;SAC/D,CAAC;QAEF,IAAI,cAAc,CAAC,MAAM,CAAC,KAAK,MAAM,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACtD,CAAC;QAED,0EAA0E;QAC1E,uEAAuE;QACvE,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,EAAE;YAC9D,UAAU,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,IAAI,CAAC,CAAC;QAEjB,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/D,OAAO,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC,EACD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,OAAO,CACL,8BAAiB,QAAQ,gBAAY,KAAK,EAAC,SAAS,EAAC,qBAAqB,aAMxE,KAAC,WAAW,IACV,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,QAAQ,CAAC,IAAI,EACnB,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,2BAA2B,EAAE,EACtE,UAAU,EAAE,UAAU;gBACtB,qEAAqE;gBACrE,uCAAuC;gBACvC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,GAC5B,EAMD,OAAO,KAAK,IAAI,IAAI,CACnB,KAAC,aAAa,IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,GAAI,CACxE,IACG,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Branch 3 — sandboxed mcp-ui renderer (LOW trust) for the NIP-on-TOON render
3
+ * trust gradient (toon-meta#58, toon-client#90).
4
+ *
5
+ * Renders an untrusted raw widget inside a hardened sandboxed iframe via
6
+ * `@mcp-ui/client`'s `AppRenderer`, and enforces the consent invariant: every
7
+ * action the widget *requests* is routed to a host-rendered, non-themeable
8
+ * {@link ConsentPrompt} drawn OUTSIDE the iframe — the widget can only request,
9
+ * never perform, and can never paint the authorization UI.
10
+ *
11
+ * The React components are part of the views *app bundle* (React), not the Node
12
+ * barrel, so they are exported from here rather than `src/index.ts` (mirroring
13
+ * the branch-2 A2UI renderer).
14
+ */
15
+ export { SandboxedAppRenderer, type SandboxedAppRendererProps, type PerformTool, } from './SandboxedAppRenderer.js';
16
+ export { ConsentPrompt, type ConsentPromptProps } from './ConsentPrompt.js';
17
+ export { BRANCH3_SANDBOX_PERMISSIONS, BRANCH3_SANDBOX_TOKENS, FORBIDDEN_SANDBOX_TOKENS, DEFAULT_MCP_UI_SANDBOX_URL, assertSafeSandbox, } from './sandbox.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp-ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,KAAK,WAAW,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Branch 3 — sandboxed mcp-ui renderer (LOW trust) for the NIP-on-TOON render
3
+ * trust gradient (toon-meta#58, toon-client#90).
4
+ *
5
+ * Renders an untrusted raw widget inside a hardened sandboxed iframe via
6
+ * `@mcp-ui/client`'s `AppRenderer`, and enforces the consent invariant: every
7
+ * action the widget *requests* is routed to a host-rendered, non-themeable
8
+ * {@link ConsentPrompt} drawn OUTSIDE the iframe — the widget can only request,
9
+ * never perform, and can never paint the authorization UI.
10
+ *
11
+ * The React components are part of the views *app bundle* (React), not the Node
12
+ * barrel, so they are exported from here rather than `src/index.ts` (mirroring
13
+ * the branch-2 A2UI renderer).
14
+ */
15
+ export { SandboxedAppRenderer, } from './SandboxedAppRenderer.js';
16
+ export { ConsentPrompt } from './ConsentPrompt.js';
17
+ export { BRANCH3_SANDBOX_PERMISSIONS, BRANCH3_SANDBOX_TOKENS, FORBIDDEN_SANDBOX_TOKENS, DEFAULT_MCP_UI_SANDBOX_URL, assertSafeSandbox, } from './sandbox.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp-ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,oBAAoB,GAGrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Hardened sandbox configuration for branch 3 (sandboxed mcp-ui, low trust) of
3
+ * the NIP-on-TOON render trust gradient (toon-meta#58, toon-client#90).
4
+ *
5
+ * The branch-3 widget is UNTRUSTED renderer code shipped as raw HTML by a
6
+ * `kind:31036` event with `m: text/html;profile=mcp-app`. It is confined to an
7
+ * iframe whose `sandbox` attribute is locked down here. The single most
8
+ * important hardening is dropping `allow-same-origin`: without it the iframe
9
+ * runs in an opaque origin, so the widget cannot reach the host's cookies,
10
+ * `localStorage`, `IndexedDB`, or same-origin DOM — and therefore cannot read or
11
+ * repaint the host-rendered consent surface.
12
+ *
13
+ * `@mcp-ui/client`'s default sandbox permission string is
14
+ * `"allow-scripts allow-same-origin allow-forms"`. We deliberately OVERRIDE it
15
+ * to a stricter allowlist with NO `allow-same-origin` and NO top-navigation /
16
+ * popup escapes.
17
+ */
18
+ /**
19
+ * The locked-down iframe `sandbox` attribute for an untrusted branch-3 widget.
20
+ *
21
+ * Granted:
22
+ * - `allow-scripts` — the widget needs JS to render and to *request* actions
23
+ * over the postMessage bridge. (With `allow-scripts` but WITHOUT
24
+ * `allow-same-origin`, the iframe is a hostile, isolated origin — exactly
25
+ * what we want.)
26
+ *
27
+ * Withheld (each one is a consent-invariant escape if granted):
28
+ * - `allow-same-origin` — would give the widget the host's origin and
29
+ * thus access to the host DOM / storage; it
30
+ * could then read or overdraw the consent UI.
31
+ * - `allow-top-navigation`* — would let the widget navigate the top frame
32
+ * away (phishing / consent bypass).
33
+ * - `allow-popups`* — would let the widget open windows it controls.
34
+ * - `allow-modals` — would let the widget raise `alert/confirm`
35
+ * dialogs that could be mistaken for host chrome.
36
+ * - `allow-forms` — not needed; widget requests ride the bridge.
37
+ * - `allow-pointer-lock` / `allow-presentation` — UI-capture vectors.
38
+ */
39
+ export declare const BRANCH3_SANDBOX_PERMISSIONS: "allow-scripts";
40
+ /**
41
+ * The default cross-origin mcp-ui sandbox proxy URL. `@mcp-ui/client`'s
42
+ * `AppRenderer` loads this opaque-origin proxy HTML to host the widget iframe, so
43
+ * the widget runs in a foreign origin it cannot escape (no `allow-same-origin`).
44
+ *
45
+ * This is the canonical mcp-ui hosted proxy; a host that self-hosts the proxy can
46
+ * pass its own `URL` to {@link import('./SandboxedAppRenderer.js').SandboxedAppRenderer}.
47
+ */
48
+ export declare const DEFAULT_MCP_UI_SANDBOX_URL: "https://sandbox.mcpui.dev";
49
+ /**
50
+ * The iframe `sandbox` tokens, as a frozen array, for assertion in tests and
51
+ * for callers that prefer a list over the space-joined string.
52
+ */
53
+ export declare const BRANCH3_SANDBOX_TOKENS: readonly string[];
54
+ /** Tokens that MUST NEVER appear in a branch-3 sandbox (each breaks the invariant). */
55
+ export declare const FORBIDDEN_SANDBOX_TOKENS: readonly string[];
56
+ /**
57
+ * Assert that a sandbox permission string is safe for branch 3. Throws if any
58
+ * forbidden token is present. Defensive belt-and-braces so a future edit can't
59
+ * silently re-enable `allow-same-origin`.
60
+ */
61
+ export declare function assertSafeSandbox(permissions: string): void;
62
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/mcp-ui/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,2BAA2B,EAAG,eAAwB,CAAC;AAEpE;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAG,2BAAoC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAEnD,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EASpD,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAS3D"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Hardened sandbox configuration for branch 3 (sandboxed mcp-ui, low trust) of
3
+ * the NIP-on-TOON render trust gradient (toon-meta#58, toon-client#90).
4
+ *
5
+ * The branch-3 widget is UNTRUSTED renderer code shipped as raw HTML by a
6
+ * `kind:31036` event with `m: text/html;profile=mcp-app`. It is confined to an
7
+ * iframe whose `sandbox` attribute is locked down here. The single most
8
+ * important hardening is dropping `allow-same-origin`: without it the iframe
9
+ * runs in an opaque origin, so the widget cannot reach the host's cookies,
10
+ * `localStorage`, `IndexedDB`, or same-origin DOM — and therefore cannot read or
11
+ * repaint the host-rendered consent surface.
12
+ *
13
+ * `@mcp-ui/client`'s default sandbox permission string is
14
+ * `"allow-scripts allow-same-origin allow-forms"`. We deliberately OVERRIDE it
15
+ * to a stricter allowlist with NO `allow-same-origin` and NO top-navigation /
16
+ * popup escapes.
17
+ */
18
+ /**
19
+ * The locked-down iframe `sandbox` attribute for an untrusted branch-3 widget.
20
+ *
21
+ * Granted:
22
+ * - `allow-scripts` — the widget needs JS to render and to *request* actions
23
+ * over the postMessage bridge. (With `allow-scripts` but WITHOUT
24
+ * `allow-same-origin`, the iframe is a hostile, isolated origin — exactly
25
+ * what we want.)
26
+ *
27
+ * Withheld (each one is a consent-invariant escape if granted):
28
+ * - `allow-same-origin` — would give the widget the host's origin and
29
+ * thus access to the host DOM / storage; it
30
+ * could then read or overdraw the consent UI.
31
+ * - `allow-top-navigation`* — would let the widget navigate the top frame
32
+ * away (phishing / consent bypass).
33
+ * - `allow-popups`* — would let the widget open windows it controls.
34
+ * - `allow-modals` — would let the widget raise `alert/confirm`
35
+ * dialogs that could be mistaken for host chrome.
36
+ * - `allow-forms` — not needed; widget requests ride the bridge.
37
+ * - `allow-pointer-lock` / `allow-presentation` — UI-capture vectors.
38
+ */
39
+ export const BRANCH3_SANDBOX_PERMISSIONS = 'allow-scripts';
40
+ /**
41
+ * The default cross-origin mcp-ui sandbox proxy URL. `@mcp-ui/client`'s
42
+ * `AppRenderer` loads this opaque-origin proxy HTML to host the widget iframe, so
43
+ * the widget runs in a foreign origin it cannot escape (no `allow-same-origin`).
44
+ *
45
+ * This is the canonical mcp-ui hosted proxy; a host that self-hosts the proxy can
46
+ * pass its own `URL` to {@link import('./SandboxedAppRenderer.js').SandboxedAppRenderer}.
47
+ */
48
+ export const DEFAULT_MCP_UI_SANDBOX_URL = 'https://sandbox.mcpui.dev';
49
+ /**
50
+ * The iframe `sandbox` tokens, as a frozen array, for assertion in tests and
51
+ * for callers that prefer a list over the space-joined string.
52
+ */
53
+ export const BRANCH3_SANDBOX_TOKENS = Object.freeze(BRANCH3_SANDBOX_PERMISSIONS.split(' '));
54
+ /** Tokens that MUST NEVER appear in a branch-3 sandbox (each breaks the invariant). */
55
+ export const FORBIDDEN_SANDBOX_TOKENS = Object.freeze([
56
+ 'allow-same-origin',
57
+ 'allow-top-navigation',
58
+ 'allow-top-navigation-by-user-activation',
59
+ 'allow-popups',
60
+ 'allow-modals',
61
+ 'allow-forms',
62
+ 'allow-pointer-lock',
63
+ 'allow-presentation',
64
+ ]);
65
+ /**
66
+ * Assert that a sandbox permission string is safe for branch 3. Throws if any
67
+ * forbidden token is present. Defensive belt-and-braces so a future edit can't
68
+ * silently re-enable `allow-same-origin`.
69
+ */
70
+ export function assertSafeSandbox(permissions) {
71
+ const tokens = new Set(permissions.split(/\s+/).filter(Boolean));
72
+ for (const forbidden of FORBIDDEN_SANDBOX_TOKENS) {
73
+ if (tokens.has(forbidden)) {
74
+ throw new Error(`branch-3 sandbox must not grant "${forbidden}" — it breaks the consent invariant`);
75
+ }
76
+ }
77
+ }
78
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/mcp-ui/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,eAAwB,CAAC;AAEpE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,2BAAoC,CAAC;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB,MAAM,CAAC,MAAM,CACpE,2BAA2B,CAAC,KAAK,CAAC,GAAG,CAAC,CACvC,CAAC;AAEF,uFAAuF;AACvF,MAAM,CAAC,MAAM,wBAAwB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACvE,mBAAmB;IACnB,sBAAsB;IACtB,yCAAyC;IACzC,cAAc;IACd,cAAc;IACd,aAAa;IACb,oBAAoB;IACpB,oBAAoB;CACrB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACjE,KAAK,MAAM,SAAS,IAAI,wBAAwB,EAAE,CAAC;QACjD,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,oCAAoC,SAAS,qCAAqC,CACnF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Media-NIP parsers.
3
+ *
4
+ * NIP-92 `imeta` tags → MediaVariant[] (inline media on any event)
5
+ * NIP-94 kind:1063 file meta → FileMetadata
6
+ * NIP-68 kind:20 picture → MediaPost (kind 'picture')
7
+ * NIP-71 kind:21/22 video → MediaPost (kind 'video')
8
+ *
9
+ * Media bytes themselves live on Arweave (uploaded via the kind:5094 blob DVM);
10
+ * these parsers only surface the URLs/hashes/dimensions for rendering.
11
+ */
12
+ import { type NostrEvent } from '../types.js';
13
+ /** A single media variant (one resolution/encoding of an image or video). */
14
+ export interface MediaVariant {
15
+ url: string;
16
+ mime?: string;
17
+ /** SHA-256 hex of the file (`x` field). */
18
+ hash?: string;
19
+ /** Dimensions as `<width>x<height>`. */
20
+ dim?: string;
21
+ alt?: string;
22
+ blurhash?: string;
23
+ /** Fallback mirror URLs. */
24
+ fallbacks: string[];
25
+ }
26
+ /**
27
+ * Parse a single NIP-92 `imeta` tag.
28
+ * Form: `["imeta", "url https://…", "m image/png", "x <hash>", "dim 800x600", …]`.
29
+ * Each element after the tag name is a space-delimited `key value` pair;
30
+ * `value` may itself contain spaces (e.g. `alt a cat`).
31
+ */
32
+ export declare function parseImeta(tag: string[]): MediaVariant | null;
33
+ /** Extract all NIP-92 inline media variants from an event's tags. */
34
+ export declare function parseInlineMedia(event: NostrEvent): MediaVariant[];
35
+ /** Parsed NIP-94 file metadata event (kind:1063). */
36
+ export interface FileMetadata {
37
+ eventId: string;
38
+ authorPubkey: string;
39
+ createdAt: number;
40
+ url: string;
41
+ mime?: string;
42
+ hash?: string;
43
+ size?: number;
44
+ dim?: string;
45
+ summary?: string;
46
+ caption: string;
47
+ }
48
+ /** Parse a kind:1063 NIP-94 file metadata event. */
49
+ export declare function parseFileMetadata(event: NostrEvent): FileMetadata | null;
50
+ /** Kinds carrying a media-first post. */
51
+ export declare const MEDIA_POST_KINDS: readonly [20, 21, 22];
52
+ /** Parsed media-first post (NIP-68 picture kind:20, NIP-71 video kind:21/22). */
53
+ export interface MediaPost {
54
+ eventId: string;
55
+ authorPubkey: string;
56
+ createdAt: number;
57
+ mediaType: 'picture' | 'video';
58
+ /** True for NIP-71 short-form video (kind:22). */
59
+ short: boolean;
60
+ title?: string;
61
+ content: string;
62
+ variants: MediaVariant[];
63
+ hashtags: string[];
64
+ durationSec?: number;
65
+ }
66
+ /** Parse a kind:20/21/22 media post. */
67
+ export declare function parseMediaPost(event: NostrEvent): MediaPost | null;
68
+ //# sourceMappingURL=media.d.ts.map