@mcp-b/react-components 0.24.0 → 0.25.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 (109) hide show
  1. package/dist/{AgentChat-Bm1qYbOo.d.ts → AgentChat-DHxdTjwF.d.ts} +34 -7
  2. package/dist/{CodeBlock-Cp67Njo3.js → CodeBlock-B3RLU3ez.js} +1 -1
  3. package/dist/{FileTree-DW60q1w7.js → FileTree-CYr5og0q.js} +1 -1
  4. package/dist/{Message-_-bEYLAO.js → Message-KlK8tlBZ.js} +1 -1
  5. package/dist/{ModelSelector-Brvj9Cab.js → ModelSelector-YTlqkIjs.js} +1 -1
  6. package/dist/{ThinkChat-E_HrfH76.js → ThinkChat-DVhCEjq-.js} +11 -2
  7. package/dist/{ThinkChatActivity-2BobmuvR.d.ts → ThinkChatActivity-DMTHKWrI.d.ts} +11 -9
  8. package/dist/{ThinkChatContext-DrsZqdaO.d.ts → ThinkChatContext-B-Nk84Wi.d.ts} +13 -1
  9. package/dist/{ThinkRecoveryNotice-DFIcG9UX.d.ts → ThinkRecoveryNotice-D6gYcBbr.d.ts} +1 -1
  10. package/dist/{WorkspaceFileView-rUEN2iox.js → WorkspaceFileView-CuMjXYQn.js} +3 -3
  11. package/dist/components/Activity.d.ts +11 -0
  12. package/dist/components/Activity.js +16 -4
  13. package/dist/components/AgentActivity.js +1 -1
  14. package/dist/components/AgentActivityPreview.js +1 -1
  15. package/dist/components/AgentChat.d.ts +1 -1
  16. package/dist/components/AgentChat.js +174 -94
  17. package/dist/components/AgentChatStartScreen.js +1 -1
  18. package/dist/components/AgentConnection.js +2 -2
  19. package/dist/components/AgentMessageParts.js +6 -2
  20. package/dist/components/AgentToolDetail.d.ts +1 -1
  21. package/dist/components/AgentToolDetail.js +2 -2
  22. package/dist/components/Approval.js +1 -1
  23. package/dist/components/Artifact.js +1 -1
  24. package/dist/components/BrowserLiveView.js +1 -1
  25. package/dist/components/BrowserReplay.js +1 -1
  26. package/dist/components/BrowserRunPanel.js +1 -1
  27. package/dist/components/ChainOfThought.d.ts +1 -1
  28. package/dist/components/ChainOfThought.js +1 -1
  29. package/dist/components/ChatGptSignInScreen.js +2 -2
  30. package/dist/components/Checkbox.js +1 -1
  31. package/dist/components/Checkpoint.js +1 -1
  32. package/dist/components/CodeBlock.js +1 -1
  33. package/dist/components/CodexModelSelector.js +1 -1
  34. package/dist/components/Commit.js +2 -2
  35. package/dist/components/ContextMenu.js +1 -1
  36. package/dist/components/Conversation.js +1 -1
  37. package/dist/components/EnvironmentVariables.js +2 -2
  38. package/dist/components/ExpansionState.d.ts +51 -0
  39. package/dist/components/ExpansionState.js +46 -0
  40. package/dist/components/FileTree.js +1 -1
  41. package/dist/components/Goal.d.ts +87 -0
  42. package/dist/components/Goal.js +92 -0
  43. package/dist/components/McpConnectionRequest.js +1 -1
  44. package/dist/components/McpPluginCatalog.js +1 -1
  45. package/dist/components/McpServerPicker.js +1 -1
  46. package/dist/components/MediaPreviewCard.js +13 -2
  47. package/dist/components/Menubar.js +1 -1
  48. package/dist/components/Message.js +1 -1
  49. package/dist/components/MessageScroller.js +1 -1
  50. package/dist/components/MessageScrollerVirtual.d.ts +72 -0
  51. package/dist/components/MessageScrollerVirtual.js +110 -0
  52. package/dist/components/ModelSelector.js +1 -1
  53. package/dist/components/Plan.js +1 -1
  54. package/dist/components/PricingPlanCard.js +1 -1
  55. package/dist/components/PromptInput.js +1 -1
  56. package/dist/components/Queue.js +1 -1
  57. package/dist/components/Reasoning.js +2 -2
  58. package/dist/components/ResponsiveSidebarShell.js +1 -1
  59. package/dist/components/SearchField.js +1 -1
  60. package/dist/components/Select.js +1 -1
  61. package/dist/components/SessionCompaction.d.ts +58 -0
  62. package/dist/components/SessionCompaction.js +117 -0
  63. package/dist/components/Sources.js +1 -1
  64. package/dist/components/Stepper.js +1 -1
  65. package/dist/components/SubagentRunIndicator.js +1 -1
  66. package/dist/components/Task.js +1 -1
  67. package/dist/components/Terminal.js +2 -2
  68. package/dist/components/TestResults.js +1 -1
  69. package/dist/components/ThemeModeControl.js +1 -1
  70. package/dist/components/ThinkChat.d.ts +6 -6
  71. package/dist/components/ThinkChat.js +1 -1
  72. package/dist/components/ThinkChatActivity.d.ts +1 -1
  73. package/dist/components/ThinkChatActivity.js +68 -14
  74. package/dist/components/ThinkChatContext.d.ts +2 -2
  75. package/dist/components/ThinkChatContext.js +5 -1
  76. package/dist/components/ThinkChatToolPanels.js +1 -1
  77. package/dist/components/ThinkExecutionDetail.js +1 -1
  78. package/dist/components/ThinkExecutionStatus.js +1 -1
  79. package/dist/components/ThinkExecutionWorkbench.d.ts +4 -3
  80. package/dist/components/ThinkExecutionWorkbench.js +7 -10
  81. package/dist/components/ThinkFullApp.js +65 -54
  82. package/dist/components/ThinkRecoveryNotice.d.ts +1 -1
  83. package/dist/components/ThinkRoutineBrowser.js +1 -1
  84. package/dist/components/ThinkRoutineForm.js +1 -1
  85. package/dist/components/ThinkRoutineLibrary.js +1 -1
  86. package/dist/components/ThinkThreadPicker.js +1 -1
  87. package/dist/components/Toast.js +1 -1
  88. package/dist/components/ToolInvocation.d.ts +8 -1
  89. package/dist/components/ToolInvocation.js +3 -2
  90. package/dist/components/WebPreview.js +1 -1
  91. package/dist/components/WorkspaceBrowser.js +1 -1
  92. package/dist/components/WorkspaceExplorer.js +1 -1
  93. package/dist/components/WorkspaceFileView.js +1 -1
  94. package/dist/components/WorkspaceHeader.js +1 -1
  95. package/dist/components/icons.d.ts +2 -2
  96. package/dist/components/icons.js +2 -2
  97. package/dist/{copy-button-TWq8nZhc.js → copy-button-Buxmtmp9.js} +1 -1
  98. package/dist/{icons-wP1yFUXF.d.ts → icons-Cih3W-zM.d.ts} +6 -1
  99. package/dist/{icons-ua6f_GH3.js → icons-w5PpKGRz.js} +3 -2
  100. package/dist/styles/activity.css +6 -0
  101. package/dist/styles/agent-chat.css +20 -4
  102. package/dist/styles/composition-motion.css +13 -23
  103. package/dist/styles/goal.css +57 -0
  104. package/dist/styles/index.css +1 -0
  105. package/dist/styles/message-scroller.css +25 -0
  106. package/dist/styles/responsive-sidebar-shell.css +12 -0
  107. package/dist/styles/think-full-app.css +22 -14
  108. package/package.json +7 -6
  109. package/dist/view-transitions-DyUP0lSg.js +0 -77
@@ -94,6 +94,15 @@ interface AgentChatProps<MessageT extends UIMessage = UIMessage> {
94
94
  items: readonly PromptInputCommandDefinition[];
95
95
  onSelect?: (command: PromptInputCommandDefinition, draft: AgentChatComposerDraft) => void;
96
96
  };
97
+ /**
98
+ * Manual session compaction. When set, a built-in `/compact` entry always
99
+ * leads the slash menu; selecting it runs this action immediately — no
100
+ * reference chip, no submitted text — bypassing `slashCommands.onSelect`.
101
+ * A rejection renders in the composer's status notice region. The status
102
+ * half (live "compacting" phase, post-compaction transcript reload) is
103
+ * `useSessionCompaction` in `SessionCompaction` — wire both for full HITL.
104
+ */
105
+ onCompact?: () => Promise<unknown>;
97
106
  /** Controlled MCP catalog revealed by `@`; selections become composer references. */
98
107
  mentionCommands?: {
99
108
  items: readonly PromptInputCommandDefinition[];
@@ -190,12 +199,6 @@ interface AgentChatProps<MessageT extends UIMessage = UIMessage> {
190
199
  * its actions, while preserving a hidden model-visible text companion.
191
200
  */
192
201
  showAssistantActions?: (context: AgentChatRenderMessageContext<MessageT>) => boolean;
193
- /**
194
- * Selects transcript rows that should anchor at the top when they appear.
195
- * Defaults to user messages; large deterministic assistant guides can opt in
196
- * so their introduction is visible instead of their final action.
197
- */
198
- isMessageScrollAnchor?: (context: AgentChatRenderMessageContext<MessageT>) => boolean;
199
202
  }
200
203
  interface AgentChatComposerDraft {
201
204
  value: string;
@@ -213,6 +216,30 @@ interface PermissionModeControl {
213
216
  * Low-level transcript/composer surface used by `ThinkChat`: props in, no
214
217
  * transport. Product code that talks to a Cloudflare Think agent should render
215
218
  * `ThinkChat`; use this directly only for plain AI SDK or read-only messages.
219
+ *
220
+ * The transcript is always windowed with TanStack Virtual (end-anchored,
221
+ * follow-on-append): only the visible rows exist in the DOM, so hours-long
222
+ * runs stay cheap. Consequences and the host-side contract:
223
+ * - Every message needs a stable `id`; keys must survive prepends and stream
224
+ * growth.
225
+ * - Keep unchanged message objects referentially stable across updates.
226
+ * Structured-cloning the array per delta over a worker/extension boundary
227
+ * rebuilds every identity and defeats row memoization — clone once per
228
+ * throttled batch instead.
229
+ * - Throttle stream deltas before React state (AI SDK
230
+ * `experimental_throttle: 50` or equivalent).
231
+ * - Bound the data itself: windowing caps DOM size, not JS memory. Truncate
232
+ * stored tool output at the buffer (~20k chars) and keep history
233
+ * compaction on.
234
+ * - Unmount the transcript to hide it; don't `display: none` it — hidden
235
+ * rows measure 0 and corrupt the virtualizer's cached heights.
236
+ * - Rows unmount off-screen: find-in-page only searches the window;
237
+ * disclosure state persists via the built-in `ExpansionStateProvider`
238
+ * (pass your own store via a wrapper to survive route remounts), but the
239
+ * default `Reasoning` disclosure resets.
240
+ * - The transcript is not a screen-reader live region (windowing would
241
+ * announce re-inserted old rows as new); announce new messages from a
242
+ * host-owned live region if that matters.
216
243
  */
217
244
  declare function AgentChat<MessageT extends UIMessage = UIMessage>({
218
245
  className,
@@ -228,6 +255,7 @@ declare function AgentChat<MessageT extends UIMessage = UIMessage>({
228
255
  composerHeader,
229
256
  composerTools,
230
257
  slashCommands,
258
+ onCompact,
231
259
  mentionCommands,
232
260
  contextSelector,
233
261
  composerEndTools,
@@ -247,7 +275,6 @@ declare function AgentChat<MessageT extends UIMessage = UIMessage>({
247
275
  renderPart,
248
276
  renderMessageAfter,
249
277
  showAssistantActions,
250
- isMessageScrollAnchor,
251
278
  ref
252
279
  }: AgentChatProps<MessageT> & {
253
280
  ref?: React.Ref<HTMLDivElement>;
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "./class-names-BiMDVpUo.js";
2
2
  import { Select } from "./components/Select.js";
3
- import { t as CopyButton } from "./copy-button-TWq8nZhc.js";
3
+ import { t as CopyButton } from "./copy-button-Buxmtmp9.js";
4
4
  import * as React from "react";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { createHighlighter } from "shiki";
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "./class-names-BiMDVpUo.js";
2
- import { C as FileIcon, T as FolderOpenIcon, m as ChevronRightIcon, w as FolderIcon } from "./icons-ua6f_GH3.js";
2
+ import { C as FileIcon, T as FolderOpenIcon, m as ChevronRightIcon, w as FolderIcon } from "./icons-w5PpKGRz.js";
3
3
  import { t as NavigationLink } from "./navigation-link-Cob7KBlM.js";
4
4
  import * as React from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "./class-names-BiMDVpUo.js";
2
2
  import { Button } from "./components/Button.js";
3
- import { C as FileIcon, i as ArrowRightIcon, r as ArrowLeftIcon } from "./icons-ua6f_GH3.js";
3
+ import { C as FileIcon, i as ArrowRightIcon, r as ArrowLeftIcon } from "./icons-w5PpKGRz.js";
4
4
  import { IconButton } from "./components/IconButton.js";
5
5
  import { c as useWorkspaceNavigationContext, r as resolveWorkspaceLink, t as WorkspaceFileLink } from "./WorkspaceLink-BYYeTQLf.js";
6
6
  import { t as AttachmentPreview } from "./attachment-preview-DIs50Q0h.js";
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "./class-names-BiMDVpUo.js";
2
2
  import { Button } from "./components/Button.js";
3
- import { G as SearchIcon, f as ChevronDownIcon } from "./icons-ua6f_GH3.js";
3
+ import { G as SearchIcon, f as ChevronDownIcon } from "./icons-w5PpKGRz.js";
4
4
  import { Dialog } from "./components/Dialog.js";
5
5
  import { i as titleCase } from "./format-S6uWyoSb.js";
6
6
  import { Separator } from "./components/Separator.js";
@@ -1,7 +1,7 @@
1
1
  import { AgentChat } from "./components/AgentChat.js";
2
2
  import { AgentToolRunsProvider, useOptionalAgentToolRuns } from "./components/AgentToolRunsContext.js";
3
3
  import { SubagentRunList } from "./components/SubagentRunList.js";
4
- import { ThinkChatContext, useThinkChatContext } from "./components/ThinkChatContext.js";
4
+ import { ThinkChatContext, ThinkChatLiveContext, useThinkChatContext } from "./components/ThinkChatContext.js";
5
5
  import { ThinkChatActivity, createThinkChatActivityRenderer, renderThinkChatActivityPart } from "./components/ThinkChatActivity.js";
6
6
  import { ThinkRecoveryNotice } from "./components/ThinkRecoveryNotice.js";
7
7
  import * as React from "react";
@@ -103,9 +103,18 @@ function useThinkPendingExecutionApprovals(stub, sourceKey, refreshSignal, enabl
103
103
  * stream with agent work folded into collapsed Activity blocks.
104
104
  */
105
105
  function ThinkChatProvider({ agentTools, chat, children }) {
106
+ const isStreaming = Boolean(chat.isStreaming);
107
+ const lastMessageId = chat.messages.at(-1)?.id;
108
+ const live = React.useMemo(() => ({
109
+ isStreaming,
110
+ lastMessageId
111
+ }), [isStreaming, lastMessageId]);
106
112
  const chatProvider = /* @__PURE__ */ jsx(ThinkChatContext.Provider, {
107
113
  value: chat,
108
- children
114
+ children: /* @__PURE__ */ jsx(ThinkChatLiveContext.Provider, {
115
+ value: live,
116
+ children
117
+ })
109
118
  });
110
119
  return agentTools ? /* @__PURE__ */ jsx(AgentToolRunsProvider, {
111
120
  agentTools,
@@ -1,5 +1,5 @@
1
1
  import { i as AgentMessageRenderPartContext } from "./AgentMessageParts-CyD2UB3V.js";
2
- import { r as AgentChatProps } from "./AgentChat-Bm1qYbOo.js";
2
+ import { r as AgentChatProps } from "./AgentChat-DHxdTjwF.js";
3
3
  import { l as ThinkChatPart } from "./ThinkChatToolParts-CSzVwMXf.js";
4
4
  import { t as ThinkChatActivityDescription } from "./ThinkChatActivitySummary-kr5fE0wg.js";
5
5
  import * as React from "react";
@@ -40,19 +40,21 @@ interface ThinkChatActivityProps {
40
40
  isStreaming?: boolean;
41
41
  /** Per-tool action/panel overrides, keyed by tool name. */
42
42
  toolRenderers?: ThinkChatToolRenderers;
43
+ /**
44
+ * Uniquely identifies this run across the whole transcript for persisted
45
+ * disclosure state (the activity renderer passes `${message.id}:${runStart}`).
46
+ * Without it, the first step's key is the scope — unique for tool-led runs
47
+ * (toolCallId) but shared by reasoning-led runs in different messages, whose
48
+ * open/closed state then bleeds together across virtualization remounts.
49
+ */
50
+ stateKey?: string;
43
51
  }
44
- /**
45
- * One run of agent work as a collapsed Activity block: while streaming the
46
- * action shimmers with the live step; settled, it becomes a short summary
47
- * ("Thought, read 2 files and ran a command") over an expandable step log
48
- * with per-tool panels. Normally reached through `ThinkChat.Messages`;
49
- * exported for apps that lay out messages themselves.
50
- */
51
52
  declare function ThinkChatActivity({
52
53
  parts,
53
54
  defaultOpen,
54
55
  isStreaming,
55
- toolRenderers
56
+ toolRenderers,
57
+ stateKey
56
58
  }: ThinkChatActivityProps): React.JSX.Element | null;
57
59
  /**
58
60
  * Builds a renderPart handler that folds every run of consecutive activity
@@ -12,5 +12,17 @@ type ThinkChatValue<State = unknown, MessageT extends UIMessage = UIMessage> = R
12
12
  declare const ThinkChatContext: React.Context<unknown>;
13
13
  declare function useOptionalThinkChatContext<State = unknown, MessageT extends UIMessage = UIMessage>(): ThinkChatValue<State, MessageT> | null;
14
14
  declare function useThinkChatContext<State = unknown, MessageT extends UIMessage = UIMessage>(component: string): ThinkChatValue<State, MessageT>;
15
+ /**
16
+ * The two live-chat facts transcript rows actually need. Kept separate from
17
+ * the full chat value (whose identity changes every stream delta) so memoized
18
+ * rows subscribed here only re-render when the run starts, ends, or moves to
19
+ * a new message.
20
+ */
21
+ interface ThinkChatLiveValue {
22
+ isStreaming: boolean;
23
+ lastMessageId: string | undefined;
24
+ }
25
+ declare const ThinkChatLiveContext: React.Context<ThinkChatLiveValue | null>;
26
+ declare function useOptionalThinkChatLive(): ThinkChatLiveValue | null;
15
27
  //#endregion
16
- export { useThinkChatContext as i, ThinkChatValue as n, useOptionalThinkChatContext as r, ThinkChatContext as t };
28
+ export { useOptionalThinkChatContext as a, ThinkChatValue as i, ThinkChatLiveContext as n, useOptionalThinkChatLive as o, ThinkChatLiveValue as r, useThinkChatContext as s, ThinkChatContext as t };
@@ -1,4 +1,4 @@
1
- import { n as ThinkChatValue } from "./ThinkChatContext-DrsZqdaO.js";
1
+ import { i as ThinkChatValue } from "./ThinkChatContext-B-Nk84Wi.js";
2
2
  import { UIMessage } from "ai";
3
3
 
4
4
  //#region src/components/ThinkRecoveryNotice.d.ts
@@ -1,10 +1,10 @@
1
1
  import { buttonVariants } from "./components/Button.js";
2
- import { $ as WarningIcon, A as MaximizeIcon, d as CheckIcon, h as CodeIcon, tt as XIcon, x as EyeIcon, y as DownloadIcon } from "./icons-ua6f_GH3.js";
2
+ import { A as MaximizeIcon, d as CheckIcon, et as WarningIcon, h as CodeIcon, nt as XIcon, x as EyeIcon, y as DownloadIcon } from "./icons-w5PpKGRz.js";
3
3
  import { t as NavigationLink } from "./navigation-link-Cob7KBlM.js";
4
4
  import { c as useWorkspaceNavigationContext, s as useWorkspaceNavigationRestoration } from "./WorkspaceLink-BYYeTQLf.js";
5
5
  import { r as formatClock } from "./format-S6uWyoSb.js";
6
- import { f as MessageResponse, m as createWorkspaceRehypePlugins } from "./Message-_-bEYLAO.js";
7
- import { a as CodeBlockCopyButton, i as CodeBlockContent, r as CodeBlockContainer, t as CodeBlock } from "./CodeBlock-Cp67Njo3.js";
6
+ import { f as MessageResponse, m as createWorkspaceRehypePlugins } from "./Message-KlK8tlBZ.js";
7
+ import { a as CodeBlockCopyButton, i as CodeBlockContent, r as CodeBlockContainer, t as CodeBlock } from "./CodeBlock-B3RLU3ez.js";
8
8
  import { AppTopBar } from "./components/AppTopBar.js";
9
9
  import { inferWorkspaceLanguage, inferWorkspaceMedia, isWorkspaceMarkdownPath, isWorkspaceSkillPath, parseWorkspaceSkill } from "./components/WorkspaceFile.js";
10
10
  import { WorkspaceHeader } from "./components/WorkspaceHeader.js";
@@ -5,6 +5,13 @@ import * as React from "react";
5
5
  interface ActivityProps extends Omit<React.ComponentProps<typeof Collapsible.Root>, "unstyled"> {
6
6
  /** While true, the trigger action shimmers. */
7
7
  isStreaming?: boolean;
8
+ /**
9
+ * Stable id (tool call id, part key) that persists the open state in the
10
+ * surrounding `ExpansionStateProvider`, so a virtualized transcript restores
11
+ * the disclosure after the row unmounts and remounts. Without a provider or
12
+ * a key the disclosure stays plain uncontrolled local state.
13
+ */
14
+ stateKey?: string;
8
15
  }
9
16
  /**
10
17
  * A collapsible activity line that aggregates agent activity (tool calls,
@@ -30,6 +37,7 @@ declare function Activity({
30
37
  className,
31
38
  isStreaming,
32
39
  defaultOpen,
40
+ stateKey,
33
41
  ref,
34
42
  ...props
35
43
  }: ActivityProps & {
@@ -108,6 +116,8 @@ interface ActivityItemGroupProps extends Omit<React.ComponentProps<typeof Collap
108
116
  detail?: React.ReactNode;
109
117
  /** Optional leading icon for the row. */
110
118
  icon?: React.ReactNode;
119
+ /** Persist the open state under this id in the ExpansionStateProvider. See Activity. */
120
+ stateKey?: string;
111
121
  }
112
122
  /**
113
123
  * An expandable activity row — the second collapse level. The trigger reads
@@ -120,6 +130,7 @@ declare function ActivityItemGroup({
120
130
  detail,
121
131
  icon,
122
132
  children,
133
+ stateKey,
123
134
  ref,
124
135
  ...props
125
136
  }: ActivityItemGroupProps & {
@@ -1,6 +1,7 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Collapsible } from "./Collapsible.js";
3
- import { m as ChevronRightIcon } from "../icons-ua6f_GH3.js";
3
+ import { useExpansionState } from "./ExpansionState.js";
4
+ import { m as ChevronRightIcon } from "../icons-w5PpKGRz.js";
4
5
  import "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/Activity.tsx
@@ -24,12 +25,17 @@ import { jsx, jsxs } from "react/jsx-runtime";
24
25
  * </Activity>
25
26
  * ```
26
27
  */
27
- function Activity({ className, isStreaming = false, defaultOpen = false, ref, ...props }) {
28
+ function Activity({ className, isStreaming = false, defaultOpen = false, stateKey, ref, ...props }) {
29
+ const [open, setOpen] = useExpansionState(stateKey, defaultOpen);
30
+ const openProps = stateKey !== void 0 ? {
31
+ open,
32
+ onOpenChange: setOpen
33
+ } : { defaultOpen };
28
34
  return /* @__PURE__ */ jsx(Collapsible.Root, {
29
35
  ref,
30
36
  className: cx("activity", className),
31
- defaultOpen,
32
37
  "data-streaming": isStreaming || void 0,
38
+ ...openProps,
33
39
  ...props,
34
40
  unstyled: true
35
41
  });
@@ -104,10 +110,16 @@ function ActivityContent({ className, children, ref, ...props }) {
104
110
  * like a plain ActivityItem; expanding reveals chrome-free detail (a Terminal,
105
111
  * a thought trace) flush inside the outer Activity log.
106
112
  */
107
- function ActivityItemGroup({ className, action, detail, icon, children, ref, ...props }) {
113
+ function ActivityItemGroup({ className, action, detail, icon, children, stateKey, ref, ...props }) {
114
+ const [open, setOpen] = useExpansionState(stateKey, false);
115
+ const openProps = stateKey !== void 0 ? {
116
+ open,
117
+ onOpenChange: setOpen
118
+ } : void 0;
108
119
  return /* @__PURE__ */ jsxs(Collapsible.Root, {
109
120
  ref,
110
121
  className: cx("activity__group", className),
122
+ ...openProps,
111
123
  ...props,
112
124
  unstyled: true,
113
125
  children: [/* @__PURE__ */ jsxs(Collapsible.Trigger, {
@@ -1,4 +1,4 @@
1
- import { $ as WarningIcon, B as PencilIcon, C as FileIcon, F as MonitorIcon, G as SearchIcon, O as InfoIcon, Z as TerminalIcon, et as WrenchIcon, k as LinkIcon } from "../icons-ua6f_GH3.js";
1
+ import { B as PencilIcon, C as FileIcon, F as MonitorIcon, G as SearchIcon, O as InfoIcon, Q as TerminalIcon, et as WarningIcon, k as LinkIcon, tt as WrenchIcon } from "../icons-w5PpKGRz.js";
2
2
  import { inferFaviconUrl } from "../utils/favicon.js";
3
3
  import * as React from "react";
4
4
  import { jsx } from "react/jsx-runtime";
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
- import { $ as WarningIcon, C as FileIcon, j as McpIcon, q as SpinnerIcon, tt as XIcon } from "../icons-ua6f_GH3.js";
2
+ import { C as FileIcon, et as WarningIcon, j as McpIcon, nt as XIcon, q as SpinnerIcon } from "../icons-w5PpKGRz.js";
3
3
  import { ActivityHeader } from "./Activity.js";
4
4
  import { AgentActivityFavicon, AgentActivityIcon } from "./AgentActivity.js";
5
5
  import { t as NavigationLink } from "../navigation-link-Cob7KBlM.js";
@@ -1,2 +1,2 @@
1
- import { a as PermissionModeControl, i as AgentChatRenderMessageContext, n as AgentChatComposerDraft, r as AgentChatProps, t as AgentChat } from "../AgentChat-Bm1qYbOo.js";
1
+ import { a as PermissionModeControl, i as AgentChatRenderMessageContext, n as AgentChatComposerDraft, r as AgentChatProps, t as AgentChat } from "../AgentChat-DHxdTjwF.js";
2
2
  export { AgentChat, AgentChatComposerDraft, AgentChatProps, AgentChatRenderMessageContext, PermissionModeControl };