@nadicodeai/ui 10.1.0 → 12.1.1

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 (96) hide show
  1. package/AGENTS.md +39 -24
  2. package/README.md +58 -124
  3. package/dist/agent-orb.d.ts +1 -1
  4. package/dist/agent-orb.d.ts.map +1 -1
  5. package/dist/assets/brand/index.json +1 -1
  6. package/dist/components/action-menu.js +1 -1
  7. package/dist/components/agent-card.d.ts.map +1 -1
  8. package/dist/components/agent-card.js +2 -4
  9. package/dist/components/agent-orb.d.ts +11 -5
  10. package/dist/components/agent-orb.d.ts.map +1 -1
  11. package/dist/components/agent-orb.js +8 -6
  12. package/dist/components/alert.js +3 -3
  13. package/dist/components/badge.js +6 -6
  14. package/dist/components/brand-field.d.ts +2 -0
  15. package/dist/components/brand-field.d.ts.map +1 -1
  16. package/dist/components/brand-field.js +3 -1
  17. package/dist/components/button.d.ts +1 -1
  18. package/dist/components/button.d.ts.map +1 -1
  19. package/dist/components/button.js +4 -5
  20. package/dist/components/carousel.js +2 -2
  21. package/dist/components/chart-bar-horizontal.js +1 -1
  22. package/dist/components/chart.js +1 -1
  23. package/dist/components/command.js +1 -1
  24. package/dist/components/context-menu.js +1 -1
  25. package/dist/components/diff-count.js +1 -1
  26. package/dist/components/dropdown-menu.js +3 -3
  27. package/dist/components/footer.d.ts +4 -7
  28. package/dist/components/footer.d.ts.map +1 -1
  29. package/dist/components/footer.js +1 -4
  30. package/dist/components/item.js +1 -1
  31. package/dist/components/kpi-card.js +2 -2
  32. package/dist/components/label-system.d.ts +1 -5
  33. package/dist/components/label-system.d.ts.map +1 -1
  34. package/dist/components/label-system.js +2 -6
  35. package/dist/components/menu-choice-row.js +1 -1
  36. package/dist/components/menubar.js +1 -1
  37. package/dist/components/object-workspace.js +1 -1
  38. package/dist/components/progress.js +1 -1
  39. package/dist/components/scope-switcher.d.ts +24 -0
  40. package/dist/components/scope-switcher.d.ts.map +1 -0
  41. package/dist/components/scope-switcher.js +34 -0
  42. package/dist/components/settings-section.d.ts +2 -1
  43. package/dist/components/settings-section.d.ts.map +1 -1
  44. package/dist/components/settings-section.js +2 -2
  45. package/dist/components/status-dot.js +1 -1
  46. package/dist/components/status-row.js +1 -1
  47. package/dist/components/table.d.ts.map +1 -1
  48. package/dist/components/table.js +1 -1
  49. package/dist/components/tabs.d.ts +11 -5
  50. package/dist/components/tabs.d.ts.map +1 -1
  51. package/dist/components/tabs.js +37 -5
  52. package/dist/components/tooltip.js +1 -1
  53. package/dist/components/trend-badge.d.ts.map +1 -1
  54. package/dist/components/trend-badge.js +1 -2
  55. package/dist/eslint/index.js +4 -0
  56. package/dist/eslint/rules/jsx-class-utility.js +1 -1
  57. package/dist/eslint/rules/no-shadcn-appearance-override.js +3 -3
  58. package/dist/eslint/rules/one-control-height.js +94 -0
  59. package/dist/eslint/rules/settings-section-description.js +45 -0
  60. package/dist/index.d.ts +1 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +1 -1
  63. package/dist/internal/agent-orb-motion.d.ts +1 -0
  64. package/dist/internal/agent-orb-motion.d.ts.map +1 -1
  65. package/dist/internal/agent-orb-motion.js +6 -3
  66. package/dist/internal/agent-orb.d.ts +10 -2
  67. package/dist/internal/agent-orb.d.ts.map +1 -1
  68. package/dist/internal/agent-orb.js +19 -9
  69. package/dist/internal/assistant-ui/attachment.js +4 -4
  70. package/dist/internal/assistant-ui/follow-up-suggestions.js +1 -1
  71. package/dist/internal/assistant-ui/markdown-text.js +4 -4
  72. package/dist/internal/assistant-ui/reasoning.js +2 -2
  73. package/dist/internal/assistant-ui/thread.d.ts.map +1 -1
  74. package/dist/internal/assistant-ui/thread.js +11 -9
  75. package/dist/internal/assistant-ui/tool-group.js +2 -2
  76. package/dist/styles/components.css +9 -5
  77. package/dist/styles/globals.css +43 -0
  78. package/package.json +3 -4
  79. package/dist/components/handoff-banner.d.ts +0 -9
  80. package/dist/components/handoff-banner.d.ts.map +0 -1
  81. package/dist/components/handoff-banner.js +0 -6
  82. package/docs/activity.md +0 -113
  83. package/docs/agent-orb.md +0 -168
  84. package/docs/component-classification.md +0 -45
  85. package/docs/consuming-cross-repo.md +0 -116
  86. package/docs/contract.md +0 -388
  87. package/docs/icon-assets.md +0 -106
  88. package/docs/migration/1.0.0.md +0 -75
  89. package/docs/migration/10.0.0.md +0 -144
  90. package/docs/migration/2.0.0.md +0 -69
  91. package/docs/migration/6.0.0.md +0 -30
  92. package/docs/migration/9.0.0.md +0 -35
  93. package/docs/migration/base-ui-migration.md +0 -62
  94. package/docs/model-identity.md +0 -18
  95. package/docs/product-compositions.md +0 -96
  96. package/docs/product-sections.md +0 -200
@@ -0,0 +1,94 @@
1
+ /*
2
+ * Product chrome uses the 32px control.
3
+ *
4
+ * DESIGN.md ("Layout") gives every control in a product's chrome one height,
5
+ * `control-height`, with a 14px label at 500. The small sizes a control
6
+ * component still ships (`xs`, `sm`, `icon-xs`, `icon-sm`) exist for a control
7
+ * nested inside dense content in another product, such as a composer; a
8
+ * surface that enables this rule has none. The failure this catches: the
9
+ * Portal's header actions rendered at 28px with a 12.8px label beside 32px
10
+ * buttons in the card below them, because each caller picked `size="sm"`.
11
+ *
12
+ * What is read is a JSX element that is a control (a name ending in `Button`
13
+ * or `Trigger`, or a `Toggle`/`ToggleGroupItem`) and its `size` attribute, plus
14
+ * the `triggerSize` attribute a confirm form passes to the button it renders,
15
+ * plus the `size` key of a `buttonVariants({ ... })` or `toggleVariants({ ... })`
16
+ * call that styles a link as a button.
17
+ * A string literal is read directly and through both branches of a
18
+ * conditional, so `size={compact ? "sm" : "default"}` is reported too.
19
+ *
20
+ * Standard tool checked first: `no-restricted-syntax` can select
21
+ * `JSXAttribute[name.name="size"][value.value="sm"]` but not the element names
22
+ * that make it a control, nor the branches of a conditional value, without a
23
+ * selector per combination.
24
+ */
25
+ import { jsxComponentName } from "./jsx-class-utility.js";
26
+
27
+ const SMALL_SIZES = new Set(["xs", "sm", "icon-xs", "icon-sm"]);
28
+ const CONTROL_NAMES = new Set(["Toggle", "ToggleGroupItem"]);
29
+ const VARIANT_FUNCTIONS = new Set(["buttonVariants", "toggleVariants"]);
30
+
31
+ function isControl(name) {
32
+ return typeof name === "string" && (CONTROL_NAMES.has(name) || /(?:Button|Trigger)$/.test(name));
33
+ }
34
+
35
+ function literals(node) {
36
+ if (!node) return [];
37
+ switch (node.type) {
38
+ case "Literal":
39
+ return typeof node.value === "string" ? [{ node, value: node.value }] : [];
40
+ case "JSXExpressionContainer":
41
+ return literals(node.expression);
42
+ case "ConditionalExpression":
43
+ return [...literals(node.consequent), ...literals(node.alternate)];
44
+ case "LogicalExpression":
45
+ return literals(node.right);
46
+ case "TemplateLiteral":
47
+ return node.expressions.length === 0
48
+ ? [{ node, value: node.quasis.map((quasi) => quasi.value.cooked).join("") }]
49
+ : [];
50
+ default:
51
+ return [];
52
+ }
53
+ }
54
+
55
+ export const oneControlHeight = {
56
+ meta: {
57
+ type: "problem",
58
+ docs: {
59
+ description: "Require the 32px control height for every control in product chrome",
60
+ },
61
+ schema: [],
62
+ messages: {
63
+ smallControl:
64
+ '{{attribute}}="{{size}}" renders this control below the 32px control height. Product chrome uses one control: drop the size for the default, or use "icon" for an icon-only control (DESIGN.md "Layout", rule/one-control-height).',
65
+ },
66
+ },
67
+ create(context) {
68
+ const reportSmall = (valueNode, attribute) => {
69
+ for (const { node, value } of literals(valueNode)) {
70
+ if (!SMALL_SIZES.has(value)) continue;
71
+ context.report({ node, messageId: "smallControl", data: { attribute, size: value } });
72
+ }
73
+ };
74
+ return {
75
+ CallExpression(call) {
76
+ if (call.callee.type !== "Identifier" || !VARIANT_FUNCTIONS.has(call.callee.name)) return;
77
+ const [options] = call.arguments;
78
+ if (options?.type !== "ObjectExpression") return;
79
+ for (const property of options.properties) {
80
+ if (property.type !== "Property" || property.computed) continue;
81
+ const key = property.key.type === "Identifier" ? property.key.name : property.key.value;
82
+ if (key === "size") reportSmall(property.value, "size");
83
+ }
84
+ },
85
+ JSXAttribute(attribute) {
86
+ const attributeName = attribute.name.type === "JSXIdentifier" ? attribute.name.name : "";
87
+ if (attributeName !== "size" && attributeName !== "triggerSize") return;
88
+ if (attributeName === "size" && !isControl(jsxComponentName(attribute.parent, context)))
89
+ return;
90
+ reportSmall(attribute.value, attributeName);
91
+ },
92
+ };
93
+ },
94
+ };
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Every settings section says what it changes.
3
+ *
4
+ * DESIGN.md ("Cards and sections") gives a settings section a one-line
5
+ * description under its title, the line that tells a person what changing the
6
+ * fields below will do before they change them. The failure this catches: the
7
+ * Portal's Profile photo and Personal details sections, whose titles named the
8
+ * content and nothing said what the change reaches.
9
+ *
10
+ * What is read is a `SettingsSection` element and whether it passes a
11
+ * `description` attribute. A spread may carry one, so an element with a spread
12
+ * attribute is not reported.
13
+ *
14
+ * Standard tool checked first: `no-restricted-syntax` can select
15
+ * `JSXOpeningElement[name.name="SettingsSection"]:not(:has(JSXAttribute[name.name="description"]))`,
16
+ * but not through a renamed import, which `jsxComponentName` resolves.
17
+ */
18
+ import { jsxComponentName } from "./jsx-class-utility.js";
19
+
20
+ export const settingsSectionDescription = {
21
+ meta: {
22
+ type: "problem",
23
+ docs: {
24
+ description: "Require a one-line description on every SettingsSection",
25
+ },
26
+ schema: [],
27
+ messages: {
28
+ missingDescription:
29
+ 'This SettingsSection has no description. Say in one line what changing it does, under its title (DESIGN.md "Cards and sections", rule/settings-section-described).',
30
+ },
31
+ },
32
+ create(context) {
33
+ return {
34
+ JSXOpeningElement(node) {
35
+ if (jsxComponentName(node, context) !== "SettingsSection") return;
36
+ const described = node.attributes.some(
37
+ (attribute) =>
38
+ attribute.type === "JSXSpreadAttribute" ||
39
+ (attribute.name?.type === "JSXIdentifier" && attribute.name.name === "description"),
40
+ );
41
+ if (!described) context.report({ node, messageId: "missingDescription" });
42
+ },
43
+ };
44
+ },
45
+ };
package/dist/index.d.ts CHANGED
@@ -58,7 +58,6 @@ export * from "./components/file-type-icon.js";
58
58
  export * from "./components/footer.js";
59
59
  export * from "./components/form.js";
60
60
  export * from "./components/glass-control.js";
61
- export * from "./components/handoff-banner.js";
62
61
  export * from "./components/house-icons.js";
63
62
  export * from "./components/hover-card.js";
64
63
  export * from "./components/input.js";
@@ -87,6 +86,7 @@ export * from "./components/radio-group.js";
87
86
  export * from "./components/reading-column.js";
88
87
  export * from "./components/resizable.js";
89
88
  export * from "./components/run-timeline.js";
89
+ export * from "./components/scope-switcher.js";
90
90
  export * from "./components/scroll-area.js";
91
91
  export * from "./components/select.js";
92
92
  export * from "./components/separator.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -58,7 +58,6 @@ export * from "./components/file-type-icon.js";
58
58
  export * from "./components/footer.js";
59
59
  export * from "./components/form.js";
60
60
  export * from "./components/glass-control.js";
61
- export * from "./components/handoff-banner.js";
62
61
  export * from "./components/house-icons.js";
63
62
  export * from "./components/hover-card.js";
64
63
  export * from "./components/input.js";
@@ -87,6 +86,7 @@ export * from "./components/radio-group.js";
87
86
  export * from "./components/reading-column.js";
88
87
  export * from "./components/resizable.js";
89
88
  export * from "./components/run-timeline.js";
89
+ export * from "./components/scope-switcher.js";
90
90
  export * from "./components/scroll-area.js";
91
91
  export * from "./components/select.js";
92
92
  export * from "./components/separator.js";
@@ -1,5 +1,6 @@
1
1
  import type { AgentOrbFigure } from "./agent-orb.js";
2
2
  export type AgentOrbState = "idle" | "working" | "waiting" | "blocked" | "thinking" | "done";
3
+ export declare function nativeSpeed(form: AgentOrbFigure): number;
3
4
  export declare function stateSpeed(state: AgentOrbState, form: AgentOrbFigure): number;
4
5
  /**
5
6
  * Reduced motion turns movement off and keeps opacity and colour, so a
@@ -1 +1 @@
1
- {"version":3,"file":"agent-orb-motion.d.ts","sourceRoot":"","sources":["../../src/internal/agent-orb-motion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAa7F,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,UAKpE;AAKD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAIlE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM;;;;;;;;EAsCjF;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,MAAM,GAAG,OAAO;AACvB,mFAAmF;AACnF,GAAG,SAAI,QAgER"}
1
+ {"version":3,"file":"agent-orb-motion.d.ts","sourceRoot":"","sources":["../../src/internal/agent-orb-motion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAa7F,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,UAE/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,UAKpE;AAKD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAIlE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM;;;;;;;;EAsCjF;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,MAAM,GAAG,OAAO;AACvB,mFAAmF;AACnF,GAAG,SAAI,QAgER"}
@@ -8,11 +8,14 @@ const personalities = {
8
8
  braid: { speed: 0.65, tilt: -0.2 },
9
9
  morph: { speed: 0.9, tilt: 0.12 },
10
10
  };
11
+ export function nativeSpeed(form) {
12
+ return personalities[form].speed;
13
+ }
11
14
  export function stateSpeed(state, form) {
12
15
  // Idle is 0: only an Agent at work moves, so a list of twenty shows at a
13
16
  // glance which ones are busy.
14
17
  const speed = { idle: 0, working: 1, thinking: 1, waiting: 0, blocked: 0, done: 0.65 };
15
- return speed[state] * personalities[form].speed;
18
+ return speed[state] * nativeSpeed(form);
16
19
  }
17
20
  /** The breath's period, in seconds. */
18
21
  const BREATH_SECONDS = 1.6;
@@ -112,7 +115,7 @@ ink = 1) {
112
115
  const gradient = context.createLinearGradient(size * 0.1, size * 0.7, size * 0.9, size * 0.3);
113
116
  colors.forEach((color, index) => gradient.addColorStop(index / Math.max(1, colors.length - 1), color));
114
117
  context.strokeStyle = gradient;
115
- context.lineCap = "round";
118
+ context.lineCap = "butt";
116
119
  for (let segment = 0; segment < 100; segment++) {
117
120
  const fraction = segment / 100;
118
121
  const angle = head - tailLength + tailLength * fraction;
@@ -124,7 +127,7 @@ ink = 1) {
124
127
  context.lineWidth = Math.max(0.65, size * 0.027 * taper);
125
128
  context.beginPath();
126
129
  context.moveTo(...point(angle));
127
- context.lineTo(...point(angle + tailLength / 100 + 0.002));
130
+ context.lineTo(...point(angle + tailLength / 100));
128
131
  context.stroke();
129
132
  }
130
133
  }
@@ -15,6 +15,8 @@ export type AgentOrbFigure = AgentOrbForm | "nadia";
15
15
  export type AgentOrbSize = 20 | 24 | 32 | 40 | 64 | 96 | 160;
16
16
  /** How loudly one orb reads on its own ground. */
17
17
  export type AgentOrbPresence = "plain" | "over-picture";
18
+ /** Status motion follows the Agent's real state; ambient motion shows only the native form. */
19
+ export type AgentOrbMotion = "status" | "ambient";
18
20
  /**
19
21
  * The vendor's `ribbon` geometry (thinking-orbs 0.3.1, MIT, Jakub Antalik),
20
22
  * repeated here only so every dot carries its lane through the depth sort. The
@@ -22,7 +24,7 @@ export type AgentOrbPresence = "plain" | "over-picture";
22
24
  * a stripe jump between lanes as the ribbon turns; the lane is the stable id.
23
25
  */
24
26
  export declare function stripedRibbonFrame(size: number, t: number, opts: ModeOpts): OrbFrame;
25
- export type AgentOrbMountOptions = {
27
+ type AgentOrbMountBase = {
26
28
  form: AgentOrbFigure;
27
29
  /**
28
30
  * The size the canvas is laid out at when nothing else sizes it. The engine
@@ -30,9 +32,15 @@ export type AgentOrbMountOptions = {
30
32
  */
31
33
  size: AgentOrbSize;
32
34
  paused?: boolean;
33
- state?: AgentOrbState;
34
35
  presence?: AgentOrbPresence;
35
36
  };
37
+ export type AgentOrbMountOptions = AgentOrbMountBase & ({
38
+ motion?: "status";
39
+ state?: AgentOrbState;
40
+ } | {
41
+ motion: "ambient";
42
+ state?: never;
43
+ });
36
44
  export declare function mountAgentOrb(canvas: HTMLCanvasElement, options: AgentOrbMountOptions): {
37
45
  destroy(): void;
38
46
  setPaused(_value: boolean): void;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-orb.d.ts","sourceRoot":"","sources":["../../src/internal/agent-orb.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,QAAQ,EAId,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAC;AAE5B,QAAA,MAAM,aAAa;;;;;;;;CAQ0B,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,aAAa,CAAC;AACtD,kEAAkE;AAClE,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,OAAO,CAAC;AACpD,MAAM,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;AAE7D,kDAAkD;AAClD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,cAAc,CAAC;AA+BxD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAuDpF;AAmFD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB;;sBAIzC,OAAO;qBAAuB,aAAa;EAqJvF"}
1
+ {"version":3,"file":"agent-orb.d.ts","sourceRoot":"","sources":["../../src/internal/agent-orb.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,QAAQ,EAId,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,aAAa,EAMnB,MAAM,oBAAoB,CAAC;AAE5B,QAAA,MAAM,aAAa;;;;;;;;CAQ0B,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,aAAa,CAAC;AACtD,kEAAkE;AAClE,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,OAAO,CAAC;AACpD,MAAM,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;AAE7D,kDAAkD;AAClD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,cAAc,CAAC;AACxD,+FAA+F;AAC/F,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AA+BlD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAuDpF;AA4FD,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,cAAc,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAClD,CAAC;IAAE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC;AAExF,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB;;sBAIzC,OAAO;qBAAuB,aAAa;EA0JvF"}
@@ -1,5 +1,5 @@
1
1
  import { finalizeFrame, MODE_FRAMES, makeProj, radiusScale, resolvePreset, } from "thinking-orbs/engine";
2
- import { motionPose, paintOrbCue, reducedBreath, stateSpeed, } from "./agent-orb-motion.js";
2
+ import { motionPose, nativeSpeed, paintOrbCue, reducedBreath, stateSpeed, } from "./agent-orb-motion.js";
3
3
  const agentOrbForms = {
4
4
  orbit: "working",
5
5
  globe: "searching",
@@ -82,8 +82,8 @@ export function stripedRibbonFrame(size, t, opts) {
82
82
  y,
83
83
  z,
84
84
  r: ((opts.rBase ?? 1.1) + (opts.rDepth ?? 1.7) * depth) * (1 - 0.25 * edge) * scale,
85
- white: 0.52 - 0.44 * depth + 0.18 * edge,
86
- a: 0.4 + 0.6 * depth,
85
+ white: 0.08 + 0.1 * edge,
86
+ a: 0.55 + 0.45 * depth,
87
87
  stripe: Math.min(3, Math.floor((lane / lanes) * 4)),
88
88
  });
89
89
  }
@@ -98,7 +98,7 @@ function paintAgentOrb(context, input) {
98
98
  ? stripedRibbonFrame(size, seconds, preset.opts)
99
99
  : MODE_FRAMES[preset.mode](size, seconds, preset.opts);
100
100
  context.clearRect(0, 0, size, size);
101
- const pose = motionPose(form, state, reduced ? (state === "done" ? 2 : 0.6) : age);
101
+ const pose = motionPose(form, input.motion === "ambient" ? "idle" : state, reduced ? (state === "done" ? 2 : 0.6) : age);
102
102
  const gestureSeconds = reduced ? 0.8 : age / (state === "done" ? 0.575 : 0.2875);
103
103
  const project = (x, y) => {
104
104
  const dx = (x - size / 2) * pose.sx;
@@ -112,7 +112,9 @@ function paintAgentOrb(context, input) {
112
112
  ];
113
113
  };
114
114
  const ink = pose.opacity * breath;
115
- paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "back", breath);
115
+ if (input.motion === "status") {
116
+ paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "back", breath);
117
+ }
116
118
  context.fillStyle = color;
117
119
  context.strokeStyle = color;
118
120
  for (const line of frame.lines) {
@@ -131,7 +133,9 @@ function paintAgentOrb(context, input) {
131
133
  context.fill();
132
134
  }
133
135
  context.globalAlpha = 1;
134
- paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "front", breath);
136
+ if (input.motion === "status") {
137
+ paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "front", breath);
138
+ }
135
139
  }
136
140
  export function mountAgentOrb(canvas, options) {
137
141
  const { form, presence = "plain" } = options;
@@ -147,6 +151,7 @@ export function mountAgentOrb(canvas, options) {
147
151
  let age = 0;
148
152
  let breath = 0;
149
153
  let state = options.state ?? "idle";
154
+ const orbMotion = options.motion ?? "status";
150
155
  let previous = null;
151
156
  let lastPaint = 0;
152
157
  let ratio = 1;
@@ -179,6 +184,7 @@ export function mountAgentOrb(canvas, options) {
179
184
  reduced: motion.matches,
180
185
  breath: motion.matches ? reducedBreath(state, breath) : 1,
181
186
  presence,
187
+ motion: orbMotion,
182
188
  celebrationColors,
183
189
  stripeColors,
184
190
  });
@@ -188,7 +194,9 @@ export function mountAgentOrb(canvas, options) {
188
194
  return false;
189
195
  // Reduced motion holds every pose; only a busy orb keeps breathing.
190
196
  if (motion.matches)
191
- return state === "thinking" || state === "working";
197
+ return orbMotion === "status" && (state === "thinking" || state === "working");
198
+ if (orbMotion === "ambient")
199
+ return true;
192
200
  return (state !== "idle" &&
193
201
  state !== "waiting" &&
194
202
  !(state === "blocked" && age >= 0.3) &&
@@ -203,8 +211,10 @@ export function mountAgentOrb(canvas, options) {
203
211
  if (motion.matches)
204
212
  breath += elapsed;
205
213
  else {
206
- seconds += elapsed * stateSpeed(state, form);
207
- age += elapsed * (state === "done" ? 0.575 : 0.2875);
214
+ seconds +=
215
+ elapsed * (orbMotion === "ambient" ? nativeSpeed(form) : stateSpeed(state, form));
216
+ if (orbMotion === "status")
217
+ age += elapsed * (state === "done" ? 0.575 : 0.2875);
208
218
  }
209
219
  }
210
220
  previous = now;
@@ -45,7 +45,7 @@ const AttachmentPreviewDialog = ({ children }) => {
45
45
  const src = useAttachmentSrc();
46
46
  if (!src)
47
47
  return children;
48
- return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { nativeButton: false, className: "aui-attachment-preview-trigger", render: isValidElement(children) ? children : _jsx("button", { type: "button" }) }), _jsxs(DialogContent, { className: "aui-attachment-preview-dialog-content [&>button]:bg-foreground/60 [&>button]:hover:bg-foreground/80 [&_svg]:text-background p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0!", children: [_jsx(DialogTitle, { className: "aui-sr-only sr-only", children: "Image Attachment Preview" }), _jsx("div", { className: "aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden rounded-sm", children: _jsx(AttachmentPreview, { src: src }) })] })] }));
48
+ return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { nativeButton: false, className: "aui-attachment-preview-trigger", render: isValidElement(children) ? children : _jsx("button", { type: "button" }) }), _jsxs(DialogContent, { className: "aui-attachment-preview-dialog-content p-2 sm:max-w-3xl", children: [_jsx(DialogTitle, { className: "aui-sr-only sr-only", children: "Image Attachment Preview" }), _jsx("div", { className: "aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden rounded-sm", children: _jsx(AttachmentPreview, { src: src }) })] })] }));
49
49
  };
50
50
  const AttachmentThumb = () => {
51
51
  const src = useAttachmentSrc();
@@ -78,10 +78,10 @@ const AttachmentUI = () => {
78
78
  const errorMessage = useAuiState((s) => s.attachment.status.type === "incomplete" && s.attachment.status.reason === "error"
79
79
  ? (s.attachment.status.message ?? "Upload failed")
80
80
  : undefined);
81
- return (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsxs(AttachmentPrimitive.Root, { className: cn("aui-attachment-root relative", isComposer && "nc-transition-opacity", isImage && !isComposer && "aui-attachment-root-message only:*:first:size-24"), children: [_jsx(AttachmentPreviewDialog, { children: _jsxs(TooltipTrigger, { render: _jsx("div", { className: cn("aui-attachment-tile nc-transition-transform relative size-14 cursor-pointer overflow-hidden rounded-[calc(var(--composer-radius)-var(--composer-padding))] bg-muted after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-border after:ring-inset hover:after:bg-foreground/10", isError && "after:ring-destructive/60"), role: "button", tabIndex: 0, "aria-label": `${typeLabel} attachment${isError ? ", upload failed" : isUploading ? ", uploading" : ""}` }), children: [_jsx(AttachmentThumb, {}), isUploading && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-uploading nc-transition-opacity absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[2px]", children: _jsx(WaitingLine, { className: "w-8 text-muted-foreground", decorative: true }) })), isError && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-error nc-transition-opacity absolute inset-0 flex items-center justify-center bg-background/70 backdrop-blur-[2px]", children: _jsx(AlertCircleIcon, { className: "text-destructive size-4" }) }))] }) }), isComposer && _jsx(AttachmentRemove, {})] }), _jsxs(TooltipContent, { side: "top", children: [_jsx(AttachmentPrimitive.Name, {}), errorMessage && _jsx("p", { className: "aui-attachment-error-message", children: errorMessage })] })] }) }));
81
+ return (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsxs(AttachmentPrimitive.Root, { className: cn("aui-attachment-root relative", isComposer && "nc-transition-opacity", isImage && !isComposer && "aui-attachment-root-message only:*:first:size-24"), children: [_jsx(AttachmentPreviewDialog, { children: _jsxs(TooltipTrigger, { render: _jsx("div", { className: cn("aui-attachment-tile nc-transition-transform relative size-14 cursor-pointer overflow-hidden rounded-[calc(var(--composer-radius)-var(--composer-padding))] bg-muted after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-border after:ring-inset hover:after:bg-foreground/10", isError && "after:ring-destructive/60"), role: "button", tabIndex: 0, "aria-label": `${typeLabel} attachment${isError ? ", upload failed" : isUploading ? ", uploading" : ""}` }), children: [_jsx(AttachmentThumb, {}), isUploading && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-uploading nc-transition-opacity absolute inset-0 flex items-center justify-center bg-muted", children: _jsx(WaitingLine, { className: "w-8", decorative: true }) })), isError && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-error nc-transition-opacity absolute inset-0 flex items-center justify-center bg-muted", children: _jsx(AlertCircleIcon, { className: "text-destructive size-4" }) }))] }) }), isComposer && _jsx(AttachmentRemove, {})] }), _jsxs(TooltipContent, { side: "top", children: [_jsx(AttachmentPrimitive.Name, {}), errorMessage && _jsx("p", { className: "aui-attachment-error-message", children: errorMessage })] })] }) }));
82
82
  };
83
83
  const AttachmentRemove = () => {
84
- return (_jsx(AttachmentPrimitive.Remove, { render: _jsx(TooltipIconButton, { tooltip: "Remove file", className: "aui-attachment-tile-remove absolute end-1 top-1 size-5 rounded-full bg-foreground/70! text-background! backdrop-blur-sm after:absolute after:-inset-1.5 hover:bg-foreground/85!", side: "top" }), children: _jsx(XIcon, { className: "aui-attachment-remove-icon size-3 stroke-[2.5]" }) }));
84
+ return (_jsx(AttachmentPrimitive.Remove, { render: _jsx(TooltipIconButton, { tooltip: "Remove file", className: "aui-attachment-tile-remove absolute end-1 top-1 size-5 rounded-md bg-background nc-elevation-floating after:absolute after:-inset-1.5", side: "top" }), children: _jsx(XIcon, { className: "aui-attachment-remove-icon size-3 stroke-[2.5]" }) }));
85
85
  };
86
86
  export const UserMessageAttachments = () => {
87
87
  return (_jsx("div", { className: "aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2", children: _jsx(MessagePrimitive.Attachments, { children: () => _jsx(AttachmentUI, {}) }) }));
@@ -90,5 +90,5 @@ export const ComposerAttachments = () => {
90
90
  return (_jsx("div", { className: "aui-composer-attachments flex w-full flex-row items-center gap-2 overflow-x-auto empty:hidden", children: _jsx(ComposerPrimitive.Attachments, { children: () => _jsx(AttachmentUI, {}) }) }));
91
91
  };
92
92
  export const ComposerAddAttachment = () => {
93
- return (_jsx(ComposerPrimitive.AddAttachment, { render: _jsx(TooltipIconButton, { tooltip: "Add Attachment", side: "bottom", variant: "ghost", size: "icon", className: "aui-composer-add-attachment size-7 rounded-full p-1 text-xs font-semibold hover:bg-muted", "aria-label": "Add Attachment" }), children: _jsx(PlusIcon, { className: "aui-attachment-add-icon size-4.5 stroke-[1.5px]" }) }));
93
+ return (_jsx(ComposerPrimitive.AddAttachment, { render: _jsx(TooltipIconButton, { tooltip: "Add Attachment", side: "bottom", variant: "ghost", size: "icon", className: "aui-composer-add-attachment size-7 rounded-md p-1 text-xs font-semibold", "aria-label": "Add Attachment" }), children: _jsx(PlusIcon, { className: "aui-attachment-add-icon size-4.5 stroke-[1.5px]" }) }));
94
94
  };
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { AuiIf, ThreadPrimitive, useAuiState } from "@assistant-ui/react";
4
4
  const FollowupSuggestionsRow = () => {
5
5
  const suggestions = useAuiState((s) => s.thread.suggestions);
6
- return (_jsx("div", { className: "aui-thread-followup-suggestions -my-1 w-full overflow-x-auto py-1 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: _jsx("div", { className: "mx-auto flex min-h-8 w-max items-center gap-2 px-0.5", children: suggestions.map((suggestion, index) => (_jsx(ThreadPrimitive.Suggestion, { className: "aui-thread-followup-suggestion nc-transition-paint rounded-full border bg-background px-3 py-1 text-sm whitespace-nowrap hover:bg-muted/80", prompt: suggestion.prompt,
6
+ return (_jsx("div", { className: "aui-thread-followup-suggestions -my-1 w-full overflow-x-auto py-1 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: _jsx("div", { className: "mx-auto flex min-h-8 w-max items-center gap-2 px-0.5", children: suggestions.map((suggestion, index) => (_jsx(ThreadPrimitive.Suggestion, { className: "aui-thread-followup-suggestion nc-transition-paint rounded-md border border-border bg-background px-3 py-1 text-sm whitespace-nowrap hover:bg-accent", prompt: suggestion.prompt,
7
7
  // `method="replace"` + `autoSend` under their current names: the
8
8
  // library renamed them to `clearComposer` + `send` and deprecated
9
9
  // the old pair, with the same behaviour behind both.
@@ -22,7 +22,7 @@ const CodeHeader = ({ language, code }) => {
22
22
  return;
23
23
  void copyToClipboard();
24
24
  };
25
- return (_jsxs("div", { className: "aui-code-header-root border-border/50 bg-muted/50 mt-3 flex items-center justify-between rounded-t-xl border border-b-0 px-3.5 py-1.5 text-xs", children: [_jsx("span", { className: "aui-code-header-language text-muted-foreground font-medium lowercase", children: language }), _jsxs(TooltipIconButton, { tooltip: "Copy", onClick: onCopy, children: [!isCopied && _jsx(CopyIcon, {}), isCopied && _jsx(CheckIcon, {})] })] }));
25
+ return (_jsxs("div", { className: "aui-code-header-root border-border bg-muted mt-3 flex items-center justify-between rounded-t-md border border-b-0 px-3.5 py-1.5 text-xs", children: [_jsx("span", { className: "aui-code-header-language text-muted-foreground font-medium lowercase", children: language }), _jsxs(TooltipIconButton, { tooltip: "Copy", onClick: onCopy, children: [!isCopied && _jsx(CopyIcon, {}), isCopied && _jsx(CheckIcon, {})] })] }));
26
26
  };
27
27
  const defaultComponents = memoizeMarkdownComponents({
28
28
  h1: ({ className, ...props }) => (_jsx("h1", { className: cn("aui-md-h1 mt-5 mb-2 scroll-m-20 text-xl font-semibold first:mt-0 last:mb-0", className), ...props })),
@@ -38,13 +38,13 @@ const defaultComponents = memoizeMarkdownComponents({
38
38
  ol: ({ className, ...props }) => (_jsx("ol", { className: cn("aui-md-ol marker:text-muted-foreground my-3 ms-5 list-decimal [&>li]:mt-1", className), ...props })),
39
39
  hr: ({ className, ...props }) => (_jsx("hr", { className: cn("aui-md-hr border-muted-foreground/20 my-3", className), ...props })),
40
40
  table: ({ className, ...props }) => (_jsx("table", { className: cn("aui-md-table my-3 w-full border-separate border-spacing-0 overflow-y-auto", className), ...props })),
41
- th: ({ className, ...props }) => (_jsx("th", { className: cn("aui-md-th bg-muted px-3 py-1.5 text-start font-medium first:rounded-ss-lg last:rounded-se-lg [[align=center]]:text-center [[align=right]]:text-right", className), ...props })),
41
+ th: ({ className, ...props }) => (_jsx("th", { className: cn("aui-md-th bg-muted px-3 py-1.5 text-start font-medium first:rounded-ss-md last:rounded-se-md [[align=center]]:text-center [[align=right]]:text-right", className), ...props })),
42
42
  td: ({ className, ...props }) => (_jsx("td", { className: cn("aui-md-td border-muted-foreground/20 border-s border-b px-3 py-1.5 text-start last:border-e [[align=center]]:text-center [[align=right]]:text-right", className), ...props })),
43
- tr: ({ className, ...props }) => (_jsx("tr", { className: cn("aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-es-lg [&:last-child>td:last-child]:rounded-ee-lg", className), ...props })),
43
+ tr: ({ className, ...props }) => (_jsx("tr", { className: cn("aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-es-md [&:last-child>td:last-child]:rounded-ee-md", className), ...props })),
44
44
  li: ({ className, ...props }) => (_jsx("li", { className: cn("aui-md-li leading-relaxed", className), ...props })),
45
45
  strong: ({ className, ...props }) => (_jsx("strong", { className: cn("aui-md-strong font-semibold", className), ...props })),
46
46
  sup: ({ className, ...props }) => (_jsx("sup", { className: cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className), ...props })),
47
- pre: ({ className, ...props }) => (_jsx("pre", { className: cn("aui-md-pre border-border/50 bg-muted/30 overflow-x-auto rounded-t-none rounded-b-xl border border-t-0 p-3.5 text-[13px] leading-relaxed", className), ...props })),
47
+ pre: ({ className, ...props }) => (_jsx("pre", { className: cn("aui-md-pre border-border bg-muted overflow-x-auto rounded-t-none rounded-b-md border border-t-0 p-3.5 text-[13px] leading-relaxed", className), ...props })),
48
48
  code: function Code({ className, ...props }) {
49
49
  const isCodeBlock = useIsMarkdownCodeBlock();
50
50
  return (_jsx("code", { className: cn(!isCodeBlock &&
@@ -12,9 +12,9 @@ const ReasoningPreviewContext = createContext(false);
12
12
  const reasoningVariants = cva("aui-reasoning-root mb-4 w-full", {
13
13
  variants: {
14
14
  variant: {
15
- outline: "rounded-lg border px-3 py-2",
15
+ outline: "rounded-md border px-3 py-2",
16
16
  ghost: "",
17
- muted: "bg-muted/50 rounded-lg px-3 py-2",
17
+ muted: "bg-muted rounded-md px-3 py-2",
18
18
  },
19
19
  },
20
20
  defaultVariants: {
@@ -1 +1 @@
1
- {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/thread.tsx"],"names":[],"mappings":"AAyBA,OAAO,EASL,gBAAgB,EAGhB,KAAK,4BAA4B,EAElC,MAAM,qBAAqB,CAAC;AAe7B,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,EAAE,EACP,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACxD,SAAS,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAC;IACrF,cAAc,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAC;CAC3F,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAWF,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAQlC,CAAC"}
1
+ {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/thread.tsx"],"names":[],"mappings":"AA2BA,OAAO,EASL,gBAAgB,EAGhB,KAAK,4BAA4B,EAElC,MAAM,qBAAqB,CAAC;AAe7B,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,EAAE,EACP,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACxD,SAAS,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAC;IACrF,cAAc,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAC;CAC3F,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAWF,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAQlC,CAAC"}
@@ -7,7 +7,9 @@ import { Reasoning, ReasoningContent, ReasoningRoot, ReasoningText, ReasoningTri
7
7
  import { ToolFallback } from "./tool-fallback.js";
8
8
  import { ToolGroupContent, ToolGroupRoot, ToolGroupTrigger, } from "./tool-group.js";
9
9
  import { TooltipIconButton } from "./tooltip-icon-button.js";
10
+ import { AgentOrb } from "../../components/agent-orb.js";
10
11
  import { Button } from "../../components/button.js";
12
+ import { Alert } from "../../components/alert.js";
11
13
  import { cn } from "../../lib/utils.js";
12
14
  import { ActionBarMorePrimitive, ActionBarPrimitive, AuiIf, BranchPickerPrimitive, ComposerPrimitive, ErrorPrimitive, groupPartByType, MessagePrimitive, SuggestionPrimitive, ThreadPrimitive, useAuiState, } from "@assistant-ui/react";
13
15
  import { ArrowDownIcon, ArrowUpIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, CopyIcon, DownloadIcon, MicIcon, MoreHorizontalIcon, PencilIcon, RefreshCwIcon, SquareIcon, } from "lucide-react";
@@ -26,7 +28,7 @@ const ThreadRoot = ({ isEmpty }) => {
26
28
  return (_jsx(ThreadPrimitive.Root, { className: "aui-root aui-thread-root bg-background @container flex h-full flex-col", style: {
27
29
  ["--thread-max-width"]: "44rem",
28
30
  ["--composer-bg"]: "var(--color-muted)",
29
- ["--composer-radius"]: "1.5rem",
31
+ ["--composer-radius"]: "var(--radius-md)",
30
32
  ["--composer-padding"]: "8px",
31
33
  }, children: _jsx(ThreadPrimitive.Viewport, { turnAnchor: "top", "data-slot": "aui_thread-viewport", className: "relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth", children: _jsxs("div", { className: cn("mx-auto flex w-full max-w-(--thread-max-width) flex-1 flex-col px-4 pt-4", isEmpty && "justify-center"), children: [_jsx(AuiIf, { condition: isNewChatView, children: _jsx(Welcome, {}) }), _jsx("div", { "data-slot": "aui_message-group", className: "mb-14 flex flex-col gap-y-6 empty:hidden", children: _jsx(ThreadPrimitive.Messages, { children: () => _jsx(ThreadMessage, {}) }) }), _jsxs(ThreadPrimitive.ViewportFooter, { className: cn("aui-thread-viewport-footer bg-background flex flex-col gap-4 overflow-visible pb-4 md:pb-6", !isEmpty && "sticky bottom-0 mt-auto rounded-t-(--composer-radius)"), children: [_jsx(ThreadScrollToBottom, {}), _jsx(ThreadFollowupSuggestions, {}), _jsx(Composer, {}), _jsx(AuiIf, { condition: (s) => isNewChatView(s) && s.composer.isEmpty, children: _jsx(ThreadSuggestions, {}) })] })] }) }) }));
32
34
  };
@@ -41,7 +43,7 @@ const ThreadMessage = () => {
41
43
  return _jsx(AssistantMessageComponent, {});
42
44
  };
43
45
  const ThreadScrollToBottom = () => {
44
- return (_jsx(ThreadPrimitive.ScrollToBottom, { render: _jsx(TooltipIconButton, { tooltip: "Scroll to bottom", variant: "outline", className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full border-border bg-background p-4 hover:bg-accent disabled:invisible" }), children: _jsx(ArrowDownIcon, {}) }));
46
+ return (_jsx(ThreadPrimitive.ScrollToBottom, { render: _jsx(TooltipIconButton, { tooltip: "Scroll to bottom", variant: "outline", className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-md p-4 disabled:invisible" }), children: _jsx(ArrowDownIcon, {}) }));
45
47
  };
46
48
  const ThreadWelcome = () => {
47
49
  return (_jsx("div", { className: "aui-thread-welcome-root mb-6 flex flex-col items-center px-4 text-center", children: _jsx("h1", { className: "aui-thread-welcome-message-inner text-2xl font-semibold", children: "How can I help you today?" }) }));
@@ -50,16 +52,16 @@ const ThreadSuggestions = () => {
50
52
  return (_jsx("div", { className: "aui-thread-welcome-suggestions flex w-full flex-wrap items-center justify-center gap-2 px-4", children: _jsx(ThreadPrimitive.Suggestions, { children: () => _jsx(ThreadSuggestionItem, {}) }) }));
51
53
  };
52
54
  const ThreadSuggestionItem = () => {
53
- return (_jsx("div", { className: "aui-thread-welcome-suggestion-display", children: _jsxs(SuggestionPrimitive.Trigger, { send: true, render: _jsx(Button, { variant: "ghost", className: "aui-thread-welcome-suggestion text-foreground hover:bg-muted border-border/60 h-auto gap-1.5 rounded-full border px-3.5 py-1.5 text-sm font-normal whitespace-nowrap transition-colors" }), children: [_jsx(SuggestionPrimitive.Title, { className: "aui-thread-welcome-suggestion-text-1" }), _jsx(SuggestionPrimitive.Description, { className: "aui-thread-welcome-suggestion-text-2 empty:hidden" })] }) }));
55
+ return (_jsx("div", { className: "aui-thread-welcome-suggestion-display", children: _jsxs(SuggestionPrimitive.Trigger, { send: true, render: _jsx(Button, { variant: "ghost", className: "aui-thread-welcome-suggestion text-foreground hover:bg-muted border-border h-auto gap-1.5 rounded-md border px-3.5 py-1.5 text-sm font-normal whitespace-nowrap transition-colors" }), children: [_jsx(SuggestionPrimitive.Title, { className: "aui-thread-welcome-suggestion-text-1" }), _jsx(SuggestionPrimitive.Description, { className: "aui-thread-welcome-suggestion-text-2 empty:hidden" })] }) }));
54
56
  };
55
57
  const Composer = () => {
56
58
  return (_jsx(ComposerPrimitive.Root, { className: "aui-composer-root relative flex w-full flex-col", children: _jsxs(ComposerPrimitive.AttachmentDropzone, { render: _jsx("div", { "data-slot": "aui_composer-shell", className: "nc-transition-paint flex w-full flex-col gap-2 rounded-(--composer-radius) border border-border bg-(--composer-bg) p-(--composer-padding) focus-within:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:border-ring data-[dragging=true]:bg-accent" }), children: [_jsx(ComposerAttachments, {}), _jsx(ComposerPrimitive.Input, { placeholder: "Send a message...", className: "aui-composer-input caret-primary placeholder:text-muted-foreground/80 max-h-32 min-h-10 w-full resize-none bg-transparent px-2.5 py-1 text-base outline-none", rows: 1, autoFocus: true, enterKeyHint: "send", "aria-label": "Message input" }), _jsx(ComposerAction, {})] }) }));
57
59
  };
58
60
  const ComposerAction = () => {
59
- return (_jsxs("div", { className: "aui-composer-action-wrapper relative flex items-center justify-between", children: [_jsx(ComposerAddAttachment, {}), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(AuiIf, { condition: (s) => s.thread.capabilities.dictation, children: [_jsx(AuiIf, { condition: (s) => s.composer.dictation == null, children: _jsx(ComposerPrimitive.Dictate, { render: _jsx(TooltipIconButton, { tooltip: "Voice input", side: "bottom", type: "button", variant: "ghost", size: "icon", className: "aui-composer-dictate size-7 rounded-full", "aria-label": "Start voice input" }), children: _jsx(MicIcon, { className: "aui-composer-dictate-icon size-4" }) }) }), _jsx(AuiIf, { condition: (s) => s.composer.dictation != null, children: _jsx(ComposerPrimitive.StopDictation, { render: _jsx(TooltipIconButton, { tooltip: "Stop dictation", side: "bottom", type: "button", variant: "ghost", size: "icon", className: "aui-composer-stop-dictation text-destructive size-7 rounded-full", "aria-label": "Stop voice input" }), children: _jsx(SquareIcon, { className: "aui-composer-stop-dictation-icon size-3.5 fill-current motion-safe:animate-pulse" }) }) })] }), _jsx(AuiIf, { condition: (s) => !s.thread.isRunning, children: _jsx(ComposerPrimitive.Send, { render: _jsx(TooltipIconButton, { tooltip: "Send message", side: "bottom", type: "button", variant: "default", size: "icon", className: "aui-composer-send size-7 rounded-full", "aria-label": "Send message" }), children: _jsx(ArrowUpIcon, { className: "aui-composer-send-icon size-4.5" }) }) }), _jsx(AuiIf, { condition: (s) => s.thread.isRunning, children: _jsx(ComposerPrimitive.Cancel, { render: _jsx(Button, { type: "button", variant: "default", size: "icon", className: "aui-composer-cancel size-7 rounded-full", "aria-label": "Stop generating" }), children: _jsx(SquareIcon, { className: "aui-composer-cancel-icon size-3.5 fill-current" }) }) })] })] }));
61
+ return (_jsxs("div", { className: "aui-composer-action-wrapper relative flex items-center justify-between", children: [_jsx(ComposerAddAttachment, {}), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(AuiIf, { condition: (s) => s.thread.capabilities.dictation, children: [_jsx(AuiIf, { condition: (s) => s.composer.dictation == null, children: _jsx(ComposerPrimitive.Dictate, { render: _jsx(TooltipIconButton, { tooltip: "Voice input", side: "bottom", type: "button", variant: "ghost", size: "icon", className: "aui-composer-dictate size-7 rounded-md", "aria-label": "Start voice input" }), children: _jsx(MicIcon, { className: "aui-composer-dictate-icon size-4" }) }) }), _jsx(AuiIf, { condition: (s) => s.composer.dictation != null, children: _jsx(ComposerPrimitive.StopDictation, { render: _jsx(TooltipIconButton, { tooltip: "Stop dictation", side: "bottom", type: "button", variant: "ghost", size: "icon", className: "aui-composer-stop-dictation text-destructive size-7 rounded-md", "aria-label": "Stop voice input" }), children: _jsx(SquareIcon, { className: "aui-composer-stop-dictation-icon size-3.5 fill-current" }) }) })] }), _jsx(AuiIf, { condition: (s) => !s.thread.isRunning, children: _jsx(ComposerPrimitive.Send, { render: _jsx(TooltipIconButton, { tooltip: "Send message", side: "bottom", type: "button", variant: "default", size: "icon", className: "aui-composer-send size-7 rounded-md", "aria-label": "Send message" }), children: _jsx(ArrowUpIcon, { className: "aui-composer-send-icon size-4.5" }) }) }), _jsx(AuiIf, { condition: (s) => s.thread.isRunning, children: _jsx(ComposerPrimitive.Cancel, { render: _jsx(Button, { type: "button", variant: "default", size: "icon", className: "aui-composer-cancel size-7 rounded-md", "aria-label": "Stop generating" }), children: _jsx(SquareIcon, { className: "aui-composer-cancel-icon size-3.5 fill-current" }) }) })] })] }));
60
62
  };
61
63
  const MessageError = () => {
62
- return (_jsx(MessagePrimitive.Error, { children: _jsx(ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-[var(--nc-error-deep)] bg-[var(--nc-error-soft)] p-3 text-sm text-[var(--nc-error-deep)]", children: _jsx(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) }));
64
+ return (_jsx(MessagePrimitive.Error, { children: _jsx(ErrorPrimitive.Root, { render: _jsx(Alert, { className: "aui-message-error-root mt-2", variant: "destructive" }), children: _jsx(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) }));
63
65
  };
64
66
  const AssistantMessage = () => {
65
67
  const { ToolFallback: ToolFallbackComponent = ToolFallback, ToolGroup, ReasoningGroup, } = useContext(ThreadComponentsContext);
@@ -95,23 +97,23 @@ const AssistantMessage = () => {
95
97
  case "data":
96
98
  return part.dataRendererUI;
97
99
  case "indicator":
98
- return (_jsx("span", { "data-slot": "aui_assistant-message-indicator", className: "font-sans motion-safe:animate-pulse", "aria-label": "Assistant is working", children: "●" }));
100
+ return (_jsx("span", { "data-slot": "aui_assistant-message-indicator", className: "inline-flex", children: _jsx(AgentOrb, { form: "orbit", size: 20, state: "working", label: "Assistant is working" }) }));
99
101
  default:
100
102
  return null;
101
103
  }
102
104
  } }), _jsx(MessageError, {})] }), _jsxs("div", { "data-slot": "aui_assistant-message-footer", className: cn("ms-2 flex items-center", ACTION_BAR_HEIGHT), children: [_jsx(BranchPicker, {}), _jsx(AssistantActionBar, {})] })] }));
103
105
  };
104
106
  const AssistantActionBar = () => {
105
- return (_jsxs(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-assistant-action-bar-root nc-transition-opacity col-start-3 row-start-2 -ms-1 flex gap-1 text-muted-foreground", children: [_jsxs(ActionBarPrimitive.Copy, { render: _jsx(TooltipIconButton, { tooltip: "Copy" }), children: [_jsx(AuiIf, { condition: (s) => s.message.isCopied, children: _jsx(CheckIcon, {}) }), _jsx(AuiIf, { condition: (s) => !s.message.isCopied, children: _jsx(CopyIcon, {}) })] }), _jsx(ActionBarPrimitive.Reload, { render: _jsx(TooltipIconButton, { tooltip: "Refresh" }), children: _jsx(RefreshCwIcon, {}) }), _jsxs(ActionBarMorePrimitive.Root, { children: [_jsx(ActionBarMorePrimitive.Trigger, { render: _jsx(TooltipIconButton, { tooltip: "More", className: "data-[state=open]:bg-accent" }), children: _jsx(MoreHorizontalIcon, {}) }), _jsx(ActionBarMorePrimitive.Content, { side: "bottom", align: "start", sideOffset: 6, className: "aui-action-bar-more-content nc-transition-opacity z-50 min-w-[8rem] overflow-hidden rounded-xl border-0 bg-popover p-1.5 text-popover-foreground nc-elevation-floating data-[state=closed]:opacity-0 data-[state=open]:opacity-100", children: _jsxs(ActionBarPrimitive.ExportMarkdown, { render: _jsx(ActionBarMorePrimitive.Item, { className: "aui-action-bar-more-item hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm outline-none select-none" }), children: [_jsx(DownloadIcon, { className: "size-4" }), "Export as Markdown"] }) })] })] }));
107
+ return (_jsxs(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-assistant-action-bar-root nc-transition-opacity col-start-3 row-start-2 -ms-1 flex gap-1 text-muted-foreground", children: [_jsxs(ActionBarPrimitive.Copy, { render: _jsx(TooltipIconButton, { tooltip: "Copy" }), children: [_jsx(AuiIf, { condition: (s) => s.message.isCopied, children: _jsx(CheckIcon, {}) }), _jsx(AuiIf, { condition: (s) => !s.message.isCopied, children: _jsx(CopyIcon, {}) })] }), _jsx(ActionBarPrimitive.Reload, { render: _jsx(TooltipIconButton, { tooltip: "Refresh" }), children: _jsx(RefreshCwIcon, {}) }), _jsxs(ActionBarMorePrimitive.Root, { children: [_jsx(ActionBarMorePrimitive.Trigger, { render: _jsx(TooltipIconButton, { tooltip: "More", className: "data-[state=open]:bg-accent" }), children: _jsx(MoreHorizontalIcon, {}) }), _jsx(ActionBarMorePrimitive.Content, { side: "bottom", align: "start", sideOffset: 6, className: "aui-action-bar-more-content nc-transition-opacity z-50 min-w-[8rem] overflow-hidden rounded-md border-0 bg-popover p-1.5 text-popover-foreground nc-elevation-floating data-[state=closed]:opacity-0 data-[state=open]:opacity-100", children: _jsxs(ActionBarPrimitive.ExportMarkdown, { render: _jsx(ActionBarMorePrimitive.Item, { className: "aui-action-bar-more-item hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground flex cursor-pointer items-center gap-2 rounded-md px-2.5 py-1.5 text-sm outline-none select-none" }), children: [_jsx(DownloadIcon, { className: "size-4" }), "Export as Markdown"] }) })] })] }));
106
108
  };
107
109
  const UserMessage = () => {
108
- return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_user-message-root", className: "grid auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 [contain-intrinsic-size:auto_200px] [content-visibility:auto] [&:where(>*)]:col-start-2", "data-role": "user", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [_jsx("div", { className: "aui-user-message-content peer bg-muted text-foreground rounded-xl px-4 py-2 wrap-break-word empty:hidden", children: _jsx(MessagePrimitive.Parts, {}) }), _jsx("div", { className: "aui-user-action-bar-wrapper absolute start-0 top-1/2 -translate-x-full -translate-y-1/2 pe-2 peer-empty:hidden rtl:translate-x-full", children: _jsx(UserActionBar, {}) })] }), _jsx(BranchPicker, { "data-slot": "aui_user-branch-picker", className: "col-span-full col-start-1 row-start-3 -me-1 justify-end" })] }));
110
+ return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_user-message-root", className: "grid auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 [contain-intrinsic-size:auto_200px] [content-visibility:auto] [&:where(>*)]:col-start-2", "data-role": "user", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [_jsx("div", { className: "aui-user-message-content peer bg-muted text-foreground rounded-md px-4 py-2 wrap-break-word empty:hidden", children: _jsx(MessagePrimitive.Parts, {}) }), _jsx("div", { className: "aui-user-action-bar-wrapper absolute start-0 top-1/2 -translate-x-full -translate-y-1/2 pe-2 peer-empty:hidden rtl:translate-x-full", children: _jsx(UserActionBar, {}) })] }), _jsx(BranchPicker, { "data-slot": "aui_user-branch-picker", className: "col-span-full col-start-1 row-start-3 -me-1 justify-end" })] }));
109
111
  };
110
112
  const UserActionBar = () => {
111
113
  return (_jsx(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-user-action-bar-root flex flex-col items-end", children: _jsx(ActionBarPrimitive.Edit, { render: _jsx(TooltipIconButton, { tooltip: "Edit", className: "aui-user-action-edit" }), children: _jsx(PencilIcon, {}) }) }));
112
114
  };
113
115
  const EditComposer = () => {
114
- return (_jsx(MessagePrimitive.Root, { "data-slot": "aui_edit-composer-wrapper", className: "flex flex-col px-2 [contain-intrinsic-size:auto_200px] [content-visibility:auto]", children: _jsxs(ComposerPrimitive.Root, { className: "aui-edit-composer-root ms-auto flex w-full max-w-[85%] flex-col rounded-(--composer-radius) border border-border bg-(--composer-bg)", children: [_jsx(ComposerPrimitive.Input, { className: "aui-edit-composer-input text-foreground min-h-14 w-full resize-none bg-transparent px-4 pt-3 pb-1 text-base outline-none", autoFocus: true }), _jsxs("div", { className: "aui-edit-composer-footer mx-2.5 mb-2.5 flex items-center gap-1.5 self-end", children: [_jsx(ComposerPrimitive.Cancel, { render: _jsx(Button, { variant: "ghost", size: "sm", className: "h-8 rounded-full px-3.5" }), children: "Cancel" }), _jsx(ComposerPrimitive.Send, { render: _jsx(Button, { size: "sm", className: "h-8 rounded-full px-3.5" }), children: "Update" })] })] }) }));
116
+ return (_jsx(MessagePrimitive.Root, { "data-slot": "aui_edit-composer-wrapper", className: "flex flex-col px-2 [contain-intrinsic-size:auto_200px] [content-visibility:auto]", children: _jsxs(ComposerPrimitive.Root, { className: "aui-edit-composer-root ms-auto flex w-full max-w-[85%] flex-col rounded-(--composer-radius) border border-border bg-(--composer-bg)", children: [_jsx(ComposerPrimitive.Input, { className: "aui-edit-composer-input text-foreground min-h-14 w-full resize-none bg-transparent px-4 pt-3 pb-1 text-base outline-none", autoFocus: true }), _jsxs("div", { className: "aui-edit-composer-footer mx-2.5 mb-2.5 flex items-center gap-1.5 self-end", children: [_jsx(ComposerPrimitive.Cancel, { render: _jsx(Button, { variant: "ghost", size: "sm", className: "h-8 px-3.5" }), children: "Cancel" }), _jsx(ComposerPrimitive.Send, { render: _jsx(Button, { size: "sm", className: "h-8 px-3.5" }), children: "Update" })] })] }) }));
115
117
  };
116
118
  const BranchPicker = ({ className, ...rest }) => {
117
119
  return (_jsxs(BranchPickerPrimitive.Root, { hideWhenSingleBranch: true, className: cn("aui-branch-picker-root text-muted-foreground -ms-2 me-2 inline-flex items-center text-xs", className), ...rest, children: [_jsx(BranchPickerPrimitive.Previous, { render: _jsx(TooltipIconButton, { tooltip: "Previous" }), children: _jsx(ChevronLeftIcon, {}) }), _jsxs("span", { className: "aui-branch-picker-state font-medium", children: [_jsx(BranchPickerPrimitive.Number, {}), " / ", _jsx(BranchPickerPrimitive.Count, {})] }), _jsx(BranchPickerPrimitive.Next, { render: _jsx(TooltipIconButton, { tooltip: "Next" }), children: _jsx(ChevronRightIcon, {}) })] }));
@@ -10,9 +10,9 @@ const ANIMATION_DURATION = 200;
10
10
  const toolGroupVariants = cva("aui-tool-group-root group/tool-group w-full", {
11
11
  variants: {
12
12
  variant: {
13
- outline: "rounded-lg border py-3",
13
+ outline: "rounded-md border py-3",
14
14
  ghost: "",
15
- muted: "border-muted-foreground/30 bg-muted/30 rounded-lg border py-3",
15
+ muted: "border-border bg-muted rounded-md border py-3",
16
16
  },
17
17
  },
18
18
  defaultVariants: { variant: "outline" },