@agent-native/dispatch 0.40.13 → 0.40.14-nightly-20261006033736

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 (38) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/actions/provider-api-register.d.ts +10 -10
  3. package/dist/components/connected-app-card.d.ts.map +1 -1
  4. package/dist/components/connected-app-card.js +23 -4
  5. package/dist/components/connected-app-card.js.map +1 -1
  6. package/dist/components/layout/Layout.d.ts.map +1 -1
  7. package/dist/components/layout/Layout.js +116 -60
  8. package/dist/components/layout/Layout.js.map +1 -1
  9. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  10. package/dist/components/layout/workspace-apps-rail.js +35 -9
  11. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  12. package/dist/lib/other-apps.d.ts +1 -0
  13. package/dist/lib/other-apps.d.ts.map +1 -1
  14. package/dist/lib/other-apps.js +29 -1
  15. package/dist/lib/other-apps.js.map +1 -1
  16. package/dist/lib/workspace-apps.d.ts +2 -1
  17. package/dist/lib/workspace-apps.d.ts.map +1 -1
  18. package/dist/lib/workspace-apps.js +15 -5
  19. package/dist/lib/workspace-apps.js.map +1 -1
  20. package/dist/routes/pages/apps.d.ts.map +1 -1
  21. package/dist/routes/pages/apps.js +17 -4
  22. package/dist/routes/pages/apps.js.map +1 -1
  23. package/dist/server/plugins/auth.js +2 -2
  24. package/dist/server/plugins/auth.js.map +1 -1
  25. package/package.json +4 -4
  26. package/src/components/connected-app-card.spec.tsx +100 -0
  27. package/src/components/connected-app-card.tsx +38 -9
  28. package/src/components/layout/Layout.spec.tsx +397 -6
  29. package/src/components/layout/Layout.tsx +173 -85
  30. package/src/components/layout/workspace-apps-rail.spec.tsx +69 -7
  31. package/src/components/layout/workspace-apps-rail.tsx +49 -7
  32. package/src/lib/other-apps.spec.ts +84 -2
  33. package/src/lib/other-apps.ts +39 -1
  34. package/src/lib/workspace-apps.spec.ts +53 -0
  35. package/src/lib/workspace-apps.ts +15 -7
  36. package/src/routes/pages/apps.spec.tsx +132 -0
  37. package/src/routes/pages/apps.tsx +46 -10
  38. package/src/server/plugins/auth.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"../../components/workspace-app-search\";\nimport { cn } from \"../../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredArchivedApps = orderedArchivedApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n filteredArchivedApps.length > 0;\n const showAppSkeletons = appsLoading && allApps.length === 0;\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n </div>\n </div>\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\">\n {!showAppSkeletons ? (\n <WorkspaceAppSearch\n className=\"w-full sm:w-[250px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n {activeApps.length > 0 || pendingApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", {\n defaultValue: \"Add app\",\n })}\n </Button>\n }\n />\n ) : null}\n </div>\n </div>\n\n {!showAppSkeletons && allApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : !hasSearchResults && searchQuery.trim() ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : filteredActiveApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id.toLowerCase())}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n </AppList>\n ) : searchQuery.trim() ? null : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showPending || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n {archivedApps.length > 0 &&\n (!searchQuery.trim() || filteredArchivedApps.length > 0) ? (\n <Collapsible\n open={showHidden || Boolean(searchQuery.trim())}\n onOpenChange={setShowHidden}\n >\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showHidden || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredArchivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../../src/routes/pages/apps.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport {\n IconApps,\n IconChevronDown,\n IconClockHour4,\n IconEyeOff,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { Outlet, useParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport {\n APP_LIST_GRID_CLASS,\n APP_LIST_GRID_ROW_CLASS,\n AppList,\n} from \"../../components/app-list-row\";\nimport { ConnectedAppCard } from \"../../components/connected-app-card\";\nimport { CreateAppPopover } from \"../../components/create-app-popover\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../components/ui/collapsible\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport { WorkspaceAppCard } from \"../../components/workspace-app-card\";\nimport {\n WorkspaceAppSearch,\n WorkspaceAppSearchEmpty,\n} from \"../../components/workspace-app-search\";\nimport {\n filterBuiltInApps,\n type ConnectedAppSummary,\n} from \"../../lib/other-apps\";\nimport { cn } from \"../../lib/utils\";\nimport {\n orderWorkspaceApps,\n useWorkspaceAppLayout,\n workspaceAppMatchesQuery,\n} from \"../../lib/workspace-app-layout\";\nimport {\n isWorkspaceAppVisibleInDefaultLaunchers,\n type WorkspaceAppSummary,\n} from \"../../lib/workspace-apps\";\n\nexport function meta() {\n return [{ title: \"Apps — Dispatch\" }];\n}\n\ninterface WorkspaceInfo {\n name: string | null;\n displayName: string | null;\n appCount: number;\n}\n\nexport default function AppsRouteEntry() {\n const { appId } = useParams();\n return appId ? <Outlet /> : <AppsRoute />;\n}\n\nfunction AppsRoute() {\n const t = useT();\n const [showPending, setShowPending] = useState(false);\n const [showHidden, setShowHidden] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { layout, persistenceError, togglePinned } = useWorkspaceAppLayout();\n const appsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const connectedAppsQuery = useActionQuery<ConnectedAppSummary[]>(\n \"list-connected-agents\",\n {},\n );\n const { data: apps = [], isLoading: appsLoading } = appsQuery;\n const { data: workspace } = useActionQuery(\n \"get-workspace-info\",\n {},\n { staleTime: 60_000 },\n );\n const ws = workspace as WorkspaceInfo | undefined;\n const workspaceLabel = ws?.displayName ?? ws?.name ?? null;\n const allApps = (apps as WorkspaceAppSummary[]).filter(\n isWorkspaceAppVisibleInDefaultLaunchers,\n );\n const visibleApps = allApps.filter((app) => !app.archived);\n const activeApps = visibleApps.filter((app) => app.status !== \"pending\");\n const pendingApps = visibleApps.filter((app) => app.status === \"pending\");\n const archivedApps = allApps.filter((app) => app.archived);\n const defaultApps = filterBuiltInApps(connectedAppsQuery.data ?? [], allApps);\n const orderedActiveApps = orderWorkspaceApps(activeApps, layout);\n const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);\n const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);\n const filteredActiveApps = orderedActiveApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredPendingApps = orderedPendingApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredArchivedApps = orderedArchivedApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const filteredDefaultApps = defaultApps.filter((app) =>\n workspaceAppMatchesQuery(app, searchQuery),\n );\n const hasSearchResults =\n filteredActiveApps.length > 0 ||\n filteredPendingApps.length > 0 ||\n filteredArchivedApps.length > 0 ||\n filteredDefaultApps.length > 0;\n const showAppSkeletons =\n (appsLoading || connectedAppsQuery.isLoading) &&\n allApps.length === 0 &&\n defaultApps.length === 0;\n const appDiscoveryFailed = appsQuery.isError || connectedAppsQuery.isError;\n\n return (\n <DispatchShell\n title={t(\"dispatch.nav.apps\")}\n description={\n workspaceLabel\n ? t(\"dispatch.pages.appsDescriptionWithWorkspace\", {\n workspace: workspaceLabel,\n })\n : t(\"dispatch.pages.appsDescription\")\n }\n >\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2\">\n <IconApps\n size={16}\n className=\"mt-0.5 shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"truncate text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.yourApps\", { defaultValue: \"Your apps\" })}\n </h2>\n </div>\n </div>\n <div className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\">\n {!showAppSkeletons ? (\n <WorkspaceAppSearch\n className=\"w-full sm:w-[250px]\"\n query={searchQuery}\n onQueryChange={setSearchQuery}\n />\n ) : null}\n {activeApps.length > 0 ||\n pendingApps.length > 0 ||\n defaultApps.length > 0 ? (\n <CreateAppPopover\n align=\"end\"\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", {\n defaultValue: \"Add app\",\n })}\n </Button>\n }\n />\n ) : null}\n </div>\n </div>\n\n {!showAppSkeletons && allApps.length > 0 && persistenceError ? (\n <p className=\"text-xs text-muted-foreground\" role=\"status\">\n {persistenceError === \"both\"\n ? t(\"dispatch.pages.appPinSaveFailed\", {\n defaultValue: \"App pins could not be saved.\",\n })\n : t(\"dispatch.pages.appPinSavedLocally\", {\n defaultValue: \"App pins are saved on this device only.\",\n })}\n </p>\n ) : null}\n\n {appsQuery.isError ? (\n <ActionQueryError\n error={appsQuery.error}\n onRetry={() => void appsQuery.refetch()}\n />\n ) : null}\n {connectedAppsQuery.isError ? (\n <ActionQueryError\n error={connectedAppsQuery.error}\n onRetry={() => void connectedAppsQuery.refetch()}\n />\n ) : null}\n {showAppSkeletons ? (\n <AppsSkeletonGrid />\n ) : filteredActiveApps.length > 0 ||\n filteredDefaultApps.length > 0 ? (\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredActiveApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n isPinned={layout.pinnedIds.includes(app.id.toLowerCase())}\n onTogglePinned={() => togglePinned(app.id)}\n />\n ))}\n {filteredDefaultApps.map((app) => (\n <ConnectedAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n ) : appDiscoveryFailed ? null : !hasSearchResults &&\n searchQuery.trim() ? (\n <WorkspaceAppSearchEmpty\n query={searchQuery}\n onClear={() => setSearchQuery(\"\")}\n />\n ) : searchQuery.trim() ? null : pendingApps.length > 0 ? (\n <EmptyActiveAppsState />\n ) : (\n <EmptyAppsState />\n )}\n </section>\n\n {pendingApps.length > 0 &&\n (!searchQuery.trim() || filteredPendingApps.length > 0) ? (\n <Collapsible\n open={showPending || Boolean(searchQuery.trim())}\n onOpenChange={setShowPending}\n >\n <section className=\"space-y-3 border-t pt-6\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconClockHour4\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.pendingApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.pendingCount\", {\n count: pendingApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showPending || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hidePendingApps\")\n : t(\"dispatch.pages.showPendingApps\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showPending || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredPendingApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n\n {archivedApps.length > 0 &&\n (!searchQuery.trim() || filteredArchivedApps.length > 0) ? (\n <Collapsible\n open={showHidden || Boolean(searchQuery.trim())}\n onOpenChange={setShowHidden}\n >\n <section className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-t pt-4\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <IconEyeOff\n size={16}\n className=\"shrink-0 text-muted-foreground\"\n />\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.hiddenApps\")}\n </h2>\n <p className=\"text-xs text-muted-foreground\">\n {t(\"dispatch.pages.hiddenAppCount\", {\n count: archivedApps.length,\n })}\n </p>\n </div>\n </div>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n >\n {showHidden || Boolean(searchQuery.trim())\n ? t(\"dispatch.pages.hide\")\n : t(\"dispatch.pages.show\")}\n <IconChevronDown\n size={14}\n className={cn(\n \"transition-transform\",\n (showHidden || Boolean(searchQuery.trim())) &&\n \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <AppList className={APP_LIST_GRID_CLASS}>\n {filteredArchivedApps.map((app) => (\n <WorkspaceAppCard\n key={app.id}\n app={app}\n className={APP_LIST_GRID_ROW_CLASS}\n />\n ))}\n </AppList>\n </CollapsibleContent>\n </section>\n </Collapsible>\n ) : null}\n </div>\n </DispatchShell>\n );\n}\n\nfunction AppsSkeletonGrid() {\n return (\n <AppList className={APP_LIST_GRID_CLASS}>\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={cn(\n \"flex min-w-0 items-center gap-3 border-b px-4 py-3.5 last:border-b-0\",\n APP_LIST_GRID_ROW_CLASS,\n )}\n >\n <Skeleton className=\"size-8 shrink-0 rounded-md\" />\n <div className=\"min-w-0 flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-32\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-8 w-24 shrink-0 rounded-md\" />\n </div>\n ))}\n </AppList>\n );\n}\n\nfunction EmptyAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <div className=\"mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <IconApps size={18} />\n </div>\n <h3 className=\"mt-3 text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.noWorkspaceApps\")}\n </h3>\n <p className=\"mx-auto mt-1 max-w-sm text-sm text-muted-foreground\">\n {t(\"dispatch.pages.noWorkspaceAppsDescription\")}\n </p>\n <div className=\"mt-4\">\n <CreateAppPopover\n trigger={\n <Button size=\"sm\" variant=\"outline\">\n <IconPlus size={15} className=\"mr-1.5\" />\n {t(\"dispatch.pages.addApp\", { defaultValue: \"Add app\" })}\n </Button>\n }\n />\n </div>\n </div>\n );\n}\n\nfunction EmptyActiveAppsState() {\n const t = useT();\n return (\n <div className=\"rounded-lg border border-dashed bg-card px-4 py-10 text-center\">\n <p className=\"text-sm font-medium text-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceApps\")}\n </p>\n <p className=\"mx-auto mt-1 max-w-md text-xs text-muted-foreground\">\n {t(\"dispatch.pages.noActiveWorkspaceAppsDescription\")}\n </p>\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { createAuthPlugin } from "@agent-native/core/server";
1
+ import { createToolkitAuthPlugin } from "@agent-native/toolkit/app/auth/server";
2
2
  import { getDispatchConfig } from "../index.js";
3
3
  const DEFAULT_MARKETING = {
4
4
  appName: "Dispatch",
@@ -15,7 +15,7 @@ const dispatchAuthPlugin = async (nitroApp) => {
15
15
  const marketing = authConfig.marketing
16
16
  ? { ...DEFAULT_MARKETING, ...authConfig.marketing }
17
17
  : DEFAULT_MARKETING;
18
- const plugin = createAuthPlugin({
18
+ const plugin = createToolkitAuthPlugin({
19
19
  googleOnly,
20
20
  marketing: marketing,
21
21
  workspaceAppPublicPaths: ["/"],
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/plugins/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,UAAU;IACnB,OAAO,EACL,sGAAsG;IACxG,QAAQ,EAAE;QACR,4DAA4D;QAC5D,6DAA6D;QAC7D,oDAAoD;KACrD;CACO,CAAC;AAEX,MAAM,kBAAkB,GAAG,KAAK,EAAE,QAAa,EAAE,EAAE;IACjD,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC;IAClD,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS;QACpC,CAAC,CAAC,EAAE,GAAG,iBAAiB,EAAE,GAAG,UAAU,CAAC,SAAS,EAAE;QACnD,CAAC,CAAC,iBAAiB,CAAC;IACtB,MAAM,MAAM,GAAG,gBAAgB,CAAC;QAC9B,UAAU;QACV,SAAS,EAAE,SAAgB;QAC3B,uBAAuB,EAAE,CAAC,GAAG,CAAC;QAC9B,4EAA4E;QAC5E,qEAAqE;QACrE,WAAW,EAAE;YACX,GAAG,CAAC,UAAU,CAAC,WAAW,IAAI,EAAE,CAAC;YACjC,8BAA8B;SAC/B;KACF,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import { createAuthPlugin } from \"@agent-native/core/server\";\n\nimport { getDispatchConfig } from \"../index.js\";\n\nconst DEFAULT_MARKETING = {\n appName: \"Dispatch\",\n tagline:\n \"Your AI agent manages secrets, orchestrates other agents, and routes messages across your workspace.\",\n features: [\n \"Centralized vault for secrets with granular per-app grants\",\n \"Cross-agent orchestration and delegation to specialist apps\",\n \"Slack and Telegram routing with approval workflows\",\n ],\n} as const;\n\nconst dispatchAuthPlugin = async (nitroApp: any) => {\n const { auth: authConfig = {} } = getDispatchConfig();\n const googleOnly = authConfig.googleOnly ?? false;\n const marketing = authConfig.marketing\n ? { ...DEFAULT_MARKETING, ...authConfig.marketing }\n : DEFAULT_MARKETING;\n const plugin = createAuthPlugin({\n googleOnly,\n marketing: marketing as any,\n workspaceAppPublicPaths: [\"/\"],\n // This route authenticates its own audience-bound service bearer before any\n // asset lookup; the session guard cannot authenticate peer services.\n publicPaths: [\n ...(authConfig.publicPaths ?? []),\n \"/_agent-native/private-icons\",\n ],\n });\n return plugin(nitroApp);\n};\n\nexport default dispatchAuthPlugin;\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/server/plugins/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,UAAU;IACnB,OAAO,EACL,sGAAsG;IACxG,QAAQ,EAAE;QACR,4DAA4D;QAC5D,6DAA6D;QAC7D,oDAAoD;KACrD;CACO,CAAC;AAEX,MAAM,kBAAkB,GAAG,KAAK,EAAE,QAAa,EAAE,EAAE;IACjD,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC;IAClD,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS;QACpC,CAAC,CAAC,EAAE,GAAG,iBAAiB,EAAE,GAAG,UAAU,CAAC,SAAS,EAAE;QACnD,CAAC,CAAC,iBAAiB,CAAC;IACtB,MAAM,MAAM,GAAG,uBAAuB,CAAC;QACrC,UAAU;QACV,SAAS,EAAE,SAAgB;QAC3B,uBAAuB,EAAE,CAAC,GAAG,CAAC;QAC9B,4EAA4E;QAC5E,qEAAqE;QACrE,WAAW,EAAE;YACX,GAAG,CAAC,UAAU,CAAC,WAAW,IAAI,EAAE,CAAC;YACjC,8BAA8B;SAC/B;KACF,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import { createToolkitAuthPlugin } from \"@agent-native/toolkit/app/auth/server\";\n\nimport { getDispatchConfig } from \"../index.js\";\n\nconst DEFAULT_MARKETING = {\n appName: \"Dispatch\",\n tagline:\n \"Your AI agent manages secrets, orchestrates other agents, and routes messages across your workspace.\",\n features: [\n \"Centralized vault for secrets with granular per-app grants\",\n \"Cross-agent orchestration and delegation to specialist apps\",\n \"Slack and Telegram routing with approval workflows\",\n ],\n} as const;\n\nconst dispatchAuthPlugin = async (nitroApp: any) => {\n const { auth: authConfig = {} } = getDispatchConfig();\n const googleOnly = authConfig.googleOnly ?? false;\n const marketing = authConfig.marketing\n ? { ...DEFAULT_MARKETING, ...authConfig.marketing }\n : DEFAULT_MARKETING;\n const plugin = createToolkitAuthPlugin({\n googleOnly,\n marketing: marketing as any,\n workspaceAppPublicPaths: [\"/\"],\n // This route authenticates its own audience-bound service bearer before any\n // asset lookup; the session guard cannot authenticate peer services.\n publicPaths: [\n ...(authConfig.publicPaths ?? []),\n \"/_agent-native/private-icons\",\n ],\n });\n return plugin(nitroApp);\n};\n\nexport default dispatchAuthPlugin;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/dispatch",
3
- "version": "0.40.13",
3
+ "version": "0.40.14-nightly-20261006033736",
4
4
  "description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -89,7 +89,7 @@
89
89
  "tailwind-merge": "^3.5.0",
90
90
  "vaul": "^1.1.2",
91
91
  "zod": "^4.3.6",
92
- "@agent-native/toolkit": "0.201.1"
92
+ "@agent-native/toolkit": "0.202.0-nightly-20261006033736"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@react-router/dev": "^8.1.0",
@@ -103,10 +103,10 @@
103
103
  "typescript-7": "npm:typescript@^7.0.2",
104
104
  "vite": "8.1.0",
105
105
  "vitest": "^4.1.5",
106
- "@agent-native/core": "0.201.1"
106
+ "@agent-native/core": "0.202.0-nightly-20261006033736"
107
107
  },
108
108
  "peerDependencies": {
109
- "@agent-native/core": ">=0.198.6",
109
+ "@agent-native/core": "0.202.0-nightly-20261006033736",
110
110
  "react": ">=19.2.7",
111
111
  "react-dom": ">=19.2.7",
112
112
  "react-router": ">=8"
@@ -0,0 +1,100 @@
1
+ // @vitest-environment happy-dom
2
+ import React, { act } from "react";
3
+ import { createRoot, type Root } from "react-dom/client";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+
6
+ import type { ConnectedAppSummary } from "../lib/other-apps";
7
+ import { ConnectedAppCard } from "./connected-app-card";
8
+
9
+ vi.mock("./app-icon", () => ({ AppIcon: () => null }));
10
+ vi.mock("./app-open-actions", () => ({
11
+ AppOpenActions: ({ name, href }: { name: string; href: string }) =>
12
+ React.createElement(
13
+ "a",
14
+ { className: "app-open-actions__primary", href },
15
+ name,
16
+ ),
17
+ }));
18
+
19
+ const app: ConnectedAppSummary = {
20
+ id: "clips",
21
+ name: "Clips",
22
+ url: "https://clips.agent-native.com",
23
+ homeUrl: "https://clips.agent-native.com/home",
24
+ source: "builtin",
25
+ };
26
+ const navigation = vi.hoisted(() => ({
27
+ navigate: vi.fn(() => true),
28
+ shouldOpenInTopWindow: vi.fn(() => false),
29
+ }));
30
+
31
+ vi.mock("../lib/workspace-apps", async (importOriginal) => ({
32
+ ...(await importOriginal<typeof import("../lib/workspace-apps")>()),
33
+ navigateToWorkspaceApp: navigation.navigate,
34
+ shouldOpenWorkspaceAppInTopWindow: navigation.shouldOpenInTopWindow,
35
+ }));
36
+
37
+ describe("ConnectedAppCard", () => {
38
+ let container: HTMLDivElement;
39
+ let root: Root;
40
+
41
+ beforeEach(() => {
42
+ vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
43
+ navigation.navigate.mockClear();
44
+ navigation.navigate.mockReturnValue(true);
45
+ navigation.shouldOpenInTopWindow.mockReturnValue(false);
46
+ container = document.createElement("div");
47
+ document.body.appendChild(container);
48
+ root = createRoot(container);
49
+ });
50
+
51
+ afterEach(() => {
52
+ act(() => root.unmount());
53
+ container.remove();
54
+ vi.unstubAllGlobals();
55
+ });
56
+
57
+ it("keeps a native link unless the host surface needs custom navigation", async () => {
58
+ await act(async () => {
59
+ root.render(<ConnectedAppCard app={app} />);
60
+ });
61
+
62
+ const anchor = container.querySelector<HTMLAnchorElement>(
63
+ ".app-open-actions__primary",
64
+ );
65
+ expect(anchor).not.toBeNull();
66
+ expect(anchor?.getAttribute("href")).toContain(
67
+ "https://clips.agent-native.com/home",
68
+ );
69
+ });
70
+
71
+ it("opens built-in app actions through the host window on primary clicks", async () => {
72
+ navigation.shouldOpenInTopWindow.mockReturnValue(true);
73
+ await act(async () => {
74
+ root.render(<ConnectedAppCard app={app} />);
75
+ });
76
+
77
+ const anchor = container.querySelector<HTMLAnchorElement>(
78
+ ".app-open-actions__primary",
79
+ );
80
+ expect(anchor).not.toBeNull();
81
+ const click = new MouseEvent("click", { bubbles: true, cancelable: true });
82
+ anchor?.dispatchEvent(click);
83
+
84
+ expect(navigation.navigate).toHaveBeenCalledWith(anchor?.href);
85
+ expect(navigation.navigate.mock.calls[0][0]).toContain(
86
+ "https://clips.agent-native.com/home",
87
+ );
88
+ expect(click.defaultPrevented).toBe(true);
89
+
90
+ const modifiedClick = new MouseEvent("click", {
91
+ bubbles: true,
92
+ cancelable: true,
93
+ ctrlKey: true,
94
+ });
95
+ anchor?.dispatchEvent(modifiedClick);
96
+
97
+ expect(navigation.navigate).toHaveBeenCalledTimes(1);
98
+ expect(modifiedClick.defaultPrevented).toBe(false);
99
+ });
100
+ });
@@ -1,6 +1,11 @@
1
1
  import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
2
+ import type { MouseEvent } from "react";
2
3
 
3
4
  import type { ConnectedAppSummary } from "../lib/other-apps";
5
+ import {
6
+ navigateToWorkspaceApp,
7
+ shouldOpenWorkspaceAppInTopWindow,
8
+ } from "../lib/workspace-apps";
4
9
  import { AppIcon } from "./app-icon";
5
10
  import { AppListRow } from "./app-list-row";
6
11
  import { AppOpenActions } from "./app-open-actions";
@@ -13,6 +18,31 @@ export function ConnectedAppCard({
13
18
  className?: string;
14
19
  }) {
15
20
  const launchUrl = app.homeUrl ?? app.url;
21
+ const trackedLaunchUrl = withBuilderUtmTrackingParams(launchUrl, {
22
+ campaign: "product",
23
+ content: "dispatch_app",
24
+ });
25
+ const handleActionClick = (event: MouseEvent<HTMLDivElement>) => {
26
+ if (
27
+ event.button !== 0 ||
28
+ event.metaKey ||
29
+ event.ctrlKey ||
30
+ event.shiftKey ||
31
+ event.altKey
32
+ ) {
33
+ return;
34
+ }
35
+ const anchor =
36
+ event.target instanceof Element ? event.target.closest("a") : null;
37
+ if (
38
+ !anchor ||
39
+ anchor.target === "_blank" ||
40
+ !shouldOpenWorkspaceAppInTopWindow()
41
+ ) {
42
+ return;
43
+ }
44
+ if (navigateToWorkspaceApp(anchor.href)) event.preventDefault();
45
+ };
16
46
 
17
47
  return (
18
48
  <AppListRow className={className}>
@@ -25,15 +55,14 @@ export function ConnectedAppCard({
25
55
  {app.description || app.url}
26
56
  </div>
27
57
  </div>
28
- <AppOpenActions
29
- name={app.name}
30
- href={withBuilderUtmTrackingParams(launchUrl, {
31
- campaign: "product",
32
- content: "dispatch_app",
33
- })}
34
- rel="noopener noreferrer"
35
- showNewTabOption
36
- />
58
+ <div className="flex shrink-0" onClickCapture={handleActionClick}>
59
+ <AppOpenActions
60
+ name={app.name}
61
+ href={trackedLaunchUrl}
62
+ rel="noopener noreferrer"
63
+ showNewTabOption
64
+ />
65
+ </div>
37
66
  </AppListRow>
38
67
  );
39
68
  }