@agent-native/dispatch 0.13.10 → 0.13.12

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 (254) hide show
  1. package/dist/actions/navigate.js +1 -1
  2. package/dist/actions/navigate.js.map +1 -1
  3. package/dist/components/agents-panel.js +3 -3
  4. package/dist/components/agents-panel.js.map +1 -1
  5. package/dist/components/app-keys-popover.d.ts.map +1 -1
  6. package/dist/components/app-keys-popover.js +3 -3
  7. package/dist/components/app-keys-popover.js.map +1 -1
  8. package/dist/components/create-app-popover.d.ts.map +1 -1
  9. package/dist/components/create-app-popover.js +2 -2
  10. package/dist/components/create-app-popover.js.map +1 -1
  11. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  12. package/dist/components/dispatch-control-plane.js +19 -7
  13. package/dist/components/dispatch-control-plane.js.map +1 -1
  14. package/dist/components/dispatch-shell.d.ts.map +1 -1
  15. package/dist/components/dispatch-shell.js +2 -2
  16. package/dist/components/dispatch-shell.js.map +1 -1
  17. package/dist/components/layout/Header.js +2 -1
  18. package/dist/components/layout/Header.js.map +1 -1
  19. package/dist/components/layout/Layout.d.ts.map +1 -1
  20. package/dist/components/layout/Layout.js +12 -5
  21. package/dist/components/layout/Layout.js.map +1 -1
  22. package/dist/components/messaging-setup-panel.d.ts.map +1 -1
  23. package/dist/components/messaging-setup-panel.js +4 -4
  24. package/dist/components/messaging-setup-panel.js.map +1 -1
  25. package/dist/components/task-queue-health.d.ts +2 -0
  26. package/dist/components/task-queue-health.d.ts.map +1 -0
  27. package/dist/components/task-queue-health.js +49 -0
  28. package/dist/components/task-queue-health.js.map +1 -0
  29. package/dist/components/ui/accordion.js.map +1 -1
  30. package/dist/components/ui/alert-dialog.js +1 -1
  31. package/dist/components/ui/alert-dialog.js.map +1 -1
  32. package/dist/components/ui/alert.js.map +1 -1
  33. package/dist/components/ui/avatar.js.map +1 -1
  34. package/dist/components/ui/badge.js.map +1 -1
  35. package/dist/components/ui/breadcrumb.js.map +1 -1
  36. package/dist/components/ui/button.js.map +1 -1
  37. package/dist/components/ui/calendar.js +1 -1
  38. package/dist/components/ui/calendar.js.map +1 -1
  39. package/dist/components/ui/card.js.map +1 -1
  40. package/dist/components/ui/carousel.d.ts +2 -2
  41. package/dist/components/ui/carousel.d.ts.map +1 -1
  42. package/dist/components/ui/carousel.js +1 -1
  43. package/dist/components/ui/carousel.js.map +1 -1
  44. package/dist/components/ui/chart.js.map +1 -1
  45. package/dist/components/ui/checkbox.js.map +1 -1
  46. package/dist/components/ui/command.js +1 -1
  47. package/dist/components/ui/command.js.map +1 -1
  48. package/dist/components/ui/context-menu.js.map +1 -1
  49. package/dist/components/ui/dialog.js.map +1 -1
  50. package/dist/components/ui/drawer.js.map +1 -1
  51. package/dist/components/ui/dropdown-menu.js.map +1 -1
  52. package/dist/components/ui/form.js +1 -1
  53. package/dist/components/ui/form.js.map +1 -1
  54. package/dist/components/ui/hover-card.js.map +1 -1
  55. package/dist/components/ui/input-otp.js.map +1 -1
  56. package/dist/components/ui/input.js.map +1 -1
  57. package/dist/components/ui/label.js.map +1 -1
  58. package/dist/components/ui/menubar.js.map +1 -1
  59. package/dist/components/ui/navigation-menu.js.map +1 -1
  60. package/dist/components/ui/pagination.d.ts +1 -1
  61. package/dist/components/ui/pagination.d.ts.map +1 -1
  62. package/dist/components/ui/pagination.js +1 -1
  63. package/dist/components/ui/pagination.js.map +1 -1
  64. package/dist/components/ui/popover.js.map +1 -1
  65. package/dist/components/ui/progress.js.map +1 -1
  66. package/dist/components/ui/radio-group.js.map +1 -1
  67. package/dist/components/ui/resizable.js.map +1 -1
  68. package/dist/components/ui/scroll-area.js.map +1 -1
  69. package/dist/components/ui/select.js.map +1 -1
  70. package/dist/components/ui/separator.js.map +1 -1
  71. package/dist/components/ui/sheet.js.map +1 -1
  72. package/dist/components/ui/sidebar.d.ts +2 -2
  73. package/dist/components/ui/sidebar.d.ts.map +1 -1
  74. package/dist/components/ui/sidebar.js +6 -6
  75. package/dist/components/ui/sidebar.js.map +1 -1
  76. package/dist/components/ui/skeleton.js.map +1 -1
  77. package/dist/components/ui/slider.js.map +1 -1
  78. package/dist/components/ui/sonner.js.map +1 -1
  79. package/dist/components/ui/spinner.js.map +1 -1
  80. package/dist/components/ui/switch.js.map +1 -1
  81. package/dist/components/ui/table.js.map +1 -1
  82. package/dist/components/ui/tabs.js.map +1 -1
  83. package/dist/components/ui/textarea.js.map +1 -1
  84. package/dist/components/ui/toast.js.map +1 -1
  85. package/dist/components/ui/toaster.js +1 -1
  86. package/dist/components/ui/toaster.js.map +1 -1
  87. package/dist/components/ui/toggle-group.js +1 -1
  88. package/dist/components/ui/toggle-group.js.map +1 -1
  89. package/dist/components/ui/toggle.js.map +1 -1
  90. package/dist/components/ui/tooltip.js.map +1 -1
  91. package/dist/components/ui/use-toast.d.ts.map +1 -1
  92. package/dist/components/ui/use-toast.js.map +1 -1
  93. package/dist/components/workspace-app-card.d.ts.map +1 -1
  94. package/dist/components/workspace-app-card.js +10 -10
  95. package/dist/components/workspace-app-card.js.map +1 -1
  96. package/dist/components/workspace-resource-effective-stack.js +1 -1
  97. package/dist/components/workspace-resource-effective-stack.js.map +1 -1
  98. package/dist/components/workspace-resource-impact-preview.d.ts.map +1 -1
  99. package/dist/components/workspace-resource-impact-preview.js +2 -2
  100. package/dist/components/workspace-resource-impact-preview.js.map +1 -1
  101. package/dist/hooks/use-navigation-state.js +5 -0
  102. package/dist/hooks/use-navigation-state.js.map +1 -1
  103. package/dist/hooks/use-toast.d.ts.map +1 -1
  104. package/dist/hooks/use-toast.js.map +1 -1
  105. package/dist/lib/automation-display.d.ts +13 -0
  106. package/dist/lib/automation-display.d.ts.map +1 -0
  107. package/dist/lib/automation-display.js +62 -0
  108. package/dist/lib/automation-display.js.map +1 -0
  109. package/dist/lib/task-queue.d.ts +19 -0
  110. package/dist/lib/task-queue.d.ts.map +1 -0
  111. package/dist/lib/task-queue.js +54 -0
  112. package/dist/lib/task-queue.js.map +1 -0
  113. package/dist/routes/index.d.ts.map +1 -1
  114. package/dist/routes/index.js +1 -0
  115. package/dist/routes/index.js.map +1 -1
  116. package/dist/routes/pages/_index.js.map +1 -1
  117. package/dist/routes/pages/agents.d.ts.map +1 -1
  118. package/dist/routes/pages/agents.js +1 -1
  119. package/dist/routes/pages/agents.js.map +1 -1
  120. package/dist/routes/pages/approval.js.map +1 -1
  121. package/dist/routes/pages/approvals.js.map +1 -1
  122. package/dist/routes/pages/apps.$appId.js.map +1 -1
  123. package/dist/routes/pages/apps.js.map +1 -1
  124. package/dist/routes/pages/audit.js.map +1 -1
  125. package/dist/routes/pages/automations.d.ts +5 -0
  126. package/dist/routes/pages/automations.d.ts.map +1 -0
  127. package/dist/routes/pages/automations.js +106 -0
  128. package/dist/routes/pages/automations.js.map +1 -0
  129. package/dist/routes/pages/chat.js.map +1 -1
  130. package/dist/routes/pages/destinations.d.ts.map +1 -1
  131. package/dist/routes/pages/destinations.js +31 -27
  132. package/dist/routes/pages/destinations.js.map +1 -1
  133. package/dist/routes/pages/dreams.d.ts.map +1 -1
  134. package/dist/routes/pages/dreams.js +1 -1
  135. package/dist/routes/pages/dreams.js.map +1 -1
  136. package/dist/routes/pages/identities.js.map +1 -1
  137. package/dist/routes/pages/integrations.js.map +1 -1
  138. package/dist/routes/pages/messaging.js.map +1 -1
  139. package/dist/routes/pages/metrics.js.map +1 -1
  140. package/dist/routes/pages/new-app.js.map +1 -1
  141. package/dist/routes/pages/overview.d.ts +2 -2
  142. package/dist/routes/pages/overview.js.map +1 -1
  143. package/dist/routes/pages/settings.d.ts.map +1 -1
  144. package/dist/routes/pages/settings.js +2 -2
  145. package/dist/routes/pages/settings.js.map +1 -1
  146. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  147. package/dist/routes/pages/thread-debug.js +1 -1
  148. package/dist/routes/pages/thread-debug.js.map +1 -1
  149. package/dist/routes/pages/vault.d.ts.map +1 -1
  150. package/dist/routes/pages/vault.js +1 -1
  151. package/dist/routes/pages/vault.js.map +1 -1
  152. package/dist/routes/pages/workspace.d.ts.map +1 -1
  153. package/dist/routes/pages/workspace.js +1 -1
  154. package/dist/routes/pages/workspace.js.map +1 -1
  155. package/dist/server/lib/pre-auth-routing.d.ts.map +1 -1
  156. package/dist/server/lib/pre-auth-routing.js +1 -0
  157. package/dist/server/lib/pre-auth-routing.js.map +1 -1
  158. package/dist/server/lib/usage-metrics-store.d.ts.map +1 -1
  159. package/dist/server/lib/usage-metrics-store.js +12 -3
  160. package/dist/server/lib/usage-metrics-store.js.map +1 -1
  161. package/package.json +7 -7
  162. package/src/actions/navigate.ts +1 -1
  163. package/src/components/agents-panel.tsx +3 -3
  164. package/src/components/app-keys-popover.tsx +3 -7
  165. package/src/components/create-app-popover.tsx +2 -6
  166. package/src/components/dispatch-control-plane.tsx +48 -7
  167. package/src/components/dispatch-shell.tsx +2 -6
  168. package/src/components/layout/Header.tsx +2 -2
  169. package/src/components/layout/Layout.tsx +13 -15
  170. package/src/components/messaging-setup-panel.tsx +4 -8
  171. package/src/components/task-queue-health.tsx +166 -0
  172. package/src/components/ui/accordion.tsx +1 -1
  173. package/src/components/ui/alert-dialog.tsx +2 -2
  174. package/src/components/ui/alert.tsx +1 -1
  175. package/src/components/ui/avatar.tsx +1 -1
  176. package/src/components/ui/badge.tsx +1 -1
  177. package/src/components/ui/breadcrumb.tsx +1 -1
  178. package/src/components/ui/button.tsx +1 -1
  179. package/src/components/ui/calendar.tsx +2 -2
  180. package/src/components/ui/card.tsx +1 -1
  181. package/src/components/ui/carousel.tsx +2 -2
  182. package/src/components/ui/chart.tsx +1 -1
  183. package/src/components/ui/checkbox.tsx +1 -1
  184. package/src/components/ui/command.tsx +2 -2
  185. package/src/components/ui/context-menu.tsx +1 -1
  186. package/src/components/ui/dialog.tsx +1 -1
  187. package/src/components/ui/drawer.tsx +1 -1
  188. package/src/components/ui/dropdown-menu.tsx +1 -1
  189. package/src/components/ui/form.tsx +2 -2
  190. package/src/components/ui/hover-card.tsx +1 -1
  191. package/src/components/ui/input-otp.tsx +1 -1
  192. package/src/components/ui/input.tsx +1 -1
  193. package/src/components/ui/label.tsx +1 -1
  194. package/src/components/ui/menubar.tsx +1 -1
  195. package/src/components/ui/navigation-menu.tsx +1 -1
  196. package/src/components/ui/pagination.tsx +2 -2
  197. package/src/components/ui/popover.tsx +1 -1
  198. package/src/components/ui/progress.tsx +1 -1
  199. package/src/components/ui/radio-group.tsx +1 -1
  200. package/src/components/ui/resizable.tsx +1 -1
  201. package/src/components/ui/scroll-area.tsx +1 -1
  202. package/src/components/ui/select.tsx +1 -1
  203. package/src/components/ui/separator.tsx +1 -1
  204. package/src/components/ui/sheet.tsx +1 -1
  205. package/src/components/ui/sidebar.tsx +8 -13
  206. package/src/components/ui/skeleton.tsx +1 -1
  207. package/src/components/ui/slider.tsx +1 -1
  208. package/src/components/ui/sonner.tsx +1 -1
  209. package/src/components/ui/spinner.tsx +1 -1
  210. package/src/components/ui/switch.tsx +1 -1
  211. package/src/components/ui/table.tsx +1 -1
  212. package/src/components/ui/tabs.tsx +1 -1
  213. package/src/components/ui/textarea.tsx +1 -1
  214. package/src/components/ui/toast.tsx +1 -1
  215. package/src/components/ui/toaster.tsx +2 -2
  216. package/src/components/ui/toggle-group.tsx +2 -2
  217. package/src/components/ui/toggle.tsx +1 -1
  218. package/src/components/ui/tooltip.tsx +1 -1
  219. package/src/components/ui/use-toast.ts +1 -1
  220. package/src/components/workspace-app-card.tsx +16 -20
  221. package/src/components/workspace-resource-effective-stack.tsx +2 -2
  222. package/src/components/workspace-resource-impact-preview.tsx +2 -3
  223. package/src/hooks/use-navigation-state.spec.ts +7 -0
  224. package/src/hooks/use-navigation-state.ts +4 -0
  225. package/src/hooks/use-toast.ts +1 -1
  226. package/src/lib/automation-display.spec.ts +95 -0
  227. package/src/lib/automation-display.ts +70 -0
  228. package/src/lib/task-queue.spec.ts +57 -0
  229. package/src/lib/task-queue.ts +72 -0
  230. package/src/routes/index.ts +1 -0
  231. package/src/routes/pages/_index.tsx +1 -1
  232. package/src/routes/pages/agents.tsx +8 -5
  233. package/src/routes/pages/approval.tsx +4 -4
  234. package/src/routes/pages/approvals.tsx +4 -4
  235. package/src/routes/pages/apps.$appId.tsx +5 -5
  236. package/src/routes/pages/apps.tsx +8 -8
  237. package/src/routes/pages/audit.tsx +1 -1
  238. package/src/routes/pages/automations.tsx +280 -0
  239. package/src/routes/pages/chat.tsx +1 -1
  240. package/src/routes/pages/destinations.tsx +163 -154
  241. package/src/routes/pages/dreams.tsx +22 -18
  242. package/src/routes/pages/identities.tsx +2 -2
  243. package/src/routes/pages/integrations.tsx +8 -8
  244. package/src/routes/pages/messaging.tsx +2 -2
  245. package/src/routes/pages/metrics.tsx +6 -6
  246. package/src/routes/pages/new-app.tsx +1 -1
  247. package/src/routes/pages/overview.tsx +1 -1
  248. package/src/routes/pages/settings.tsx +37 -6
  249. package/src/routes/pages/thread-debug.tsx +14 -9
  250. package/src/routes/pages/vault.tsx +17 -12
  251. package/src/routes/pages/workspace.tsx +17 -12
  252. package/src/server/lib/pre-auth-routing.ts +1 -0
  253. package/src/server/lib/usage-metrics-store.spec.ts +102 -0
  254. package/src/server/lib/usage-metrics-store.ts +12 -3
@@ -17,20 +17,20 @@ import { useEffect, useMemo, useState } from "react";
17
17
  import { useSearchParams } from "react-router";
18
18
  import { toast } from "sonner";
19
19
 
20
- import { DispatchShell } from "@/components/dispatch-shell";
20
+ import { DispatchShell } from "../../components/dispatch-shell";
21
21
  import {
22
22
  Accordion,
23
23
  AccordionContent,
24
24
  AccordionItem,
25
25
  AccordionTrigger,
26
- } from "@/components/ui/accordion";
27
- import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
28
- import { Badge } from "@/components/ui/badge";
29
- import { Button } from "@/components/ui/button";
30
- import { Input } from "@/components/ui/input";
31
- import { Label } from "@/components/ui/label";
32
- import { ScrollArea } from "@/components/ui/scroll-area";
33
- import { Separator } from "@/components/ui/separator";
26
+ } from "../../components/ui/accordion";
27
+ import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert";
28
+ import { Badge } from "../../components/ui/badge";
29
+ import { Button } from "../../components/ui/button";
30
+ import { Input } from "../../components/ui/input";
31
+ import { Label } from "../../components/ui/label";
32
+ import { ScrollArea } from "../../components/ui/scroll-area";
33
+ import { Separator } from "../../components/ui/separator";
34
34
  import {
35
35
  Sheet,
36
36
  SheetContent,
@@ -39,10 +39,10 @@ import {
39
39
  SheetHeader,
40
40
  SheetTitle,
41
41
  SheetTrigger,
42
- } from "@/components/ui/sheet";
43
- import { Skeleton } from "@/components/ui/skeleton";
44
- import { Spinner } from "@/components/ui/spinner";
45
- import { Switch } from "@/components/ui/switch";
42
+ } from "../../components/ui/sheet";
43
+ import { Skeleton } from "../../components/ui/skeleton";
44
+ import { Spinner } from "../../components/ui/spinner";
45
+ import { Switch } from "../../components/ui/switch";
46
46
  import {
47
47
  Table,
48
48
  TableBody,
@@ -50,11 +50,15 @@ import {
50
50
  TableHead,
51
51
  TableHeader,
52
52
  TableRow,
53
- } from "@/components/ui/table";
54
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
55
- import { Textarea } from "@/components/ui/textarea";
56
- import { cn } from "@/lib/utils";
57
-
53
+ } from "../../components/ui/table";
54
+ import {
55
+ Tabs,
56
+ TabsContent,
57
+ TabsList,
58
+ TabsTrigger,
59
+ } from "../../components/ui/tabs";
60
+ import { Textarea } from "../../components/ui/textarea";
61
+ import { cn } from "../../lib/utils";
58
62
  import {
59
63
  dreamSettingsToDraft,
60
64
  dreamSettingsUpdateFromDraft,
@@ -1,8 +1,8 @@
1
1
  import { useActionMutation, useActionQuery } from "@agent-native/core/client";
2
2
  import { toast } from "sonner";
3
3
 
4
- import { DispatchShell } from "@/components/dispatch-shell";
5
- import { Button } from "@/components/ui/button";
4
+ import { DispatchShell } from "../../components/dispatch-shell";
5
+ import { Button } from "../../components/ui/button";
6
6
 
7
7
  export function meta() {
8
8
  return [{ title: "Identities — Dispatch" }];
@@ -11,14 +11,14 @@ import { useQueryClient } from "@tanstack/react-query";
11
11
  import { useMemo, useState } from "react";
12
12
  import { toast } from "sonner";
13
13
 
14
- import { DispatchShell } from "@/components/dispatch-shell";
15
- import { Badge } from "@/components/ui/badge";
16
- import { Button } from "@/components/ui/button";
14
+ import { DispatchShell } from "../../components/dispatch-shell";
15
+ import { Badge } from "../../components/ui/badge";
16
+ import { Button } from "../../components/ui/button";
17
17
  import {
18
18
  Collapsible,
19
19
  CollapsibleContent,
20
20
  CollapsibleTrigger,
21
- } from "@/components/ui/collapsible";
21
+ } from "../../components/ui/collapsible";
22
22
  import {
23
23
  Dialog,
24
24
  DialogContent,
@@ -26,14 +26,14 @@ import {
26
26
  DialogFooter,
27
27
  DialogHeader,
28
28
  DialogTitle,
29
- } from "@/components/ui/dialog";
30
- import { Input } from "@/components/ui/input";
31
- import { Label } from "@/components/ui/label";
29
+ } from "../../components/ui/dialog";
30
+ import { Input } from "../../components/ui/input";
31
+ import { Label } from "../../components/ui/label";
32
32
  import {
33
33
  Tooltip,
34
34
  TooltipContent,
35
35
  TooltipTrigger,
36
- } from "@/components/ui/tooltip";
36
+ } from "../../components/ui/tooltip";
37
37
 
38
38
  export function meta() {
39
39
  return [{ title: "Connections — Dispatch" }];
@@ -1,5 +1,5 @@
1
- import { DispatchShell } from "@/components/dispatch-shell";
2
- import { MessagingSetupPanel } from "@/components/messaging-setup-panel";
1
+ import { DispatchShell } from "../../components/dispatch-shell";
2
+ import { MessagingSetupPanel } from "../../components/messaging-setup-panel";
3
3
 
4
4
  export function meta() {
5
5
  return [{ title: "Messaging — Dispatch" }];
@@ -11,12 +11,12 @@ import {
11
11
  } from "@tabler/icons-react";
12
12
  import { useMemo, useState, type ReactNode } from "react";
13
13
 
14
- import { DispatchShell } from "@/components/dispatch-shell";
15
- import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
16
- import { Badge } from "@/components/ui/badge";
17
- import { Button } from "@/components/ui/button";
18
- import { Skeleton } from "@/components/ui/skeleton";
19
- import { cn } from "@/lib/utils";
14
+ import { DispatchShell } from "../../components/dispatch-shell";
15
+ import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert";
16
+ import { Badge } from "../../components/ui/badge";
17
+ import { Button } from "../../components/ui/button";
18
+ import { Skeleton } from "../../components/ui/skeleton";
19
+ import { cn } from "../../lib/utils";
20
20
 
21
21
  export function meta() {
22
22
  return [{ title: "Metrics — Dispatch" }];
@@ -1,6 +1,6 @@
1
1
  import { NewWorkspaceAppFlow, useT } from "@agent-native/core/client";
2
2
 
3
- import { DispatchShell } from "@/components/dispatch-shell";
3
+ import { DispatchShell } from "../../components/dispatch-shell";
4
4
 
5
5
  export function meta() {
6
6
  return [{ title: "New App — Dispatch" }];
@@ -1,4 +1,4 @@
1
- import { DispatchControlPlane } from "@/components/dispatch-control-plane";
1
+ import { DispatchControlPlane } from "../../components/dispatch-control-plane";
2
2
 
3
3
  const SEO_TITLE =
4
4
  "Agent-Native Dispatch - Open Source workspace control plane for AI agents";
@@ -8,18 +8,17 @@ import {
8
8
  import { TeamPage } from "@agent-native/core/client/org";
9
9
  import { Link } from "react-router";
10
10
 
11
- import { DispatchShell } from "@/components/dispatch-shell";
12
- import { Button } from "@/components/ui/button";
11
+ import changelog from "../../../CHANGELOG.md?raw";
12
+ import { DispatchShell } from "../../components/dispatch-shell";
13
+ import { Button } from "../../components/ui/button";
13
14
  import {
14
15
  Card,
15
16
  CardContent,
16
17
  CardDescription,
17
18
  CardHeader,
18
19
  CardTitle,
19
- } from "@/components/ui/card";
20
- import { Label } from "@/components/ui/label";
21
-
22
- import changelog from "../../../CHANGELOG.md?raw";
20
+ } from "../../components/ui/card";
21
+ import { Label } from "../../components/ui/label";
23
22
 
24
23
  export function meta() {
25
24
  return [{ title: "Settings - Dispatch" }];
@@ -70,6 +69,38 @@ export default function SettingsRoute() {
70
69
  </Button>
71
70
  </CardContent>
72
71
  </Card>
72
+
73
+ <Card>
74
+ <CardHeader>
75
+ <CardTitle className="text-base">
76
+ {t("settings.automationsTitle")}
77
+ </CardTitle>
78
+ <CardDescription>
79
+ {t("settings.automationsDescription")}
80
+ </CardDescription>
81
+ </CardHeader>
82
+ <CardContent>
83
+ <Button variant="outline" asChild>
84
+ <Link to="/automations">{t("settings.openAutomations")}</Link>
85
+ </Button>
86
+ </CardContent>
87
+ </Card>
88
+
89
+ <Card>
90
+ <CardHeader>
91
+ <CardTitle className="text-base">
92
+ {t("settings.deliveryTitle")}
93
+ </CardTitle>
94
+ <CardDescription>
95
+ {t("settings.deliveryDescription")}
96
+ </CardDescription>
97
+ </CardHeader>
98
+ <CardContent>
99
+ <Button variant="outline" asChild>
100
+ <Link to="/destinations">{t("settings.openDelivery")}</Link>
101
+ </Button>
102
+ </CardContent>
103
+ </Card>
73
104
  </div>
74
105
  }
75
106
  team={
@@ -7,21 +7,26 @@ import {
7
7
  } from "@tabler/icons-react";
8
8
  import { useEffect, useMemo, useState } from "react";
9
9
 
10
- import { DispatchShell } from "@/components/dispatch-shell";
11
- import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
12
- import { Badge } from "@/components/ui/badge";
13
- import { Button } from "@/components/ui/button";
14
- import { Input } from "@/components/ui/input";
10
+ import { DispatchShell } from "../../components/dispatch-shell";
11
+ import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert";
12
+ import { Badge } from "../../components/ui/badge";
13
+ import { Button } from "../../components/ui/button";
14
+ import { Input } from "../../components/ui/input";
15
15
  import {
16
16
  Select,
17
17
  SelectContent,
18
18
  SelectItem,
19
19
  SelectTrigger,
20
20
  SelectValue,
21
- } from "@/components/ui/select";
22
- import { Skeleton } from "@/components/ui/skeleton";
23
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
24
- import { cn } from "@/lib/utils";
21
+ } from "../../components/ui/select";
22
+ import { Skeleton } from "../../components/ui/skeleton";
23
+ import {
24
+ Tabs,
25
+ TabsContent,
26
+ TabsList,
27
+ TabsTrigger,
28
+ } from "../../components/ui/tabs";
29
+ import { cn } from "../../lib/utils";
25
30
 
26
31
  export function meta() {
27
32
  return [{ title: "Thread Debug — Dispatch" }];
@@ -14,7 +14,7 @@ import {
14
14
  import { useState } from "react";
15
15
  import { toast } from "sonner";
16
16
 
17
- import { DispatchShell } from "@/components/dispatch-shell";
17
+ import { DispatchShell } from "../../components/dispatch-shell";
18
18
  import {
19
19
  AlertDialog,
20
20
  AlertDialogAction,
@@ -25,9 +25,9 @@ import {
25
25
  AlertDialogHeader,
26
26
  AlertDialogTitle,
27
27
  AlertDialogTrigger,
28
- } from "@/components/ui/alert-dialog";
29
- import { Badge } from "@/components/ui/badge";
30
- import { Button } from "@/components/ui/button";
28
+ } from "../../components/ui/alert-dialog";
29
+ import { Badge } from "../../components/ui/badge";
30
+ import { Button } from "../../components/ui/button";
31
31
  import {
32
32
  Dialog,
33
33
  DialogContent,
@@ -36,20 +36,25 @@ import {
36
36
  DialogHeader,
37
37
  DialogTitle,
38
38
  DialogTrigger,
39
- } from "@/components/ui/dialog";
40
- import { Input } from "@/components/ui/input";
41
- import { Label } from "@/components/ui/label";
39
+ } from "../../components/ui/dialog";
40
+ import { Input } from "../../components/ui/input";
41
+ import { Label } from "../../components/ui/label";
42
42
  import {
43
43
  Select,
44
44
  SelectContent,
45
45
  SelectItem,
46
46
  SelectTrigger,
47
47
  SelectValue,
48
- } from "@/components/ui/select";
49
- import { Skeleton } from "@/components/ui/skeleton";
50
- import { Switch } from "@/components/ui/switch";
51
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
52
- import { Textarea } from "@/components/ui/textarea";
48
+ } from "../../components/ui/select";
49
+ import { Skeleton } from "../../components/ui/skeleton";
50
+ import { Switch } from "../../components/ui/switch";
51
+ import {
52
+ Tabs,
53
+ TabsContent,
54
+ TabsList,
55
+ TabsTrigger,
56
+ } from "../../components/ui/tabs";
57
+ import { Textarea } from "../../components/ui/textarea";
53
58
 
54
59
  const PROVIDERS = [
55
60
  "google",
@@ -17,7 +17,7 @@ import {
17
17
  import { useEffect, useState, type ReactNode } from "react";
18
18
  import { toast } from "sonner";
19
19
 
20
- import { DispatchShell } from "@/components/dispatch-shell";
20
+ import { DispatchShell } from "../../components/dispatch-shell";
21
21
  import {
22
22
  AlertDialog,
23
23
  AlertDialogAction,
@@ -28,9 +28,9 @@ import {
28
28
  AlertDialogHeader,
29
29
  AlertDialogTitle,
30
30
  AlertDialogTrigger,
31
- } from "@/components/ui/alert-dialog";
32
- import { Badge } from "@/components/ui/badge";
33
- import { Button } from "@/components/ui/button";
31
+ } from "../../components/ui/alert-dialog";
32
+ import { Badge } from "../../components/ui/badge";
33
+ import { Button } from "../../components/ui/button";
34
34
  import {
35
35
  Dialog,
36
36
  DialogContent,
@@ -39,23 +39,28 @@ import {
39
39
  DialogHeader,
40
40
  DialogTitle,
41
41
  DialogTrigger,
42
- } from "@/components/ui/dialog";
43
- import { Input } from "@/components/ui/input";
44
- import { Label } from "@/components/ui/label";
42
+ } from "../../components/ui/dialog";
43
+ import { Input } from "../../components/ui/input";
44
+ import { Label } from "../../components/ui/label";
45
45
  import {
46
46
  Select,
47
47
  SelectContent,
48
48
  SelectItem,
49
49
  SelectTrigger,
50
50
  SelectValue,
51
- } from "@/components/ui/select";
52
- import { Skeleton } from "@/components/ui/skeleton";
53
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
54
- import { Textarea } from "@/components/ui/textarea";
51
+ } from "../../components/ui/select";
52
+ import { Skeleton } from "../../components/ui/skeleton";
53
+ import {
54
+ Tabs,
55
+ TabsContent,
56
+ TabsList,
57
+ TabsTrigger,
58
+ } from "../../components/ui/tabs";
59
+ import { Textarea } from "../../components/ui/textarea";
55
60
  import {
56
61
  ImpactPreview,
57
62
  workspaceResourceMutationMessage,
58
- } from "@/components/workspace-resource-impact-preview";
63
+ } from "../../components/workspace-resource-impact-preview";
59
64
 
60
65
  export function meta() {
61
66
  return [{ title: "Workspace Resources — Dispatch" }];
@@ -26,6 +26,7 @@ const DISPATCH_PAGE_PATHS = new Set([
26
26
  "/destinations",
27
27
  "/identities",
28
28
  "/approvals",
29
+ "/automations",
29
30
  "/audit",
30
31
  "/team",
31
32
  ]);
@@ -0,0 +1,102 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+
3
+ const mocks = vi.hoisted(() => ({
4
+ detectEngineFromEnv: vi.fn(() => null),
5
+ detectEngineFromUserSecrets: vi.fn(async () => null),
6
+ execute: vi.fn(),
7
+ getSetting: vi.fn(async () => null),
8
+ getUsageSummary: vi.fn(),
9
+ listWorkspaceApps: vi.fn(),
10
+ registerBuiltinEngines: vi.fn(),
11
+ }));
12
+
13
+ vi.mock("@agent-native/core/agent/engine", () => ({
14
+ detectEngineFromEnv: (...args: any[]) => mocks.detectEngineFromEnv(...args),
15
+ detectEngineFromUserSecrets: (...args: any[]) =>
16
+ mocks.detectEngineFromUserSecrets(...args),
17
+ getAgentEngineEntry: vi.fn(() => null),
18
+ isAgentEngineSettingConfigured: vi.fn(() => false),
19
+ isStoredEngineUsable: vi.fn(() => false),
20
+ registerBuiltinEngines: () => mocks.registerBuiltinEngines(),
21
+ }));
22
+
23
+ vi.mock("@agent-native/core/db", () => ({
24
+ getDbExec: () => ({
25
+ execute: (...args: any[]) => mocks.execute(...args),
26
+ }),
27
+ }));
28
+
29
+ vi.mock("@agent-native/core/settings", () => ({
30
+ getSetting: (...args: any[]) => mocks.getSetting(...args),
31
+ }));
32
+
33
+ vi.mock("@agent-native/core/usage", () => ({
34
+ getUsageSummary: (...args: any[]) => mocks.getUsageSummary(...args),
35
+ usageBillingForEngine: () => ({
36
+ unit: "usd",
37
+ label: "Estimated spend",
38
+ shortLabel: "Cost",
39
+ source: "estimated-provider-cost",
40
+ }),
41
+ }));
42
+
43
+ vi.mock("./app-creation-store.js", () => ({
44
+ listWorkspaceApps: (...args: any[]) => mocks.listWorkspaceApps(...args),
45
+ }));
46
+
47
+ vi.mock("./dispatch-store.js", () => ({
48
+ currentOrgId: () => null,
49
+ currentOwnerEmail: () => "owner@example.test",
50
+ }));
51
+
52
+ const { listDispatchUsageMetrics } = await import("./usage-metrics-store.js");
53
+
54
+ afterEach(() => {
55
+ vi.clearAllMocks();
56
+ });
57
+
58
+ describe("listDispatchUsageMetrics", () => {
59
+ it("returns empty metrics when usage storage bootstrap and reads fail", async () => {
60
+ mocks.getUsageSummary.mockRejectedValue(new Error("database is locked"));
61
+ mocks.execute.mockRejectedValue(new Error("no such table: token_usage"));
62
+ mocks.listWorkspaceApps.mockResolvedValue([
63
+ {
64
+ id: "dispatch",
65
+ name: "Dispatch",
66
+ path: "/dispatch",
67
+ status: "ready",
68
+ isDispatch: true,
69
+ },
70
+ ]);
71
+
72
+ const metrics = await listDispatchUsageMetrics({ sinceDays: 30 });
73
+
74
+ expect(mocks.getUsageSummary).toHaveBeenCalledWith({
75
+ ownerEmail: "__dispatch_metrics_init__",
76
+ sinceMs: expect.any(Number),
77
+ });
78
+ expect(metrics.access).toEqual({
79
+ viewerEmail: "owner@example.test",
80
+ orgId: null,
81
+ role: null,
82
+ scope: "solo",
83
+ totalUsers: 0,
84
+ });
85
+ expect(metrics.totals).toEqual({
86
+ costCents: 0,
87
+ calls: 0,
88
+ chatCalls: 0,
89
+ inputTokens: 0,
90
+ outputTokens: 0,
91
+ cacheReadTokens: 0,
92
+ cacheWriteTokens: 0,
93
+ activeUsers: 0,
94
+ chatThreads: 0,
95
+ chatMessages: 0,
96
+ workspaceApps: 0,
97
+ });
98
+ expect(metrics.byUser).toEqual([]);
99
+ expect(metrics.recent).toEqual([]);
100
+ expect(metrics.appAccess).toHaveLength(1);
101
+ });
102
+ });
@@ -213,6 +213,17 @@ async function queryRows<T extends Record<string, unknown>>(
213
213
  }
214
214
  }
215
215
 
216
+ async function initializeUsageMetricsTable(sinceMs: number): Promise<void> {
217
+ try {
218
+ // Initializes token_usage on fresh deployments before the read-only
219
+ // aggregate queries below. The fake owner avoids changing visible data.
220
+ await getUsageSummary({ ownerEmail: "__dispatch_metrics_init__", sinceMs });
221
+ } catch {
222
+ // Metrics should still render an empty state if usage storage is locked,
223
+ // stale, or unavailable; each aggregate read below is already best-effort.
224
+ }
225
+ }
226
+
216
227
  async function getViewerOrgRole(
217
228
  orgId: string | null,
218
229
  email: string,
@@ -397,9 +408,7 @@ export async function listDispatchUsageMetrics(input: {
397
408
  const sinceMs = Date.now() - sinceDays * DAY_MS;
398
409
  const billing = usageBillingForEngine(await detectUsageEngineName());
399
410
 
400
- // Initializes token_usage on fresh deployments before the read-only
401
- // aggregate queries below. The fake owner avoids changing visible data.
402
- await getUsageSummary({ ownerEmail: "__dispatch_metrics_init__", sinceMs });
411
+ await initializeUsageMetricsTable(sinceMs);
403
412
 
404
413
  const rawMembers = orgId
405
414
  ? await listOrgMembers(orgId)