@surf-kit/agent 0.1.1 → 0.2.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 (74) hide show
  1. package/README.md +19 -1
  2. package/dist/agent-BNSmiexZ.d.cts +44 -0
  3. package/dist/agent-BNSmiexZ.d.ts +44 -0
  4. package/dist/agent-identity/index.cjs +157 -0
  5. package/dist/agent-identity/index.cjs.map +1 -0
  6. package/dist/agent-identity/index.d.cts +35 -0
  7. package/dist/agent-identity/index.d.ts +35 -0
  8. package/dist/agent-identity/index.js +127 -0
  9. package/dist/agent-identity/index.js.map +1 -0
  10. package/dist/chat/index.cjs +1281 -0
  11. package/dist/chat/index.cjs.map +1 -0
  12. package/dist/chat/index.d.cts +72 -0
  13. package/dist/chat/index.d.ts +72 -0
  14. package/dist/chat/index.js +1239 -0
  15. package/dist/chat/index.js.map +1 -0
  16. package/dist/chat--OifhIRe.d.ts +24 -0
  17. package/dist/chat-ChYl2XjV.d.cts +24 -0
  18. package/dist/confidence/index.cjs +253 -0
  19. package/dist/confidence/index.cjs.map +1 -0
  20. package/dist/confidence/index.d.cts +40 -0
  21. package/dist/confidence/index.d.ts +40 -0
  22. package/dist/confidence/index.js +222 -0
  23. package/dist/confidence/index.js.map +1 -0
  24. package/dist/feedback/index.cjs +186 -0
  25. package/dist/feedback/index.cjs.map +1 -0
  26. package/dist/feedback/index.d.cts +27 -0
  27. package/dist/feedback/index.d.ts +27 -0
  28. package/dist/feedback/index.js +157 -0
  29. package/dist/feedback/index.js.map +1 -0
  30. package/dist/{hooks-B8CSeOsn.d.cts → hooks-BGs8-4GK.d.ts} +4 -99
  31. package/dist/{hooks-B8CSeOsn.d.ts → hooks-DLfF18IU.d.cts} +4 -99
  32. package/dist/hooks.d.cts +4 -1
  33. package/dist/hooks.d.ts +4 -1
  34. package/dist/index-BazLnae1.d.cts +67 -0
  35. package/dist/index-BazLnae1.d.ts +67 -0
  36. package/dist/index.cjs +889 -144
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +15 -321
  39. package/dist/index.d.ts +15 -321
  40. package/dist/index.js +879 -142
  41. package/dist/index.js.map +1 -1
  42. package/dist/layouts/index.cjs +1588 -0
  43. package/dist/layouts/index.cjs.map +1 -0
  44. package/dist/layouts/index.d.cts +46 -0
  45. package/dist/layouts/index.d.ts +46 -0
  46. package/dist/layouts/index.js +1548 -0
  47. package/dist/layouts/index.js.map +1 -0
  48. package/dist/mcp/index.cjs +522 -0
  49. package/dist/mcp/index.cjs.map +1 -0
  50. package/dist/mcp/index.d.cts +2 -0
  51. package/dist/mcp/index.d.ts +2 -0
  52. package/dist/mcp/index.js +492 -0
  53. package/dist/mcp/index.js.map +1 -0
  54. package/dist/response/index.cjs +519 -0
  55. package/dist/response/index.cjs.map +1 -0
  56. package/dist/response/index.d.cts +44 -0
  57. package/dist/response/index.d.ts +44 -0
  58. package/dist/response/index.js +478 -0
  59. package/dist/response/index.js.map +1 -0
  60. package/dist/sources/index.cjs +243 -0
  61. package/dist/sources/index.cjs.map +1 -0
  62. package/dist/sources/index.d.cts +44 -0
  63. package/dist/sources/index.d.ts +44 -0
  64. package/dist/sources/index.js +212 -0
  65. package/dist/sources/index.js.map +1 -0
  66. package/dist/streaming/index.cjs +531 -0
  67. package/dist/streaming/index.cjs.map +1 -0
  68. package/dist/streaming/index.d.cts +81 -0
  69. package/dist/streaming/index.d.ts +81 -0
  70. package/dist/streaming/index.js +495 -0
  71. package/dist/streaming/index.js.map +1 -0
  72. package/dist/streaming-DbQxScpi.d.ts +39 -0
  73. package/dist/streaming-DfT22A0z.d.cts +39 -0
  74. package/package.json +62 -17
package/dist/index.cjs CHANGED
@@ -47,6 +47,10 @@ __export(index_exports, {
47
47
  FeedbackConfirmation: () => FeedbackConfirmation,
48
48
  FeedbackDialog: () => FeedbackDialog,
49
49
  FollowUpChips: () => FollowUpChips,
50
+ MCPApprovalDialog: () => MCPApprovalDialog,
51
+ MCPResourceView: () => MCPResourceView,
52
+ MCPServerStatus: () => MCPServerStatus,
53
+ MCPToolCall: () => MCPToolCall,
50
54
  MessageBubble: () => MessageBubble,
51
55
  MessageComposer: () => MessageComposer,
52
56
  MessageThread: () => MessageThread,
@@ -58,12 +62,16 @@ __export(index_exports, {
58
62
  SourceDrawer: () => SourceDrawer,
59
63
  SourceInline: () => SourceInline,
60
64
  SourceList: () => SourceList,
65
+ StreamingList: () => StreamingList,
61
66
  StreamingMessage: () => StreamingMessage,
67
+ StreamingStructure: () => StreamingStructure,
62
68
  StructuredResponse: () => StructuredResponse,
69
+ TextGlimmer: () => TextGlimmer,
63
70
  ThinkingIndicator: () => ThinkingIndicator,
64
71
  ThumbsFeedback: () => ThumbsFeedback,
65
72
  ToolExecution: () => ToolExecution,
66
73
  TypewriterText: () => TypewriterText,
74
+ TypingIndicator: () => TypingIndicator,
67
75
  VerificationBadge: () => VerificationBadge,
68
76
  VerificationDetail: () => VerificationDetail,
69
77
  VerificationProgress: () => VerificationProgress,
@@ -656,7 +664,7 @@ function FollowUpChips({ suggestions, onSelect, className }) {
656
664
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
657
665
  "div",
658
666
  {
659
- className: `flex gap-2 overflow-x-auto py-1 ${className ?? ""}`,
667
+ className: (0, import_tailwind_merge3.twMerge)("flex flex-wrap gap-2 py-1", className),
660
668
  role: "group",
661
669
  "aria-label": "Follow-up suggestions",
662
670
  "data-testid": "follow-up-chips",
@@ -666,9 +674,9 @@ function FollowUpChips({ suggestions, onSelect, className }) {
666
674
  type: "button",
667
675
  onClick: () => onSelect(suggestion),
668
676
  className: (0, import_tailwind_merge3.twMerge)(
669
- "px-4 py-1.5 rounded-full text-sm shrink-0 whitespace-nowrap",
670
- "border border-border bg-surface text-text-primary",
671
- "hover:bg-surface-raised hover:border-interactive hover:text-text-primary",
677
+ "px-4 py-1.5 rounded-full text-sm whitespace-nowrap",
678
+ "border border-border bg-transparent text-text-secondary",
679
+ "hover:bg-accent/10 hover:border-interactive hover:text-text-primary",
672
680
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
673
681
  "transition-all duration-200"
674
682
  ),
@@ -771,6 +779,7 @@ function MessageBubble({
771
779
  showSources = true,
772
780
  showConfidence = true,
773
781
  showVerification = true,
782
+ animated = true,
774
783
  className
775
784
  }) {
776
785
  const isUser = message.role === "user";
@@ -780,7 +789,16 @@ function MessageBubble({
780
789
  {
781
790
  "data-message-id": message.id,
782
791
  className: (0, import_tailwind_merge4.twMerge)("flex w-full justify-end", className),
783
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "max-w-[75%] rounded-[18px] rounded-br-[4px] px-4 py-2.5 bg-accent text-white whitespace-pre-wrap text-sm leading-relaxed", children: message.content })
792
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
793
+ "div",
794
+ {
795
+ className: (0, import_tailwind_merge4.twMerge)(
796
+ "max-w-[70%] rounded-[18px] rounded-br-[4px] px-4 py-2.5 bg-accent text-brand-cream break-words whitespace-pre-wrap text-sm leading-relaxed",
797
+ animated && "motion-safe:animate-slideFromRight"
798
+ ),
799
+ children: message.content
800
+ }
801
+ )
784
802
  }
785
803
  );
786
804
  }
@@ -790,16 +808,25 @@ function MessageBubble({
790
808
  "data-message-id": message.id,
791
809
  className: (0, import_tailwind_merge4.twMerge)("flex w-full flex-col items-start gap-1.5", className),
792
810
  children: [
793
- showAgent && message.agent && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-[11px] font-medium uppercase tracking-[0.08em] text-text-secondary px-1", children: message.agent.replace("_agent", "").replace("_", " ") }),
794
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "max-w-[88%] rounded-[18px] rounded-tl-[4px] px-4 py-3 bg-surface-raised border border-border", children: message.response ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
795
- AgentResponse,
811
+ showAgent && message.agent && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-[11px] font-semibold uppercase tracking-[0.08em] text-text-muted px-1", children: message.agent.replace("_agent", "").replace("_", " ") }),
812
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
813
+ "div",
796
814
  {
797
- response: message.response,
798
- showSources,
799
- showConfidence,
800
- showVerification
815
+ className: (0, import_tailwind_merge4.twMerge)(
816
+ "max-w-[88%] rounded-[18px] rounded-tl-[4px] px-4 py-3 bg-surface border border-border",
817
+ animated && "motion-safe:animate-springFromLeft"
818
+ ),
819
+ children: message.response ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
820
+ AgentResponse,
821
+ {
822
+ response: message.response,
823
+ showSources,
824
+ showConfidence,
825
+ showVerification
826
+ }
827
+ ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ResponseMessage, { content: message.content })
801
828
  }
802
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ResponseMessage, { content: message.content }) })
829
+ )
803
830
  ]
804
831
  }
805
832
  );
@@ -853,12 +880,20 @@ function MessageComposer({
853
880
  const [value, setValue] = (0, import_react4.useState)("");
854
881
  const textareaRef = (0, import_react4.useRef)(null);
855
882
  const canSend = value.trim().length > 0 && !isLoading;
883
+ const resetHeight = (0, import_react4.useCallback)(() => {
884
+ const el = textareaRef.current;
885
+ if (el) {
886
+ el.style.height = "auto";
887
+ el.style.overflowY = "hidden";
888
+ }
889
+ }, []);
856
890
  const handleSend = (0, import_react4.useCallback)(() => {
857
891
  if (!canSend) return;
858
892
  onSend(value.trim());
859
893
  setValue("");
894
+ resetHeight();
860
895
  textareaRef.current?.focus();
861
- }, [canSend, onSend, value]);
896
+ }, [canSend, onSend, value, resetHeight]);
862
897
  const handleKeyDown = (0, import_react4.useCallback)(
863
898
  (e) => {
864
899
  if (e.key === "Enter" && !e.shiftKey) {
@@ -868,11 +903,22 @@ function MessageComposer({
868
903
  },
869
904
  [handleSend]
870
905
  );
906
+ const handleChange = (0, import_react4.useCallback)(
907
+ (e) => {
908
+ setValue(e.target.value);
909
+ const el = e.target;
910
+ el.style.height = "auto";
911
+ const capped = Math.min(el.scrollHeight, 128);
912
+ el.style.height = `${capped}px`;
913
+ el.style.overflowY = el.scrollHeight > 128 ? "auto" : "hidden";
914
+ },
915
+ []
916
+ );
871
917
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
872
918
  "div",
873
919
  {
874
920
  className: (0, import_tailwind_merge6.twMerge)(
875
- "flex items-end gap-3 border-t border-border px-4 py-3 bg-canvas",
921
+ "flex items-end gap-3 shrink-0 border-t border-border px-4 py-3",
876
922
  className
877
923
  ),
878
924
  children: [
@@ -881,16 +927,17 @@ function MessageComposer({
881
927
  {
882
928
  ref: textareaRef,
883
929
  value,
884
- onChange: (e) => setValue(e.target.value),
930
+ onChange: handleChange,
885
931
  onKeyDown: handleKeyDown,
886
932
  placeholder,
887
933
  rows: 1,
888
934
  disabled: isLoading,
889
935
  className: (0, import_tailwind_merge6.twMerge)(
890
- "flex-1 resize-none rounded-xl border border-border bg-surface",
936
+ "flex-1 resize-none rounded-xl border border-border bg-surface/80",
891
937
  "px-4 py-2.5 text-sm text-text-primary placeholder:text-text-muted",
892
938
  "focus:border-transparent focus:ring-2 focus:ring-accent/40 focus:outline-none",
893
939
  "disabled:opacity-50 disabled:cursor-not-allowed",
940
+ "overflow-hidden",
894
941
  "transition-all duration-200"
895
942
  ),
896
943
  style: { colorScheme: "dark" },
@@ -909,7 +956,7 @@ function MessageComposer({
909
956
  "text-sm font-semibold text-white shrink-0",
910
957
  "transition-all duration-200",
911
958
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
912
- value.trim() && !isLoading ? "bg-accent hover:bg-accent-hover hover:scale-[1.02] active:scale-[0.98]" : "bg-accent/30 text-text-muted cursor-not-allowed"
959
+ value.trim() && !isLoading ? "bg-accent hover:bg-accent-hover hover:scale-[1.02] hover:shadow-glow-cyan active:scale-[0.98]" : "bg-accent/30 text-text-muted cursor-not-allowed"
913
960
  ),
914
961
  children: "Send"
915
962
  }
@@ -925,6 +972,7 @@ var import_jsx_runtime10 = require("react/jsx-runtime");
925
972
  function WelcomeScreen({
926
973
  title = "Welcome",
927
974
  message = "How can I help you today?",
975
+ icon,
928
976
  suggestedQuestions = [],
929
977
  onQuestionSelect,
930
978
  className
@@ -933,7 +981,7 @@ function WelcomeScreen({
933
981
  "div",
934
982
  {
935
983
  className: (0, import_tailwind_merge7.twMerge)(
936
- "flex flex-1 flex-col items-center justify-center gap-8 p-8 text-center",
984
+ "flex flex-1 flex-col items-center justify-center gap-8 p-8 text-center motion-safe:animate-fadeUp",
937
985
  className
938
986
  ),
939
987
  children: [
@@ -942,12 +990,12 @@ function WelcomeScreen({
942
990
  {
943
991
  className: "w-14 h-14 rounded-2xl bg-accent/10 border border-border flex items-center justify-center pulse-glow",
944
992
  "aria-hidden": "true",
945
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-2xl", children: "\u2726" })
993
+ children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-2xl", children: "\u2726" })
946
994
  }
947
995
  ),
948
996
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2", children: [
949
- title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "text-2xl font-semibold text-text-primary", children: title }),
950
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-text-secondary text-base leading-relaxed max-w-sm", children: message })
997
+ title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "text-3xl font-bold text-text-primary", children: title }),
998
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-text-secondary text-base leading-relaxed max-w-md", children: message })
951
999
  ] }),
952
1000
  suggestedQuestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
953
1001
  "div",
@@ -962,8 +1010,8 @@ function WelcomeScreen({
962
1010
  onClick: () => onQuestionSelect?.(question),
963
1011
  className: (0, import_tailwind_merge7.twMerge)(
964
1012
  "px-4 py-2 rounded-full text-sm",
965
- "border border-border bg-surface text-text-primary",
966
- "hover:bg-surface-raised hover:border-interactive hover:text-text-primary",
1013
+ "border border-border bg-transparent text-text-secondary",
1014
+ "hover:bg-accent/10 hover:border-interactive hover:text-text-primary",
967
1015
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
968
1016
  "transition-colors duration-200"
969
1017
  ),
@@ -1048,11 +1096,11 @@ function useCharacterDrain(target, msPerChar = 15) {
1048
1096
  var import_jsx_runtime11 = require("react/jsx-runtime");
1049
1097
  var phaseLabels = {
1050
1098
  idle: "",
1051
- waiting: "Waiting",
1052
- thinking: "Thinking",
1053
- retrieving: "Searching",
1054
- generating: "Writing",
1055
- verifying: "Verifying"
1099
+ waiting: "Waiting...",
1100
+ thinking: "Thinking...",
1101
+ retrieving: "Searching...",
1102
+ generating: "Writing...",
1103
+ verifying: "Verifying..."
1056
1104
  };
1057
1105
  function StreamingMessage({
1058
1106
  stream,
@@ -1076,27 +1124,29 @@ function StreamingMessage({
1076
1124
  stream.active && stream.phase !== "idle" && "Response started",
1077
1125
  !stream.active && stream.content && "Response complete"
1078
1126
  ] }),
1079
- showPhases && stream.active && stream.phase !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1080
- "div",
1081
- {
1082
- className: "flex items-center gap-2 mb-2 text-sm text-text-secondary",
1083
- "data-testid": "phase-indicator",
1084
- children: [
1085
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_core3.Spinner, { size: "sm" }) }),
1086
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: phaseLabel })
1087
- ]
1088
- }
1089
- ),
1090
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-text-primary whitespace-pre-wrap", children: [
1091
- displayedContent,
1092
- stream.active && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1093
- "span",
1127
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "max-w-[88%] px-4 py-3 rounded-[18px] rounded-tl-[4px] bg-surface border border-border motion-safe:animate-springFromLeft", children: [
1128
+ showPhases && stream.active && stream.phase !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1129
+ "div",
1094
1130
  {
1095
- className: "inline-block w-0.5 h-4 bg-accent align-text-bottom animate-pulse ml-0.5",
1096
- "aria-hidden": "true",
1097
- "data-testid": "streaming-cursor"
1131
+ className: "flex items-center gap-2 mb-2 text-sm text-text-secondary",
1132
+ "data-testid": "phase-indicator",
1133
+ children: [
1134
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_core3.Spinner, { size: "sm" }) }),
1135
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: phaseLabel })
1136
+ ]
1098
1137
  }
1099
- )
1138
+ ),
1139
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-sm leading-relaxed text-text-primary whitespace-pre-wrap", children: [
1140
+ displayedContent,
1141
+ stream.active && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1142
+ "span",
1143
+ {
1144
+ className: "inline-block w-0.5 h-4 bg-accent align-text-bottom animate-pulse ml-0.5",
1145
+ "aria-hidden": "true",
1146
+ "data-testid": "streaming-cursor"
1147
+ }
1148
+ )
1149
+ ] })
1100
1150
  ] })
1101
1151
  ] });
1102
1152
  }
@@ -1615,7 +1665,7 @@ function ThinkingIndicator({ label = "Thinking...", className }) {
1615
1665
  "span",
1616
1666
  {
1617
1667
  role: "status",
1618
- className: `inline-flex items-center gap-2 text-sm ${className ?? ""}`,
1668
+ className: `inline-flex items-center gap-2 text-sm motion-safe:animate-fadeSlideUpSm ${className ?? ""}`,
1619
1669
  "data-testid": "thinking-indicator",
1620
1670
  children: [
1621
1671
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-text-secondary", children: label }),
@@ -1763,9 +1813,210 @@ function TypewriterText({
1763
1813
  ] });
1764
1814
  }
1765
1815
 
1766
- // src/chat/ConversationList/ConversationList.tsx
1816
+ // src/streaming/TypingIndicator/TypingIndicator.tsx
1767
1817
  var import_tailwind_merge9 = require("tailwind-merge");
1818
+ var import_hooks2 = require("@surf-kit/hooks");
1768
1819
  var import_jsx_runtime31 = require("react/jsx-runtime");
1820
+ var bounceKeyframes = `
1821
+ @keyframes typing-bounce {
1822
+ 0%, 80%, 100% { transform: translateY(0); }
1823
+ 40% { transform: translateY(-6px); }
1824
+ }
1825
+ `;
1826
+ function TypingIndicator({
1827
+ label,
1828
+ dotCount = 3,
1829
+ className
1830
+ }) {
1831
+ const reducedMotion = (0, import_hooks2.useReducedMotion)();
1832
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1833
+ "span",
1834
+ {
1835
+ role: "status",
1836
+ "aria-label": label ?? "typing",
1837
+ className: (0, import_tailwind_merge9.twMerge)("inline-flex items-center gap-2", className),
1838
+ "data-testid": "typing-indicator",
1839
+ children: [
1840
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("style", { children: bounceKeyframes }),
1841
+ label && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-sm text-text-secondary", children: label }),
1842
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "flex gap-1", "data-testid": "typing-dots", children: Array.from({ length: dotCount }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1843
+ "span",
1844
+ {
1845
+ className: "w-2 h-2 rounded-full bg-text-secondary",
1846
+ style: reducedMotion ? void 0 : {
1847
+ animation: "typing-bounce 1.4s infinite ease-in-out",
1848
+ animationDelay: `${i * 160}ms`
1849
+ }
1850
+ },
1851
+ i
1852
+ )) })
1853
+ ]
1854
+ }
1855
+ );
1856
+ }
1857
+
1858
+ // src/streaming/TextGlimmer/TextGlimmer.tsx
1859
+ var import_tailwind_merge10 = require("tailwind-merge");
1860
+ var import_hooks3 = require("@surf-kit/hooks");
1861
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1862
+ var shimmerKeyframes = `
1863
+ @keyframes text-shimmer {
1864
+ 0% { background-position: 200% 0; }
1865
+ 100% { background-position: -200% 0; }
1866
+ }
1867
+ `;
1868
+ var widthPattern = ["100%", "90%", "60%"];
1869
+ function TextGlimmer({ lines = 3, className }) {
1870
+ const reducedMotion = (0, import_hooks3.useReducedMotion)();
1871
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1872
+ "div",
1873
+ {
1874
+ role: "status",
1875
+ "aria-label": "Loading",
1876
+ className: (0, import_tailwind_merge10.twMerge)("flex flex-col gap-2", className),
1877
+ "data-testid": "text-glimmer",
1878
+ children: [
1879
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: shimmerKeyframes }),
1880
+ Array.from({ length: lines }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1881
+ "div",
1882
+ {
1883
+ className: "h-3 rounded bg-surface-raised",
1884
+ style: {
1885
+ width: widthPattern[i % widthPattern.length],
1886
+ ...reducedMotion ? void 0 : {
1887
+ backgroundImage: "linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent)",
1888
+ backgroundSize: "200% 100%",
1889
+ animation: "text-shimmer 1.5s infinite ease-in-out"
1890
+ }
1891
+ },
1892
+ "data-testid": "glimmer-line"
1893
+ },
1894
+ i
1895
+ ))
1896
+ ]
1897
+ }
1898
+ );
1899
+ }
1900
+
1901
+ // src/streaming/StreamingList/StreamingList.tsx
1902
+ var import_tailwind_merge11 = require("tailwind-merge");
1903
+ var import_hooks4 = require("@surf-kit/hooks");
1904
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1905
+ var fadeSlideInKeyframes = `
1906
+ @keyframes fadeSlideIn {
1907
+ from { opacity: 0; transform: translateY(8px); }
1908
+ to { opacity: 1; transform: translateY(0); }
1909
+ }
1910
+ `;
1911
+ function StreamingList({
1912
+ items,
1913
+ renderItem,
1914
+ isStreaming = false,
1915
+ className,
1916
+ emptyMessage
1917
+ }) {
1918
+ const reducedMotion = (0, import_hooks4.useReducedMotion)();
1919
+ if (items.length === 0 && !isStreaming) {
1920
+ return emptyMessage ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: (0, import_tailwind_merge11.twMerge)("text-sm text-text-secondary", className), "data-testid": "streaming-list-empty", children: emptyMessage }) : null;
1921
+ }
1922
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
1923
+ "ul",
1924
+ {
1925
+ "aria-live": "polite",
1926
+ className: (0, import_tailwind_merge11.twMerge)("list-none p-0 m-0", className),
1927
+ "data-testid": "streaming-list",
1928
+ children: [
1929
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("style", { children: fadeSlideInKeyframes }),
1930
+ items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1931
+ "li",
1932
+ {
1933
+ style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
1934
+ "data-testid": "streaming-list-item",
1935
+ children: renderItem(item, index)
1936
+ },
1937
+ index
1938
+ )),
1939
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("li", { "data-testid": "streaming-list-loading", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TypingIndicator, {}) })
1940
+ ]
1941
+ }
1942
+ );
1943
+ }
1944
+
1945
+ // src/streaming/StreamingStructure/StreamingStructure.tsx
1946
+ var import_tailwind_merge12 = require("tailwind-merge");
1947
+ var import_hooks5 = require("@surf-kit/hooks");
1948
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1949
+ var fadeSlideInKeyframes2 = `
1950
+ @keyframes fadeSlideIn {
1951
+ from { opacity: 0; transform: translateY(8px); }
1952
+ to { opacity: 1; transform: translateY(0); }
1953
+ }
1954
+ `;
1955
+ function renderValue(value, reducedMotion) {
1956
+ if (value === null) {
1957
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "italic text-text-secondary", children: "null" });
1958
+ }
1959
+ if (value === void 0) {
1960
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "italic text-text-secondary", children: "undefined" });
1961
+ }
1962
+ if (Array.isArray(value)) {
1963
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ol", { className: "list-decimal pl-4 m-0", children: value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("li", { className: "text-text-secondary text-sm", children: renderValue(item, reducedMotion) }, i)) });
1964
+ }
1965
+ if (typeof value === "object") {
1966
+ return renderNestedDl(value, reducedMotion);
1967
+ }
1968
+ return String(value);
1969
+ }
1970
+ function renderNestedDl(data, reducedMotion) {
1971
+ const entries = Object.entries(data);
1972
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dl", { className: "pl-4 m-0", "data-testid": "streaming-structure-nested", children: entries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1973
+ "div",
1974
+ {
1975
+ style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
1976
+ children: [
1977
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dt", { className: "font-medium text-text-primary text-sm", children: key }),
1978
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
1979
+ ]
1980
+ },
1981
+ key
1982
+ )) });
1983
+ }
1984
+ function StreamingStructure({
1985
+ data,
1986
+ isStreaming = false,
1987
+ className
1988
+ }) {
1989
+ const reducedMotion = (0, import_hooks5.useReducedMotion)();
1990
+ const entries = Object.entries(data);
1991
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1992
+ "dl",
1993
+ {
1994
+ "aria-live": "polite",
1995
+ className: (0, import_tailwind_merge12.twMerge)("m-0", className),
1996
+ "data-testid": "streaming-structure",
1997
+ children: [
1998
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("style", { children: fadeSlideInKeyframes2 }),
1999
+ entries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2000
+ "div",
2001
+ {
2002
+ style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
2003
+ "data-testid": "streaming-structure-entry",
2004
+ children: [
2005
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dt", { className: "font-medium text-text-primary text-sm", children: key }),
2006
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
2007
+ ]
2008
+ },
2009
+ key
2010
+ )),
2011
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { "data-testid": "streaming-structure-loading", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(TextGlimmer, { lines: 1 }) })
2012
+ ]
2013
+ }
2014
+ );
2015
+ }
2016
+
2017
+ // src/chat/ConversationList/ConversationList.tsx
2018
+ var import_tailwind_merge13 = require("tailwind-merge");
2019
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1769
2020
  function ConversationList({
1770
2021
  conversations,
1771
2022
  activeId,
@@ -1774,13 +2025,13 @@ function ConversationList({
1774
2025
  onNew,
1775
2026
  className
1776
2027
  }) {
1777
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2028
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1778
2029
  "nav",
1779
2030
  {
1780
2031
  "aria-label": "Conversation list",
1781
- className: (0, import_tailwind_merge9.twMerge)("flex flex-col h-full bg-canvas", className),
2032
+ className: (0, import_tailwind_merge13.twMerge)("flex flex-col h-full bg-canvas", className),
1782
2033
  children: [
1783
- onNew && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "p-3 border-b border-border", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2034
+ onNew && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "p-3 border-b border-border", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1784
2035
  "button",
1785
2036
  {
1786
2037
  type: "button",
@@ -1789,19 +2040,19 @@ function ConversationList({
1789
2040
  children: "New conversation"
1790
2041
  }
1791
2042
  ) }),
1792
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("ul", { role: "list", className: "flex-1 overflow-y-auto", children: [
2043
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("ul", { role: "list", className: "flex-1 overflow-y-auto", children: [
1793
2044
  conversations.map((conversation) => {
1794
2045
  const isActive = conversation.id === activeId;
1795
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2046
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1796
2047
  "li",
1797
2048
  {
1798
- className: (0, import_tailwind_merge9.twMerge)(
2049
+ className: (0, import_tailwind_merge13.twMerge)(
1799
2050
  "flex items-start border-b border-border transition-colors duration-200",
1800
2051
  "hover:bg-surface",
1801
2052
  isActive && "bg-surface-raised border-l-2 border-l-accent"
1802
2053
  ),
1803
2054
  children: [
1804
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2055
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1805
2056
  "button",
1806
2057
  {
1807
2058
  type: "button",
@@ -1809,19 +2060,19 @@ function ConversationList({
1809
2060
  "aria-current": isActive ? "true" : void 0,
1810
2061
  className: "flex-1 min-w-0 text-left px-4 py-3",
1811
2062
  children: [
1812
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "text-sm font-medium text-brand-cream truncate", children: conversation.title }),
1813
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "text-xs text-brand-cream/40 truncate mt-0.5 leading-relaxed", children: conversation.lastMessage })
2063
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "text-sm font-medium text-brand-cream truncate", children: conversation.title }),
2064
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "text-xs text-brand-cream/40 truncate mt-0.5 leading-relaxed", children: conversation.lastMessage })
1814
2065
  ]
1815
2066
  }
1816
2067
  ),
1817
- onDelete && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2068
+ onDelete && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1818
2069
  "button",
1819
2070
  {
1820
2071
  type: "button",
1821
2072
  onClick: () => onDelete(conversation.id),
1822
2073
  "aria-label": `Delete ${conversation.title}`,
1823
2074
  className: "shrink-0 p-1.5 m-2 rounded-lg text-brand-cream/25 hover:text-brand-watermelon hover:bg-brand-watermelon/10 transition-colors duration-200",
1824
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2075
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1825
2076
  "svg",
1826
2077
  {
1827
2078
  xmlns: "http://www.w3.org/2000/svg",
@@ -1835,8 +2086,8 @@ function ConversationList({
1835
2086
  strokeLinejoin: "round",
1836
2087
  "aria-hidden": "true",
1837
2088
  children: [
1838
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("polyline", { points: "3 6 5 6 21 6" }),
1839
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
2089
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("polyline", { points: "3 6 5 6 21 6" }),
2090
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
1840
2091
  ]
1841
2092
  }
1842
2093
  )
@@ -1847,7 +2098,7 @@ function ConversationList({
1847
2098
  conversation.id
1848
2099
  );
1849
2100
  }),
1850
- conversations.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("li", { className: "px-4 py-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-sm text-brand-cream/30 font-body", children: "No conversations yet" }) })
2101
+ conversations.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("li", { className: "px-4 py-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-sm text-brand-cream/30 font-body", children: "No conversations yet" }) })
1851
2102
  ] })
1852
2103
  ]
1853
2104
  }
@@ -1855,9 +2106,9 @@ function ConversationList({
1855
2106
  }
1856
2107
 
1857
2108
  // src/layouts/AgentFullPage/AgentFullPage.tsx
1858
- var import_tailwind_merge10 = require("tailwind-merge");
2109
+ var import_tailwind_merge14 = require("tailwind-merge");
1859
2110
  var import_react11 = require("react");
1860
- var import_jsx_runtime32 = require("react/jsx-runtime");
2111
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1861
2112
  function AgentFullPage({
1862
2113
  endpoint,
1863
2114
  title = "Chat",
@@ -1877,14 +2128,14 @@ function AgentFullPage({
1877
2128
  },
1878
2129
  [onConversationSelect]
1879
2130
  );
1880
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2131
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
1881
2132
  "div",
1882
2133
  {
1883
- className: (0, import_tailwind_merge10.twMerge)("flex h-screen w-full overflow-hidden bg-brand-dark", className),
2134
+ className: (0, import_tailwind_merge14.twMerge)("flex h-screen w-full overflow-hidden bg-brand-dark", className),
1884
2135
  "data-testid": "agent-full-page",
1885
2136
  children: [
1886
- showConversationList && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
1887
- sidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2137
+ showConversationList && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
2138
+ sidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1888
2139
  "div",
1889
2140
  {
1890
2141
  className: "fixed inset-0 bg-brand-dark/80 backdrop-blur-sm z-30 md:hidden",
@@ -1892,10 +2143,10 @@ function AgentFullPage({
1892
2143
  "data-testid": "sidebar-overlay"
1893
2144
  }
1894
2145
  ),
1895
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2146
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1896
2147
  "aside",
1897
2148
  {
1898
- className: (0, import_tailwind_merge10.twMerge)(
2149
+ className: (0, import_tailwind_merge14.twMerge)(
1899
2150
  "bg-brand-dark border-r border-brand-gold/15 w-72 shrink-0 flex-col z-40",
1900
2151
  // Desktop: always visible
1901
2152
  "hidden md:flex",
@@ -1903,7 +2154,7 @@ function AgentFullPage({
1903
2154
  sidebarOpen && "fixed inset-y-0 left-0 flex md:relative"
1904
2155
  ),
1905
2156
  "aria-label": "Conversations sidebar",
1906
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2157
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1907
2158
  ConversationList,
1908
2159
  {
1909
2160
  conversations,
@@ -1916,15 +2167,15 @@ function AgentFullPage({
1916
2167
  }
1917
2168
  )
1918
2169
  ] }),
1919
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex-1 flex flex-col min-w-0 bg-brand-dark", children: [
1920
- showConversationList && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "md:hidden flex items-center border-b border-brand-gold/15 px-3 py-2 bg-brand-dark-panel/60 backdrop-blur-sm", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2170
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex-1 flex flex-col min-w-0 bg-brand-dark", children: [
2171
+ showConversationList && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "md:hidden flex items-center border-b border-brand-gold/15 px-3 py-2 bg-brand-dark-panel/60 backdrop-blur-sm", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1921
2172
  "button",
1922
2173
  {
1923
2174
  type: "button",
1924
2175
  onClick: () => setSidebarOpen(true),
1925
2176
  "aria-label": "Open conversations sidebar",
1926
2177
  className: "p-2 rounded-xl text-brand-cream/60 hover:text-brand-cream hover:bg-brand-dark-panel transition-colors duration-200",
1927
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2178
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
1928
2179
  "svg",
1929
2180
  {
1930
2181
  xmlns: "http://www.w3.org/2000/svg",
@@ -1938,15 +2189,15 @@ function AgentFullPage({
1938
2189
  strokeLinejoin: "round",
1939
2190
  "aria-hidden": "true",
1940
2191
  children: [
1941
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
1942
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
1943
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
2192
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
2193
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
2194
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
1944
2195
  ]
1945
2196
  }
1946
2197
  )
1947
2198
  }
1948
2199
  ) }),
1949
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2200
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1950
2201
  AgentChat,
1951
2202
  {
1952
2203
  endpoint,
@@ -1961,9 +2212,9 @@ function AgentFullPage({
1961
2212
  }
1962
2213
 
1963
2214
  // src/layouts/AgentPanel/AgentPanel.tsx
1964
- var import_tailwind_merge11 = require("tailwind-merge");
2215
+ var import_tailwind_merge15 = require("tailwind-merge");
1965
2216
  var import_react12 = require("react");
1966
- var import_jsx_runtime33 = require("react/jsx-runtime");
2217
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1967
2218
  function AgentPanel({
1968
2219
  endpoint,
1969
2220
  isOpen,
@@ -1983,16 +2234,16 @@ function AgentPanel({
1983
2234
  return () => document.removeEventListener("keydown", handleKeyDown);
1984
2235
  }, [isOpen, onClose]);
1985
2236
  const widthStyle = typeof width === "number" ? `${width}px` : width;
1986
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
2237
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
1987
2238
  "div",
1988
2239
  {
1989
- className: (0, import_tailwind_merge11.twMerge)("fixed inset-0 z-50", !isOpen && "pointer-events-none"),
2240
+ className: (0, import_tailwind_merge15.twMerge)("fixed inset-0 z-50", !isOpen && "pointer-events-none"),
1990
2241
  "aria-hidden": !isOpen,
1991
2242
  children: [
1992
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2243
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1993
2244
  "div",
1994
2245
  {
1995
- className: (0, import_tailwind_merge11.twMerge)(
2246
+ className: (0, import_tailwind_merge15.twMerge)(
1996
2247
  "fixed inset-0 transition-opacity duration-300",
1997
2248
  isOpen ? "opacity-100 bg-brand-dark/70 backdrop-blur-sm pointer-events-auto" : "opacity-0 pointer-events-none"
1998
2249
  ),
@@ -2000,7 +2251,7 @@ function AgentPanel({
2000
2251
  "data-testid": "panel-backdrop"
2001
2252
  }
2002
2253
  ),
2003
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
2254
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
2004
2255
  "div",
2005
2256
  {
2006
2257
  ref: panelRef,
@@ -2008,30 +2259,30 @@ function AgentPanel({
2008
2259
  "aria-label": title,
2009
2260
  "aria-modal": isOpen ? "true" : void 0,
2010
2261
  style: { width: widthStyle, maxWidth: "100vw" },
2011
- className: (0, import_tailwind_merge11.twMerge)(
2262
+ className: (0, import_tailwind_merge15.twMerge)(
2012
2263
  "fixed top-0 h-full flex flex-col z-50 bg-brand-dark shadow-card",
2013
2264
  "transition-transform duration-300 ease-in-out",
2014
2265
  side === "left" ? `left-0 border-r border-brand-gold/15 ${isOpen ? "translate-x-0" : "-translate-x-full"}` : `right-0 border-l border-brand-gold/15 ${isOpen ? "translate-x-0" : "translate-x-full"}`,
2015
2266
  className
2016
2267
  ),
2017
2268
  children: [
2018
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between border-b border-brand-gold/15 px-5 py-3.5 bg-brand-dark-panel/60 backdrop-blur-sm shrink-0", children: [
2019
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h2", { className: "text-base font-display font-semibold text-brand-cream", children: title }),
2020
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2269
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between border-b border-brand-gold/15 px-5 py-3.5 bg-brand-dark-panel/60 backdrop-blur-sm shrink-0", children: [
2270
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("h2", { className: "text-base font-display font-semibold text-brand-cream", children: title }),
2271
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2021
2272
  "button",
2022
2273
  {
2023
2274
  type: "button",
2024
2275
  onClick: onClose,
2025
2276
  "aria-label": "Close panel",
2026
2277
  className: "rounded-xl p-2 text-brand-cream/40 hover:text-brand-cream/80 hover:bg-brand-cream/5 transition-colors duration-200",
2027
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2028
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2029
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2278
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2279
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2280
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2030
2281
  ] })
2031
2282
  }
2032
2283
  )
2033
2284
  ] }),
2034
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2285
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2035
2286
  AgentChat,
2036
2287
  {
2037
2288
  endpoint,
@@ -2050,9 +2301,9 @@ function AgentPanel({
2050
2301
  }
2051
2302
 
2052
2303
  // src/layouts/AgentWidget/AgentWidget.tsx
2053
- var import_tailwind_merge12 = require("tailwind-merge");
2304
+ var import_tailwind_merge16 = require("tailwind-merge");
2054
2305
  var import_react13 = require("react");
2055
- var import_jsx_runtime34 = require("react/jsx-runtime");
2306
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2056
2307
  function AgentWidget({
2057
2308
  endpoint,
2058
2309
  position = "bottom-right",
@@ -2067,14 +2318,14 @@ function AgentWidget({
2067
2318
  const positionClasses = position === "bottom-left" ? "left-4 bottom-4" : "right-4 bottom-4";
2068
2319
  const popoverPositionClasses = position === "bottom-left" ? "left-4 bottom-20" : "right-4 bottom-20";
2069
2320
  const popoverOrigin = position === "bottom-left" ? "origin-bottom-left" : "origin-bottom-right";
2070
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className, children: [
2071
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2321
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className, children: [
2322
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2072
2323
  "div",
2073
2324
  {
2074
2325
  role: "dialog",
2075
2326
  "aria-label": title,
2076
2327
  "aria-hidden": !isOpen,
2077
- className: (0, import_tailwind_merge12.twMerge)(
2328
+ className: (0, import_tailwind_merge16.twMerge)(
2078
2329
  "fixed z-50 flex flex-col",
2079
2330
  "w-[min(400px,calc(100vw-2rem))] h-[min(600px,calc(100vh-6rem))]",
2080
2331
  "rounded-2xl overflow-hidden border border-brand-gold/15",
@@ -2085,23 +2336,23 @@ function AgentWidget({
2085
2336
  isOpen ? "opacity-100 scale-100 pointer-events-auto translate-y-0" : "opacity-0 scale-95 pointer-events-none translate-y-2"
2086
2337
  ),
2087
2338
  children: [
2088
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center justify-between px-4 py-2.5 bg-brand-dark-panel/80 border-b border-brand-gold/15 shrink-0", children: [
2089
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h2", { className: "text-sm font-display font-semibold text-brand-cream", children: title }),
2090
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2339
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between px-4 py-2.5 bg-brand-dark-panel/80 border-b border-brand-gold/15 shrink-0", children: [
2340
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "text-sm font-display font-semibold text-brand-cream", children: title }),
2341
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2091
2342
  "button",
2092
2343
  {
2093
2344
  type: "button",
2094
2345
  onClick: () => setIsOpen(false),
2095
2346
  "aria-label": "Minimize chat",
2096
2347
  className: "rounded-lg p-1.5 text-brand-cream/40 hover:text-brand-cream/70 transition-colors duration-200",
2097
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2098
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2099
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2348
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2349
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2350
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2100
2351
  ] })
2101
2352
  }
2102
2353
  )
2103
2354
  ] }),
2104
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2355
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2105
2356
  AgentChat,
2106
2357
  {
2107
2358
  endpoint,
@@ -2114,14 +2365,14 @@ function AgentWidget({
2114
2365
  ]
2115
2366
  }
2116
2367
  ),
2117
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2368
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2118
2369
  "button",
2119
2370
  {
2120
2371
  type: "button",
2121
2372
  onClick: toggle,
2122
2373
  "aria-label": isOpen ? "Close chat" : triggerLabel,
2123
2374
  "aria-expanded": isOpen,
2124
- className: (0, import_tailwind_merge12.twMerge)(
2375
+ className: (0, import_tailwind_merge16.twMerge)(
2125
2376
  "fixed z-50 flex items-center justify-center w-14 h-14 rounded-full",
2126
2377
  "bg-brand-blue text-brand-cream shadow-glow-cyan",
2127
2378
  "hover:bg-brand-cyan hover:shadow-glow-cyan hover:scale-105",
@@ -2129,29 +2380,29 @@ function AgentWidget({
2129
2380
  "transition-all duration-200",
2130
2381
  positionClasses
2131
2382
  ),
2132
- children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2133
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2134
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2135
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })
2383
+ children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2384
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2385
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2386
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })
2136
2387
  }
2137
2388
  )
2138
2389
  ] });
2139
2390
  }
2140
2391
 
2141
2392
  // src/layouts/AgentEmbed/AgentEmbed.tsx
2142
- var import_tailwind_merge13 = require("tailwind-merge");
2143
- var import_jsx_runtime35 = require("react/jsx-runtime");
2393
+ var import_tailwind_merge17 = require("tailwind-merge");
2394
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2144
2395
  function AgentEmbed({
2145
2396
  endpoint,
2146
2397
  title = "Chat",
2147
2398
  className
2148
2399
  }) {
2149
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2400
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2150
2401
  "div",
2151
2402
  {
2152
- className: (0, import_tailwind_merge13.twMerge)("w-full h-full min-h-0", className),
2403
+ className: (0, import_tailwind_merge17.twMerge)("w-full h-full min-h-0", className),
2153
2404
  "data-testid": "agent-embed",
2154
- children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2405
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2155
2406
  AgentChat,
2156
2407
  {
2157
2408
  endpoint,
@@ -2163,9 +2414,495 @@ function AgentEmbed({
2163
2414
  );
2164
2415
  }
2165
2416
 
2166
- // src/feedback/ThumbsFeedback/ThumbsFeedback.tsx
2417
+ // src/mcp/MCPToolCall/MCPToolCall.tsx
2418
+ var import_class_variance_authority = require("class-variance-authority");
2419
+ var import_tailwind_merge18 = require("tailwind-merge");
2420
+ var import_core12 = require("@surf-kit/core");
2421
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2422
+ var statusBadgeIntent = {
2423
+ pending: "default",
2424
+ running: "info",
2425
+ success: "success",
2426
+ error: "error"
2427
+ };
2428
+ var statusLabel = {
2429
+ pending: "Pending",
2430
+ running: "Running",
2431
+ success: "Success",
2432
+ error: "Error"
2433
+ };
2434
+ var container = (0, import_class_variance_authority.cva)(
2435
+ "rounded-lg border text-sm",
2436
+ {
2437
+ variants: {
2438
+ status: {
2439
+ pending: "border-neutral-200 bg-neutral-50",
2440
+ running: "border-sky-200 bg-sky-50",
2441
+ success: "border-status-success-subtle bg-status-success-subtle/30",
2442
+ error: "border-status-error-subtle bg-status-error-subtle/30"
2443
+ }
2444
+ },
2445
+ defaultVariants: { status: "pending" }
2446
+ }
2447
+ );
2448
+ function formatDuration(start, end) {
2449
+ if (!start || !end) return null;
2450
+ const ms = end.getTime() - start.getTime();
2451
+ if (ms < 1e3) return `${ms}ms`;
2452
+ return `${(ms / 1e3).toFixed(1)}s`;
2453
+ }
2454
+ function formatValue(value) {
2455
+ if (typeof value === "string") return value;
2456
+ return JSON.stringify(value, null, 2);
2457
+ }
2458
+ function MCPToolCall({ call, isExpanded = false, onToggleExpand, className }) {
2459
+ const duration = formatDuration(call.startedAt, call.completedAt);
2460
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2461
+ "div",
2462
+ {
2463
+ className: (0, import_tailwind_merge18.twMerge)(container({ status: call.status }), className),
2464
+ "data-testid": "mcp-tool-call",
2465
+ children: [
2466
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2467
+ "button",
2468
+ {
2469
+ type: "button",
2470
+ className: "flex w-full items-center justify-between gap-2 px-3 py-2",
2471
+ onClick: onToggleExpand,
2472
+ "aria-expanded": isExpanded,
2473
+ "data-testid": "mcp-tool-call-header",
2474
+ children: [
2475
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
2476
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "font-medium text-text-primary truncate", "data-testid": "mcp-tool-name", children: call.name }),
2477
+ call.serverName && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-xs text-text-secondary truncate", children: call.serverName })
2478
+ ] }),
2479
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
2480
+ call.status === "running" && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core12.Spinner, { size: "sm" }) }),
2481
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2482
+ import_core12.Badge,
2483
+ {
2484
+ intent: statusBadgeIntent[call.status],
2485
+ size: "sm",
2486
+ role: "status",
2487
+ "aria-label": `Status: ${statusLabel[call.status]}`,
2488
+ "data-testid": "mcp-tool-status",
2489
+ children: statusLabel[call.status]
2490
+ }
2491
+ ),
2492
+ duration && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-xs text-text-secondary", "data-testid": "mcp-tool-duration", children: duration }),
2493
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2494
+ "svg",
2495
+ {
2496
+ className: `h-4 w-4 text-text-secondary transition-transform ${isExpanded ? "rotate-180" : ""}`,
2497
+ viewBox: "0 0 20 20",
2498
+ fill: "currentColor",
2499
+ "aria-hidden": "true",
2500
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2501
+ "path",
2502
+ {
2503
+ fillRule: "evenodd",
2504
+ d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
2505
+ clipRule: "evenodd"
2506
+ }
2507
+ )
2508
+ }
2509
+ )
2510
+ ] })
2511
+ ]
2512
+ }
2513
+ ),
2514
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "border-t border-inherit px-3 py-2 space-y-3", "data-testid": "mcp-tool-call-body", children: [
2515
+ Object.keys(call.arguments).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
2516
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("h4", { className: "text-xs font-medium text-text-secondary mb-1", children: "Arguments" }),
2517
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("dl", { className: "space-y-1", "data-testid": "mcp-tool-arguments", children: Object.entries(call.arguments).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex gap-2", children: [
2518
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("dt", { className: "text-xs font-mono text-text-secondary shrink-0", children: [
2519
+ key,
2520
+ ":"
2521
+ ] }),
2522
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("dd", { className: "text-xs font-mono text-text-primary break-all", children: formatValue(value) })
2523
+ ] }, key)) })
2524
+ ] }),
2525
+ call.result !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
2526
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("h4", { className: "text-xs font-medium text-text-secondary mb-1", children: "Result" }),
2527
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2528
+ "pre",
2529
+ {
2530
+ className: "text-xs font-mono text-text-primary bg-neutral-100 rounded p-2 overflow-x-auto whitespace-pre-wrap",
2531
+ "data-testid": "mcp-tool-result",
2532
+ children: typeof call.result === "string" ? call.result : JSON.stringify(call.result, null, 2)
2533
+ }
2534
+ )
2535
+ ] }),
2536
+ call.error && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("h4", { className: "text-xs font-medium text-status-error mb-1", children: "Error" }),
2538
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2539
+ "p",
2540
+ {
2541
+ className: "text-xs text-status-error bg-status-error-subtle/30 rounded p-2",
2542
+ "data-testid": "mcp-tool-error",
2543
+ children: call.error
2544
+ }
2545
+ )
2546
+ ] })
2547
+ ] })
2548
+ ]
2549
+ }
2550
+ );
2551
+ }
2552
+
2553
+ // src/mcp/MCPResourceView/MCPResourceView.tsx
2554
+ var import_tailwind_merge19 = require("tailwind-merge");
2555
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2556
+ function isImageMime(mime) {
2557
+ return !!mime && mime.startsWith("image/");
2558
+ }
2559
+ function isTextMime(mime) {
2560
+ if (!mime) return true;
2561
+ return mime.startsWith("text/") || mime === "application/json" || mime === "application/xml" || mime === "application/javascript" || mime === "application/typescript";
2562
+ }
2563
+ function isUrlContent(content) {
2564
+ if (typeof content !== "string") return false;
2565
+ return /^https?:\/\//.test(content.trim());
2566
+ }
2567
+ function MCPResourceView({ resource, className }) {
2568
+ const { uri, name, mimeType, description, content } = resource;
2569
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2570
+ "div",
2571
+ {
2572
+ className: (0, import_tailwind_merge19.twMerge)("rounded-lg border border-border bg-surface p-3 text-sm", className),
2573
+ "data-testid": "mcp-resource-view",
2574
+ children: [
2575
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "mb-2", children: [
2576
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "font-medium text-text-primary", "data-testid": "mcp-resource-name", children: name }),
2577
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2578
+ "span",
2579
+ {
2580
+ className: "ml-2 text-xs text-text-secondary font-mono truncate",
2581
+ "data-testid": "mcp-resource-uri",
2582
+ children: uri
2583
+ }
2584
+ )
2585
+ ] }),
2586
+ description && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "text-xs text-text-secondary mb-2", "data-testid": "mcp-resource-description", children: description }),
2587
+ content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { "data-testid": "mcp-resource-content", children: isImageMime(mimeType) && typeof content === "string" ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2588
+ "img",
2589
+ {
2590
+ src: content,
2591
+ alt: name,
2592
+ className: "max-w-full rounded",
2593
+ "data-testid": "mcp-resource-image"
2594
+ }
2595
+ ) : isUrlContent(content) ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2596
+ "a",
2597
+ {
2598
+ href: typeof content === "string" ? content.trim() : void 0,
2599
+ target: "_blank",
2600
+ rel: "noopener noreferrer",
2601
+ className: "text-sm text-interactive-primary hover:underline break-all",
2602
+ "data-testid": "mcp-resource-link",
2603
+ children: typeof content === "string" ? content.trim() : ""
2604
+ }
2605
+ ) : isTextMime(mimeType) ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2606
+ "pre",
2607
+ {
2608
+ className: "text-xs font-mono text-text-primary bg-neutral-100 rounded p-2 overflow-x-auto whitespace-pre-wrap",
2609
+ "data-testid": "mcp-resource-code",
2610
+ children: typeof content === "string" ? content : "[Binary data]"
2611
+ }
2612
+ ) : /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("p", { className: "text-xs text-text-secondary italic", children: [
2613
+ "Unsupported content type: ",
2614
+ mimeType
2615
+ ] }) })
2616
+ ]
2617
+ }
2618
+ );
2619
+ }
2620
+
2621
+ // src/mcp/MCPServerStatus/MCPServerStatus.tsx
2167
2622
  var import_react14 = require("react");
2168
- var import_jsx_runtime36 = require("react/jsx-runtime");
2623
+ var import_class_variance_authority2 = require("class-variance-authority");
2624
+ var import_tailwind_merge20 = require("tailwind-merge");
2625
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2626
+ var statusDot = (0, import_class_variance_authority2.cva)("inline-block h-2 w-2 rounded-full shrink-0", {
2627
+ variants: {
2628
+ status: {
2629
+ connected: "bg-status-success",
2630
+ disconnected: "bg-neutral-400",
2631
+ error: "bg-status-error"
2632
+ }
2633
+ },
2634
+ defaultVariants: { status: "disconnected" }
2635
+ });
2636
+ var statusLabel2 = {
2637
+ connected: "Connected",
2638
+ disconnected: "Disconnected",
2639
+ error: "Error"
2640
+ };
2641
+ function formatLastPing(date) {
2642
+ if (!date) return null;
2643
+ return date.toLocaleTimeString();
2644
+ }
2645
+ function MCPServerStatus({ server, className }) {
2646
+ const [showTools, setShowTools] = (0, import_react14.useState)(false);
2647
+ const [showResources, setShowResources] = (0, import_react14.useState)(false);
2648
+ const lastPing = formatLastPing(server.lastPing);
2649
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2650
+ "div",
2651
+ {
2652
+ className: (0, import_tailwind_merge20.twMerge)("rounded-lg border border-border bg-surface p-3 text-sm", className),
2653
+ "data-testid": "mcp-server-status",
2654
+ children: [
2655
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-2 mb-1", children: [
2656
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2657
+ "span",
2658
+ {
2659
+ className: statusDot({ status: server.status }),
2660
+ role: "status",
2661
+ "aria-label": statusLabel2[server.status],
2662
+ "data-testid": "mcp-server-status-dot"
2663
+ }
2664
+ ),
2665
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-medium text-text-primary", "data-testid": "mcp-server-name", children: server.name }),
2666
+ server.version && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-xs text-text-secondary", "data-testid": "mcp-server-version", children: [
2667
+ "v",
2668
+ server.version
2669
+ ] })
2670
+ ] }),
2671
+ lastPing && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("p", { className: "text-xs text-text-secondary ml-4 mb-2", "data-testid": "mcp-server-last-ping", children: [
2672
+ "Last ping: ",
2673
+ lastPing
2674
+ ] }),
2675
+ server.tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "mt-2", children: [
2676
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2677
+ "button",
2678
+ {
2679
+ type: "button",
2680
+ className: "flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary w-full",
2681
+ onClick: () => setShowTools((prev) => !prev),
2682
+ "aria-expanded": showTools,
2683
+ "data-testid": "mcp-server-tools-toggle",
2684
+ children: [
2685
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2686
+ "svg",
2687
+ {
2688
+ className: `h-3 w-3 transition-transform ${showTools ? "rotate-90" : ""}`,
2689
+ viewBox: "0 0 20 20",
2690
+ fill: "currentColor",
2691
+ "aria-hidden": "true",
2692
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2693
+ "path",
2694
+ {
2695
+ fillRule: "evenodd",
2696
+ d: "M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z",
2697
+ clipRule: "evenodd"
2698
+ }
2699
+ )
2700
+ }
2701
+ ),
2702
+ "Tools (",
2703
+ server.tools.length,
2704
+ ")"
2705
+ ]
2706
+ }
2707
+ ),
2708
+ showTools && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className: "mt-1 ml-4 space-y-1", "data-testid": "mcp-server-tools-list", children: server.tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("li", { className: "text-xs text-text-primary", children: [
2709
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-mono", children: tool.name }),
2710
+ tool.description && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-text-secondary ml-1", children: [
2711
+ "\u2014 ",
2712
+ tool.description
2713
+ ] })
2714
+ ] }, tool.name)) })
2715
+ ] }),
2716
+ server.resources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "mt-2", children: [
2717
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2718
+ "button",
2719
+ {
2720
+ type: "button",
2721
+ className: "flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary w-full",
2722
+ onClick: () => setShowResources((prev) => !prev),
2723
+ "aria-expanded": showResources,
2724
+ "data-testid": "mcp-server-resources-toggle",
2725
+ children: [
2726
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2727
+ "svg",
2728
+ {
2729
+ className: `h-3 w-3 transition-transform ${showResources ? "rotate-90" : ""}`,
2730
+ viewBox: "0 0 20 20",
2731
+ fill: "currentColor",
2732
+ "aria-hidden": "true",
2733
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2734
+ "path",
2735
+ {
2736
+ fillRule: "evenodd",
2737
+ d: "M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z",
2738
+ clipRule: "evenodd"
2739
+ }
2740
+ )
2741
+ }
2742
+ ),
2743
+ "Resources (",
2744
+ server.resources.length,
2745
+ ")"
2746
+ ]
2747
+ }
2748
+ ),
2749
+ showResources && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className: "mt-1 ml-4 space-y-1", "data-testid": "mcp-server-resources-list", children: server.resources.map((res) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("li", { className: "text-xs text-text-primary", children: [
2750
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "font-mono", children: res.name }),
2751
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "text-text-secondary ml-1", children: [
2752
+ "(",
2753
+ res.uri,
2754
+ ")"
2755
+ ] })
2756
+ ] }, res.uri)) })
2757
+ ] })
2758
+ ]
2759
+ }
2760
+ );
2761
+ }
2762
+
2763
+ // src/mcp/MCPApprovalDialog/MCPApprovalDialog.tsx
2764
+ var import_react15 = require("react");
2765
+ var import_class_variance_authority3 = require("class-variance-authority");
2766
+ var import_tailwind_merge21 = require("tailwind-merge");
2767
+ var import_react_aria = require("react-aria");
2768
+ var import_core13 = require("@surf-kit/core");
2769
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2770
+ var riskBadgeIntent = {
2771
+ low: "success",
2772
+ medium: "warning",
2773
+ high: "error"
2774
+ };
2775
+ var riskLabel = {
2776
+ low: "Low Risk",
2777
+ medium: "Medium Risk",
2778
+ high: "High Risk"
2779
+ };
2780
+ var riskBorder = (0, import_class_variance_authority3.cva)("relative bg-surface rounded-xl shadow-xl border p-6 outline-none w-full max-w-lg", {
2781
+ variants: {
2782
+ risk: {
2783
+ low: "border-status-success-subtle",
2784
+ medium: "border-status-warning-subtle",
2785
+ high: "border-status-error-subtle"
2786
+ }
2787
+ },
2788
+ defaultVariants: { risk: "low" }
2789
+ });
2790
+ function formatValue2(value) {
2791
+ if (typeof value === "string") return value;
2792
+ return JSON.stringify(value, null, 2);
2793
+ }
2794
+ function MCPApprovalDialog({
2795
+ call,
2796
+ riskLevel = "low",
2797
+ onApprove,
2798
+ onDeny,
2799
+ isOpen,
2800
+ className
2801
+ }) {
2802
+ const ref = (0, import_react15.useRef)(null);
2803
+ const { dialogProps, titleProps } = (0, import_react_aria.useDialog)({ role: "alertdialog" }, ref);
2804
+ (0, import_react15.useEffect)(() => {
2805
+ if (!isOpen) return;
2806
+ const handleKeyDown = (e) => {
2807
+ if (e.key === "Escape") {
2808
+ e.preventDefault();
2809
+ e.stopPropagation();
2810
+ }
2811
+ };
2812
+ document.addEventListener("keydown", handleKeyDown, true);
2813
+ return () => document.removeEventListener("keydown", handleKeyDown, true);
2814
+ }, [isOpen]);
2815
+ if (!isOpen) return null;
2816
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2817
+ "div",
2818
+ {
2819
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50",
2820
+ "data-testid": "mcp-approval-overlay",
2821
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_aria.FocusScope, { contain: true, restoreFocus: true, autoFocus: true, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2822
+ "div",
2823
+ {
2824
+ ...dialogProps,
2825
+ ref,
2826
+ className: (0, import_tailwind_merge21.twMerge)(riskBorder({ risk: riskLevel }), className),
2827
+ "data-testid": "mcp-approval-dialog",
2828
+ children: [
2829
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
2830
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2831
+ "h2",
2832
+ {
2833
+ ...titleProps,
2834
+ className: "text-lg font-semibold text-text-primary",
2835
+ "data-testid": "mcp-approval-title",
2836
+ children: "Tool Approval Required"
2837
+ }
2838
+ ),
2839
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2840
+ import_core13.Badge,
2841
+ {
2842
+ intent: riskBadgeIntent[riskLevel],
2843
+ size: "sm",
2844
+ "data-testid": "mcp-approval-risk-badge",
2845
+ children: riskLabel[riskLevel]
2846
+ }
2847
+ )
2848
+ ] }),
2849
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "space-y-3 text-sm", children: [
2850
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { children: [
2851
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h3", { className: "text-xs font-medium text-text-secondary mb-1", children: "Tool" }),
2852
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "font-mono text-text-primary", "data-testid": "mcp-approval-tool-name", children: call.name }),
2853
+ call.serverName && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "text-xs text-text-secondary mt-0.5", "data-testid": "mcp-approval-server", children: [
2854
+ "Server: ",
2855
+ call.serverName
2856
+ ] })
2857
+ ] }),
2858
+ Object.keys(call.arguments).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { children: [
2859
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h3", { className: "text-xs font-medium text-text-secondary mb-1", children: "Arguments" }),
2860
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2861
+ "dl",
2862
+ {
2863
+ className: "space-y-1 bg-neutral-100 rounded p-2",
2864
+ "data-testid": "mcp-approval-arguments",
2865
+ children: Object.entries(call.arguments).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex gap-2", children: [
2866
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("dt", { className: "text-xs font-mono text-text-secondary shrink-0", children: [
2867
+ key,
2868
+ ":"
2869
+ ] }),
2870
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("dd", { className: "text-xs font-mono text-text-primary break-all", children: formatValue2(value) })
2871
+ ] }, key))
2872
+ }
2873
+ )
2874
+ ] })
2875
+ ] }),
2876
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "mt-6 flex justify-end gap-3", children: [
2877
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2878
+ import_core13.Button,
2879
+ {
2880
+ intent: "secondary",
2881
+ onPress: onDeny,
2882
+ "aria-label": "Deny tool execution",
2883
+ children: "Deny"
2884
+ }
2885
+ ),
2886
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2887
+ import_core13.Button,
2888
+ {
2889
+ intent: "primary",
2890
+ onPress: onApprove,
2891
+ "aria-label": "Approve tool execution",
2892
+ children: "Approve"
2893
+ }
2894
+ )
2895
+ ] })
2896
+ ]
2897
+ }
2898
+ ) })
2899
+ }
2900
+ );
2901
+ }
2902
+
2903
+ // src/feedback/ThumbsFeedback/ThumbsFeedback.tsx
2904
+ var import_react16 = require("react");
2905
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2169
2906
  function ThumbsFeedback({
2170
2907
  messageId,
2171
2908
  onFeedback,
@@ -2173,7 +2910,7 @@ function ThumbsFeedback({
2173
2910
  onNegative,
2174
2911
  className
2175
2912
  }) {
2176
- const [selected, setSelected] = (0, import_react14.useState)(state);
2913
+ const [selected, setSelected] = (0, import_react16.useState)(state);
2177
2914
  const handleClick = (rating) => {
2178
2915
  setSelected(rating);
2179
2916
  onFeedback(messageId, rating);
@@ -2181,7 +2918,7 @@ function ThumbsFeedback({
2181
2918
  onNegative();
2182
2919
  }
2183
2920
  };
2184
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2921
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2185
2922
  "div",
2186
2923
  {
2187
2924
  className: `inline-flex items-center gap-0.5 ${className ?? ""}`,
@@ -2189,7 +2926,7 @@ function ThumbsFeedback({
2189
2926
  "aria-label": "Rate this response",
2190
2927
  "data-testid": "thumbs-feedback",
2191
2928
  children: [
2192
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2929
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2193
2930
  "button",
2194
2931
  {
2195
2932
  type: "button",
@@ -2198,7 +2935,7 @@ function ThumbsFeedback({
2198
2935
  "aria-pressed": selected === "positive",
2199
2936
  className: `p-1.5 rounded-md transition-colors duration-200 ${selected === "positive" ? "text-brand-cyan bg-brand-cyan/15" : "text-brand-cream/30 hover:text-brand-cyan hover:bg-brand-cyan/10"}`,
2200
2937
  "data-testid": "thumbs-up",
2201
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2938
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2202
2939
  "svg",
2203
2940
  {
2204
2941
  width: "16",
@@ -2211,14 +2948,14 @@ function ThumbsFeedback({
2211
2948
  strokeLinejoin: "round",
2212
2949
  "aria-hidden": "true",
2213
2950
  children: [
2214
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { d: "M7 10v12" }),
2215
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z" })
2951
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M7 10v12" }),
2952
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z" })
2216
2953
  ]
2217
2954
  }
2218
2955
  )
2219
2956
  }
2220
2957
  ),
2221
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2958
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2222
2959
  "button",
2223
2960
  {
2224
2961
  type: "button",
@@ -2227,7 +2964,7 @@ function ThumbsFeedback({
2227
2964
  "aria-pressed": selected === "negative",
2228
2965
  className: `p-1.5 rounded-md transition-colors duration-200 ${selected === "negative" ? "text-brand-watermelon bg-brand-watermelon/15" : "text-brand-cream/30 hover:text-brand-watermelon hover:bg-brand-watermelon/10"}`,
2229
2966
  "data-testid": "thumbs-down",
2230
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2967
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2231
2968
  "svg",
2232
2969
  {
2233
2970
  width: "16",
@@ -2240,8 +2977,8 @@ function ThumbsFeedback({
2240
2977
  strokeLinejoin: "round",
2241
2978
  "aria-hidden": "true",
2242
2979
  children: [
2243
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { d: "M17 14V2" }),
2244
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22h0a3.13 3.13 0 0 1-3-3.88Z" })
2980
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M17 14V2" }),
2981
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22h0a3.13 3.13 0 0 1-3-3.88Z" })
2245
2982
  ]
2246
2983
  }
2247
2984
  )
@@ -2253,30 +2990,30 @@ function ThumbsFeedback({
2253
2990
  }
2254
2991
 
2255
2992
  // src/feedback/FeedbackDialog/FeedbackDialog.tsx
2256
- var import_react15 = require("react");
2257
- var import_core12 = require("@surf-kit/core");
2258
- var import_jsx_runtime37 = require("react/jsx-runtime");
2993
+ var import_react17 = require("react");
2994
+ var import_core14 = require("@surf-kit/core");
2995
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2259
2996
  function FeedbackDialog({ isOpen, onClose, onSubmit, className }) {
2260
- const [comment, setComment] = (0, import_react15.useState)("");
2997
+ const [comment, setComment] = (0, import_react17.useState)("");
2261
2998
  const handleSubmit = () => {
2262
2999
  onSubmit(comment);
2263
3000
  setComment("");
2264
3001
  onClose();
2265
3002
  };
2266
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2267
- import_core12.Dialog,
3003
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3004
+ import_core14.Dialog,
2268
3005
  {
2269
3006
  isOpen,
2270
3007
  onClose,
2271
3008
  title: "Share your feedback",
2272
3009
  size: "sm",
2273
3010
  className,
2274
- footer: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
2275
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core12.Button, { intent: "ghost", onPress: onClose, children: "Cancel" }),
2276
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core12.Button, { intent: "primary", onPress: handleSubmit, isDisabled: comment.trim().length === 0, children: "Submit" })
3011
+ footer: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
3012
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core14.Button, { intent: "ghost", onPress: onClose, children: "Cancel" }),
3013
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_core14.Button, { intent: "primary", onPress: handleSubmit, isDisabled: comment.trim().length === 0, children: "Submit" })
2277
3014
  ] }),
2278
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2279
- import_core12.TextArea,
3015
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3016
+ import_core14.TextArea,
2280
3017
  {
2281
3018
  label: "What could be improved?",
2282
3019
  value: comment,
@@ -2291,10 +3028,10 @@ function FeedbackDialog({ isOpen, onClose, onSubmit, className }) {
2291
3028
  }
2292
3029
 
2293
3030
  // src/feedback/FeedbackConfirmation/FeedbackConfirmation.tsx
2294
- var import_jsx_runtime38 = require("react/jsx-runtime");
3031
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2295
3032
  function FeedbackConfirmation({ variant = "inline", className }) {
2296
3033
  if (variant === "toast") {
2297
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3034
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
2298
3035
  "div",
2299
3036
  {
2300
3037
  role: "status",
@@ -2304,7 +3041,7 @@ function FeedbackConfirmation({ variant = "inline", className }) {
2304
3041
  }
2305
3042
  );
2306
3043
  }
2307
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3044
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
2308
3045
  "span",
2309
3046
  {
2310
3047
  role: "status",
@@ -2333,6 +3070,10 @@ function FeedbackConfirmation({ variant = "inline", className }) {
2333
3070
  FeedbackConfirmation,
2334
3071
  FeedbackDialog,
2335
3072
  FollowUpChips,
3073
+ MCPApprovalDialog,
3074
+ MCPResourceView,
3075
+ MCPServerStatus,
3076
+ MCPToolCall,
2336
3077
  MessageBubble,
2337
3078
  MessageComposer,
2338
3079
  MessageThread,
@@ -2344,12 +3085,16 @@ function FeedbackConfirmation({ variant = "inline", className }) {
2344
3085
  SourceDrawer,
2345
3086
  SourceInline,
2346
3087
  SourceList,
3088
+ StreamingList,
2347
3089
  StreamingMessage,
3090
+ StreamingStructure,
2348
3091
  StructuredResponse,
3092
+ TextGlimmer,
2349
3093
  ThinkingIndicator,
2350
3094
  ThumbsFeedback,
2351
3095
  ToolExecution,
2352
3096
  TypewriterText,
3097
+ TypingIndicator,
2353
3098
  VerificationBadge,
2354
3099
  VerificationDetail,
2355
3100
  VerificationProgress,