@page-speed/agent-everywhere 0.5.0 → 0.6.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.
package/README.md CHANGED
@@ -141,6 +141,56 @@ run fully controlled with no provider. For 100%-custom UI, read the session
141
141
  directly with `useNativeAgent()`. The connection is lazy by default
142
142
  (`connectionStrategy="eager"` to pre-connect on mount).
143
143
 
144
+ ### AgentWorkspace — the page-level AI layout wrapper
145
+
146
+ `AgentWorkspace` composes the native pieces into a full workspace layout: an
147
+ optional left panel, the host's page content in a growing center column with the
148
+ prompt composer docked at the bottom, an optional right panel, and a
149
+ conversation layer that **slides in over the center content** when the shared
150
+ session activates (and slides away on `reset()`).
151
+
152
+ ```tsx
153
+ import {
154
+ NativeAgentProvider,
155
+ AgentWorkspace,
156
+ AgentWorkspacePanelToggle,
157
+ } from '@page-speed/agent-everywhere';
158
+
159
+ <NativeAgentProvider resolveSocketUrl={resolveSocketUrl} websiteId={id} pageCategoryId="pages">
160
+ <AgentWorkspace
161
+ className="h-dvh"
162
+ leftPanel={<KnowledgePanel />} // omit → no panel, no toggle
163
+ rightPanel={<AnalyticsPanel />} // widths via left/rightPanelWidth
164
+ composerPlaceholder="Describe a site-wide change…"
165
+ composerHint="Agents render live, interactive artifacts inline."
166
+ >
167
+ <YourPage />
168
+ </AgentWorkspace>
169
+ </NativeAgentProvider>;
170
+ ```
171
+
172
+ Every region is independently optional and controllable:
173
+
174
+ - **Panels** collapse/expand with a smooth width-collapse animation (the
175
+ outer rail animates to `0` while the inner wrapper keeps its open width, so
176
+ content clips out instead of reflowing). Uncontrolled by default;
177
+ controlled via `leftPanelOpen`/`onLeftPanelOpenChange` (and the right-side
178
+ equivalents). Built-in floating toggles render in the top corners
179
+ (`showPanelToggles={false}` to place `<AgentWorkspacePanelToggle side="…"/>`
180
+ in your own chrome). Panels are gated to `lg:` viewports.
181
+ - **Conversation layer** auto-opens on the first submit (or `activate()`),
182
+ can be minimized back to the page without ending the session (a
183
+ "View conversation" chip appears in the dock), and accepts a custom node via
184
+ `conversation` for decorated transcripts. Controlled via `conversationOpen`.
185
+ - **Composer dock** renders `AgentWorkspaceComposer` — a pill input with an
186
+ auto-growing textarea (Enter submits, Shift+Enter inserts a newline), an
187
+ optional attach affordance (`onAttach`), and a circular send button. Pass
188
+ `composer={false}` to drop it, a node to replace it, or `onComposerSubmit`
189
+ to intercept submits.
190
+ - **Programmatic control** from anywhere inside: `useAgentWorkspace()` exposes
191
+ `toggleLeftPanel`, `setRightPanelOpen`, `openConversation`,
192
+ `closeConversation`, and friends for dynamic layout scenarios.
193
+
144
194
  ### Inline confirmation / proposed-plan panels
145
195
 
146
196
  Confirmation and proposed-plan panels flow **inline in the transcript** — attach
package/dist/index.cjs CHANGED
@@ -8552,6 +8552,437 @@ function AgentConversation({
8552
8552
  )
8553
8553
  ] });
8554
8554
  }
8555
+ var AgentWorkspaceContext = React4.createContext(null);
8556
+ function useAgentWorkspace() {
8557
+ const ctx = React4.useContext(AgentWorkspaceContext);
8558
+ if (!ctx) {
8559
+ throw new Error(
8560
+ "useAgentWorkspace must be used within an <AgentWorkspace>."
8561
+ );
8562
+ }
8563
+ return ctx;
8564
+ }
8565
+ function useAgentWorkspaceOptional() {
8566
+ return React4.useContext(AgentWorkspaceContext);
8567
+ }
8568
+ var noop2 = () => {
8569
+ };
8570
+ function warnDev2(message) {
8571
+ const env = globalThis.process?.env;
8572
+ if (env && env.NODE_ENV !== "production") {
8573
+ console.warn(`[AgentWorkspaceComposer] ${message}`);
8574
+ }
8575
+ }
8576
+ var LINE_HEIGHT_PX2 = 20;
8577
+ var VERTICAL_PADDING_PX2 = 16;
8578
+ function AgentWorkspaceComposer({
8579
+ value: valueProp,
8580
+ onChange,
8581
+ onSubmit,
8582
+ loading: loadingProp,
8583
+ disabled = false,
8584
+ placeholder = "Ask anything\u2026",
8585
+ onAttach,
8586
+ leftActions,
8587
+ minRows = 1,
8588
+ maxRows = 6,
8589
+ autoFocus = false,
8590
+ className,
8591
+ inputClassName
8592
+ }) {
8593
+ const agent = useNativeAgentOptional();
8594
+ const workspace = useAgentWorkspaceOptional();
8595
+ const [draft, setDraft] = React4.useState("");
8596
+ const textareaRef = React4.useRef(null);
8597
+ const propsControlEditing = valueProp !== void 0 || onChange !== void 0;
8598
+ const value = propsControlEditing ? valueProp ?? "" : agent ? agent.input : draft;
8599
+ const handleChange = propsControlEditing ? onChange ?? noop2 : agent ? agent.setInput : setDraft;
8600
+ const loading = loadingProp ?? agent?.isResponding ?? false;
8601
+ const resize = React4.useCallback(() => {
8602
+ const el = textareaRef.current;
8603
+ if (!el) return;
8604
+ el.style.height = "auto";
8605
+ const maxHeight = maxRows * LINE_HEIGHT_PX2 + VERTICAL_PADDING_PX2;
8606
+ const minHeight = minRows * LINE_HEIGHT_PX2 + VERTICAL_PADDING_PX2;
8607
+ const next = Math.min(Math.max(el.scrollHeight, minHeight), maxHeight);
8608
+ el.style.height = `${next}px`;
8609
+ el.style.overflowY = el.scrollHeight > maxHeight ? "auto" : "hidden";
8610
+ }, [maxRows, minRows]);
8611
+ React4.useLayoutEffect(() => {
8612
+ resize();
8613
+ }, [value, resize]);
8614
+ const handleSubmit = React4.useCallback(
8615
+ (e) => {
8616
+ e?.preventDefault();
8617
+ if (!value.trim() || disabled || loading) return;
8618
+ workspace?.openConversation();
8619
+ if (onSubmit) {
8620
+ onSubmit(value);
8621
+ return;
8622
+ }
8623
+ if (!propsControlEditing && agent) {
8624
+ agent.submit();
8625
+ return;
8626
+ }
8627
+ warnDev2(
8628
+ "submit was ignored: provide `onSubmit`, or render inside a <NativeAgentProvider>."
8629
+ );
8630
+ },
8631
+ [value, disabled, loading, workspace, onSubmit, propsControlEditing, agent]
8632
+ );
8633
+ const handleKeyDown = React4.useCallback(
8634
+ (e) => {
8635
+ if (e.key === "Enter" && !e.shiftKey) {
8636
+ e.preventDefault();
8637
+ handleSubmit();
8638
+ }
8639
+ },
8640
+ [handleSubmit]
8641
+ );
8642
+ const attach = leftActions ?? (onAttach ? /* @__PURE__ */ jsxRuntime.jsx(
8643
+ "button",
8644
+ {
8645
+ type: "button",
8646
+ onClick: onAttach,
8647
+ "aria-label": "Attach",
8648
+ className: "flex size-9 shrink-0 items-center justify-center rounded-xl text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground",
8649
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { className: "size-4" })
8650
+ }
8651
+ ) : null);
8652
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8653
+ "form",
8654
+ {
8655
+ onSubmit: handleSubmit,
8656
+ className: cn(
8657
+ "flex items-end gap-2 rounded-2xl border border-border bg-background p-2 shadow-sm transition-colors focus-within:border-foreground/30",
8658
+ className
8659
+ ),
8660
+ children: [
8661
+ attach,
8662
+ /* @__PURE__ */ jsxRuntime.jsx(
8663
+ "textarea",
8664
+ {
8665
+ ref: textareaRef,
8666
+ value,
8667
+ onChange: (e) => handleChange(e.target.value),
8668
+ onKeyDown: handleKeyDown,
8669
+ placeholder,
8670
+ disabled,
8671
+ autoFocus,
8672
+ rows: minRows,
8673
+ className: cn(
8674
+ "flex-1 resize-none border-0 bg-transparent px-1 py-2 text-sm leading-5 shadow-none outline-none",
8675
+ "placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0",
8676
+ "disabled:cursor-not-allowed disabled:opacity-50",
8677
+ inputClassName
8678
+ )
8679
+ }
8680
+ ),
8681
+ /* @__PURE__ */ jsxRuntime.jsx(
8682
+ "button",
8683
+ {
8684
+ type: "submit",
8685
+ "aria-label": "Send",
8686
+ disabled: !value.trim() || disabled || loading,
8687
+ className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground transition-opacity disabled:opacity-30",
8688
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "size-4" })
8689
+ }
8690
+ )
8691
+ ]
8692
+ }
8693
+ );
8694
+ }
8695
+ function AgentWorkspacePanelToggle({
8696
+ side,
8697
+ open: openProp,
8698
+ onToggle,
8699
+ className
8700
+ }) {
8701
+ const workspace = useAgentWorkspaceOptional();
8702
+ const propsControlled = openProp !== void 0 || onToggle !== void 0;
8703
+ if (!propsControlled && workspace) {
8704
+ const hasPanel = side === "left" ? workspace.hasLeftPanel : workspace.hasRightPanel;
8705
+ if (!hasPanel) return null;
8706
+ }
8707
+ const open = propsControlled ? openProp ?? false : side === "left" ? workspace?.leftPanelOpen ?? false : workspace?.rightPanelOpen ?? false;
8708
+ const handleToggle = propsControlled ? onToggle : side === "left" ? workspace?.toggleLeftPanel : workspace?.toggleRightPanel;
8709
+ const Icon = side === "left" ? lucideReact.PanelLeft : lucideReact.PanelRight;
8710
+ return /* @__PURE__ */ jsxRuntime.jsx(
8711
+ "button",
8712
+ {
8713
+ type: "button",
8714
+ onClick: handleToggle,
8715
+ "aria-label": side === "left" ? "Toggle left panel" : "Toggle right panel",
8716
+ "aria-pressed": open,
8717
+ className: cn(
8718
+ "flex size-8 items-center justify-center rounded-lg transition-colors",
8719
+ open ? "bg-secondary text-foreground" : "text-muted-foreground hover:bg-secondary",
8720
+ className
8721
+ ),
8722
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "size-4" })
8723
+ }
8724
+ );
8725
+ }
8726
+ var inertProps = (inert) => inert ? { inert: "" } : {};
8727
+ function useOpenState(controlled, defaultOpen, onChange) {
8728
+ const [internal, setInternal] = React4.useState(defaultOpen);
8729
+ const isControlled = controlled !== void 0;
8730
+ const open = isControlled ? controlled : internal;
8731
+ const onChangeRef = React4.useRef(onChange);
8732
+ React4.useEffect(() => {
8733
+ onChangeRef.current = onChange;
8734
+ }, [onChange]);
8735
+ const setOpen = React4.useCallback(
8736
+ (next) => {
8737
+ if (!isControlled) setInternal(next);
8738
+ onChangeRef.current?.(next);
8739
+ },
8740
+ [isControlled]
8741
+ );
8742
+ return [open, setOpen];
8743
+ }
8744
+ function AgentWorkspace({
8745
+ children,
8746
+ leftPanel,
8747
+ rightPanel,
8748
+ leftPanelWidth = 320,
8749
+ rightPanelWidth = 460,
8750
+ defaultLeftPanelOpen = true,
8751
+ defaultRightPanelOpen = true,
8752
+ leftPanelOpen: leftPanelOpenProp,
8753
+ rightPanelOpen: rightPanelOpenProp,
8754
+ onLeftPanelOpenChange,
8755
+ onRightPanelOpenChange,
8756
+ showPanelToggles = true,
8757
+ conversation,
8758
+ conversationOpen: conversationOpenProp,
8759
+ onConversationOpenChange,
8760
+ conversationTitle = "AI Assistant",
8761
+ showConversationHeader = true,
8762
+ composer = true,
8763
+ composerPlaceholder,
8764
+ composerHint,
8765
+ onComposerSubmit,
8766
+ className,
8767
+ contentClassName,
8768
+ conversationClassName,
8769
+ leftPanelClassName,
8770
+ rightPanelClassName,
8771
+ composerClassName
8772
+ }) {
8773
+ const agent = useNativeAgentOptional();
8774
+ const hasLeftPanel = leftPanel !== void 0 && leftPanel !== null;
8775
+ const hasRightPanel = rightPanel !== void 0 && rightPanel !== null;
8776
+ const [leftOpen, setLeftOpen] = useOpenState(
8777
+ leftPanelOpenProp,
8778
+ defaultLeftPanelOpen,
8779
+ onLeftPanelOpenChange
8780
+ );
8781
+ const [rightOpen, setRightOpen] = useOpenState(
8782
+ rightPanelOpenProp,
8783
+ defaultRightPanelOpen,
8784
+ onRightPanelOpenChange
8785
+ );
8786
+ const [conversationOpen, setConversationOpen] = useOpenState(
8787
+ conversationOpenProp,
8788
+ false,
8789
+ onConversationOpenChange
8790
+ );
8791
+ const isActive = agent?.isActive ?? false;
8792
+ const wasActiveRef = React4.useRef(false);
8793
+ React4.useEffect(() => {
8794
+ if (isActive !== wasActiveRef.current) {
8795
+ wasActiveRef.current = isActive;
8796
+ setConversationOpen(isActive);
8797
+ }
8798
+ }, [isActive, setConversationOpen]);
8799
+ const value = React4.useMemo(
8800
+ () => ({
8801
+ hasLeftPanel,
8802
+ hasRightPanel,
8803
+ leftPanelOpen: leftOpen,
8804
+ rightPanelOpen: rightOpen,
8805
+ setLeftPanelOpen: setLeftOpen,
8806
+ setRightPanelOpen: setRightOpen,
8807
+ toggleLeftPanel: () => setLeftOpen(!leftOpen),
8808
+ toggleRightPanel: () => setRightOpen(!rightOpen),
8809
+ conversationOpen,
8810
+ setConversationOpen,
8811
+ openConversation: () => setConversationOpen(true),
8812
+ closeConversation: () => setConversationOpen(false)
8813
+ }),
8814
+ [
8815
+ hasLeftPanel,
8816
+ hasRightPanel,
8817
+ leftOpen,
8818
+ rightOpen,
8819
+ setLeftOpen,
8820
+ setRightOpen,
8821
+ conversationOpen,
8822
+ setConversationOpen
8823
+ ]
8824
+ );
8825
+ const showDock = composer !== false;
8826
+ const dockNode = composer === true || composer === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
8827
+ AgentWorkspaceComposer,
8828
+ {
8829
+ placeholder: composerPlaceholder,
8830
+ onSubmit: onComposerSubmit
8831
+ }
8832
+ ) : composer;
8833
+ const statusLine = agent ? agent.error ?? agent.statusLabel : null;
8834
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentWorkspaceContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsxs(
8835
+ "div",
8836
+ {
8837
+ "data-conversation-open": conversationOpen || void 0,
8838
+ className: cn(
8839
+ "flex h-full w-full overflow-hidden bg-background text-foreground",
8840
+ className
8841
+ ),
8842
+ children: [
8843
+ hasLeftPanel && /* @__PURE__ */ jsxRuntime.jsx(
8844
+ "aside",
8845
+ {
8846
+ "data-state": leftOpen ? "open" : "collapsed",
8847
+ "aria-hidden": !leftOpen || void 0,
8848
+ className: cn(
8849
+ "relative hidden h-full shrink-0 overflow-hidden border-r border-border transition-[width] duration-300 ease-in-out lg:block",
8850
+ !leftOpen && "border-r-0",
8851
+ leftPanelClassName
8852
+ ),
8853
+ style: { width: leftOpen ? leftPanelWidth : 0 },
8854
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full", style: { width: leftPanelWidth }, children: leftPanel })
8855
+ }
8856
+ ),
8857
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-full min-w-0 grow flex-col", children: [
8858
+ showPanelToggles && hasLeftPanel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-3 z-30 hidden lg:block", children: /* @__PURE__ */ jsxRuntime.jsx(
8859
+ AgentWorkspacePanelToggle,
8860
+ {
8861
+ side: "left",
8862
+ className: "border border-border/60 bg-background/80 shadow-sm backdrop-blur"
8863
+ }
8864
+ ) }),
8865
+ showPanelToggles && hasRightPanel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 top-3 z-30 hidden lg:block", children: /* @__PURE__ */ jsxRuntime.jsx(
8866
+ AgentWorkspacePanelToggle,
8867
+ {
8868
+ side: "right",
8869
+ className: "border border-border/60 bg-background/80 shadow-sm backdrop-blur"
8870
+ }
8871
+ ) }),
8872
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-h-0 grow", children: [
8873
+ /* @__PURE__ */ jsxRuntime.jsx(
8874
+ "div",
8875
+ {
8876
+ "aria-hidden": conversationOpen || void 0,
8877
+ ...inertProps(conversationOpen),
8878
+ className: cn("h-full overflow-y-auto", contentClassName),
8879
+ children
8880
+ }
8881
+ ),
8882
+ /* @__PURE__ */ jsxRuntime.jsxs(
8883
+ "div",
8884
+ {
8885
+ "data-state": conversationOpen ? "open" : "closed",
8886
+ "aria-hidden": !conversationOpen || void 0,
8887
+ ...inertProps(!conversationOpen),
8888
+ className: cn(
8889
+ "absolute inset-0 z-20 flex flex-col bg-background transition-[opacity,transform] duration-300 ease-out",
8890
+ conversationOpen ? "translate-y-0 opacity-100" : "pointer-events-none translate-y-8 opacity-0",
8891
+ conversationClassName
8892
+ ),
8893
+ children: [
8894
+ showConversationHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center justify-between gap-3 border-b border-border bg-background px-4 py-2.5", children: [
8895
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
8896
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-7 shrink-0 items-center justify-center rounded-md bg-primary text-primary-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-3.5" }) }),
8897
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
8898
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-medium", children: conversationTitle }),
8899
+ statusLine && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-muted-foreground", children: statusLine })
8900
+ ] })
8901
+ ] }),
8902
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
8903
+ (hasLeftPanel || hasRightPanel) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mr-1 hidden items-center gap-1 border-r border-border pr-2 lg:flex", children: [
8904
+ /* @__PURE__ */ jsxRuntime.jsx(AgentWorkspacePanelToggle, { side: "left" }),
8905
+ /* @__PURE__ */ jsxRuntime.jsx(AgentWorkspacePanelToggle, { side: "right" })
8906
+ ] }),
8907
+ agent && /* @__PURE__ */ jsxRuntime.jsx(
8908
+ "button",
8909
+ {
8910
+ type: "button",
8911
+ onClick: () => agent.reset(),
8912
+ "aria-label": "Start a new conversation",
8913
+ title: "New conversation",
8914
+ className: "flex size-8 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground",
8915
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "size-4" })
8916
+ }
8917
+ ),
8918
+ /* @__PURE__ */ jsxRuntime.jsx(
8919
+ "button",
8920
+ {
8921
+ type: "button",
8922
+ onClick: () => setConversationOpen(false),
8923
+ "aria-label": "Hide conversation",
8924
+ title: "Hide conversation",
8925
+ className: "flex size-8 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground",
8926
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" })
8927
+ }
8928
+ )
8929
+ ] })
8930
+ ] }),
8931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 grow", children: conversation ?? /* @__PURE__ */ jsxRuntime.jsx(
8932
+ AgentConversation,
8933
+ {
8934
+ contentClassName: "mx-auto w-full max-w-3xl",
8935
+ showAvatars: true
8936
+ }
8937
+ ) })
8938
+ ]
8939
+ }
8940
+ )
8941
+ ] }),
8942
+ showDock && /* @__PURE__ */ jsxRuntime.jsx(
8943
+ "div",
8944
+ {
8945
+ className: cn(
8946
+ "relative z-30 shrink-0 border-t border-border bg-background/80 px-4 py-3 backdrop-blur",
8947
+ composerClassName
8948
+ ),
8949
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-3xl", children: [
8950
+ isActive && !conversationOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
8951
+ "button",
8952
+ {
8953
+ type: "button",
8954
+ onClick: () => setConversationOpen(true),
8955
+ className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-2.5 py-1 text-xs text-muted-foreground transition-colors hover:border-foreground/20 hover:text-foreground",
8956
+ children: [
8957
+ agent?.isResponding ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-3" }),
8958
+ "View conversation"
8959
+ ]
8960
+ }
8961
+ ) }),
8962
+ dockNode,
8963
+ composerHint && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-center text-[11px] text-muted-foreground", children: composerHint })
8964
+ ] })
8965
+ }
8966
+ )
8967
+ ] }),
8968
+ hasRightPanel && /* @__PURE__ */ jsxRuntime.jsx(
8969
+ "aside",
8970
+ {
8971
+ "data-state": rightOpen ? "open" : "collapsed",
8972
+ "aria-hidden": !rightOpen || void 0,
8973
+ className: cn(
8974
+ "relative hidden h-full shrink-0 overflow-hidden border-l border-border transition-[width] duration-300 ease-in-out lg:block",
8975
+ !rightOpen && "border-l-0",
8976
+ rightPanelClassName
8977
+ ),
8978
+ style: { width: rightOpen ? rightPanelWidth : 0 },
8979
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full", style: { width: rightPanelWidth }, children: rightPanel })
8980
+ }
8981
+ )
8982
+ ]
8983
+ }
8984
+ ) });
8985
+ }
8555
8986
 
8556
8987
  exports.AgentAvatar = AgentAvatar;
8557
8988
  exports.AgentComposer = AgentComposer;
@@ -8559,6 +8990,9 @@ exports.AgentConversation = AgentConversation;
8559
8990
  exports.AgentHandoff = AgentHandoff;
8560
8991
  exports.AgentProvider = AgentProvider;
8561
8992
  exports.AgentSurface = AgentSurface;
8993
+ exports.AgentWorkspace = AgentWorkspace;
8994
+ exports.AgentWorkspaceComposer = AgentWorkspaceComposer;
8995
+ exports.AgentWorkspacePanelToggle = AgentWorkspacePanelToggle;
8562
8996
  exports.AllocationBreakdown = AllocationBreakdown;
8563
8997
  exports.AnalyticsDashboard = AnalyticsDashboard;
8564
8998
  exports.Avatar = Avatar;
@@ -8672,6 +9106,8 @@ exports.useAgentBackend = useAgentBackend;
8672
9106
  exports.useAgentInput = useAgentInput;
8673
9107
  exports.useAgentLayout = useAgentLayout;
8674
9108
  exports.useAgentMessages = useAgentMessages;
9109
+ exports.useAgentWorkspace = useAgentWorkspace;
9110
+ exports.useAgentWorkspaceOptional = useAgentWorkspaceOptional;
8675
9111
  exports.useNativeAgent = useNativeAgent;
8676
9112
  exports.useNativeAgentOptional = useNativeAgentOptional;
8677
9113
  exports.useSemanticBuilder = useSemanticBuilder;