@agent-native/dispatch 0.15.10 → 0.15.11

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.
@@ -14,7 +14,7 @@ import { useT } from "@agent-native/core/client/i18n";
14
14
  import { InvitationBanner, OrgSwitcher } from "@agent-native/core/client/org";
15
15
  import { FeedbackButton } from "@agent-native/core/client/ui";
16
16
  import {
17
- ChatHistoryList,
17
+ ChatHistoryRail,
18
18
  type ChatHistoryItem,
19
19
  } from "@agent-native/toolkit/chat-history";
20
20
  import {
@@ -29,7 +29,6 @@ import {
29
29
  IconLayersSubtract,
30
30
  IconMessageQuestion,
31
31
  IconMessages,
32
- IconPlus,
33
32
  IconPlugConnected,
34
33
  IconBroadcast,
35
34
  IconFingerprint,
@@ -355,7 +354,7 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
355
354
  (thread) => thread.messageCount > 0 || thread.id === activeThreadId,
356
355
  )
357
356
  .sort((a, b) => threadUpdatedAt(b) - threadUpdatedAt(a))
358
- .slice(0, 8),
357
+ .slice(0, 15),
359
358
  [activeThreadId, threads],
360
359
  );
361
360
  const localPathname = localDispatchPath(location.pathname);
@@ -430,36 +429,31 @@ function DispatchChatsSection({ onNavigate }: { onNavigate?: () => void }) {
430
429
  <Skeleton className="h-3 w-3/4 rounded" />
431
430
  </div>
432
431
  ))}
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
- )}
455
- <button
456
- type="button"
457
- onClick={() => void handleNewChat()}
458
- className="flex w-full cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 text-xs text-muted-foreground/60 transition-colors hover:bg-sidebar-accent/50 hover:text-foreground"
459
- >
460
- <IconPlus className="size-3 shrink-0" />
461
- <span className="truncate">{t("dispatch.sidebar.newChat")}</span>
462
- </button>
432
+ <ChatHistoryRail
433
+ items={chatItems}
434
+ activeId={displayedActiveThreadId}
435
+ onSelect={(threadId) => openThread(threadId)}
436
+ onNewChat={() => void handleNewChat()}
437
+ railLabels={{
438
+ newChat: t("dispatch.sidebar.newChat"),
439
+ showMore: t("dispatch.sidebar.chats"),
440
+ showLess: t("dispatch.sidebar.chats"),
441
+ }}
442
+ renameMaxLength={160}
443
+ onRename={(threadId, title) => void renameThread(threadId, title)}
444
+ labels={{
445
+ options: (item) =>
446
+ t("dispatch.sidebar.chatOptions", {
447
+ title: item.titleText ?? "",
448
+ }),
449
+ renameInput: (item) =>
450
+ t("dispatch.sidebar.renameThread", {
451
+ title: item.titleText ?? "",
452
+ }),
453
+ rename: t("dispatch.sidebar.renameChat"),
454
+ }}
455
+ className="min-w-0"
456
+ />
463
457
  </div>
464
458
  );
465
459
  }
@@ -723,7 +717,7 @@ export function NavContent({
723
717
  <OrgSwitcher />
724
718
  </div>
725
719
 
726
- <div className="px-3 py-2">
720
+ <div className="px-3 py-2 empty:hidden">
727
721
  <FeedbackButton />
728
722
  </div>
729
723
  </div>
@@ -61,7 +61,7 @@ describe("WorkspaceAppCard", () => {
61
61
 
62
62
  const actions = [
63
63
  container.querySelector<HTMLButtonElement>(
64
- 'button[aria-label="View context resources for Analytics"]',
64
+ 'button[aria-label="View agent resources for Analytics"]',
65
65
  ),
66
66
  container.querySelector<HTMLButtonElement>(
67
67
  'button[aria-label="Manage keys for Analytics"]',
@@ -82,6 +82,38 @@ describe("WorkspaceAppCard", () => {
82
82
  }
83
83
  });
84
84
 
85
+ it("labels per-app context as agent resources while preserving workspace scope", async () => {
86
+ await act(async () => {
87
+ root.render(
88
+ <TooltipProvider>
89
+ <WorkspaceAppCard
90
+ app={{
91
+ id: "analytics",
92
+ name: "Analytics",
93
+ path: "/analytics",
94
+ description: "Explore product and growth performance.",
95
+ status: "ready",
96
+ }}
97
+ />
98
+ </TooltipProvider>,
99
+ );
100
+ });
101
+
102
+ const resourcesButton = container.querySelector<HTMLButtonElement>(
103
+ 'button[aria-label="View agent resources for Analytics"]',
104
+ );
105
+
106
+ await act(async () => resourcesButton?.click());
107
+
108
+ expect(document.body.textContent).toContain("Analytics agent resources");
109
+ expect(document.body.textContent).toContain(
110
+ "Workspace-scope agent resources are inherited at runtime.",
111
+ );
112
+ expect(document.body.textContent).toContain(
113
+ "All-app agent resources live once at workspace scope",
114
+ );
115
+ });
116
+
85
117
  it("opens pending Builder apps in a new tab", async () => {
86
118
  await act(async () => {
87
119
  root.render(
@@ -323,7 +323,7 @@ function AppResourcesDialog({ app }: { app: WorkspaceAppSummary }) {
323
323
  type="button"
324
324
  variant="ghost"
325
325
  size="sm"
326
- aria-label={`View context resources for ${app.name}`}
326
+ aria-label={`View agent resources for ${app.name}`}
327
327
  className={APP_CARD_ACTION_CLASS}
328
328
  onClick={(e) => e.stopPropagation()}
329
329
  >
@@ -331,20 +331,21 @@ function AppResourcesDialog({ app }: { app: WorkspaceAppSummary }) {
331
331
  </Button>
332
332
  </DialogTrigger>
333
333
  </TooltipTrigger>
334
- <TooltipContent>View context</TooltipContent>
334
+ <TooltipContent>View agent resources</TooltipContent>
335
335
  </Tooltip>
336
336
  <DialogContent className="max-w-2xl">
337
337
  <DialogHeader>
338
- <DialogTitle>{app.name} workspace resources</DialogTitle>
338
+ <DialogTitle>{app.name} agent resources</DialogTitle>
339
339
  <DialogDescription>
340
- Workspace-level resources are inherited at runtime. App shared and
341
- personal resources can override them locally.
340
+ Workspace-scope agent resources are inherited at runtime. App shared
341
+ and personal resources can override them locally.
342
342
  </DialogDescription>
343
343
  </DialogHeader>
344
344
  <div className="space-y-4">
345
345
  <div className="rounded-lg border bg-muted/30 px-3 py-2 text-xs leading-relaxed text-muted-foreground">
346
- All-app resources live once at workspace scope and are read by each
347
- app agent when it builds context. Nothing is copied into this app.
346
+ All-app agent resources live once at workspace scope and are read by
347
+ each app agent when it builds context. Nothing is copied into this
348
+ app.
348
349
  </div>
349
350
 
350
351
  <div className="flex flex-wrap items-center gap-2">
@@ -72,7 +72,7 @@ export default function ApprovalsRoute() {
72
72
  </div>
73
73
  <div className="mt-1 text-xs text-muted-foreground">
74
74
  {hasOrg
75
- ? "Applies to saved destinations, shared dream proposals, All-app workspace resources, and dispatch settings."
75
+ ? "Applies to saved destinations, shared dream proposals, All-app agent resources, and dispatch settings."
76
76
  : "Requires a team workspace. Set one up on the Team page."}
77
77
  </div>
78
78
  </div>
@@ -67,7 +67,7 @@ import {
67
67
  } from "../../components/workspace-resource-impact-preview";
68
68
 
69
69
  export function meta() {
70
- return [{ title: "Workspace Resources — Dispatch" }];
70
+ return [{ title: "Agent Resources — Dispatch" }];
71
71
  }
72
72
 
73
73
  const KIND_CONFIG = {
@@ -252,10 +252,10 @@ function EditResourceDialog({
252
252
  </DialogTrigger>
253
253
  <DialogContent className="max-w-2xl">
254
254
  <DialogHeader>
255
- <DialogTitle>Edit workspace resource</DialogTitle>
255
+ <DialogTitle>Edit agent resource</DialogTitle>
256
256
  <DialogDescription>
257
- Updates apply immediately anywhere this workspace resource is
258
- inherited. App shared or personal resources can override it locally.
257
+ Updates apply immediately anywhere this agent resource is inherited.
258
+ App shared or personal resources can override it locally.
259
259
  </DialogDescription>
260
260
  </DialogHeader>
261
261
  <div className="space-y-4 py-2">
@@ -364,10 +364,11 @@ function AddResourceDialog() {
364
364
  </DialogTrigger>
365
365
  <DialogContent className="max-w-2xl">
366
366
  <DialogHeader>
367
- <DialogTitle>Add workspace resource</DialogTitle>
367
+ <DialogTitle>Add agent resource</DialogTitle>
368
368
  <DialogDescription>
369
- Create a skill, instruction, agent profile, reference resource, or
370
- MCP server that can be shared across workspace apps.
369
+ Create an agent resource—a skill, instruction, agent profile,
370
+ reference resource, or MCP serverthat can be shared across
371
+ workspace apps.
371
372
  </DialogDescription>
372
373
  </DialogHeader>
373
374
  <div className="space-y-4 py-2">
@@ -1088,8 +1089,8 @@ export default function WorkspaceRoute() {
1088
1089
 
1089
1090
  return (
1090
1091
  <DispatchShell
1091
- title="Workspace Resources"
1092
- description="Manage inherited workspace skills, guardrail instructions, agent profiles, reference resources, and MCP servers. All-app resources are available to every app without syncing."
1092
+ title="Agent Resources"
1093
+ description="Manage inherited skills, guardrail instructions, agent profiles, reference resources, and MCP servers. All-app resources are available to every app without syncing."
1093
1094
  >
1094
1095
  {resourcesQuery.isError || grantsQuery.isError ? (
1095
1096
  <ActionQueryError
@@ -1141,21 +1142,21 @@ export default function WorkspaceRoute() {
1141
1142
  <TabsContent value="skills" className="mt-4">
1142
1143
  <ResourceList
1143
1144
  items={skills}
1144
- emptyText="No workspace skills yet. Add a skill to share agent guidance across apps."
1145
+ emptyText="No skills yet. Add a skill to share agent guidance across apps."
1145
1146
  />
1146
1147
  </TabsContent>
1147
1148
 
1148
1149
  <TabsContent value="instructions" className="mt-4">
1149
1150
  <ResourceList
1150
1151
  items={instructions}
1151
- emptyText="No workspace instructions yet. Add instructions to set behavioral rules across apps."
1152
+ emptyText="No instructions yet. Add instructions to set behavioral rules across apps."
1152
1153
  />
1153
1154
  </TabsContent>
1154
1155
 
1155
1156
  <TabsContent value="agents" className="mt-4">
1156
1157
  <ResourceList
1157
1158
  items={agents}
1158
- emptyText="No workspace agents yet. Add a reusable agent profile to share specialist agents across apps."
1159
+ emptyText="No agent profiles yet. Add a reusable profile to share specialist agents across apps."
1159
1160
  />
1160
1161
  </TabsContent>
1161
1162
 
@@ -1169,7 +1170,7 @@ export default function WorkspaceRoute() {
1169
1170
  <TabsContent value="mcp" className="mt-4">
1170
1171
  <ResourceList
1171
1172
  items={mcpServers}
1172
- emptyText="No workspace MCP servers yet. Add an HTTP MCP server to share external tools across apps."
1173
+ emptyText="No MCP servers yet. Add an HTTP MCP server to share external tools across apps."
1173
1174
  />
1174
1175
  </TabsContent>
1175
1176
  </Tabs>