@redocly/theme 0.70.0-next.5 → 0.70.0-next.6

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 (87) hide show
  1. package/lib/components/Buttons/ConnectMCPButton.js +8 -13
  2. package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.js +1 -1
  3. package/lib/components/Catalog/CatalogFilter/CatalogFilterDateRange.js +2 -1
  4. package/lib/components/Dropdown/Dropdown.d.ts +4 -2
  5. package/lib/components/Dropdown/Dropdown.js +28 -8
  6. package/lib/components/Filter/FilterDateRange.js +36 -2
  7. package/lib/components/Search/SearchAiActivity.d.ts +10 -0
  8. package/lib/components/Search/SearchAiActivity.js +278 -0
  9. package/lib/components/Search/SearchAiDialog.js +5 -1
  10. package/lib/components/Search/SearchAiMessage.d.ts +2 -1
  11. package/lib/components/Search/SearchAiMessage.js +20 -108
  12. package/lib/components/Search/SearchItem.js +1 -8
  13. package/lib/components/Search/variables.js +15 -2
  14. package/lib/components/Select/SelectInput.js +2 -8
  15. package/lib/components/SplitButton/SplitButton.js +37 -3
  16. package/lib/core/constants/mcp.d.ts +2 -2
  17. package/lib/core/constants/mcp.js +3 -8
  18. package/lib/core/constants/search.js +5 -1
  19. package/lib/core/hooks/index.d.ts +1 -0
  20. package/lib/core/hooks/index.js +1 -0
  21. package/lib/core/hooks/menu/use-collapse.js +1 -1
  22. package/lib/core/hooks/search/use-search-ai-activity.d.ts +11 -0
  23. package/lib/core/hooks/search/use-search-ai-activity.js +15 -0
  24. package/lib/core/hooks/use-connect-mcp-button.js +2 -1
  25. package/lib/core/hooks/use-full-height.d.ts +1 -1
  26. package/lib/core/hooks/use-full-height.js +8 -8
  27. package/lib/core/styles/global.d.ts +2 -0
  28. package/lib/core/styles/global.js +80 -76
  29. package/lib/core/styles/index.d.ts +1 -0
  30. package/lib/core/styles/index.js +3 -1
  31. package/lib/core/styles/search-ai-appear.d.ts +1 -0
  32. package/lib/core/styles/search-ai-appear.js +18 -0
  33. package/lib/core/types/dropdown.d.ts +1 -0
  34. package/lib/core/types/dropdown.js +3 -0
  35. package/lib/core/types/index.d.ts +1 -0
  36. package/lib/core/types/l10n.d.ts +1 -1
  37. package/lib/core/types/mcp.d.ts +2 -1
  38. package/lib/core/types/search.d.ts +23 -0
  39. package/lib/core/utils/assign-ref.d.ts +2 -0
  40. package/lib/core/utils/assign-ref.js +12 -0
  41. package/lib/core/utils/content-segments.d.ts +12 -1
  42. package/lib/core/utils/content-segments.js +90 -5
  43. package/lib/core/utils/dropdown.d.ts +2 -0
  44. package/lib/core/utils/dropdown.js +12 -0
  45. package/lib/core/utils/index.d.ts +2 -0
  46. package/lib/core/utils/index.js +2 -0
  47. package/lib/core/utils/mcp.d.ts +2 -1
  48. package/lib/core/utils/mcp.js +5 -0
  49. package/lib/core/utils/search-ai-activity.d.ts +4 -0
  50. package/lib/core/utils/search-ai-activity.js +83 -0
  51. package/lib/markdoc/tags/connect-mcp.js +15 -0
  52. package/package.json +2 -2
  53. package/src/components/Buttons/ConnectMCPButton.tsx +8 -14
  54. package/src/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.tsx +3 -1
  55. package/src/components/Catalog/CatalogFilter/CatalogFilterDateRange.tsx +3 -2
  56. package/src/components/Dropdown/Dropdown.tsx +28 -6
  57. package/src/components/Filter/FilterDateRange.tsx +3 -2
  58. package/src/components/Search/SearchAiActivity.tsx +318 -0
  59. package/src/components/Search/SearchAiDialog.tsx +4 -3
  60. package/src/components/Search/SearchAiMessage.tsx +27 -135
  61. package/src/components/Search/SearchItem.tsx +2 -9
  62. package/src/components/Search/variables.ts +15 -2
  63. package/src/components/Select/SelectInput.tsx +2 -8
  64. package/src/components/SplitButton/SplitButton.tsx +8 -2
  65. package/src/core/constants/mcp.ts +3 -9
  66. package/src/core/constants/search.ts +5 -1
  67. package/src/core/hooks/__mocks__/index.ts +1 -0
  68. package/src/core/hooks/index.ts +1 -0
  69. package/src/core/hooks/menu/use-collapse.ts +1 -1
  70. package/src/core/hooks/search/use-search-ai-activity.ts +31 -0
  71. package/src/core/hooks/use-connect-mcp-button.ts +7 -2
  72. package/src/core/hooks/use-full-height.ts +8 -8
  73. package/src/core/styles/global.ts +80 -75
  74. package/src/core/styles/index.ts +2 -1
  75. package/src/core/styles/search-ai-appear.ts +16 -0
  76. package/src/core/types/dropdown.ts +1 -0
  77. package/src/core/types/index.ts +1 -0
  78. package/src/core/types/l10n.ts +1 -1
  79. package/src/core/types/mcp.ts +3 -1
  80. package/src/core/types/search.ts +21 -0
  81. package/src/core/utils/assign-ref.ts +9 -0
  82. package/src/core/utils/content-segments.ts +98 -6
  83. package/src/core/utils/dropdown.ts +14 -0
  84. package/src/core/utils/index.ts +2 -0
  85. package/src/core/utils/mcp.ts +7 -1
  86. package/src/core/utils/search-ai-activity.ts +110 -0
  87. package/src/markdoc/tags/connect-mcp.ts +16 -1
@@ -41,6 +41,7 @@ const react_1 = __importStar(require("react"));
41
41
  const styled_components_1 = __importDefault(require("styled-components"));
42
42
  const types_1 = require("../../core/types");
43
43
  const constants_1 = require("../../core/constants");
44
+ const utils_1 = require("../../core/utils");
44
45
  const Link_1 = require("../../components/Link/Link");
45
46
  const Tag_1 = require("../../components/Tag/Tag");
46
47
  const hooks_1 = require("../../core/hooks");
@@ -50,36 +51,14 @@ const AiStarsIcon_1 = require("../../icons/AiStarsIcon/AiStarsIcon");
50
51
  const CheckmarkOutlineIcon_1 = require("../../icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon");
51
52
  const SearchAiActionButtons_1 = require("../../components/Search/SearchAiActionButtons");
52
53
  const SearchAiNegativeFeedbackForm_1 = require("../../components/Search/SearchAiNegativeFeedbackForm");
54
+ const SearchAiActivity_1 = require("../../components/Search/SearchAiActivity");
55
+ const styles_1 = require("../../core/styles");
53
56
  function MarkdownSegment({ text }) {
54
57
  const { useMarkdownText } = (0, hooks_1.useThemeHooks)();
55
58
  const markdown = useMarkdownText(text);
56
59
  return react_1.default.createElement(ResponseText, { as: "div", children: markdown, "data-testid": "response-text" });
57
60
  }
58
- // The codemode `execute` tool passes a human-readable `description` of what its code
59
- // does; show that instead of a generic "Executing execute..." label.
60
- function getExecuteDescription(args) {
61
- if (args && typeof args === 'object' && 'description' in args) {
62
- const { description } = args;
63
- if (typeof description === 'string' && description.trim().length > 0) {
64
- return description.trim();
65
- }
66
- }
67
- return undefined;
68
- }
69
- function getToolCallDisplayText(toolCall) {
70
- var _a;
71
- if (toolCall.name === types_1.ToolCallName.Execute) {
72
- const description = getExecuteDescription(toolCall.args);
73
- if (description) {
74
- return { inProgressText: description, completedText: description };
75
- }
76
- }
77
- return ((_a = constants_1.TOOL_CALL_DISPLAY_TEXT[toolCall.name]) !== null && _a !== void 0 ? _a : {
78
- inProgressText: `Executing ${toolCall.name}...`,
79
- completedText: `${toolCall.name} executed`,
80
- });
81
- }
82
- function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, toolCalls = [], contentSegments = [{ type: 'text', text: content }], }) {
61
+ function SearchAiMessageComponent({ role, content, isThinking, resources, className, messageId, feedback, onFeedbackChange, contentSegments = [{ type: 'text', text: content }], }) {
83
62
  var _a;
84
63
  const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
85
64
  const { translate } = useTranslate();
@@ -88,7 +67,8 @@ function SearchAiMessageComponent({ role, content, isThinking, resources, classN
88
67
  const hasResources = !isThinking && resources && resources.length > 0;
89
68
  const resourcesCount = (_a = resources === null || resources === void 0 ? void 0 : resources.length) !== null && _a !== void 0 ? _a : 0;
90
69
  const showSuccessMessage = feedbackSent && feedback;
91
- const isLoading = isThinking && content.length === 0 && toolCalls.length === 0;
70
+ const groupedSegments = (0, utils_1.groupToolCallSegments)(contentSegments, isThinking);
71
+ const isFullWidth = (0, utils_1.hasToolCallsAndText)(contentSegments);
92
72
  const sendFeedbackTelemetry = (feedbackValue, dislikeReason) => {
93
73
  if (!messageId)
94
74
  return;
@@ -122,17 +102,11 @@ function SearchAiMessageComponent({ role, content, isThinking, resources, classN
122
102
  };
123
103
  return (react_1.default.createElement(SearchAiMessageWrapper, { "data-component-name": "Search/SearchAiMessage", $role: role, className: className, "data-testid": "search-ai-message" },
124
104
  role === constants_1.AiSearchConversationRole.ASSISTANT && (react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { size: "32px", background: "var(--search-ai-icon-bg-color)", borderRadius: "var(--border-radius-lg)", color: "var(--search-ai-icon-color)", margin: "0 var(--spacing-xs) 0 0" })),
125
- react_1.default.createElement(MessageContentWrapper, null, role === constants_1.AiSearchConversationRole.ASSISTANT ? (react_1.default.createElement(react_1.default.Fragment, null,
126
- react_1.default.createElement(MessageWrapper, { $role: role },
127
- contentSegments.map((segment, index) => {
128
- if (segment.type === 'tool') {
129
- const toolCallCompleted = Boolean(segment.toolCall.result);
130
- const { inProgressText, completedText } = getToolCallDisplayText(segment.toolCall);
131
- const toolCallDisplayText = toolCallCompleted ? completedText : inProgressText;
132
- return (react_1.default.createElement(ToolCallsInfoWrapper, { key: `tool-${index}`, "data-testid": "tool-calls-info" },
133
- react_1.default.createElement(ToolCallInfoItem, null,
134
- react_1.default.createElement(DocumentIcon_1.DocumentIcon, { size: "14px", color: "--search-ai-text-color" }),
135
- react_1.default.createElement(ToolCallText, { $isSearching: !toolCallCompleted }, toolCallDisplayText))));
105
+ react_1.default.createElement(MessageContentWrapper, { $isFullWidth: isFullWidth }, role === constants_1.AiSearchConversationRole.ASSISTANT ? (react_1.default.createElement(react_1.default.Fragment, null,
106
+ react_1.default.createElement(MessageWrapper, { $role: role, $isFullWidth: isFullWidth },
107
+ groupedSegments.map((segment, index) => {
108
+ if (segment.type === 'tools') {
109
+ return (react_1.default.createElement(ToolCallsActivity, { key: `tools-${index}`, toolCalls: segment.toolCalls, isActive: segment.isActive }));
136
110
  }
137
111
  return react_1.default.createElement(MarkdownSegment, { key: `text-${index}`, text: segment.text });
138
112
  }),
@@ -146,11 +120,7 @@ function SearchAiMessageComponent({ role, content, isThinking, resources, classN
146
120
  translate('search.ai.resourcesFound.resources', 'resources')),
147
121
  react_1.default.createElement(ResourceTagsWrapper, null, resources === null || resources === void 0 ? void 0 : resources.map((resource, index) => (react_1.default.createElement(Link_1.Link, { key: `${resource.url}-${index}`, to: resource.url, target: "_blank" },
148
122
  react_1.default.createElement(ResourceTag, { borderless: true, icon: react_1.default.createElement(DocumentIcon_1.DocumentIcon, { color: "--search-ai-resource-tag-icon-color" }) }, resource.title)))))))),
149
- isLoading && (react_1.default.createElement(ThinkingDotsWrapper, { "data-testid": "thinking-dots-wrapper" },
150
- react_1.default.createElement(ThinkingDot, null),
151
- react_1.default.createElement(ThinkingDot, null),
152
- react_1.default.createElement(ThinkingDot, null))),
153
- content.length > 0 && (react_1.default.createElement(FeedbackWrapper, null,
123
+ !isThinking && content.length > 0 && (react_1.default.createElement(FeedbackWrapper, null,
154
124
  react_1.default.createElement(SearchAiActionButtons_1.SearchAiActionButtons, { content: content, feedback: feedback, onFeedback: handleFeedbackClick, disabled: !!feedback })))),
155
125
  messageId && feedback === types_1.FeedbackType.Dislike && !showSuccessMessage && (react_1.default.createElement(SearchAiNegativeFeedbackForm_1.SearchAiNegativeFeedbackForm, { messageId: messageId, onClose: (messageId, feedback) => {
156
126
  onFeedbackChange(messageId, feedback);
@@ -171,7 +141,6 @@ function areResourcesEqual(prev, next) {
171
141
  });
172
142
  }
173
143
  exports.SearchAiMessage = (0, react_1.memo)(SearchAiMessageComponent, (prevProps, nextProps) => {
174
- var _a, _b;
175
144
  return (prevProps.role === nextProps.role &&
176
145
  prevProps.content === nextProps.content &&
177
146
  prevProps.isThinking === nextProps.isThinking &&
@@ -179,7 +148,6 @@ exports.SearchAiMessage = (0, react_1.memo)(SearchAiMessageComponent, (prevProps
179
148
  prevProps.feedback === nextProps.feedback &&
180
149
  prevProps.onFeedbackChange === nextProps.onFeedbackChange &&
181
150
  areResourcesEqual(prevProps.resources, nextProps.resources) &&
182
- ((_a = prevProps.toolCalls) === null || _a === void 0 ? void 0 : _a.length) === ((_b = nextProps.toolCalls) === null || _b === void 0 ? void 0 : _b.length) &&
183
151
  prevProps.contentSegments === nextProps.contentSegments);
184
152
  });
185
153
  const SearchAiMessageWrapper = styled_components_1.default.div `
@@ -192,6 +160,7 @@ const SearchAiMessageWrapper = styled_components_1.default.div `
192
160
  const MessageContentWrapper = styled_components_1.default.div `
193
161
  display: flex;
194
162
  flex-direction: column;
163
+ flex-grow: ${({ $isFullWidth }) => ($isFullWidth ? 1 : 0)};
195
164
  gap: var(--spacing-sm);
196
165
  max-width: 80%;
197
166
  min-width: 0;
@@ -217,7 +186,7 @@ const MessageWrapper = styled_components_1.default.div `
217
186
  ? 'var(--spacing-sm)'
218
187
  : 'var(--spacing-sm) var(--spacing-sm) var(--spacing-xs) var(--spacing-sm)'};
219
188
  border-radius: var(--border-radius-xl);
220
- width: fit-content;
189
+ width: ${({ $isFullWidth }) => ($isFullWidth ? 'auto' : 'fit-content')};
221
190
  max-width: 100%;
222
191
  word-wrap: break-word;
223
192
  white-space: pre-wrap;
@@ -234,12 +203,14 @@ const ResourcesWrapper = styled_components_1.default.div `
234
203
  display: flex;
235
204
  flex-direction: column;
236
205
  margin: 0;
206
+ ${styles_1.searchAiAppearAnimation}
237
207
  `;
238
208
  const FeedbackWrapper = styled_components_1.default.div `
239
209
  display: flex;
240
210
  flex-direction: row;
241
211
  gap: var(--search-ai-feedback-gap);
242
212
  margin-top: var(--spacing-sm);
213
+ ${styles_1.searchAiAppearAnimation}
243
214
  `;
244
215
  const ResourcesTitle = styled_components_1.default.div `
245
216
  font-weight: var(--search-ai-resources-title-font-weight);
@@ -270,41 +241,6 @@ const ResourceTag = (0, styled_components_1.default)(Tag_1.Tag).attrs({ textTran
270
241
  max-width: 100%;
271
242
  }
272
243
  `;
273
- const ThinkingDotsWrapper = styled_components_1.default.div `
274
- display: flex;
275
- gap: var(--search-ai-thinking-dots-gap);
276
- padding: var(--search-ai-thinking-dots-padding);
277
- `;
278
- const ThinkingDot = styled_components_1.default.div `
279
- width: var(--search-ai-thinking-dot-size);
280
- height: var(--search-ai-thinking-dot-size);
281
- border-radius: 50%;
282
- background: var(--search-ai-thinking-dot-color);
283
- animation: bounce 1.4s infinite ease-in-out;
284
-
285
- &:nth-child(1) {
286
- animation-delay: -0.32s;
287
- }
288
- &:nth-child(2) {
289
- animation-delay: -0.16s;
290
- }
291
- &:nth-child(3) {
292
- animation-delay: 0s;
293
- }
294
-
295
- @keyframes bounce {
296
- 0%,
297
- 80%,
298
- 100% {
299
- opacity: 0.2;
300
- transform: scale(0.8);
301
- }
302
- 40% {
303
- opacity: 1;
304
- transform: scale(1);
305
- }
306
- }
307
- `;
308
244
  const SuccessMessageWrapper = styled_components_1.default.div `
309
245
  max-width: fit-content;
310
246
  display: flex;
@@ -319,35 +255,11 @@ const SuccessMessageText = styled_components_1.default.div `
319
255
  font-size: var(--font-size-base);
320
256
  color: var(--color-success-darker);
321
257
  `;
322
- const ToolCallsInfoWrapper = styled_components_1.default.div `
323
- display: flex;
324
- flex-direction: column;
325
- gap: var(--spacing-xxs);
258
+ const ToolCallsActivity = (0, styled_components_1.default)(SearchAiActivity_1.SearchAiActivity) `
326
259
  margin: 0 0 var(--spacing-sm) 0;
327
- font-size: var(--font-size-xs);
328
- color: var(--search-ai-text-color);
329
- opacity: 0.6;
330
- `;
331
- const ToolCallInfoItem = styled_components_1.default.div `
332
- display: flex;
333
- align-items: center;
334
- gap: var(--spacing-xxs);
335
- `;
336
- const ToolCallText = styled_components_1.default.span `
337
- font-weight: var(--font-weight-regular);
338
260
 
339
- ${({ $isSearching }) => $isSearching &&
340
- `
341
- animation: pulse 1.5s ease-in-out infinite;
342
-
343
- @keyframes pulse {
344
- 0%, 100% {
345
- opacity: 1;
346
- }
347
- 50% {
348
- opacity: 0.4;
349
- }
350
- }
351
- `}
261
+ &:last-child {
262
+ margin-bottom: var(--spacing-xxs);
263
+ }
352
264
  `;
353
265
  //# sourceMappingURL=SearchAiMessage.js.map
@@ -67,14 +67,7 @@ function SearchItem({ onClick, item, className, product, innerRef, }) {
67
67
  });
68
68
  return (react_1.default.createElement(SearchItemWrapper, { className: className, to: document.url, onClick: onClick, tabIndex: 0, innerRef: (el) => {
69
69
  ref.current = el;
70
- if (!innerRef)
71
- return;
72
- if (typeof innerRef === 'function') {
73
- innerRef(el);
74
- }
75
- else {
76
- innerRef.current = el;
77
- }
70
+ (0, utils_1.assignRef)(innerRef, el);
78
71
  }, "data-component-name": "Search/SearchItem" },
79
72
  react_1.default.createElement(SearchItemContent, null,
80
73
  react_1.default.createElement(SearchItemHeader, null,
@@ -200,8 +200,21 @@ exports.search = (0, styled_components_1.css) `
200
200
  --search-ai-suggestions-title-font-weight: var(--font-weight-light);
201
201
  --search-ai-suggestions-text-color: var(--text-color-description);
202
202
 
203
- --search-ai-thinking-dots-gap: 4px;
204
- --search-ai-thinking-dots-padding: 4px 0;
203
+ --search-ai-activity-font-size: var(--font-size-base);
204
+ --search-ai-activity-line-height: var(--line-height-sm);
205
+ --search-ai-activity-count-font-size: var(--font-size-sm);
206
+ --search-ai-activity-count-bg-color: var(--border-color-secondary);
207
+ --search-ai-activity-text-color: var(--text-color-description);
208
+ --search-ai-activity-text-color-hover: var(--text-color-primary);
209
+ --search-ai-activity-detail-color: var(--text-color-secondary);
210
+ --search-ai-activity-shimmer-color: var(--text-color-primary);
211
+ --search-ai-activity-rail-color: var(--border-color-primary);
212
+ --search-ai-activity-icon-size: 14px;
213
+ --search-ai-activity-fade-duration: 200ms;
214
+ --search-ai-activity-expand-duration: 250ms;
215
+ --search-ai-activity-shimmer-duration: 2s;
216
+ --search-ai-activity-easing: cubic-bezier(0.32, 0.72, 0, 1);
217
+
205
218
  --search-ai-thinking-dot-size: 6px;
206
219
  --search-ai-thinking-dot-color: var(--search-ai-gradient);
207
220
 
@@ -43,6 +43,7 @@ const react_1 = __importStar(require("react"));
43
43
  const Tag_1 = require("../../components/Tag/Tag");
44
44
  const CloseIcon_1 = require("../../icons/CloseIcon/CloseIcon");
45
45
  const Button_1 = require("../../components/Button/Button");
46
+ const utils_1 = require("../../core/utils");
46
47
  function SelectInput(props) {
47
48
  const { id, listboxId, onlyIcon, icon, customIcon, selectedOptions, placeholder, stickyValue, multiple, searchable, expanded, clearable, clearHandler, searchHandler, clickHandler, searchValue, inputBlurHandler, inputFocusHandler, inputRef: forwardedInputRef, } = props;
48
49
  const inputRef = (0, react_1.useRef)(null);
@@ -87,14 +88,7 @@ function SelectInput(props) {
87
88
  if (!input)
88
89
  return;
89
90
  inputRef.current = input;
90
- if (!forwardedInputRef)
91
- return;
92
- if (typeof forwardedInputRef === 'function') {
93
- forwardedInputRef(input);
94
- }
95
- else {
96
- forwardedInputRef.current = input;
97
- }
91
+ (0, utils_1.assignRef)(forwardedInputRef, input);
98
92
  }, $width: multiple ? (!searchValue && selectedOptions.length ? '10px' : 'auto') : '100%', tabIndex: 0, role: "combobox", "aria-expanded": !!expanded, "aria-controls": listboxId, "aria-autocomplete": "list", "aria-label": "Select option", onFocus: (e) => {
99
93
  e.stopPropagation();
100
94
  }, onMouseDown: (e) => {
@@ -1,10 +1,43 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  exports.SplitButton = SplitButton;
7
- const react_1 = __importDefault(require("react"));
40
+ const react_1 = __importStar(require("react"));
8
41
  const styled_components_1 = __importDefault(require("styled-components"));
9
42
  const Button_1 = require("../../components/Button/Button");
10
43
  const ButtonGroup_1 = require("../../components/Button/ButtonGroup");
@@ -12,10 +45,11 @@ const Dropdown_1 = require("../../components/Dropdown/Dropdown");
12
45
  function SplitButton(props) {
13
46
  const { button, children, variant, size, tone, placement = 'bottom', alignment = 'end', portalled, closeOnSelect = true, disabled, toggleAriaLabel, onOpen, onClose, className, } = props;
14
47
  const hasMenu = typeof children === 'function' || react_1.default.Children.toArray(children).length > 0;
15
- return (react_1.default.createElement(SplitButtonWrapper, { "data-component-name": "SplitButton/SplitButton", className: className },
48
+ const wrapperRef = (0, react_1.useRef)(null);
49
+ return (react_1.default.createElement(SplitButtonWrapper, { "data-component-name": "SplitButton/SplitButton", className: className, ref: wrapperRef },
16
50
  react_1.default.createElement(ButtonGroup_1.ButtonGroup, { variant: variant, size: size },
17
51
  button,
18
- hasMenu ? (react_1.default.createElement(ToggleDropdown, { closeOnClick: closeOnSelect, placement: placement, alignment: alignment, portalled: portalled, withArrow: true, onOpen: onOpen, onClose: onClose, trigger: react_1.default.createElement(Button_1.Button, { "aria-label": toggleAriaLabel, "aria-haspopup": "menu", variant: variant, size: size, tone: tone, disabled: disabled }) }, children)) : null)));
52
+ hasMenu ? (react_1.default.createElement(ToggleDropdown, { closeOnClick: closeOnSelect, placement: placement, alignment: alignment, portalled: portalled, alignmentAnchorRef: wrapperRef, withArrow: true, onOpen: onOpen, onClose: onClose, trigger: react_1.default.createElement(Button_1.Button, { "aria-label": toggleAriaLabel, "aria-haspopup": "menu", variant: variant, size: size, tone: tone, disabled: disabled }) }, children)) : null)));
19
53
  }
20
54
  const SplitButtonWrapper = styled_components_1.default.div `
21
55
  position: relative;
@@ -1,5 +1,5 @@
1
- import type { MCPOption } from '../types/mcp';
2
1
  export declare const DEFAULT_MCP_SERVER_NAME = "mcp-server";
3
2
  export declare const MCP_ROUTE = "/mcp";
4
3
  export declare const PUBLIC_MCP_ROUTE = "/mcp-public";
5
- export declare const DEFAULT_MCP_OPTIONS: MCPOption[];
4
+ export declare const MCP_OPTIONS: readonly ['cursor', 'vscode', 'claude-code', 'codex', 'copy'];
5
+ export declare const DEFAULT_MCP_OPTIONS: ("claude-code" | "codex" | "copy" | "cursor" | "vscode")[];
@@ -1,14 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_MCP_OPTIONS = exports.PUBLIC_MCP_ROUTE = exports.MCP_ROUTE = exports.DEFAULT_MCP_SERVER_NAME = void 0;
3
+ exports.DEFAULT_MCP_OPTIONS = exports.MCP_OPTIONS = exports.PUBLIC_MCP_ROUTE = exports.MCP_ROUTE = exports.DEFAULT_MCP_SERVER_NAME = void 0;
4
4
  exports.DEFAULT_MCP_SERVER_NAME = 'mcp-server';
5
5
  exports.MCP_ROUTE = '/mcp';
6
6
  exports.PUBLIC_MCP_ROUTE = '/mcp-public';
7
- exports.DEFAULT_MCP_OPTIONS = [
8
- 'cursor',
9
- 'vscode',
10
- 'claude-code',
11
- 'codex',
12
- 'copy',
13
- ];
7
+ exports.MCP_OPTIONS = ['cursor', 'vscode', 'claude-code', 'codex', 'copy'];
8
+ exports.DEFAULT_MCP_OPTIONS = [...exports.MCP_OPTIONS];
14
9
  //# sourceMappingURL=mcp.js.map
@@ -43,7 +43,7 @@ exports.DEFAULT_KEYBOARD_SHORTCUTS = '⌘+K,CTRL+K';
43
43
  exports.TOOL_CALL_DISPLAY_TEXT = {
44
44
  [search_1.ToolCallName.SearchDocumentation]: {
45
45
  inProgressText: 'Searching documentation...',
46
- completedText: 'Search completed',
46
+ completedText: 'Searched the documentation',
47
47
  },
48
48
  [search_1.ToolCallName.ListApis]: {
49
49
  inProgressText: 'Browsing APIs...',
@@ -65,6 +65,10 @@ exports.TOOL_CALL_DISPLAY_TEXT = {
65
65
  inProgressText: 'Reading API description...',
66
66
  completedText: 'Read API description',
67
67
  },
68
+ [search_1.ToolCallName.Execute]: {
69
+ inProgressText: 'Running code...',
70
+ completedText: 'Ran code',
71
+ },
68
72
  [search_1.ToolCallName.DescribeTools]: {
69
73
  inProgressText: 'Discovering available tools...',
70
74
  completedText: 'Discovered available tools',
@@ -30,6 +30,7 @@ export * from './use-product-picker';
30
30
  export * from './search/use-search-dialog';
31
31
  export * from './search/use-search-filter';
32
32
  export * from './search/use-feedback-tooltip';
33
+ export * from './search/use-search-ai-activity';
33
34
  export * from './use-controlled-state';
34
35
  export * from './use-codeblock-tabs-controls';
35
36
  export * from './code-walkthrough/use-code-walkthrough';
@@ -46,6 +46,7 @@ __exportStar(require("./use-product-picker"), exports);
46
46
  __exportStar(require("./search/use-search-dialog"), exports);
47
47
  __exportStar(require("./search/use-search-filter"), exports);
48
48
  __exportStar(require("./search/use-feedback-tooltip"), exports);
49
+ __exportStar(require("./search/use-search-ai-activity"), exports);
49
50
  __exportStar(require("./use-controlled-state"), exports);
50
51
  __exportStar(require("./use-codeblock-tabs-controls"), exports);
51
52
  __exportStar(require("./code-walkthrough/use-code-walkthrough"), exports);
@@ -169,6 +169,6 @@ function useEvent(callback) {
169
169
  (0, react_1.useEffect)(() => {
170
170
  ref.current = callback;
171
171
  });
172
- return (0, react_1.useCallback)(((...args) => { var _a; return (_a = ref.current) === null || _a === void 0 ? void 0 : _a.call(ref, ...args); }), []);
172
+ return (0, react_1.useCallback)((...args) => { var _a; return (_a = ref.current) === null || _a === void 0 ? void 0 : _a.call(ref, ...args); }, []);
173
173
  }
174
174
  //# sourceMappingURL=use-collapse.js.map
@@ -0,0 +1,11 @@
1
+ import type { SearchAiActivityStatus, SearchAiActivityStep, ToolCall } from '../../types/search';
2
+ type UseSearchAiActivityParams = {
3
+ toolCalls: ToolCall[];
4
+ isActive: boolean;
5
+ };
6
+ type UseSearchAiActivityReturn = {
7
+ status: SearchAiActivityStatus;
8
+ steps: SearchAiActivityStep[];
9
+ };
10
+ export declare function useSearchAiActivity({ toolCalls, isActive, }: UseSearchAiActivityParams): UseSearchAiActivityReturn;
11
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSearchAiActivity = useSearchAiActivity;
4
+ const use_theme_hooks_1 = require("../use-theme-hooks");
5
+ const search_ai_activity_1 = require("../../utils/search-ai-activity");
6
+ function useSearchAiActivity({ toolCalls, isActive, }) {
7
+ const { useTranslate } = (0, use_theme_hooks_1.useThemeHooks)();
8
+ const { translate } = useTranslate();
9
+ const runningToolCall = isActive ? toolCalls.find((toolCall) => !toolCall.result) : undefined;
10
+ return {
11
+ status: (0, search_ai_activity_1.getSearchAiActivityStatus)(toolCalls, isActive, runningToolCall, translate),
12
+ steps: toolCalls.map((toolCall) => (0, search_ai_activity_1.getSearchAiActivityStep)(toolCall, isActive && !toolCall.result, translate)),
13
+ };
14
+ }
15
+ //# sourceMappingURL=use-search-ai-activity.js.map
@@ -45,7 +45,8 @@ function useConnectMCPButton({ options = mcp_1.DEFAULT_MCP_OPTIONS, } = {}) {
45
45
  window.open(urlMap[action], '_blank');
46
46
  }, [cursorUrl, vscodeUrl, serverUrl, serverName, resetCopied, telemetry]);
47
47
  const triggerButtonText = (0, react_1.useMemo)(() => translate('page.actions.connectMcp', 'Connect MCP'), [translate]);
48
- const visibleOptions = (0, react_1.useMemo)(() => options.filter(Boolean), [options]);
48
+ // Markdoc reports attribute errors but still renders the tag, so `options` can be any value.
49
+ const visibleOptions = (0, react_1.useMemo)(() => Array.isArray(options) ? [...new Set(options.filter(mcp_2.isMCPOption))] : [...mcp_1.DEFAULT_MCP_OPTIONS], [options]);
49
50
  return {
50
51
  copiedOption,
51
52
  cursorUrl,
@@ -1,2 +1,2 @@
1
1
  import type { RefObject } from 'react';
2
- export declare function useFullHeight(element: RefObject<HTMLElement | null>): void;
2
+ export declare function useFullHeight(elementRef: RefObject<HTMLElement | null>): void;
@@ -6,27 +6,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.useFullHeight = useFullHeight;
7
7
  const react_1 = require("react");
8
8
  const lodash_throttle_1 = __importDefault(require("lodash.throttle"));
9
- function useFullHeight(element) {
9
+ function useFullHeight(elementRef) {
10
10
  const handler = (0, react_1.useCallback)(() => {
11
- if (!element.current) {
11
+ if (!elementRef.current) {
12
12
  return;
13
13
  }
14
14
  const footer = document.querySelector('footer');
15
15
  if (!footer) {
16
16
  return;
17
17
  }
18
- const elementTop = element.current.getBoundingClientRect().top;
18
+ const elementTop = elementRef.current.getBoundingClientRect().top;
19
19
  const footerOffset = footer.offsetTop - window.scrollY - elementTop;
20
20
  if (footerOffset > window.innerHeight) {
21
- element.current.style.maxHeight = `${window.innerHeight - elementTop}px`;
21
+ elementRef.current.style.maxHeight = `${window.innerHeight - elementTop}px`;
22
22
  }
23
23
  else {
24
- element.current.style.maxHeight = `${footerOffset}px`;
24
+ elementRef.current.style.maxHeight = `${footerOffset}px`;
25
25
  }
26
- }, [element]);
26
+ }, [elementRef]);
27
27
  const throttledHandler = (0, react_1.useMemo)(() => (0, lodash_throttle_1.default)(handler, 150), [handler]);
28
28
  (0, react_1.useEffect)(() => {
29
- if (typeof window === 'undefined' || !element.current) {
29
+ if (typeof window === 'undefined' || !elementRef.current) {
30
30
  return () => {
31
31
  // nope
32
32
  };
@@ -42,6 +42,6 @@ function useFullHeight(element) {
42
42
  window.removeEventListener('scroll', throttledHandler);
43
43
  window.removeEventListener('resize', throttledHandler);
44
44
  };
45
- }, [throttledHandler, element, handler]);
45
+ }, [throttledHandler, elementRef, handler]);
46
46
  }
47
47
  //# sourceMappingURL=use-full-height.js.map
@@ -1,3 +1,5 @@
1
+ /** The light theme tokens without a selector, for a host that sets them on one element. */
2
+ export declare const tokens: import("styled-components").RuleSet<object>;
1
3
  export declare const styles: import("styled-components").RuleSet<NoInfer<{
2
4
  palette?: string;
3
5
  }>>;