@shapesos/clay 0.7.0 → 0.8.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.
package/dist/index.cjs CHANGED
@@ -16357,9 +16357,11 @@ __export(src_exports, {
16357
16357
  MESSAGE_ROLE: () => MESSAGE_ROLE,
16358
16358
  TextArea: () => TextArea,
16359
16359
  colors: () => colors,
16360
+ convertTableToCSV: () => convertTableToCSV,
16360
16361
  fontFamilies: () => fontFamilies,
16361
16362
  markdownToPlainText: () => markdownToPlainText,
16362
16363
  mergeRefs: () => mergeRefs,
16364
+ parseMarkdownTable: () => parseMarkdownTable,
16363
16365
  typographyMixin: () => typographyMixin,
16364
16366
  typographyStyles: () => typographyStyles,
16365
16367
  typographyTypes: () => typographyTypes,
@@ -16756,9 +16758,63 @@ var import_react_markdown = __toESM(require("react-markdown"), 1);
16756
16758
  var import_remark_breaks = __toESM(require("remark-breaks"), 1);
16757
16759
  var import_remark_gfm = __toESM(require("remark-gfm"), 1);
16758
16760
 
16759
- // src/components/chat/chat-message-content/chat-message-content-styles.ts
16761
+ // src/components/chat/scrollable-table/scrollable-table.tsx
16762
+ var import_react2 = require("react");
16763
+
16764
+ // src/components/chat/chat-context/chat-context.ts
16765
+ var import_react = require("react");
16766
+ var ChatContext = (0, import_react.createContext)(null);
16767
+ function useChatContext() {
16768
+ const context = (0, import_react.useContext)(ChatContext);
16769
+ if (!context) {
16770
+ throw new Error("useChatContext must be used within a Chat.Root component");
16771
+ }
16772
+ return context;
16773
+ }
16774
+
16775
+ // src/components/chat/scrollable-table/scrollable-table-styles.ts
16760
16776
  var import_styled_components = __toESM(require("styled-components"), 1);
16761
- var ContentWrapper = import_styled_components.default.div`
16777
+ var TableContainer = import_styled_components.default.div`
16778
+ position: relative;
16779
+ margin-block: 8px 16px;
16780
+ `;
16781
+ var TableScroll = import_styled_components.default.div`
16782
+ width: 100%;
16783
+ overflow-x: auto;
16784
+ overflow-y: hidden;
16785
+ `;
16786
+ var TableActionsWrapper = import_styled_components.default.div`
16787
+ display: flex;
16788
+ justify-content: flex-start;
16789
+ margin-block: 8px 0;
16790
+ `;
16791
+ var TableActionsDivider = import_styled_components.default.div`
16792
+ height: 1px;
16793
+ background: ${colors["brown-40"]};
16794
+ margin-block: 8px 0;
16795
+ `;
16796
+
16797
+ // src/components/chat/scrollable-table/scrollable-table.tsx
16798
+ var import_jsx_runtime = require("react/jsx-runtime");
16799
+ function ScrollableTable({ node: _node, messageId, counter, ...props }) {
16800
+ const currentIndex = counter ? counter.value : 0;
16801
+ if (counter) {
16802
+ counter.value += 1;
16803
+ }
16804
+ const context = (0, import_react2.useContext)(ChatContext);
16805
+ const TableActions = context?.TableActions;
16806
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableContainer, { children: [
16807
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) }),
16808
+ TableActions && messageId && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
16809
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActions, { messageId, tableIndex: currentIndex }) }),
16810
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableActionsDivider, {})
16811
+ ] })
16812
+ ] });
16813
+ }
16814
+
16815
+ // src/components/chat/chat-message-content/chat-message-content-styles.ts
16816
+ var import_styled_components2 = __toESM(require("styled-components"), 1);
16817
+ var ContentWrapper = import_styled_components2.default.div`
16762
16818
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
16763
16819
  color: ${colors["brown-100"]};
16764
16820
  word-break: break-word;
@@ -16874,30 +16930,26 @@ var ContentWrapper = import_styled_components.default.div`
16874
16930
  color: ${colors["brown-80"]};
16875
16931
  }
16876
16932
  `;
16877
- var TableScroll = import_styled_components.default.div`
16878
- width: 100%;
16879
- overflow-x: auto;
16880
- overflow-y: hidden;
16881
- margin-block: 8px 16px;
16882
- `;
16883
16933
 
16884
16934
  // src/components/chat/chat-message-content/chat-message-content.tsx
16885
- var import_jsx_runtime = require("react/jsx-runtime");
16886
- function ScrollableTable({ node: _node, ...props }) {
16887
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { ...props }) });
16888
- }
16889
- var markdownComponents = {
16890
- table: ScrollableTable
16891
- };
16892
- function ChatMessageContent({ content: content2 }) {
16893
- 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 }) });
16935
+ var import_jsx_runtime2 = require("react/jsx-runtime");
16936
+ function ChatMessageContent({ content: content2, messageId }) {
16937
+ const counter = { value: 0 };
16938
+ const sanitizedContent = content2.split("\n").filter((line) => {
16939
+ const t = line.trim();
16940
+ return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
16941
+ }).join("\n");
16942
+ const markdownComponents = {
16943
+ table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ScrollableTable, { ...tableProps, messageId, counter }))
16944
+ };
16945
+ 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 }) });
16894
16946
  }
16895
16947
 
16896
16948
  // src/components/chat/chat-message-actions/chat-message-actions.tsx
16897
- var import_react5 = require("react");
16949
+ var import_react6 = require("react");
16898
16950
 
16899
16951
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
16900
- var import_react = require("react");
16952
+ var import_react3 = require("react");
16901
16953
 
16902
16954
  // node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs
16903
16955
  var defaultAttributes = {
@@ -16924,8 +16976,8 @@ var defaultAttributes = {
16924
16976
 
16925
16977
  // node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
16926
16978
  var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
16927
- const Component = (0, import_react.forwardRef)(
16928
- ({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0, import_react.createElement)(
16979
+ const Component = (0, import_react3.forwardRef)(
16980
+ ({ color = "currentColor", size = 24, stroke = 2, title, className, children, ...rest }, ref) => (0, import_react3.createElement)(
16929
16981
  "svg",
16930
16982
  {
16931
16983
  ref,
@@ -16942,8 +16994,8 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
16942
16994
  ...rest
16943
16995
  },
16944
16996
  [
16945
- title && (0, import_react.createElement)("title", { key: "svg-title" }, title),
16946
- ...iconNode.map(([tag, attrs]) => (0, import_react.createElement)(tag, attrs)),
16997
+ title && (0, import_react3.createElement)("title", { key: "svg-title" }, title),
16998
+ ...iconNode.map(([tag, attrs]) => (0, import_react3.createElement)(tag, attrs)),
16947
16999
  ...Array.isArray(children) ? children : [children]
16948
17000
  ]
16949
17001
  )
@@ -16969,10 +17021,10 @@ var __iconNode4 = [["path", { "d": "M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7
16969
17021
  var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode4);
16970
17022
 
16971
17023
  // src/components/icon/icon.tsx
16972
- var import_react2 = require("react");
17024
+ var import_react4 = require("react");
16973
17025
 
16974
17026
  // src/components/icon/icon-styles.ts
16975
- var import_styled_components2 = __toESM(require("styled-components"), 1);
17027
+ var import_styled_components3 = __toESM(require("styled-components"), 1);
16976
17028
  var STROKE_WIDTH_BY_SIZE = {
16977
17029
  12: 1.4,
16978
17030
  14: 1.4,
@@ -16985,7 +17037,7 @@ var DEFAULT_STROKE_WIDTH = 1.8;
16985
17037
  function getStrokeWidth(size) {
16986
17038
  return STROKE_WIDTH_BY_SIZE[size] ?? DEFAULT_STROKE_WIDTH;
16987
17039
  }
16988
- var IconWrapper = import_styled_components2.default.span`
17040
+ var IconWrapper = import_styled_components3.default.span`
16989
17041
  display: inline-flex;
16990
17042
  align-items: center;
16991
17043
  justify-content: center;
@@ -16994,10 +17046,10 @@ var IconWrapper = import_styled_components2.default.span`
16994
17046
  `;
16995
17047
 
16996
17048
  // src/components/icon/icon.tsx
16997
- var import_jsx_runtime2 = require("react/jsx-runtime");
17049
+ var import_jsx_runtime3 = require("react/jsx-runtime");
16998
17050
  var DEFAULT_SIZE = 16;
16999
- var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
17000
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
17051
+ var Icon = (0, import_react4.forwardRef)(function Icon2({ icon: IconComponent, size = DEFAULT_SIZE, color, className, "aria-label": ariaLabel }, ref) {
17052
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
17001
17053
  IconWrapper,
17002
17054
  {
17003
17055
  ref,
@@ -17005,13 +17057,13 @@ var Icon = (0, import_react2.forwardRef)(function Icon2({ icon: IconComponent, s
17005
17057
  $color: color,
17006
17058
  "aria-label": ariaLabel,
17007
17059
  role: ariaLabel ? "img" : void 0,
17008
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
17060
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconComponent, { width: size, height: size, strokeWidth: getStrokeWidth(size) })
17009
17061
  }
17010
17062
  );
17011
17063
  });
17012
17064
 
17013
17065
  // src/components/icon-button/icon-button-styles.ts
17014
- var import_styled_components3 = __toESM(require("styled-components"), 1);
17066
+ var import_styled_components4 = __toESM(require("styled-components"), 1);
17015
17067
  var PADDING = {
17016
17068
  short: {
17017
17069
  small: "4px",
@@ -17026,7 +17078,7 @@ var BORDER_RADIUS = {
17026
17078
  small: 6,
17027
17079
  medium: 10
17028
17080
  };
17029
- var Button = import_styled_components3.default.button`
17081
+ var Button = import_styled_components4.default.button`
17030
17082
  display: inline-flex;
17031
17083
  align-items: center;
17032
17084
  justify-content: center;
@@ -17054,7 +17106,7 @@ var Button = import_styled_components3.default.button`
17054
17106
  `;
17055
17107
 
17056
17108
  // src/components/icon-button/icon-button.tsx
17057
- var import_jsx_runtime3 = require("react/jsx-runtime");
17109
+ var import_jsx_runtime4 = require("react/jsx-runtime");
17058
17110
  var ICON_SIZE_BY_BUTTON_SIZE = {
17059
17111
  small: 16,
17060
17112
  medium: 20
@@ -17071,7 +17123,7 @@ function IconButton({
17071
17123
  as,
17072
17124
  "aria-label": ariaLabel
17073
17125
  }) {
17074
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
17126
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17075
17127
  Button,
17076
17128
  {
17077
17129
  className,
@@ -17083,24 +17135,13 @@ function IconButton({
17083
17135
  disabled,
17084
17136
  onClick: disabled ? void 0 : onClick,
17085
17137
  "aria-label": ariaLabel,
17086
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
17138
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { icon, size: ICON_SIZE_BY_BUTTON_SIZE[size] })
17087
17139
  }
17088
17140
  );
17089
17141
  }
17090
17142
 
17091
- // src/components/chat/chat-context/chat-context.ts
17092
- var import_react3 = require("react");
17093
- var ChatContext = (0, import_react3.createContext)(null);
17094
- function useChatContext() {
17095
- const context = (0, import_react3.useContext)(ChatContext);
17096
- if (!context) {
17097
- throw new Error("useChatContext must be used within a Chat.Root component");
17098
- }
17099
- return context;
17100
- }
17101
-
17102
17143
  // src/components/chat/hooks/use-copy-to-clipboard.ts
17103
- var import_react4 = require("react");
17144
+ var import_react5 = require("react");
17104
17145
 
17105
17146
  // src/utils/clipboard.ts
17106
17147
  function copyToClipboard(text2, options) {
@@ -17117,7 +17158,7 @@ var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUF
17117
17158
  function markdownToPlainText(markdown) {
17118
17159
  if (!markdown) return "";
17119
17160
  const inlineCodeSnippets = [];
17120
- let result = markdown.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
17161
+ let result = markdown.replace(/^<!--[\s\S]*?--!?>\n?/gm, "").replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
17121
17162
  inlineCodeSnippets.push(code);
17122
17163
  return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
17123
17164
  }).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();
@@ -17128,14 +17169,14 @@ function markdownToPlainText(markdown) {
17128
17169
  // src/components/chat/hooks/use-copy-to-clipboard.ts
17129
17170
  var RESET_DELAY_MS = 2e3;
17130
17171
  function useCopyToClipboard() {
17131
- const [isCopied, setIsCopied] = (0, import_react4.useState)(false);
17132
- const timeoutRef = (0, import_react4.useRef)(null);
17133
- (0, import_react4.useEffect)(() => {
17172
+ const [isCopied, setIsCopied] = (0, import_react5.useState)(false);
17173
+ const timeoutRef = (0, import_react5.useRef)(null);
17174
+ (0, import_react5.useEffect)(() => {
17134
17175
  return () => {
17135
17176
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
17136
17177
  };
17137
17178
  }, []);
17138
- const copy = (0, import_react4.useCallback)((text2) => {
17179
+ const copy = (0, import_react5.useCallback)((text2) => {
17139
17180
  copyToClipboard(markdownToPlainText(text2), {
17140
17181
  onSuccess: () => {
17141
17182
  setIsCopied(true);
@@ -17157,16 +17198,16 @@ var MESSAGE_ROLE = {
17157
17198
  };
17158
17199
 
17159
17200
  // src/components/chat/chat-message-actions/chat-message-actions-styles.ts
17160
- var import_styled_components4 = __toESM(require("styled-components"), 1);
17201
+ var import_styled_components5 = __toESM(require("styled-components"), 1);
17161
17202
  var FADE_DURATION_MS = 150;
17162
17203
  var ANIMATE_DURATION_MS = 200;
17163
- var ActionsContainer = import_styled_components4.default.div`
17204
+ var ActionsContainer = import_styled_components5.default.div`
17164
17205
  display: flex;
17165
17206
  opacity: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? 1 : 0};
17166
17207
  pointer-events: ${({ $role }) => $role === MESSAGE_ROLE.ASSISTANT ? "auto" : "none"};
17167
17208
  transition: opacity ${FADE_DURATION_MS}ms ease;
17168
17209
  `;
17169
- var AnimatedAction = import_styled_components4.default.div`
17210
+ var AnimatedAction = import_styled_components5.default.div`
17170
17211
  display: flex;
17171
17212
  overflow: hidden;
17172
17213
  max-width: ${({ $visible }) => $visible ? "40px" : "0"};
@@ -17175,24 +17216,24 @@ var AnimatedAction = import_styled_components4.default.div`
17175
17216
  `;
17176
17217
 
17177
17218
  // src/components/chat/chat-message-actions/chat-message-actions.tsx
17178
- var import_jsx_runtime4 = require("react/jsx-runtime");
17219
+ var import_jsx_runtime5 = require("react/jsx-runtime");
17179
17220
  function ChatMessageActions({ className, messageId, content: content2, role, isHelpful }) {
17180
17221
  const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
17181
17222
  const { isCopied, copy } = useCopyToClipboard();
17182
- const handleCopy = (0, import_react5.useCallback)(() => {
17223
+ const handleCopy = (0, import_react6.useCallback)(() => {
17183
17224
  copy(content2);
17184
17225
  onCopyMessage?.(messageId);
17185
17226
  }, [content2, messageId, copy, onCopyMessage]);
17186
- const handleThumbUp = (0, import_react5.useCallback)(() => {
17227
+ const handleThumbUp = (0, import_react6.useCallback)(() => {
17187
17228
  onThumbUpClick?.(messageId, isHelpful === true ? null : true);
17188
17229
  }, [messageId, isHelpful, onThumbUpClick]);
17189
- const handleThumbDown = (0, import_react5.useCallback)(() => {
17230
+ const handleThumbDown = (0, import_react6.useCallback)(() => {
17190
17231
  onThumbDownClick?.(messageId, isHelpful === false ? null : false);
17191
17232
  }, [messageId, isHelpful, onThumbDownClick]);
17192
17233
  const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
17193
17234
  const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
17194
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ActionsContainer, { $role: role, className, children: [
17195
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17235
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ActionsContainer, { $role: role, className, children: [
17236
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17196
17237
  IconButton,
17197
17238
  {
17198
17239
  icon: isCopied ? IconCheck : IconCopy,
@@ -17200,7 +17241,7 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
17200
17241
  "aria-label": isCopied ? "Copied" : "Copy message"
17201
17242
  }
17202
17243
  ),
17203
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17244
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17204
17245
  IconButton,
17205
17246
  {
17206
17247
  icon: IconThumbUp,
@@ -17209,7 +17250,7 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
17209
17250
  "aria-label": "Good response"
17210
17251
  }
17211
17252
  ) }),
17212
- hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
17253
+ hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17213
17254
  IconButton,
17214
17255
  {
17215
17256
  icon: IconThumbDown,
@@ -17222,8 +17263,8 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
17222
17263
  }
17223
17264
 
17224
17265
  // src/components/chat/chat-message/chat-message-styles.ts
17225
- var import_styled_components5 = __toESM(require("styled-components"), 1);
17226
- var MessageRow = import_styled_components5.default.div`
17266
+ var import_styled_components6 = __toESM(require("styled-components"), 1);
17267
+ var MessageRow = import_styled_components6.default.div`
17227
17268
  display: flex;
17228
17269
  justify-content: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
17229
17270
 
@@ -17232,7 +17273,7 @@ var MessageRow = import_styled_components5.default.div`
17232
17273
  pointer-events: auto;
17233
17274
  }
17234
17275
  `;
17235
- var MessageContainer = import_styled_components5.default.div`
17276
+ var MessageContainer = import_styled_components6.default.div`
17236
17277
  display: flex;
17237
17278
  flex-direction: column;
17238
17279
  align-items: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "flex-end" : "flex-start"};
@@ -17240,7 +17281,7 @@ var MessageContainer = import_styled_components5.default.div`
17240
17281
  width: ${({ $role }) => $role === MESSAGE_ROLE.USER ? "auto" : "100%"};
17241
17282
  gap: 12px;
17242
17283
  `;
17243
- var MessageBubble = import_styled_components5.default.div`
17284
+ var MessageBubble = import_styled_components6.default.div`
17244
17285
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17245
17286
  color: ${colors["brown-100"]};
17246
17287
  background: ${({ $role }) => $role === MESSAGE_ROLE.USER ? colors.white : "transparent"};
@@ -17251,11 +17292,11 @@ var MessageBubble = import_styled_components5.default.div`
17251
17292
  `;
17252
17293
 
17253
17294
  // src/components/chat/chat-message/chat-message.tsx
17254
- var import_jsx_runtime5 = require("react/jsx-runtime");
17295
+ var import_jsx_runtime6 = require("react/jsx-runtime");
17255
17296
  function ChatMessage({ message }) {
17256
- 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: [
17257
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatMessageContent, { content: message.content }) }),
17258
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
17297
+ 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: [
17298
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { $role: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatMessageContent, { content: message.content, messageId: message.id }) }),
17299
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
17259
17300
  ChatMessageActions,
17260
17301
  {
17261
17302
  messageId: message.id,
@@ -17268,7 +17309,7 @@ function ChatMessage({ message }) {
17268
17309
  }
17269
17310
 
17270
17311
  // src/components/keyboard-shortcut/keyboard-shortcut-styles.ts
17271
- var import_styled_components6 = __toESM(require("styled-components"), 1);
17312
+ var import_styled_components7 = __toESM(require("styled-components"), 1);
17272
17313
 
17273
17314
  // src/components/keyboard-shortcut/types.ts
17274
17315
  var KEYBOARD_SHORTCUT_VARIANTS = {
@@ -17280,21 +17321,21 @@ var KEYBOARD_SHORTCUT_VARIANTS = {
17280
17321
 
17281
17322
  // src/components/keyboard-shortcut/keyboard-shortcut-styles.ts
17282
17323
  var variantStyles = {
17283
- [KEYBOARD_SHORTCUT_VARIANTS.OUTLINED]: import_styled_components6.css`
17324
+ [KEYBOARD_SHORTCUT_VARIANTS.OUTLINED]: import_styled_components7.css`
17284
17325
  border: 1px solid ${colors["white-alpha-40"]};
17285
17326
  color: ${colors["brown-10"]};
17286
17327
  `,
17287
- [KEYBOARD_SHORTCUT_VARIANTS.FILLED]: import_styled_components6.css`
17328
+ [KEYBOARD_SHORTCUT_VARIANTS.FILLED]: import_styled_components7.css`
17288
17329
  background: ${colors["brown-80"]};
17289
17330
  color: ${colors["brown-10"]};
17290
17331
  `
17291
17332
  };
17292
- var Wrapper = import_styled_components6.default.div`
17333
+ var Wrapper = import_styled_components7.default.div`
17293
17334
  display: inline-flex;
17294
17335
  align-items: center;
17295
17336
  gap: 2px;
17296
17337
  `;
17297
- var Key = import_styled_components6.default.kbd`
17338
+ var Key = import_styled_components7.default.kbd`
17298
17339
  display: inline-flex;
17299
17340
  align-items: center;
17300
17341
  justify-content: center;
@@ -17304,20 +17345,20 @@ var Key = import_styled_components6.default.kbd`
17304
17345
  `;
17305
17346
 
17306
17347
  // src/components/keyboard-shortcut/keyboard-shortcut.tsx
17307
- var import_jsx_runtime6 = require("react/jsx-runtime");
17348
+ var import_jsx_runtime7 = require("react/jsx-runtime");
17308
17349
  function KeyboardShortcut({
17309
17350
  keys,
17310
17351
  variant = KEYBOARD_SHORTCUT_VARIANTS.OUTLINED,
17311
17352
  className
17312
17353
  }) {
17313
- 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)) });
17354
+ 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)) });
17314
17355
  }
17315
17356
 
17316
17357
  // src/components/keyboard-shortcut/icons/icon-ctrl.tsx
17317
- var import_jsx_runtime7 = require("react/jsx-runtime");
17358
+ var import_jsx_runtime8 = require("react/jsx-runtime");
17318
17359
  function IconCtrl(props) {
17319
17360
  const { width: width2 = 24, height: height2 = 24, ...rest } = props;
17320
- 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)(
17361
+ 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)(
17321
17362
  "text",
17322
17363
  {
17323
17364
  x: "50%",
@@ -17334,11 +17375,11 @@ function IconCtrl(props) {
17334
17375
  }
17335
17376
 
17336
17377
  // src/components/lottie/lottie.tsx
17337
- var import_react7 = require("react");
17378
+ var import_react8 = require("react");
17338
17379
 
17339
17380
  // src/components/lottie/lottie-styles.ts
17340
- var import_styled_components7 = __toESM(require("styled-components"), 1);
17341
- var LottieContainer = import_styled_components7.default.div`
17381
+ var import_styled_components8 = __toESM(require("styled-components"), 1);
17382
+ var LottieContainer = import_styled_components8.default.div`
17342
17383
  display: inline-flex;
17343
17384
  width: ${({ $width }) => typeof $width === "number" ? `${$width}px` : $width};
17344
17385
  height: ${({ $height }) => typeof $height === "number" ? `${$height}px` : $height};
@@ -17350,7 +17391,7 @@ var LottieContainer = import_styled_components7.default.div`
17350
17391
  `;
17351
17392
 
17352
17393
  // src/components/lottie/use-lottie.ts
17353
- var import_react6 = require("react");
17394
+ var import_react7 = require("react");
17354
17395
  var import_lottie_web = __toESM(require_lottie(), 1);
17355
17396
  function useLottie({
17356
17397
  animationData: animationData2,
@@ -17365,17 +17406,17 @@ function useLottie({
17365
17406
  onLoopComplete,
17366
17407
  onEnterFrame
17367
17408
  }) {
17368
- const containerRef = (0, import_react6.useRef)(null);
17369
- const animationRef = (0, import_react6.useRef)(null);
17370
- const onAnimationLoadedRef = (0, import_react6.useRef)(onAnimationLoaded);
17371
- const onCompleteRef = (0, import_react6.useRef)(onComplete);
17372
- const onLoopCompleteRef = (0, import_react6.useRef)(onLoopComplete);
17373
- const onEnterFrameRef = (0, import_react6.useRef)(onEnterFrame);
17409
+ const containerRef = (0, import_react7.useRef)(null);
17410
+ const animationRef = (0, import_react7.useRef)(null);
17411
+ const onAnimationLoadedRef = (0, import_react7.useRef)(onAnimationLoaded);
17412
+ const onCompleteRef = (0, import_react7.useRef)(onComplete);
17413
+ const onLoopCompleteRef = (0, import_react7.useRef)(onLoopComplete);
17414
+ const onEnterFrameRef = (0, import_react7.useRef)(onEnterFrame);
17374
17415
  onAnimationLoadedRef.current = onAnimationLoaded;
17375
17416
  onCompleteRef.current = onComplete;
17376
17417
  onLoopCompleteRef.current = onLoopComplete;
17377
17418
  onEnterFrameRef.current = onEnterFrame;
17378
- (0, import_react6.useEffect)(() => {
17419
+ (0, import_react7.useEffect)(() => {
17379
17420
  if (!containerRef.current) return;
17380
17421
  const anim = import_lottie_web.default.loadAnimation({
17381
17422
  container: containerRef.current,
@@ -17467,8 +17508,8 @@ function createLottieRef(animationRef) {
17467
17508
  }
17468
17509
 
17469
17510
  // src/components/lottie/lottie.tsx
17470
- var import_jsx_runtime8 = require("react/jsx-runtime");
17471
- var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17511
+ var import_jsx_runtime9 = require("react/jsx-runtime");
17512
+ var Lottie = (0, import_react8.forwardRef)(function Lottie2({
17472
17513
  animationData: animationData2,
17473
17514
  autoplay,
17474
17515
  loop,
@@ -17498,8 +17539,8 @@ var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17498
17539
  onLoopComplete,
17499
17540
  onEnterFrame
17500
17541
  });
17501
- (0, import_react7.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17502
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
17542
+ (0, import_react8.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
17543
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
17503
17544
  LottieContainer,
17504
17545
  {
17505
17546
  ref: containerRef,
@@ -17513,7 +17554,7 @@ var Lottie = (0, import_react7.forwardRef)(function Lottie2({
17513
17554
  });
17514
17555
 
17515
17556
  // src/components/text-area/text-area.tsx
17516
- var import_react8 = require("react");
17557
+ var import_react9 = require("react");
17517
17558
 
17518
17559
  // src/utils/merge-refs.ts
17519
17560
  function mergeRefs(...refs) {
@@ -17529,8 +17570,8 @@ function mergeRefs(...refs) {
17529
17570
  }
17530
17571
 
17531
17572
  // src/components/text-area/text-area-styles.ts
17532
- var import_styled_components8 = __toESM(require("styled-components"), 1);
17533
- var StyledTextArea = import_styled_components8.default.textarea`
17573
+ var import_styled_components9 = __toESM(require("styled-components"), 1);
17574
+ var StyledTextArea = import_styled_components9.default.textarea`
17534
17575
  ${typographyMixin(typographyTypes.GEIST_BODY_S_REGULAR)};
17535
17576
  color: ${colors["brown-100"]};
17536
17577
  border: none;
@@ -17553,23 +17594,23 @@ var StyledTextArea = import_styled_components8.default.textarea`
17553
17594
  `;
17554
17595
 
17555
17596
  // src/components/text-area/text-area.tsx
17556
- var import_jsx_runtime9 = require("react/jsx-runtime");
17557
- var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
17558
- const internalRef = (0, import_react8.useRef)(null);
17559
- (0, import_react8.useLayoutEffect)(() => {
17597
+ var import_jsx_runtime10 = require("react/jsx-runtime");
17598
+ var TextArea = (0, import_react9.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
17599
+ const internalRef = (0, import_react9.useRef)(null);
17600
+ (0, import_react9.useLayoutEffect)(() => {
17560
17601
  const el = internalRef.current;
17561
17602
  if (el) {
17562
17603
  el.style.height = "auto";
17563
17604
  el.style.height = `${el.scrollHeight}px`;
17564
17605
  }
17565
17606
  }, [value2]);
17566
- const handleChange = (0, import_react8.useCallback)(
17607
+ const handleChange = (0, import_react9.useCallback)(
17567
17608
  (e) => {
17568
17609
  onChange(e.target.value);
17569
17610
  },
17570
17611
  [onChange]
17571
17612
  );
17572
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
17613
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
17573
17614
  StyledTextArea,
17574
17615
  {
17575
17616
  ref: mergeRefs(internalRef, externalRef),
@@ -17586,30 +17627,96 @@ var TextArea = (0, import_react8.forwardRef)(function TextArea2({ value: value2,
17586
17627
  );
17587
17628
  });
17588
17629
 
17630
+ // src/utils/parse-markdown-table.ts
17631
+ function parseCells(line) {
17632
+ const trimmed = line.trim();
17633
+ const stripped = trimmed.startsWith("|") ? trimmed.slice(1) : trimmed;
17634
+ const withoutTrailing = stripped.endsWith("|") ? stripped.slice(0, -1) : stripped;
17635
+ return withoutTrailing.split("|").map((cell) => cell.trim());
17636
+ }
17637
+ function isSeparatorRow(line) {
17638
+ const cells = parseCells(line);
17639
+ return cells.length > 0 && cells.every((cell) => /^:?-{1,}:?$/.test(cell));
17640
+ }
17641
+ function isTableRow(line) {
17642
+ return line.includes("|");
17643
+ }
17644
+ var TABLE_TITLE_PREFIX = "<!-- table-title:";
17645
+ var TABLE_TITLE_SUFFIX = "-->";
17646
+ function extractTableTitle(line) {
17647
+ const trimmed = line.trim();
17648
+ if (!trimmed.startsWith(TABLE_TITLE_PREFIX) || !trimmed.endsWith(TABLE_TITLE_SUFFIX)) {
17649
+ return void 0;
17650
+ }
17651
+ return trimmed.slice(TABLE_TITLE_PREFIX.length, -TABLE_TITLE_SUFFIX.length).trim() || void 0;
17652
+ }
17653
+ function parseMarkdownTable(markdown, tableIndex = 0) {
17654
+ const lines = markdown.split("\n");
17655
+ let tableCount = 0;
17656
+ for (let i = 0; i < lines.length - 1; i++) {
17657
+ const headerLine = lines[i];
17658
+ const separatorLine = lines[i + 1];
17659
+ if (!isTableRow(headerLine) || !isSeparatorRow(separatorLine)) {
17660
+ continue;
17661
+ }
17662
+ if (tableCount === tableIndex) {
17663
+ const columns = parseCells(headerLine);
17664
+ const rows = [];
17665
+ const title = i > 0 ? extractTableTitle(lines[i - 1]) : void 0;
17666
+ for (let j = i + 2; j < lines.length; j++) {
17667
+ if (!isTableRow(lines[j]) || isSeparatorRow(lines[j])) {
17668
+ break;
17669
+ }
17670
+ const trimmedLine = lines[j].trim();
17671
+ if (trimmedLine === "") {
17672
+ break;
17673
+ }
17674
+ rows.push(parseCells(lines[j]));
17675
+ }
17676
+ return { columns, rows, ...title ? { title } : {} };
17677
+ }
17678
+ tableCount++;
17679
+ }
17680
+ return null;
17681
+ }
17682
+
17683
+ // src/utils/convert-table-to-csv.ts
17684
+ function escapeField(field) {
17685
+ if (field.includes(",") || field.includes('"') || field.includes("\n") || field.includes("\r")) {
17686
+ return `"${field.replace(/"/g, '""')}"`;
17687
+ }
17688
+ return field;
17689
+ }
17690
+ function convertTableToCSV(table) {
17691
+ const headerRow = table.columns.map(escapeField).join(",");
17692
+ const dataRows = table.rows.map((row) => row.map(escapeField).join(","));
17693
+ return [headerRow, ...dataRows].join("\r\n");
17694
+ }
17695
+
17589
17696
  // src/components/button/button.tsx
17590
- var import_react9 = require("react");
17697
+ var import_react10 = require("react");
17591
17698
 
17592
17699
  // src/components/button/button-styles.ts
17593
- var import_styled_components9 = __toESM(require("styled-components"), 1);
17700
+ var import_styled_components10 = __toESM(require("styled-components"), 1);
17594
17701
  var sizeStyles = {
17595
- xs: import_styled_components9.css`
17702
+ xs: import_styled_components10.css`
17596
17703
  padding: 6px 10px;
17597
17704
  border-radius: 8px;
17598
17705
  gap: 4px;
17599
17706
  `,
17600
- s: import_styled_components9.css`
17707
+ s: import_styled_components10.css`
17601
17708
  padding: 8px 12px;
17602
17709
  border-radius: 10px;
17603
17710
  gap: 6px;
17604
17711
  `,
17605
- m: import_styled_components9.css`
17712
+ m: import_styled_components10.css`
17606
17713
  padding: 10px 14px;
17607
17714
  border-radius: 10px;
17608
17715
  gap: 6px;
17609
17716
  `
17610
17717
  };
17611
17718
  var variantStyles2 = {
17612
- solid: import_styled_components9.css`
17719
+ solid: import_styled_components10.css`
17613
17720
  background: ${colors["brown-100"]};
17614
17721
  color: ${colors.white};
17615
17722
  border: none;
@@ -17623,7 +17730,7 @@ var variantStyles2 = {
17623
17730
  color: ${colors["brown-50"]};
17624
17731
  }
17625
17732
  `,
17626
- outline: import_styled_components9.css`
17733
+ outline: import_styled_components10.css`
17627
17734
  background: ${colors.white};
17628
17735
  color: ${colors["brown-100"]};
17629
17736
  border: 1px solid ${colors["brown-40"]};
@@ -17637,7 +17744,7 @@ var variantStyles2 = {
17637
17744
  color: ${colors["brown-50"]};
17638
17745
  }
17639
17746
  `,
17640
- ghost: import_styled_components9.css`
17747
+ ghost: import_styled_components10.css`
17641
17748
  background: transparent;
17642
17749
  color: ${colors["brown-100"]};
17643
17750
  border: none;
@@ -17651,7 +17758,7 @@ var variantStyles2 = {
17651
17758
  }
17652
17759
  `
17653
17760
  };
17654
- var StyledButton = import_styled_components9.default.button`
17761
+ var StyledButton = import_styled_components10.default.button`
17655
17762
  display: inline-flex;
17656
17763
  align-items: center;
17657
17764
  justify-content: center;
@@ -17684,8 +17791,8 @@ var ICON_POSITION = {
17684
17791
  };
17685
17792
 
17686
17793
  // src/components/button/button.tsx
17687
- var import_jsx_runtime10 = require("react/jsx-runtime");
17688
- var Button2 = (0, import_react9.forwardRef)(function Button3({
17794
+ var import_jsx_runtime11 = require("react/jsx-runtime");
17795
+ var Button2 = (0, import_react10.forwardRef)(function Button3({
17689
17796
  children,
17690
17797
  variant = BUTTON_VARIANT.SOLID,
17691
17798
  size = BUTTON_SIZE.M,
@@ -17696,8 +17803,8 @@ var Button2 = (0, import_react9.forwardRef)(function Button3({
17696
17803
  className,
17697
17804
  "aria-label": ariaLabel
17698
17805
  }, ref) {
17699
- const iconElement = icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { icon, size: 16 }) : null;
17700
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
17806
+ const iconElement = icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { icon, size: 16 }) : null;
17807
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
17701
17808
  StyledButton,
17702
17809
  {
17703
17810
  ref,
@@ -17710,7 +17817,7 @@ var Button2 = (0, import_react9.forwardRef)(function Button3({
17710
17817
  "aria-label": ariaLabel,
17711
17818
  children: [
17712
17819
  iconPosition === ICON_POSITION.LEADING && iconElement,
17713
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children }),
17820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children }),
17714
17821
  iconPosition === ICON_POSITION.TRAILING && iconElement
17715
17822
  ]
17716
17823
  }
@@ -17733,9 +17840,11 @@ var Button2 = (0, import_react9.forwardRef)(function Button3({
17733
17840
  MESSAGE_ROLE,
17734
17841
  TextArea,
17735
17842
  colors,
17843
+ convertTableToCSV,
17736
17844
  fontFamilies,
17737
17845
  markdownToPlainText,
17738
17846
  mergeRefs,
17847
+ parseMarkdownTable,
17739
17848
  typographyMixin,
17740
17849
  typographyStyles,
17741
17850
  typographyTypes,