@agent-native/dispatch 0.22.1 → 0.23.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 (51) hide show
  1. package/dist/components/app-icon.d.ts +2 -1
  2. package/dist/components/app-icon.d.ts.map +1 -1
  3. package/dist/components/app-icon.js +4 -2
  4. package/dist/components/app-icon.js.map +1 -1
  5. package/dist/components/app-list-row.d.ts +1 -1
  6. package/dist/components/app-list-row.d.ts.map +1 -1
  7. package/dist/components/app-list-row.js +1 -1
  8. package/dist/components/app-list-row.js.map +1 -1
  9. package/dist/components/app-open-actions.d.ts +2 -1
  10. package/dist/components/app-open-actions.d.ts.map +1 -1
  11. package/dist/components/app-open-actions.js +2 -2
  12. package/dist/components/app-open-actions.js.map +1 -1
  13. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  14. package/dist/components/dispatch-control-plane.js +16 -17
  15. package/dist/components/dispatch-control-plane.js.map +1 -1
  16. package/dist/components/layout/Layout.d.ts.map +1 -1
  17. package/dist/components/layout/Layout.js +84 -56
  18. package/dist/components/layout/Layout.js.map +1 -1
  19. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  20. package/dist/components/layout/workspace-apps-rail.js +1 -1
  21. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  22. package/dist/components/other-apps-section.d.ts +3 -1
  23. package/dist/components/other-apps-section.d.ts.map +1 -1
  24. package/dist/components/other-apps-section.js +9 -6
  25. package/dist/components/other-apps-section.js.map +1 -1
  26. package/dist/components/workspace-app-card.d.ts.map +1 -1
  27. package/dist/components/workspace-app-card.js +7 -2
  28. package/dist/components/workspace-app-card.js.map +1 -1
  29. package/dist/components/workspace-template-card.d.ts.map +1 -1
  30. package/dist/components/workspace-template-card.js +2 -5
  31. package/dist/components/workspace-template-card.js.map +1 -1
  32. package/dist/lib/overview-chat.d.ts.map +1 -1
  33. package/dist/lib/overview-chat.js +0 -8
  34. package/dist/lib/overview-chat.js.map +1 -1
  35. package/package.json +3 -3
  36. package/src/components/app-icon.tsx +6 -2
  37. package/src/components/app-list-row.tsx +1 -1
  38. package/src/components/app-open-actions.tsx +4 -2
  39. package/src/components/dispatch-control-plane.spec.tsx +43 -7
  40. package/src/components/dispatch-control-plane.tsx +56 -75
  41. package/src/components/layout/Layout.spec.tsx +46 -0
  42. package/src/components/layout/Layout.tsx +149 -84
  43. package/src/components/layout/workspace-apps-rail.tsx +1 -0
  44. package/src/components/other-apps-section.tsx +61 -40
  45. package/src/components/workspace-app-card.spec.tsx +63 -66
  46. package/src/components/workspace-app-card.tsx +10 -3
  47. package/src/components/workspace-template-card.spec.tsx +7 -8
  48. package/src/components/workspace-template-card.tsx +21 -11
  49. package/src/lib/overview-chat.spec.ts +0 -19
  50. package/src/lib/overview-chat.ts +0 -9
  51. package/src/styles/dispatch.css +2 -2
@@ -417,7 +417,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
417
417
  if (threadId)
418
418
  openThread(threadId, { isNew: true });
419
419
  }
420
- return (_jsxs("div", { className: cn("ms-4 min-w-0 space-y-0.5", showNewChat && "dispatch-chat-first-chats"), children: [showNewChat && chatFirstNavigation ? (_jsx("nav", { className: "space-y-0.5 px-2 py-2", children: _jsx(ChatFirstPrimaryNavigation, { copy: chatFirstCopy, onNewChat: () => void handleNewChat(), onOpenIntegrations: chatFirstNavigation.onOpenIntegrations, onOpenScheduled: chatFirstNavigation.onOpenScheduled, onSearch: openCommandMenu }) })) : null, prelude, !chatFirstMode ? (_jsx("div", { className: "flex justify-end px-2 pt-0.5", children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-dispatch-chat-source-toggle": true, "aria-pressed": includeExternal, "aria-label": includeExternal
420
+ return (_jsxs("div", { className: cn("min-w-0 space-y-0.5", showNewChat && "dispatch-chat-first-chats"), children: [showNewChat && chatFirstNavigation ? (_jsx("nav", { className: "space-y-0.5 px-2 py-2", children: _jsx(ChatFirstPrimaryNavigation, { copy: chatFirstCopy, onNewChat: () => void handleNewChat(), onOpenIntegrations: chatFirstNavigation.onOpenIntegrations, onOpenScheduled: chatFirstNavigation.onOpenScheduled, onSearch: openCommandMenu }) })) : null, prelude, !chatFirstMode ? (_jsx("div", { className: "flex justify-end px-2 pt-0.5", children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-dispatch-chat-source-toggle": true, "aria-pressed": includeExternal, "aria-label": includeExternal
421
421
  ? t("dispatch.sidebar.showLocalChats", {
422
422
  defaultValue: "Show local chats",
423
423
  })
@@ -432,7 +432,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
432
432
  }) })] }) })) : null, !chatFirstMode &&
433
433
  chatsLoading &&
434
434
  visibleThreads.length === 0 &&
435
- Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, `chat-skeleton-${index}`))), chatFirstMode ? (_jsx(ChatFirstChatHistory, { items: chatItems, activeId: displayedActiveThreadId, loading: chatsLoading && visibleThreads.length === 0, loadingLabel: _jsx("div", { className: "space-y-1 px-2 py-1", children: [0, 1, 2].map((index) => (_jsxs("div", { className: "flex items-center gap-2 px-1 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, index))) }), label: t("dispatch.sidebar.chats", { defaultValue: "Chats" }), onSelect: (threadId) => openThread(threadId), renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
435
+ Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, `chat-skeleton-${index}`))), chatFirstMode && (chatsLoading || visibleThreads.length > 0) ? (_jsx(ChatFirstChatHistory, { items: chatItems, activeId: displayedActiveThreadId, loading: chatsLoading && visibleThreads.length === 0, loadingLabel: _jsx("div", { className: "space-y-1 px-2 py-1", children: [0, 1, 2].map((index) => (_jsxs("div", { className: "flex items-center gap-2 px-1 py-1", children: [_jsx(Skeleton, { className: "size-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] }, index))) }), label: t("dispatch.sidebar.chats", { defaultValue: "Chats" }), onSelect: (threadId) => openThread(threadId), renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
436
436
  options: (item) => t("dispatch.sidebar.chatOptions", {
437
437
  title: item.titleText ?? "",
438
438
  }),
@@ -515,7 +515,7 @@ export function NavContent({ onNavigate, extensions, chatFirstMode = false, chat
515
515
  }, onOpenAllApps: () => {
516
516
  navigate(dispatchNavLinkTarget("/apps"));
517
517
  onNavigate?.();
518
- }, createAppTrigger: chatFirstCreateAppTrigger, renderIcon: (app) => (_jsx(AppIcon, { id: app.id, name: app.name, size: "sm", className: "size-5 rounded-md" })), copy: chatFirstCopy }));
518
+ }, createAppTrigger: chatFirstCreateAppTrigger, renderIcon: (app) => (_jsx(AppIcon, { id: app.id, name: app.name, size: "sm", monochrome: true, className: "size-5 rounded-md" })), copy: chatFirstCopy }));
519
519
  const renderNavItem = (item) => {
520
520
  const Icon = item.icon;
521
521
  const itemMatchesLocalPath = navItemMatchesPath(item, localPathname);
@@ -584,22 +584,43 @@ export function Layout({ children, extensions, agentPageHref, }) {
584
584
  const localPathname = localDispatchPath(location.pathname);
585
585
  const isChatRoute = localPathname === "/chat" || localPathname.startsWith("/chat/");
586
586
  const chatFirstSurfaceScope = threadIdFromPath(localPathname) ?? "new";
587
- const isWorkspaceAppHostRoute = localPathname.startsWith("/apps/");
587
+ const isWorkspaceAppRoute = localPathname.startsWith("/apps/");
588
+ const isWorkspaceAppHostRoute = isWorkspaceAppRoute &&
589
+ typeof window !== "undefined" &&
590
+ new URLSearchParams(window.location.search).get("embedded") === "1";
588
591
  const [chatFirstPreference, setChatFirstPreference] = useState(() => readChatFirstMode());
589
592
  const chatFirstEmbedded = typeof window !== "undefined" &&
590
593
  new URLSearchParams(window.location.search).get("chatFirst") === "1";
591
594
  const chatFirstMode = extensions?.chatFirst === true || chatFirstPreference || chatFirstEmbedded;
592
595
  const [chatFirstAppLayout, setChatFirstAppLayout] = useState(() => readChatFirstAppLayout());
593
596
  const chatFirstAppLayoutHydratedRef = useRef(false);
594
- const chatFirstAppsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false }, { enabled: chatFirstMode && isChatRoute });
597
+ const chatFirstAppsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false }, { enabled: chatFirstMode });
598
+ const chatFirstGrantedAppsQuery = useActionQuery("list_apps", {}, { enabled: chatFirstMode });
595
599
  const chatFirstWorkspaceApps = useMemo(() => mergeChatFirstWorkspaceApps(chatFirstAppsQuery.data), [chatFirstAppsQuery.data]);
596
- const chatFirstAppRegistrations = useMemo(() => chatFirstWorkspaceApps.map((app) => ({
597
- id: app.id,
598
- name: app.name,
599
- path: app.path,
600
- url: app.url,
601
- enabled: app.status !== "pending" && app.archived !== true,
602
- })), [chatFirstWorkspaceApps]);
600
+ const chatFirstAppRegistrations = useMemo(() => {
601
+ const registrations = new Map();
602
+ for (const app of chatFirstWorkspaceApps) {
603
+ registrations.set(app.id.toLowerCase(), {
604
+ id: app.id,
605
+ name: app.name,
606
+ path: app.path,
607
+ url: app.url,
608
+ enabled: app.status !== "pending" && app.archived !== true,
609
+ });
610
+ }
611
+ for (const app of chatFirstGrantedAppsQuery.data?.apps ?? []) {
612
+ const id = app.id.trim();
613
+ if (!id || registrations.has(id.toLowerCase()))
614
+ continue;
615
+ registrations.set(id.toLowerCase(), {
616
+ id,
617
+ name: app.name,
618
+ url: app.url,
619
+ enabled: true,
620
+ });
621
+ }
622
+ return [...registrations.values()];
623
+ }, [chatFirstGrantedAppsQuery.data?.apps, chatFirstWorkspaceApps]);
603
624
  const chatFirstAppItems = useMemo(() => chatFirstWorkspaceApps.map((app) => ({
604
625
  id: app.id,
605
626
  name: app.name,
@@ -627,10 +648,18 @@ export function Layout({ children, extensions, agentPageHref, }) {
627
648
  const previousChatFirstSurfaceScopeRef = useRef(chatFirstSurfaceScope);
628
649
  const previousChatFirstSurfaceTabCountRef = useRef(null);
629
650
  const activeChatFirstSurfaceTab = useMemo(() => chatFirstSurfaceTabs.tabs.find((tab) => tab.id === chatFirstSurfaceTabs.activeTabId) ?? null, [chatFirstSurfaceTabs]);
630
- const activeChatFirstApp = useMemo(() => activeChatFirstSurfaceTab?.kind === "app" &&
651
+ const chatFirstAppTakesMain = chatFirstMode && isChatRoute && activeChatFirstSurfaceTab?.kind === "app";
652
+ const activeChatFirstAppRegistration = useMemo(() => activeChatFirstSurfaceTab?.kind === "app" &&
631
653
  activeChatFirstSurfaceTab.appId
632
- ? (chatFirstWorkspaceApps.find((app) => app.id === activeChatFirstSurfaceTab.appId) ?? null)
633
- : null, [activeChatFirstSurfaceTab, chatFirstWorkspaceApps]);
654
+ ? (chatFirstAppRegistrations.find((app) => app.id === activeChatFirstSurfaceTab.appId) ?? null)
655
+ : null, [activeChatFirstSurfaceTab, chatFirstAppRegistrations]);
656
+ const activeChatFirstApp = useMemo(() => activeChatFirstAppRegistration
657
+ ? {
658
+ id: activeChatFirstAppRegistration.id,
659
+ name: activeChatFirstAppRegistration.name ??
660
+ activeChatFirstAppRegistration.id,
661
+ }
662
+ : null, [activeChatFirstAppRegistration]);
634
663
  const chatFirstAgentActivities = useMemo(() => (chatFirstAgentsQuery.data?.threads ?? []).map((thread) => ({
635
664
  sessionId: thread.id,
636
665
  title: thread.title || chatFirstCopy("agentsTitle", { name: thread.id }),
@@ -641,7 +670,8 @@ export function Layout({ children, extensions, agentPageHref, }) {
641
670
  const chatFirstEmbedPath = activeChatFirstSurfaceTab?.kind === "app"
642
671
  ? (activeChatFirstSurfaceTab.path ??
643
672
  chatFirstPane?.path ??
644
- activeChatFirstApp?.path)
673
+ activeChatFirstAppRegistration?.path ??
674
+ "/")
645
675
  : null;
646
676
  useEffect(() => {
647
677
  if (!chatFirstMode || !isChatRoute || !activeChatFirstApp) {
@@ -691,6 +721,9 @@ export function Layout({ children, extensions, agentPageHref, }) {
691
721
  const openChatFirstPane = useCallback((pane) => {
692
722
  setChatFirstNotice(null);
693
723
  closeChatFirstSessionWatch();
724
+ if (!isChatRoute) {
725
+ navigateWithAgentChatViewTransition(navigate, dispatchNavLinkTarget("/chat"));
726
+ }
694
727
  const app = chatFirstAppRegistrations.find((candidate) => candidate.id === pane.appId);
695
728
  chatFirstSurfaceTabsStore.open({
696
729
  id: chatFirstSurfaceTabId("app", `${pane.appId}:${pane.path ?? pane.view ?? "/"}`),
@@ -700,11 +733,15 @@ export function Layout({ children, extensions, agentPageHref, }) {
700
733
  ...(pane.path ? { path: pane.path } : {}),
701
734
  ...(pane.view ? { view: pane.view } : {}),
702
735
  });
736
+ setChatFirstSurfacePanelOpen(true);
703
737
  persistChatFirstPane(pane);
704
738
  }, [
705
739
  chatFirstAppRegistrations,
706
740
  chatFirstSurfaceTabsStore,
707
741
  persistChatFirstPane,
742
+ isChatRoute,
743
+ navigate,
744
+ setChatFirstSurfacePanelOpen,
708
745
  ]);
709
746
  const openChatFirstSurface = useCallback((kind) => {
710
747
  if (kind !== "agents")
@@ -734,7 +771,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
734
771
  });
735
772
  }, [chatFirstSurfaceTabsStore, persistChatFirstPane]);
736
773
  const resolveChatFirstOpenApp = useCallback((detail) => {
737
- if (chatFirstAppsQuery.isLoading) {
774
+ if (chatFirstAppsQuery.isLoading || chatFirstGrantedAppsQuery.isLoading) {
738
775
  pendingChatFirstOpenAppRef.current = detail;
739
776
  return;
740
777
  }
@@ -756,10 +793,9 @@ export function Layout({ children, extensions, agentPageHref, }) {
756
793
  chatFirstAppRegistrations,
757
794
  chatFirstAppsQuery.isError,
758
795
  chatFirstAppsQuery.isLoading,
796
+ chatFirstGrantedAppsQuery.isLoading,
759
797
  openChatFirstPane,
760
798
  ]);
761
- const sidebarBeforeAppRef = useRef(null);
762
- const sidebarAutoCollapsedRef = useRef(false);
763
799
  const chatHomeHandoffActive = useAgentChatHomeHandoff({
764
800
  storageKey: "dispatch",
765
801
  activePath: localPathname,
@@ -811,7 +847,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
811
847
  });
812
848
  }, []);
813
849
  useEffect(() => {
814
- if (!chatFirstMode || !isChatRoute) {
850
+ if (!chatFirstMode) {
815
851
  setChatFirstPane(null);
816
852
  closeChatFirstSessionWatch();
817
853
  chatFirstSurfaceTabsStore.closeAll();
@@ -904,7 +940,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
904
940
  useEffect(() => {
905
941
  const tabCount = chatFirstSurfaceTabs.tabs.length;
906
942
  const previousTabCount = previousChatFirstSurfaceTabCountRef.current;
907
- if (!chatFirstMode || !isChatRoute) {
943
+ if (!chatFirstMode) {
908
944
  setChatFirstSurfacePanelOpen(false);
909
945
  }
910
946
  else if (tabCount > 0 &&
@@ -933,13 +969,17 @@ export function Layout({ children, extensions, agentPageHref, }) {
933
969
  }, [activeChatFirstSurfaceTab, chatFirstSessionWatch.target]);
934
970
  useEffect(() => {
935
971
  const pending = pendingChatFirstOpenAppRef.current;
936
- if (!pending || chatFirstAppsQuery.isLoading)
972
+ if (!pending ||
973
+ chatFirstAppsQuery.isLoading ||
974
+ chatFirstGrantedAppsQuery.isLoading)
937
975
  return;
938
976
  resolveChatFirstOpenApp(pending);
939
977
  }, [
940
978
  chatFirstAppsQuery.data,
941
979
  chatFirstAppsQuery.isError,
942
980
  chatFirstAppsQuery.isLoading,
981
+ chatFirstGrantedAppsQuery.data,
982
+ chatFirstGrantedAppsQuery.isLoading,
943
983
  resolveChatFirstOpenApp,
944
984
  ]);
945
985
  useEffect(() => {
@@ -959,26 +999,6 @@ export function Layout({ children, extensions, agentPageHref, }) {
959
999
  chatFirstSurfaceTabsStore,
960
1000
  isChatRoute,
961
1001
  ]);
962
- useEffect(() => {
963
- if (isWorkspaceAppHostRoute) {
964
- if (!sidebarAutoCollapsedRef.current) {
965
- sidebarAutoCollapsedRef.current = true;
966
- sidebarBeforeAppRef.current = sidebarCollapsed;
967
- }
968
- if (!sidebarCollapsed)
969
- setSidebarCollapsed(true);
970
- return;
971
- }
972
- if (!sidebarAutoCollapsedRef.current)
973
- return;
974
- sidebarAutoCollapsedRef.current = false;
975
- const previousSidebarState = sidebarBeforeAppRef.current;
976
- sidebarBeforeAppRef.current = null;
977
- if (previousSidebarState !== null &&
978
- previousSidebarState !== sidebarCollapsed) {
979
- setSidebarCollapsed(previousSidebarState);
980
- }
981
- }, [isWorkspaceAppHostRoute, sidebarCollapsed]);
982
1002
  useEffect(() => {
983
1003
  if (typeof window === "undefined" || isWorkspaceAppHostRoute)
984
1004
  return;
@@ -1042,8 +1062,14 @@ export function Layout({ children, extensions, agentPageHref, }) {
1042
1062
  if (tab.kind === "app") {
1043
1063
  if (tab.id !== chatFirstSurfaceTabs.activeTabId)
1044
1064
  return null;
1045
- const app = tab.appId
1046
- ? (chatFirstWorkspaceApps.find((candidate) => candidate.id === tab.appId) ?? null)
1065
+ const registration = tab.appId
1066
+ ? (chatFirstAppRegistrations.find((candidate) => candidate.id === tab.appId) ?? null)
1067
+ : null;
1068
+ const app = registration
1069
+ ? {
1070
+ id: registration.id,
1071
+ name: registration.name ?? registration.id,
1072
+ }
1047
1073
  : null;
1048
1074
  return (_jsx(ChatFirstAppPane, { app: app, status: chatFirstEmbedError
1049
1075
  ? "error"
@@ -1087,7 +1113,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
1087
1113
  chatFirstEmbedUrl,
1088
1114
  chatFirstSessionWatch.target,
1089
1115
  chatFirstSurfaceTabs.activeTabId,
1090
- chatFirstWorkspaceApps,
1116
+ chatFirstAppRegistrations,
1091
1117
  closeChatFirstSurfaceTab,
1092
1118
  renderChatFirstWatchChat,
1093
1119
  ]);
@@ -1107,19 +1133,21 @@ export function Layout({ children, extensions, agentPageHref, }) {
1107
1133
  t("dispatch.sidebar.suggestionRouteSlack"),
1108
1134
  t("dispatch.sidebar.suggestionGrantKey"),
1109
1135
  ];
1110
- const appContent = (_jsxs("div", { className: "relative flex h-full min-w-0 flex-1 flex-col overflow-hidden", children: [showHeader ? _jsx(Header, { onOpenMobile: () => setMobileOpen(true) }) : null, _jsx(InvitationBanner, {}), isChatRoute && chatFirstMode ? (_jsx(ChatFirstSurfacePanelToggle, { open: chatFirstSurfacePanel.open, onToggle: chatFirstSurfacePanel.toggle, className: "absolute right-3 top-2 z-[4]" })) : null, isChatRoute && chatFirstMode && chatFirstNotice ? (_jsxs("div", { className: "dispatch-chat-first-notice", role: "status", "aria-live": "polite", children: [_jsx("span", { children: chatFirstNotice }), _jsx("button", { type: "button", onClick: () => setChatFirstNotice(null), "aria-label": "Dismiss app notice", children: "Dismiss" })] })) : null, _jsx("main", { className: cn("flex-1", isChatRoute || isWorkspaceAppHostRoute
1136
+ const appContent = (_jsxs("div", { className: "relative flex h-full min-w-0 flex-1 flex-col overflow-hidden", children: [showHeader ? _jsx(Header, { onOpenMobile: () => setMobileOpen(true) }) : null, _jsx(InvitationBanner, {}), isChatRoute && chatFirstMode ? (_jsx(ChatFirstSurfacePanelToggle, { open: chatFirstSurfacePanel.open, onToggle: chatFirstSurfacePanel.toggle, className: "absolute right-3 top-2 z-[4]" })) : null, isChatRoute && chatFirstMode && chatFirstNotice ? (_jsxs("div", { className: "dispatch-chat-first-notice", role: "status", "aria-live": "polite", children: [_jsx("span", { children: chatFirstNotice }), _jsx("button", { type: "button", onClick: () => setChatFirstNotice(null), "aria-label": "Dismiss app notice", children: "Dismiss" })] })) : null, _jsx("main", { className: cn("flex-1", isChatRoute || isWorkspaceAppRoute
1111
1137
  ? "min-h-0 overflow-hidden"
1112
1138
  : "overflow-y-auto"), children: showHeader ? (_jsx("div", { className: "mx-auto max-w-7xl space-y-10 px-4 py-6 sm:px-6", children: children })) : (children) })] }));
1113
- const content = isChatRoute ? (_jsxs("div", { className: cn("agent-layout-main-surface flex min-w-0 flex-1 overflow-hidden", chatFirstMode && "dispatch-chat-first-surface"), children: [appContent, chatFirstMode && chatFirstSurfacePanel.open ? (_jsxs(ChatFirstSurfacePanel, { width: chatFirstSurfaceResize.width, onResizePointerDown: chatFirstSurfaceResize.onPointerDown, copy: chatFirstCopy, children: [_jsx(ChatFirstSurfaceTabs, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, onActivate: activateChatFirstSurfaceTab, onClose: closeChatFirstSurfaceTab, onCloseOthers: (tab) => {
1114
- activateChatFirstSurfaceTab(tab);
1115
- chatFirstSurfaceTabsStore.closeOthers(tab.id);
1116
- }, onCloseToRight: (tab) => {
1117
- const targetIndex = chatFirstSurfaceTabs.tabs.findIndex((candidate) => candidate.id === tab.id);
1118
- const activeIndex = chatFirstSurfaceTabs.tabs.findIndex((candidate) => candidate.id === chatFirstSurfaceTabs.activeTabId);
1119
- if (activeIndex > targetIndex)
1120
- activateChatFirstSurfaceTab(tab);
1121
- chatFirstSurfaceTabsStore.closeToRight(tab.id);
1122
- }, onCloseAll: closeAllChatFirstSurfaceTabs, onOpenSurface: openChatFirstSurface, copy: chatFirstCopy }), chatFirstSurfaceTabs.tabs.length > 0 ? (_jsx(ChatFirstSurfaceContent, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, renderTab: renderChatFirstSurfaceTab })) : null] })) : null] })) : (_jsx(AgentSidebar, { position: "right", defaultOpen: false, agentPageHref: agentPageHref, chatViewTransition: true, storageKey: "dispatch", openOnChatRunning: chatHomeHandoffActive, onFullscreenRequest: openAskAgentFullscreen, emptyStateText: t("dispatch.sidebar.emptyAgentText"), suggestions: sidebarSuggestions, children: appContent }));
1139
+ const chatFirstSurfaceTabsBar = activeChatFirstSurfaceTab?.kind === "app" ? null : (_jsx(ChatFirstSurfaceTabs, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, onActivate: activateChatFirstSurfaceTab, onClose: closeChatFirstSurfaceTab, onCloseOthers: (tab) => {
1140
+ activateChatFirstSurfaceTab(tab);
1141
+ chatFirstSurfaceTabsStore.closeOthers(tab.id);
1142
+ }, onCloseToRight: (tab) => {
1143
+ const targetIndex = chatFirstSurfaceTabs.tabs.findIndex((candidate) => candidate.id === tab.id);
1144
+ const activeIndex = chatFirstSurfaceTabs.tabs.findIndex((candidate) => candidate.id === chatFirstSurfaceTabs.activeTabId);
1145
+ if (activeIndex > targetIndex)
1146
+ activateChatFirstSurfaceTab(tab);
1147
+ chatFirstSurfaceTabsStore.closeToRight(tab.id);
1148
+ }, onCloseAll: closeAllChatFirstSurfaceTabs, onOpenSurface: openChatFirstSurface, copy: chatFirstCopy }));
1149
+ const chatFirstSurfaceContent = chatFirstSurfaceTabs.tabs.length > 0 ? (_jsx(ChatFirstSurfaceContent, { tabs: chatFirstSurfaceTabs.tabs, activeTabId: chatFirstSurfaceTabs.activeTabId, renderTab: renderChatFirstSurfaceTab })) : null;
1150
+ const content = isChatRoute ? (_jsx("div", { className: cn("agent-layout-main-surface flex min-w-0 flex-1 overflow-hidden", chatFirstMode && "dispatch-chat-first-surface"), children: chatFirstAppTakesMain ? (_jsx("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", "data-dispatch-chat-first-main-app": true, children: chatFirstSurfaceContent })) : (_jsxs(_Fragment, { children: [appContent, chatFirstMode && chatFirstSurfacePanel.open ? (_jsxs(ChatFirstSurfacePanel, { width: chatFirstSurfaceResize.width, onResizePointerDown: chatFirstSurfaceResize.onPointerDown, copy: chatFirstCopy, children: [chatFirstSurfaceTabsBar, chatFirstSurfaceContent] })) : null] })) })) : isWorkspaceAppRoute ? (appContent) : (_jsx(AgentSidebar, { position: "right", defaultOpen: false, agentPageHref: agentPageHref, chatViewTransition: true, storageKey: "dispatch", openOnChatRunning: chatHomeHandoffActive, onFullscreenRequest: openAskAgentFullscreen, emptyStateText: t("dispatch.sidebar.emptyAgentText"), suggestions: sidebarSuggestions, children: appContent }));
1123
1151
  return (_jsx(DispatchExtensionsContext.Provider, { value: extensions, children: _jsx(HeaderActionsProvider, { children: _jsxs("div", { className: "agent-layout-shell flex h-screen w-full overflow-hidden bg-background", children: [_jsx("aside", { "data-collapsed": sidebarCollapsed ? "true" : "false", className: cn("agent-layout-left-drawer hidden shrink-0 flex-col border-e !border-e-sidebar-border bg-sidebar text-sidebar-foreground transition-[width] duration-200 ease-out lg:flex", sidebarCollapsed ? "w-14" : "w-56"), children: _jsx(NavContent, { extensions: extensions, chatFirstMode: chatFirstMode, chatFirstEmbedded: chatFirstEmbedded, collapsed: sidebarCollapsed, chatFirstAppLayout: chatFirstAppLayout, onChatFirstAppLayoutChange: persistChatFirstAppLayout, chatFirstApps: chatFirstAppItems, chatFirstAppsLoading: chatFirstAppsQuery.isLoading, chatFirstAppsError: chatFirstAppsQuery.isError
1124
1152
  ? chatFirstCopy("appsLoadError")
1125
1153
  : null, chatFirstActiveAppId: activeChatFirstSurfaceTab?.kind === "app"