@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.
Files changed (121) hide show
  1. package/CHANGELOG.md +38 -12
  2. package/dist/actions/provider-api-register.d.ts +7 -7
  3. package/dist/components/app-open-actions.d.ts +1 -1
  4. package/dist/components/app-open-actions.d.ts.map +1 -1
  5. package/dist/components/app-open-actions.js +1 -1
  6. package/dist/components/app-open-actions.js.map +1 -1
  7. package/dist/components/app-row-settings.js +1 -1
  8. package/dist/components/app-row-settings.js.map +1 -1
  9. package/dist/components/automation-create-dialog.js +2 -2
  10. package/dist/components/automation-create-dialog.js.map +1 -1
  11. package/dist/components/automation-details-panel.js +1 -1
  12. package/dist/components/automation-details-panel.js.map +1 -1
  13. package/dist/components/chat-home-apps.js +1 -1
  14. package/dist/components/chat-home-apps.js.map +1 -1
  15. package/dist/components/create-app-popover.js +3 -3
  16. package/dist/components/create-app-popover.js.map +1 -1
  17. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  18. package/dist/components/dispatch-control-plane.js +9 -30
  19. package/dist/components/dispatch-control-plane.js.map +1 -1
  20. package/dist/components/layout/Header.js +2 -2
  21. package/dist/components/layout/Header.js.map +1 -1
  22. package/dist/components/layout/Layout.d.ts +6 -5
  23. package/dist/components/layout/Layout.d.ts.map +1 -1
  24. package/dist/components/layout/Layout.js +73 -113
  25. package/dist/components/layout/Layout.js.map +1 -1
  26. package/dist/components/layout/workspace-apps-rail.d.ts.map +1 -1
  27. package/dist/components/layout/workspace-apps-rail.js +7 -19
  28. package/dist/components/layout/workspace-apps-rail.js.map +1 -1
  29. package/dist/components/messaging-setup-panel.js +2 -1
  30. package/dist/components/messaging-setup-panel.js.map +1 -1
  31. package/dist/components/workspace-app-card.js +2 -2
  32. package/dist/components/workspace-app-card.js.map +1 -1
  33. package/dist/components/workspace-app-host.d.ts +1 -1
  34. package/dist/components/workspace-app-host.d.ts.map +1 -1
  35. package/dist/components/workspace-app-host.js +7 -74
  36. package/dist/components/workspace-app-host.js.map +1 -1
  37. package/dist/hooks/use-navigation-state.js +1 -1
  38. package/dist/hooks/use-navigation-state.js.map +1 -1
  39. package/dist/lib/workspace-apps.js +1 -1
  40. package/dist/lib/workspace-apps.js.map +1 -1
  41. package/dist/routes/pages/$appId.js +1 -1
  42. package/dist/routes/pages/$appId.js.map +1 -1
  43. package/dist/routes/pages/_index.js +1 -1
  44. package/dist/routes/pages/_index.js.map +1 -1
  45. package/dist/routes/pages/admin._index.js +1 -1
  46. package/dist/routes/pages/admin._index.js.map +1 -1
  47. package/dist/routes/pages/agent-integrations.js +1 -1
  48. package/dist/routes/pages/agent-integrations.js.map +1 -1
  49. package/dist/routes/pages/apps.d.ts.map +1 -1
  50. package/dist/routes/pages/apps.js +3 -43
  51. package/dist/routes/pages/apps.js.map +1 -1
  52. package/dist/routes/pages/browser-chat.js +1 -1
  53. package/dist/routes/pages/browser-chat.js.map +1 -1
  54. package/dist/routes/pages/chat.d.ts.map +1 -1
  55. package/dist/routes/pages/chat.js +24 -43
  56. package/dist/routes/pages/chat.js.map +1 -1
  57. package/dist/routes/pages/extensions.$id.js +1 -1
  58. package/dist/routes/pages/extensions.$id.js.map +1 -1
  59. package/dist/routes/pages/extensions._index.js +1 -1
  60. package/dist/routes/pages/extensions._index.js.map +1 -1
  61. package/dist/routes/pages/integrations.js +1 -1
  62. package/dist/routes/pages/integrations.js.map +1 -1
  63. package/dist/routes/pages/new-app.js +1 -1
  64. package/dist/routes/pages/new-app.js.map +1 -1
  65. package/dist/routes/pages/operations.js +2 -2
  66. package/dist/routes/pages/operations.js.map +1 -1
  67. package/dist/routes/pages/overview.d.ts +2 -2
  68. package/dist/routes/pages/settings.d.ts.map +1 -1
  69. package/dist/routes/pages/settings.js +26 -8
  70. package/dist/routes/pages/settings.js.map +1 -1
  71. package/dist/routes/pages/tools.$id.js +1 -1
  72. package/dist/routes/pages/tools.$id.js.map +1 -1
  73. package/dist/routes/pages/tools._index.js +1 -1
  74. package/dist/routes/pages/tools._index.js.map +1 -1
  75. package/dist/routes/pages/vault.d.ts +1 -1
  76. package/dist/routes/pages/vault.js +1 -1
  77. package/dist/routes/pages/vault.js.map +1 -1
  78. package/dist/shared/app-roles.js.map +1 -1
  79. package/package.json +3 -3
  80. package/src/components/app-open-actions.tsx +1 -1
  81. package/src/components/app-row-settings.tsx +1 -1
  82. package/src/components/automation-create-dialog.tsx +7 -7
  83. package/src/components/automation-details-panel.tsx +1 -1
  84. package/src/components/chat-home-apps.tsx +1 -1
  85. package/src/components/create-app-popover.spec.tsx +5 -7
  86. package/src/components/create-app-popover.tsx +3 -3
  87. package/src/components/dispatch-control-plane.spec.tsx +12 -19
  88. package/src/components/dispatch-control-plane.tsx +10 -84
  89. package/src/components/layout/Header.tsx +2 -2
  90. package/src/components/layout/Layout.app-chat.spec.ts +1 -0
  91. package/src/components/layout/Layout.spec.tsx +18 -20
  92. package/src/components/layout/Layout.tsx +153 -205
  93. package/src/components/layout/workspace-apps-rail.spec.tsx +79 -0
  94. package/src/components/layout/workspace-apps-rail.tsx +6 -30
  95. package/src/components/messaging-setup-panel.tsx +1 -1
  96. package/src/components/workspace-app-card.tsx +2 -2
  97. package/src/components/workspace-app-chat-rail.spec.tsx +1 -1
  98. package/src/components/workspace-app-host.spec.tsx +19 -19
  99. package/src/components/workspace-app-host.tsx +12 -129
  100. package/src/hooks/use-navigation-state.ts +1 -1
  101. package/src/lib/workspace-apps.ts +1 -1
  102. package/src/routes/pages/$appId.tsx +1 -1
  103. package/src/routes/pages/_index.tsx +1 -1
  104. package/src/routes/pages/admin._index.tsx +1 -1
  105. package/src/routes/pages/agent-integrations.tsx +1 -1
  106. package/src/routes/pages/apps.tsx +2 -86
  107. package/src/routes/pages/automations.spec.tsx +1 -1
  108. package/src/routes/pages/browser-chat.tsx +1 -1
  109. package/src/routes/pages/chat.spec.tsx +23 -46
  110. package/src/routes/pages/chat.tsx +20 -57
  111. package/src/routes/pages/extensions.$id.tsx +1 -1
  112. package/src/routes/pages/extensions._index.tsx +1 -1
  113. package/src/routes/pages/integrations.tsx +1 -1
  114. package/src/routes/pages/new-app.tsx +1 -1
  115. package/src/routes/pages/operations.tsx +2 -2
  116. package/src/routes/pages/settings.spec.tsx +30 -8
  117. package/src/routes/pages/settings.tsx +75 -7
  118. package/src/routes/pages/tools.$id.tsx +1 -1
  119. package/src/routes/pages/tools._index.tsx +1 -1
  120. package/src/routes/pages/vault.tsx +1 -1
  121. package/src/shared/app-roles.ts +1 -1
@@ -1,23 +1,21 @@
1
1
  import {
2
- AgentChatHome,
3
- type AgentChatHomeProps,
4
2
  insertAgentComposerReference,
5
3
  markAgentChatHomeHandoff,
6
4
  readChatFirstMode,
7
- useActiveAgentChatRunId,
8
5
  } from "@agent-native/core/client/agent-chat";
9
6
  import { appBasePath, appPath } from "@agent-native/core/client/api-path";
10
- import { writeClipboardText } from "@agent-native/core/client/clipboard";
11
7
  import { useActionQuery } from "@agent-native/core/client/hooks";
12
8
  import { useT } from "@agent-native/core/client/i18n";
13
- import { IconCheck, IconCopy } from "@tabler/icons-react";
9
+ import {
10
+ AgentChatHome,
11
+ type AgentChatHomeProps,
12
+ } from "@agent-native/toolkit/app/chat";
14
13
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
15
14
  import { useLocation, useNavigate } from "react-router";
16
15
 
17
16
  import { ActionQueryError } from "../../components/action-query-error";
18
17
  import { DispatchChatHomeApps } from "../../components/chat-home-apps";
19
18
  import { useDispatchExtensions } from "../../components/layout/Layout";
20
- import { Button } from "../../components/ui/button";
21
19
  import { Skeleton } from "../../components/ui/skeleton";
22
20
  import { submitOverviewPrompt } from "../../lib/overview-chat";
23
21
 
@@ -73,46 +71,6 @@ interface DispatchThreadUrlSync {
73
71
  navigate: (path: string, options?: { replace?: boolean }) => void;
74
72
  }
75
73
 
76
- function DispatchRequestIdButton({ requestId }: { requestId: string | null }) {
77
- const t = useT();
78
- const [copied, setCopied] = useState(false);
79
-
80
- const handleCopy = useCallback(() => {
81
- if (!requestId) return;
82
- void writeClipboardText(requestId).then((ok) => {
83
- if (!ok) return;
84
- setCopied(true);
85
- window.setTimeout(() => setCopied(false), 1000);
86
- });
87
- }, [requestId]);
88
-
89
- return (
90
- <Button
91
- type="button"
92
- variant="outline"
93
- size="sm"
94
- disabled={!requestId}
95
- onClick={handleCopy}
96
- aria-label={t("dispatch.pages.copyRequestId", {
97
- defaultValue: requestId ? "Copy request ID" : "Request ID unavailable",
98
- })}
99
- >
100
- {copied ? (
101
- <IconCheck aria-hidden="true" />
102
- ) : (
103
- <IconCopy aria-hidden="true" />
104
- )}
105
- {copied
106
- ? t("dispatch.pages.copied", { defaultValue: "Copied" })
107
- : t("dispatch.pages.copyRequestId", {
108
- defaultValue: requestId
109
- ? "Copy request ID"
110
- : "Request ID unavailable",
111
- })}
112
- </Button>
113
- );
114
- }
115
-
116
74
  interface DispatchChatLocationState {
117
75
  dispatchPrompt?: {
118
76
  id?: string | number;
@@ -136,7 +94,6 @@ export default function ChatRoute() {
136
94
  const location = useLocation();
137
95
  const navigate = useNavigate();
138
96
  const routeThreadId = threadIdFromPath(location.pathname);
139
- const activeRunId = useActiveAgentChatRunId(routeThreadId);
140
97
  const agentPath = new URLSearchParams(location.search).get("agent");
141
98
  const agentsQuery = useActionQuery<WorkspaceAgentResource[]>(
142
99
  "list-workspace-resources",
@@ -194,6 +151,14 @@ export default function ChatRoute() {
194
151
  const state = location.state as DispatchChatLocationState | null;
195
152
  const prompt = state?.dispatchPrompt;
196
153
  const thread = state?.dispatchThread;
154
+ const [pendingOverviewPrompt, setPendingOverviewPrompt] = useState<
155
+ DispatchChatLocationState["dispatchPrompt"] | null
156
+ >(null);
157
+ const activePrompt = prompt?.message ? prompt : pendingOverviewPrompt;
158
+
159
+ useEffect(() => {
160
+ if (routeThreadId) setPendingOverviewPrompt(null);
161
+ }, [routeThreadId]);
197
162
 
198
163
  useEffect(() => {
199
164
  const message = prompt?.message?.trim();
@@ -215,6 +180,7 @@ export default function ChatRoute() {
215
180
  );
216
181
  }
217
182
  if (message) {
183
+ setPendingOverviewPrompt(prompt ?? null);
218
184
  submitOverviewPrompt(message, prompt?.selectedModel, {
219
185
  openSidebar: false,
220
186
  selectedEngine: prompt?.selectedEngine,
@@ -303,15 +269,10 @@ export default function ChatRoute() {
303
269
 
304
270
  return (
305
271
  <div className="flex h-full min-h-0 flex-col bg-background">
306
- {threadUrlSync.routeThreadId ? (
307
- <div className="flex justify-end px-4 pt-4 sm:px-6">
308
- <DispatchRequestIdButton requestId={activeRunId} />
309
- </div>
310
- ) : null}
311
272
  <AgentChatHome
312
273
  key={agent ? `agent-${agent.id}` : "dispatch"}
313
274
  className="flex-1 min-h-0"
314
- contentClassName="max-w-6xl"
275
+ contentClassName="max-w-none"
315
276
  surfaceClassName="dispatch-chat-panel px-4 sm:px-6"
316
277
  chatViewTransition
317
278
  defaultMode="chat"
@@ -323,7 +284,7 @@ export default function ChatRoute() {
323
284
  dynamicSuggestions={false}
324
285
  suppressInlineOpenApp={suppressInlineOpenApp}
325
286
  suggestions={
326
- agent || routeThreadId || prompt?.message
287
+ agent || routeThreadId || activePrompt?.message
327
288
  ? []
328
289
  : [
329
290
  t("dispatch.pages.suggestionWorkspaceHealth"),
@@ -335,8 +296,10 @@ export default function ChatRoute() {
335
296
  defaultValue:
336
297
  "Route work, inspect status, or create something new from one place.",
337
298
  })}
338
- centerComposerWhenEmpty={!prompt?.message}
339
- composerLayoutVariant={prompt?.message ? "default" : "hero"}
299
+ centerComposerWhenEmpty={!activePrompt?.message && !routeThreadId}
300
+ composerLayoutVariant={
301
+ activePrompt?.message || routeThreadId ? "default" : "hero"
302
+ }
340
303
  composerPlaceholder={
341
304
  agent
342
305
  ? `Ask ${agent.name}...`
@@ -350,7 +313,7 @@ export default function ChatRoute() {
350
313
  <h1>{agent.name}</h1>
351
314
  {agent.description ? <p>{agent.description}</p> : null}
352
315
  </div>
353
- ) : !prompt?.message ? (
316
+ ) : !activePrompt?.message && !routeThreadId ? (
354
317
  <div className="dispatch-chat-intro">
355
318
  <h1>
356
319
  {t("dispatch.pages.chatHomeTitle", {
@@ -1,4 +1,4 @@
1
- import { ExtensionViewerPage } from "@agent-native/core/client/extensions";
1
+ import { ExtensionViewerPage } from "@agent-native/toolkit/app/extensions";
2
2
 
3
3
  export function meta() {
4
4
  return [{ title: "Extension \u2014 Dispatch" }];
@@ -1,4 +1,4 @@
1
- import { ExtensionsListPage } from "@agent-native/core/client/extensions";
1
+ import { ExtensionsListPage } from "@agent-native/toolkit/app/extensions";
2
2
 
3
3
  export function meta() {
4
4
  return [{ title: "Extensions \u2014 Dispatch" }];
@@ -1,5 +1,5 @@
1
1
  import { useT } from "@agent-native/core/client/i18n";
2
- import { McpIntegrationsLanding } from "@agent-native/core/client/integrations";
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";
@@ -1,5 +1,5 @@
1
1
  import { useT } from "@agent-native/core/client/i18n";
2
- import { NewWorkspaceAppFlow } from "@agent-native/core/client/ui";
2
+ import { NewWorkspaceAppFlow } from "@agent-native/toolkit/app/onboarding";
3
3
 
4
4
  import { DispatchShell } from "../../components/dispatch-shell";
5
5
 
@@ -1,6 +1,6 @@
1
- import { DbAdminPage } from "@agent-native/core/client/db-admin";
2
1
  import { useT } from "@agent-native/core/client/i18n";
3
- import { ObservabilityDashboard } from "@agent-native/core/client/observability";
2
+ import { DbAdminPage } from "@agent-native/toolkit/app/db-admin";
3
+ import { ObservabilityDashboard } from "@agent-native/toolkit/app/observability";
4
4
  import {
5
5
  IconActivity,
6
6
  IconArrowUpRight,
@@ -8,6 +8,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
8
8
  import { dispatchAccessDescriptor } from "../../shared/app-roles.js";
9
9
 
10
10
  const state = vi.hoisted(() => ({
11
+ redesign: false,
11
12
  registered: [] as Array<{
12
13
  id: string;
13
14
  component: ComponentType;
@@ -16,7 +17,6 @@ const state = vi.hoisted(() => ({
16
17
  membersAppRoles: undefined as unknown,
17
18
  pageProps: null as null | {
18
19
  general?: ReactNode;
19
- account?: ReactNode;
20
20
  generalGroups?: ReactNode;
21
21
  generalSearchEntries?: Array<{ id: string; hash?: string }>;
22
22
  extraTabs?: Array<{ id: string; href?: string }>;
@@ -30,7 +30,7 @@ vi.mock("@agent-native/core/client/agent-chat", () => ({
30
30
  writeChatFirstMode: () => ({ ok: true }),
31
31
  }));
32
32
 
33
- vi.mock("@agent-native/core/client/changelog", () => ({
33
+ vi.mock("@agent-native/toolkit/app/changelog", () => ({
34
34
  ChangelogSettingsCard: ({ markdown }: { markdown: string }) => (
35
35
  <div data-changelog>{markdown}</div>
36
36
  ),
@@ -38,10 +38,12 @@ vi.mock("@agent-native/core/client/changelog", () => ({
38
38
 
39
39
  vi.mock("@agent-native/core/client/feature-flags", () => ({
40
40
  useFeatureFlag: () => false,
41
+ useFeatureFlagState: () => ({ status: "ready", enabled: state.redesign }),
41
42
  }));
42
43
 
43
44
  vi.mock("@agent-native/core/feature-flags/registry", () => ({
44
45
  CONNECT_APPS_FLAG: { key: "connect-apps" },
46
+ SETTINGS_REDESIGN_FLAG: { key: "settings-redesign" },
45
47
  defineFeatureFlag: (flag: { key: string }) => flag,
46
48
  }));
47
49
 
@@ -49,7 +51,11 @@ vi.mock("@agent-native/core/client/i18n", () => ({
49
51
  useT: () => (key: string) => key,
50
52
  }));
51
53
 
52
- vi.mock("@agent-native/core/client/org", () => ({
54
+ vi.mock("@agent-native/toolkit/app/shared", () => ({
55
+ LanguagePicker: () => null,
56
+ }));
57
+
58
+ vi.mock("@agent-native/toolkit/app/org", () => ({
53
59
  TeamPage: () => null,
54
60
  OrgMembersPage: ({ appRoles }: { appRoles?: unknown }) => {
55
61
  state.membersAppRoles = appRoles;
@@ -57,7 +63,8 @@ vi.mock("@agent-native/core/client/org", () => ({
57
63
  },
58
64
  }));
59
65
 
60
- vi.mock("@agent-native/core/client/settings", () => ({
66
+ vi.mock("@agent-native/toolkit/app/settings", () => ({
67
+ AccountSettingsCard: () => null,
61
68
  CORE_SETTINGS_PAGES: [
62
69
  { id: "profile", component: () => null },
63
70
  {
@@ -88,7 +95,7 @@ vi.mock("@agent-native/core/client/settings", () => ({
88
95
  ),
89
96
  SettingsTabsPage: (props: NonNullable<typeof state.pageProps>) => {
90
97
  state.pageProps = props;
91
- return <main>{props.generalGroups}</main>;
98
+ return <main>{state.redesign ? props.generalGroups : props.general}</main>;
92
99
  },
93
100
  useAgentSettingsTabs: () => [{ id: "organization", label: "Organization" }],
94
101
  }));
@@ -111,6 +118,7 @@ describe("Dispatch settings route", () => {
111
118
 
112
119
  beforeEach(() => {
113
120
  vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
121
+ state.redesign = false;
114
122
  state.pageProps = null;
115
123
  state.membersAppRoles = undefined;
116
124
  container = document.createElement("div");
@@ -137,11 +145,25 @@ describe("Dispatch settings route", () => {
137
145
  expect(state.membersAppRoles).toBe(dispatchAccessDescriptor);
138
146
  });
139
147
 
140
- it("renders Dispatch rows in the app's General groups", () => {
148
+ it("keeps the language row and Admin link on today's General tab", () => {
149
+ render();
150
+
151
+ expect(container.querySelector('[data-row="language"]')).not.toBeNull();
152
+ expect(container.textContent).toContain(
153
+ "settings.chatFirstSessionWatchDescription",
154
+ );
155
+ expect(
156
+ state.pageProps?.generalSearchEntries?.map((entry) => entry.id),
157
+ ).toContain("dispatch-language");
158
+ expect(
159
+ state.pageProps?.extraTabs?.find((tab) => tab.id === "admin")?.href,
160
+ ).toBe("/admin");
161
+ });
162
+
163
+ it("drops the language row in the redesigned Settings", () => {
164
+ state.redesign = true;
141
165
  render();
142
166
 
143
- expect(state.pageProps?.general).toBeUndefined();
144
- expect(state.pageProps?.account).toBeUndefined();
145
167
  expect(container.querySelector('[data-row="language"]')).toBeNull();
146
168
  expect(container.querySelector('[data-row="chat-first"]')).not.toBeNull();
147
169
  expect(
@@ -3,10 +3,16 @@ import {
3
3
  readChatFirstModeState,
4
4
  writeChatFirstMode,
5
5
  } from "@agent-native/core/client/agent-chat";
6
- import { useFeatureFlag } from "@agent-native/core/client/feature-flags";
6
+ import {
7
+ useFeatureFlag,
8
+ useFeatureFlagState,
9
+ } from "@agent-native/core/client/feature-flags";
7
10
  import { useT } from "@agent-native/core/client/i18n";
8
- import { OrgMembersPage, TeamPage } from "@agent-native/core/client/org";
11
+ import { SETTINGS_REDESIGN_FLAG } from "@agent-native/core/feature-flags/registry";
12
+ import { ChangelogSettingsCard } from "@agent-native/toolkit/app/changelog";
13
+ import { OrgMembersPage, TeamPage } from "@agent-native/toolkit/app/org";
9
14
  import {
15
+ AccountSettingsCard,
10
16
  CORE_SETTINGS_PAGES,
11
17
  registerSettingsPages,
12
18
  SettingsGroup,
@@ -14,7 +20,8 @@ import {
14
20
  SettingsTabsPage,
15
21
  useAgentSettingsTabs,
16
22
  type SettingsSearchEntry,
17
- } from "@agent-native/core/client/settings";
23
+ } from "@agent-native/toolkit/app/settings";
24
+ import { LanguagePicker } from "@agent-native/toolkit/app/shared";
18
25
  import { IconShield } from "@tabler/icons-react";
19
26
  import { useMemo, useState } from "react";
20
27
  import { Link } from "react-router";
@@ -36,8 +43,8 @@ function DispatchMembersSettingsPage() {
36
43
  return <OrgMembersPage appRoles={dispatchAccessDescriptor} />;
37
44
  }
38
45
 
39
- // Settings shows Members from core; Dispatch's replaces it so the app-role
40
- // column stays.
46
+ // The redesigned Settings shows Members from core; Dispatch's replaces it so
47
+ // the app-role column stays.
41
48
  registerSettingsPages([
42
49
  { ...coreMembersPage, component: DispatchMembersSettingsPage },
43
50
  ]);
@@ -58,6 +65,9 @@ export interface DispatchSettingsPageProps {
58
65
  export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
59
66
  const t = useT();
60
67
  const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);
68
+ // Core Preferences owns the interface language in the redesigned Settings,
69
+ // whose Dispatch General page shows `generalGroups` instead of `general`.
70
+ const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;
61
71
  const agentSettingsTabs = useAgentSettingsTabs({
62
72
  usageAppId: "dispatch",
63
73
  usageViewAllHref: "/admin/metrics",
@@ -111,9 +121,21 @@ export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
111
121
 
112
122
  const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
113
123
  () => [
124
+ ...(redesign
125
+ ? []
126
+ : [
127
+ {
128
+ id: "dispatch-language",
129
+ label: t("settings.languageTitle"),
130
+ keywords: "language locale translation i18n",
131
+ hash: "language",
132
+ },
133
+ ]),
114
134
  {
115
135
  id: "dispatch-workspace",
116
- label: t("settings.resourcesTitle"),
136
+ label: redesign
137
+ ? t("settings.resourcesTitle")
138
+ : t("settings.workspaceTitle"),
117
139
  keywords: "workspace resources integrations vault destinations",
118
140
  hash: "workspace-resources",
119
141
  },
@@ -124,7 +146,7 @@ export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
124
146
  hash: "chat-first",
125
147
  },
126
148
  ],
127
- [t],
149
+ [redesign, t],
128
150
  );
129
151
 
130
152
  const chatFirstSwitch = (
@@ -159,8 +181,49 @@ export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
159
181
 
160
182
  return (
161
183
  <SettingsTabsPage
184
+ account={<AccountSettingsCard />}
162
185
  extraTabs={settingsTabs}
163
186
  generalSearchEntries={generalSearchEntries}
187
+ general={
188
+ <div className="mx-auto w-full max-w-2xl space-y-6">
189
+ <p className="text-sm leading-6 text-muted-foreground">
190
+ {t("settings.description")}
191
+ </p>
192
+
193
+ <SettingsGroup>
194
+ <SettingsRow
195
+ id="language"
196
+ label={t("settings.languageTitle")}
197
+ description={t("settings.languageDescription")}
198
+ control={
199
+ <div className="w-56">
200
+ <LanguagePicker label={t("settings.languageLabel")} />
201
+ </div>
202
+ }
203
+ />
204
+ <SettingsRow
205
+ id="workspace-resources"
206
+ label={t("settings.workspaceTitle")}
207
+ description={t("settings.workspaceDescription")}
208
+ control={resourceSettingsButton}
209
+ />
210
+ {connectAppsRow}
211
+ </SettingsGroup>
212
+
213
+ <SettingsGroup id="chat-first">
214
+ <SettingsRow
215
+ label={t("settings.chatFirstTitle")}
216
+ description={t("settings.chatFirstDescription")}
217
+ control={chatFirstSwitch}
218
+ >
219
+ <p className="text-sm leading-6 text-muted-foreground">
220
+ {t("settings.chatFirstSessionWatchDescription")}
221
+ </p>
222
+ {chatFirstStorageAlert}
223
+ </SettingsRow>
224
+ </SettingsGroup>
225
+ </div>
226
+ }
164
227
  generalGroups={
165
228
  <SettingsGroup id="workspace" title={t("settings.workspaceTitle")}>
166
229
  <SettingsRow
@@ -180,6 +243,11 @@ export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
180
243
  {connectAppsRow}
181
244
  </SettingsGroup>
182
245
  }
246
+ whatsNew={
247
+ <div className="mx-auto w-full max-w-2xl">
248
+ <ChangelogSettingsCard markdown={changelog} />
249
+ </div>
250
+ }
183
251
  whatsNewMarkdown={changelog}
184
252
  />
185
253
  );
@@ -1,4 +1,4 @@
1
- import { ToolViewerPage } from "@agent-native/core/client/tools";
1
+ import { ToolViewerPage } from "@agent-native/toolkit/app/extensions";
2
2
 
3
3
  export function meta() {
4
4
  return [{ title: "Extension \u2014 Dispatch" }];
@@ -1,4 +1,4 @@
1
- import { ToolsListPage } from "@agent-native/core/client/tools";
1
+ import { ToolsListPage } from "@agent-native/toolkit/app/extensions";
2
2
 
3
3
  export function meta() {
4
4
  return [{ title: "Extensions \u2014 Dispatch" }];
@@ -7,7 +7,7 @@ import { useOrgRole } from "@agent-native/core/client/org";
7
7
  import {
8
8
  NewKeyMenu,
9
9
  type NewKeyOption,
10
- } from "@agent-native/core/client/settings";
10
+ } from "@agent-native/toolkit/app/settings";
11
11
  import {
12
12
  IconChevronDown,
13
13
  IconChevronRight,
@@ -1,4 +1,4 @@
1
- import type { AppRolesDescriptor } from "@agent-native/core/client/org";
1
+ import type { AppRolesDescriptor } from "@agent-native/core/org/app-roles";
2
2
 
3
3
  export const dispatchAccessDescriptor = {
4
4
  appId: "dispatch",