@agent-native/dispatch 0.23.5 → 0.24.2

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 (224) hide show
  1. package/dist/actions/list-connected-agents.d.ts +1 -0
  2. package/dist/actions/list-connected-agents.js +5 -1
  3. package/dist/actions/list-connected-agents.js.map +1 -1
  4. package/dist/actions/list-dispatch-usage-metrics.d.ts +2 -0
  5. package/dist/actions/list-dispatch-usage-metrics.js +11 -1
  6. package/dist/actions/list-dispatch-usage-metrics.js.map +1 -1
  7. package/dist/actions/provider-api-register.d.ts +12 -12
  8. package/dist/actions/remix-workspace-template.js +4 -3
  9. package/dist/actions/remix-workspace-template.js.map +1 -1
  10. package/dist/actions/scaffold-workspace-app.js +3 -2
  11. package/dist/actions/scaffold-workspace-app.js.map +1 -1
  12. package/dist/actions/start-workspace-app-creation.js +3 -2
  13. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  14. package/dist/actions/view-screen.js +11 -1
  15. package/dist/actions/view-screen.js.map +1 -1
  16. package/dist/components/admin-navigation.d.ts.map +1 -1
  17. package/dist/components/admin-navigation.js +21 -5
  18. package/dist/components/admin-navigation.js.map +1 -1
  19. package/dist/components/app-icon.js +1 -1
  20. package/dist/components/app-icon.js.map +1 -1
  21. package/dist/components/app-list-row.d.ts +1 -1
  22. package/dist/components/app-list-row.d.ts.map +1 -1
  23. package/dist/components/app-list-row.js +1 -1
  24. package/dist/components/app-list-row.js.map +1 -1
  25. package/dist/components/app-open-actions.d.ts +1 -17
  26. package/dist/components/app-open-actions.d.ts.map +1 -1
  27. package/dist/components/app-open-actions.js +1 -20
  28. package/dist/components/app-open-actions.js.map +1 -1
  29. package/dist/components/app-row-settings.d.ts +6 -0
  30. package/dist/components/app-row-settings.d.ts.map +1 -0
  31. package/dist/components/app-row-settings.js +11 -0
  32. package/dist/components/app-row-settings.js.map +1 -0
  33. package/dist/components/automation-run-history-dialog.d.ts.map +1 -1
  34. package/dist/components/automation-run-history-dialog.js +3 -2
  35. package/dist/components/automation-run-history-dialog.js.map +1 -1
  36. package/dist/components/connected-app-card.d.ts.map +1 -1
  37. package/dist/components/connected-app-card.js +3 -2
  38. package/dist/components/connected-app-card.js.map +1 -1
  39. package/dist/components/create-app-popover.js +2 -2
  40. package/dist/components/create-app-popover.js.map +1 -1
  41. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  42. package/dist/components/dispatch-control-plane.js +23 -7
  43. package/dist/components/dispatch-control-plane.js.map +1 -1
  44. package/dist/components/dispatch-shell.d.ts.map +1 -1
  45. package/dist/components/dispatch-shell.js +5 -1
  46. package/dist/components/dispatch-shell.js.map +1 -1
  47. package/dist/components/docs-link.d.ts +16 -0
  48. package/dist/components/docs-link.d.ts.map +1 -0
  49. package/dist/components/docs-link.js +34 -0
  50. package/dist/components/docs-link.js.map +1 -0
  51. package/dist/components/layout/Layout.d.ts +1 -0
  52. package/dist/components/layout/Layout.d.ts.map +1 -1
  53. package/dist/components/layout/Layout.js +43 -35
  54. package/dist/components/layout/Layout.js.map +1 -1
  55. package/dist/components/messaging-setup-panel.d.ts.map +1 -1
  56. package/dist/components/messaging-setup-panel.js +3 -2
  57. package/dist/components/messaging-setup-panel.js.map +1 -1
  58. package/dist/components/usage-alerts-panel.d.ts +11 -0
  59. package/dist/components/usage-alerts-panel.d.ts.map +1 -0
  60. package/dist/components/usage-alerts-panel.js +125 -0
  61. package/dist/components/usage-alerts-panel.js.map +1 -0
  62. package/dist/components/workspace-app-card.d.ts +3 -1
  63. package/dist/components/workspace-app-card.d.ts.map +1 -1
  64. package/dist/components/workspace-app-card.js +70 -29
  65. package/dist/components/workspace-app-card.js.map +1 -1
  66. package/dist/components/workspace-app-search.d.ts +10 -0
  67. package/dist/components/workspace-app-search.d.ts.map +1 -0
  68. package/dist/components/workspace-app-search.js +27 -0
  69. package/dist/components/workspace-app-search.js.map +1 -0
  70. package/dist/components/workspace-resource-effective-stack.d.ts.map +1 -1
  71. package/dist/components/workspace-resource-effective-stack.js +3 -2
  72. package/dist/components/workspace-resource-effective-stack.js.map +1 -1
  73. package/dist/components/workspace-template-card.d.ts.map +1 -1
  74. package/dist/components/workspace-template-card.js +10 -15
  75. package/dist/components/workspace-template-card.js.map +1 -1
  76. package/dist/hooks/use-navigation-state.d.ts +2 -0
  77. package/dist/hooks/use-navigation-state.d.ts.map +1 -1
  78. package/dist/hooks/use-navigation-state.js +10 -0
  79. package/dist/hooks/use-navigation-state.js.map +1 -1
  80. package/dist/lib/embed-session-recovery.d.ts +3 -0
  81. package/dist/lib/embed-session-recovery.d.ts.map +1 -0
  82. package/dist/lib/embed-session-recovery.js +18 -0
  83. package/dist/lib/embed-session-recovery.js.map +1 -0
  84. package/dist/lib/other-apps.d.ts +2 -0
  85. package/dist/lib/other-apps.d.ts.map +1 -1
  86. package/dist/lib/other-apps.js.map +1 -1
  87. package/dist/lib/workspace-app-layout.d.ts +19 -0
  88. package/dist/lib/workspace-app-layout.d.ts.map +1 -0
  89. package/dist/lib/workspace-app-layout.js +75 -0
  90. package/dist/lib/workspace-app-layout.js.map +1 -0
  91. package/dist/lib/workspace-apps.d.ts +14 -0
  92. package/dist/lib/workspace-apps.d.ts.map +1 -1
  93. package/dist/lib/workspace-apps.js +66 -0
  94. package/dist/lib/workspace-apps.js.map +1 -1
  95. package/dist/lib/workspace-apps.test.d.ts +2 -0
  96. package/dist/lib/workspace-apps.test.d.ts.map +1 -0
  97. package/dist/lib/workspace-apps.test.js +33 -0
  98. package/dist/lib/workspace-apps.test.js.map +1 -0
  99. package/dist/routes/pages/$appId.d.ts.map +1 -1
  100. package/dist/routes/pages/$appId.js +4 -2
  101. package/dist/routes/pages/$appId.js.map +1 -1
  102. package/dist/routes/pages/agents.d.ts.map +1 -1
  103. package/dist/routes/pages/agents.js +2 -3
  104. package/dist/routes/pages/agents.js.map +1 -1
  105. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  106. package/dist/routes/pages/apps.$appId.js +17 -13
  107. package/dist/routes/pages/apps.$appId.js.map +1 -1
  108. package/dist/routes/pages/apps.d.ts.map +1 -1
  109. package/dist/routes/pages/apps.js +31 -16
  110. package/dist/routes/pages/apps.js.map +1 -1
  111. package/dist/routes/pages/audit.d.ts.map +1 -1
  112. package/dist/routes/pages/audit.js +2 -1
  113. package/dist/routes/pages/audit.js.map +1 -1
  114. package/dist/routes/pages/chat.d.ts.map +1 -1
  115. package/dist/routes/pages/chat.js +7 -2
  116. package/dist/routes/pages/chat.js.map +1 -1
  117. package/dist/routes/pages/dreams.d.ts.map +1 -1
  118. package/dist/routes/pages/dreams.js +14 -18
  119. package/dist/routes/pages/dreams.js.map +1 -1
  120. package/dist/routes/pages/integrations.d.ts.map +1 -1
  121. package/dist/routes/pages/integrations.js +51 -14
  122. package/dist/routes/pages/integrations.js.map +1 -1
  123. package/dist/routes/pages/metrics.d.ts.map +1 -1
  124. package/dist/routes/pages/metrics.js +146 -17
  125. package/dist/routes/pages/metrics.js.map +1 -1
  126. package/dist/routes/pages/operations.js +1 -1
  127. package/dist/routes/pages/operations.js.map +1 -1
  128. package/dist/routes/pages/settings.d.ts.map +1 -1
  129. package/dist/routes/pages/settings.js +19 -2
  130. package/dist/routes/pages/settings.js.map +1 -1
  131. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  132. package/dist/routes/pages/thread-debug.js +5 -8
  133. package/dist/routes/pages/thread-debug.js.map +1 -1
  134. package/dist/routes/pages/vault.d.ts.map +1 -1
  135. package/dist/routes/pages/vault.js +1 -1
  136. package/dist/routes/pages/vault.js.map +1 -1
  137. package/dist/routes/pages/workspace.d.ts.map +1 -1
  138. package/dist/routes/pages/workspace.js +13 -10
  139. package/dist/routes/pages/workspace.js.map +1 -1
  140. package/dist/server/index.d.ts.map +1 -1
  141. package/dist/server/index.js +3 -0
  142. package/dist/server/index.js.map +1 -1
  143. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  144. package/dist/server/lib/app-creation-store.js +12 -52
  145. package/dist/server/lib/app-creation-store.js.map +1 -1
  146. package/dist/server/lib/usage-metrics-store.d.ts +17 -0
  147. package/dist/server/lib/usage-metrics-store.d.ts.map +1 -1
  148. package/dist/server/lib/usage-metrics-store.js +187 -30
  149. package/dist/server/lib/usage-metrics-store.js.map +1 -1
  150. package/dist/server/plugins/agent-chat.js +2 -0
  151. package/dist/server/plugins/agent-chat.js.map +1 -1
  152. package/dist/server/plugins/integrations.d.ts.map +1 -1
  153. package/dist/server/plugins/integrations.js +1 -0
  154. package/dist/server/plugins/integrations.js.map +1 -1
  155. package/dist/shared/app-roles.d.ts +9 -0
  156. package/dist/shared/app-roles.d.ts.map +1 -0
  157. package/dist/shared/app-roles.js +7 -0
  158. package/dist/shared/app-roles.js.map +1 -0
  159. package/package.json +4 -3
  160. package/src/actions/list-connected-agents.spec.ts +73 -0
  161. package/src/actions/list-connected-agents.ts +6 -2
  162. package/src/actions/list-dispatch-usage-metrics.ts +11 -1
  163. package/src/actions/remix-workspace-template.spec.ts +29 -0
  164. package/src/actions/remix-workspace-template.ts +13 -6
  165. package/src/actions/scaffold-workspace-app.ts +12 -5
  166. package/src/actions/start-workspace-app-creation.ts +8 -2
  167. package/src/actions/view-screen.ts +13 -1
  168. package/src/components/admin-navigation.tsx +57 -11
  169. package/src/components/app-icon.spec.tsx +34 -0
  170. package/src/components/app-icon.tsx +1 -1
  171. package/src/components/app-list-row.tsx +1 -2
  172. package/src/components/app-open-actions.tsx +5 -114
  173. package/src/components/app-row-settings.tsx +54 -0
  174. package/src/components/automation-run-history-dialog.tsx +8 -4
  175. package/src/components/connected-app-card.tsx +3 -2
  176. package/src/components/create-app-popover.spec.tsx +1 -1
  177. package/src/components/create-app-popover.tsx +2 -2
  178. package/src/components/dispatch-control-plane.spec.tsx +44 -3
  179. package/src/components/dispatch-control-plane.tsx +83 -27
  180. package/src/components/dispatch-shell.tsx +7 -1
  181. package/src/components/docs-link.tsx +52 -0
  182. package/src/components/layout/Layout.spec.tsx +13 -0
  183. package/src/components/layout/Layout.tsx +63 -32
  184. package/src/components/messaging-setup-panel.tsx +10 -3
  185. package/src/components/usage-alerts-panel.tsx +445 -0
  186. package/src/components/workspace-app-card.spec.tsx +130 -9
  187. package/src/components/workspace-app-card.tsx +128 -71
  188. package/src/components/workspace-app-search.tsx +96 -0
  189. package/src/components/workspace-resource-effective-stack.tsx +10 -5
  190. package/src/components/workspace-template-card.spec.tsx +53 -24
  191. package/src/components/workspace-template-card.tsx +16 -26
  192. package/src/hooks/use-navigation-state.ts +12 -0
  193. package/src/lib/embed-session-recovery.spec.ts +63 -0
  194. package/src/lib/embed-session-recovery.ts +26 -0
  195. package/src/lib/other-apps.ts +2 -0
  196. package/src/lib/workspace-app-layout.spec.ts +47 -0
  197. package/src/lib/workspace-app-layout.ts +121 -0
  198. package/src/lib/workspace-apps.test.ts +64 -0
  199. package/src/lib/workspace-apps.ts +82 -0
  200. package/src/routes/pages/$appId.tsx +3 -6
  201. package/src/routes/pages/agents.tsx +6 -3
  202. package/src/routes/pages/apps.$appId.tsx +16 -17
  203. package/src/routes/pages/apps.tsx +116 -62
  204. package/src/routes/pages/audit.tsx +28 -8
  205. package/src/routes/pages/chat.spec.tsx +10 -0
  206. package/src/routes/pages/chat.tsx +8 -0
  207. package/src/routes/pages/dreams.tsx +92 -142
  208. package/src/routes/pages/integrations.tsx +147 -68
  209. package/src/routes/pages/metrics.tsx +460 -102
  210. package/src/routes/pages/operations.tsx +2 -2
  211. package/src/routes/pages/settings.tsx +27 -10
  212. package/src/routes/pages/thread-debug.tsx +18 -36
  213. package/src/routes/pages/vault.tsx +7 -2
  214. package/src/routes/pages/workspace.tsx +92 -56
  215. package/src/server/index.ts +4 -0
  216. package/src/server/lib/app-creation-store.spec.ts +90 -43
  217. package/src/server/lib/app-creation-store.ts +15 -61
  218. package/src/server/lib/usage-metrics-store.spec.ts +117 -0
  219. package/src/server/lib/usage-metrics-store.ts +249 -30
  220. package/src/server/plugins/agent-chat.spec.ts +4 -0
  221. package/src/server/plugins/agent-chat.ts +2 -0
  222. package/src/server/plugins/integrations.ts +1 -0
  223. package/src/shared/app-roles.ts +8 -0
  224. package/src/styles/dispatch.css +9 -0
@@ -15,8 +15,9 @@ import { IconApps, IconBrandSlack, IconBrandTelegram, IconCopy, IconEye, IconMes
15
15
  import { createContext, useEffect, useMemo, useRef, useState, useContext, useCallback, } from "react";
16
16
  import { Link, useLocation, useNavigate } from "react-router";
17
17
  import { toast } from "sonner";
18
+ import { isEmbedSessionExpiredMessage } from "../../lib/embed-session-recovery.js";
18
19
  import { cn } from "../../lib/utils.js";
19
- import { isDispatchWorkspaceAppId, isWorkspaceAppVisibleInDefaultLaunchers, mergeChatFirstWorkspaceApps, workspaceAppIdFromRoute, workspaceAppRoute, } from "../../lib/workspace-apps.js";
20
+ import { isDispatchWorkspaceAppId, isWorkspaceAppVisibleInDefaultLaunchers, mergeChatFirstWorkspaceApps, workspaceAppDirectHref, workspaceAppIdFromRoute, workspaceAppRoute, } from "../../lib/workspace-apps.js";
20
21
  import { AppIcon } from "../app-icon.js";
21
22
  import { CreateAppPopover } from "../create-app-popover.js";
22
23
  import { Sheet, SheetContent, SheetDescription, SheetTitle } from "../ui/sheet.js";
@@ -118,6 +119,9 @@ function localDispatchPath(pathname) {
118
119
  export function isElectronEmbeddedSearch(search) {
119
120
  return new URLSearchParams(search).get("electron") === "1";
120
121
  }
122
+ export function shouldAutoCollapseDispatchSidebar(pathname) {
123
+ return localDispatchPath(pathname).startsWith("/apps/");
124
+ }
121
125
  function chatFirstPrimaryTabForPath(pathname) {
122
126
  if (pathname === "/chat" || pathname.startsWith("/chat/")) {
123
127
  return "new-chat";
@@ -329,17 +333,6 @@ export function formatThreadAge(updatedAt, now = Date.now()) {
329
333
  function threadTitle(thread, fallback) {
330
334
  return thread.title || thread.preview || fallback;
331
335
  }
332
- function readChatHistoryIncludesExternal() {
333
- if (typeof window === "undefined")
334
- return false;
335
- try {
336
- return localStorage.getItem(CHAT_HISTORY_SOURCE_KEY) === "all";
337
- }
338
- catch {
339
- // coercion-ok: localStorage is optional browser persistence.
340
- return false;
341
- }
342
- }
343
336
  function threadSourceIcon(platform) {
344
337
  const normalized = platform?.trim().toLowerCase();
345
338
  if (!normalized)
@@ -352,6 +345,17 @@ function threadSourceIcon(platform) {
352
345
  }
353
346
  return _jsx(IconWorld, { size: 13, "aria-hidden": "true" });
354
347
  }
348
+ function readChatHistoryIncludesExternal() {
349
+ if (typeof window === "undefined")
350
+ return false;
351
+ try {
352
+ return localStorage.getItem(CHAT_HISTORY_SOURCE_KEY) === "all";
353
+ }
354
+ catch {
355
+ // coercion-ok: localStorage is optional browser persistence.
356
+ return false;
357
+ }
358
+ }
355
359
  function threadUpdatedAt(thread) {
356
360
  return Number.isFinite(thread.updatedAt)
357
361
  ? thread.updatedAt
@@ -367,14 +371,14 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
367
371
  const [includeExternal, setIncludeExternal] = useState(false);
368
372
  const [historyPreferenceReady, setHistoryPreferenceReady] = useState(false);
369
373
  const historyModeRef = useRef(includeExternal);
370
- const { threads, activeThreadId, isLoading: chatsLoading, createThread, switchThread, renameThread, refreshThreads, } = useChatThreads(undefined, "dispatch", undefined, {
374
+ const { threads, activeThreadId, isLoading: chatsLoading, threadsLoadError, createThread, switchThread, renameThread, refreshThreads, } = useChatThreads(undefined, "dispatch", undefined, {
371
375
  autoCreate: false,
372
376
  includeExternal,
373
377
  });
374
378
  const visibleThreads = useMemo(() => threads
375
379
  .filter((thread) => thread.messageCount > 0 || thread.id === activeThreadId)
376
380
  .sort((a, b) => threadUpdatedAt(b) - threadUpdatedAt(a))
377
- .slice(0, 15), [activeThreadId, threads]);
381
+ .slice(0, 8), [activeThreadId, threads]);
378
382
  const localPathname = localDispatchPath(location.pathname);
379
383
  const displayedActiveThreadId = threadIdFromPath(localPathname) ??
380
384
  (localPathname === "/chat" ? null : activeThreadId);
@@ -394,6 +398,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
394
398
  : formatThreadAge(threadUpdatedAt(thread)),
395
399
  };
396
400
  });
401
+ const chatHistoryError = threadsLoadError ? (_jsxs("button", { type: "button", onClick: () => void refreshThreads(), className: "flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-xs text-sidebar-foreground/65 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", children: [_jsx("span", { children: "Could not load chats" }), _jsx("span", { className: "font-medium", children: "Retry" })] })) : undefined;
397
402
  useEffect(() => {
398
403
  setIncludeExternal(readChatHistoryIncludesExternal());
399
404
  setHistoryPreferenceReady(true);
@@ -459,7 +464,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
459
464
  }) })] }) })) : null, !chatFirstMode &&
460
465
  chatsLoading &&
461
466
  visibleThreads.length === 0 &&
462
- 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: {
467
+ 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" }), error: chatHistoryError, onSelect: (threadId) => openThread(threadId), renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
463
468
  options: (item) => t("dispatch.sidebar.chatOptions", {
464
469
  title: item.titleText ?? "",
465
470
  }),
@@ -486,7 +491,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
486
491
  newChat: t("dispatch.sidebar.newChat"),
487
492
  showMore: t("dispatch.sidebar.chats"),
488
493
  showLess: t("dispatch.sidebar.chats"),
489
- }, renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
494
+ }, error: chatHistoryError, renameMaxLength: 160, onRename: (threadId, title) => void renameThread(threadId, title), labels: {
490
495
  options: (item) => t("dispatch.sidebar.chatOptions", {
491
496
  title: item.titleText ?? "",
492
497
  }),
@@ -509,7 +514,7 @@ function DispatchChatsSection({ onNavigate, showNewChat = false, prelude, chatFi
509
514
  kind: "agent-chat",
510
515
  sourceSessionId: displayedActiveThreadId ?? undefined,
511
516
  });
512
- }, children: [_jsx(IconEye, { size: 13, strokeWidth: 1.8 }), _jsx("span", { children: "Watch and message session" })] })) : null] })), className: cn("min-w-0", chatFirstMode && "px-2") }))] }));
517
+ }, children: [_jsx(IconEye, { size: 13, strokeWidth: 1.8 }), _jsx("span", { children: "Watch and message session" })] })) : null] })), className: "min-w-0 px-2" }))] }));
513
518
  }
514
519
  export function NavContent({ onNavigate, extensions, chatFirstMode = false, chatFirstEmbedded = false, collapsed = false, collapsible = false, onCollapsedChange, chatFirstAppLayout, onChatFirstAppLayoutChange, chatFirstApps = [], chatFirstAppsLoading = false, chatFirstAppsError, chatFirstActiveAppId, chatFirstActivePrimaryTab, onChatFirstNewChat, onChatFirstAppOpen, onChatFirstAppsRetry, }) {
515
520
  const t = useT();
@@ -580,9 +585,9 @@ export function NavContent({ onNavigate, extensions, chatFirstMode = false, chat
580
585
  : "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"), children: [Icon ? (_jsx(Icon, { size: 16, className: "shrink-0" })) : (_jsx("span", { className: "h-4 w-4 shrink-0", "aria-hidden": "true" })), _jsx("span", { className: "truncate", children: label })] })), !collapsed && item.id === "chat" && itemMatchesLocalPath ? (_jsx(DispatchChatsSection, { onNavigate: onNavigate, chatFirstMode: chatFirstMode, chatFirstEmbedded: chatFirstEmbedded })) : null] }, item.id));
581
586
  };
582
587
  const bottomNavigation = (_jsx("nav", { className: cn("py-1", collapsed ? "px-1.5" : "px-2"), children: _jsx("ul", { className: cn(collapsed ? "flex flex-col items-center gap-1" : "space-y-0.5"), children: BOTTOM_NAV_ITEMS.map(renderNavItem) }) }));
583
- const organizationPicker = (_jsx("div", { className: cn("py-2", collapsed ? "flex justify-center px-1" : "px-3"), children: _jsx(OrgSwitcher, { compact: collapsed, reserveSpace: true }) }));
588
+ const organizationPicker = (_jsx("div", { className: cn("py-2", collapsed ? "flex justify-center px-1" : "px-3"), children: _jsx(OrgSwitcher, { compact: collapsed, reserveSpace: true, currentAppId: "dispatch" }) }));
584
589
  const sidebarFooterActions = (_jsx(SidebarFooterActions, { collapsed: collapsed, feedback: feedbackButton, search: searchButton, collapse: collapseButton }));
585
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn("flex h-12 shrink-0 items-center border-b border-sidebar-border", collapsed ? "justify-center px-0" : "px-4"), children: _jsxs("div", { className: cn("flex items-center", collapsed ? "justify-center" : "gap-2"), children: [_jsx("img", { src: appPath("/agent-native-icon-light.svg"), alt: "", "aria-hidden": "true", width: 35, height: 20, className: cn("block shrink-0 object-contain object-center dark:hidden", collapsed ? "h-4 w-7" : "h-5 w-[35px]") }), _jsx("img", { src: appPath("/agent-native-icon-dark.svg"), alt: "", "aria-hidden": "true", width: 35, height: 20, className: cn("hidden shrink-0 object-contain object-center dark:block", collapsed ? "h-4 w-7" : "h-5 w-[35px]") }), !collapsed && (_jsx("div", { className: "min-w-0 flex-1", children: _jsx("div", { "data-dispatch-sidebar-label": true, className: "truncate text-lg font-bold tracking-tight text-foreground", children: DISPATCH_SIDEBAR_LABEL }) }))] }) }), chatFirstMode ? (_jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto", children: !collapsed ? (_jsx(DispatchChatsSection, { onNavigate: onNavigate, showNewChat: true, chatFirstMode: true, chatFirstEmbedded: chatFirstEmbedded, chatFirstNavigation: {
590
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn("flex h-12 shrink-0 items-center border-b border-sidebar-border", collapsed ? "justify-center px-0" : "px-4"), children: _jsxs(Link, { to: dispatchNavLinkTarget("/overview"), "aria-label": `${DISPATCH_SIDEBAR_LABEL} overview`, "data-dispatch-logo": true, className: cn("flex items-center rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring", collapsed ? "justify-center" : "gap-2"), children: [_jsx("img", { src: appPath("/agent-native-icon-light.svg"), alt: "", "aria-hidden": "true", width: 35, height: 20, className: cn("block shrink-0 object-contain object-center dark:hidden", collapsed ? "h-4 w-7" : "h-5 w-[35px]") }), _jsx("img", { src: appPath("/agent-native-icon-dark.svg"), alt: "", "aria-hidden": "true", width: 35, height: 20, className: cn("hidden shrink-0 object-contain object-center dark:block", collapsed ? "h-4 w-7" : "h-5 w-[35px]") }), !collapsed && (_jsx("div", { className: "min-w-0 flex-1", children: _jsx("div", { "data-dispatch-sidebar-label": true, className: "truncate text-lg font-bold tracking-tight text-foreground", children: DISPATCH_SIDEBAR_LABEL }) }))] }) }), chatFirstMode ? (_jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto", children: !collapsed ? (_jsx(DispatchChatsSection, { onNavigate: onNavigate, showNewChat: true, chatFirstMode: true, chatFirstEmbedded: chatFirstEmbedded, chatFirstNavigation: {
586
591
  activeTab: chatFirstActivePrimaryTab,
587
592
  onNewChat: onChatFirstNewChat,
588
593
  onOpenIntegrations: () => {
@@ -616,7 +621,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
616
621
  : false);
617
622
  const isChatRoute = localPathname === "/chat" || localPathname.startsWith("/chat/");
618
623
  const chatFirstSurfaceScope = threadIdFromPath(localPathname) ?? "new";
619
- const isWorkspaceAppRoute = localPathname.startsWith("/apps/");
624
+ const isWorkspaceAppRoute = shouldAutoCollapseDispatchSidebar(location.pathname);
620
625
  const isWorkspaceAppHostRoute = isWorkspaceAppRoute &&
621
626
  typeof window !== "undefined" &&
622
627
  new URLSearchParams(window.location.search).get("embedded") === "1";
@@ -634,12 +639,6 @@ export function Layout({ children, extensions, agentPageHref, }) {
634
639
  url.searchParams.set("electron", "1");
635
640
  window.history.replaceState(window.history.state, "", `${url.pathname}${url.search}${url.hash}`);
636
641
  }, [electronEmbedded, location.pathname, location.search]);
637
- useEffect(() => {
638
- if (!chatFirstMode || chatFirstEmbedded || localPathname !== "/overview") {
639
- return;
640
- }
641
- navigate(dispatchNavLinkTarget("/chat"), { replace: true });
642
- }, [chatFirstEmbedded, chatFirstMode, localPathname, navigate]);
643
642
  const [chatFirstAppLayout, setChatFirstAppLayout] = useState(() => readChatFirstAppLayout());
644
643
  const chatFirstAppLayoutHydratedRef = useRef(false);
645
644
  const chatFirstAppsQuery = useActionQuery("list-workspace-apps", { includeAgentCards: false }, { enabled: chatFirstMode });
@@ -761,6 +760,11 @@ export function Layout({ children, extensions, agentPageHref, }) {
761
760
  })
762
761
  .catch((cause) => {
763
762
  if (!cancelled) {
763
+ const directAppUrl = activeChatFirstAppRegistration
764
+ ? workspaceAppDirectHref(activeChatFirstAppRegistration, chatFirstEmbedPath)
765
+ : null;
766
+ if (directAppUrl)
767
+ setChatFirstEmbedUrl(directAppUrl);
764
768
  setChatFirstEmbedError(cause instanceof Error
765
769
  ? cause.message
766
770
  : chatFirstCopy("appUnavailable"));
@@ -782,10 +786,8 @@ export function Layout({ children, extensions, agentPageHref, }) {
782
786
  if (!chatFirstMode || !isChatRoute || !activeChatFirstApp)
783
787
  return;
784
788
  const handleEmbedSessionExpired = (event) => {
785
- if (event.data?.type !== "agentNative.embedSessionExpired" ||
786
- event.source !== chatFirstAppFrameRef.current?.contentWindow) {
789
+ if (!isEmbedSessionExpiredMessage(event, chatFirstAppFrameRef.current, null))
787
790
  return;
788
- }
789
791
  setChatFirstEmbedAttempt((attempt) => attempt + 1);
790
792
  };
791
793
  window.addEventListener("message", handleEmbedSessionExpired);
@@ -812,6 +814,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
812
814
  const openChatFirstPane = useCallback((pane, placement = "side") => {
813
815
  if (placement === "side" && !chatFirstHasActiveChat)
814
816
  return;
817
+ setSidebarCollapsed(true);
815
818
  setChatFirstNotice(null);
816
819
  closeChatFirstSessionWatch();
817
820
  if (!isChatRoute) {
@@ -1136,6 +1139,11 @@ export function Layout({ children, extensions, agentPageHref, }) {
1136
1139
  chatFirstSurfaceTabsStore,
1137
1140
  isChatRoute,
1138
1141
  ]);
1142
+ useEffect(() => {
1143
+ if (!isWorkspaceAppRoute)
1144
+ return;
1145
+ setSidebarCollapsed(true);
1146
+ }, [isWorkspaceAppRoute, localPathname]);
1139
1147
  useEffect(() => {
1140
1148
  if (typeof window === "undefined" || isWorkspaceAppHostRoute)
1141
1149
  return;
@@ -1195,7 +1203,7 @@ export function Layout({ children, extensions, agentPageHref, }) {
1195
1203
  routeThreadId: target.sessionId,
1196
1204
  getPath: chatThreadPath,
1197
1205
  navigate: () => undefined,
1198
- }, showHeader: false, showTabBar: false, showPageNewChatButton: false, chatOnly: true, dynamicSuggestions: false, suggestions: [], emptyStateDisplay: "hidden", composerPlaceholder: t("dispatch.pages.chatFirstSessionMessagePlaceholder") })), [t]);
1206
+ }, showHeader: false, showTabBar: false, showPageNewChatButton: false, chatOnly: true, dynamicSuggestions: false, suggestions: [], suppressInlineOpenApp: chatFirstMode, emptyStateDisplay: "hidden", composerPlaceholder: t("dispatch.pages.chatFirstSessionMessagePlaceholder") })), [chatFirstMode, t]);
1199
1207
  const renderChatFirstSurfaceTab = useCallback((tab) => {
1200
1208
  if (tab.kind === "app") {
1201
1209
  if (tab.id !== chatFirstSurfaceTabs.activeTabId)
@@ -1209,15 +1217,15 @@ export function Layout({ children, extensions, agentPageHref, }) {
1209
1217
  name: registration.name ?? registration.id,
1210
1218
  }
1211
1219
  : null;
1212
- return (_jsx(ChatFirstAppPane, { app: app, status: chatFirstEmbedError
1213
- ? "error"
1214
- : chatFirstEmbedUrl
1215
- ? "ready"
1220
+ return (_jsx(ChatFirstAppPane, { app: app, status: chatFirstEmbedUrl
1221
+ ? "ready"
1222
+ : chatFirstEmbedError
1223
+ ? "error"
1216
1224
  : chatFirstAppsQuery.isLoading
1217
1225
  ? "loading"
1218
1226
  : app
1219
1227
  ? "loading"
1220
- : "unresolved", embedUrl: chatFirstEmbedUrl, errorMessage: chatFirstEmbedError, onRetry: () => setChatFirstEmbedAttempt((value) => value + 1), renderEmbed: ({ url, title }) => (_jsx("iframe", { "data-dispatch-chat-first-app-frame": true, src: url, title: title ?? chatFirstCopy("appUnavailable"), ref: chatFirstAppFrameRef, referrerPolicy: "no-referrer", allow: "clipboard-read; clipboard-write", className: "h-full w-full border-0 bg-background" })), copy: chatFirstCopy }));
1228
+ : "unresolved", embedUrl: chatFirstEmbedUrl, errorMessage: chatFirstEmbedError, onRetry: () => setChatFirstEmbedAttempt((value) => value + 1), renderEmbed: ({ url, title }) => (_jsx("iframe", { "data-dispatch-chat-first-app-frame": true, src: url, title: title ?? chatFirstCopy("appUnavailable"), ref: chatFirstAppFrameRef, referrerPolicy: "no-referrer", allow: "clipboard-read; clipboard-write", className: "h-full w-full border-0 bg-background" }, `${url}:${chatFirstEmbedAttempt}`)), copy: chatFirstCopy }));
1221
1229
  }
1222
1230
  if (tab.kind === "browser" && tab.url) {
1223
1231
  return (_jsx(ChatFirstBrowserPane, { url: tab.url, title: tab.title, onClose: () => closeChatFirstSurfaceTab(tab), renderEmbed: ({ url, title, key }) => (_jsx("iframe", { src: url, title: title ?? chatFirstCopy("browserPage"), referrerPolicy: "no-referrer", allow: "clipboard-read; clipboard-write", className: "h-full w-full border-0 bg-background" }, key)), copy: chatFirstCopy }));