@hanzo/ui 8.27.3 → 8.27.4

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 (59) hide show
  1. package/dist/backdrop/Backdrop.cjs +420 -0
  2. package/dist/backdrop/Backdrop.d.ts +53 -0
  3. package/dist/backdrop/Backdrop.d.ts.map +1 -0
  4. package/dist/backdrop/Backdrop.js +418 -0
  5. package/dist/backdrop/Backdrop.js.map +1 -0
  6. package/dist/backdrop/index.cjs +50 -0
  7. package/dist/backdrop/index.d.ts +29 -0
  8. package/dist/backdrop/index.d.ts.map +1 -0
  9. package/dist/backdrop/index.js +29 -0
  10. package/dist/backdrop/index.js.map +1 -0
  11. package/dist/backdrop/scene.cjs +439 -0
  12. package/dist/backdrop/scene.d.ts +235 -0
  13. package/dist/backdrop/scene.d.ts.map +1 -0
  14. package/dist/backdrop/scene.js +423 -0
  15. package/dist/backdrop/scene.js.map +1 -0
  16. package/dist/chat/Chat.cjs +23 -1
  17. package/dist/chat/Chat.d.ts +6 -3
  18. package/dist/chat/Chat.d.ts.map +1 -1
  19. package/dist/chat/Chat.js +23 -1
  20. package/dist/chat/Chat.js.map +1 -1
  21. package/dist/chat/Inspector.cjs +51 -0
  22. package/dist/chat/Inspector.d.ts +49 -0
  23. package/dist/chat/Inspector.d.ts.map +1 -0
  24. package/dist/chat/Inspector.js +49 -0
  25. package/dist/chat/Inspector.js.map +1 -0
  26. package/dist/chat/Message.cjs +3 -1
  27. package/dist/chat/Message.d.ts +3 -1
  28. package/dist/chat/Message.d.ts.map +1 -1
  29. package/dist/chat/Message.js +3 -1
  30. package/dist/chat/Message.js.map +1 -1
  31. package/dist/chat/Parts.cjs +159 -0
  32. package/dist/chat/Parts.d.ts +186 -0
  33. package/dist/chat/Parts.d.ts.map +1 -0
  34. package/dist/chat/Parts.js +153 -0
  35. package/dist/chat/Parts.js.map +1 -0
  36. package/dist/chat/Persona.cjs +34 -0
  37. package/dist/chat/Persona.d.ts +37 -0
  38. package/dist/chat/Persona.d.ts.map +1 -0
  39. package/dist/chat/Persona.js +30 -0
  40. package/dist/chat/Persona.js.map +1 -0
  41. package/dist/chat/Preview.cjs +42 -0
  42. package/dist/chat/Preview.d.ts +36 -0
  43. package/dist/chat/Preview.d.ts.map +1 -0
  44. package/dist/chat/Preview.js +40 -0
  45. package/dist/chat/Preview.js.map +1 -0
  46. package/dist/chat/directive.cjs +272 -0
  47. package/dist/chat/directive.d.ts +167 -0
  48. package/dist/chat/directive.d.ts.map +1 -0
  49. package/dist/chat/directive.js +266 -0
  50. package/dist/chat/directive.js.map +1 -0
  51. package/dist/chat/index.cjs +59 -4
  52. package/dist/chat/index.d.ts +31 -3
  53. package/dist/chat/index.d.ts.map +1 -1
  54. package/dist/chat/index.js +31 -3
  55. package/dist/chat/index.js.map +1 -1
  56. package/dist/gallery.html +4 -4
  57. package/dist/styles.css +3 -3
  58. package/dist/theme.css +3 -3
  59. package/package.json +7 -1
@@ -0,0 +1,153 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Parts — a streamed turn, drawn by what each piece of it IS.
5
+ *
6
+ * A completion's content is a list of parts, and until now this package had one
7
+ * answer for all of them: `words` flattens the list to prose and DROPS every
8
+ * part that is not text. An image, a tool call, a citation, an artifact — all of
9
+ * it arrived on the wire and none of it reached the screen. Six surfaces wrote
10
+ * six switch statements over the same union to get it back.
11
+ *
12
+ * `MessagePart` is that union, closed, and `Parts` is the dispatcher over it.
13
+ * Closed is the decision: `words`'s `Part` stays OPEN because it reads the wire
14
+ * and must survive a type it has never heard of, while this one is the CANON —
15
+ * the set a surface can exhaustively handle, and the set this package promises
16
+ * to draw. A part whose `type` is outside it still contributes its text, exactly
17
+ * as `words` does, so an unknown part degrades to prose instead of vanishing.
18
+ *
19
+ * Nothing here is new furniture. Every branch dispatches to a piece this package
20
+ * already had: `Code` for a tool's arguments and its output, `Step` for the call
21
+ * itself, `Failure` for an error, `Sources` for citations, `ArtifactCard` for a
22
+ * produced thing. That is the whole reason a typed renderer belongs here rather
23
+ * than in each surface — the parts were already drawn, one per surface, with no
24
+ * agreement about which part got which drawing.
25
+ *
26
+ * MARKDOWN IS STILL NOT HERE. `prose` is where a surface's pipeline enters, and
27
+ * with none supplied the words render plainly. The plugin set is per-surface —
28
+ * nine plugins, one plugin, or a regex under a bundle ceiling that cannot afford
29
+ * a parser — so this package ships no parser and takes the rendered nodes.
30
+ */
31
+ import { Image, SizableText, XStack, YStack } from '@hanzo/gui';
32
+ import { Paperclip } from '@hanzogui/lucide-icons-2';
33
+ import { ArtifactCard } from '../agents/Pane.js';
34
+ import { ink } from '../backends/gui/ink.js';
35
+ import { slot } from '../backends/gui/slot.js';
36
+ import { Code } from './Code.js';
37
+ import { Failure } from './Failure.js';
38
+ import { Preview } from './Preview.js';
39
+ import { Sources } from './Sources.js';
40
+ import { Step } from './Step.js';
41
+ /**
42
+ * Adjacent prose, put back together.
43
+ *
44
+ * The wire splits a sentence across parts — and mid-word, which is why `words`
45
+ * joins with no separator — so drawing each text part as its own block would
46
+ * break one paragraph into a dozen and hand a markdown parser fragments that are
47
+ * not markdown. Runs of `text` and runs of `reasoning` each collapse to one;
48
+ * everything else passes through untouched and in order.
49
+ *
50
+ * This is what makes `Parts` a strict improvement on `words` rather than a
51
+ * different-looking one: an all-text turn renders exactly the string `words`
52
+ * would have produced.
53
+ */
54
+ export function join(parts) {
55
+ const out = [];
56
+ for (const part of parts) {
57
+ const last = out[out.length - 1];
58
+ if ((part.type === 'text' || part.type === 'reasoning') &&
59
+ last &&
60
+ last.type === part.type) {
61
+ out[out.length - 1] = { type: part.type, text: last.text + part.text };
62
+ continue;
63
+ }
64
+ out.push(part);
65
+ }
66
+ return out;
67
+ }
68
+ /**
69
+ * What a tool was asked, or answered, as text.
70
+ *
71
+ * The wire sends JSON, so a caller holding the parsed object should not have to
72
+ * re-serialise it at every call site — that is six copies of two lines. The
73
+ * fallback exists because this takes `unknown` and a value that cannot be
74
+ * serialised must not take the page down with it.
75
+ */
76
+ export const show = (value) => {
77
+ if (value == null)
78
+ return '';
79
+ if (typeof value === 'string')
80
+ return value;
81
+ try {
82
+ return JSON.stringify(value, null, 2);
83
+ }
84
+ catch {
85
+ return String(value);
86
+ }
87
+ };
88
+ /** A size a person can read. Every surface writes this one; here it is once. */
89
+ const weigh = (bytes) => {
90
+ const units = ['B', 'KB', 'MB', 'GB'];
91
+ let n = bytes;
92
+ let i = 0;
93
+ while (n >= 1024 && i < units.length - 1) {
94
+ n /= 1024;
95
+ i += 1;
96
+ }
97
+ return `${i === 0 ? n : n.toFixed(1)} ${units[i]}`;
98
+ };
99
+ /**
100
+ * One part.
101
+ *
102
+ * It spreads no residual props and owns no box, which is the one place this
103
+ * package's house rule does not apply: a piece IS whichever component its type
104
+ * names, and giving it a wrapper of its own would put an anonymous div between
105
+ * every part and the column that spaces them. `Parts` is the box.
106
+ *
107
+ * Named `Piece` and not `Part` because `Part` is already the name of `words`'s
108
+ * open wire type on this barrel, and a module cannot export one name as both a
109
+ * type and a value.
110
+ */
111
+ export function Piece({ part, prose, onRetry, onOpen, onSource }) {
112
+ switch (part.type) {
113
+ case 'text':
114
+ return _jsx(_Fragment, { children: prose ? prose(part.text, part) : ink(part.text) });
115
+ case 'reasoning':
116
+ // Dimmed rather than recoloured: a surface's markdown paints its own
117
+ // colours, and a token on the container would not reach inside them.
118
+ return (_jsx(YStack, { ...slot('reasoning'), opacity: 0.72, children: prose ? prose(part.text, part) : ink(part.text) }));
119
+ case 'toolCall':
120
+ return (_jsx(Step, { name: part.name, status: "running", detail: part.id, children: part.args == null ? undefined : _jsx(Code, { language: "json", children: show(part.args) }) }));
121
+ case 'toolResult':
122
+ return (_jsx(Step, { name: part.name, status: part.status ?? 'done', detail: part.id, children: part.result == null ? undefined : _jsx(Code, { language: "json", children: show(part.result) }) }));
123
+ case 'image':
124
+ return (_jsx(YStack, { ...slot('image'), maxW: 420, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", children: _jsx(Image, { src: part.url, alt: part.alt ?? '', style: { width: '100%', height: 'auto', display: 'block' } }) }));
125
+ case 'file':
126
+ return (_jsxs(XStack, { ...slot('file'), items: "center", gap: "$2", maxW: 420, px: "$2.5", py: "$2", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", children: [_jsx(Paperclip, { size: 13, color: "$quiet" }), _jsx(SizableText, { size: "$2", color: "$ink", numberOfLines: 1, flex: 1, children: part.name }), part.size == null ? null : (_jsx(SizableText, { size: "$1", color: "$quiet", children: weigh(part.size) }))] }));
127
+ case 'citation':
128
+ return _jsx(Sources, { sources: part.sources, onOpen: onSource });
129
+ case 'artifact':
130
+ // Held, so shown. `Preview` renders it with scripting disabled, which is
131
+ // what makes drawing model-authored markup a different question from
132
+ // loading a `uiResource`'s url — see that arm, and `Preview`'s own note.
133
+ return part.markup ? (_jsx(Preview, { title: part.title, markup: part.markup })) : (_jsx(ArtifactCard, { title: part.title, kind: part.kind, onOpen: onOpen ? () => onOpen(part) : undefined }));
134
+ case 'uiResource':
135
+ return (_jsx(Step, { name: part.uri, detail: part.mime, children: part.text ? _jsx(Code, { language: part.mime ?? 'text', children: part.text }) : undefined }));
136
+ case 'error':
137
+ return _jsx(Failure, { onRetry: onRetry, children: part.text });
138
+ default: {
139
+ // The union is closed and the WIRE is not, which is the one place those
140
+ // two facts have to meet. A part this does not know contributes its text
141
+ // and nothing else — the same answer `words` gives, so nothing a surface
142
+ // sends can go missing without also having been missing before.
143
+ const unknown = part;
144
+ return _jsx(_Fragment, { children: unknown.text ? ink(unknown.text) : null });
145
+ }
146
+ }
147
+ }
148
+ /** A turn's parts, in order, spaced. Goes in a `Message`'s children — `Chat`
149
+ * puts it there for a turn whose content is a list. */
150
+ export function Parts({ parts, prose, onRetry, onOpen, onSource, ...props }) {
151
+ return (_jsx(YStack, { ...slot('parts'), width: "100%", gap: "$2", ...props, children: join(parts).map((part, i) => (_jsx(Piece, { part: part, prose: prose, onRetry: onRetry, onOpen: onOpen, onSource: onSource }, `${part.type}-${i}`))) }));
152
+ }
153
+ //# sourceMappingURL=Parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Parts.js","sourceRoot":"","sources":["../../src/chat/Parts.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.clip = void 0;
5
+ exports.Persona = Persona;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ /**
8
+ * Persona — a face on the canvas, and what it is doing.
9
+ *
10
+ * A persona is not a new engine. It is a MAPPING: an emotion names a clip, the
11
+ * clip goes to `Backdrop`'s `clips` mode, and that mode's preloaded crossfade
12
+ * does the switching it already does — one live frame over another, never a
13
+ * flash of black. So a mood change is a prop change, and there is exactly one
14
+ * piece of machinery playing video in this package rather than two.
15
+ *
16
+ * The mapping is the whole component, and it is deliberately thin. What an
17
+ * emotion MEANS — when a persona is listening, when it is thinking — belongs to
18
+ * whatever is driving the conversation; a component that guessed would be
19
+ * guessing from the one place with the least information.
20
+ *
21
+ * `idle` is required and every other emotion is optional, so a persona with one
22
+ * clip is a legal persona and adding a mood is adding a file. `clip` is pure and
23
+ * exported, which is what lets a surface preload the next mood, or test the
24
+ * mapping, without mounting anything.
25
+ */
26
+ const Backdrop_1 = require("../backdrop/Backdrop.cjs");
27
+ /** The clip for this emotion, falling back to idle. */
28
+ const clip = (scenes, emotion) => scenes[emotion] ?? scenes.idle;
29
+ exports.clip = clip;
30
+ function Persona({ scenes, emotion = 'idle', ...props }) {
31
+ // One clip, so it loops itself rather than ending and handing over — a mood
32
+ // holds until something changes it, which is what a mood is.
33
+ return (0, jsx_runtime_1.jsx)(Backdrop_1.Backdrop, { ...props, mode: "clips", clips: [(0, exports.clip)(scenes, emotion)] });
34
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Persona — a face on the canvas, and what it is doing.
3
+ *
4
+ * A persona is not a new engine. It is a MAPPING: an emotion names a clip, the
5
+ * clip goes to `Backdrop`'s `clips` mode, and that mode's preloaded crossfade
6
+ * does the switching it already does — one live frame over another, never a
7
+ * flash of black. So a mood change is a prop change, and there is exactly one
8
+ * piece of machinery playing video in this package rather than two.
9
+ *
10
+ * The mapping is the whole component, and it is deliberately thin. What an
11
+ * emotion MEANS — when a persona is listening, when it is thinking — belongs to
12
+ * whatever is driving the conversation; a component that guessed would be
13
+ * guessing from the one place with the least information.
14
+ *
15
+ * `idle` is required and every other emotion is optional, so a persona with one
16
+ * clip is a legal persona and adding a mood is adding a file. `clip` is pure and
17
+ * exported, which is what lets a surface preload the next mood, or test the
18
+ * mapping, without mounting anything.
19
+ */
20
+ import { type BackdropProps } from '../backdrop/Backdrop.js';
21
+ /** What a persona is doing. The set a conversation can actually report. */
22
+ export type Emotion = 'idle' | 'listening' | 'thinking' | 'speaking' | 'happy' | 'sad' | 'surprised';
23
+ /** Which clip plays for each emotion. `idle` is required: it is what plays when
24
+ * a persona has nothing for the emotion at hand, so there is always something
25
+ * on the canvas and never a gap to design around. */
26
+ export type Scenes = {
27
+ idle: string;
28
+ } & Partial<Record<Emotion, string>>;
29
+ /** The clip for this emotion, falling back to idle. */
30
+ export declare const clip: (scenes: Scenes, emotion: Emotion) => string;
31
+ export interface PersonaProps extends Omit<BackdropProps, 'mode' | 'clips'> {
32
+ scenes: Scenes;
33
+ /** What the persona is doing right now. Defaults to idle. */
34
+ emotion?: Emotion;
35
+ }
36
+ export declare function Persona({ scenes, emotion, ...props }: PersonaProps): import("react").JSX.Element;
37
+ //# sourceMappingURL=Persona.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Persona.d.ts","sourceRoot":"","sources":["../../src/chat/Persona.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEnE,2EAA2E;AAC3E,MAAM,MAAM,OAAO,GACf,MAAM,GACN,WAAW,GACX,UAAU,GACV,UAAU,GACV,OAAO,GACP,KAAK,GACL,WAAW,CAAA;AAEf;;sDAEsD;AACtD,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;AAExE,uDAAuD;AACvD,eAAO,MAAM,IAAI,WAAY,MAAM,WAAW,OAAO,KAAG,MAAwC,CAAA;AAEhG,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IACzE,MAAM,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,OAAgB,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAI3E"}
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Persona — a face on the canvas, and what it is doing.
5
+ *
6
+ * A persona is not a new engine. It is a MAPPING: an emotion names a clip, the
7
+ * clip goes to `Backdrop`'s `clips` mode, and that mode's preloaded crossfade
8
+ * does the switching it already does — one live frame over another, never a
9
+ * flash of black. So a mood change is a prop change, and there is exactly one
10
+ * piece of machinery playing video in this package rather than two.
11
+ *
12
+ * The mapping is the whole component, and it is deliberately thin. What an
13
+ * emotion MEANS — when a persona is listening, when it is thinking — belongs to
14
+ * whatever is driving the conversation; a component that guessed would be
15
+ * guessing from the one place with the least information.
16
+ *
17
+ * `idle` is required and every other emotion is optional, so a persona with one
18
+ * clip is a legal persona and adding a mood is adding a file. `clip` is pure and
19
+ * exported, which is what lets a surface preload the next mood, or test the
20
+ * mapping, without mounting anything.
21
+ */
22
+ import { Backdrop } from '../backdrop/Backdrop.js';
23
+ /** The clip for this emotion, falling back to idle. */
24
+ export const clip = (scenes, emotion) => scenes[emotion] ?? scenes.idle;
25
+ export function Persona({ scenes, emotion = 'idle', ...props }) {
26
+ // One clip, so it loops itself rather than ending and handing over — a mood
27
+ // holds until something changes it, which is what a mood is.
28
+ return _jsx(Backdrop, { ...props, mode: "clips", clips: [clip(scenes, emotion)] });
29
+ }
30
+ //# sourceMappingURL=Persona.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Persona.js","sourceRoot":"","sources":["../../src/chat/Persona.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,QAAQ,EAAsB,MAAM,sBAAsB,CAAA;AAiBnE,uDAAuD;AACvD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,OAAgB,EAAU,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAA;AAQhG,MAAM,UAAU,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,KAAK,EAAgB;IAC1E,4EAA4E;IAC5E,6DAA6D;IAC7D,OAAO,KAAC,QAAQ,OAAK,KAAK,EAAE,IAAI,EAAC,OAAO,EAAC,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAI,CAAA;AAC7E,CAAC"}
@@ -0,0 +1,42 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Preview = Preview;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * Preview — an interface the model wrote, shown but not run.
8
+ *
9
+ * Generative UI arrives as markup, and markup from a model is untrusted input
10
+ * that happens to be a document. Rendering it into the host page is
11
+ * cross-site scripting with extra steps; refusing to render it at all leaves
12
+ * the feature as a paragraph of HTML source. Neither is the answer.
13
+ *
14
+ * The answer is `sandbox=""`. An empty allow-list is the STRICTEST setting the
15
+ * attribute has, not a lax one: no scripts, no same-origin, no forms, no
16
+ * navigation, no popups, no pointer lock. The document lays out and paints —
17
+ * real CSS, real fonts, real layout, a real screenshot — and can do nothing
18
+ * else. That is exactly the shape of a mockup, so nothing is lost by taking
19
+ * away the half that is dangerous.
20
+ *
21
+ * This is why `Parts` can draw an `artifact` and still refuses a `uiResource`.
22
+ * They are not the same risk: a `uiResource` is a URL, and loading one pulls a
23
+ * third-party origin into the page over the network. Inline markup with
24
+ * scripting off reaches nothing and runs nothing.
25
+ *
26
+ * Web only, like `Backdrop` — it is an `<iframe>`, and there is no such thing
27
+ * off the web. A surface that runs on native sends artifacts with no `markup`
28
+ * and gets `ArtifactCard`, which is where that decision already lived.
29
+ */
30
+ const gui_1 = require("@hanzo/gui");
31
+ const slot_1 = require("../backends/gui/slot.cjs");
32
+ function Preview({ markup, title, height = 320, ...props }) {
33
+ const named = title ?? 'Preview';
34
+ return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('preview'), width: "100%", maxW: 720, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", ...props, children: [title ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { items: "center", gap: "$2", px: "$3", py: "$2", borderBottomWidth: 1, borderColor: "$borderColor", children: (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: title }) })) : null, (0, jsx_runtime_1.jsx)("iframe", { title: named, srcDoc: markup, sandbox: "", referrerPolicy: "no-referrer", style: {
35
+ display: 'block',
36
+ width: '100%',
37
+ height,
38
+ border: 0,
39
+ background: '#fff',
40
+ colorScheme: 'light',
41
+ } })] }));
42
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Preview — an interface the model wrote, shown but not run.
3
+ *
4
+ * Generative UI arrives as markup, and markup from a model is untrusted input
5
+ * that happens to be a document. Rendering it into the host page is
6
+ * cross-site scripting with extra steps; refusing to render it at all leaves
7
+ * the feature as a paragraph of HTML source. Neither is the answer.
8
+ *
9
+ * The answer is `sandbox=""`. An empty allow-list is the STRICTEST setting the
10
+ * attribute has, not a lax one: no scripts, no same-origin, no forms, no
11
+ * navigation, no popups, no pointer lock. The document lays out and paints —
12
+ * real CSS, real fonts, real layout, a real screenshot — and can do nothing
13
+ * else. That is exactly the shape of a mockup, so nothing is lost by taking
14
+ * away the half that is dangerous.
15
+ *
16
+ * This is why `Parts` can draw an `artifact` and still refuses a `uiResource`.
17
+ * They are not the same risk: a `uiResource` is a URL, and loading one pulls a
18
+ * third-party origin into the page over the network. Inline markup with
19
+ * scripting off reaches nothing and runs nothing.
20
+ *
21
+ * Web only, like `Backdrop` — it is an `<iframe>`, and there is no such thing
22
+ * off the web. A surface that runs on native sends artifacts with no `markup`
23
+ * and gets `ArtifactCard`, which is where that decision already lived.
24
+ */
25
+ import { YStack } from '@hanzo/gui';
26
+ import type { ComponentProps } from 'react';
27
+ export interface PreviewProps extends Omit<ComponentProps<typeof YStack>, 'children'> {
28
+ /** A self-contained HTML document. Script in it will not run. */
29
+ markup: string;
30
+ /** Named in the frame's header. Also the frame's accessible name. */
31
+ title?: string;
32
+ /** Viewport height, px. The document scrolls inside it. */
33
+ height?: number;
34
+ }
35
+ export declare function Preview({ markup, title, height, ...props }: PreviewProps): import("react").JSX.Element;
36
+ //# sourceMappingURL=Preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/chat/Preview.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAuB,MAAM,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAI3C,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;IACnF,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAY,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAiD9E"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Preview — an interface the model wrote, shown but not run.
5
+ *
6
+ * Generative UI arrives as markup, and markup from a model is untrusted input
7
+ * that happens to be a document. Rendering it into the host page is
8
+ * cross-site scripting with extra steps; refusing to render it at all leaves
9
+ * the feature as a paragraph of HTML source. Neither is the answer.
10
+ *
11
+ * The answer is `sandbox=""`. An empty allow-list is the STRICTEST setting the
12
+ * attribute has, not a lax one: no scripts, no same-origin, no forms, no
13
+ * navigation, no popups, no pointer lock. The document lays out and paints —
14
+ * real CSS, real fonts, real layout, a real screenshot — and can do nothing
15
+ * else. That is exactly the shape of a mockup, so nothing is lost by taking
16
+ * away the half that is dangerous.
17
+ *
18
+ * This is why `Parts` can draw an `artifact` and still refuses a `uiResource`.
19
+ * They are not the same risk: a `uiResource` is a URL, and loading one pulls a
20
+ * third-party origin into the page over the network. Inline markup with
21
+ * scripting off reaches nothing and runs nothing.
22
+ *
23
+ * Web only, like `Backdrop` — it is an `<iframe>`, and there is no such thing
24
+ * off the web. A surface that runs on native sends artifacts with no `markup`
25
+ * and gets `ArtifactCard`, which is where that decision already lived.
26
+ */
27
+ import { SizableText, XStack, YStack } from '@hanzo/gui';
28
+ import { slot } from '../backends/gui/slot.js';
29
+ export function Preview({ markup, title, height = 320, ...props }) {
30
+ const named = title ?? 'Preview';
31
+ return (_jsxs(YStack, { ...slot('preview'), width: "100%", maxW: 720, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", ...props, children: [title ? (_jsx(XStack, { items: "center", gap: "$2", px: "$3", py: "$2", borderBottomWidth: 1, borderColor: "$borderColor", children: _jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: title }) })) : null, _jsx("iframe", { title: named, srcDoc: markup, sandbox: "", referrerPolicy: "no-referrer", style: {
32
+ display: 'block',
33
+ width: '100%',
34
+ height,
35
+ border: 0,
36
+ background: '#fff',
37
+ colorScheme: 'light',
38
+ } })] }));
39
+ }
40
+ //# sourceMappingURL=Preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Preview.js","sourceRoot":"","sources":["../../src/chat/Preview.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAW3C,MAAM,UAAU,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,KAAK,EAAgB;IAC7E,MAAM,KAAK,GAAG,KAAK,IAAI,SAAS,CAAA;IAChC,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,EACnB,KAAK,EAAC,MAAM,EACZ,IAAI,EAAE,GAAG,EACT,OAAO,EAAC,IAAI,EACZ,QAAQ,EAAC,QAAQ,EACjB,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,EAAE,EAAC,QAAQ,KACP,KAAK,aAER,KAAK,CAAC,CAAC,CAAC,CACP,KAAC,MAAM,IACL,KAAK,EAAC,QAAQ,EACd,GAAG,EAAC,IAAI,EACR,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,iBAAiB,EAAE,CAAC,EACpB,WAAW,EAAC,cAAc,YAE1B,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,OAAO,EAAC,aAAa,EAAE,CAAC,YAClD,KAAK,GACM,GACP,CACV,CAAC,CAAC,CAAC,IAAI,EAMR,iBACE,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAC,EAAE,EACV,cAAc,EAAC,aAAa,EAC5B,KAAK,EAAE;oBACL,OAAO,EAAE,OAAO;oBAChB,KAAK,EAAE,MAAM;oBACb,MAAM;oBACN,MAAM,EAAE,CAAC;oBACT,UAAU,EAAE,MAAM;oBAClB,WAAW,EAAE,OAAO;iBACrB,GACD,IACK,CACV,CAAA;AACH,CAAC"}