@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
@@ -0,0 +1,46 @@
1
+ import * as React from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/ExpansionState.tsx
4
+ /** Plain Map-backed store. Create one per conversation/thread. */
5
+ function createExpansionStore() {
6
+ const state = /* @__PURE__ */ new Map();
7
+ return {
8
+ get: (key) => state.get(key),
9
+ set: (key, open) => void state.set(key, open)
10
+ };
11
+ }
12
+ const ExpansionStateContext = React.createContext(null);
13
+ /**
14
+ * Provides the expansion store that `Activity`, `ActivityItemGroup`, and
15
+ * `ToolInvocation` write through when given a `stateKey`. (`Reasoning` is the
16
+ * deliberate exception — it keeps its own auto-open/auto-close streaming
17
+ * state and resets on remount.) `AgentChat` renders one around its transcript
18
+ * automatically; wrap it yourself (with an app-held `store`) to persist
19
+ * across remounts. A provider without an explicit `store` defers to an
20
+ * enclosing one, so AgentChat's built-in provider never shadows a host's.
21
+ */
22
+ function ExpansionStateProvider({ store, children }) {
23
+ const inherited = React.useContext(ExpansionStateContext);
24
+ const [fallback] = React.useState(createExpansionStore);
25
+ return /* @__PURE__ */ jsx(ExpansionStateContext.Provider, {
26
+ value: store ?? inherited ?? fallback,
27
+ children
28
+ });
29
+ }
30
+ /**
31
+ * Open state initialized from the surrounding store (falling back to
32
+ * `defaultOpen`) and written through on every change. Only the mounted row
33
+ * reads a given key, so there is no subscription — remounting re-reads the
34
+ * store. Without a provider or a `stateKey` this is plain local state.
35
+ */
36
+ function useExpansionState(stateKey, defaultOpen) {
37
+ const store = React.useContext(ExpansionStateContext);
38
+ const persisted = stateKey !== void 0 ? store : null;
39
+ const [open, setLocalOpen] = React.useState(() => (stateKey !== void 0 ? store?.get(stateKey) : void 0) ?? defaultOpen);
40
+ return [open, React.useCallback((next) => {
41
+ if (persisted) persisted.set(stateKey, next);
42
+ setLocalOpen(next);
43
+ }, [persisted, stateKey])];
44
+ }
45
+ //#endregion
46
+ export { ExpansionStateProvider, createExpansionStore, useExpansionState };
@@ -1,2 +1,2 @@
1
- import { a as FileTreeIcon, i as FileTreeFolder, n as FileTreeActions, o as FileTreeName, r as FileTreeFile, t as FileTree } from "../FileTree-DW60q1w7.js";
1
+ import { a as FileTreeIcon, i as FileTreeFolder, n as FileTreeActions, o as FileTreeName, r as FileTreeFile, t as FileTree } from "../FileTree-CYr5og0q.js";
2
2
  export { FileTree, FileTreeActions, FileTreeFile, FileTreeFolder, FileTreeIcon, FileTreeName };
@@ -0,0 +1,87 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/components/Goal.d.ts
4
+ /**
5
+ * Lifecycle of a persisted conversation goal. Mirrors the host's goal state;
6
+ * this is not a Think or AI SDK execution status.
7
+ */
8
+ type GoalStatus = "pursuing" | "paused" | "achieved" | "unmet" | "budget_limited";
9
+ interface GoalProps extends React.HTMLAttributes<HTMLDivElement> {
10
+ /** Drives the default title and the `data-status` styling hook. */
11
+ status?: GoalStatus;
12
+ /** Goal icon, content, and optional application-owned actions. */
13
+ children?: React.ReactNode;
14
+ }
15
+ /**
16
+ * Presentation-only banner for a persisted conversation goal — an objective
17
+ * the agent keeps pursuing across turns until it completes, pauses, or runs
18
+ * out of budget. Renders in `AgentChat`'s `notice` region between transcript
19
+ * and composer.
20
+ *
21
+ * Actions are ordinary composed buttons; this primitive does not set, pause,
22
+ * resume, or clear a goal and owns no timer or transport. The host-side goal
23
+ * contract lives in docs/think-goal.md.
24
+ */
25
+ declare function Goal({
26
+ className,
27
+ status,
28
+ ref,
29
+ ...props
30
+ }: GoalProps & {
31
+ ref?: React.Ref<HTMLDivElement>;
32
+ }): React.JSX.Element;
33
+ interface GoalIconProps extends React.HTMLAttributes<HTMLSpanElement> {}
34
+ declare function GoalIcon({
35
+ children,
36
+ className,
37
+ ref,
38
+ ...props
39
+ }: GoalIconProps & {
40
+ ref?: React.Ref<HTMLSpanElement>;
41
+ }): React.JSX.Element;
42
+ interface GoalContentProps extends React.HTMLAttributes<HTMLDivElement> {}
43
+ declare function GoalContent({
44
+ className,
45
+ ref,
46
+ ...props
47
+ }: GoalContentProps & {
48
+ ref?: React.Ref<HTMLDivElement>;
49
+ }): React.JSX.Element;
50
+ interface GoalTitleProps extends React.HTMLAttributes<HTMLSpanElement> {}
51
+ /** Status headline; defaults to the label for the surrounding `Goal` status. */
52
+ declare function GoalTitle({
53
+ children,
54
+ className,
55
+ ref,
56
+ ...props
57
+ }: GoalTitleProps & {
58
+ ref?: React.Ref<HTMLSpanElement>;
59
+ }): React.JSX.Element;
60
+ interface GoalObjectiveProps extends React.HTMLAttributes<HTMLSpanElement> {}
61
+ /** The user- or model-authored objective text. */
62
+ declare function GoalObjective({
63
+ className,
64
+ ref,
65
+ ...props
66
+ }: GoalObjectiveProps & {
67
+ ref?: React.Ref<HTMLSpanElement>;
68
+ }): React.JSX.Element;
69
+ interface GoalMetaProps extends React.HTMLAttributes<HTMLSpanElement> {}
70
+ /** Host-formatted progress metadata — elapsed time, turn count, budget. */
71
+ declare function GoalMeta({
72
+ className,
73
+ ref,
74
+ ...props
75
+ }: GoalMetaProps & {
76
+ ref?: React.Ref<HTMLSpanElement>;
77
+ }): React.JSX.Element;
78
+ interface GoalActionsProps extends React.HTMLAttributes<HTMLDivElement> {}
79
+ declare function GoalActions({
80
+ className,
81
+ ref,
82
+ ...props
83
+ }: GoalActionsProps & {
84
+ ref?: React.Ref<HTMLDivElement>;
85
+ }): React.JSX.Element;
86
+ //#endregion
87
+ export { Goal, GoalActions, GoalActionsProps, GoalContent, GoalContentProps, GoalIcon, GoalIconProps, GoalMeta, GoalMetaProps, GoalObjective, GoalObjectiveProps, GoalProps, GoalStatus, GoalTitle, GoalTitleProps };
@@ -0,0 +1,92 @@
1
+ import { t as cx } from "../class-names-BiMDVpUo.js";
2
+ import { Z as TargetIcon } from "../icons-w5PpKGRz.js";
3
+ import * as React from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/Goal.tsx
6
+ const GoalStatusContext = React.createContext("pursuing");
7
+ const STATUS_LABELS = {
8
+ pursuing: "Pursuing goal",
9
+ paused: "Goal paused",
10
+ achieved: "Goal achieved",
11
+ unmet: "Goal blocked",
12
+ budget_limited: "Goal budget exhausted"
13
+ };
14
+ /**
15
+ * Presentation-only banner for a persisted conversation goal — an objective
16
+ * the agent keeps pursuing across turns until it completes, pauses, or runs
17
+ * out of budget. Renders in `AgentChat`'s `notice` region between transcript
18
+ * and composer.
19
+ *
20
+ * Actions are ordinary composed buttons; this primitive does not set, pause,
21
+ * resume, or clear a goal and owns no timer or transport. The host-side goal
22
+ * contract lives in docs/think-goal.md.
23
+ */
24
+ function Goal({ className, status = "pursuing", ref, ...props }) {
25
+ return /* @__PURE__ */ jsx(GoalStatusContext.Provider, {
26
+ value: status,
27
+ children: /* @__PURE__ */ jsx("div", {
28
+ ref,
29
+ "data-slot": "goal",
30
+ "data-status": status,
31
+ className: cx("goal", className),
32
+ ...props
33
+ })
34
+ });
35
+ }
36
+ function GoalIcon({ children, className, ref, ...props }) {
37
+ return /* @__PURE__ */ jsx("span", {
38
+ ref,
39
+ "data-slot": "goal-icon",
40
+ "aria-hidden": "true",
41
+ className: cx("goal__icon", className),
42
+ ...props,
43
+ children: children ?? /* @__PURE__ */ jsx(TargetIcon, {})
44
+ });
45
+ }
46
+ function GoalContent({ className, ref, ...props }) {
47
+ return /* @__PURE__ */ jsx("div", {
48
+ ref,
49
+ "data-slot": "goal-content",
50
+ className: cx("goal__content", className),
51
+ ...props
52
+ });
53
+ }
54
+ /** Status headline; defaults to the label for the surrounding `Goal` status. */
55
+ function GoalTitle({ children, className, ref, ...props }) {
56
+ const status = React.useContext(GoalStatusContext);
57
+ return /* @__PURE__ */ jsx("span", {
58
+ ref,
59
+ "data-slot": "goal-title",
60
+ className: cx("goal__title", className),
61
+ ...props,
62
+ children: children ?? STATUS_LABELS[status]
63
+ });
64
+ }
65
+ /** The user- or model-authored objective text. */
66
+ function GoalObjective({ className, ref, ...props }) {
67
+ return /* @__PURE__ */ jsx("span", {
68
+ ref,
69
+ "data-slot": "goal-objective",
70
+ className: cx("goal__objective", className),
71
+ ...props
72
+ });
73
+ }
74
+ /** Host-formatted progress metadata — elapsed time, turn count, budget. */
75
+ function GoalMeta({ className, ref, ...props }) {
76
+ return /* @__PURE__ */ jsx("span", {
77
+ ref,
78
+ "data-slot": "goal-meta",
79
+ className: cx("goal__meta", className),
80
+ ...props
81
+ });
82
+ }
83
+ function GoalActions({ className, ref, ...props }) {
84
+ return /* @__PURE__ */ jsx("div", {
85
+ ref,
86
+ "data-slot": "goal-actions",
87
+ className: cx("goal__actions", className),
88
+ ...props
89
+ });
90
+ }
91
+ //#endregion
92
+ export { Goal, GoalActions, GoalContent, GoalIcon, GoalMeta, GoalObjective, GoalTitle };
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
- import { $ as WarningIcon, d as CheckIcon, j as McpIcon, q as SpinnerIcon } from "../icons-ua6f_GH3.js";
3
+ import { d as CheckIcon, et as WarningIcon, j as McpIcon, q as SpinnerIcon } from "../icons-w5PpKGRz.js";
4
4
  import { AgentAttention, AgentAttentionActions, AgentAttentionBody, AgentAttentionHeader } from "./AgentAttention.js";
5
5
  import { getMcpServerEntry, getMcpServerRuntimeState } from "../utils/mcp-server-catalog.js";
6
6
  import { DescriptionList } from "./DescriptionList.js";
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
- import { $ as WarningIcon, H as PlusIcon, b as EllipsisIcon, o as ArrowUpRightIcon, q as SpinnerIcon, tt as XIcon } from "../icons-ua6f_GH3.js";
3
+ import { H as PlusIcon, b as EllipsisIcon, et as WarningIcon, nt as XIcon, o as ArrowUpRightIcon, q as SpinnerIcon } from "../icons-w5PpKGRz.js";
4
4
  import { AppIcon } from "./AppIcon.js";
5
5
  import { IconButton } from "./IconButton.js";
6
6
  import { AgentAttention, AgentAttentionBody, AgentAttentionHeader } from "./AgentAttention.js";
@@ -1,6 +1,6 @@
1
1
  import { n as mergeBaseClassName } from "../class-names-BiMDVpUo.js";
2
2
  import { buttonVariants } from "./Button.js";
3
- import { $ as WarningIcon, P as MinusIcon, d as CheckIcon, q as SpinnerIcon } from "../icons-ua6f_GH3.js";
3
+ import { P as MinusIcon, d as CheckIcon, et as WarningIcon, q as SpinnerIcon } from "../icons-w5PpKGRz.js";
4
4
  import { AppIcon } from "./AppIcon.js";
5
5
  import { Dialog } from "./Dialog.js";
6
6
  import { Menu } from "./Menu.js";
@@ -1,10 +1,21 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
- import { V as PlayIcon } from "../icons-ua6f_GH3.js";
2
+ import { V as PlayIcon } from "../icons-w5PpKGRz.js";
3
3
  import { n as mergeRefs } from "../merge-refs-DF_7w2x_.js";
4
4
  import { Card } from "./Card.js";
5
- import { t as motionIsReduced } from "../view-transitions-DyUP0lSg.js";
6
5
  import * as React from "react";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/components/_internal/motion-preferences.ts
8
+ /**
9
+ * Reports whether motion should be suppressed, honoring both the app-level
10
+ * `data-motion="reduce"` override and the `prefers-reduced-motion` media query.
11
+ * Returns `true` when there is no document, e.g. during SSR.
12
+ */
13
+ function motionIsReduced() {
14
+ if (typeof document === "undefined") return true;
15
+ if (document.documentElement.dataset.motion === "reduce") return true;
16
+ return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
17
+ }
18
+ //#endregion
8
19
  //#region src/components/MediaPreviewCard.tsx
9
20
  const MediaPreviewCardContext = React.createContext(null);
10
21
  function useMediaPreviewCardContext() {
@@ -1,6 +1,6 @@
1
1
  import { n as mergeBaseClassName, t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { buttonVariants } from "./Button.js";
3
- import { d as CheckIcon, v as DotIcon } from "../icons-ua6f_GH3.js";
3
+ import { d as CheckIcon, v as DotIcon } from "../icons-w5PpKGRz.js";
4
4
  import "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { Menu } from "@base-ui/react/menu";
@@ -1,2 +1,2 @@
1
- import { a as MessageBranch, c as MessageBranchPage, d as MessageContent, f as MessageResponse, i as MessageAttachment, l as MessageBranchPrevious, n as MessageAction, o as MessageBranchContent, p as MessageToolbar, r as MessageActions, s as MessageBranchNext, t as Message, u as MessageBranchSelector } from "../Message-_-bEYLAO.js";
1
+ import { a as MessageBranch, c as MessageBranchPage, d as MessageContent, f as MessageResponse, i as MessageAttachment, l as MessageBranchPrevious, n as MessageAction, o as MessageBranchContent, p as MessageToolbar, r as MessageActions, s as MessageBranchNext, t as Message, u as MessageBranchSelector } from "../Message-KlK8tlBZ.js";
2
2
  export { Message, MessageAction, MessageActions, MessageAttachment, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageResponse, MessageToolbar };
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
- import { n as ArrowDownIcon } from "../icons-ua6f_GH3.js";
3
+ import { n as ArrowDownIcon } from "../icons-w5PpKGRz.js";
4
4
  import "react";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { MessageScroller as MessageScroller$1, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility } from "@shadcn/react/message-scroller";
@@ -0,0 +1,72 @@
1
+ import { r as ButtonProps } from "../Button-SBIz6Lqi.js";
2
+ import * as React from "react";
3
+
4
+ //#region src/components/MessageScrollerVirtual.d.ts
5
+ interface VirtualMessageScrollerProps<Item> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
6
+ items: readonly Item[];
7
+ /**
8
+ * Stable per-item key. Must survive prepends and stream updates — the
9
+ * virtualizer tracks identity by key to keep scroll anchored. Message ids,
10
+ * never indexes (deliberately not passed here).
11
+ */
12
+ getItemKey: (item: Item) => string | number;
13
+ renderItem: (item: Item, index: number) => React.ReactNode;
14
+ /**
15
+ * Pre-measurement height estimate in px. Rows are measured once rendered;
16
+ * changing this later never re-estimates already-measured rows — only rows
17
+ * measured afterward see the new value.
18
+ */
19
+ estimateSize?: number;
20
+ /** Rows rendered beyond the viewport on each side. */
21
+ overscan?: number;
22
+ /** Rendered inside the viewport when `items` is empty. */
23
+ emptyState?: React.ReactNode;
24
+ /** Props for the inner content element (`role="log"` container). */
25
+ contentProps?: React.HTMLAttributes<HTMLDivElement>;
26
+ /** Accessible label for the scroll-to-latest button. */
27
+ scrollButtonLabel?: string;
28
+ scrollButtonProps?: Omit<ButtonProps, "onClick" | "aria-label" | "tabIndex">;
29
+ }
30
+ /**
31
+ * Windowed chat transcript for unbounded threads (hours-long agent runs):
32
+ * only the visible slice of rows exists in the DOM, end-anchored so streaming
33
+ * growth and appends keep the viewport pinned while reading history doesn't
34
+ * get yanked to the bottom (TanStack Virtual `anchorTo: 'end'`).
35
+ *
36
+ * Trade-offs versus the plain `MessageScroller`: rows unmount when scrolled
37
+ * away, so browser find-in-page only searches the rendered window, and any
38
+ * disclosure state living inside a row is lost unless it is persisted — wrap
39
+ * the transcript in `ExpansionStateProvider` (AgentChat does) and give
40
+ * disclosures a `stateKey`. The "anchor user message to top" behavior of the
41
+ * plain scroller is not implemented; new turns pin to the bottom instead.
42
+ *
43
+ * Host-side contract (what the consuming app must do — the scroller cannot
44
+ * compensate for any of these):
45
+ * - Give every item a stable id for `getItemKey`; keys must not change when
46
+ * older history is prepended or the last message grows.
47
+ * - Keep unchanged items referentially stable across updates so memoized row
48
+ * content skips re-rendering. Rebuilding the array element-by-element —
49
+ * e.g. structured-clone over a worker/extension boundary per delta —
50
+ * defeats this; clone once per batch, not per row.
51
+ * - Throttle stream deltas before they reach React state (AI SDK
52
+ * `experimental_throttle: 50` or equivalent); the scroller re-windows per
53
+ * update.
54
+ * - Bound the data itself: windowing caps DOM size, not JS memory. Truncate
55
+ * stored tool output at the buffer (Codex caps at 20k chars) and keep
56
+ * compaction on so a six-hour run doesn't hold every byte it ever streamed.
57
+ */
58
+ declare function VirtualMessageScroller<Item>({
59
+ items,
60
+ getItemKey,
61
+ renderItem,
62
+ estimateSize,
63
+ overscan,
64
+ emptyState,
65
+ contentProps,
66
+ scrollButtonLabel,
67
+ scrollButtonProps,
68
+ className,
69
+ ...props
70
+ }: VirtualMessageScrollerProps<Item>): React.JSX.Element;
71
+ //#endregion
72
+ export { VirtualMessageScroller, VirtualMessageScrollerProps };
@@ -0,0 +1,110 @@
1
+ import { t as cx } from "../class-names-BiMDVpUo.js";
2
+ import { Button } from "./Button.js";
3
+ import { n as ArrowDownIcon } from "../icons-w5PpKGRz.js";
4
+ import * as React from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { useVirtualizer } from "@tanstack/react-virtual";
7
+ //#region src/components/MessageScrollerVirtual.tsx
8
+ /**
9
+ * Windowed chat transcript for unbounded threads (hours-long agent runs):
10
+ * only the visible slice of rows exists in the DOM, end-anchored so streaming
11
+ * growth and appends keep the viewport pinned while reading history doesn't
12
+ * get yanked to the bottom (TanStack Virtual `anchorTo: 'end'`).
13
+ *
14
+ * Trade-offs versus the plain `MessageScroller`: rows unmount when scrolled
15
+ * away, so browser find-in-page only searches the rendered window, and any
16
+ * disclosure state living inside a row is lost unless it is persisted — wrap
17
+ * the transcript in `ExpansionStateProvider` (AgentChat does) and give
18
+ * disclosures a `stateKey`. The "anchor user message to top" behavior of the
19
+ * plain scroller is not implemented; new turns pin to the bottom instead.
20
+ *
21
+ * Host-side contract (what the consuming app must do — the scroller cannot
22
+ * compensate for any of these):
23
+ * - Give every item a stable id for `getItemKey`; keys must not change when
24
+ * older history is prepended or the last message grows.
25
+ * - Keep unchanged items referentially stable across updates so memoized row
26
+ * content skips re-rendering. Rebuilding the array element-by-element —
27
+ * e.g. structured-clone over a worker/extension boundary per delta —
28
+ * defeats this; clone once per batch, not per row.
29
+ * - Throttle stream deltas before they reach React state (AI SDK
30
+ * `experimental_throttle: 50` or equivalent); the scroller re-windows per
31
+ * update.
32
+ * - Bound the data itself: windowing caps DOM size, not JS memory. Truncate
33
+ * stored tool output at the buffer (Codex caps at 20k chars) and keep
34
+ * compaction on so a six-hour run doesn't hold every byte it ever streamed.
35
+ */
36
+ function VirtualMessageScroller({ items, getItemKey, renderItem, estimateSize = 160, overscan = 6, emptyState, contentProps, scrollButtonLabel = "Scroll to latest", scrollButtonProps, className, ...props }) {
37
+ const viewportRef = React.useRef(null);
38
+ const warnedNullKey = React.useRef(false);
39
+ const [atEnd, setAtEnd] = React.useState(true);
40
+ const [scrollEdges, setScrollEdges] = React.useState();
41
+ const virtualizer = useVirtualizer({
42
+ count: items.length,
43
+ getScrollElement: () => viewportRef.current,
44
+ estimateSize: () => estimateSize,
45
+ getItemKey: (index) => {
46
+ const key = getItemKey(items[index]);
47
+ if (key == null && !warnedNullKey.current) {
48
+ warnedNullKey.current = true;
49
+ console.error("VirtualMessageScroller: getItemKey returned a nullish key — every item needs a stable id.");
50
+ }
51
+ return key;
52
+ },
53
+ anchorTo: "end",
54
+ followOnAppend: true,
55
+ scrollEndThreshold: 80,
56
+ overscan,
57
+ gap: 16,
58
+ initialOffset: () => items.length * (estimateSize + 16),
59
+ onChange: (instance) => {
60
+ setAtEnd(instance.isAtEnd());
61
+ const viewport = viewportRef.current;
62
+ const edges = [viewport && viewport.scrollTop > 1 ? "start" : null, instance.getDistanceFromEnd() > 1 ? "end" : null].filter(Boolean).join(" ");
63
+ setScrollEdges(edges || void 0);
64
+ }
65
+ });
66
+ React.useLayoutEffect(() => {
67
+ virtualizer.scrollToEnd();
68
+ }, []);
69
+ return /* @__PURE__ */ jsxs("div", {
70
+ className: cx("message-scroller", className),
71
+ ...props,
72
+ children: [/* @__PURE__ */ jsx("div", {
73
+ ref: viewportRef,
74
+ "data-slot": "message-scroller-viewport",
75
+ "data-scrollable": scrollEdges,
76
+ className: "message-scroller__viewport",
77
+ children: items.length === 0 ? emptyState : /* @__PURE__ */ jsx("div", {
78
+ ...contentProps,
79
+ className: cx("message-scroller__virtual-content", contentProps?.className),
80
+ style: {
81
+ ...contentProps?.style,
82
+ height: virtualizer.getTotalSize()
83
+ },
84
+ children: virtualizer.getVirtualItems().map((virtualItem) => /* @__PURE__ */ jsx("div", {
85
+ ref: virtualizer.measureElement,
86
+ "data-index": virtualItem.index,
87
+ "data-item-key": virtualItem.key,
88
+ className: "message-scroller__virtual-item",
89
+ style: { transform: `translateY(${virtualItem.start}px)` },
90
+ children: renderItem(items[virtualItem.index], virtualItem.index)
91
+ }, virtualItem.key))
92
+ })
93
+ }), /* @__PURE__ */ jsx(Button, {
94
+ "aria-label": scrollButtonLabel,
95
+ color: "neutral",
96
+ variant: "normal",
97
+ size: "sm",
98
+ iconOnly: true,
99
+ ...scrollButtonProps,
100
+ className: cx("message-scroller__button", scrollButtonProps?.className),
101
+ "data-direction": "end",
102
+ "data-active": !atEnd,
103
+ tabIndex: atEnd ? -1 : void 0,
104
+ onClick: () => virtualizer.scrollToEnd({ behavior: "smooth" }),
105
+ children: /* @__PURE__ */ jsx(ArrowDownIcon, {})
106
+ })]
107
+ });
108
+ }
109
+ //#endregion
110
+ export { VirtualMessageScroller };
@@ -1,2 +1,2 @@
1
- import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorSource, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-Brvj9Cab.js";
1
+ import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorSource, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-YTlqkIjs.js";
2
2
  export { CloudflareModelSelector, ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorSource, ModelSelectorTrigger, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
@@ -1,5 +1,5 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
- import { d as CheckIcon, i as ArrowRightIcon, v as DotIcon } from "../icons-ua6f_GH3.js";
2
+ import { d as CheckIcon, i as ArrowRightIcon, v as DotIcon } from "../icons-w5PpKGRz.js";
3
3
  import * as React from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/components/Plan.tsx
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
- import { O as InfoIcon, P as MinusIcon, d as CheckIcon } from "../icons-ua6f_GH3.js";
3
+ import { O as InfoIcon, P as MinusIcon, d as CheckIcon } from "../icons-w5PpKGRz.js";
4
4
  import { IconButton } from "./IconButton.js";
5
5
  import { Separator } from "./Separator.js";
6
6
  import { Badge } from "./Badge.js";
@@ -1,6 +1,6 @@
1
1
  import { n as mergeBaseClassName, t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
- import { $ as WarningIcon, C as FileIcon, F as MonitorIcon, H as PlusIcon, J as SquareIcon, N as MicrophoneIcon, R as PaperclipIcon, Y as StopIcon, a as ArrowUpIcon, d as CheckIcon, et as WrenchIcon, f as ChevronDownIcon, q as SpinnerIcon, tt as XIcon, w as FolderIcon } from "../icons-ua6f_GH3.js";
3
+ import { C as FileIcon, F as MonitorIcon, H as PlusIcon, J as SquareIcon, N as MicrophoneIcon, R as PaperclipIcon, Y as StopIcon, a as ArrowUpIcon, d as CheckIcon, et as WarningIcon, f as ChevronDownIcon, nt as XIcon, q as SpinnerIcon, tt as WrenchIcon, w as FolderIcon } from "../icons-w5PpKGRz.js";
4
4
  import { Tooltip } from "./Tooltip.js";
5
5
  import { IconButton } from "./IconButton.js";
6
6
  import { t as AttachmentPreview } from "../attachment-preview-DIs50Q0h.js";
@@ -1,7 +1,7 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
3
  import { Collapsible } from "./Collapsible.js";
4
- import { C as FileIcon, d as CheckIcon, m as ChevronRightIcon, v as DotIcon } from "../icons-ua6f_GH3.js";
4
+ import { C as FileIcon, d as CheckIcon, m as ChevronRightIcon, v as DotIcon } from "../icons-w5PpKGRz.js";
5
5
  import { Badge } from "./Badge.js";
6
6
  import { ScrollArea } from "./ScrollArea.js";
7
7
  import "react";
@@ -1,8 +1,8 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Collapsible } from "./Collapsible.js";
3
- import { q as SpinnerIcon } from "../icons-ua6f_GH3.js";
3
+ import { q as SpinnerIcon } from "../icons-w5PpKGRz.js";
4
4
  import { ActivityContent, ActivityText, ActivityTrigger } from "./Activity.js";
5
- import { f as MessageResponse } from "../Message-_-bEYLAO.js";
5
+ import { f as MessageResponse } from "../Message-KlK8tlBZ.js";
6
6
  import * as React from "react";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
  //#region src/components/Reasoning.tsx
@@ -1,6 +1,6 @@
1
1
  import { t as cx } from "../class-names-BiMDVpUo.js";
2
2
  import { Button } from "./Button.js";
3
- import { K as SidebarIcon } from "../icons-ua6f_GH3.js";
3
+ import { K as SidebarIcon } from "../icons-w5PpKGRz.js";
4
4
  import { t as capitalize } from "../format-S6uWyoSb.js";
5
5
  import { n as mergeRefs } from "../merge-refs-DF_7w2x_.js";
6
6
  import { AppTopBar } from "./AppTopBar.js";
@@ -1,5 +1,5 @@
1
1
  import { n as mergeBaseClassName } from "../class-names-BiMDVpUo.js";
2
- import { G as SearchIcon } from "../icons-ua6f_GH3.js";
2
+ import { G as SearchIcon } from "../icons-w5PpKGRz.js";
3
3
  import { Field } from "./Field.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/components/SearchField.tsx
@@ -1,5 +1,5 @@
1
1
  import { n as mergeBaseClassName } from "../class-names-BiMDVpUo.js";
2
- import { a as ArrowUpIcon, d as CheckIcon, n as ArrowDownIcon } from "../icons-ua6f_GH3.js";
2
+ import { a as ArrowUpIcon, d as CheckIcon, n as ArrowDownIcon } from "../icons-w5PpKGRz.js";
3
3
  import "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Select as Select$1 } from "@base-ui/react/select";
@@ -0,0 +1,58 @@
1
+ import { ChatStatus, UIMessage } from "ai";
2
+
3
+ //#region src/components/SessionCompaction.d.ts
4
+ type SessionStatusPhase = "idle" | "compacting";
5
+ interface SessionStatusFrame {
6
+ phase: SessionStatusPhase;
7
+ /** Present on the idle frame that follows a successful compaction. */
8
+ compacted: boolean;
9
+ }
10
+ /**
11
+ * Parse a raw websocket payload as a `cf_agent_session` status frame.
12
+ * Returns null for every other frame on the connection.
13
+ */
14
+ declare function parseSessionStatusFrame(data: unknown): SessionStatusFrame | null;
15
+ /**
16
+ * Parse a raw websocket payload as a `cf_agent_session_error` frame,
17
+ * returning its error text. Null for every other frame on the connection.
18
+ */
19
+ declare function parseSessionErrorFrame(data: unknown): string | null;
20
+ /** The message-frame surface of a `useAgent` connection. */
21
+ interface SessionFrameSource {
22
+ addEventListener(type: "message", listener: (event: MessageEvent) => void): void;
23
+ removeEventListener(type: "message", listener: (event: MessageEvent) => void): void;
24
+ }
25
+ interface UseSessionCompactionOptions<MessageT extends UIMessage> {
26
+ /** The conversation agent's `useAgent` connection. */
27
+ agent: SessionFrameSource;
28
+ /** The conversation's `useAgentChat` value (status + local view setter). */
29
+ chat: {
30
+ status: ChatStatus;
31
+ setMessages: (messages: MessageT[]) => void;
32
+ };
33
+ /** Server read used to reload the transcript after a compaction lands. */
34
+ getMessages: () => Promise<MessageT[]>;
35
+ }
36
+ declare function useSessionCompaction<MessageT extends UIMessage>({
37
+ agent,
38
+ chat,
39
+ getMessages
40
+ }: UseSessionCompactionOptions<MessageT>): {
41
+ compacting: boolean;
42
+ /**
43
+ * Set when the post-compaction transcript reload rejected — the local view
44
+ * is stale relative to the server until a retry succeeds. Surface it
45
+ * ("Transcript may be out of date"); the hook retries on the next status
46
+ * transition to `"ready"`.
47
+ */
48
+ reloadError: unknown;
49
+ /**
50
+ * Error text from the last `cf_agent_session_error` frame — the only signal
51
+ * a user who ran /compact gets when the server-side compaction itself fails
52
+ * (the phase just flips back to idle with no `compacted` payload). Cleared
53
+ * when the next compaction starts.
54
+ */
55
+ sessionError: string | null;
56
+ };
57
+ //#endregion
58
+ export { SessionFrameSource, SessionStatusFrame, SessionStatusPhase, UseSessionCompactionOptions, parseSessionErrorFrame, parseSessionStatusFrame, useSessionCompaction };