@agent-native/dispatch 0.40.0 → 0.40.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.
- package/CHANGELOG.md +38 -12
- package/dist/actions/provider-api-register.d.ts +7 -7
- package/dist/components/app-open-actions.d.ts +1 -1
- package/dist/components/app-open-actions.d.ts.map +1 -1
- package/dist/components/app-open-actions.js +1 -1
- package/dist/components/app-open-actions.js.map +1 -1
- package/dist/components/app-row-settings.js +1 -1
- package/dist/components/app-row-settings.js.map +1 -1
- package/dist/components/automation-create-dialog.js +2 -2
- package/dist/components/automation-create-dialog.js.map +1 -1
- package/dist/components/automation-details-panel.js +1 -1
- package/dist/components/automation-details-panel.js.map +1 -1
- package/dist/components/chat-home-apps.js +1 -1
- package/dist/components/chat-home-apps.js.map +1 -1
- package/dist/components/create-app-popover.js +3 -3
- package/dist/components/create-app-popover.js.map +1 -1
- package/dist/components/dispatch-control-plane.d.ts.map +1 -1
- package/dist/components/dispatch-control-plane.js +9 -30
- package/dist/components/dispatch-control-plane.js.map +1 -1
- package/dist/components/layout/Header.js +2 -2
- package/dist/components/layout/Header.js.map +1 -1
- package/dist/components/layout/Layout.d.ts +6 -5
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +73 -113
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
- package/dist/components/layout/workspace-apps-rail.js +7 -19
- package/dist/components/layout/workspace-apps-rail.js.map +1 -1
- package/dist/components/messaging-setup-panel.js +2 -1
- package/dist/components/messaging-setup-panel.js.map +1 -1
- package/dist/components/workspace-app-card.js +2 -2
- package/dist/components/workspace-app-card.js.map +1 -1
- package/dist/components/workspace-app-host.d.ts +1 -1
- package/dist/components/workspace-app-host.d.ts.map +1 -1
- package/dist/components/workspace-app-host.js +7 -74
- package/dist/components/workspace-app-host.js.map +1 -1
- package/dist/hooks/use-navigation-state.js +1 -1
- package/dist/hooks/use-navigation-state.js.map +1 -1
- package/dist/lib/workspace-apps.js +1 -1
- package/dist/lib/workspace-apps.js.map +1 -1
- package/dist/routes/pages/$appId.js +1 -1
- package/dist/routes/pages/$appId.js.map +1 -1
- package/dist/routes/pages/_index.js +1 -1
- package/dist/routes/pages/_index.js.map +1 -1
- package/dist/routes/pages/admin._index.js +1 -1
- package/dist/routes/pages/admin._index.js.map +1 -1
- package/dist/routes/pages/agent-integrations.js +1 -1
- package/dist/routes/pages/agent-integrations.js.map +1 -1
- package/dist/routes/pages/apps.d.ts.map +1 -1
- package/dist/routes/pages/apps.js +3 -43
- package/dist/routes/pages/apps.js.map +1 -1
- package/dist/routes/pages/browser-chat.js +1 -1
- package/dist/routes/pages/browser-chat.js.map +1 -1
- package/dist/routes/pages/chat.d.ts.map +1 -1
- package/dist/routes/pages/chat.js +24 -43
- package/dist/routes/pages/chat.js.map +1 -1
- package/dist/routes/pages/extensions.$id.js +1 -1
- package/dist/routes/pages/extensions.$id.js.map +1 -1
- package/dist/routes/pages/extensions._index.js +1 -1
- package/dist/routes/pages/extensions._index.js.map +1 -1
- package/dist/routes/pages/integrations.js +1 -1
- package/dist/routes/pages/integrations.js.map +1 -1
- package/dist/routes/pages/new-app.js +1 -1
- package/dist/routes/pages/new-app.js.map +1 -1
- package/dist/routes/pages/operations.js +2 -2
- package/dist/routes/pages/operations.js.map +1 -1
- package/dist/routes/pages/overview.d.ts +2 -2
- package/dist/routes/pages/settings.d.ts.map +1 -1
- package/dist/routes/pages/settings.js +26 -8
- package/dist/routes/pages/settings.js.map +1 -1
- package/dist/routes/pages/tools.$id.js +1 -1
- package/dist/routes/pages/tools.$id.js.map +1 -1
- package/dist/routes/pages/tools._index.js +1 -1
- package/dist/routes/pages/tools._index.js.map +1 -1
- package/dist/routes/pages/vault.d.ts +1 -1
- package/dist/routes/pages/vault.js +1 -1
- package/dist/routes/pages/vault.js.map +1 -1
- package/dist/shared/app-roles.js.map +1 -1
- package/package.json +3 -3
- package/src/components/app-open-actions.tsx +1 -1
- package/src/components/app-row-settings.tsx +1 -1
- package/src/components/automation-create-dialog.tsx +7 -7
- package/src/components/automation-details-panel.tsx +1 -1
- package/src/components/chat-home-apps.tsx +1 -1
- package/src/components/create-app-popover.spec.tsx +5 -7
- package/src/components/create-app-popover.tsx +3 -3
- package/src/components/dispatch-control-plane.spec.tsx +12 -19
- package/src/components/dispatch-control-plane.tsx +10 -84
- package/src/components/layout/Header.tsx +2 -2
- package/src/components/layout/Layout.app-chat.spec.ts +1 -0
- package/src/components/layout/Layout.spec.tsx +18 -20
- package/src/components/layout/Layout.tsx +153 -205
- package/src/components/layout/workspace-apps-rail.spec.tsx +79 -0
- package/src/components/layout/workspace-apps-rail.tsx +6 -30
- package/src/components/messaging-setup-panel.tsx +1 -1
- package/src/components/workspace-app-card.tsx +2 -2
- package/src/components/workspace-app-chat-rail.spec.tsx +1 -1
- package/src/components/workspace-app-host.spec.tsx +19 -19
- package/src/components/workspace-app-host.tsx +12 -129
- package/src/hooks/use-navigation-state.ts +1 -1
- package/src/lib/workspace-apps.ts +1 -1
- package/src/routes/pages/$appId.tsx +1 -1
- package/src/routes/pages/_index.tsx +1 -1
- package/src/routes/pages/admin._index.tsx +1 -1
- package/src/routes/pages/agent-integrations.tsx +1 -1
- package/src/routes/pages/apps.tsx +2 -86
- package/src/routes/pages/automations.spec.tsx +1 -1
- package/src/routes/pages/browser-chat.tsx +1 -1
- package/src/routes/pages/chat.spec.tsx +23 -46
- package/src/routes/pages/chat.tsx +20 -57
- package/src/routes/pages/extensions.$id.tsx +1 -1
- package/src/routes/pages/extensions._index.tsx +1 -1
- package/src/routes/pages/integrations.tsx +1 -1
- package/src/routes/pages/new-app.tsx +1 -1
- package/src/routes/pages/operations.tsx +2 -2
- package/src/routes/pages/settings.spec.tsx +30 -8
- package/src/routes/pages/settings.tsx +75 -7
- package/src/routes/pages/tools.$id.tsx +1 -1
- package/src/routes/pages/tools._index.tsx +1 -1
- package/src/routes/pages/vault.tsx +1 -1
- package/src/shared/app-roles.ts +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useFormatters, useT } from "@agent-native/core/client/i18n";
|
|
2
2
|
import {
|
|
3
|
-
channelIcon,
|
|
4
3
|
disconnectManagedIntegrationInstallation,
|
|
5
4
|
hasMissingRequiredCredentials,
|
|
6
5
|
listManagedIntegrationBudgets,
|
|
@@ -26,6 +25,7 @@ import {
|
|
|
26
25
|
listBuiltInChannelIntegrations,
|
|
27
26
|
type IntegrationCatalogEntry,
|
|
28
27
|
} from "@agent-native/core/integrations";
|
|
28
|
+
import { channelIcon } from "@agent-native/toolkit/app/integrations";
|
|
29
29
|
import {
|
|
30
30
|
IconBrandSlack,
|
|
31
31
|
IconCheck,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { APP_ACTION_MENU_CONTENT_CLASS } from "@agent-native/core/client/chat-first";
|
|
2
1
|
import {
|
|
3
2
|
useActionMutation,
|
|
4
3
|
useActionQuery,
|
|
5
4
|
} from "@agent-native/core/client/hooks";
|
|
6
5
|
import { useT } from "@agent-native/core/client/i18n";
|
|
7
|
-
import {
|
|
6
|
+
import { APP_ACTION_MENU_CONTENT_CLASS } from "@agent-native/toolkit/app/chat/chat-first";
|
|
7
|
+
import { ShareButton } from "@agent-native/toolkit/app/sharing";
|
|
8
8
|
import {
|
|
9
9
|
IconChevronDown,
|
|
10
10
|
IconChevronRight,
|
|
@@ -25,7 +25,7 @@ vi.mock("@agent-native/core/client/api-path", () => ({
|
|
|
25
25
|
agentNativePath: (path: string) => path,
|
|
26
26
|
}));
|
|
27
27
|
|
|
28
|
-
vi.mock("@agent-native/
|
|
28
|
+
vi.mock("@agent-native/toolkit/app/chat/chat-first", () => ({
|
|
29
29
|
ChatFirstAppPane: ({ app }: { app: { name: string } | null }) => (
|
|
30
30
|
<div data-app-pane>{app?.name}</div>
|
|
31
31
|
),
|
|
@@ -47,7 +47,7 @@ const clientState = vi.hoisted(() => {
|
|
|
47
47
|
};
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
vi.mock("@agent-native/
|
|
50
|
+
vi.mock("@agent-native/toolkit/app/chat/chat-first", () => ({
|
|
51
51
|
CHAT_FIRST_DEFAULT_APP_IDS: [
|
|
52
52
|
"content",
|
|
53
53
|
"design",
|
|
@@ -91,6 +91,10 @@ vi.mock("@agent-native/core/client/chat-first", () => ({
|
|
|
91
91
|
defaultChatFirstCopy: (key: string) => key,
|
|
92
92
|
}));
|
|
93
93
|
|
|
94
|
+
vi.mock("@agent-native/toolkit/app/chat", () => ({
|
|
95
|
+
AgentSidebar: () => null,
|
|
96
|
+
}));
|
|
97
|
+
|
|
94
98
|
vi.mock("@agent-native/core/client/feature-flags", () => ({
|
|
95
99
|
useFeatureFlag: () => clientState.workspaceSsoEnabled,
|
|
96
100
|
}));
|
|
@@ -249,37 +253,33 @@ describe("WorkspaceAppKeepAlive", () => {
|
|
|
249
253
|
)?.params,
|
|
250
254
|
).toEqual({ includeAgentCards: false, includeArchived: true });
|
|
251
255
|
expect(
|
|
252
|
-
clientState.
|
|
253
|
-
?.options?.enabled,
|
|
256
|
+
clientState.actionQueryParams.some((query) => query.name === "list_apps"),
|
|
254
257
|
).toBe(false);
|
|
255
258
|
});
|
|
256
259
|
|
|
257
|
-
it("
|
|
260
|
+
it("does not resolve apps granted through Dispatch MCP", async () => {
|
|
258
261
|
await act(async () => {
|
|
259
262
|
root.render(
|
|
260
|
-
<
|
|
263
|
+
<MemoryRouter>
|
|
264
|
+
<WorkspaceAppKeepAlive activeAppId="analytics.agent-native.com" />
|
|
265
|
+
</MemoryRouter>,
|
|
261
266
|
);
|
|
262
267
|
await Promise.resolve();
|
|
263
268
|
await Promise.resolve();
|
|
264
269
|
});
|
|
265
270
|
|
|
266
|
-
expect(
|
|
267
|
-
container.querySelector(
|
|
268
|
-
'[data-dispatch-workspace-app-cache-entry="analytics.agent-native.com"]',
|
|
269
|
-
),
|
|
270
|
-
).not.toBeNull();
|
|
271
271
|
expect(
|
|
272
272
|
container.querySelector('[data-chat-first-app-status="ready"]'),
|
|
273
|
-
).
|
|
274
|
-
expect(clientState.legacyMutateAsync).
|
|
275
|
-
app: "analytics.agent-native.com",
|
|
276
|
-
url: "https://analytics.agent-native.com/home",
|
|
277
|
-
chrome: "minimal",
|
|
278
|
-
});
|
|
273
|
+
).toBeNull();
|
|
274
|
+
expect(clientState.legacyMutateAsync).not.toHaveBeenCalled();
|
|
279
275
|
expect(
|
|
280
|
-
clientState.
|
|
281
|
-
|
|
282
|
-
|
|
276
|
+
clientState.actionQueryParams.some((query) => query.name === "list_apps"),
|
|
277
|
+
).toBe(false);
|
|
278
|
+
expect(
|
|
279
|
+
clientState.actionQueryParams.some(
|
|
280
|
+
(query) => query.name === "list-connected-agents",
|
|
281
|
+
),
|
|
282
|
+
).toBe(false);
|
|
283
283
|
});
|
|
284
284
|
|
|
285
285
|
it("does not resolve archived workspace apps from granted discovery", async () => {
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import { AgentSidebar } from "@agent-native/core/client/agent-chat";
|
|
2
1
|
import { agentNativePath } from "@agent-native/core/client/api-path";
|
|
3
|
-
import {
|
|
4
|
-
ChatFirstAppPane,
|
|
5
|
-
defaultChatFirstCopy,
|
|
6
|
-
type ChatFirstCopy,
|
|
7
|
-
} from "@agent-native/core/client/chat-first";
|
|
8
2
|
import { useFeatureFlag } from "@agent-native/core/client/feature-flags";
|
|
9
3
|
import {
|
|
10
4
|
useActionMutation,
|
|
@@ -13,6 +7,12 @@ import {
|
|
|
13
7
|
import { useT } from "@agent-native/core/client/i18n";
|
|
14
8
|
import { AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE } from "@agent-native/core/client/navigation";
|
|
15
9
|
import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
|
|
10
|
+
import { AgentSidebar } from "@agent-native/toolkit/app/chat";
|
|
11
|
+
import {
|
|
12
|
+
ChatFirstAppPane,
|
|
13
|
+
defaultChatFirstCopy,
|
|
14
|
+
type ChatFirstCopy,
|
|
15
|
+
} from "@agent-native/toolkit/app/chat/chat-first";
|
|
16
16
|
import {
|
|
17
17
|
IconAlertTriangle,
|
|
18
18
|
IconArrowLeft,
|
|
@@ -30,9 +30,7 @@ import {
|
|
|
30
30
|
import { Link } from "react-router";
|
|
31
31
|
|
|
32
32
|
import { isEmbedSessionExpiredMessage } from "../lib/embed-session-recovery";
|
|
33
|
-
import { filterOtherApps, type ConnectedAppSummary } from "../lib/other-apps";
|
|
34
33
|
import {
|
|
35
|
-
mergeChatFirstWorkspaceApps,
|
|
36
34
|
isWorkspaceSsoApp,
|
|
37
35
|
isDispatchWorkspaceAppId,
|
|
38
36
|
navigateToWorkspaceApp,
|
|
@@ -63,16 +61,6 @@ interface EmbedSessionInput {
|
|
|
63
61
|
chrome: "minimal";
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
interface GrantedWorkspaceAppSummary {
|
|
67
|
-
id: string;
|
|
68
|
-
name: string;
|
|
69
|
-
url?: string | null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
interface GrantedWorkspaceAppsResult {
|
|
73
|
-
apps: GrantedWorkspaceAppSummary[];
|
|
74
|
-
}
|
|
75
|
-
|
|
76
64
|
type WorkspaceAppTheme = "light" | "dark";
|
|
77
65
|
function buildWorkspaceAppThemeUpdate(theme: WorkspaceAppTheme) {
|
|
78
66
|
return {
|
|
@@ -568,104 +556,10 @@ export function WorkspaceAppHost({
|
|
|
568
556
|
"list-workspace-apps",
|
|
569
557
|
{ includeAgentCards: false, includeArchived: true },
|
|
570
558
|
);
|
|
571
|
-
const
|
|
572
|
-
() =>
|
|
573
|
-
|
|
574
|
-
(item) =>
|
|
575
|
-
!item.archived &&
|
|
576
|
-
item.id.trim().toLowerCase() === appId?.trim().toLowerCase(),
|
|
577
|
-
) ?? null,
|
|
578
|
-
[appId, workspaceAppsQuery.data],
|
|
579
|
-
);
|
|
580
|
-
const grantedAppsQuery = useActionQuery<GrantedWorkspaceAppsResult>(
|
|
581
|
-
"list_apps",
|
|
582
|
-
{},
|
|
583
|
-
{
|
|
584
|
-
enabled: !workspaceAppsQuery.isLoading && !mountedWorkspaceApp,
|
|
585
|
-
},
|
|
586
|
-
);
|
|
587
|
-
const connectedAppsQuery = useActionQuery<ConnectedAppSummary[]>(
|
|
588
|
-
"list-connected-agents",
|
|
589
|
-
{},
|
|
590
|
-
{
|
|
591
|
-
enabled: !workspaceAppsQuery.isLoading && !mountedWorkspaceApp,
|
|
592
|
-
},
|
|
593
|
-
);
|
|
594
|
-
const enabledBuiltinAppIds = useMemo(
|
|
595
|
-
() =>
|
|
596
|
-
connectedAppsQuery.data
|
|
597
|
-
?.filter((app) => app.source === "builtin")
|
|
598
|
-
.map((app) => app.id),
|
|
599
|
-
[connectedAppsQuery.data],
|
|
559
|
+
const apps = useMemo(
|
|
560
|
+
() => (workspaceAppsQuery.data ?? []).filter((item) => !item.archived),
|
|
561
|
+
[workspaceAppsQuery.data],
|
|
600
562
|
);
|
|
601
|
-
const workspaceApps = useMemo(
|
|
602
|
-
() =>
|
|
603
|
-
mergeChatFirstWorkspaceApps(
|
|
604
|
-
workspaceAppsQuery.data,
|
|
605
|
-
enabledBuiltinAppIds,
|
|
606
|
-
),
|
|
607
|
-
[enabledBuiltinAppIds, workspaceAppsQuery.data],
|
|
608
|
-
);
|
|
609
|
-
const visibleWorkspaceApps = useMemo(
|
|
610
|
-
() => workspaceApps.filter((item) => !item.archived),
|
|
611
|
-
[workspaceApps],
|
|
612
|
-
);
|
|
613
|
-
const workspaceAppIds = useMemo(
|
|
614
|
-
() => new Set(workspaceApps.map((item) => item.id.trim().toLowerCase())),
|
|
615
|
-
[workspaceApps],
|
|
616
|
-
);
|
|
617
|
-
const apps = useMemo(() => {
|
|
618
|
-
const merged = new Map<string, WorkspaceAppSummary>();
|
|
619
|
-
|
|
620
|
-
for (const app of visibleWorkspaceApps) {
|
|
621
|
-
merged.set(app.id.trim().toLowerCase(), app);
|
|
622
|
-
}
|
|
623
|
-
for (const app of grantedAppsQuery.data?.apps ?? []) {
|
|
624
|
-
const id = app.id.trim();
|
|
625
|
-
if (
|
|
626
|
-
!id ||
|
|
627
|
-
workspaceAppIds.has(id.toLowerCase()) ||
|
|
628
|
-
merged.has(id.toLowerCase())
|
|
629
|
-
) {
|
|
630
|
-
continue;
|
|
631
|
-
}
|
|
632
|
-
merged.set(id.toLowerCase(), {
|
|
633
|
-
id,
|
|
634
|
-
name: app.name.trim() || id,
|
|
635
|
-
path: "",
|
|
636
|
-
url: app.url?.trim() || null,
|
|
637
|
-
status: "ready",
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
for (const app of filterOtherApps(
|
|
641
|
-
connectedAppsQuery.data ?? [],
|
|
642
|
-
visibleWorkspaceApps,
|
|
643
|
-
)) {
|
|
644
|
-
const id = app.id.trim();
|
|
645
|
-
if (
|
|
646
|
-
!id ||
|
|
647
|
-
workspaceAppIds.has(id.toLowerCase()) ||
|
|
648
|
-
merged.has(id.toLowerCase())
|
|
649
|
-
) {
|
|
650
|
-
continue;
|
|
651
|
-
}
|
|
652
|
-
merged.set(id.toLowerCase(), {
|
|
653
|
-
id,
|
|
654
|
-
name: app.name.trim() || id,
|
|
655
|
-
description: app.description,
|
|
656
|
-
path: "",
|
|
657
|
-
url: app.homeUrl?.trim() || app.url.trim(),
|
|
658
|
-
status: "ready",
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
return [...merged.values()];
|
|
663
|
-
}, [
|
|
664
|
-
connectedAppsQuery.data,
|
|
665
|
-
grantedAppsQuery.data?.apps,
|
|
666
|
-
visibleWorkspaceApps,
|
|
667
|
-
workspaceAppIds,
|
|
668
|
-
]);
|
|
669
563
|
const app = useMemo(
|
|
670
564
|
() =>
|
|
671
565
|
apps.find(
|
|
@@ -673,17 +567,10 @@ export function WorkspaceAppHost({
|
|
|
673
567
|
) ?? null,
|
|
674
568
|
[appId, apps],
|
|
675
569
|
);
|
|
676
|
-
const isLoading =
|
|
677
|
-
workspaceAppsQuery.isLoading ||
|
|
678
|
-
grantedAppsQuery.isLoading ||
|
|
679
|
-
connectedAppsQuery.isLoading;
|
|
570
|
+
const isLoading = workspaceAppsQuery.isLoading;
|
|
680
571
|
const queryError = workspaceAppsQuery.isError
|
|
681
572
|
? workspaceAppsQuery.error
|
|
682
|
-
:
|
|
683
|
-
? grantedAppsQuery.error
|
|
684
|
-
: connectedAppsQuery.isError
|
|
685
|
-
? connectedAppsQuery.error
|
|
686
|
-
: null;
|
|
573
|
+
: null;
|
|
687
574
|
|
|
688
575
|
if (queryError && !app) {
|
|
689
576
|
return (
|
|
@@ -691,11 +578,7 @@ export function WorkspaceAppHost({
|
|
|
691
578
|
<div className="w-full max-w-2xl">
|
|
692
579
|
<ActionQueryError
|
|
693
580
|
error={queryError}
|
|
694
|
-
onRetry={() =>
|
|
695
|
-
void workspaceAppsQuery.refetch();
|
|
696
|
-
void grantedAppsQuery.refetch();
|
|
697
|
-
void connectedAppsQuery.refetch();
|
|
698
|
-
}}
|
|
581
|
+
onRetry={() => void workspaceAppsQuery.refetch()}
|
|
699
582
|
/>
|
|
700
583
|
</div>
|
|
701
584
|
</div>
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
appBasePath,
|
|
8
8
|
appPath,
|
|
9
9
|
} from "@agent-native/core/client/api-path";
|
|
10
|
-
import { extensionIdFromPathname } from "@agent-native/core/client/extensions";
|
|
11
10
|
import { getBrowserTabId } from "@agent-native/core/client/hooks";
|
|
11
|
+
import { extensionIdFromPathname } from "@agent-native/toolkit/app/extensions";
|
|
12
12
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
13
13
|
import { useEffect } from "react";
|
|
14
14
|
import { useLocation, useNavigate } from "react-router";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CHAT_FIRST_DEFAULT_APP_IDS } from "@agent-native/core/client/chat-first";
|
|
2
1
|
import {
|
|
3
2
|
getClientSurface,
|
|
4
3
|
isInBuilderFrame,
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
resolveEnvironmentTargets,
|
|
9
8
|
withBuilderUtmTrackingParams,
|
|
10
9
|
} from "@agent-native/core/shared";
|
|
10
|
+
import { CHAT_FIRST_DEFAULT_APP_IDS } from "@agent-native/toolkit/app/chat/chat-first";
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
CANONICAL_WORKSPACE_SSO_APP_ORIGINS,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { appPath } from "@agent-native/core/client/api-path";
|
|
2
2
|
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
3
3
|
import { useT } from "@agent-native/core/client/i18n";
|
|
4
|
-
import { DefaultSpinner } from "@agent-native/core/client/ui";
|
|
5
4
|
import { withSsrHtmlContentType } from "@agent-native/core/shared";
|
|
6
5
|
import { withBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
|
|
6
|
+
import { DefaultSpinner } from "@agent-native/toolkit/app/shared";
|
|
7
7
|
import {
|
|
8
8
|
IconArrowLeft,
|
|
9
9
|
IconArrowUpRight,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { appPath } from "@agent-native/core/client/api-path";
|
|
2
|
-
import { DefaultSpinner } from "@agent-native/core/client/ui";
|
|
3
2
|
import { withSsrHtmlContentType } from "@agent-native/core/shared";
|
|
3
|
+
import { DefaultSpinner } from "@agent-native/toolkit/app/shared";
|
|
4
4
|
import { redirect, type LoaderFunctionArgs } from "react-router";
|
|
5
5
|
|
|
6
6
|
const SEO_TITLE =
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
-
import { SettingsGroup } from "@agent-native/
|
|
2
|
+
import { SettingsGroup } from "@agent-native/toolkit/app/settings";
|
|
3
3
|
import { IconChevronRight } from "@tabler/icons-react";
|
|
4
4
|
import { Link } from "react-router";
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
-
import { McpIntegrationsLanding } from "@agent-native/
|
|
2
|
+
import { McpIntegrationsLanding } from "@agent-native/toolkit/app/integrations";
|
|
3
3
|
import { Link } from "react-router";
|
|
4
4
|
|
|
5
5
|
import { DispatchShell } from "../../components/dispatch-shell";
|
|
@@ -16,14 +16,8 @@ import {
|
|
|
16
16
|
APP_LIST_GRID_ROW_CLASS,
|
|
17
17
|
AppList,
|
|
18
18
|
} from "../../components/app-list-row";
|
|
19
|
-
import { AvailableAppsSection } from "../../components/available-apps-section";
|
|
20
19
|
import { CreateAppPopover } from "../../components/create-app-popover";
|
|
21
20
|
import { DispatchShell } from "../../components/dispatch-shell";
|
|
22
|
-
import {
|
|
23
|
-
filterOtherAppEntries,
|
|
24
|
-
mergeOtherAppEntries,
|
|
25
|
-
OtherAppsSection,
|
|
26
|
-
} from "../../components/other-apps-section";
|
|
27
21
|
import { Button } from "../../components/ui/button";
|
|
28
22
|
import {
|
|
29
23
|
Collapsible,
|
|
@@ -36,12 +30,6 @@ import {
|
|
|
36
30
|
WorkspaceAppSearch,
|
|
37
31
|
WorkspaceAppSearchEmpty,
|
|
38
32
|
} from "../../components/workspace-app-search";
|
|
39
|
-
import type {
|
|
40
|
-
CuratedWorkspaceTemplatesResult,
|
|
41
|
-
WorkspaceTemplateLabels,
|
|
42
|
-
} from "../../components/workspace-template-card";
|
|
43
|
-
import { AVAILABLE_APPS } from "../../lib/available-apps";
|
|
44
|
-
import type { ConnectedAppSummary } from "../../lib/other-apps";
|
|
45
33
|
import { cn } from "../../lib/utils";
|
|
46
34
|
import {
|
|
47
35
|
orderWorkspaceApps,
|
|
@@ -78,11 +66,6 @@ function AppsRoute() {
|
|
|
78
66
|
includeAgentCards: false,
|
|
79
67
|
includeArchived: true,
|
|
80
68
|
});
|
|
81
|
-
const connectedAppsQuery = useActionQuery("list-connected-agents", {});
|
|
82
|
-
const curatedTemplatesQuery = useActionQuery(
|
|
83
|
-
"list-curated-workspace-templates",
|
|
84
|
-
{},
|
|
85
|
-
);
|
|
86
69
|
const { data: apps = [], isLoading: appsLoading } = appsQuery;
|
|
87
70
|
const { data: workspace } = useActionQuery(
|
|
88
71
|
"get-workspace-info",
|
|
@@ -98,23 +81,6 @@ function AppsRoute() {
|
|
|
98
81
|
const activeApps = visibleApps.filter((app) => app.status !== "pending");
|
|
99
82
|
const pendingApps = visibleApps.filter((app) => app.status === "pending");
|
|
100
83
|
const archivedApps = allApps.filter((app) => app.archived);
|
|
101
|
-
const connectedApps =
|
|
102
|
-
(connectedAppsQuery.data as ConnectedAppSummary[] | undefined) ?? [];
|
|
103
|
-
const curatedTemplates = curatedTemplatesQuery.data as
|
|
104
|
-
| CuratedWorkspaceTemplatesResult
|
|
105
|
-
| undefined;
|
|
106
|
-
const filteredOtherApps = filterOtherAppEntries(
|
|
107
|
-
mergeOtherAppEntries({
|
|
108
|
-
templates: curatedTemplates,
|
|
109
|
-
connectedApps,
|
|
110
|
-
workspaceApps: allApps,
|
|
111
|
-
}),
|
|
112
|
-
searchQuery,
|
|
113
|
-
);
|
|
114
|
-
const otherAppsLoading =
|
|
115
|
-
curatedTemplatesQuery.isLoading || connectedAppsQuery.isLoading;
|
|
116
|
-
const otherAppsError =
|
|
117
|
-
curatedTemplatesQuery.error || connectedAppsQuery.error;
|
|
118
84
|
const orderedActiveApps = orderWorkspaceApps(activeApps, layout);
|
|
119
85
|
const orderedPendingApps = orderWorkspaceApps(pendingApps, layout);
|
|
120
86
|
const orderedArchivedApps = orderWorkspaceApps(archivedApps, layout);
|
|
@@ -130,30 +96,8 @@ function AppsRoute() {
|
|
|
130
96
|
const hasSearchResults =
|
|
131
97
|
filteredActiveApps.length > 0 ||
|
|
132
98
|
filteredPendingApps.length > 0 ||
|
|
133
|
-
filteredArchivedApps.length > 0
|
|
134
|
-
filteredOtherApps.length > 0 ||
|
|
135
|
-
AVAILABLE_APPS.some((app) => {
|
|
136
|
-
const query = searchQuery.trim().toLowerCase();
|
|
137
|
-
return (
|
|
138
|
-
!query || `${app.name} ${app.description}`.toLowerCase().includes(query)
|
|
139
|
-
);
|
|
140
|
-
});
|
|
99
|
+
filteredArchivedApps.length > 0;
|
|
141
100
|
const showAppSkeletons = appsLoading && allApps.length === 0;
|
|
142
|
-
const templateLabels: WorkspaceTemplateLabels = {
|
|
143
|
-
appId: t("dispatch.pages.remixAppIdLabel"),
|
|
144
|
-
appIdDescription: t("dispatch.pages.remixAppIdDescription"),
|
|
145
|
-
cancel: t("dispatch.pages.cancel"),
|
|
146
|
-
integrationSetup: t("dispatch.pages.integrationSetup"),
|
|
147
|
-
installed: t("dispatch.pages.alreadyInWorkspace"),
|
|
148
|
-
remix: t("dispatch.pages.addApp", { defaultValue: "Add app" }),
|
|
149
|
-
remixing: t("dispatch.pages.remixing"),
|
|
150
|
-
remixSuccess: t("dispatch.pages.remixSuccess"),
|
|
151
|
-
remixError: t("dispatch.pages.remixError"),
|
|
152
|
-
appIdRequired: t("dispatch.pages.appIdRequired"),
|
|
153
|
-
source: t("dispatch.pages.source"),
|
|
154
|
-
openApp: t("dispatch.pages.openApp", { defaultValue: "Open app" }),
|
|
155
|
-
viewLiveApp: t("dispatch.pages.openApp", { defaultValue: "Open" }),
|
|
156
|
-
};
|
|
157
101
|
|
|
158
102
|
return (
|
|
159
103
|
<DispatchShell
|
|
@@ -223,10 +167,7 @@ function AppsRoute() {
|
|
|
223
167
|
/>
|
|
224
168
|
) : showAppSkeletons ? (
|
|
225
169
|
<AppsSkeletonGrid />
|
|
226
|
-
) : !hasSearchResults &&
|
|
227
|
-
searchQuery.trim() &&
|
|
228
|
-
!otherAppsLoading &&
|
|
229
|
-
!otherAppsError ? (
|
|
170
|
+
) : !hasSearchResults && searchQuery.trim() ? (
|
|
230
171
|
<WorkspaceAppSearchEmpty
|
|
231
172
|
query={searchQuery}
|
|
232
173
|
onClear={() => setSearchQuery("")}
|
|
@@ -310,31 +251,6 @@ function AppsRoute() {
|
|
|
310
251
|
</Collapsible>
|
|
311
252
|
) : null}
|
|
312
253
|
|
|
313
|
-
<OtherAppsSection
|
|
314
|
-
templates={curatedTemplates}
|
|
315
|
-
connectedApps={connectedApps}
|
|
316
|
-
workspaceApps={allApps}
|
|
317
|
-
query={searchQuery}
|
|
318
|
-
templatesLoading={curatedTemplatesQuery.isLoading}
|
|
319
|
-
connectedAppsLoading={connectedAppsQuery.isLoading}
|
|
320
|
-
templatesError={curatedTemplatesQuery.error}
|
|
321
|
-
connectedAppsError={connectedAppsQuery.error}
|
|
322
|
-
onRetryTemplates={() => void curatedTemplatesQuery.refetch()}
|
|
323
|
-
onRetryConnectedApps={() => void connectedAppsQuery.refetch()}
|
|
324
|
-
templateLabels={templateLabels}
|
|
325
|
-
onRemixSuccess={() => {
|
|
326
|
-
void appsQuery.refetch();
|
|
327
|
-
void curatedTemplatesQuery.refetch();
|
|
328
|
-
}}
|
|
329
|
-
/>
|
|
330
|
-
|
|
331
|
-
<AvailableAppsSection
|
|
332
|
-
connectedApps={connectedApps}
|
|
333
|
-
workspaceApps={allApps}
|
|
334
|
-
query={searchQuery}
|
|
335
|
-
onConnected={() => void connectedAppsQuery.refetch()}
|
|
336
|
-
/>
|
|
337
|
-
|
|
338
254
|
{archivedApps.length > 0 &&
|
|
339
255
|
(!searchQuery.trim() || filteredArchivedApps.length > 0) ? (
|
|
340
256
|
<Collapsible
|
|
@@ -79,7 +79,7 @@ vi.mock("@agent-native/core/client/agent-chat", () => ({
|
|
|
79
79
|
sendToAgentChat: vi.fn(),
|
|
80
80
|
}));
|
|
81
81
|
|
|
82
|
-
vi.mock("@agent-native/
|
|
82
|
+
vi.mock("@agent-native/toolkit/app/chat/composer/index", () => ({
|
|
83
83
|
PromptComposer: () => null,
|
|
84
84
|
}));
|
|
85
85
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AgentChatSurface } from "@agent-native/core/client/agent-chat";
|
|
2
1
|
import { isEmbedAuthActive } from "@agent-native/core/client/host";
|
|
3
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
+
import { AgentChatSurface } from "@agent-native/toolkit/app/chat";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { useSearchParams } from "react-router";
|
|
6
6
|
|
|
@@ -8,8 +8,6 @@ import ChatRoute from "./chat";
|
|
|
8
8
|
|
|
9
9
|
const clientState = vi.hoisted(() => ({
|
|
10
10
|
surfaceProps: null as Record<string, unknown> | null,
|
|
11
|
-
activeRunId: null as string | null,
|
|
12
|
-
writeClipboardText: vi.fn(),
|
|
13
11
|
openWorkspaceApp: vi.fn(),
|
|
14
12
|
workspaceApps: [
|
|
15
13
|
{
|
|
@@ -33,6 +31,17 @@ const clientState = vi.hoisted(() => ({
|
|
|
33
31
|
}));
|
|
34
32
|
|
|
35
33
|
vi.mock("@agent-native/core/client/agent-chat", () => ({
|
|
34
|
+
insertAgentComposerReference: vi.fn(),
|
|
35
|
+
markAgentChatHomeHandoff: vi.fn(),
|
|
36
|
+
readChatFirstMode: () => true,
|
|
37
|
+
navigateWithAgentChatViewTransition: (
|
|
38
|
+
navigate: (path: string) => void,
|
|
39
|
+
path: string,
|
|
40
|
+
) => navigate(path),
|
|
41
|
+
sendToAgentChat: vi.fn(),
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
vi.mock("@agent-native/toolkit/app/chat", () => ({
|
|
36
45
|
AgentChatHome: (props: Record<string, unknown>) => {
|
|
37
46
|
clientState.surfaceProps = { mode: "page", ...props };
|
|
38
47
|
return (
|
|
@@ -42,19 +51,10 @@ vi.mock("@agent-native/core/client/agent-chat", () => ({
|
|
|
42
51
|
</>
|
|
43
52
|
);
|
|
44
53
|
},
|
|
45
|
-
insertAgentComposerReference: vi.fn(),
|
|
46
|
-
markAgentChatHomeHandoff: vi.fn(),
|
|
47
|
-
readChatFirstMode: () => true,
|
|
48
|
-
useActiveAgentChatRunId: () => clientState.activeRunId,
|
|
49
|
-
navigateWithAgentChatViewTransition: (
|
|
50
|
-
navigate: (path: string) => void,
|
|
51
|
-
path: string,
|
|
52
|
-
) => navigate(path),
|
|
53
|
-
sendToAgentChat: vi.fn(),
|
|
54
54
|
}));
|
|
55
55
|
|
|
56
|
-
vi.mock("
|
|
57
|
-
|
|
56
|
+
vi.mock("../../components/create-app-popover", () => ({
|
|
57
|
+
CreateAppPopover: () => null,
|
|
58
58
|
}));
|
|
59
59
|
|
|
60
60
|
vi.mock("@agent-native/core/client/hooks", () => ({
|
|
@@ -120,7 +120,6 @@ describe("Dispatch ChatRoute", () => {
|
|
|
120
120
|
vi.useFakeTimers();
|
|
121
121
|
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
122
122
|
clientState.surfaceProps = null;
|
|
123
|
-
clientState.activeRunId = null;
|
|
124
123
|
clientState.agents = [];
|
|
125
124
|
clientState.openWorkspaceApp.mockReset();
|
|
126
125
|
clientState.retryWorkspaceApps.mockReset();
|
|
@@ -257,6 +256,13 @@ describe("Dispatch ChatRoute", () => {
|
|
|
257
256
|
);
|
|
258
257
|
expect(clientState.surfaceProps?.suggestions).toEqual([]);
|
|
259
258
|
expect(container.textContent).not.toContain("What should we do today?");
|
|
259
|
+
|
|
260
|
+
await act(async () => {
|
|
261
|
+
vi.runOnlyPendingTimers();
|
|
262
|
+
await Promise.resolve();
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
expect(container.textContent).not.toContain("What should we do today?");
|
|
260
266
|
});
|
|
261
267
|
|
|
262
268
|
it("keeps an agent chat scoped and preserves the scope in thread URLs", async () => {
|
|
@@ -300,10 +306,7 @@ describe("Dispatch ChatRoute", () => {
|
|
|
300
306
|
).toBe("/chat/thread-1?agent=agents%2Fresearch-partner.md");
|
|
301
307
|
});
|
|
302
308
|
|
|
303
|
-
it("
|
|
304
|
-
clientState.activeRunId = "run-456";
|
|
305
|
-
clientState.writeClipboardText.mockResolvedValue(true);
|
|
306
|
-
|
|
309
|
+
it("keeps threaded chats free of request ID chrome", async () => {
|
|
307
310
|
await act(async () => {
|
|
308
311
|
root.render(
|
|
309
312
|
<MemoryRouter initialEntries={["/chat/chat-123"]}>
|
|
@@ -313,33 +316,7 @@ describe("Dispatch ChatRoute", () => {
|
|
|
313
316
|
});
|
|
314
317
|
|
|
315
318
|
expect(clientState.surfaceProps?.suggestions).toEqual([]);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
el.textContent?.includes("Copy request ID"),
|
|
319
|
-
);
|
|
320
|
-
expect(button).toBeTruthy();
|
|
321
|
-
|
|
322
|
-
await act(async () => {
|
|
323
|
-
button?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
324
|
-
await Promise.resolve();
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
expect(clientState.writeClipboardText).toHaveBeenCalledWith("run-456");
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it("keeps the request ID affordance unavailable before a run starts", async () => {
|
|
331
|
-
await act(async () => {
|
|
332
|
-
root.render(
|
|
333
|
-
<MemoryRouter initialEntries={["/chat/chat-123"]}>
|
|
334
|
-
<ChatRoute />
|
|
335
|
-
</MemoryRouter>,
|
|
336
|
-
);
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
const button = Array.from(container.querySelectorAll("button")).find((el) =>
|
|
340
|
-
el.textContent?.includes("Request ID unavailable"),
|
|
341
|
-
);
|
|
342
|
-
expect(button).toBeTruthy();
|
|
343
|
-
expect(button).toHaveProperty("disabled", true);
|
|
319
|
+
expect(clientState.surfaceProps?.contentClassName).toBe("max-w-none");
|
|
320
|
+
expect(container.textContent).not.toContain("Request ID");
|
|
344
321
|
});
|
|
345
322
|
});
|