@iloveagents/foundry-web-ui 0.3.0 → 0.4.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 (223) hide show
  1. package/README.md +14 -5
  2. package/dist/components/ag-ui-runtime-provider.d.ts +64 -0
  3. package/dist/components/ag-ui-runtime-provider.js +71 -0
  4. package/dist/components/app-brand.d.ts +6 -0
  5. package/dist/components/app-brand.js +13 -0
  6. package/dist/components/assistant-chat.d.ts +26 -0
  7. package/dist/components/assistant-chat.js +93 -0
  8. package/dist/components/chat-attachments.d.ts +25 -0
  9. package/dist/components/chat-attachments.js +20 -0
  10. package/dist/components/chat-bubble.d.ts +1 -0
  11. package/dist/components/chat-bubble.js +103 -0
  12. package/dist/components/chat-header.d.ts +2 -0
  13. package/dist/components/chat-header.js +16 -0
  14. package/dist/components/client-tool-executor.d.ts +12 -0
  15. package/dist/components/client-tool-executor.js +108 -0
  16. package/dist/components/collection-empty-state.d.ts +9 -0
  17. package/dist/components/collection-empty-state.js +6 -0
  18. package/dist/components/collection-filter-bar.d.ts +19 -0
  19. package/dist/components/collection-filter-bar.js +28 -0
  20. package/dist/components/collection-search-input.d.ts +6 -0
  21. package/dist/components/collection-search-input.js +8 -0
  22. package/dist/components/collection-skeleton.d.ts +6 -0
  23. package/dist/components/collection-skeleton.js +10 -0
  24. package/dist/components/collection-sort-menu.d.ts +10 -0
  25. package/dist/components/collection-sort-menu.js +9 -0
  26. package/dist/components/collection-surface.d.ts +8 -0
  27. package/dist/components/collection-surface.js +5 -0
  28. package/dist/components/collection-toolbar.d.ts +9 -0
  29. package/dist/components/collection-toolbar.js +5 -0
  30. package/dist/components/collection-view-toggle.d.ts +7 -0
  31. package/dist/components/collection-view-toggle.js +17 -0
  32. package/dist/components/composer-submit-bridge.d.ts +1 -0
  33. package/dist/components/composer-submit-bridge.js +15 -0
  34. package/dist/components/confirm-dialog.d.ts +11 -0
  35. package/dist/components/confirm-dialog.js +6 -0
  36. package/dist/components/confirmation-card.d.ts +14 -0
  37. package/dist/components/confirmation-card.js +12 -0
  38. package/dist/components/context-badges.d.ts +16 -0
  39. package/dist/components/context-badges.js +56 -0
  40. package/dist/components/context-bar.d.ts +41 -0
  41. package/dist/components/context-bar.js +123 -0
  42. package/dist/components/form-dialog.d.ts +12 -0
  43. package/dist/components/form-dialog.js +13 -0
  44. package/dist/components/global-selection-popover.d.ts +7 -0
  45. package/dist/components/global-selection-popover.js +167 -0
  46. package/dist/components/infinite-scroll-sentinel.d.ts +6 -0
  47. package/dist/components/infinite-scroll-sentinel.js +25 -0
  48. package/dist/components/json-viewer.d.ts +10 -0
  49. package/dist/components/json-viewer.js +80 -0
  50. package/dist/components/loading-indicator.d.ts +4 -0
  51. package/dist/components/loading-indicator.js +22 -0
  52. package/dist/components/markdown-text.d.ts +13 -0
  53. package/dist/components/markdown-text.js +221 -0
  54. package/dist/components/name-dialog.d.ts +16 -0
  55. package/dist/components/name-dialog.js +23 -0
  56. package/dist/components/selection-popover.d.ts +12 -0
  57. package/dist/components/selection-popover.js +111 -0
  58. package/dist/components/show-document-tool-ui.d.ts +1 -0
  59. package/dist/components/show-document-tool-ui.js +53 -0
  60. package/dist/components/sidebar.d.ts +4 -0
  61. package/dist/components/sidebar.js +904 -0
  62. package/dist/components/surface-card.d.ts +9 -0
  63. package/dist/components/surface-card.js +33 -0
  64. package/dist/components/theme-runtime-provider.d.ts +15 -0
  65. package/dist/components/theme-runtime-provider.js +48 -0
  66. package/dist/components/theme-toggle.d.ts +2 -0
  67. package/dist/components/theme-toggle.js +19 -0
  68. package/dist/components/tool-call-card.d.ts +27 -0
  69. package/dist/components/tool-call-card.js +13 -0
  70. package/dist/components/tool-fallback.d.ts +26 -0
  71. package/dist/components/tool-fallback.js +129 -0
  72. package/dist/components/tool-panel-layout.d.ts +10 -0
  73. package/dist/components/tool-panel-layout.js +12 -0
  74. package/dist/components/tool-panel.d.ts +1 -0
  75. package/dist/components/tool-panel.js +89 -0
  76. package/dist/components/tooltip-icon-button.d.ts +7 -0
  77. package/dist/components/tooltip-icon-button.js +9 -0
  78. package/dist/components/user-menu.d.ts +2 -0
  79. package/dist/components/user-menu.js +14 -0
  80. package/dist/index.d.ts +68 -0
  81. package/dist/index.js +83 -0
  82. package/dist/lib/ag-ui-adapter.d.ts +29 -0
  83. package/dist/lib/ag-ui-adapter.js +373 -0
  84. package/dist/lib/app-store.d.ts +115 -0
  85. package/dist/lib/app-store.js +199 -0
  86. package/dist/lib/attachment-adapter.d.ts +20 -0
  87. package/dist/lib/attachment-adapter.js +99 -0
  88. package/dist/lib/auth-provider.d.ts +16 -0
  89. package/dist/lib/auth-provider.js +88 -0
  90. package/dist/lib/chat-bubble-store.d.ts +30 -0
  91. package/dist/lib/chat-bubble-store.js +23 -0
  92. package/dist/lib/chat-lifecycle-store.d.ts +10 -0
  93. package/{src/lib/chat-lifecycle-store.ts → dist/lib/chat-lifecycle-store.js} +3 -13
  94. package/dist/lib/client-tools.d.ts +11 -0
  95. package/dist/lib/client-tools.js +274 -0
  96. package/dist/lib/composer-submit-store.d.ts +12 -0
  97. package/dist/lib/composer-submit-store.js +17 -0
  98. package/dist/lib/dev-store.d.ts +38 -0
  99. package/dist/lib/dev-store.js +32 -0
  100. package/dist/lib/nav-config.d.ts +159 -0
  101. package/dist/lib/nav-config.js +162 -0
  102. package/dist/lib/nav-dnd.d.ts +8 -0
  103. package/dist/lib/nav-dnd.js +9 -0
  104. package/dist/lib/nav-store.d.ts +45 -0
  105. package/dist/lib/nav-store.js +49 -0
  106. package/dist/lib/selection-context.d.ts +21 -0
  107. package/dist/lib/selection-context.js +34 -0
  108. package/dist/lib/sidebar-store.d.ts +23 -0
  109. package/dist/lib/sidebar-store.js +98 -0
  110. package/dist/lib/theme-runtime.d.ts +130 -0
  111. package/dist/lib/theme-runtime.js +479 -0
  112. package/dist/lib/theme-store.d.ts +15 -0
  113. package/dist/lib/theme-store.js +53 -0
  114. package/dist/lib/tool-panel-store.d.ts +48 -0
  115. package/dist/lib/tool-panel-store.js +69 -0
  116. package/dist/lib/use-new-conversation.d.ts +8 -0
  117. package/dist/lib/use-new-conversation.js +62 -0
  118. package/dist/lib/use-page-tools.d.ts +27 -0
  119. package/{src/lib/use-page-tools.ts → dist/lib/use-page-tools.js} +11 -13
  120. package/dist/styles.css +142 -0
  121. package/dist/ui/collapsible.d.ts +5 -0
  122. package/{src/ui/collapsible.tsx → dist/ui/collapsible.js} +0 -2
  123. package/dist/ui/dialog.d.ts +15 -0
  124. package/dist/ui/dialog.js +25 -0
  125. package/dist/ui/dropdown-menu.d.ts +7 -0
  126. package/dist/ui/dropdown-menu.js +19 -0
  127. package/dist/ui/popover.d.ts +7 -0
  128. package/dist/ui/popover.js +10 -0
  129. package/dist/ui/select.d.ts +4 -0
  130. package/dist/ui/select.js +9 -0
  131. package/dist/ui/tooltip.d.ts +7 -0
  132. package/dist/ui/tooltip.js +10 -0
  133. package/package.json +31 -12
  134. package/AGENTS.md +0 -59
  135. package/CHANGELOG.md +0 -203
  136. package/CLAUDE.md +0 -1
  137. package/src/__tests__/no-spaces-imports.test.ts +0 -59
  138. package/src/__tests__/open-core-guards.test.ts +0 -307
  139. package/src/__tests__/theme-runtime.test.ts +0 -81
  140. package/src/__tests__/tool-fallback.test.tsx +0 -109
  141. package/src/components/__tests__/context-bar.test.ts +0 -112
  142. package/src/components/ag-ui-runtime-provider.tsx +0 -170
  143. package/src/components/app-brand.tsx +0 -38
  144. package/src/components/assistant-chat.tsx +0 -461
  145. package/src/components/chat-attachments.tsx +0 -68
  146. package/src/components/chat-bubble.tsx +0 -373
  147. package/src/components/chat-header.tsx +0 -44
  148. package/src/components/client-tool-executor.tsx +0 -230
  149. package/src/components/collection-empty-state.tsx +0 -37
  150. package/src/components/collection-filter-bar.tsx +0 -168
  151. package/src/components/collection-search-input.tsx +0 -41
  152. package/src/components/collection-skeleton.tsx +0 -55
  153. package/src/components/collection-sort-menu.tsx +0 -62
  154. package/src/components/collection-surface.tsx +0 -46
  155. package/src/components/collection-toolbar.tsx +0 -33
  156. package/src/components/collection-view-toggle.tsx +0 -61
  157. package/src/components/composer-submit-bridge.tsx +0 -19
  158. package/src/components/confirm-dialog.tsx +0 -49
  159. package/src/components/confirmation-card.tsx +0 -32
  160. package/src/components/context-badges.tsx +0 -136
  161. package/src/components/context-bar.tsx +0 -238
  162. package/src/components/form-dialog.tsx +0 -56
  163. package/src/components/global-selection-popover.tsx +0 -266
  164. package/src/components/infinite-scroll-sentinel.tsx +0 -48
  165. package/src/components/json-viewer.tsx +0 -232
  166. package/src/components/loading-indicator.tsx +0 -40
  167. package/src/components/markdown-text-citations.test.tsx +0 -108
  168. package/src/components/markdown-text.tsx +0 -508
  169. package/src/components/name-dialog.tsx +0 -87
  170. package/src/components/selection-popover.tsx +0 -156
  171. package/src/components/show-document-tool-ui.tsx +0 -90
  172. package/src/components/sidebar.test.tsx +0 -611
  173. package/src/components/sidebar.tsx +0 -1689
  174. package/src/components/surface-card.tsx +0 -45
  175. package/src/components/theme-runtime-provider.tsx +0 -93
  176. package/src/components/theme-toggle.tsx +0 -27
  177. package/src/components/tool-call-card.tsx +0 -126
  178. package/src/components/tool-fallback.tsx +0 -169
  179. package/src/components/tool-panel-layout.tsx +0 -36
  180. package/src/components/tool-panel.tsx +0 -233
  181. package/src/components/tooltip-icon-button.tsx +0 -28
  182. package/src/components/user-menu.tsx +0 -60
  183. package/src/index.ts +0 -185
  184. package/src/lib/__tests__/ag-ui-adapter.test.ts +0 -273
  185. package/src/lib/__tests__/app-store.test.ts +0 -405
  186. package/src/lib/__tests__/attachment-adapter.test.ts +0 -48
  187. package/src/lib/__tests__/chat-bubble-store.test.ts +0 -67
  188. package/src/lib/__tests__/client-tools.test.ts +0 -124
  189. package/src/lib/__tests__/dev-store.test.ts +0 -78
  190. package/src/lib/__tests__/nav-config.test.ts +0 -135
  191. package/src/lib/__tests__/nav-dnd.test.ts +0 -24
  192. package/src/lib/__tests__/nav-store.test.ts +0 -59
  193. package/src/lib/__tests__/selection-context.test.ts +0 -114
  194. package/src/lib/__tests__/sidebar-store.test.ts +0 -144
  195. package/src/lib/__tests__/theme-store.test.ts +0 -83
  196. package/src/lib/__tests__/tool-panel-store.test.ts +0 -61
  197. package/src/lib/__tests__/use-page-context.test.ts +0 -58
  198. package/src/lib/ag-ui-adapter.ts +0 -412
  199. package/src/lib/app-store.ts +0 -361
  200. package/src/lib/attachment-adapter.ts +0 -92
  201. package/src/lib/auth-provider.tsx +0 -144
  202. package/src/lib/chat-bubble-store.ts +0 -46
  203. package/src/lib/client-tools.ts +0 -293
  204. package/src/lib/composer-submit-store.ts +0 -32
  205. package/src/lib/dev-store.ts +0 -69
  206. package/src/lib/nav-config.ts +0 -329
  207. package/src/lib/nav-dnd.ts +0 -14
  208. package/src/lib/nav-store.ts +0 -89
  209. package/src/lib/selection-context.ts +0 -65
  210. package/src/lib/sidebar-store.ts +0 -113
  211. package/src/lib/theme-runtime.ts +0 -660
  212. package/src/lib/theme-store.ts +0 -67
  213. package/src/lib/tool-panel-store.ts +0 -121
  214. package/src/lib/use-new-conversation.test.tsx +0 -168
  215. package/src/lib/use-new-conversation.ts +0 -64
  216. package/src/ui/dialog.tsx +0 -109
  217. package/src/ui/dropdown-menu.tsx +0 -75
  218. package/src/ui/popover.tsx +0 -34
  219. package/src/ui/select.tsx +0 -15
  220. package/src/ui/tooltip.tsx +0 -30
  221. package/src/vite-env.d.ts +0 -1
  222. package/tsconfig.json +0 -16
  223. package/vitest.config.ts +0 -8
@@ -0,0 +1,9 @@
1
+ import { type VariantProps } from "class-variance-authority";
2
+ import type { ComponentPropsWithoutRef } from "react";
3
+ declare const surfaceCardVariants: (props?: ({
4
+ tone?: "default" | "muted" | "empty" | "subtle" | null | undefined;
5
+ radius?: "lg" | "md" | "xl" | null | undefined;
6
+ padding?: "sm" | "lg" | "md" | "xl" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ export declare function SurfaceCard({ className, tone, radius, padding, ...props }: ComponentPropsWithoutRef<"div"> & VariantProps<typeof surfaceCardVariants>): import("react/jsx-runtime").JSX.Element;
9
+ export { surfaceCardVariants };
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cva } from "class-variance-authority";
3
+ import { cn } from "@iloveagents/foundry-web-primitives";
4
+ const surfaceCardVariants = cva("border border-border shadow-sm", {
5
+ variants: {
6
+ tone: {
7
+ default: "bg-card",
8
+ subtle: "bg-background/80",
9
+ muted: "bg-muted/10",
10
+ empty: "border-dashed bg-muted/10 text-sm text-muted-foreground",
11
+ },
12
+ radius: {
13
+ md: "rounded-xl",
14
+ lg: "rounded-[1.5rem]",
15
+ xl: "rounded-[2rem]",
16
+ },
17
+ padding: {
18
+ sm: "p-4",
19
+ md: "p-5",
20
+ lg: "p-6",
21
+ xl: "p-7",
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ tone: "default",
26
+ radius: "lg",
27
+ padding: "md",
28
+ },
29
+ });
30
+ export function SurfaceCard({ className, tone, radius, padding, ...props }) {
31
+ return (_jsx("div", { className: cn(surfaceCardVariants({ tone, radius, padding }), className), ...props }));
32
+ }
33
+ export { surfaceCardVariants };
@@ -0,0 +1,15 @@
1
+ import { type CSSProperties, type ReactNode } from "react";
2
+ import type { ThemeMode } from "../lib/theme-store.js";
3
+ import { type ResolvedThemeRuntime, type ThemeLayer } from "../lib/theme-runtime.js";
4
+ export declare function ThemeRuntimeProvider({ layers, mode, children, }: {
5
+ layers: ThemeLayer[];
6
+ mode: ThemeMode;
7
+ children: ReactNode;
8
+ }): import("react/jsx-runtime").JSX.Element;
9
+ export declare function useThemeRuntime(): ResolvedThemeRuntime;
10
+ export declare function ThemeScope({ children, className, style, }: {
11
+ children: ReactNode;
12
+ className?: string;
13
+ style?: CSSProperties;
14
+ }): import("react/jsx-runtime").JSX.Element;
15
+ export declare function ThemeDocumentMetadata(): null;
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useMemo, useRef, useState, } from "react";
3
+ import { resolveThemeRuntime, } from "../lib/theme-runtime.js";
4
+ const ThemeRuntimeContext = createContext(null);
5
+ export function ThemeRuntimeProvider({ layers, mode, children, }) {
6
+ const fallback = useRef(resolveThemeRuntime([], "system"));
7
+ const [systemPrefersDark, setSystemPrefersDark] = useState(() => typeof window !== "undefined"
8
+ ? window.matchMedia("(prefers-color-scheme: dark)").matches
9
+ : false);
10
+ useEffect(() => {
11
+ if (mode !== "system" || typeof window === "undefined")
12
+ return;
13
+ const media = window.matchMedia("(prefers-color-scheme: dark)");
14
+ const handleChange = (event) => {
15
+ setSystemPrefersDark(event.matches);
16
+ };
17
+ setSystemPrefersDark(media.matches);
18
+ media.addEventListener("change", handleChange);
19
+ return () => media.removeEventListener("change", handleChange);
20
+ }, [mode]);
21
+ const runtime = useMemo(() => {
22
+ try {
23
+ const next = resolveThemeRuntime(layers, mode);
24
+ fallback.current = next;
25
+ return next;
26
+ }
27
+ catch {
28
+ return fallback.current;
29
+ }
30
+ }, [layers, mode, systemPrefersDark]);
31
+ return _jsx(ThemeRuntimeContext.Provider, { value: runtime, children: children });
32
+ }
33
+ export function useThemeRuntime() {
34
+ return useContext(ThemeRuntimeContext) ?? resolveThemeRuntime([], "system");
35
+ }
36
+ export function ThemeScope({ children, className, style, }) {
37
+ const runtime = useThemeRuntime();
38
+ return (_jsx("div", { className: className, style: { ...runtime.variables, fontFamily: "var(--font-body)", ...style }, children: children }));
39
+ }
40
+ export function ThemeDocumentMetadata() {
41
+ const runtime = useThemeRuntime();
42
+ useEffect(() => {
43
+ if (typeof document === "undefined")
44
+ return;
45
+ document.title = runtime.branding.appTitle || runtime.branding.appName || "Foundry UI";
46
+ }, [runtime.branding.appName, runtime.branding.appTitle]);
47
+ return null;
48
+ }
@@ -0,0 +1,2 @@
1
+ import { type FC } from "react";
2
+ export declare const ThemeToggle: FC;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Sun, Moon, Monitor } from "lucide-react";
3
+ import { TooltipIconButton } from "./tooltip-icon-button.js";
4
+ import { useThemeStore } from "../lib/theme-store.js";
5
+ const icons = {
6
+ light: Sun,
7
+ dark: Moon,
8
+ system: Monitor,
9
+ };
10
+ const labels = {
11
+ light: "Light mode",
12
+ dark: "Dark mode",
13
+ system: "System theme",
14
+ };
15
+ export const ThemeToggle = () => {
16
+ const { mode, cycle } = useThemeStore();
17
+ const Icon = icons[mode];
18
+ return (_jsx(TooltipIconButton, { tooltip: labels[mode], size: "icon", onClick: cycle, children: _jsx(Icon, { className: "size-4 text-primary" }) }));
19
+ };
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from "react";
2
+ export type ToolCallStatus = {
3
+ type: "running";
4
+ } | {
5
+ type: "complete";
6
+ } | {
7
+ type: "incomplete";
8
+ reason?: string;
9
+ } | {
10
+ type: "requires-action";
11
+ reason?: string;
12
+ };
13
+ interface ToolCallCardProps {
14
+ icon?: ReactNode;
15
+ title: string;
16
+ description?: string;
17
+ status: ToolCallStatus;
18
+ action?: {
19
+ label: string;
20
+ onClick: () => void;
21
+ disabled?: boolean;
22
+ };
23
+ children?: ReactNode;
24
+ className?: string;
25
+ }
26
+ export declare function ToolCallCard({ icon, title, description, status, action, children, className, }: ToolCallCardProps): import("react/jsx-runtime").JSX.Element;
27
+ export {};
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Loader2, CheckCircle2, XCircle, AlertCircle, ChevronDown } from "lucide-react";
3
+ import { cn } from "@iloveagents/foundry-web-primitives";
4
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../ui/collapsible.js";
5
+ import { useState } from "react";
6
+ export function ToolCallCard({ icon, title, description, status, action, children, className, }) {
7
+ const [isOpen, setIsOpen] = useState(false);
8
+ const isSuccess = status.type === "complete";
9
+ const isError = status.type === "incomplete" && status.reason === "error";
10
+ const isRunning = status.type === "running";
11
+ const requiresAction = status.type === "requires-action";
12
+ return (_jsx(Collapsible, { open: isOpen, onOpenChange: setIsOpen, className: className, children: _jsxs("div", { className: cn("flex items-start gap-3 p-3 rounded-lg border", "bg-muted/50 text-sm transition-colors", isSuccess && "border-primary/30 bg-primary/5", isError && "border-destructive/30 bg-destructive/5", requiresAction && "border-primary/30 bg-primary/5"), children: [_jsxs("div", { className: "flex-shrink-0 mt-0.5", children: [isRunning && _jsx(Loader2, { className: "size-4 text-primary animate-spin" }), isSuccess && _jsx(CheckCircle2, { className: "size-4 text-primary" }), isError && _jsx(XCircle, { className: "size-4 text-destructive" }), requiresAction && _jsx(AlertCircle, { className: "size-4 text-primary" })] }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [icon && _jsx("span", { className: "text-muted-foreground", children: icon }), _jsx("span", { className: "font-medium text-foreground", children: title }), _jsxs("div", { className: "ml-auto flex items-center gap-1.5", children: [action && !isRunning && (_jsx("button", { type: "button", onClick: action.onClick, disabled: action.disabled, className: cn("h-6 px-2.5 text-xs font-medium rounded-md", "border border-primary/30 text-primary", "hover:bg-primary/10 transition-colors", "disabled:opacity-50 disabled:pointer-events-none"), children: action.label })), children && (_jsx(CollapsibleTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "p-0.5 hover:bg-muted rounded transition-colors", "aria-label": "Toggle details", children: _jsx(ChevronDown, { className: cn("size-4 text-muted-foreground transition-transform", isOpen && "rotate-180") }) }) }))] })] }), description && (_jsx("div", { className: cn("text-xs mt-0.5", isError ? "text-destructive" : "text-primary"), children: description })), children && (_jsx(CollapsibleContent, { children: _jsx("div", { className: "mt-2", children: children }) }))] })] }) }));
13
+ }
@@ -0,0 +1,26 @@
1
+ export declare const ToolFallback: (props: Record<string, unknown>) => import("react/jsx-runtime").JSX.Element;
2
+ /**
3
+ * Heuristically detect a failed tool result. The agent-framework
4
+ * adapter flattens both plain-Python and MCP tool errors into the
5
+ * same ``result`` field without a dedicated error flag, so we have
6
+ * to sniff:
7
+ *
8
+ * - MCP canonical shape: ``{isError: true, content: [...]}``
9
+ * - Python ``@tool`` exception: a string starting with ``"Error:"``
10
+ * (agent-framework's default serialization — see
11
+ * ``agent_framework/_tools.py::_serialize_tool_exception``).
12
+ * - Structured error objects: ``{error: "..."}`` or
13
+ * ``{error: {message: "..."}}`` — what FastMCP's ``ToolError``
14
+ * (re-)raises produce.
15
+ *
16
+ * Keep this narrow. A substring match on ``"Error"`` would false-
17
+ * positive on legitimate results ("…contains the word Error in a
18
+ * heading…"), so anchor patterns to prefix / explicit fields only.
19
+ */
20
+ export declare function _detectErrorResult(result: unknown): boolean;
21
+ /**
22
+ * Pull a user-readable one-liner out of an error result so the card
23
+ * header shows *why* it failed rather than the generic "Execution
24
+ * failed". Matches the shapes enumerated in ``detectErrorResult``.
25
+ */
26
+ export declare function _extractErrorMessage(result: unknown): string | null;
@@ -0,0 +1,129 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { ToolCallCard } from "./tool-call-card.js";
3
+ import { Wrench } from "lucide-react";
4
+ export const ToolFallback = (props) => {
5
+ const { toolName, args, result, part } = props;
6
+ const rawStatus = part?.status || props.status;
7
+ // Tool results that *describe* a failure (Python ``@tool`` raises an
8
+ // exception → agent-framework serializes it as an error string;
9
+ // FastMCP returns ``{isError: true, content: [...]}``; our own tools
10
+ // sometimes return a plain ``"Error: ..."`` string) arrive here with
11
+ // ``status.type === "complete"`` because the tool-call round-trip
12
+ // succeeded from the transport's point of view. Without sniffing
13
+ // the payload we'd render "Execution complete" in green for a red
14
+ // condition — exactly what the user called out. Normalize to the
15
+ // ``incomplete + reason: "error"`` state the card knows how to
16
+ // show in red with an X-circle.
17
+ const isErrorResult = _detectErrorResult(result);
18
+ const status = isErrorResult
19
+ ? { type: "incomplete", reason: "error" }
20
+ : rawStatus;
21
+ let description = "";
22
+ if (status.type === "running") {
23
+ description = `Executing ${toolName}...`;
24
+ }
25
+ else if (status.type === "incomplete" && status.reason === "error") {
26
+ description = _extractErrorMessage(result) ?? "Execution failed";
27
+ }
28
+ else if (status.type === "complete") {
29
+ description = result ? "Execution complete" : "Completed";
30
+ }
31
+ else if (status.type === "requires-action") {
32
+ description = "Waiting for execution...";
33
+ }
34
+ return (_jsxs(ToolCallCard, { icon: _jsx(Wrench, { className: "size-3.5" }), title: formatToolName(toolName), description: description, status: status, className: "w-full", children: [args && Object.keys(args).length > 0 && (_jsx("div", { className: "text-muted-foreground text-xs space-y-1", children: Object.entries(args).map(([key, value]) => (_jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [key, ":"] }), " ", _jsx("span", { className: "font-mono", children: formatValue(value) })] }, key))) })), (status.type === "complete" ||
35
+ (status.type === "incomplete" && status.reason === "error")) &&
36
+ result != null && (_jsxs("div", { className: "text-muted-foreground text-xs mt-2 pt-2 border-t border-border", children: [_jsxs("div", { className: "font-medium mb-1", children: [status.type === "incomplete" ? "Error" : "Result", ":"] }), _jsx("pre", { className: "font-mono text-xs bg-muted p-2 rounded overflow-x-auto", children: formatResult(result) })] }))] }));
37
+ };
38
+ function formatToolName(toolName) {
39
+ return toolName
40
+ .split("_")
41
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
42
+ .join(" ");
43
+ }
44
+ function formatValue(value) {
45
+ if (typeof value === "string")
46
+ return value;
47
+ if (typeof value === "number" || typeof value === "boolean")
48
+ return String(value);
49
+ return JSON.stringify(value);
50
+ }
51
+ function formatResult(result) {
52
+ if (typeof result === "string")
53
+ return result;
54
+ return JSON.stringify(result, null, 2);
55
+ }
56
+ /**
57
+ * Heuristically detect a failed tool result. The agent-framework
58
+ * adapter flattens both plain-Python and MCP tool errors into the
59
+ * same ``result`` field without a dedicated error flag, so we have
60
+ * to sniff:
61
+ *
62
+ * - MCP canonical shape: ``{isError: true, content: [...]}``
63
+ * - Python ``@tool`` exception: a string starting with ``"Error:"``
64
+ * (agent-framework's default serialization — see
65
+ * ``agent_framework/_tools.py::_serialize_tool_exception``).
66
+ * - Structured error objects: ``{error: "..."}`` or
67
+ * ``{error: {message: "..."}}`` — what FastMCP's ``ToolError``
68
+ * (re-)raises produce.
69
+ *
70
+ * Keep this narrow. A substring match on ``"Error"`` would false-
71
+ * positive on legitimate results ("…contains the word Error in a
72
+ * heading…"), so anchor patterns to prefix / explicit fields only.
73
+ */
74
+ export function _detectErrorResult(result) {
75
+ if (result == null)
76
+ return false;
77
+ if (typeof result === "string") {
78
+ // Python tools: "Error: <message>" (agent-framework default).
79
+ return /^\s*Error:\s/.test(result);
80
+ }
81
+ if (typeof result === "object") {
82
+ const obj = result;
83
+ // MCP Streamable-HTTP canonical shape.
84
+ if (obj.isError === true)
85
+ return true;
86
+ // FastMCP ToolError + some of our hand-rolled paths.
87
+ if (typeof obj.error === "string" && obj.error.length > 0)
88
+ return true;
89
+ if (obj.error &&
90
+ typeof obj.error === "object" &&
91
+ typeof obj.error.message === "string") {
92
+ return true;
93
+ }
94
+ }
95
+ return false;
96
+ }
97
+ /**
98
+ * Pull a user-readable one-liner out of an error result so the card
99
+ * header shows *why* it failed rather than the generic "Execution
100
+ * failed". Matches the shapes enumerated in ``detectErrorResult``.
101
+ */
102
+ export function _extractErrorMessage(result) {
103
+ if (typeof result === "string") {
104
+ // Strip the "Error: " prefix so the header isn't redundant.
105
+ const m = /^\s*Error:\s*(.*)$/s.exec(result);
106
+ return m ? m[1].trim() || "Execution failed" : null;
107
+ }
108
+ if (result && typeof result === "object") {
109
+ const obj = result;
110
+ if (typeof obj.error === "string")
111
+ return obj.error;
112
+ if (obj.error &&
113
+ typeof obj.error === "object" &&
114
+ typeof obj.error.message === "string") {
115
+ return obj.error.message;
116
+ }
117
+ if (Array.isArray(obj.content)) {
118
+ // MCP error: content[].text usually carries the human message.
119
+ for (const item of obj.content) {
120
+ if (item &&
121
+ typeof item === "object" &&
122
+ typeof item.text === "string") {
123
+ return item.text;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return null;
129
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Layout wrapper that adjusts main content when tool panel is open.
3
+ * - Narrow screens (< 1280px): Full-screen overlay, chat hidden
4
+ * - Wide screens (>= 1280px): Side-by-side layout, chat shifts left
5
+ */
6
+ interface ToolPanelLayoutProps {
7
+ children: React.ReactNode;
8
+ }
9
+ export declare function ToolPanelLayout({ children }: ToolPanelLayoutProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "@iloveagents/foundry-web-primitives";
3
+ import { useToolPanelStore } from "../lib/tool-panel-store.js";
4
+ import { ToolPanel } from "./tool-panel.js";
5
+ export function ToolPanelLayout({ children }) {
6
+ const isOpen = useToolPanelStore((state) => state.isOpen);
7
+ const panelWidth = useToolPanelStore((state) => state.panelWidth);
8
+ const useOverlay = useToolPanelStore((state) => state.useOverlay);
9
+ return (_jsxs("div", { className: "relative h-full flex-1 min-w-0 overflow-hidden", children: [_jsx("div", { className: cn("h-full flex flex-col transition-all duration-300 ease-in-out", useOverlay && isOpen && "hidden"), style: {
10
+ width: isOpen && !useOverlay ? `calc(100% - ${panelWidth}px)` : "100%",
11
+ }, children: children }), _jsx(ToolPanel, {})] }));
12
+ }
@@ -0,0 +1 @@
1
+ export declare function ToolPanel(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,89 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState, Suspense } from "react";
3
+ import { X, Maximize2, Minimize2, Copy, Check, Pin, PinOff, FolderOpen } from "lucide-react";
4
+ import { useNavigate } from "react-router";
5
+ import { cn } from "@iloveagents/foundry-web-primitives";
6
+ import { useToolPanelStore } from "../lib/tool-panel-store.js";
7
+ import { useAppStore } from "../lib/app-store.js";
8
+ import ReactMarkdown from "react-markdown";
9
+ import remarkGfm from "remark-gfm";
10
+ import { markdownComponents } from "./markdown-text.js";
11
+ import { SelectionPopover } from "./selection-popover.js";
12
+ /** Renders panel content using the renderer registry, then built-in markdown/text. */
13
+ function PanelContentRenderer({ content }) {
14
+ const renderers = useToolPanelStore((s) => s.renderers);
15
+ // Check registered renderers first (e.g., PDF viewer, entity pages, demo pages)
16
+ const customRenderer = renderers.find((r) => r.match(content));
17
+ if (customRenderer) {
18
+ const Component = customRenderer.component;
19
+ return (_jsx(Suspense, { fallback: null, children: _jsx(Component, { content: content }) }));
20
+ }
21
+ // Built-in markdown / text rendering
22
+ return (_jsx("div", { className: "px-6 py-4", children: content.type === "markdown" ? (_jsx("div", { className: "max-w-2xl mx-auto", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: content.content }) })) : (_jsx("div", { className: "whitespace-pre-wrap text-sm text-foreground max-w-2xl mx-auto", children: content.content })) }));
23
+ }
24
+ export function ToolPanel() {
25
+ const isOpen = useToolPanelStore((state) => state.isOpen);
26
+ const content = useToolPanelStore((state) => state.content);
27
+ const closePanel = useToolPanelStore((state) => state.closePanel);
28
+ const panelWidth = useToolPanelStore((state) => state.panelWidth);
29
+ const isFullscreen = useToolPanelStore((state) => state.isFullscreen);
30
+ const toggleFullscreen = useToolPanelStore((state) => state.toggleFullscreen);
31
+ const navigate = useNavigate();
32
+ const contentRef = useRef(null);
33
+ const [copied, setCopied] = useState(false);
34
+ // Pin state for SPACES entities
35
+ const entityId = content?.entityId;
36
+ const contextItems = useAppStore((s) => s.contextItems);
37
+ const addContextItem = useAppStore((s) => s.addContextItem);
38
+ const removeContextItem = useAppStore((s) => s.removeContextItem);
39
+ const entityPin = entityId
40
+ ? contextItems.find((i) => i.persistence === "persistent" &&
41
+ i.type === "page" &&
42
+ i.payload.kind === "page" &&
43
+ i.payload.path === `/spaces/${entityId}`)
44
+ : null;
45
+ const isEntityPinned = !!entityPin;
46
+ const handleToggleEntityPin = useCallback(() => {
47
+ if (!entityId || !content)
48
+ return;
49
+ if (entityPin) {
50
+ removeContextItem(entityPin.id);
51
+ }
52
+ else {
53
+ addContextItem({
54
+ type: "page",
55
+ label: content.title,
56
+ payload: { kind: "page", path: `/spaces/${entityId}`, label: content.title, meta: {} },
57
+ sourcePage: `/spaces/${entityId}`,
58
+ persistence: "persistent",
59
+ });
60
+ }
61
+ }, [entityId, entityPin, content, addContextItem, removeContextItem]);
62
+ const handleNavigateToEntity = useCallback(() => {
63
+ if (!entityId || !content)
64
+ return;
65
+ navigate(content.type === "page" ? content.content : `/spaces/${entityId}`);
66
+ closePanel();
67
+ }, [entityId, content, navigate, closePanel]);
68
+ const handleCopyAll = useCallback(() => {
69
+ if (!content)
70
+ return;
71
+ navigator.clipboard.writeText(content.content).then(() => {
72
+ setCopied(true);
73
+ setTimeout(() => setCopied(false), 2000);
74
+ });
75
+ }, [content]);
76
+ // Close on Escape key
77
+ useEffect(() => {
78
+ const handleEscape = (e) => {
79
+ if (e.key === "Escape" && isOpen) {
80
+ closePanel();
81
+ }
82
+ };
83
+ window.addEventListener("keydown", handleEscape);
84
+ return () => window.removeEventListener("keydown", handleEscape);
85
+ }, [isOpen, closePanel]);
86
+ if (!content)
87
+ return null;
88
+ return (_jsxs("div", { "data-tool-panel": true, className: cn("fixed top-0 right-0 z-40", "h-dvh", "bg-background border-l border-border shadow-2xl", "transition-transform duration-300 ease-in-out", "flex flex-col", isOpen ? "translate-x-0" : "translate-x-full"), style: { width: panelWidth }, children: [_jsx("div", { className: "flex-shrink-0 border-b border-border px-6 py-4", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { className: "text-lg font-semibold text-foreground truncate pr-4", children: content.title }), _jsxs("div", { className: "flex items-center gap-1", children: [entityId && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: handleToggleEntityPin, className: cn("flex items-center justify-center", "size-8 rounded-md shrink-0", "hover:bg-muted transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary", isEntityPinned && "text-primary"), "aria-label": isEntityPinned ? "Unpin document" : "Pin document", title: isEntityPinned ? "Unpin document" : "Pin document", children: isEntityPinned ? (_jsx(PinOff, { className: "size-4" })) : (_jsx(Pin, { className: "size-4 text-muted-foreground" })) }), _jsx("button", { type: "button", onClick: handleNavigateToEntity, className: cn("flex items-center justify-center", "size-8 rounded-md shrink-0", "hover:bg-muted transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary"), "aria-label": "Open in navigation", title: "Open in navigation", children: _jsx(FolderOpen, { className: "size-4 text-muted-foreground" }) })] })), _jsx("button", { type: "button", onClick: handleCopyAll, className: cn("flex items-center justify-center", "size-8 rounded-md flex-shrink-0", "hover:bg-muted transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary"), "aria-label": "Copy content", children: copied ? (_jsx(Check, { className: "size-4 text-success" })) : (_jsx(Copy, { className: "size-4 text-muted-foreground" })) }), _jsx("button", { type: "button", onClick: toggleFullscreen, className: cn("flex items-center justify-center", "size-8 rounded-md flex-shrink-0", "hover:bg-muted transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary"), "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen", children: isFullscreen ? (_jsx(Minimize2, { className: "size-4 text-muted-foreground" })) : (_jsx(Maximize2, { className: "size-4 text-muted-foreground" })) }), _jsx("button", { type: "button", onClick: closePanel, className: cn("flex items-center justify-center", "size-8 rounded-md flex-shrink-0", "hover:bg-muted transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary"), "aria-label": "Close panel", children: _jsx(X, { className: "size-5 text-muted-foreground" }) })] })] }) }), _jsxs("div", { className: "relative flex-1 overflow-y-auto", ref: contentRef, "data-testid": "tool-panel-content", children: [_jsx(PanelContentRenderer, { content: content }), _jsx(SelectionPopover, { containerRef: contentRef })] })] }));
89
+ }
@@ -0,0 +1,7 @@
1
+ import { type ComponentPropsWithRef } from "react";
2
+ import { Button } from "@iloveagents/foundry-web-primitives";
3
+ export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
4
+ tooltip: string;
5
+ side?: "top" | "bottom" | "left" | "right";
6
+ };
7
+ export declare const TooltipIconButton: import("react").ForwardRefExoticComponent<Omit<TooltipIconButtonProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { Slottable } from "@radix-ui/react-slot";
4
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js";
5
+ import { Button } from "@iloveagents/foundry-web-primitives";
6
+ export const TooltipIconButton = forwardRef(({ children, tooltip, side = "bottom", ...rest }, ref) => {
7
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "icon", ...rest, ref: ref, children: [_jsx(Slottable, { children: children }), _jsx("span", { className: "sr-only", children: tooltip })] }) }), _jsx(TooltipContent, { side: side, children: tooltip })] }));
8
+ });
9
+ TooltipIconButton.displayName = "TooltipIconButton";
@@ -0,0 +1,2 @@
1
+ import { type FC } from "react";
2
+ export declare const UserMenu: FC;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { LogOut, User } from "lucide-react";
3
+ import { useStore } from "zustand";
4
+ import { useShallow } from "zustand/react/shallow";
5
+ import { cn } from "@iloveagents/foundry-web-primitives";
6
+ import { authStore } from "@iloveagents/foundry-agent/msal";
7
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "../ui/dropdown-menu.js";
8
+ import { Button } from "@iloveagents/foundry-web-primitives";
9
+ export const UserMenu = () => {
10
+ const { user, signOut } = useStore(authStore, useShallow((s) => ({ user: s.user, signOut: s.signOut })));
11
+ if (!user)
12
+ return null;
13
+ return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", className: "gap-2 rounded-full px-2", children: [user.avatar ? (_jsx("img", { src: user.avatar, alt: user.name, className: "size-6 rounded-full" })) : (_jsx("div", { className: cn("size-6 rounded-full", "bg-primary/10 text-primary", "flex items-center justify-center"), children: _jsx(User, { className: "size-3.5" }) })), _jsx("span", { className: "text-xs text-muted-foreground hidden sm:inline", children: user.name })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [_jsx(DropdownMenuLabel, { className: "font-normal", children: _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("p", { className: "text-sm font-medium", children: user.name }), _jsx("p", { className: "text-xs text-muted-foreground", children: user.email })] }) }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: signOut, className: "text-destructive cursor-pointer", children: [_jsx(LogOut, { className: "size-4" }), "Sign out"] })] })] }));
14
+ };
@@ -0,0 +1,68 @@
1
+ export { Sidebar } from "./components/sidebar.js";
2
+ export { ToolPanel } from "./components/tool-panel.js";
3
+ export { ToolPanelLayout } from "./components/tool-panel-layout.js";
4
+ export { MarkdownText, markdownComponents } from "./components/markdown-text.js";
5
+ export { ClientToolExecutor } from "./components/client-tool-executor.js";
6
+ export { AGUIRuntimeProvider, useAGUIAdapter } from "./components/ag-ui-runtime-provider.js";
7
+ export type { AGUIChatConversationFactoryArgs, AGUIHistoryAdapterFactory, } from "./components/ag-ui-runtime-provider.js";
8
+ export { ChatContent, DEFAULT_STARTER_SUGGESTIONS } from "./components/assistant-chat.js";
9
+ export type { ChatContentProps } from "./components/assistant-chat.js";
10
+ export { ChatBubble } from "./components/chat-bubble.js";
11
+ export { ChatHeader } from "./components/chat-header.js";
12
+ export { ComposerAttachment, UserMessageAttachment, userAttachmentComponents, composerAttachmentComponents, } from "./components/chat-attachments.js";
13
+ export { ShowDocumentToolUI } from "./components/show-document-tool-ui.js";
14
+ export { ToolCallCard } from "./components/tool-call-card.js";
15
+ export type { ToolCallStatus } from "./components/tool-call-card.js";
16
+ export { ToolFallback } from "./components/tool-fallback.js";
17
+ export { ConfirmationCard } from "./components/confirmation-card.js";
18
+ export { TooltipIconButton } from "./components/tooltip-icon-button.js";
19
+ export { ComposerContextBadges, SentContextBadges } from "./components/context-badges.js";
20
+ export { ContextPins } from "./components/context-bar.js";
21
+ export { SelectionPopover } from "./components/selection-popover.js";
22
+ export { GlobalSelectionPopover } from "./components/global-selection-popover.js";
23
+ export { LoadingIndicator } from "./components/loading-indicator.js";
24
+ export { ThemeToggle } from "./components/theme-toggle.js";
25
+ export { AppBrand } from "./components/app-brand.js";
26
+ export { CollectionToolbar } from "./components/collection-toolbar.js";
27
+ export { CollectionSearchInput } from "./components/collection-search-input.js";
28
+ export { CollectionFilterBar, type CollectionFilterDefinition, type CollectionFilterOption, type CollectionFilterValue, } from "./components/collection-filter-bar.js";
29
+ export { CollectionSortMenu, type CollectionSortOption, } from "./components/collection-sort-menu.js";
30
+ export { CollectionViewToggle, type CollectionViewMode, } from "./components/collection-view-toggle.js";
31
+ export { CollectionEmptyState } from "./components/collection-empty-state.js";
32
+ export { CollectionSkeleton } from "./components/collection-skeleton.js";
33
+ export { InfiniteScrollSentinel } from "./components/infinite-scroll-sentinel.js";
34
+ export { CollectionSurface } from "./components/collection-surface.js";
35
+ export { ThemeRuntimeProvider, ThemeScope, ThemeDocumentMetadata, useThemeRuntime, } from "./components/theme-runtime-provider.js";
36
+ export { JsonViewer } from "./components/json-viewer.js";
37
+ export { UserMenu } from "./components/user-menu.js";
38
+ export { FormDialog } from "./components/form-dialog.js";
39
+ export { ConfirmDialog } from "./components/confirm-dialog.js";
40
+ export { NameDialog } from "./components/name-dialog.js";
41
+ export { SurfaceCard, surfaceCardVariants } from "./components/surface-card.js";
42
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, } from "./ui/tooltip.js";
43
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent, } from "./ui/collapsible.js";
44
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuLabel, } from "./ui/dropdown-menu.js";
45
+ export { Dialog, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, } from "./ui/dialog.js";
46
+ export { Popover, PopoverTrigger, PopoverAnchor, PopoverContent } from "./ui/popover.js";
47
+ export { Select, selectClassName } from "./ui/select.js";
48
+ export { useAppStore } from "./lib/app-store.js";
49
+ export { useNavStore, type NavFooterAction } from "./lib/nav-store.js";
50
+ export { useToolPanelStore } from "./lib/tool-panel-store.js";
51
+ export type { ToolPanelContent, PdfHighlightRef, PanelRendererEntry, } from "./lib/tool-panel-store.js";
52
+ export { useSidebarStore, SIDEBAR_WIDTH, RAIL_WIDTH } from "./lib/sidebar-store.js";
53
+ export { useChatBubbleStore } from "./lib/chat-bubble-store.js";
54
+ export { useChatLifecycleStore } from "./lib/chat-lifecycle-store.js";
55
+ export { submitComposerText } from "./lib/composer-submit-store.js";
56
+ export { registerSelectionContextResolver, resolveSelectionContext, type SelectionContextInput, type SelectionContextItem, type SelectionContextResolver, type SelectionContextResult, } from "./lib/selection-context.js";
57
+ export { useThemeStore } from "./lib/theme-store.js";
58
+ export type { ThemeMode } from "./lib/theme-store.js";
59
+ export { mergeThemeDefinitions, resolveThemeRuntime, getEffectiveThemeMode, getThemePreset, } from "./lib/theme-runtime.js";
60
+ export type { ThemeDefinition, ThemeLayer, ResolvedThemeRuntime, ThemeColorSlots, ThemeSidebarSlots, ThemeStatusSlots, ThemeChartSlots, ThemeTypographySlots, ThemeRadiusSlots, ThemeAppSlots, ThemeBranding, } from "./lib/theme-runtime.js";
61
+ export { useDevStore } from "./lib/dev-store.js";
62
+ export { DEFAULT_NAV_CONFIG, findNavItem } from "./lib/nav-config.js";
63
+ export type { NavItem, NavItemAction, NavItemDnd, NavGroup, NavGroupCreateAction, NavMatch, CollapsedRailItem, CollapsedRailContext, } from "./lib/nav-config.js";
64
+ export { usePageTools } from "./lib/use-page-tools.js";
65
+ export { useNewConversation } from "./lib/use-new-conversation.js";
66
+ export { AGUIAdapterSDK } from "./lib/ag-ui-adapter.js";
67
+ export { FileAttachmentAdapter } from "./lib/attachment-adapter.js";
68
+ export { AuthProvider } from "./lib/auth-provider.js";