@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.
- package/dist/a2ui/A2UIRenderer.d.ts +47 -0
- package/dist/a2ui/A2UIRenderer.d.ts.map +1 -0
- package/dist/a2ui/A2UIRenderer.js +106 -0
- package/dist/a2ui/A2UIRenderer.js.map +1 -0
- package/dist/a2ui/binding.d.ts +46 -0
- package/dist/a2ui/binding.d.ts.map +1 -0
- package/dist/a2ui/binding.js +111 -0
- package/dist/a2ui/binding.js.map +1 -0
- package/dist/a2ui/index.d.ts +17 -0
- package/dist/a2ui/index.d.ts.map +1 -0
- package/dist/a2ui/index.js +17 -0
- package/dist/a2ui/index.js.map +1 -0
- package/dist/a2ui/types.d.ts +101 -0
- package/dist/a2ui/types.d.ts.map +1 -0
- package/dist/a2ui/types.js +64 -0
- package/dist/a2ui/types.js.map +1 -0
- package/dist/a2ui/validate.d.ts +55 -0
- package/dist/a2ui/validate.d.ts.map +1 -0
- package/dist/a2ui/validate.js +117 -0
- package/dist/a2ui/validate.js.map +1 -0
- package/dist/app/index.html +246 -0
- package/dist/app-bridge/ext-apps-bridge.d.ts +16 -0
- package/dist/app-bridge/ext-apps-bridge.d.ts.map +1 -0
- package/dist/app-bridge/ext-apps-bridge.js +66 -0
- package/dist/app-bridge/ext-apps-bridge.js.map +1 -0
- package/dist/app-bridge/types.d.ts +41 -0
- package/dist/app-bridge/types.d.ts.map +1 -0
- package/dist/app-bridge/types.js +10 -0
- package/dist/app-bridge/types.js.map +1 -0
- package/dist/app-entry.d.ts +13 -0
- package/dist/app-entry.d.ts.map +1 -0
- package/dist/app-entry.js +45 -0
- package/dist/app-entry.js.map +1 -0
- package/dist/atoms/defi.d.ts +3 -0
- package/dist/atoms/defi.d.ts.map +1 -0
- package/dist/atoms/defi.js +80 -0
- package/dist/atoms/defi.js.map +1 -0
- package/dist/atoms/fallback.d.ts +4 -0
- package/dist/atoms/fallback.d.ts.map +1 -0
- package/dist/atoms/fallback.js +15 -0
- package/dist/atoms/fallback.js.map +1 -0
- package/dist/atoms/forge.d.ts +3 -0
- package/dist/atoms/forge.d.ts.map +1 -0
- package/dist/atoms/forge.js +50 -0
- package/dist/atoms/forge.js.map +1 -0
- package/dist/atoms/interactive.d.ts +3 -0
- package/dist/atoms/interactive.d.ts.map +1 -0
- package/dist/atoms/interactive.js +99 -0
- package/dist/atoms/interactive.js.map +1 -0
- package/dist/atoms/layout.d.ts +3 -0
- package/dist/atoms/layout.d.ts.map +1 -0
- package/dist/atoms/layout.js +22 -0
- package/dist/atoms/layout.js.map +1 -0
- package/dist/atoms/media.d.ts +3 -0
- package/dist/atoms/media.d.ts.map +1 -0
- package/dist/atoms/media.js +92 -0
- package/dist/atoms/media.js.map +1 -0
- package/dist/atoms/onboard.d.ts +3 -0
- package/dist/atoms/onboard.d.ts.map +1 -0
- package/dist/atoms/onboard.js +26 -0
- package/dist/atoms/onboard.js.map +1 -0
- package/dist/atoms/registry.d.ts +35 -0
- package/dist/atoms/registry.d.ts.map +1 -0
- package/dist/atoms/registry.js +77 -0
- package/dist/atoms/registry.js.map +1 -0
- package/dist/atoms/social.d.ts +3 -0
- package/dist/atoms/social.d.ts.map +1 -0
- package/dist/atoms/social.js +52 -0
- package/dist/atoms/social.js.map +1 -0
- package/dist/atoms/types.d.ts +72 -0
- package/dist/atoms/types.d.ts.map +1 -0
- package/dist/atoms/types.js +11 -0
- package/dist/atoms/types.js.map +1 -0
- package/dist/catalog.d.ts +27 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +121 -0
- package/dist/catalog.js.map +1 -0
- package/dist/components/mono-id.d.ts +16 -0
- package/dist/components/mono-id.d.ts.map +1 -0
- package/dist/components/mono-id.js +18 -0
- package/dist/components/mono-id.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +12 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +25 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +26 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +37 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +8 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +9 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +4 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +8 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/examples.d.ts +39 -0
- package/dist/examples.d.ts.map +1 -0
- package/dist/examples.js +168 -0
- package/dist/examples.js.map +1 -0
- package/dist/filters.d.ts +40 -0
- package/dist/filters.d.ts.map +1 -0
- package/dist/filters.js +84 -0
- package/dist/filters.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cn.d.ts +4 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +7 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +7 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp-ui/ConsentPrompt.d.ts +41 -0
- package/dist/mcp-ui/ConsentPrompt.d.ts.map +1 -0
- package/dist/mcp-ui/ConsentPrompt.js +45 -0
- package/dist/mcp-ui/ConsentPrompt.js.map +1 -0
- package/dist/mcp-ui/SandboxedAppRenderer.d.ts +54 -0
- package/dist/mcp-ui/SandboxedAppRenderer.d.ts.map +1 -0
- package/dist/mcp-ui/SandboxedAppRenderer.js +74 -0
- package/dist/mcp-ui/SandboxedAppRenderer.js.map +1 -0
- package/dist/mcp-ui/index.d.ts +18 -0
- package/dist/mcp-ui/index.d.ts.map +1 -0
- package/dist/mcp-ui/index.js +18 -0
- package/dist/mcp-ui/index.js.map +1 -0
- package/dist/mcp-ui/sandbox.d.ts +62 -0
- package/dist/mcp-ui/sandbox.d.ts.map +1 -0
- package/dist/mcp-ui/sandbox.js +78 -0
- package/dist/mcp-ui/sandbox.js.map +1 -0
- package/dist/parsers/media.d.ts +68 -0
- package/dist/parsers/media.d.ts.map +1 -0
- package/dist/parsers/media.js +124 -0
- package/dist/parsers/media.js.map +1 -0
- package/dist/parsers/nip34.d.ts +75 -0
- package/dist/parsers/nip34.d.ts.map +1 -0
- package/dist/parsers/nip34.js +142 -0
- package/dist/parsers/nip34.js.map +1 -0
- package/dist/parsers/social.d.ts +89 -0
- package/dist/parsers/social.d.ts.map +1 -0
- package/dist/parsers/social.js +136 -0
- package/dist/parsers/social.js.map +1 -0
- package/dist/render/node-shims/node-builtins.d.ts +30 -0
- package/dist/render/node-shims/node-builtins.d.ts.map +1 -0
- package/dist/render/node-shims/node-builtins.js +38 -0
- package/dist/render/node-shims/node-builtins.js.map +1 -0
- package/dist/render/resolve.d.ts +72 -0
- package/dist/render/resolve.d.ts.map +1 -0
- package/dist/render/resolve.js +115 -0
- package/dist/render/resolve.js.map +1 -0
- package/dist/runtime.d.ts +17 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +218 -0
- package/dist/runtime.js.map +1 -0
- package/dist/server/apps-server.d.ts +32 -0
- package/dist/server/apps-server.d.ts.map +1 -0
- package/dist/server/apps-server.js +163 -0
- package/dist/server/apps-server.js.map +1 -0
- package/dist/server/backend.d.ts +148 -0
- package/dist/server/backend.d.ts.map +1 -0
- package/dist/server/backend.js +11 -0
- package/dist/server/backend.js.map +1 -0
- package/dist/server/daemon-backend.d.ts +113 -0
- package/dist/server/daemon-backend.d.ts.map +1 -0
- package/dist/server/daemon-backend.js +79 -0
- package/dist/server/daemon-backend.js.map +1 -0
- package/dist/server/daemon-main.d.ts +25 -0
- package/dist/server/daemon-main.d.ts.map +1 -0
- package/dist/server/daemon-main.js +165 -0
- package/dist/server/daemon-main.js.map +1 -0
- package/dist/server/fake-backend.d.ts +53 -0
- package/dist/server/fake-backend.d.ts.map +1 -0
- package/dist/server/fake-backend.js +157 -0
- package/dist/server/fake-backend.js.map +1 -0
- package/dist/server/fake-main.d.ts +15 -0
- package/dist/server/fake-main.d.ts.map +1 -0
- package/dist/server/fake-main.js +39 -0
- package/dist/server/fake-main.js.map +1 -0
- package/dist/spec.d.ts +67 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +221 -0
- package/dist/spec.js.map +1 -0
- package/dist/tool-names.d.ts +27 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tool-names.js +32 -0
- package/dist/tool-names.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- 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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"}
|
package/dist/index.d.ts
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.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"}
|
package/dist/lib/cn.d.ts
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
package/dist/main.js.map
ADDED
|
@@ -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
|