@shapesos/clay 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -16342,8 +16342,12 @@ var require_lottie = __commonJS({
16342
16342
  // src/index.ts
16343
16343
  var src_exports = {};
16344
16344
  __export(src_exports, {
16345
+ BUTTON_SIZE: () => BUTTON_SIZE,
16346
+ BUTTON_VARIANT: () => BUTTON_VARIANT,
16347
+ Button: () => Button2,
16345
16348
  ChatContext: () => ChatContext,
16346
16349
  ChatMessage: () => ChatMessage,
16350
+ ICON_POSITION: () => ICON_POSITION,
16347
16351
  Icon: () => Icon,
16348
16352
  IconButton: () => IconButton,
16349
16353
  IconCtrl: () => IconCtrl,
@@ -16353,9 +16357,11 @@ __export(src_exports, {
16353
16357
  MESSAGE_ROLE: () => MESSAGE_ROLE,
16354
16358
  TextArea: () => TextArea,
16355
16359
  colors: () => colors,
16360
+ convertTableToCSV: () => convertTableToCSV,
16356
16361
  fontFamilies: () => fontFamilies,
16357
16362
  markdownToPlainText: () => markdownToPlainText,
16358
16363
  mergeRefs: () => mergeRefs,
16364
+ parseMarkdownTable: () => parseMarkdownTable,
16359
16365
  typographyMixin: () => typographyMixin,
16360
16366
  typographyStyles: () => typographyStyles,
16361
16367
  typographyTypes: () => typographyTypes,
@@ -16748,13 +16754,68 @@ function typographyMixin(type) {
16748
16754
  }
16749
16755
 
16750
16756
  // src/components/chat/chat-message-content/chat-message-content.tsx
16757
+ var import_react3 = require("react");
16751
16758
  var import_react_markdown = __toESM(require("react-markdown"), 1);
16752
16759
  var import_remark_breaks = __toESM(require("remark-breaks"), 1);
16753
16760
  var import_remark_gfm = __toESM(require("remark-gfm"), 1);
16754
16761
 
16755
- // src/components/chat/chat-message-content/chat-message-content-styles.ts
16762
+ // src/components/chat/scrollable-table/scrollable-table.tsx
16763
+ var import_react2 = require("react");
16764
+
16765
+ // src/components/chat/chat-context/chat-context.ts
16766
+ var import_react = require("react");
16767
+ var ChatContext = (0, import_react.createContext)(null);
16768
+ function useChatContext() {
16769
+ const context = (0, import_react.useContext)(ChatContext);
16770
+ if (!context) {
16771
+ throw new Error("useChatContext must be used within a Chat.Root component");
16772
+ }
16773
+ return context;
16774
+ }
16775
+
16776
+ // src/components/chat/scrollable-table/scrollable-table-styles.ts
16756
16777
  var import_styled_components = __toESM(require("styled-components"), 1);
16757
- var ContentWrapper = import_styled_components.default.div`
16778
+ var TableContainer = import_styled_components.default.div`
16779
+ position: relative;
16780
+ margin-block: 8px 16px;
16781
+ `;
16782
+ var TableScroll = import_styled_components.default.div`
16783
+ width: 100%;
16784
+ overflow-x: auto;
16785
+ overflow-y: hidden;
16786
+ `;
16787
+ var TableActionsWrapper = import_styled_components.default.div`
16788
+ display: flex;
16789
+ justify-content: flex-start;
16790
+ margin-block: 8px 0;
16791
+ `;
16792
+ var TableActionsDivider = import_styled_components.default.div`
16793
+ height: 1px;
16794
+ background: ${colors["brown-40"]};
16795
+ margin-block: 8px 0;
16796
+ `;
16797
+
16798
+ // src/components/chat/scrollable-table/scrollable-table.tsx
16799
+ var import_jsx_runtime = require("react/jsx-runtime");
16800
+ function ScrollableTable({ node: _node, messageId, counter, ...props }) {
16801
+ const currentIndex = counter ? counter.value : 0;
16802
+ if (counter) {
16803
+ counter.value += 1;
16804
+ }
16805
+ const context = (0, import_react2.useContext)(ChatContext);
16806
+ const TableActions = context?.TableActions;
16807
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableContainer, { children: [
16808
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) }),
16809
+ TableActions && messageId && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
16810
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActions, { messageId, tableIndex: currentIndex }) }),
16811
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsDivider, {})
16812
+ ] })
16813
+ ] });
16814
+ }
16815
+
16816
+ // src/components/chat/chat-message-content/chat-message-content-styles.ts
16817
+ var import_styled_components2 = __toESM(require("styled-components"), 1);
16818
+ var ContentWrapper = import_styled_components2.default.div`
16758
16819
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
16759
16820
  color: ${colors["brown-100"]};
16760
16821
  word-break: break-word;
@@ -16870,30 +16931,30 @@ var ContentWrapper = import_styled_components.default.div`
16870
16931
  color: ${colors["brown-80"]};
16871
16932
  }
16872
16933
  `;
16873
- var TableScroll = import_styled_components.default.div`
16874
- width: 100%;
16875
- overflow-x: auto;
16876
- overflow-y: hidden;
16877
- margin-block: 8px 16px;
16878
- `;
16879
16934
 
16880
16935
  // src/components/chat/chat-message-content/chat-message-content.tsx
16881
- var import_jsx_runtime = require("react/jsx-runtime");
16882
- function ScrollableTable({ node: _node, ...props }) {
16883
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) });
16884
- }
16885
- var markdownComponents = {
16886
- table: ScrollableTable
16887
- };
16888
- function ChatMessageContent({ content: content2 }) {
16889
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: content2 }) });
16936
+ var import_jsx_runtime2 = require("react/jsx-runtime");
16937
+ function ChatMessageContent({ content: content2, messageId }) {
16938
+ const counter = { value: 0 };
16939
+ const sanitizedContent = content2.split("\n").filter((line) => {
16940
+ const t = line.trim();
16941
+ return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
16942
+ }).join("\n");
16943
+ const markdownComponents = (0, import_react3.useMemo)(
16944
+ () => ({
16945
+ table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ScrollableTable, { ...tableProps, messageId, counter }))
16946
+ }),
16947
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- counter is intentionally a fresh object each render for sequential table indexing
16948
+ [messageId]
16949
+ );
16950
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ContentWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: sanitizedContent }) });
16890
16951
  }
16891
16952
 
16892
16953
  // src/components/chat/chat-message-actions/chat-message-actions.tsx
16893
- var import_react5 = require("react");
16954
+ var import_react7 = require("react");
16894
16955
 
16895
16956
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
16896
- var import_react = require("react");
16957
+ var import_react4 = require("react");
16897
16958
 
16898
16959
  // node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs
16899
16960
  var defaultAttributes = {
@@ -16920,8 +16981,8 @@ var defaultAttributes = {
16920
16981
 
16921
16982
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
16922
16983
  var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
16923
- const Component = (0, import_react.forwardRef)(
16924
- ({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0, import_react.createElement)(
16984
+ const Component = (0, import_react4.forwardRef)(
16985
+ ({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0, import_react4.createElement)(
16925
16986
  "svg",
16926
16987
  {
16927
16988
  ref,
@@ -16938,8 +16999,8 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
16938
16999
  ...rest
16939
17000
  },
16940
17001
  [
16941
- title && (0, import_react.createElement)("title", { key: "svg-title" }, title),
16942
- ...iconNode.map(([tag, attrs]) => (0, import_react.createElement)(tag, attrs)),
17002
+ title && (0, import_react4.createElement)("title", { key: "svg-title" }, title),
17003
+ ...iconNode.map(([tag, attrs]) => (0, import_react4.createElement)(tag, attrs)),
16943
17004
  ...Array.isArray(children) ? children : [children]
16944
17005
  ]
16945
17006
  )
@@ -16965,10 +17026,10 @@ var __iconNode4 = [["path", { "d": "M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7
16965
17026
  var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode4);
16966
17027
 
16967
17028
  // src/components/icon/icon.tsx
16968
- var import_react2 = require("react");
17029
+ var import_react5 = require("react");
16969
17030
 
16970
17031
  // src/components/icon/icon-styles.ts
16971
- var import_styled_components2 = __toESM(require("styled-components"), 1);
17032
+ var import_styled_components3 = __toESM(require("styled-components"), 1);
16972
17033
  var STROKE_WIDTH_BY_SIZE = {
16973
17034
  12: 1.4,
16974
17035
  14: 1.4,
@@ -16981,7 +17042,7 @@ var DEFAULT_STROKE_WIDTH = 1.8;
16981
17042
  function getStrokeWidth(size) {
16982
17043
  return STROKE_WIDTH_BY_SIZE[size] ?? DEFAULT_STROKE_WIDTH;
16983
17044
  }
16984
- var IconWrapper = import_styled_components2.default.span`
17045
+ var IconWrapper = import_styled_components3.default.span`
16985
17046
  display: inline-flex;
16986
17047
  align-items: center;
16987
17048
  justify-content: center;
@@ -16990,10 +17051,10 @@ var IconWrapper = import_styled_components2.default.span`
16990
17051
  `;
16991
17052
 
16992
17053
  // src/components/icon/icon.tsx
16993
- var import_jsx_runtime2 = require("react/jsx-runtime");
17054
+ var import_jsx_runtime3 = require("react/jsx-runtime");
16994
17055
  var DEFAULT_SIZE = 16;
16995
- var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
16996
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
17056
+ var Icon = (0, import_react5.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
17057
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
16997
17058
  IconWrapper,
16998
17059
  {
16999
17060
  ref,
@@ -17001,13 +17062,13 @@ var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, s
17001
17062
  $color: color,
17002
17063
  "aria-label": ariaLabel,
17003
17064
  role: ariaLabel ? "img" : void 0,
17004
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
17065
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
17005
17066
  }
17006
17067
  );
17007
17068
  });
17008
17069
 
17009
17070
  // src/components/icon-button/icon-button-styles.ts
17010
- var import_styled_components3 = __toESM(require("styled-components"), 1);
17071
+ var import_styled_components4 = __toESM(require("styled-components"), 1);
17011
17072
  var PADDING = {
17012
17073
  short: {
17013
17074
  small: "4px",
@@ -17022,7 +17083,7 @@ var BORDER_RADIUS = {
17022
17083
  small: 6,
17023
17084
  medium: 10
17024
17085
  };
17025
- var Button = import_styled_components3.default.button`
17086
+ var Button = import_styled_components4.default.button`
17026
17087
  display: inline-flex;
17027
17088
  align-items: center;
17028
17089
  justify-content: center;
@@ -17050,7 +17111,7 @@ var Button = import_styled_components3.default.button`
17050
17111
  `;
17051
17112
 
17052
17113
  // src/components/icon-button/icon-button.tsx
17053
- var import_jsx_runtime3 = require("react/jsx-runtime");
17114
+ var import_jsx_runtime4 = require("react/jsx-runtime");
17054
17115
  var ICON_SIZE_BY_BUTTON_SIZE = {
17055
17116
  small: 16,
17056
17117
  medium: 20
@@ -17067,7 +17128,7 @@ function IconButton({
17067
17128
  as,
17068
17129
  "aria-label": ariaLabel
17069
17130
  }) {
17070
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
17131
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17071
17132
  Button,
17072
17133
  {
17073
17134
  className,
@@ -17079,24 +17140,13 @@ function IconButton({
17079
17140
  disabled,
17080
17141
  onClick: disabled ? void 0 : onClick,
17081
17142
  "aria-label": ariaLabel,
17082
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
17143
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
17083
17144
  }
17084
17145
  );
17085
17146
  }
17086
17147
 
17087
- // src/components/chat/chat-context/chat-context.ts
17088
- var import_react3 = require("react");
17089
- var ChatContext = (0, import_react3.createContext)(null);
17090
- function useChatContext() {
17091
- const context = (0, import_react3.useContext)(ChatContext);
17092
- if (!context) {
17093
- throw new Error("useChatContext must be used within a Chat.Root component");
17094
- }
17095
- return context;
17096
- }
17097
-
17098
17148
  // src/components/chat/hooks/use-copy-to-clipboard.ts
17099
- var import_react4 = require("react");
17149
+ var import_react6 = require("react");
17100
17150
 
17101
17151
  // src/utils/clipboard.ts
17102
17152
  function copyToClipboard(text2, options) {
@@ -17113,7 +17163,7 @@ var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUF
17113
17163
  function markdownToPlainText(markdown) {
17114
17164
  if (!markdown) return "";
17115
17165
  const inlineCodeSnippets = [];
17116
- let result = markdown.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
17166
+ let result = markdown.replace(/^<!--[\s\S]*?--!?>\n?/gm, "").replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
17117
17167
  inlineCodeSnippets.push(code);
17118
17168
  return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
17119
17169
  }).replace(/^#{1,6}\s+/gm, "").replace(/^(?:---|\*\*\*|___)\s*$/gm, "").replace(/\*{3}(.+?)\*{3}/g, "$1").replace(/\*{2}(.+?)\*{2}/g, "$1").replace(/_{2}(.+?)_{2}/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/_(.+?)_/g, "$1").replace(/~~(.+?)~~/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s?/gm, "").replace(/^\|[-:\s|]+\|\s*$/gm, "").replace(/^\|\s?/gm, "").replace(/\s?\|$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
@@ -17124,14 +17174,14 @@ function markdownToPlainText(markdown) {
17124
17174
  // src/components/chat/hooks/use-copy-to-clipboard.ts
17125
17175
  var RESET_DELAY_MS = 2e3;
17126
17176
  function useCopyToClipboard() {
17127
- const [isCopied, setIsCopied] = (0, import_react4.useState)(false);
17128
- const timeoutRef = (0, import_react4.useRef)(null);
17129
- (0, import_react4.useEffect)(() => {
17177
+ const [isCopied, setIsCopied] = (0, import_react6.useState)(false);
17178
+ const timeoutRef = (0, import_react6.useRef)(null);
17179
+ (0, import_react6.useEffect)(() => {
17130
17180
  return () => {
17131
17181
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
17132
17182
  };
17133
17183
  }, []);
17134
- const copy = (0, import_react4.useCallback)((text2) => {
17184
+ const copy = (0, import_react6.useCallback)((text2) => {
17135
17185
  copyToClipboard(markdownToPlainText(text2), {
17136
17186
  onSuccess: () => {
17137
17187
  setIsCopied(true);
@@ -17153,16 +17203,16 @@ var MESSAGE_ROLE = {
17153
17203
  };
17154
17204
 
17155
17205
  // src/components/chat/chat-message-actions/chat-message-actions-styles.ts
17156
- var import_styled_components4 = __toESM(require("styled-components"), 1);
17206
+ var import_styled_components5 = __toESM(require("styled-components"), 1);
17157
17207
  var FADE_DURATION_MS = 150;
17158
17208
  var ANIMATE_DURATION_MS = 200;
17159
- var ActionsContainer = import_styled_components4.default.div`
17209
+ var ActionsContainer = import_styled_components5.default.div`
17160
17210
  display: flex;
17161
17211
  opacity: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? 1 : 0};
17162
17212
  pointer-events: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? "auto" : "none"};
17163
17213
  transition: opacity ${FADE_DURATION_MS}ms ease;
17164
17214
  `;
17165
- var AnimatedAction = import_styled_components4.default.div`
17215
+ var AnimatedAction = import_styled_components5.default.div`
17166
17216
  display: flex;
17167
17217
  overflow: hidden;
17168
17218
  max-width: ${({ $visible }) => $visible ? "40px" : "0"};
@@ -17171,24 +17221,24 @@ var AnimatedAction = import_styled_components4.default.div`
17171
17221
  `;
17172
17222
 
17173
17223
  // src/components/chat/chat-message-actions/chat-message-actions.tsx
17174
- var import_jsx_runtime4 = require("react/jsx-runtime");
17224
+ var import_jsx_runtime5 = require("react/jsx-runtime");
17175
17225
  function ChatMessageActions({ className, messageId, content: content2, role, isHelpful }) {
17176
17226
  const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
17177
17227
  const { isCopied, copy } = useCopyToClipboard();
17178
- const handleCopy = (0, import_react5.useCallback)(() => {
17228
+ const handleCopy = (0, import_react7.useCallback)(() => {
17179
17229
  copy(content2);
17180
17230
  onCopyMessage?.(messageId);
17181
17231
  }, [content2, messageId, copy, onCopyMessage]);
17182
- const handleThumbUp = (0, import_react5.useCallback)(() => {
17232
+ const handleThumbUp = (0, import_react7.useCallback)(() => {
17183
17233
  onThumbUpClick?.(messageId, isHelpful === true ? null : true);
17184
17234
  }, [messageId, isHelpful, onThumbUpClick]);
17185
- const handleThumbDown = (0, import_react5.useCallback)(() => {
17235
+ const handleThumbDown = (0, import_react7.useCallback)(() => {
17186
17236
  onThumbDownClick?.(messageId, isHelpful === false ? null : false);
17187
17237
  }, [messageId, isHelpful, onThumbDownClick]);
17188
17238
  const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
17189
17239
  const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
17190
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { $role: role, className, children: [
17191
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17240
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ActionsContainer, { $role: role, className, children: [
17241
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17192
17242
  IconButton,
17193
17243
  {
17194
17244
  icon: isCopied ? IconCheck : IconCopy,
@@ -17196,7 +17246,7 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
17196
17246
  "aria-label": isCopied ? "Copied" : "Copy message"
17197
17247
  }
17198
17248
  ),
17199
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17249
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17200
17250
  IconButton,
17201
17251
  {
17202
17252
  icon: IconThumbUp,
@@ -17205,7 +17255,7 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
17205
17255
  "aria-label": "Good response"
17206
17256
  }
17207
17257
  ) }),
17208
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17258
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17209
17259
  IconButton,
17210
17260
  {
17211
17261
  icon: IconThumbDown,
@@ -17218,8 +17268,8 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
17218
17268
  }
17219
17269
 
17220
17270
  // src/components/chat/chat-message/chat-message-styles.ts
17221
- var import_styled_components5 = __toESM(require("styled-components"), 1);
17222
- var MessageRow = import_styled_components5.default.div`
17271
+ var import_styled_components6 = __toESM(require("styled-components"), 1);
17272
+ var MessageRow = import_styled_components6.default.div`
17223
17273
  display: flex;
17224
17274
  justify-content: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
17225
17275
 
@@ -17228,7 +17278,7 @@ var MessageRow = import_styled_components5.default.div`
17228
17278
  pointer-events: auto;
17229
17279
  }
17230
17280
  `;
17231
- var MessageContainer = import_styled_components5.default.div`
17281
+ var MessageContainer = import_styled_components6.default.div`
17232
17282
  display: flex;
17233
17283
  flex-direction: column;
17234
17284
  align-items: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
@@ -17236,7 +17286,7 @@ var MessageContainer = import_styled_components5.default.div`
17236
17286
  width: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "auto" : "100%"};
17237
17287
  gap: 12px;
17238
17288
  `;
17239
- var MessageBubble = import_styled_components5.default.div`
17289
+ var MessageBubble = import_styled_components6.default.div`
17240
17290
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17241
17291
  color: ${colors["brown-100"]};
17242
17292
  background: ${({ $role }) => $role === MESSAGE_ROLE.USER ? colors.white : "transparent"};
@@ -17247,11 +17297,11 @@ var MessageBubble = import_styled_components5.default.div`
17247
17297
  `;
17248
17298
 
17249
17299
  // src/components/chat/chat-message/chat-message.tsx
17250
- var import_jsx_runtime5 = require("react/jsx-runtime");
17300
+ var import_jsx_runtime6 = require("react/jsx-runtime");
17251
17301
  function ChatMessage({ message }) {
17252
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageRow, { $role: message.role, role: "article", "aria-label": `${message.role} message`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageContainer, { $role: message.role, children: [
17253
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatMessageContent, { content: message.content }) }),
17254
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17302
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageRow, { $role: message.role, role: "article", "aria-label": `${message.role} message`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(MessageContainer, { $role: message.role, children: [
17303
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatMessageContent, { content: message.content, messageId: message.id }) }),
17304
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
17255
17305
  ChatMessageActions,
17256
17306
  {
17257
17307
  messageId: message.id,
@@ -17264,7 +17314,7 @@ function ChatMessage({ message }) {
17264
17314
  }
17265
17315
 
17266
17316
  // src/components/keyboard-shortcut/keyboard-shortcut-styles.ts
17267
- var import_styled_components6 = __toESM(require("styled-components"), 1);
17317
+ var import_styled_components7 = __toESM(require("styled-components"), 1);
17268
17318
 
17269
17319
  // src/components/keyboard-shortcut/types.ts
17270
17320
  var KEYBOARD_SHORTCUT_VARIANTS = {
@@ -17276,21 +17326,21 @@ var KEYBOARD_SHORTCUT_VARIANTS = {
17276
17326
 
17277
17327
  // src/components/keyboard-shortcut/keyboard-shortcut-styles.ts
17278
17328
  var variantStyles = {
17279
- [KEYBOARD_SHORTCUT_VARIANTS.OUTLINED]: import_styled_components6.css`
17329
+ [KEYBOARD_SHORTCUT_VARIANTS.OUTLINED]: import_styled_components7.css`
17280
17330
  border: 1px solid ${colors["white-alpha-40"]};
17281
17331
  color: ${colors["brown-10"]};
17282
17332
  `,
17283
- [KEYBOARD_SHORTCUT_VARIANTS.FILLED]: import_styled_components6.css`
17333
+ [KEYBOARD_SHORTCUT_VARIANTS.FILLED]: import_styled_components7.css`
17284
17334
  background: ${colors["brown-80"]};
17285
17335
  color: ${colors["brown-10"]};
17286
17336
  `
17287
17337
  };
17288
- var Wrapper = import_styled_components6.default.div`
17338
+ var Wrapper = import_styled_components7.default.div`
17289
17339
  display: inline-flex;
17290
17340
  align-items: center;
17291
17341
  gap: 2px;
17292
17342
  `;
17293
- var Key = import_styled_components6.default.kbd`
17343
+ var Key = import_styled_components7.default.kbd`
17294
17344
  display: inline-flex;
17295
17345
  align-items: center;
17296
17346
  justify-content: center;
@@ -17300,20 +17350,20 @@ var Key = import_styled_components6.default.kbd`
17300
17350
  `;
17301
17351
 
17302
17352
  // src/components/keyboard-shortcut/keyboard-shortcut.tsx
17303
- var import_jsx_runtime6 = require("react/jsx-runtime");
17353
+ var import_jsx_runtime7 = require("react/jsx-runtime");
17304
17354
  function KeyboardShortcut({
17305
17355
  keys,
17306
17356
  variant = KEYBOARD_SHORTCUT_VARIANTS.OUTLINED,
17307
17357
  className
17308
17358
  }) {
17309
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Wrapper, { className, children: keys.map((KeyComponent, index2) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Key, { $variant: variant, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { icon: KeyComponent, size: 12 }) }, index2)) });
17359
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Wrapper, { className, children: keys.map((KeyComponent, index2) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Key, { $variant: variant, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { icon: KeyComponent, size: 12 }) }, index2)) });
17310
17360
  }
17311
17361
 
17312
17362
  // src/components/keyboard-shortcut/icons/icon-ctrl.tsx
17313
- var import_jsx_runtime7 = require("react/jsx-runtime");
17363
+ var import_jsx_runtime8 = require("react/jsx-runtime");
17314
17364
  function IconCtrl(props) {
17315
17365
  const { width: width2 = 24, height: height2 = 24, ...rest } = props;
17316
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: width2, height: height2, fill: "none", ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
17366
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: width2, height: height2, fill: "none", ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
17317
17367
  "text",
17318
17368
  {
17319
17369
  x: "50%",
@@ -17330,11 +17380,11 @@ function IconCtrl(props) {
17330
17380
  }
17331
17381
 
17332
17382
  // src/components/lottie/lottie.tsx
17333
- var import_react7 = require("react");
17383
+ var import_react9 = require("react");
17334
17384
 
17335
17385
  // src/components/lottie/lottie-styles.ts
17336
- var import_styled_components7 = __toESM(require("styled-components"), 1);
17337
- var LottieContainer = import_styled_components7.default.div`
17386
+ var import_styled_components8 = __toESM(require("styled-components"), 1);
17387
+ var LottieContainer = import_styled_components8.default.div`
17338
17388
  display: inline-flex;
17339
17389
  width: ${({ $width }) => typeof $width === "number" ? `${$width}px` : $width};
17340
17390
  height: ${({ $height }) => typeof $height === "number" ? `${$height}px` : $height};
@@ -17346,7 +17396,7 @@ var LottieContainer = import_styled_components7.default.div`
17346
17396
  `;
17347
17397
 
17348
17398
  // src/components/lottie/use-lottie.ts
17349
- var import_react6 = require("react");
17399
+ var import_react8 = require("react");
17350
17400
  var import_lottie_web = __toESM(require_lottie(), 1);
17351
17401
  function useLottie({
17352
17402
  animationData: animationData2,
@@ -17361,17 +17411,17 @@ function useLottie({
17361
17411
  onLoopComplete,
17362
17412
  onEnterFrame
17363
17413
  }) {
17364
- const containerRef = (0, import_react6.useRef)(null);
17365
- const animationRef = (0, import_react6.useRef)(null);
17366
- const onAnimationLoadedRef = (0, import_react6.useRef)(onAnimationLoaded);
17367
- const onCompleteRef = (0, import_react6.useRef)(onComplete);
17368
- const onLoopCompleteRef = (0, import_react6.useRef)(onLoopComplete);
17369
- const onEnterFrameRef = (0, import_react6.useRef)(onEnterFrame);
17414
+ const containerRef = (0, import_react8.useRef)(null);
17415
+ const animationRef = (0, import_react8.useRef)(null);
17416
+ const onAnimationLoadedRef = (0, import_react8.useRef)(onAnimationLoaded);
17417
+ const onCompleteRef = (0, import_react8.useRef)(onComplete);
17418
+ const onLoopCompleteRef = (0, import_react8.useRef)(onLoopComplete);
17419
+ const onEnterFrameRef = (0, import_react8.useRef)(onEnterFrame);
17370
17420
  onAnimationLoadedRef.current = onAnimationLoaded;
17371
17421
  onCompleteRef.current = onComplete;
17372
17422
  onLoopCompleteRef.current = onLoopComplete;
17373
17423
  onEnterFrameRef.current = onEnterFrame;
17374
- (0, import_react6.useEffect)(() => {
17424
+ (0, import_react8.useEffect)(() => {
17375
17425
  if (!containerRef.current) return;
17376
17426
  const anim = import_lottie_web.default.loadAnimation({
17377
17427
  container: containerRef.current,
@@ -17463,8 +17513,8 @@ function createLottieRef(animationRef) {
17463
17513
  }
17464
17514
 
17465
17515
  // src/components/lottie/lottie.tsx
17466
- var import_jsx_runtime8 = require("react/jsx-runtime");
17467
- var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17516
+ var import_jsx_runtime9 = require("react/jsx-runtime");
17517
+ var Lottie = (0, import_react9.forwardRef)(function Lottie2({
17468
17518
  animationData: animationData2,
17469
17519
  autoplay,
17470
17520
  loop,
@@ -17494,8 +17544,8 @@ var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17494
17544
  onLoopComplete,
17495
17545
  onEnterFrame
17496
17546
  });
17497
- (0, import_react7.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17498
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
17547
+ (0, import_react9.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17548
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
17499
17549
  LottieContainer,
17500
17550
  {
17501
17551
  ref: containerRef,
@@ -17509,7 +17559,7 @@ var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17509
17559
  });
17510
17560
 
17511
17561
  // src/components/text-area/text-area.tsx
17512
- var import_react8 = require("react");
17562
+ var import_react10 = require("react");
17513
17563
 
17514
17564
  // src/utils/merge-refs.ts
17515
17565
  function mergeRefs(...refs) {
@@ -17525,8 +17575,8 @@ function mergeRefs(...refs) {
17525
17575
  }
17526
17576
 
17527
17577
  // src/components/text-area/text-area-styles.ts
17528
- var import_styled_components8 = __toESM(require("styled-components"), 1);
17529
- var StyledTextArea = import_styled_components8.default.textarea`
17578
+ var import_styled_components9 = __toESM(require("styled-components"), 1);
17579
+ var StyledTextArea = import_styled_components9.default.textarea`
17530
17580
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17531
17581
  color: ${colors["brown-100"]};
17532
17582
  border: none;
@@ -17549,23 +17599,23 @@ var StyledTextArea = import_styled_components8.default.textarea`
17549
17599
  `;
17550
17600
 
17551
17601
  // src/components/text-area/text-area.tsx
17552
- var import_jsx_runtime9 = require("react/jsx-runtime");
17553
- var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
17554
- const internalRef = (0, import_react8.useRef)(null);
17555
- (0, import_react8.useLayoutEffect)(() => {
17602
+ var import_jsx_runtime10 = require("react/jsx-runtime");
17603
+ var TextArea = (0, import_react10.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
17604
+ const internalRef = (0, import_react10.useRef)(null);
17605
+ (0, import_react10.useLayoutEffect)(() => {
17556
17606
  const el = internalRef.current;
17557
17607
  if (el) {
17558
17608
  el.style.height = "auto";
17559
17609
  el.style.height = `${el.scrollHeight}px`;
17560
17610
  }
17561
17611
  }, [value2]);
17562
- const handleChange = (0, import_react8.useCallback)(
17612
+ const handleChange = (0, import_react10.useCallback)(
17563
17613
  (e) => {
17564
17614
  onChange(e.target.value);
17565
17615
  },
17566
17616
  [onChange]
17567
17617
  );
17568
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
17618
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
17569
17619
  StyledTextArea,
17570
17620
  {
17571
17621
  ref: mergeRefs(internalRef, externalRef),
@@ -17581,10 +17631,211 @@ var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2,
17581
17631
  }
17582
17632
  );
17583
17633
  });
17634
+
17635
+ // src/utils/parse-markdown-table.ts
17636
+ function parseCells(line) {
17637
+ const trimmed = line.trim();
17638
+ const stripped = trimmed.startsWith("|") ? trimmed.slice(1) : trimmed;
17639
+ const withoutTrailing = stripped.endsWith("|") ? stripped.slice(0, -1) : stripped;
17640
+ return withoutTrailing.split("|").map((cell) => cell.trim());
17641
+ }
17642
+ function isSeparatorRow(line) {
17643
+ const cells = parseCells(line);
17644
+ return cells.length > 0 && cells.every((cell) => /^:?-{1,}:?$/.test(cell));
17645
+ }
17646
+ function isTableRow(line) {
17647
+ return line.includes("|");
17648
+ }
17649
+ var TABLE_TITLE_PREFIX = "<!-- table-title:";
17650
+ var TABLE_TITLE_SUFFIX = "-->";
17651
+ function extractTableTitle(line) {
17652
+ const trimmed = line.trim();
17653
+ if (!trimmed.startsWith(TABLE_TITLE_PREFIX) || !trimmed.endsWith(TABLE_TITLE_SUFFIX)) {
17654
+ return void 0;
17655
+ }
17656
+ return trimmed.slice(TABLE_TITLE_PREFIX.length, -TABLE_TITLE_SUFFIX.length).trim() || void 0;
17657
+ }
17658
+ function parseMarkdownTable(markdown, tableIndex = 0) {
17659
+ const lines = markdown.split("\n");
17660
+ let tableCount = 0;
17661
+ for (let i = 0; i < lines.length - 1; i++) {
17662
+ const headerLine = lines[i];
17663
+ const separatorLine = lines[i + 1];
17664
+ if (!isTableRow(headerLine) || !isSeparatorRow(separatorLine)) {
17665
+ continue;
17666
+ }
17667
+ if (tableCount === tableIndex) {
17668
+ const columns = parseCells(headerLine);
17669
+ const rows = [];
17670
+ const title = i > 0 ? extractTableTitle(lines[i - 1]) : void 0;
17671
+ for (let j = i + 2; j < lines.length; j++) {
17672
+ if (!isTableRow(lines[j]) || isSeparatorRow(lines[j])) {
17673
+ break;
17674
+ }
17675
+ const trimmedLine = lines[j].trim();
17676
+ if (trimmedLine === "") {
17677
+ break;
17678
+ }
17679
+ rows.push(parseCells(lines[j]));
17680
+ }
17681
+ return { columns, rows, ...title ? { title } : {} };
17682
+ }
17683
+ tableCount++;
17684
+ }
17685
+ return null;
17686
+ }
17687
+
17688
+ // src/utils/convert-table-to-csv.ts
17689
+ function escapeField(field) {
17690
+ if (field.includes(",") || field.includes('"') || field.includes("\n") || field.includes("\r")) {
17691
+ return `"${field.replace(/"/g, '""')}"`;
17692
+ }
17693
+ return field;
17694
+ }
17695
+ function convertTableToCSV(table) {
17696
+ const headerRow = table.columns.map(escapeField).join(",");
17697
+ const dataRows = table.rows.map((row) => row.map(escapeField).join(","));
17698
+ return [headerRow, ...dataRows].join("\r\n");
17699
+ }
17700
+
17701
+ // src/components/button/button.tsx
17702
+ var import_react11 = require("react");
17703
+
17704
+ // src/components/button/button-styles.ts
17705
+ var import_styled_components10 = __toESM(require("styled-components"), 1);
17706
+ var sizeStyles = {
17707
+ xs: import_styled_components10.css`
17708
+ padding: 6px 10px;
17709
+ border-radius: 8px;
17710
+ gap: 4px;
17711
+ `,
17712
+ s: import_styled_components10.css`
17713
+ padding: 8px 12px;
17714
+ border-radius: 10px;
17715
+ gap: 6px;
17716
+ `,
17717
+ m: import_styled_components10.css`
17718
+ padding: 10px 14px;
17719
+ border-radius: 10px;
17720
+ gap: 6px;
17721
+ `
17722
+ };
17723
+ var variantStyles2 = {
17724
+ solid: import_styled_components10.css`
17725
+ background: ${colors["brown-100"]};
17726
+ color: ${colors.white};
17727
+ border: none;
17728
+
17729
+ &:hover:not(:disabled) {
17730
+ background: ${colors["brown-90"]};
17731
+ }
17732
+
17733
+ &:disabled {
17734
+ background: ${colors["brown-20"]};
17735
+ color: ${colors["brown-50"]};
17736
+ }
17737
+ `,
17738
+ outline: import_styled_components10.css`
17739
+ background: ${colors.white};
17740
+ color: ${colors["brown-100"]};
17741
+ border: 1px solid ${colors["brown-40"]};
17742
+
17743
+ &:hover:not(:disabled) {
17744
+ background: ${colors["brown-20"]};
17745
+ }
17746
+
17747
+ &:disabled {
17748
+ border-color: ${colors["brown-20"]};
17749
+ color: ${colors["brown-50"]};
17750
+ }
17751
+ `,
17752
+ ghost: import_styled_components10.css`
17753
+ background: transparent;
17754
+ color: ${colors["brown-100"]};
17755
+ border: none;
17756
+
17757
+ &:hover:not(:disabled) {
17758
+ background: ${colors["brown-20"]};
17759
+ }
17760
+
17761
+ &:disabled {
17762
+ color: ${colors["brown-50"]};
17763
+ }
17764
+ `
17765
+ };
17766
+ var StyledButton = import_styled_components10.default.button`
17767
+ display: inline-flex;
17768
+ align-items: center;
17769
+ justify-content: center;
17770
+ cursor: pointer;
17771
+ ${typographyMixin(typographyTypes.GEIST_BODY_XS_MEDIUM)};
17772
+ transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
17773
+
17774
+ &:disabled {
17775
+ cursor: not-allowed;
17776
+ }
17777
+
17778
+ ${({ $size }) => sizeStyles[$size]}
17779
+ ${({ $variant }) => variantStyles2[$variant]}
17780
+ `;
17781
+
17782
+ // src/components/button/constants.ts
17783
+ var BUTTON_VARIANT = {
17784
+ SOLID: "solid",
17785
+ OUTLINE: "outline",
17786
+ GHOST: "ghost"
17787
+ };
17788
+ var BUTTON_SIZE = {
17789
+ XS: "xs",
17790
+ S: "s",
17791
+ M: "m"
17792
+ };
17793
+ var ICON_POSITION = {
17794
+ LEADING: "leading",
17795
+ TRAILING: "trailing"
17796
+ };
17797
+
17798
+ // src/components/button/button.tsx
17799
+ var import_jsx_runtime11 = require("react/jsx-runtime");
17800
+ var Button2 = (0, import_react11.forwardRef)(function Button3({
17801
+ children,
17802
+ variant = BUTTON_VARIANT.SOLID,
17803
+ size = BUTTON_SIZE.M,
17804
+ icon,
17805
+ iconPosition = ICON_POSITION.LEADING,
17806
+ disabled = false,
17807
+ onClick,
17808
+ className,
17809
+ "aria-label": ariaLabel
17810
+ }, ref) {
17811
+ const iconElement = icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { icon, size: 16 }) : null;
17812
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
17813
+ StyledButton,
17814
+ {
17815
+ ref,
17816
+ type: "button",
17817
+ $variant: variant,
17818
+ $size: size,
17819
+ disabled,
17820
+ onClick: disabled ? void 0 : onClick,
17821
+ className,
17822
+ "aria-label": ariaLabel,
17823
+ children: [
17824
+ iconPosition === ICON_POSITION.LEADING && iconElement,
17825
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children }),
17826
+ iconPosition === ICON_POSITION.TRAILING && iconElement
17827
+ ]
17828
+ }
17829
+ );
17830
+ });
17584
17831
  // Annotate the CommonJS export names for ESM import in node:
17585
17832
  0 && (module.exports = {
17833
+ BUTTON_SIZE,
17834
+ BUTTON_VARIANT,
17835
+ Button,
17586
17836
  ChatContext,
17587
17837
  ChatMessage,
17838
+ ICON_POSITION,
17588
17839
  Icon,
17589
17840
  IconButton,
17590
17841
  IconCtrl,
@@ -17594,9 +17845,11 @@ var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2,
17594
17845
  MESSAGE_ROLE,
17595
17846
  TextArea,
17596
17847
  colors,
17848
+ convertTableToCSV,
17597
17849
  fontFamilies,
17598
17850
  markdownToPlainText,
17599
17851
  mergeRefs,
17852
+ parseMarkdownTable,
17600
17853
  typographyMixin,
17601
17854
  typographyStyles,
17602
17855
  typographyTypes,