@nadicodeai/ui 10.0.2 → 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +15 -9
  28. package/dist/components/footer.d.ts.map +1 -1
  29. package/dist/components/footer.js +6 -27
  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
@@ -17,6 +17,7 @@ import { noMonoTitleRegister } from "./rules/no-mono-title-register.js";
17
17
  import { noPackageComponentRedefinition } from "./rules/no-package-component-redefinition.js";
18
18
  import { noPairedSizeUtility } from "./rules/no-paired-size-utility.js";
19
19
  import { noRestingSettingsControl } from "./rules/no-resting-settings-control.js";
20
+ import { oneControlHeight } from "./rules/one-control-height.js";
20
21
  import { noShadcnAppearanceOverride } from "./rules/no-shadcn-appearance-override.js";
21
22
  import { noSubjectDerivedExpectation } from "./rules/no-subject-derived-expectation.js";
22
23
  import { noUnpinnedVercelFunctionsImport } from "./rules/no-unpinned-vercel-functions-import.js";
@@ -25,6 +26,7 @@ import { noRepaintedFocus } from "./rules/no-repainted-focus.js";
25
26
  import { noInvalidTokenUtility } from "./rules/no-invalid-token-utility.js";
26
27
  import { noTokenCategoryBypass } from "./rules/no-token-category-bypass.js";
27
28
  import { serverActionDiscipline } from "./rules/server-action-discipline.js";
29
+ import { settingsSectionDescription } from "./rules/settings-section-description.js";
28
30
  import { shadcnComposition } from "./rules/shadcn-composition.js";
29
31
 
30
32
  /**
@@ -104,7 +106,9 @@ const plugin = {
104
106
  "no-unpinned-vercel-functions-import": noUnpinnedVercelFunctionsImport,
105
107
  "no-invalid-token-utility": noInvalidTokenUtility,
106
108
  "no-token-category-bypass": noTokenCategoryBypass,
109
+ "one-control-height": oneControlHeight,
107
110
  "server-action-discipline": serverActionDiscipline,
111
+ "settings-section-description": settingsSectionDescription,
108
112
  "shadcn-composition": shadcnComposition,
109
113
  },
110
114
  };
@@ -12,7 +12,7 @@
12
12
  * One hop, and no further: nothing chains through a second binding, nothing
13
13
  * crosses a file, nothing evaluates a condition or a template, and no value the
14
14
  * hop cannot see is guessed at. That is the minimum that holds the package
15
- * contract's repaint ban (`packages/ui/docs/contract.md`) against the way
15
+ * repaint ban (`packages/design-system/DESIGN.md`, "Components") against the way
16
16
  * this repository actually authors classes — a tone table beside its component
17
17
  * and a lookup at the call site, as in
18
18
  * `apps/portal/src/components/portal-overview/overview-usage-tone.ts`. Without the
@@ -1,7 +1,7 @@
1
1
  /*
2
- * The @nadicodeai/ui package contract (`packages/ui/docs/contract.md`):
3
- * "Consumers compose structure. Appearance — colour, elevation, radius,
4
- * opacity, the primitive's own border — belongs to the package." A caller that
2
+ * The design system (`packages/design-system/DESIGN.md`, "Components"): "A page
3
+ * arranges and sizes a component and never restyles it: a new appearance is a
4
+ * typed variant or slot added to the component." A caller that
5
5
  * repaints an imported primitive forks its appearance into the call site, where
6
6
  * the next token change does not reach it.
7
7
  *
@@ -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":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mCAAmC,CAAC;AAClD,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC"}
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"}