@agent-native/dispatch 0.13.1 → 0.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/create-pylon-ticket.js +2 -1
- package/dist/actions/create-pylon-ticket.js.map +1 -1
- package/dist/actions/send-platform-message.js +7 -7
- package/dist/actions/send-platform-message.js.map +1 -1
- package/dist/components/dispatch-control-plane.js +1 -1
- package/dist/components/dispatch-control-plane.js.map +1 -1
- package/dist/components/layout/Header.d.ts.map +1 -1
- package/dist/components/layout/Header.js +0 -1
- package/dist/components/layout/Header.js.map +1 -1
- package/dist/components/layout/Layout.d.ts +4 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +55 -17
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/hooks/use-navigation-state.js +2 -2
- package/dist/hooks/use-navigation-state.js.map +1 -1
- package/dist/routes/pages/settings.d.ts.map +1 -1
- package/dist/routes/pages/settings.js +4 -2
- package/dist/routes/pages/settings.js.map +1 -1
- package/dist/routes/pages/team.d.ts.map +1 -1
- package/dist/routes/pages/team.js +2 -3
- package/dist/routes/pages/team.js.map +1 -1
- package/package.json +2 -2
- package/src/actions/create-pylon-ticket.ts +2 -1
- package/src/actions/send-platform-message.ts +12 -8
- package/src/components/dispatch-control-plane.tsx +1 -1
- package/src/components/layout/Header.tsx +0 -1
- package/src/components/layout/Layout.tsx +229 -102
- package/src/hooks/use-navigation-state.ts +2 -2
- package/src/routes/pages/settings.tsx +70 -47
- package/src/routes/pages/team.tsx +2 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team.js","sourceRoot":"","sources":["../../../src/routes/pages/team.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"team.js","sourceRoot":"","sources":["../../../src/routes/pages/team.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,OAAO,KAAC,QAAQ,IAAC,EAAE,EAAC,gBAAgB,EAAC,OAAO,SAAG,CAAC;AAClD,CAAC","sourcesContent":["import { Navigate } from \"react-router\";\n\nexport function meta() {\n return [{ title: \"Team — Dispatch\" }];\n}\n\nexport default function TeamRoute() {\n return <Navigate to=\"/settings#team\" replace />;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.3",
|
|
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": {
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"typescript": "^6.0.3",
|
|
95
95
|
"vite": "8.1.0",
|
|
96
96
|
"vitest": "^4.1.5",
|
|
97
|
-
"@agent-native/core": "0.
|
|
97
|
+
"@agent-native/core": "0.80.0"
|
|
98
98
|
},
|
|
99
99
|
"peerDependencies": {
|
|
100
100
|
"@agent-native/core": ">=0.8.0",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import { resolveSecret } from "@agent-native/core/server";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
|
|
4
5
|
import { recordAudit } from "../server/lib/dispatch-store.js";
|
|
@@ -33,7 +34,7 @@ export default defineAction({
|
|
|
33
34
|
teamId: z.string().optional(),
|
|
34
35
|
}),
|
|
35
36
|
run: async (input) => {
|
|
36
|
-
const apiKey =
|
|
37
|
+
const apiKey = await resolveSecret("PYLON_API_KEY");
|
|
37
38
|
if (!apiKey) {
|
|
38
39
|
throw new Error(
|
|
39
40
|
"PYLON_API_KEY is not set. Add it to the Dispatch Vault.",
|
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
slackAdapter,
|
|
4
4
|
telegramAdapter,
|
|
5
5
|
emailAdapter,
|
|
6
|
+
isEmailConfigured,
|
|
7
|
+
resolveSecret,
|
|
6
8
|
} from "@agent-native/core/server";
|
|
7
9
|
import { z } from "zod";
|
|
8
10
|
|
|
@@ -16,18 +18,20 @@ function getAdapter(platform: "slack" | "telegram" | "email") {
|
|
|
16
18
|
return platform === "slack" ? slackAdapter() : telegramAdapter();
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
function assertOutboundConfigured(
|
|
20
|
-
|
|
21
|
+
async function assertOutboundConfigured(
|
|
22
|
+
platform: "slack" | "telegram" | "email",
|
|
23
|
+
) {
|
|
24
|
+
if (platform === "slack" && !(await resolveSecret("SLACK_BOT_TOKEN"))) {
|
|
21
25
|
throw new Error("Slack outbound messaging is not configured");
|
|
22
26
|
}
|
|
23
|
-
if (platform === "telegram" && !
|
|
27
|
+
if (platform === "telegram" && !(await resolveSecret("TELEGRAM_BOT_TOKEN"))) {
|
|
24
28
|
throw new Error("Telegram outbound messaging is not configured");
|
|
25
29
|
}
|
|
26
30
|
if (platform === "email") {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
if (
|
|
32
|
+
!(await resolveSecret("EMAIL_AGENT_ADDRESS")) ||
|
|
33
|
+
!(await isEmailConfigured())
|
|
34
|
+
) {
|
|
31
35
|
throw new Error("Email outbound messaging is not configured");
|
|
32
36
|
}
|
|
33
37
|
}
|
|
@@ -59,7 +63,7 @@ export default defineAction({
|
|
|
59
63
|
throw new Error("A platform and destination are required");
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
assertOutboundConfigured(resolvedPlatform);
|
|
66
|
+
await assertOutboundConfigured(resolvedPlatform);
|
|
63
67
|
|
|
64
68
|
const adapter = getAdapter(resolvedPlatform);
|
|
65
69
|
if (!adapter.sendMessageToTarget) {
|
|
@@ -1120,7 +1120,7 @@ function ReadinessPanel({
|
|
|
1120
1120
|
label: "Team",
|
|
1121
1121
|
detail: `${overview?.counts?.linkedIdentities ?? 0} linked identities`,
|
|
1122
1122
|
ok: (overview?.counts?.linkedIdentities ?? 0) > 0,
|
|
1123
|
-
to: "/team",
|
|
1123
|
+
to: "/settings#team",
|
|
1124
1124
|
icon: IconUsersGroup,
|
|
1125
1125
|
},
|
|
1126
1126
|
];
|
|
@@ -33,10 +33,11 @@ import {
|
|
|
33
33
|
IconBroadcast,
|
|
34
34
|
IconFingerprint,
|
|
35
35
|
IconHistory,
|
|
36
|
+
IconLayoutSidebarLeftCollapse,
|
|
37
|
+
IconLayoutSidebarLeftExpand,
|
|
36
38
|
IconPuzzle,
|
|
37
39
|
IconSettings,
|
|
38
40
|
IconShieldCheck,
|
|
39
|
-
IconUsersGroup,
|
|
40
41
|
} from "@tabler/icons-react";
|
|
41
42
|
import {
|
|
42
43
|
useEffect,
|
|
@@ -215,18 +216,12 @@ const OPERATIONS_NAV_ITEMS = [
|
|
|
215
216
|
icon: IconSettings,
|
|
216
217
|
section: "operations",
|
|
217
218
|
},
|
|
218
|
-
{
|
|
219
|
-
id: "team",
|
|
220
|
-
to: "/team",
|
|
221
|
-
label: "Team",
|
|
222
|
-
icon: IconUsersGroup,
|
|
223
|
-
section: "operations",
|
|
224
|
-
},
|
|
225
219
|
] as const satisfies readonly DispatchNavItem[];
|
|
226
220
|
|
|
227
221
|
const EMPTY_NAV_ITEMS: readonly DispatchNavItem[] = [];
|
|
228
222
|
|
|
229
223
|
const CHROMELESS_PATHS = ["/approval"];
|
|
224
|
+
const SIDEBAR_COLLAPSE_KEY = "dispatch.sidebar.collapsed";
|
|
230
225
|
|
|
231
226
|
// Routes whose page renders its own toolbar (with NotificationsBell + AgentToggleButton).
|
|
232
227
|
// Layout still mounts the sidebar + AgentSidebar, but skips its own Header so
|
|
@@ -581,9 +576,15 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
|
|
|
581
576
|
export function NavContent({
|
|
582
577
|
onNavigate,
|
|
583
578
|
extensions,
|
|
579
|
+
collapsed = false,
|
|
580
|
+
collapsible = false,
|
|
581
|
+
onCollapsedChange,
|
|
584
582
|
}: {
|
|
585
583
|
onNavigate?: () => void;
|
|
586
584
|
extensions?: DispatchExtensionConfig;
|
|
585
|
+
collapsed?: boolean;
|
|
586
|
+
collapsible?: boolean;
|
|
587
|
+
onCollapsedChange?: (collapsed: boolean) => void;
|
|
587
588
|
}) {
|
|
588
589
|
const t = useT();
|
|
589
590
|
const location = useLocation();
|
|
@@ -624,45 +625,91 @@ export function NavContent({
|
|
|
624
625
|
const label = navLabel(item);
|
|
625
626
|
return (
|
|
626
627
|
<li key={item.id}>
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
628
|
+
{collapsed ? (
|
|
629
|
+
<Tooltip>
|
|
630
|
+
<TooltipTrigger asChild>
|
|
631
|
+
<NavLink
|
|
632
|
+
to={dispatchNavLinkTarget(item.to)}
|
|
633
|
+
onClick={(event) => {
|
|
634
|
+
if (
|
|
635
|
+
item.id === "chat" &&
|
|
636
|
+
localPathname !== "/chat" &&
|
|
637
|
+
!event.metaKey &&
|
|
638
|
+
!event.ctrlKey &&
|
|
639
|
+
!event.shiftKey &&
|
|
640
|
+
!event.altKey
|
|
641
|
+
) {
|
|
642
|
+
event.preventDefault();
|
|
643
|
+
navigateWithAgentChatViewTransition(
|
|
644
|
+
navigate,
|
|
645
|
+
dispatchNavLinkTarget("/chat"),
|
|
646
|
+
);
|
|
647
|
+
onNavigate?.();
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
onNavigate?.();
|
|
651
|
+
}}
|
|
652
|
+
aria-label={label}
|
|
653
|
+
className={({ isActive }) => {
|
|
654
|
+
const active = isActive || itemMatchesLocalPath;
|
|
655
|
+
return cn(
|
|
656
|
+
"flex h-10 w-10 items-center justify-center rounded-md text-sm",
|
|
657
|
+
active
|
|
658
|
+
? "bg-sidebar-accent font-medium text-sidebar-accent-foreground"
|
|
659
|
+
: "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
660
|
+
);
|
|
661
|
+
}}
|
|
662
|
+
>
|
|
663
|
+
{Icon ? (
|
|
664
|
+
<Icon size={16} className="shrink-0" />
|
|
665
|
+
) : (
|
|
666
|
+
<span className="h-4 w-4 shrink-0" aria-hidden="true" />
|
|
667
|
+
)}
|
|
668
|
+
</NavLink>
|
|
669
|
+
</TooltipTrigger>
|
|
670
|
+
<TooltipContent side="right">{label}</TooltipContent>
|
|
671
|
+
</Tooltip>
|
|
672
|
+
) : (
|
|
673
|
+
<NavLink
|
|
674
|
+
to={dispatchNavLinkTarget(item.to)}
|
|
675
|
+
onClick={(event) => {
|
|
676
|
+
if (
|
|
677
|
+
item.id === "chat" &&
|
|
678
|
+
localPathname !== "/chat" &&
|
|
679
|
+
!event.metaKey &&
|
|
680
|
+
!event.ctrlKey &&
|
|
681
|
+
!event.shiftKey &&
|
|
682
|
+
!event.altKey
|
|
683
|
+
) {
|
|
684
|
+
event.preventDefault();
|
|
685
|
+
navigateWithAgentChatViewTransition(
|
|
686
|
+
navigate,
|
|
687
|
+
dispatchNavLinkTarget("/chat"),
|
|
688
|
+
);
|
|
689
|
+
onNavigate?.();
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
643
692
|
onNavigate?.();
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
</NavLink>
|
|
665
|
-
{item.id === "chat" && itemMatchesLocalPath ? (
|
|
693
|
+
}}
|
|
694
|
+
className={({ isActive }) => {
|
|
695
|
+
const active = isActive || itemMatchesLocalPath;
|
|
696
|
+
return cn(
|
|
697
|
+
"flex h-8 w-full items-center gap-2 rounded-md px-2 text-sm",
|
|
698
|
+
active
|
|
699
|
+
? "bg-sidebar-accent font-medium text-sidebar-accent-foreground"
|
|
700
|
+
: "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
701
|
+
);
|
|
702
|
+
}}
|
|
703
|
+
>
|
|
704
|
+
{Icon ? (
|
|
705
|
+
<Icon size={16} className="shrink-0" />
|
|
706
|
+
) : (
|
|
707
|
+
<span className="h-4 w-4 shrink-0" aria-hidden="true" />
|
|
708
|
+
)}
|
|
709
|
+
<span className="truncate">{label}</span>
|
|
710
|
+
</NavLink>
|
|
711
|
+
)}
|
|
712
|
+
{!collapsed && item.id === "chat" && itemMatchesLocalPath ? (
|
|
666
713
|
<DispatchChatsSection onNavigate={onNavigate} />
|
|
667
714
|
) : null}
|
|
668
715
|
</li>
|
|
@@ -671,70 +718,118 @@ export function NavContent({
|
|
|
671
718
|
|
|
672
719
|
return (
|
|
673
720
|
<>
|
|
674
|
-
<div className="border-b px-
|
|
675
|
-
<div
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
721
|
+
<div className={cn("border-b py-3", collapsed ? "px-1" : "px-4")}>
|
|
722
|
+
<div
|
|
723
|
+
className={cn(
|
|
724
|
+
"flex items-center",
|
|
725
|
+
collapsed ? "justify-center" : "gap-3",
|
|
726
|
+
)}
|
|
727
|
+
>
|
|
728
|
+
{!collapsed && (
|
|
729
|
+
<>
|
|
730
|
+
<div className="flex h-9 w-9 items-center justify-center rounded-xl border bg-card text-foreground">
|
|
731
|
+
<img
|
|
732
|
+
src={appPath("/agent-native-icon-light.svg")}
|
|
733
|
+
alt=""
|
|
734
|
+
aria-hidden="true"
|
|
735
|
+
className="block h-4 w-auto shrink-0 dark:hidden"
|
|
736
|
+
/>
|
|
737
|
+
<img
|
|
738
|
+
src={appPath("/agent-native-icon-dark.svg")}
|
|
739
|
+
alt=""
|
|
740
|
+
aria-hidden="true"
|
|
741
|
+
className="hidden h-4 w-auto shrink-0 dark:block"
|
|
742
|
+
/>
|
|
743
|
+
</div>
|
|
744
|
+
<div className="min-w-0 flex-1">
|
|
745
|
+
<div className="truncate text-sm font-semibold text-foreground">
|
|
746
|
+
{workspaceLabel ?? "Dispatch"}
|
|
747
|
+
</div>
|
|
748
|
+
<div className="truncate text-xs text-muted-foreground">
|
|
749
|
+
{workspaceLabel
|
|
750
|
+
? t("dispatch.sidebar.workspaceSubtitle", {
|
|
751
|
+
count: ws?.appCount ?? 0,
|
|
752
|
+
})
|
|
753
|
+
: t("dispatch.sidebar.workspaceControlPlane")}
|
|
754
|
+
</div>
|
|
755
|
+
</div>
|
|
756
|
+
</>
|
|
757
|
+
)}
|
|
758
|
+
{collapsible ? (
|
|
759
|
+
<Tooltip>
|
|
760
|
+
<TooltipTrigger asChild>
|
|
761
|
+
<button
|
|
762
|
+
type="button"
|
|
763
|
+
onClick={() => onCollapsedChange?.(!collapsed)}
|
|
764
|
+
aria-label={
|
|
765
|
+
collapsed
|
|
766
|
+
? t("sidebar.expandSidebar")
|
|
767
|
+
: t("sidebar.collapseSidebar")
|
|
768
|
+
}
|
|
769
|
+
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-sidebar-foreground/65 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
|
|
770
|
+
>
|
|
771
|
+
{collapsed ? (
|
|
772
|
+
<IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
|
|
773
|
+
) : (
|
|
774
|
+
<IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
|
|
775
|
+
)}
|
|
776
|
+
</button>
|
|
777
|
+
</TooltipTrigger>
|
|
778
|
+
<TooltipContent side="right">
|
|
779
|
+
{collapsed
|
|
780
|
+
? t("sidebar.expandSidebar")
|
|
781
|
+
: t("sidebar.collapseSidebar")}
|
|
782
|
+
</TooltipContent>
|
|
783
|
+
</Tooltip>
|
|
784
|
+
) : null}
|
|
702
785
|
</div>
|
|
703
786
|
</div>
|
|
704
787
|
|
|
705
788
|
<div className="flex min-h-0 flex-1 flex-col overflow-y-auto">
|
|
706
|
-
<nav className="px-
|
|
707
|
-
<ul
|
|
789
|
+
<nav className={cn("py-3", collapsed ? "px-1" : "px-2")}>
|
|
790
|
+
<ul
|
|
791
|
+
className={cn(
|
|
792
|
+
"space-y-0.5",
|
|
793
|
+
collapsed && "flex flex-col items-center",
|
|
794
|
+
)}
|
|
795
|
+
>
|
|
796
|
+
{(collapsed
|
|
797
|
+
? [...primaryNavItems, ...operationsNavItems]
|
|
798
|
+
: primaryNavItems
|
|
799
|
+
).map(renderNavItem)}
|
|
800
|
+
</ul>
|
|
708
801
|
</nav>
|
|
709
802
|
|
|
710
|
-
|
|
711
|
-
<div className="
|
|
712
|
-
<
|
|
713
|
-
<
|
|
714
|
-
<
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
803
|
+
{!collapsed ? (
|
|
804
|
+
<div className="mt-auto shrink-0">
|
|
805
|
+
<div className="px-2 py-2">
|
|
806
|
+
<details className="group" open={operationsOpen}>
|
|
807
|
+
<summary className="flex h-8 cursor-pointer list-none items-center justify-between rounded-md px-2 text-xs font-medium uppercase text-sidebar-foreground/50 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground [&::-webkit-details-marker]:hidden">
|
|
808
|
+
<span>{t("dispatch.nav.operations")}</span>
|
|
809
|
+
<IconChevronDown
|
|
810
|
+
size={14}
|
|
811
|
+
className="transition-transform group-open:rotate-180"
|
|
812
|
+
/>
|
|
813
|
+
</summary>
|
|
814
|
+
<ul className="mt-1 space-y-0.5">
|
|
815
|
+
{operationsNavItems.map(renderNavItem)}
|
|
816
|
+
</ul>
|
|
817
|
+
</details>
|
|
818
|
+
</div>
|
|
725
819
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
820
|
+
<div className="px-2 py-1">
|
|
821
|
+
<ExtensionsSidebarSection />
|
|
822
|
+
</div>
|
|
729
823
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
824
|
+
<div className="px-3 py-2">
|
|
825
|
+
<OrgSwitcher />
|
|
826
|
+
</div>
|
|
733
827
|
|
|
734
|
-
|
|
735
|
-
|
|
828
|
+
<div className="px-3 py-2">
|
|
829
|
+
<FeedbackButton />
|
|
830
|
+
</div>
|
|
736
831
|
</div>
|
|
737
|
-
|
|
832
|
+
) : null}
|
|
738
833
|
</div>
|
|
739
834
|
</>
|
|
740
835
|
);
|
|
@@ -751,6 +846,14 @@ export function Layout({
|
|
|
751
846
|
const location = useLocation();
|
|
752
847
|
const navigate = useNavigate();
|
|
753
848
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
849
|
+
const [sidebarCollapsed, setSidebarCollapsed] = useState(() => {
|
|
850
|
+
if (typeof window === "undefined") return false;
|
|
851
|
+
try {
|
|
852
|
+
return window.localStorage.getItem(SIDEBAR_COLLAPSE_KEY) === "1";
|
|
853
|
+
} catch {
|
|
854
|
+
return false;
|
|
855
|
+
}
|
|
856
|
+
});
|
|
754
857
|
const localPathname = localDispatchPath(location.pathname);
|
|
755
858
|
const isChatRoute =
|
|
756
859
|
localPathname === "/chat" || localPathname.startsWith("/chat/");
|
|
@@ -766,6 +869,18 @@ export function Layout({
|
|
|
766
869
|
};
|
|
767
870
|
useAgentChatHomeHandoffLinks(chatHandoffLinkOptions);
|
|
768
871
|
|
|
872
|
+
useEffect(() => {
|
|
873
|
+
if (typeof window === "undefined") return;
|
|
874
|
+
try {
|
|
875
|
+
window.localStorage.setItem(
|
|
876
|
+
SIDEBAR_COLLAPSE_KEY,
|
|
877
|
+
sidebarCollapsed ? "1" : "0",
|
|
878
|
+
);
|
|
879
|
+
} catch {
|
|
880
|
+
// Ignore storage failures; the in-memory preference still works.
|
|
881
|
+
}
|
|
882
|
+
}, [sidebarCollapsed]);
|
|
883
|
+
|
|
769
884
|
if (CHROMELESS_PATHS.some((path) => localPathname === path)) {
|
|
770
885
|
return <>{children}</>;
|
|
771
886
|
}
|
|
@@ -825,8 +940,19 @@ export function Layout({
|
|
|
825
940
|
return (
|
|
826
941
|
<HeaderActionsProvider>
|
|
827
942
|
<div className="agent-layout-shell flex h-screen w-full overflow-hidden bg-background">
|
|
828
|
-
<aside
|
|
829
|
-
|
|
943
|
+
<aside
|
|
944
|
+
data-collapsed={sidebarCollapsed ? "true" : "false"}
|
|
945
|
+
className={cn(
|
|
946
|
+
"agent-layout-left-drawer hidden shrink-0 flex-col border-e bg-sidebar text-sidebar-foreground transition-[width] duration-200 ease-out lg:flex",
|
|
947
|
+
sidebarCollapsed ? "w-12" : "w-64",
|
|
948
|
+
)}
|
|
949
|
+
>
|
|
950
|
+
<NavContent
|
|
951
|
+
extensions={extensions}
|
|
952
|
+
collapsed={sidebarCollapsed}
|
|
953
|
+
collapsible
|
|
954
|
+
onCollapsedChange={setSidebarCollapsed}
|
|
955
|
+
/>
|
|
830
956
|
</aside>
|
|
831
957
|
|
|
832
958
|
<Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
|
|
@@ -843,6 +969,7 @@ export function Layout({
|
|
|
843
969
|
<div className="flex h-full w-full flex-col">
|
|
844
970
|
<NavContent
|
|
845
971
|
extensions={extensions}
|
|
972
|
+
collapsed={false}
|
|
846
973
|
onNavigate={() => setMobileOpen(false)}
|
|
847
974
|
/>
|
|
848
975
|
</div>
|
|
@@ -219,7 +219,7 @@ function resolveView(
|
|
|
219
219
|
if (pathname.startsWith("/audit")) return "audit";
|
|
220
220
|
if (pathname.startsWith("/dreams")) return "dreams";
|
|
221
221
|
if (pathname.startsWith("/thread-debug")) return "thread-debug";
|
|
222
|
-
if (pathname.startsWith("/team")) return "
|
|
222
|
+
if (pathname.startsWith("/team")) return "settings";
|
|
223
223
|
return "overview";
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -271,7 +271,7 @@ function resolvePath(
|
|
|
271
271
|
case "threads":
|
|
272
272
|
return "/thread-debug";
|
|
273
273
|
case "team":
|
|
274
|
-
return "/team";
|
|
274
|
+
return "/settings#team";
|
|
275
275
|
case "extensions":
|
|
276
276
|
return command?.extensionId
|
|
277
277
|
? `/extensions/${encodeURIComponent(command.extensionId)}`
|