@agent-native/dispatch 0.15.1 → 0.15.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.
Files changed (191) hide show
  1. package/dist/actions/delete-staged-dataset.d.ts +3 -1
  2. package/dist/actions/delete-staged-dataset.js +3 -26
  3. package/dist/actions/delete-staged-dataset.js.map +1 -1
  4. package/dist/actions/delete-workspace-resource.d.ts +13 -13
  5. package/dist/actions/list-staged-datasets.d.ts +1 -1
  6. package/dist/actions/list-staged-datasets.js +3 -28
  7. package/dist/actions/list-staged-datasets.js.map +1 -1
  8. package/dist/actions/provider-api-catalog.d.ts +6 -4
  9. package/dist/actions/provider-api-catalog.js +3 -17
  10. package/dist/actions/provider-api-catalog.js.map +1 -1
  11. package/dist/actions/provider-api-docs.d.ts +21 -2
  12. package/dist/actions/provider-api-docs.js +6 -51
  13. package/dist/actions/provider-api-docs.js.map +1 -1
  14. package/dist/actions/provider-api-register.d.ts +39 -15
  15. package/dist/actions/provider-api-register.js +4 -193
  16. package/dist/actions/provider-api-register.js.map +1 -1
  17. package/dist/actions/provider-api-request.d.ts +34 -2
  18. package/dist/actions/provider-api-request.js +6 -171
  19. package/dist/actions/provider-api-request.js.map +1 -1
  20. package/dist/actions/query-staged-dataset.d.ts +18 -1
  21. package/dist/actions/query-staged-dataset.d.ts.map +1 -1
  22. package/dist/actions/query-staged-dataset.js +3 -100
  23. package/dist/actions/query-staged-dataset.js.map +1 -1
  24. package/dist/actions/upsert-destination.d.ts +12 -12
  25. package/dist/components/action-query-error.js +1 -1
  26. package/dist/components/action-query-error.js.map +1 -1
  27. package/dist/components/agents-panel.js +1 -1
  28. package/dist/components/agents-panel.js.map +1 -1
  29. package/dist/components/app-keys-popover.d.ts.map +1 -1
  30. package/dist/components/app-keys-popover.js +1 -1
  31. package/dist/components/app-keys-popover.js.map +1 -1
  32. package/dist/components/create-app-popover.js +5 -1
  33. package/dist/components/create-app-popover.js.map +1 -1
  34. package/dist/components/dispatch-control-plane.js +5 -1
  35. package/dist/components/dispatch-control-plane.js.map +1 -1
  36. package/dist/components/dispatch-shell.js +1 -1
  37. package/dist/components/dispatch-shell.js.map +1 -1
  38. package/dist/components/layout/Header.d.ts.map +1 -1
  39. package/dist/components/layout/Header.js +2 -1
  40. package/dist/components/layout/Header.js.map +1 -1
  41. package/dist/components/layout/Layout.d.ts.map +1 -1
  42. package/dist/components/layout/Layout.js +31 -65
  43. package/dist/components/layout/Layout.js.map +1 -1
  44. package/dist/components/messaging-setup-panel.d.ts.map +1 -1
  45. package/dist/components/messaging-setup-panel.js +2 -1
  46. package/dist/components/messaging-setup-panel.js.map +1 -1
  47. package/dist/components/task-queue-health.d.ts.map +1 -1
  48. package/dist/components/task-queue-health.js +2 -1
  49. package/dist/components/task-queue-health.js.map +1 -1
  50. package/dist/components/workspace-app-card.d.ts.map +1 -1
  51. package/dist/components/workspace-app-card.js +1 -1
  52. package/dist/components/workspace-app-card.js.map +1 -1
  53. package/dist/components/workspace-resource-effective-stack.js +1 -1
  54. package/dist/components/workspace-resource-effective-stack.js.map +1 -1
  55. package/dist/components/workspace-resource-impact-preview.js +1 -1
  56. package/dist/components/workspace-resource-impact-preview.js.map +1 -1
  57. package/dist/components/workspace-template-card.js +1 -1
  58. package/dist/components/workspace-template-card.js.map +1 -1
  59. package/dist/hooks/use-navigation-state.d.ts.map +1 -1
  60. package/dist/hooks/use-navigation-state.js +2 -1
  61. package/dist/hooks/use-navigation-state.js.map +1 -1
  62. package/dist/lib/automations.js +1 -1
  63. package/dist/lib/automations.js.map +1 -1
  64. package/dist/lib/overview-chat.d.ts.map +1 -1
  65. package/dist/lib/overview-chat.js +2 -1
  66. package/dist/lib/overview-chat.js.map +1 -1
  67. package/dist/lib/task-queue.js +1 -1
  68. package/dist/lib/task-queue.js.map +1 -1
  69. package/dist/routes/pages/$appId.d.ts.map +1 -1
  70. package/dist/routes/pages/$appId.js +3 -1
  71. package/dist/routes/pages/$appId.js.map +1 -1
  72. package/dist/routes/pages/_index.js +1 -1
  73. package/dist/routes/pages/_index.js.map +1 -1
  74. package/dist/routes/pages/agents.js +2 -1
  75. package/dist/routes/pages/agents.js.map +1 -1
  76. package/dist/routes/pages/approval.d.ts.map +1 -1
  77. package/dist/routes/pages/approval.js +3 -1
  78. package/dist/routes/pages/approval.js.map +1 -1
  79. package/dist/routes/pages/approvals.d.ts.map +1 -1
  80. package/dist/routes/pages/approvals.js +1 -1
  81. package/dist/routes/pages/approvals.js.map +1 -1
  82. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  83. package/dist/routes/pages/apps.$appId.js +2 -1
  84. package/dist/routes/pages/apps.$appId.js.map +1 -1
  85. package/dist/routes/pages/apps.d.ts.map +1 -1
  86. package/dist/routes/pages/apps.js +2 -1
  87. package/dist/routes/pages/apps.js.map +1 -1
  88. package/dist/routes/pages/audit.js +1 -1
  89. package/dist/routes/pages/audit.js.map +1 -1
  90. package/dist/routes/pages/automations.d.ts.map +1 -1
  91. package/dist/routes/pages/automations.js +3 -1
  92. package/dist/routes/pages/automations.js.map +1 -1
  93. package/dist/routes/pages/chat.d.ts.map +1 -1
  94. package/dist/routes/pages/chat.js +3 -1
  95. package/dist/routes/pages/chat.js.map +1 -1
  96. package/dist/routes/pages/destinations.js +2 -1
  97. package/dist/routes/pages/destinations.js.map +1 -1
  98. package/dist/routes/pages/dreams.d.ts.map +1 -1
  99. package/dist/routes/pages/dreams.js +1 -1
  100. package/dist/routes/pages/dreams.js.map +1 -1
  101. package/dist/routes/pages/identities.d.ts.map +1 -1
  102. package/dist/routes/pages/identities.js +1 -1
  103. package/dist/routes/pages/identities.js.map +1 -1
  104. package/dist/routes/pages/integrations.d.ts.map +1 -1
  105. package/dist/routes/pages/integrations.js +1 -1
  106. package/dist/routes/pages/integrations.js.map +1 -1
  107. package/dist/routes/pages/metrics.d.ts.map +1 -1
  108. package/dist/routes/pages/metrics.js +2 -1
  109. package/dist/routes/pages/metrics.js.map +1 -1
  110. package/dist/routes/pages/new-app.d.ts.map +1 -1
  111. package/dist/routes/pages/new-app.js +2 -1
  112. package/dist/routes/pages/new-app.js.map +1 -1
  113. package/dist/routes/pages/operations.d.ts.map +1 -1
  114. package/dist/routes/pages/operations.js +3 -1
  115. package/dist/routes/pages/operations.js.map +1 -1
  116. package/dist/routes/pages/settings.d.ts.map +1 -1
  117. package/dist/routes/pages/settings.js +3 -1
  118. package/dist/routes/pages/settings.js.map +1 -1
  119. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  120. package/dist/routes/pages/thread-debug.js +2 -1
  121. package/dist/routes/pages/thread-debug.js.map +1 -1
  122. package/dist/routes/pages/vault.d.ts.map +1 -1
  123. package/dist/routes/pages/vault.js +1 -1
  124. package/dist/routes/pages/vault.js.map +1 -1
  125. package/dist/routes/pages/workspace.d.ts.map +1 -1
  126. package/dist/routes/pages/workspace.js +1 -1
  127. package/dist/routes/pages/workspace.js.map +1 -1
  128. package/package.json +4 -3
  129. package/src/actions/delete-staged-dataset.ts +3 -33
  130. package/src/actions/list-staged-datasets.ts +3 -30
  131. package/src/actions/provider-api-audit.spec.ts +2 -3
  132. package/src/actions/provider-api-catalog.ts +10 -23
  133. package/src/actions/provider-api-docs.ts +19 -68
  134. package/src/actions/provider-api-register.ts +5 -233
  135. package/src/actions/provider-api-request.ts +19 -232
  136. package/src/actions/query-staged-dataset.ts +3 -119
  137. package/src/components/action-query-error.spec.tsx +1 -1
  138. package/src/components/action-query-error.tsx +1 -1
  139. package/src/components/agents-panel.tsx +1 -1
  140. package/src/components/app-keys-popover.spec.tsx +4 -1
  141. package/src/components/app-keys-popover.tsx +4 -1
  142. package/src/components/create-app-popover.tsx +5 -5
  143. package/src/components/dispatch-control-plane.spec.tsx +20 -8
  144. package/src/components/dispatch-control-plane.tsx +5 -5
  145. package/src/components/dispatch-shell.tsx +1 -1
  146. package/src/components/layout/Header.tsx +2 -1
  147. package/src/components/layout/Layout.spec.tsx +24 -19
  148. package/src/components/layout/Layout.tsx +47 -151
  149. package/src/components/messaging-setup-panel.spec.tsx +4 -1
  150. package/src/components/messaging-setup-panel.tsx +2 -3
  151. package/src/components/task-queue-health.tsx +2 -1
  152. package/src/components/workspace-app-card.spec.tsx +1 -1
  153. package/src/components/workspace-app-card.tsx +4 -1
  154. package/src/components/workspace-resource-effective-stack.spec.tsx +1 -1
  155. package/src/components/workspace-resource-effective-stack.tsx +1 -1
  156. package/src/components/workspace-resource-impact-preview.spec.tsx +1 -1
  157. package/src/components/workspace-resource-impact-preview.tsx +1 -1
  158. package/src/components/workspace-template-card.spec.tsx +1 -1
  159. package/src/components/workspace-template-card.tsx +1 -1
  160. package/src/hooks/use-navigation-state.ts +5 -3
  161. package/src/lib/automations.ts +1 -1
  162. package/src/lib/overview-chat.spec.ts +5 -2
  163. package/src/lib/overview-chat.ts +2 -1
  164. package/src/lib/task-queue.ts +1 -1
  165. package/src/routes/pages/$appId.tsx +3 -1
  166. package/src/routes/pages/_index.tsx +1 -1
  167. package/src/routes/pages/agents.tsx +2 -2
  168. package/src/routes/pages/approval.tsx +4 -2
  169. package/src/routes/pages/approvals.tsx +4 -1
  170. package/src/routes/pages/apps.$appId.tsx +2 -1
  171. package/src/routes/pages/apps.tsx +2 -1
  172. package/src/routes/pages/audit.tsx +1 -1
  173. package/src/routes/pages/automations.tsx +3 -5
  174. package/src/routes/pages/chat.spec.tsx +15 -4
  175. package/src/routes/pages/chat.tsx +3 -4
  176. package/src/routes/pages/destinations.tsx +2 -2
  177. package/src/routes/pages/dreams.tsx +4 -1
  178. package/src/routes/pages/identities.tsx +4 -1
  179. package/src/routes/pages/integrations.tsx +4 -1
  180. package/src/routes/pages/metrics.tsx +2 -1
  181. package/src/routes/pages/new-app.tsx +2 -1
  182. package/src/routes/pages/operations.tsx +3 -5
  183. package/src/routes/pages/settings.tsx +4 -5
  184. package/src/routes/pages/thread-debug.tsx +2 -1
  185. package/src/routes/pages/vault.tsx +4 -1
  186. package/src/routes/pages/workspace.tsx +4 -1
  187. package/dist/actions/provider-api-audit.d.ts +0 -7
  188. package/dist/actions/provider-api-audit.d.ts.map +0 -1
  189. package/dist/actions/provider-api-audit.js +0 -74
  190. package/dist/actions/provider-api-audit.js.map +0 -1
  191. package/src/actions/provider-api-audit.ts +0 -88
@@ -1,4 +1,7 @@
1
- import { useActionMutation, useActionQuery } from "@agent-native/core/client";
1
+ import {
2
+ useActionMutation,
3
+ useActionQuery,
4
+ } from "@agent-native/core/client/hooks";
2
5
  import {
3
6
  IconCheck,
4
7
  IconLoader2,
@@ -1,11 +1,11 @@
1
+ import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
2
+ import { useDevMode } from "@agent-native/core/client/agent-chat";
1
3
  import {
2
- PromptComposer,
3
4
  agentNativePath,
4
5
  appBasePath,
5
- isInBuilderFrame,
6
- sendToAgentChat,
7
- useDevMode,
8
- } from "@agent-native/core/client";
6
+ } from "@agent-native/core/client/api-path";
7
+ import { PromptComposer } from "@agent-native/core/client/composer";
8
+ import { isInBuilderFrame } from "@agent-native/core/client/host";
9
9
  import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
10
10
  import {
11
11
  IconArrowLeft,
@@ -11,7 +11,16 @@ const clientState = vi.hoisted(() => ({
11
11
  navigateWithTransition: vi.fn(),
12
12
  }));
13
13
 
14
- vi.mock("@agent-native/core/client", () => ({
14
+ vi.mock("@agent-native/core/client/agent-chat", () => ({
15
+ navigateWithAgentChatViewTransition: (
16
+ navigate: unknown,
17
+ path: string,
18
+ options?: unknown,
19
+ ) => clientState.navigateWithTransition(navigate, path, options),
20
+ useChatModels: () => ({ selectedModel: "auto" }),
21
+ }));
22
+
23
+ vi.mock("@agent-native/core/client/composer", () => ({
15
24
  PromptComposer: ({
16
25
  onSubmit,
17
26
  placeholder,
@@ -27,19 +36,22 @@ vi.mock("@agent-native/core/client", () => ({
27
36
  Composer
28
37
  </button>
29
38
  ),
30
- isInBuilderFrame: () => false,
31
- navigateWithAgentChatViewTransition: (
32
- navigate: unknown,
33
- path: string,
34
- options?: unknown,
35
- ) => clientState.navigateWithTransition(navigate, path, options),
39
+ }));
40
+
41
+ vi.mock("@agent-native/core/client/hooks", () => ({
36
42
  useActionQuery: () => ({
37
43
  data: [],
38
44
  isLoading: false,
39
45
  isError: false,
40
46
  refetch: vi.fn(),
41
47
  }),
42
- useChatModels: () => ({ selectedModel: "auto" }),
48
+ }));
49
+
50
+ vi.mock("@agent-native/core/client/host", () => ({
51
+ isInBuilderFrame: () => false,
52
+ }));
53
+
54
+ vi.mock("@agent-native/core/client/i18n", () => ({
43
55
  useT: () => (key: string, values?: { defaultValue?: string }) =>
44
56
  values?.defaultValue ?? key,
45
57
  }));
@@ -1,11 +1,11 @@
1
1
  import {
2
- PromptComposer,
3
- isInBuilderFrame,
4
2
  navigateWithAgentChatViewTransition,
5
- useActionQuery,
6
3
  useChatModels,
7
- useT,
8
- } from "@agent-native/core/client";
4
+ } from "@agent-native/core/client/agent-chat";
5
+ import { PromptComposer } from "@agent-native/core/client/composer";
6
+ import { useActionQuery } from "@agent-native/core/client/hooks";
7
+ import { isInBuilderFrame } from "@agent-native/core/client/host";
8
+ import { useT } from "@agent-native/core/client/i18n";
9
9
  import { IconArrowUpRight } from "@tabler/icons-react";
10
10
  import type { ReactNode } from "react";
11
11
  import { Link, useNavigate } from "react-router";
@@ -1,4 +1,4 @@
1
- import { useT } from "@agent-native/core/client";
1
+ import { useT } from "@agent-native/core/client/i18n";
2
2
  import { IconInfoCircle } from "@tabler/icons-react";
3
3
  import { type ReactNode } from "react";
4
4
 
@@ -1,4 +1,5 @@
1
- import { AgentToggleButton, LanguagePicker } from "@agent-native/core/client";
1
+ import { AgentToggleButton } from "@agent-native/core/client/agent-chat";
2
+ import { LanguagePicker } from "@agent-native/core/client/i18n";
2
3
  import { RunsTray } from "@agent-native/core/client/progress";
3
4
  import { IconLayoutSidebar } from "@tabler/icons-react";
4
5
  import { useLocation, useNavigate } from "react-router";
@@ -13,17 +13,13 @@ const clientState = vi.hoisted(() => ({
13
13
  threads: [] as Array<Record<string, unknown>>,
14
14
  }));
15
15
 
16
- vi.mock("@agent-native/core/client", () => ({
16
+ vi.mock("@agent-native/core/client/agent-chat", () => ({
17
17
  AgentSidebar: ({ children }: { children: React.ReactNode }) => children,
18
- FeedbackButton: () => <div>Feedback</div>,
19
- appBasePath: () => "",
20
- appPath: (path: string) => path,
21
18
  focusAgentChat: vi.fn(),
22
19
  navigateWithAgentChatViewTransition: (
23
20
  navigate: (path: string) => void,
24
21
  path: string,
25
22
  ) => navigate(path),
26
- useActionQuery: () => ({ data: undefined }),
27
23
  useAgentChatHomeHandoff: () => false,
28
24
  useAgentChatHomeHandoffLinks: vi.fn(),
29
25
  useChatThreads: () => ({
@@ -35,9 +31,18 @@ vi.mock("@agent-native/core/client", () => ({
35
31
  renameThread: vi.fn(),
36
32
  refreshThreads: vi.fn(),
37
33
  }),
38
- useFormatters: () => ({
39
- formatDate: () => "Jan 1",
40
- }),
34
+ }));
35
+
36
+ vi.mock("@agent-native/core/client/api-path", () => ({
37
+ appBasePath: () => "",
38
+ appPath: (path: string) => path,
39
+ }));
40
+
41
+ vi.mock("@agent-native/core/client/hooks", () => ({
42
+ useActionQuery: () => ({ data: undefined }),
43
+ }));
44
+
45
+ vi.mock("@agent-native/core/client/i18n", () => ({
41
46
  useT: () => (key: string, values?: Record<string, unknown>) => {
42
47
  const messages: Record<string, string> = {
43
48
  "dispatch.nav.chat": "Chat",
@@ -57,6 +62,10 @@ vi.mock("@agent-native/core/client", () => ({
57
62
  },
58
63
  }));
59
64
 
65
+ vi.mock("@agent-native/core/client/ui", () => ({
66
+ FeedbackButton: () => <div>Feedback</div>,
67
+ }));
68
+
60
69
  vi.mock("@agent-native/core/client/extensions", () => ({
61
70
  ExtensionsSidebarSection: () => <div>Extensions</div>,
62
71
  }));
@@ -159,7 +168,7 @@ describe("Dispatch NavContent", () => {
159
168
  expect(lists[0].querySelector("a")?.className).toContain("h-8 w-8");
160
169
  });
161
170
 
162
- it("uses the quieter Analytics-style chat history and retains thread actions", async () => {
171
+ it("uses the shared chat history rail and retains thread actions", async () => {
163
172
  await act(async () => {
164
173
  root.render(
165
174
  <MemoryRouter initialEntries={["/chat/active-thread"]}>
@@ -175,18 +184,14 @@ describe("Dispatch NavContent", () => {
175
184
  expect(container.textContent).toContain("Earlier Dispatch work");
176
185
  expect(container.textContent).toContain("New chat");
177
186
  expect(container.textContent).toContain("5m");
178
- const age = [...container.querySelectorAll("time")].find(
187
+ const age = [...container.querySelectorAll("span")].find(
179
188
  (element) => element.textContent === "5m",
180
189
  );
181
- expect(age?.className).toContain("w-8");
182
- expect(age?.className).toContain("shrink-0");
183
- expect(age?.className).toContain("whitespace-nowrap");
184
- expect(age?.className).toContain("tabular-nums");
185
- expect(
186
- [...container.querySelectorAll("div")].some((element) =>
187
- element.className.includes("group/item"),
188
- ),
189
- ).toBe(true);
190
+ expect(age?.className).toContain("an-chat-history-row__timestamp");
191
+ const historyList = container.querySelector(
192
+ '[data-agent-native="chat-history-list"]',
193
+ );
194
+ expect(historyList?.className).toContain("an-chat-history--rail");
190
195
  expect(
191
196
  container.querySelector('img[src="/agent-native-icon-light.svg"]')
192
197
  ?.parentElement?.className,
@@ -1,19 +1,22 @@
1
1
  import {
2
2
  AgentSidebar,
3
- FeedbackButton,
4
- appBasePath,
5
- appPath,
6
3
  focusAgentChat,
7
4
  navigateWithAgentChatViewTransition,
8
- useActionQuery,
9
5
  useAgentChatHomeHandoff,
10
6
  useAgentChatHomeHandoffLinks,
11
7
  useChatThreads,
12
- useT,
13
8
  type ChatThreadSummary,
14
- } from "@agent-native/core/client";
9
+ } from "@agent-native/core/client/agent-chat";
10
+ import { appBasePath, appPath } from "@agent-native/core/client/api-path";
15
11
  import { ExtensionsSidebarSection } from "@agent-native/core/client/extensions";
12
+ import { useActionQuery } from "@agent-native/core/client/hooks";
13
+ import { useT } from "@agent-native/core/client/i18n";
16
14
  import { InvitationBanner, OrgSwitcher } from "@agent-native/core/client/org";
15
+ import { FeedbackButton } from "@agent-native/core/client/ui";
16
+ import {
17
+ ChatHistoryList,
18
+ type ChatHistoryItem,
19
+ } from "@agent-native/toolkit/chat-history";
17
20
  import {
18
21
  IconActivity,
19
22
  IconArrowUpRight,
@@ -23,8 +26,6 @@ import {
23
26
  IconBrandTelegram,
24
27
  IconKey,
25
28
  IconChevronDown,
26
- IconDots,
27
- IconEdit,
28
29
  IconLayersSubtract,
29
30
  IconMessageQuestion,
30
31
  IconMessages,
@@ -43,10 +44,8 @@ import {
43
44
  import {
44
45
  useEffect,
45
46
  useMemo,
46
- useRef,
47
47
  useState,
48
48
  type ComponentType,
49
- type FormEvent,
50
49
  type ReactNode,
51
50
  } from "react";
52
51
  import { NavLink, useLocation, useNavigate } from "react-router";
@@ -58,7 +57,6 @@ import {
58
57
  DropdownMenuItem,
59
58
  DropdownMenuTrigger,
60
59
  } from "../ui/dropdown-menu";
61
- import { Input } from "../ui/input";
62
60
  import { Sheet, SheetContent, SheetDescription, SheetTitle } from "../ui/sheet";
63
61
  import { Skeleton } from "../ui/skeleton";
64
62
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
@@ -349,10 +347,6 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
349
347
  renameThread,
350
348
  refreshThreads,
351
349
  } = useChatThreads(undefined, "dispatch", undefined, { autoCreate: false });
352
- const [renamingThreadId, setRenamingThreadId] = useState<string | null>(null);
353
- const [renameDraft, setRenameDraft] = useState("");
354
- const renameInputRef = useRef<HTMLInputElement | null>(null);
355
- const committingRenameRef = useRef(false);
356
350
 
357
351
  const visibleThreads = useMemo(
358
352
  () =>
@@ -364,6 +358,22 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
364
358
  .slice(0, 8),
365
359
  [activeThreadId, threads],
366
360
  );
361
+ const localPathname = localDispatchPath(location.pathname);
362
+ const displayedActiveThreadId =
363
+ threadIdFromPath(localPathname) ??
364
+ (localPathname === "/chat" ? null : activeThreadId);
365
+ const chatItems: ChatHistoryItem[] = visibleThreads.map((thread) => {
366
+ const title = threadTitle(thread, t("dispatch.sidebar.newChat"));
367
+ return {
368
+ id: thread.id,
369
+ title: <span title={title}>{title}</span>,
370
+ titleText: title,
371
+ timestamp:
372
+ thread.id === displayedActiveThreadId
373
+ ? ""
374
+ : formatThreadAge(threadUpdatedAt(thread)),
375
+ };
376
+ });
367
377
 
368
378
  useEffect(() => {
369
379
  const refresh = () => refreshThreads();
@@ -384,14 +394,6 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
384
394
  };
385
395
  }, [refreshThreads]);
386
396
 
387
- useEffect(() => {
388
- if (!renamingThreadId) return;
389
- requestAnimationFrame(() => {
390
- renameInputRef.current?.focus();
391
- renameInputRef.current?.select();
392
- });
393
- }, [renamingThreadId]);
394
-
395
397
  function openThread(threadId: string, options?: { isNew?: boolean }) {
396
398
  switchThread(threadId);
397
399
  navigateWithAgentChatViewTransition(
@@ -415,35 +417,6 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
415
417
  if (threadId) openThread(threadId, { isNew: true });
416
418
  }
417
419
 
418
- function startRenameThread(thread: ChatThreadSummary) {
419
- committingRenameRef.current = false;
420
- setRenameDraft(threadTitle(thread, t("dispatch.sidebar.newChat")));
421
- setRenamingThreadId(thread.id);
422
- }
423
-
424
- function cancelRenameThread() {
425
- committingRenameRef.current = true;
426
- setRenamingThreadId(null);
427
- setRenameDraft("");
428
- }
429
-
430
- async function commitRenameThread() {
431
- if (committingRenameRef.current) return;
432
- const threadId = renamingThreadId;
433
- const title = renameDraft.trim();
434
- if (!threadId) return;
435
- committingRenameRef.current = true;
436
- setRenamingThreadId(null);
437
- setRenameDraft("");
438
- if (title) await renameThread(threadId, title);
439
- committingRenameRef.current = false;
440
- }
441
-
442
- function handleRenameSubmit(event: FormEvent<HTMLFormElement>) {
443
- event.preventDefault();
444
- void commitRenameThread();
445
- }
446
-
447
420
  return (
448
421
  <div className="ms-4 min-w-0 space-y-0.5">
449
422
  {chatsLoading &&
@@ -457,105 +430,28 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
457
430
  <Skeleton className="h-3 w-3/4 rounded" />
458
431
  </div>
459
432
  ))}
460
- {visibleThreads.map((thread) => {
461
- const localPathname = localDispatchPath(location.pathname);
462
- const isActive =
463
- thread.id ===
464
- (threadIdFromPath(localPathname) ??
465
- (localPathname === "/chat" ? null : activeThreadId));
466
- const isRenaming = thread.id === renamingThreadId;
467
- const title = threadTitle(thread, t("dispatch.sidebar.newChat"));
468
- return (
469
- <div
470
- key={thread.id}
471
- className={cn(
472
- "group/item relative flex min-w-0 items-center rounded-lg transition-colors",
473
- isActive
474
- ? "bg-sidebar-accent text-sidebar-accent-foreground"
475
- : "text-muted-foreground hover:bg-sidebar-accent/50 hover:text-foreground",
476
- )}
477
- >
478
- {isRenaming ? (
479
- <form
480
- onSubmit={handleRenameSubmit}
481
- className="flex min-w-0 flex-1 items-center px-1"
482
- >
483
- <Input
484
- ref={renameInputRef}
485
- value={renameDraft}
486
- onChange={(event) => setRenameDraft(event.target.value)}
487
- onBlur={() => void commitRenameThread()}
488
- onKeyDown={(event) => {
489
- if (event.key === "Escape") {
490
- event.preventDefault();
491
- cancelRenameThread();
492
- }
493
- }}
494
- maxLength={160}
495
- aria-label={t("dispatch.sidebar.renameThread", { title })}
496
- className="h-6 min-w-0 rounded-sm border-sidebar-border bg-background px-1.5 text-xs"
497
- />
498
- </form>
499
- ) : (
500
- <>
501
- <Tooltip>
502
- <TooltipTrigger asChild>
503
- <button
504
- type="button"
505
- onClick={() => openThread(thread.id)}
506
- className="flex min-w-0 flex-1 cursor-pointer items-center gap-2 px-2 py-1.5 pe-1 text-start text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring"
507
- >
508
- <span className="block min-w-0 flex-1 truncate">
509
- {title}
510
- </span>
511
- <time className="w-8 shrink-0 whitespace-nowrap text-end text-[11px] tabular-nums text-muted-foreground/60 transition-opacity group-hover/item:opacity-0 group-focus-within/item:opacity-0">
512
- {isActive
513
- ? ""
514
- : formatThreadAge(threadUpdatedAt(thread))}
515
- </time>
516
- </button>
517
- </TooltipTrigger>
518
- <TooltipContent side="right">{title}</TooltipContent>
519
- </Tooltip>
520
- <div className="pointer-events-none absolute end-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5">
521
- <DropdownMenu>
522
- <Tooltip>
523
- <TooltipTrigger asChild>
524
- <DropdownMenuTrigger asChild>
525
- <button
526
- type="button"
527
- aria-label={t("dispatch.sidebar.chatOptions", {
528
- title,
529
- })}
530
- className="pointer-events-auto rounded p-0.5 text-muted-foreground/50 opacity-0 transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/item:opacity-100 group-focus-within/item:opacity-100 data-[state=open]:opacity-100 data-[state=open]:text-foreground"
531
- >
532
- <IconDots className="size-3" />
533
- </button>
534
- </DropdownMenuTrigger>
535
- </TooltipTrigger>
536
- <TooltipContent side="right">
537
- {t("dispatch.sidebar.chatOptions", { title })}
538
- </TooltipContent>
539
- </Tooltip>
540
- <DropdownMenuContent
541
- align="start"
542
- side="right"
543
- className="w-44"
544
- >
545
- <DropdownMenuItem
546
- onSelect={() => startRenameThread(thread)}
547
- >
548
- <IconEdit className="size-3.5" />
549
- {t("dispatch.sidebar.renameChat")}
550
- </DropdownMenuItem>
551
- </DropdownMenuContent>
552
- </DropdownMenu>
553
- </div>
554
- </>
555
- )}
556
- </div>
557
- );
558
- })}
433
+ {visibleThreads.length > 0 && (
434
+ <ChatHistoryList
435
+ items={chatItems}
436
+ activeId={displayedActiveThreadId}
437
+ onSelect={(threadId) => openThread(threadId)}
438
+ renameMaxLength={160}
439
+ onRename={(threadId, title) => void renameThread(threadId, title)}
440
+ labels={{
441
+ options: (item) =>
442
+ t("dispatch.sidebar.chatOptions", {
443
+ title: item.titleText ?? "",
444
+ }),
445
+ renameInput: (item) =>
446
+ t("dispatch.sidebar.renameThread", {
447
+ title: item.titleText ?? "",
448
+ }),
449
+ rename: t("dispatch.sidebar.renameChat"),
450
+ }}
451
+ variant="rail"
452
+ className="min-w-0"
453
+ />
454
+ )}
559
455
  <button
560
456
  type="button"
561
457
  onClick={() => void handleNewChat()}
@@ -11,7 +11,7 @@ const clientState = vi.hoisted(() => ({
11
11
  envStatuses: [] as any[],
12
12
  }));
13
13
 
14
- vi.mock("@agent-native/core/client", () => ({
14
+ vi.mock("@agent-native/core/client/integrations", () => ({
15
15
  disconnectManagedIntegrationInstallation: vi.fn(() => Promise.resolve()),
16
16
  listManagedIntegrationBudgets: vi.fn(() => Promise.resolve([])),
17
17
  listManagedIntegrationInstallations: vi.fn(() => Promise.resolve([])),
@@ -32,6 +32,9 @@ vi.mock("@agent-native/core/client", () => ({
32
32
  setIntegrationEnabled: vi.fn(),
33
33
  setupIntegration: vi.fn(),
34
34
  testManagedIntegrationInstallation: vi.fn(() => Promise.resolve()),
35
+ }));
36
+
37
+ vi.mock("@agent-native/core/client/i18n", () => ({
35
38
  useFormatters: () => ({
36
39
  formatDate: (value: Date | number | string) =>
37
40
  new Date(value).toLocaleDateString("en-US"),
@@ -1,3 +1,4 @@
1
+ import { useFormatters, useT } from "@agent-native/core/client/i18n";
1
2
  import {
2
3
  disconnectManagedIntegrationInstallation,
3
4
  listManagedIntegrationBudgets,
@@ -18,9 +19,7 @@ import {
18
19
  type ClientIntegrationUsageBudget,
19
20
  type ClientIntegrationStatus,
20
21
  type IntegrationEnvStatus,
21
- useFormatters,
22
- useT,
23
- } from "@agent-native/core/client";
22
+ } from "@agent-native/core/client/integrations";
24
23
  import {
25
24
  listBuiltInChannelIntegrations,
26
25
  type IntegrationCatalogEntry,
@@ -1,4 +1,5 @@
1
- import { useChangeVersions, useT } from "@agent-native/core/client";
1
+ import { useChangeVersions } from "@agent-native/core/client/hooks";
2
+ import { useT } from "@agent-native/core/client/i18n";
2
3
  import { IconAlertTriangle, IconPlayerPlay } from "@tabler/icons-react";
3
4
  import { useQuery } from "@tanstack/react-query";
4
5
 
@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
6
  import { TooltipProvider } from "./ui/tooltip";
7
7
  import { WorkspaceAppCard } from "./workspace-app-card";
8
8
 
9
- vi.mock("@agent-native/core/client", () => ({
9
+ vi.mock("@agent-native/core/client/hooks", () => ({
10
10
  useActionMutation: () => ({ mutate: vi.fn(), isPending: false }),
11
11
  useActionQuery: () => ({
12
12
  data: { resources: [], counts: {} },
@@ -1,4 +1,7 @@
1
- import { useActionMutation, useActionQuery } from "@agent-native/core/client";
1
+ import {
2
+ useActionMutation,
3
+ useActionQuery,
4
+ } from "@agent-native/core/client/hooks";
2
5
  import {
3
6
  IconChevronDown,
4
7
  IconChevronRight,
@@ -14,7 +14,7 @@ const queryState = vi.hoisted(() => ({
14
14
  calls: [] as any[],
15
15
  }));
16
16
 
17
- vi.mock("@agent-native/core/client", () => ({
17
+ vi.mock("@agent-native/core/client/hooks", () => ({
18
18
  useActionQuery: (...args: any[]) => {
19
19
  queryState.calls.push(args);
20
20
  return queryState.result;
@@ -1,4 +1,4 @@
1
- import { useActionQuery } from "@agent-native/core/client";
1
+ import { useActionQuery } from "@agent-native/core/client/hooks";
2
2
 
3
3
  import { cn } from "../lib/utils";
4
4
  import { ActionQueryError } from "./action-query-error";
@@ -13,7 +13,7 @@ const queryState = vi.hoisted(() => ({
13
13
  calls: [] as any[],
14
14
  }));
15
15
 
16
- vi.mock("@agent-native/core/client", () => ({
16
+ vi.mock("@agent-native/core/client/hooks", () => ({
17
17
  useActionQuery: (...args: any[]) => {
18
18
  queryState.calls.push(args);
19
19
  return queryState.result;
@@ -1,4 +1,4 @@
1
- import { useActionQuery } from "@agent-native/core/client";
1
+ import { useActionQuery } from "@agent-native/core/client/hooks";
2
2
 
3
3
  import { ActionQueryError } from "./action-query-error";
4
4
  import { Badge } from "./ui/badge";
@@ -20,7 +20,7 @@ const toast = vi.hoisted(() => ({
20
20
  success: vi.fn(),
21
21
  }));
22
22
 
23
- vi.mock("@agent-native/core/client", () => ({
23
+ vi.mock("@agent-native/core/client/hooks", () => ({
24
24
  useActionMutation: (_name: string, options: Record<string, unknown>) => {
25
25
  clientState.options = options;
26
26
  return {
@@ -1,4 +1,4 @@
1
- import { useActionMutation } from "@agent-native/core/client";
1
+ import { useActionMutation } from "@agent-native/core/client/hooks";
2
2
  import {
3
3
  IconArrowUpRight,
4
4
  IconCircleCheck,
@@ -1,10 +1,12 @@
1
+ import {
2
+ isAgentChatHomeHandoffActive,
3
+ markAgentChatHomeHandoff,
4
+ } from "@agent-native/core/client/agent-chat";
1
5
  import {
2
6
  agentNativePath,
3
7
  appBasePath,
4
8
  appPath,
5
- isAgentChatHomeHandoffActive,
6
- markAgentChatHomeHandoff,
7
- } from "@agent-native/core/client";
9
+ } from "@agent-native/core/client/api-path";
8
10
  import { extensionIdFromPathname } from "@agent-native/core/client/extensions";
9
11
  import { useQuery, useQueryClient } from "@tanstack/react-query";
10
12
  import { useEffect } from "react";
@@ -1,4 +1,4 @@
1
- import { agentNativePath } from "@agent-native/core/client";
1
+ import { agentNativePath } from "@agent-native/core/client/api-path";
2
2
 
3
3
  export interface DispatchAutomationItem {
4
4
  id: string;
@@ -3,11 +3,14 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
3
3
  const frameState = vi.hoisted(() => ({ inBuilderFrame: false }));
4
4
  const sendToAgentChatMock = vi.hoisted(() => vi.fn(() => "chat-tab"));
5
5
 
6
- vi.mock("@agent-native/core/client", () => ({
7
- isInBuilderFrame: () => frameState.inBuilderFrame,
6
+ vi.mock("@agent-native/core/client/agent-chat", () => ({
8
7
  sendToAgentChat: sendToAgentChatMock,
9
8
  }));
10
9
 
10
+ vi.mock("@agent-native/core/client/host", () => ({
11
+ isInBuilderFrame: () => frameState.inBuilderFrame,
12
+ }));
13
+
11
14
  const { submitOverviewPrompt } = await import("./overview-chat.js");
12
15
 
13
16
  describe("submitOverviewPrompt", () => {
@@ -1,4 +1,5 @@
1
- import { isInBuilderFrame, sendToAgentChat } from "@agent-native/core/client";
1
+ import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
2
+ import { isInBuilderFrame } from "@agent-native/core/client/host";
2
3
 
3
4
  export function submitOverviewPrompt(
4
5
  message: string,
@@ -1,4 +1,4 @@
1
- import { agentNativePath } from "@agent-native/core/client";
1
+ import { agentNativePath } from "@agent-native/core/client/api-path";
2
2
 
3
3
  export interface TaskQueueFailure {
4
4
  id: string;
@@ -1,4 +1,6 @@
1
- import { useActionQuery, appPath, useT } from "@agent-native/core/client";
1
+ import { appPath } from "@agent-native/core/client/api-path";
2
+ import { useActionQuery } from "@agent-native/core/client/hooks";
3
+ import { useT } from "@agent-native/core/client/i18n";
2
4
  import {
3
5
  IconArrowLeft,
4
6
  IconArrowUpRight,
@@ -1,4 +1,4 @@
1
- import { appPath } from "@agent-native/core/client";
1
+ import { appPath } from "@agent-native/core/client/api-path";
2
2
  import { redirect, type LoaderFunctionArgs } from "react-router";
3
3
 
4
4
  import { Spinner } from "../../components/ui/spinner";