@hanzo/ui 8.1.5 → 8.1.7

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 (66) hide show
  1. package/README.md +4 -2
  2. package/dist/backends/gui/textarea.cjs +5 -10
  3. package/dist/backends/gui/textarea.d.ts +11 -32
  4. package/dist/backends/gui/textarea.d.ts.map +1 -1
  5. package/dist/backends/gui/textarea.js +5 -10
  6. package/dist/backends/gui/textarea.js.map +1 -1
  7. package/dist/chat/Composer.cjs +10 -46
  8. package/dist/chat/Composer.d.ts +11 -30
  9. package/dist/chat/Composer.d.ts.map +1 -1
  10. package/dist/chat/Composer.js +10 -46
  11. package/dist/chat/Composer.js.map +1 -1
  12. package/dist/chat/Failure.cjs +9 -28
  13. package/dist/chat/Failure.d.ts +6 -20
  14. package/dist/chat/Failure.d.ts.map +1 -1
  15. package/dist/chat/Failure.js +9 -28
  16. package/dist/chat/Failure.js.map +1 -1
  17. package/dist/chat/Message.cjs +11 -34
  18. package/dist/chat/Message.d.ts +12 -40
  19. package/dist/chat/Message.d.ts.map +1 -1
  20. package/dist/chat/Message.js +11 -34
  21. package/dist/chat/Message.js.map +1 -1
  22. package/dist/chat/Sources.cjs +6 -24
  23. package/dist/chat/Sources.d.ts +8 -28
  24. package/dist/chat/Sources.d.ts.map +1 -1
  25. package/dist/chat/Sources.js +6 -24
  26. package/dist/chat/Sources.js.map +1 -1
  27. package/dist/chat/Step.cjs +16 -42
  28. package/dist/chat/Step.d.ts +5 -17
  29. package/dist/chat/Step.d.ts.map +1 -1
  30. package/dist/chat/Step.js +16 -42
  31. package/dist/chat/Step.js.map +1 -1
  32. package/dist/chat/Thread.cjs +4 -27
  33. package/dist/chat/Thread.d.ts +4 -34
  34. package/dist/chat/Thread.d.ts.map +1 -1
  35. package/dist/chat/Thread.js +4 -27
  36. package/dist/chat/Thread.js.map +1 -1
  37. package/dist/chat/index.cjs +20 -61
  38. package/dist/chat/index.d.ts +20 -61
  39. package/dist/chat/index.d.ts.map +1 -1
  40. package/dist/chat/index.js +20 -61
  41. package/dist/chat/index.js.map +1 -1
  42. package/dist/chat/pure.cjs +9 -28
  43. package/dist/chat/pure.d.ts.map +1 -1
  44. package/dist/chat/pure.js +9 -28
  45. package/dist/chat/pure.js.map +1 -1
  46. package/dist/chat/send.cjs +8 -18
  47. package/dist/chat/send.d.ts +5 -12
  48. package/dist/chat/send.d.ts.map +1 -1
  49. package/dist/chat/send.js +8 -18
  50. package/dist/chat/send.js.map +1 -1
  51. package/dist/chat/stick.cjs +2 -4
  52. package/dist/chat/stick.d.ts +2 -4
  53. package/dist/chat/stick.d.ts.map +1 -1
  54. package/dist/chat/stick.js +2 -4
  55. package/dist/chat/stick.js.map +1 -1
  56. package/dist/gallery.d.ts.map +1 -1
  57. package/dist/gallery.html +2840 -0
  58. package/dist/gallery.js.map +1 -1
  59. package/dist/product/CopyButton.d.ts +2 -8
  60. package/dist/product/CopyButton.d.ts.map +1 -1
  61. package/dist/product/CopyButton.js.map +1 -1
  62. package/dist/product/pure.cjs +3 -5
  63. package/dist/product/pure.d.ts.map +1 -1
  64. package/dist/product/pure.js +3 -5
  65. package/dist/product/pure.js.map +1 -1
  66. package/package.json +1 -1
@@ -9,36 +9,21 @@ const jsx_runtime_1 = require("react/jsx-runtime");
9
9
  *
10
10
  * Role drives presentation and nothing else: a user turn is a contained bubble
11
11
  * that shrinks to its content, an assistant turn is full-bleed prose, a system
12
- * turn is a muted aside. Content is `children`, so the surface keeps its own
13
- * markdown pipeline — the surfaces disagree on remark plugins and none of that
14
- * belongs in a presentational package.
12
+ * turn is a muted aside. The contrast is what says who is speaking, so there is
13
+ * no name and no timestamp, and `icon` is opt-in.
15
14
  *
16
- * That arrangement is not this package's taste; it is what all six turn
17
- * renderers across the estate independently arrived at. hanzo/chat states it
18
- * outright in `client/src/components/Chat/Messages/ui/MessageRender.tsx:131`:
19
- * "the user's turn is a glass bubble on the right, the reply plain and full
20
- * width — the contrast is what says who is speaking." No avatar, no sender
21
- * name, no timestamp — which is why `icon` is opt-in and there is no `name`
22
- * prop. Only the read-only share view renders a name, and only one surface
23
- * renders a timestamp.
15
+ * Content is `children`: the markdown pipeline stays with the surface.
24
16
  */
25
17
  const gui_1 = require("@hanzo/gui");
26
18
  const ink_1 = require("../backends/gui/ink.cjs");
27
19
  const slot_1 = require("../backends/gui/slot.cjs");
28
20
  /**
29
- * The mark that says a turn is still arriving.
21
+ * The mark that says a turn is still arriving. Static, not blinking.
30
22
  *
31
- * Placed by whoever knows where the prose ends. A surface rendering markdown
32
- * owns that node and can append this inside it; `Message busy` puts it at the
33
- * end of the turn instead, which is all this package can know.
34
- *
35
- * It does not blink. Every surface that ships one draws it static — an 8x16
36
- * block on hanzo.app `/chat`, a 2px caret in the builder, a 12px `⬤` from
37
- * hanzo/chat's `.result-streaming::after`. A caret is the narrowest of the
38
- * three and the one that reads as "the sentence continues" rather than as a
39
- * bullet. Decorative, so it is hidden from assistive tech: the turn's text is
40
- * already live-announced by the surface, and a cursor announced as content is
41
- * noise on every token.
23
+ * Placed by whoever knows where the prose ends: a surface rendering markdown
24
+ * owns that node and can append this inside it, and `Message busy` puts it at
25
+ * the end of the turn. Decorative, so assistive tech skips it — the surface
26
+ * already live-announces the text.
42
27
  */
43
28
  function Caret() {
44
29
  return (0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('caret'), width: 2, height: 15, rounded: 1, bg: "$color12", "aria-hidden": true });
@@ -48,18 +33,10 @@ function Message({ role, children, actions, busy = false, icon, body, ...props }
48
33
  return ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('message'), "data-role": "system", width: "100%", justify: "center", py: "$2", ...props, children: (0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$1", color: "$color10", text: "center", children: children }) }));
49
34
  const mine = role === 'user';
50
35
  return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('message'), "data-role": role, width: "100%", justify: mine ? 'flex-end' : 'flex-start', gap: "$2",
51
- // The row is a hover group, so an action strip can be revealed with
52
- // `$group-hover` instead of by a wrapper each surface adds itself. Both
53
- // hanzo/chat and hanzo.app reveal theirs on hover and both had to supply
54
- // the group. Unnamed on purpose: gui types `group` as a BOOLEAN here, so
55
- // `group="turn"` type-errors rather than registering a named group.
36
+ // Makes `actions` revealable with `$group-hover`. Unnamed: gui types
37
+ // `group` as a boolean, so a name does not compile.
56
38
  group: true, ...props, children: [icon && !mine ? (0, jsx_runtime_1.jsx)(gui_1.YStack, { pt: "$1", children: icon }) : null, (0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('message-body'), "data-bubble": mine ? 'true' : undefined, gap: "$2",
57
- // 85%, because that is the number three independent implementations
58
- // reached: hanzo/chat's `USER_TURN` (`common/turn.ts:17`,
59
- // `max-w-[85%]`), hanzo.app `/chat` (`app/chat/page.tsx:521`,
60
- // `maxWidth="85%"`) and the app builder's `UserBubble`
61
- // (`ask-ai/chat-thread.tsx:141`). This package said 80% and no one
62
- // said 80%.
39
+ // 85% is what the surfaces converged on for a user turn.
63
40
  maxW: mine ? '85%' : '100%', flex: mine ? undefined : 1, ...(mine && {
64
41
  bg: '$color3',
65
42
  rounded: '$5',
@@ -3,44 +3,24 @@
3
3
  *
4
4
  * Role drives presentation and nothing else: a user turn is a contained bubble
5
5
  * that shrinks to its content, an assistant turn is full-bleed prose, a system
6
- * turn is a muted aside. Content is `children`, so the surface keeps its own
7
- * markdown pipeline — the surfaces disagree on remark plugins and none of that
8
- * belongs in a presentational package.
6
+ * turn is a muted aside. The contrast is what says who is speaking, so there is
7
+ * no name and no timestamp, and `icon` is opt-in.
9
8
  *
10
- * That arrangement is not this package's taste; it is what all six turn
11
- * renderers across the estate independently arrived at. hanzo/chat states it
12
- * outright in `client/src/components/Chat/Messages/ui/MessageRender.tsx:131`:
13
- * "the user's turn is a glass bubble on the right, the reply plain and full
14
- * width — the contrast is what says who is speaking." No avatar, no sender
15
- * name, no timestamp — which is why `icon` is opt-in and there is no `name`
16
- * prop. Only the read-only share view renders a name, and only one surface
17
- * renders a timestamp.
9
+ * Content is `children`: the markdown pipeline stays with the surface.
18
10
  */
19
11
  import { XStack } from '@hanzo/gui';
20
12
  import type { ComponentProps, ReactNode } from 'react';
21
13
  export type Role = 'user' | 'assistant' | 'system';
22
- /**
23
- * What a gui stack accepts — id, className, style, the `$` style props.
24
- *
25
- * `role` is dropped because this component already has one and means something
26
- * else by it: the ARIA role of the row is not the speaker of the turn. The row
27
- * needs no ARIA role, and `aria-label` is still reachable for the name.
28
- */
14
+ /** What a gui stack accepts. `role` is dropped: here it names the speaker, not
15
+ * an ARIA role. `aria-label` still reaches the row. */
29
16
  type Stack = Omit<ComponentProps<typeof XStack>, 'children' | 'role'>;
30
17
  /**
31
- * The mark that says a turn is still arriving.
32
- *
33
- * Placed by whoever knows where the prose ends. A surface rendering markdown
34
- * owns that node and can append this inside it; `Message busy` puts it at the
35
- * end of the turn instead, which is all this package can know.
18
+ * The mark that says a turn is still arriving. Static, not blinking.
36
19
  *
37
- * It does not blink. Every surface that ships one draws it static — an 8x16
38
- * block on hanzo.app `/chat`, a 2px caret in the builder, a 12px `⬤` from
39
- * hanzo/chat's `.result-streaming::after`. A caret is the narrowest of the
40
- * three and the one that reads as "the sentence continues" rather than as a
41
- * bullet. Decorative, so it is hidden from assistive tech: the turn's text is
42
- * already live-announced by the surface, and a cursor announced as content is
43
- * noise on every token.
20
+ * Placed by whoever knows where the prose ends: a surface rendering markdown
21
+ * owns that node and can append this inside it, and `Message busy` puts it at
22
+ * the end of the turn. Decorative, so assistive tech skips it — the surface
23
+ * already live-announces the text.
44
24
  */
45
25
  export declare function Caret(): import("react/jsx-runtime").JSX.Element;
46
26
  export interface MessageProps extends Stack {
@@ -52,16 +32,8 @@ export interface MessageProps extends Stack {
52
32
  busy?: boolean;
53
33
  /** Leading affordance for an assistant turn: avatar or model mark. */
54
34
  icon?: ReactNode;
55
- /**
56
- * The bubble's own props — the inner box, not the row.
57
- *
58
- * The same reason `DialogContent` grew `overlay`: this component owns the
59
- * body so a caller never has to assemble one, but owning is not hiding, and
60
- * with nothing through, the fill, the corner and the width cap were
61
- * unreachable from outside the package. hanzo/chat's turn is `glass hz-turn`
62
- * with a `color-mix` fill it applies fleet-wide (`style.css:389`); it cannot
63
- * adopt a bubble welded to `$color3`. Absent, nothing changes.
64
- */
35
+ /** The bubble's own props — the inner box, not the row. Reaches the fill, the
36
+ * corner and the width cap. Absent, nothing changes. */
65
37
  body?: Stack;
66
38
  }
67
39
  export declare function Message({ role, children, actions, busy, icon, body, ...props }: MessageProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAQ,MAAM,EAAU,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtD,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;AAElD;;;;;;GAMG;AACH,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,CAAA;AAErE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,4CAEpB;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK;IACzC,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,KAAK,CAAA;CACb;AAED,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAY,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,YAAY,2CA4Dd"}
1
+ {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,OAAO,EAAQ,MAAM,EAAU,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtD,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;AAElD;wDACwD;AACxD,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,CAAA;AAErE;;;;;;;GAOG;AACH,wBAAgB,KAAK,4CAEpB;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK;IACzC,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;6DACyD;IACzD,IAAI,CAAC,EAAE,KAAK,CAAA;CACb;AAED,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAY,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,YAAY,2CAoDd"}
@@ -5,36 +5,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  *
6
6
  * Role drives presentation and nothing else: a user turn is a contained bubble
7
7
  * that shrinks to its content, an assistant turn is full-bleed prose, a system
8
- * turn is a muted aside. Content is `children`, so the surface keeps its own
9
- * markdown pipeline — the surfaces disagree on remark plugins and none of that
10
- * belongs in a presentational package.
8
+ * turn is a muted aside. The contrast is what says who is speaking, so there is
9
+ * no name and no timestamp, and `icon` is opt-in.
11
10
  *
12
- * That arrangement is not this package's taste; it is what all six turn
13
- * renderers across the estate independently arrived at. hanzo/chat states it
14
- * outright in `client/src/components/Chat/Messages/ui/MessageRender.tsx:131`:
15
- * "the user's turn is a glass bubble on the right, the reply plain and full
16
- * width — the contrast is what says who is speaking." No avatar, no sender
17
- * name, no timestamp — which is why `icon` is opt-in and there is no `name`
18
- * prop. Only the read-only share view renders a name, and only one surface
19
- * renders a timestamp.
11
+ * Content is `children`: the markdown pipeline stays with the surface.
20
12
  */
21
13
  import { Text, XStack, YStack } from '@hanzo/gui';
22
14
  import { ink } from '../backends/gui/ink.js';
23
15
  import { slot } from '../backends/gui/slot.js';
24
16
  /**
25
- * The mark that says a turn is still arriving.
17
+ * The mark that says a turn is still arriving. Static, not blinking.
26
18
  *
27
- * Placed by whoever knows where the prose ends. A surface rendering markdown
28
- * owns that node and can append this inside it; `Message busy` puts it at the
29
- * end of the turn instead, which is all this package can know.
30
- *
31
- * It does not blink. Every surface that ships one draws it static — an 8x16
32
- * block on hanzo.app `/chat`, a 2px caret in the builder, a 12px `⬤` from
33
- * hanzo/chat's `.result-streaming::after`. A caret is the narrowest of the
34
- * three and the one that reads as "the sentence continues" rather than as a
35
- * bullet. Decorative, so it is hidden from assistive tech: the turn's text is
36
- * already live-announced by the surface, and a cursor announced as content is
37
- * noise on every token.
19
+ * Placed by whoever knows where the prose ends: a surface rendering markdown
20
+ * owns that node and can append this inside it, and `Message busy` puts it at
21
+ * the end of the turn. Decorative, so assistive tech skips it — the surface
22
+ * already live-announces the text.
38
23
  */
39
24
  export function Caret() {
40
25
  return _jsx(YStack, { ...slot('caret'), width: 2, height: 15, rounded: 1, bg: "$color12", "aria-hidden": true });
@@ -44,18 +29,10 @@ export function Message({ role, children, actions, busy = false, icon, body, ...
44
29
  return (_jsx(XStack, { ...slot('message'), "data-role": "system", width: "100%", justify: "center", py: "$2", ...props, children: _jsx(Text, { fontSize: "$1", color: "$color10", text: "center", children: children }) }));
45
30
  const mine = role === 'user';
46
31
  return (_jsxs(XStack, { ...slot('message'), "data-role": role, width: "100%", justify: mine ? 'flex-end' : 'flex-start', gap: "$2",
47
- // The row is a hover group, so an action strip can be revealed with
48
- // `$group-hover` instead of by a wrapper each surface adds itself. Both
49
- // hanzo/chat and hanzo.app reveal theirs on hover and both had to supply
50
- // the group. Unnamed on purpose: gui types `group` as a BOOLEAN here, so
51
- // `group="turn"` type-errors rather than registering a named group.
32
+ // Makes `actions` revealable with `$group-hover`. Unnamed: gui types
33
+ // `group` as a boolean, so a name does not compile.
52
34
  group: true, ...props, children: [icon && !mine ? _jsx(YStack, { pt: "$1", children: icon }) : null, _jsxs(YStack, { ...slot('message-body'), "data-bubble": mine ? 'true' : undefined, gap: "$2",
53
- // 85%, because that is the number three independent implementations
54
- // reached: hanzo/chat's `USER_TURN` (`common/turn.ts:17`,
55
- // `max-w-[85%]`), hanzo.app `/chat` (`app/chat/page.tsx:521`,
56
- // `maxWidth="85%"`) and the app builder's `UserBubble`
57
- // (`ask-ai/chat-thread.tsx:141`). This package said 80% and no one
58
- // said 80%.
35
+ // 85% is what the surfaces converged on for a user turn.
59
36
  maxW: mine ? '85%' : '100%', flex: mine ? undefined : 1, ...(mine && {
60
37
  bg: '$color3',
61
38
  rounded: '$5',
@@ -1 +1 @@
1
- {"version":3,"file":"Message.js","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGjD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAa3C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,KAAC,MAAM,OAAK,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAC,UAAU,wBAAe,CAAA;AAClG,CAAC;AAwBD,MAAM,UAAU,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAI,GAAG,KAAK,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACK;IACb,IAAI,IAAI,KAAK,QAAQ;QACnB,OAAO,CACL,KAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eACT,QAAQ,EAClB,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,QAAQ,EAChB,EAAE,EAAC,IAAI,KACH,KAAK,YAET,KAAC,IAAI,IAAC,QAAQ,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,EAAC,IAAI,EAAC,QAAQ,YAC/C,QAAQ,GACJ,GACA,CACV,CAAA;IAEH,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,CAAA;IAC5B,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eACR,IAAI,EACf,KAAK,EAAC,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,EACzC,GAAG,EAAC,IAAI;QACR,oEAAoE;QACpE,wEAAwE;QACxE,yEAAyE;QACzE,yEAAyE;QACzE,oEAAoE;QACpE,KAAK,WACD,KAAK,aAER,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,EAAE,EAAC,IAAI,YAAE,IAAI,GAAU,CAAC,CAAC,CAAC,IAAI,EACvD,MAAC,MAAM,OACD,IAAI,CAAC,cAAc,CAAC,iBACX,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACtC,GAAG,EAAC,IAAI;gBACR,oEAAoE;gBACpE,0DAA0D;gBAC1D,8DAA8D;gBAC9D,uDAAuD;gBACvD,mEAAmE;gBACnE,YAAY;gBACZ,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAC3B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KACtB,CAAC,IAAI,IAAI;oBACX,EAAE,EAAE,SAAS;oBACb,OAAO,EAAE,IAAI;oBACb,EAAE,EAAE,IAAI;oBACR,EAAE,EAAE,IAAI;iBACT,CAAC,KACE,IAAI,aAEP,GAAG,CAAC,QAAQ,CAAC,EACb,IAAI,CAAC,CAAC,CAAC,KAAC,KAAK,KAAG,CAAC,CAAC,CAAC,IAAI,EACvB,OAAO,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,GAAG,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,YAAE,OAAO,GAAU,CAAC,CAAC,CAAC,IAAI,IAC7D,IACF,CACV,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"Message.js","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;GASG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGjD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAQ3C;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,KAAC,MAAM,OAAK,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAC,UAAU,wBAAe,CAAA;AAClG,CAAC;AAgBD,MAAM,UAAU,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAI,GAAG,KAAK,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACK;IACb,IAAI,IAAI,KAAK,QAAQ;QACnB,OAAO,CACL,KAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eACT,QAAQ,EAClB,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,QAAQ,EAChB,EAAE,EAAC,IAAI,KACH,KAAK,YAET,KAAC,IAAI,IAAC,QAAQ,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,EAAC,IAAI,EAAC,QAAQ,YAC/C,QAAQ,GACJ,GACA,CACV,CAAA;IAEH,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,CAAA;IAC5B,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eACR,IAAI,EACf,KAAK,EAAC,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,EACzC,GAAG,EAAC,IAAI;QACR,qEAAqE;QACrE,oDAAoD;QACpD,KAAK,WACD,KAAK,aAER,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,EAAE,EAAC,IAAI,YAAE,IAAI,GAAU,CAAC,CAAC,CAAC,IAAI,EACvD,MAAC,MAAM,OACD,IAAI,CAAC,cAAc,CAAC,iBACX,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACtC,GAAG,EAAC,IAAI;gBACR,yDAAyD;gBACzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAC3B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KACtB,CAAC,IAAI,IAAI;oBACX,EAAE,EAAE,SAAS;oBACb,OAAO,EAAE,IAAI;oBACb,EAAE,EAAE,IAAI;oBACR,EAAE,EAAE,IAAI;iBACT,CAAC,KACE,IAAI,aAEP,GAAG,CAAC,QAAQ,CAAC,EACb,IAAI,CAAC,CAAC,CAAC,KAAC,KAAK,KAAG,CAAC,CAAC,CAAC,IAAI,EACvB,OAAO,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,GAAG,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,YAAE,OAAO,GAAU,CAAC,CAAC,CAAC,IAAI,IAC7D,IACF,CACV,CAAA;AACH,CAAC"}
@@ -7,34 +7,16 @@ const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  /**
8
8
  * Sources — the citations for a turn, as a strip of cards.
9
9
  *
10
- * This used to be a wrapping grid of 28px marks with the title reachable only
11
- * as a tooltip, and the argument for it was density: sources are scanned for
12
- * "which of these do I already trust", and twenty full-width titles push the
13
- * rail past a screen. The density argument is right. Hiding the HOST was not,
14
- * because the host is the answer to that exact question — a favicon is sixteen
15
- * pixels of ambiguity and `nytimes.com` is a verdict — and neither surface that
16
- * ships citations hides it. hanzo/chat's `SourceItem` (`components/Web/
17
- * Sources.tsx`) draws favicon, domain, title and a snippet; the extension's
18
- * `answer/Source.tsx:9-26` draws a number, a favicon, the host and a
19
- * three-line-clamped title, and its own comment records where that came from:
20
- * "Source card — chat AnswerView: 160px, number pill first, favicon, host,
21
- * 3-line title".
10
+ * Each card leads with the host, which is what a reader scans to decide whether
11
+ * they trust a source; the title is the tiebreaker under it. The strip scrolls
12
+ * sideways so it stays one row tall at any count.
22
13
  *
23
- * So density is kept by scrolling sideways rather than by discarding the text —
24
- * the strip is one row tall whatever the count, which is what the grid was
25
- * really buying. Both surfaces already scroll: `.ae-sources` is
26
- * `display:flex; overflow-x:auto` at `newtab.css:260`.
27
- *
28
- * The number is not decoration. Both surfaces number the cards to match a
29
- * marker in the prose, and the marker itself is not here: chat mints it with a
30
- * remark plugin over private-use codepoints (`components/Web/plugin.ts`), which
31
- * belongs to the markdown pipeline that stays with the surface.
14
+ * The number matches a marker in the prose. Minting that marker belongs to the
15
+ * markdown pipeline, which stays with the surface.
32
16
  */
33
17
  const gui_1 = require("@hanzo/gui");
34
18
  const slot_1 = require("../backends/gui/slot.cjs");
35
- /** Card width, px. The extension's is 168 and it cites chat's 160; the point of
36
- * a fixed width is that a strip of them scans as a row rather than as ragged
37
- * columns, so it is one number and not a range. */
19
+ /** Card width, px. Fixed, so a strip scans as a row rather than ragged columns. */
38
20
  const CARD = 168;
39
21
  function Sources({ sources, title = 'Sources', onOpen, ...props }) {
40
22
  if (sources.length === 0)
@@ -1,28 +1,12 @@
1
1
  /**
2
2
  * Sources — the citations for a turn, as a strip of cards.
3
3
  *
4
- * This used to be a wrapping grid of 28px marks with the title reachable only
5
- * as a tooltip, and the argument for it was density: sources are scanned for
6
- * "which of these do I already trust", and twenty full-width titles push the
7
- * rail past a screen. The density argument is right. Hiding the HOST was not,
8
- * because the host is the answer to that exact question — a favicon is sixteen
9
- * pixels of ambiguity and `nytimes.com` is a verdict — and neither surface that
10
- * ships citations hides it. hanzo/chat's `SourceItem` (`components/Web/
11
- * Sources.tsx`) draws favicon, domain, title and a snippet; the extension's
12
- * `answer/Source.tsx:9-26` draws a number, a favicon, the host and a
13
- * three-line-clamped title, and its own comment records where that came from:
14
- * "Source card — chat AnswerView: 160px, number pill first, favicon, host,
15
- * 3-line title".
4
+ * Each card leads with the host, which is what a reader scans to decide whether
5
+ * they trust a source; the title is the tiebreaker under it. The strip scrolls
6
+ * sideways so it stays one row tall at any count.
16
7
  *
17
- * So density is kept by scrolling sideways rather than by discarding the text —
18
- * the strip is one row tall whatever the count, which is what the grid was
19
- * really buying. Both surfaces already scroll: `.ae-sources` is
20
- * `display:flex; overflow-x:auto` at `newtab.css:260`.
21
- *
22
- * The number is not decoration. Both surfaces number the cards to match a
23
- * marker in the prose, and the marker itself is not here: chat mints it with a
24
- * remark plugin over private-use codepoints (`components/Web/plugin.ts`), which
25
- * belongs to the markdown pipeline that stays with the surface.
8
+ * The number matches a marker in the prose. Minting that marker belongs to the
9
+ * markdown pipeline, which stays with the surface.
26
10
  */
27
11
  import { YStack } from '@hanzo/gui';
28
12
  import type { ComponentProps, ReactNode } from 'react';
@@ -35,14 +19,10 @@ export interface Source {
35
19
  /** Favicon or mark. Falls back to the first letter of `host` or `title`. */
36
20
  icon?: ReactNode;
37
21
  /**
38
- * Who published it — `nytimes.com`, a repo, a filename. Shown above the
39
- * title, because this is the line a reader actually scans.
22
+ * Who published it — `nytimes.com`, a repo, a filename.
40
23
  *
41
- * Derived by the SURFACE, not here. The extension parses it from the URL and
42
- * strips `www.` (`Source.tsx:10-15`); chat is handed a domain by the server
43
- * alongside a server-derived favicon. A `new URL()` in this package would be
44
- * a third answer, and it would be the wrong one for a source that is a file
45
- * path rather than a link.
24
+ * Derived by the surface: a `new URL()` here would be wrong for a source that
25
+ * is a file path rather than a link.
46
26
  */
47
27
  host?: string;
48
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Sources.d.ts","sourceRoot":"","sources":["../../src/chat/Sources.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAuB,MAAM,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAStD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;IACnF,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED,wBAAgB,OAAO,CAAC,EAAE,OAAO,EAAE,KAAiB,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,kDAiCrF;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC/F,MAAM,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CA6D9E"}
1
+ {"version":3,"file":"Sources.d.ts","sourceRoot":"","sources":["../../src/chat/Sources.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,OAAO,EAAuB,MAAM,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAOtD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;IACnF,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED,wBAAgB,OAAO,CAAC,EAAE,OAAO,EAAE,KAAiB,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,kDA6BrF;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC/F,MAAM,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,2CA2D9E"}
@@ -3,34 +3,16 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  /**
4
4
  * Sources — the citations for a turn, as a strip of cards.
5
5
  *
6
- * This used to be a wrapping grid of 28px marks with the title reachable only
7
- * as a tooltip, and the argument for it was density: sources are scanned for
8
- * "which of these do I already trust", and twenty full-width titles push the
9
- * rail past a screen. The density argument is right. Hiding the HOST was not,
10
- * because the host is the answer to that exact question — a favicon is sixteen
11
- * pixels of ambiguity and `nytimes.com` is a verdict — and neither surface that
12
- * ships citations hides it. hanzo/chat's `SourceItem` (`components/Web/
13
- * Sources.tsx`) draws favicon, domain, title and a snippet; the extension's
14
- * `answer/Source.tsx:9-26` draws a number, a favicon, the host and a
15
- * three-line-clamped title, and its own comment records where that came from:
16
- * "Source card — chat AnswerView: 160px, number pill first, favicon, host,
17
- * 3-line title".
6
+ * Each card leads with the host, which is what a reader scans to decide whether
7
+ * they trust a source; the title is the tiebreaker under it. The strip scrolls
8
+ * sideways so it stays one row tall at any count.
18
9
  *
19
- * So density is kept by scrolling sideways rather than by discarding the text —
20
- * the strip is one row tall whatever the count, which is what the grid was
21
- * really buying. Both surfaces already scroll: `.ae-sources` is
22
- * `display:flex; overflow-x:auto` at `newtab.css:260`.
23
- *
24
- * The number is not decoration. Both surfaces number the cards to match a
25
- * marker in the prose, and the marker itself is not here: chat mints it with a
26
- * remark plugin over private-use codepoints (`components/Web/plugin.ts`), which
27
- * belongs to the markdown pipeline that stays with the surface.
10
+ * The number matches a marker in the prose. Minting that marker belongs to the
11
+ * markdown pipeline, which stays with the surface.
28
12
  */
29
13
  import { SizableText, XStack, YStack } from '@hanzo/gui';
30
14
  import { slot, tip } from '../backends/gui/slot.js';
31
- /** Card width, px. The extension's is 168 and it cites chat's 160; the point of
32
- * a fixed width is that a strip of them scans as a row rather than as ragged
33
- * columns, so it is one number and not a range. */
15
+ /** Card width, px. Fixed, so a strip scans as a row rather than ragged columns. */
34
16
  const CARD = 168;
35
17
  export function Sources({ sources, title = 'Sources', onOpen, ...props }) {
36
18
  if (sources.length === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"Sources.js","sourceRoot":"","sources":["../../src/chat/Sources.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sources.js","sourceRoot":"","sources":["../../src/chat/Sources.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;GASG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAEhD,mFAAmF;AACnF,MAAM,IAAI,GAAG,GAAG,CAAA;AA0BhB,MAAM,UAAU,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAgB;IACpF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAErC,OAAO,CACL,MAAC,MAAM,OAAK,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAC,IAAI,KAAK,KAAK,aAC7C,MAAC,MAAM,IAAC,KAAK,EAAC,QAAQ,EAAC,GAAG,EAAC,MAAM,aAC/B,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,UAAU,EAAC,KAAK,EAAC,KAAK,EAAC,UAAU,YACrD,KAAK,GACM,EACd,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,SAAS,YACnC,OAAO,CAAC,MAAM,GACH,IACP,EAIT,KAAC,MAAM,OACD,IAAI,CAAC,eAAe,CAAC,EACzB,QAAQ,EAAC,QAAQ,EACjB,OAAO,EAAC,SAAS,EACjB,GAAG,EAAC,IAAI,EACR,EAAE,EAAC,IAAI,YAEN,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAC1B,KAAC,UAAU,IAAiB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,IAAvD,MAAM,CAAC,EAAE,CAAkD,CAC7E,CAAC,GACK,IACF,CACV,CAAA;AACH,CAAC;AASD,MAAM,UAAU,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAmB;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAA;IAEzC,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,aAAa,CAAC,EACvB,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,CAAC,EACT,GAAG,EAAC,MAAM,EACV,CAAC,EAAC,MAAM,EACR,OAAO,EAAC,IAAI,EACZ,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,EAAE,EAAC,SAAS,EACZ,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EACrC,OAAO,EAAE,KAAK,EACd,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAClC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,gBAEnB,MAAM,CAAC,KAAK,KACpB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EACrB,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,EAC1D,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,KAC7C,KAAK,aAET,MAAC,MAAM,IAAC,KAAK,EAAC,QAAQ,EAAC,GAAG,EAAC,MAAM,aAC9B,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CACf,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,SAAS,YACnC,KAAK,GACM,CACf,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,MAAM,IACL,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,MAAM,EAAE,CAAC,EACT,KAAK,EAAC,QAAQ,EACd,OAAO,EAAC,QAAQ,EAChB,OAAO,EAAC,IAAI,EACZ,QAAQ,EAAC,QAAQ,EACjB,EAAE,EAAC,SAAS,YAEX,MAAM,CAAC,IAAI,IAAI,CACd,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,YACpC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAClB,CACf,GACM,EACT,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,EAAC,aAAa,EAAE,CAAC,YACrD,KAAK,GACM,IACP,EAGT,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,EAAC,aAAa,EAAE,CAAC,YACrD,MAAM,CAAC,KAAK,GACD,IACP,CACV,CAAA;AACH,CAAC"}
@@ -7,51 +7,29 @@ const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  * Step — something the assistant did on the way to the answer, and how it went.
8
8
  *
9
9
  * A tool call, a retrieval, a plan, a stretch of reasoning, a progress report:
10
- * every one of them is a named region that reports a state and opens to show
11
- * its detail. Two repos had written that arrangement NINE times without ever
12
- * naming it — hanzo/chat once (`ToolCall.tsx` + `ProgressText.tsx`), hanzo.app
13
- * eight (`chat-panel/index.tsx` `ToolDisplay`, `SyntheticErrorDisplay`,
14
- * `ReasoningDisplay`, `PlanDisplay`, `AgentDisplay`, `ProgressDisplay`, the
15
- * inline `project_context` block, and the builder's own `CollapsibleSection` in
16
- * `ask-ai/chat-thread.tsx:330`). Nine chances to order the header differently,
17
- * and they took most of them.
10
+ * each is a named region that reports a state and opens to show its detail.
11
+ * The header, the state mark, the disclosure and the frame are here; what goes
12
+ * inside is `children`.
18
13
  *
19
- * What goes INSIDE stays the surface's: chat renders the input as a code block
20
- * and the result through its own markdown, the app renders
21
- * `JSON.stringify(parameters, null, 2)`. That is `children`. The header, the
22
- * state mark, the disclosure and the frame are the same drawing in all nine and
23
- * they are here.
14
+ * Open/closed is `Collapsible`, so `aria-expanded`, `aria-controls` and the
15
+ * keyboard come from the primitive.
24
16
  *
25
- * The open/closed behaviour is `Collapsible`, not a hand-rolled height
26
- * animation. Both existing implementations rolled their own — chat measures
27
- * `scrollHeight` in a `useLayoutEffect`, keeps a `ResizeObserver` alive and
28
- * transitions an explicit pixel height — and that is the keyboard handling and
29
- * the `aria-expanded`/`aria-controls` pair re-derived by hand each time. The
30
- * primitive already has them.
31
- *
32
- * There is no duration and no elapsed time. Neither implementation shows one,
33
- * and chat's apparent progress is not measured at all: `useProgress.ts:54`
34
- * ticks a `setInterval` by 0.007 every 200ms and caps at 0.95 until the server
35
- * says otherwise. A number that is invented should not be given a place to
36
- * render.
17
+ * No duration: nothing upstream measures one, and a progress ratio ticked by a
18
+ * timer is not a measurement.
37
19
  */
38
20
  const gui_1 = require("@hanzo/gui");
39
21
  const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
40
22
  const gui_2 = require("../backends/gui/index.cjs");
41
23
  const slot_1 = require("../backends/gui/slot.cjs");
42
- /** Edge of the state mark, px. One size, so the header never reflows on a state
43
- * change — a step that finishes must not move the text beside it. */
24
+ /** Edge of the state mark, px. One size, so a state change never reflows the
25
+ * header. */
44
26
  const MARK = 13;
45
27
  /**
46
28
  * The mark for each state. `running` is the one that moves.
47
29
  *
48
- * Tinted on the glyph, never on the box: `XStack` is a View and has no `color`,
49
- * so a colour set there type-errors rather than cascading — which is this
50
- * package's "a prop must actually arrive" rule catching a habit borrowed from
51
- * the DOM. Written as four call sites rather than a lookup table because the
52
- * Spinner and the three glyphs do not share a props type: the icons take a
53
- * themed `GetThemeValueForKey<'color'>` and the Spinner takes a plain string,
54
- * and the table that unified them only typechecked by widening both to `any`.
30
+ * Tinted on the glyph: `XStack` is a View and takes no `color`. Four call sites
31
+ * rather than a table because the Spinner and the icons do not share a props
32
+ * type — the icons take a themed colour, the Spinner a plain string.
55
33
  */
56
34
  const mark = (status) => {
57
35
  switch (status) {
@@ -66,16 +44,12 @@ const mark = (status) => {
66
44
  }
67
45
  };
68
46
  function Step({ name, status = 'done', detail, children, defaultOpen, open, onOpenChange, ...props }) {
69
- // A step with no body is a statement, not a control. Rendering a dead chevron
70
- // and a focusable trigger over nothing is how a keyboard user is sent to a
71
- // stop that does not answer.
47
+ // A step with no body is a statement, not a control: no chevron, no trigger,
48
+ // no keyboard stop that does not answer.
72
49
  const opens = children != null;
73
50
  const header = ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: "$2", px: "$3", py: "$2", width: "100%", children: [(0, jsx_runtime_1.jsx)(gui_1.XStack, { width: MARK + 1, items: "center", justify: "center", shrink: 0, children: mark(status) }), (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$color12", numberOfLines: 1, children: name }), detail ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$color10", numberOfLines: 1, shrink: 1, children: detail })) : null, (0, jsx_runtime_1.jsx)(gui_1.XStack, { flex: 1 }), opens ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.ChevronDown, { size: 13, color: "$color10" }) : null] }));
74
51
  return ((0, jsx_runtime_1.jsxs)(gui_2.Collapsible, { ...(0, slot_1.slot)('step'), "data-status": status, open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, width: "100%", rounded: "$4", borderWidth: 1,
75
- // The failure edge, not a red one. `product/tone.ts` states the rule this
76
- // package works under — "this system has no colour to spend" — and marks
77
- // its `stopped` register with a border rather than a fill. A step that
78
- // errored is set apart the same way, so it still reads as a failure in a
79
- // brand that retunes the whole ramp.
52
+ // An edge, not a red fill — `product/tone.ts` marks `stopped` the same
53
+ // way, so it survives a brand that retunes the ramp.
80
54
  borderColor: status === 'error' ? '$color9' : '$borderColor', bg: "$color2", overflow: "hidden", ...props, children: [opens ? (0, jsx_runtime_1.jsx)(gui_2.CollapsibleTrigger, { width: "100%", children: header }) : header, opens ? ((0, jsx_runtime_1.jsx)(gui_2.CollapsibleContent, { children: (0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('step-body'), px: "$3", py: "$2.5", gap: "$2", borderTopWidth: 1, borderColor: "$borderColor", children: children }) })) : null] }));
81
55
  }
@@ -1,33 +1,21 @@
1
1
  import type { ComponentProps, ReactNode } from 'react';
2
2
  import { Collapsible } from '../backends/gui/index.js';
3
- /**
4
- * How a step went.
5
- *
6
- * Four, from the union of what the two implementations track. chat reports
7
- * `error`, `cancelled` and a progress ratio it treats as running-or-done
8
- * (`ToolCall.tsx:139`); the app reports `pending | executing | completed |
9
- * failed` (`chat-panel/index.tsx:97`) — and `pending` and `executing` draw the
10
- * same thing, because from the reader's side a step that has not started and a
11
- * step that is running are both "not yet".
12
- */
3
+ /** How a step went. A step that has not started and one that is running draw
4
+ * the same thing: from the reader's side both are "not yet". */
13
5
  export type Ran = 'running' | 'done' | 'error' | 'cancelled';
14
6
  export interface StepProps extends Omit<ComponentProps<typeof Collapsible>, 'children' | 'open' | 'defaultOpen' | 'onOpenChange'> {
15
7
  /** What ran — a tool name, "Reasoning", "Plan". */
16
8
  name: string;
17
9
  status?: Ran;
18
- /**
19
- * One line beside the name: the command, the path, the query. Clamped to a
20
- * single line — the app truncates its own to 50 characters
21
- * (`chat-panel/index.tsx:1148`) precisely because an untruncated one wraps
22
- * the header and moves the chevron.
23
- */
10
+ /** One line beside the name: the command, the path, the query. Clamped, or it
11
+ * wraps the header and moves the chevron. */
24
12
  detail?: string;
25
13
  /** Revealed when open. Omit it and the step has nothing to open, so it does
26
14
  * not offer to: no chevron, no trigger, no keyboard stop. */
27
15
  children?: ReactNode;
28
16
  /** Uncontrolled. */
29
17
  defaultOpen?: boolean;
30
- /** Controlled — the app holds every step's state in one `Set` on the panel. */
18
+ /** Controlled. */
31
19
  open?: boolean;
32
20
  onOpenChange?: (open: boolean) => void;
33
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Step.d.ts","sourceRoot":"","sources":["../../src/chat/Step.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtD,OAAO,EAAE,WAAW,EAAmD,MAAM,iBAAiB,CAAA;AAG9F;;;;;;;;;GASG;AACH,MAAM,MAAM,GAAG,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAA;AA8B5D,MAAM,WAAW,SACf,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC;IACtG,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;kEAC8D;IAC9D,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,oBAAoB;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC;AAED,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,MAAe,EACf,MAAM,EACN,QAAQ,EACR,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,SAAS,2CA6DX"}
1
+ {"version":3,"file":"Step.d.ts","sourceRoot":"","sources":["../../src/chat/Step.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtD,OAAO,EAAE,WAAW,EAAmD,MAAM,iBAAiB,CAAA;AAG9F;iEACiE;AACjE,MAAM,MAAM,GAAG,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAA;AA0B5D,MAAM,WAAW,SACf,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC;IACtG,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ;kDAC8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;kEAC8D;IAC9D,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,oBAAoB;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kBAAkB;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC;AAED,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,MAAe,EACf,MAAM,EACN,QAAQ,EACR,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,SAAS,2CAyDX"}