@agent-native/dispatch 0.24.6 → 0.25.1

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 (151) hide show
  1. package/README.md +12 -1
  2. package/dist/actions/connect-external-agent.d.ts +18 -0
  3. package/dist/actions/connect-external-agent.d.ts.map +1 -0
  4. package/dist/actions/connect-external-agent.js +68 -0
  5. package/dist/actions/connect-external-agent.js.map +1 -0
  6. package/dist/actions/create-workspace-resource.d.ts +14 -14
  7. package/dist/actions/create-workspace-resource.js +9 -2
  8. package/dist/actions/create-workspace-resource.js.map +1 -1
  9. package/dist/actions/create_workspace_app_embed_session.d.ts +13 -0
  10. package/dist/actions/create_workspace_app_embed_session.d.ts.map +1 -0
  11. package/dist/actions/create_workspace_app_embed_session.js +30 -0
  12. package/dist/actions/create_workspace_app_embed_session.js.map +1 -0
  13. package/dist/actions/import-agent-pack.d.ts +96 -0
  14. package/dist/actions/import-agent-pack.d.ts.map +1 -0
  15. package/dist/actions/import-agent-pack.js +116 -0
  16. package/dist/actions/import-agent-pack.js.map +1 -0
  17. package/dist/actions/import-agent.d.ts +60 -0
  18. package/dist/actions/import-agent.d.ts.map +1 -0
  19. package/dist/actions/import-agent.js +82 -0
  20. package/dist/actions/import-agent.js.map +1 -0
  21. package/dist/actions/index.d.ts.map +1 -1
  22. package/dist/actions/index.js +10 -0
  23. package/dist/actions/index.js.map +1 -1
  24. package/dist/actions/list-agent-pack.d.ts +36 -0
  25. package/dist/actions/list-agent-pack.d.ts.map +1 -0
  26. package/dist/actions/list-agent-pack.js +32 -0
  27. package/dist/actions/list-agent-pack.js.map +1 -0
  28. package/dist/actions/list-workspace-resource-options.d.ts +1 -1
  29. package/dist/actions/list-workspace-resource-options.js +8 -1
  30. package/dist/actions/list-workspace-resource-options.js.map +1 -1
  31. package/dist/actions/list-workspace-resources.d.ts +1 -1
  32. package/dist/actions/list-workspace-resources.js +8 -1
  33. package/dist/actions/list-workspace-resources.js.map +1 -1
  34. package/dist/actions/navigate.js +1 -1
  35. package/dist/actions/navigate.js.map +1 -1
  36. package/dist/actions/provider-api-register.d.ts +10 -10
  37. package/dist/actions/update-workspace-resource.d.ts +13 -13
  38. package/dist/actions/view-screen.js +18 -1
  39. package/dist/actions/view-screen.js.map +1 -1
  40. package/dist/components/index.d.ts +1 -0
  41. package/dist/components/index.d.ts.map +1 -1
  42. package/dist/components/index.js +1 -0
  43. package/dist/components/index.js.map +1 -1
  44. package/dist/components/layout/Layout.d.ts +1 -8
  45. package/dist/components/layout/Layout.d.ts.map +1 -1
  46. package/dist/components/layout/Layout.js +33 -106
  47. package/dist/components/layout/Layout.js.map +1 -1
  48. package/dist/components/simple-agents-panel.d.ts +9 -0
  49. package/dist/components/simple-agents-panel.d.ts.map +1 -0
  50. package/dist/components/simple-agents-panel.js +405 -0
  51. package/dist/components/simple-agents-panel.js.map +1 -0
  52. package/dist/components/workspace-app-host.d.ts +29 -0
  53. package/dist/components/workspace-app-host.d.ts.map +1 -0
  54. package/dist/components/workspace-app-host.js +145 -0
  55. package/dist/components/workspace-app-host.js.map +1 -0
  56. package/dist/db/migrations.d.ts +2 -4
  57. package/dist/db/migrations.d.ts.map +1 -1
  58. package/dist/db/migrations.js +25 -0
  59. package/dist/db/migrations.js.map +1 -1
  60. package/dist/db/schema.js +1 -1
  61. package/dist/db/schema.js.map +1 -1
  62. package/dist/hooks/use-navigation-state.d.ts +1 -0
  63. package/dist/hooks/use-navigation-state.d.ts.map +1 -1
  64. package/dist/hooks/use-navigation-state.js +10 -0
  65. package/dist/hooks/use-navigation-state.js.map +1 -1
  66. package/dist/lib/agent-pack.d.ts +31 -0
  67. package/dist/lib/agent-pack.d.ts.map +1 -0
  68. package/dist/lib/agent-pack.js +149 -0
  69. package/dist/lib/agent-pack.js.map +1 -0
  70. package/dist/lib/simple-agent-profile.d.ts +36 -0
  71. package/dist/lib/simple-agent-profile.d.ts.map +1 -0
  72. package/dist/lib/simple-agent-profile.js +183 -0
  73. package/dist/lib/simple-agent-profile.js.map +1 -0
  74. package/dist/routes/pages/agents.d.ts.map +1 -1
  75. package/dist/routes/pages/agents.js +11 -1
  76. package/dist/routes/pages/agents.js.map +1 -1
  77. package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
  78. package/dist/routes/pages/apps.$appId.js +4 -95
  79. package/dist/routes/pages/apps.$appId.js.map +1 -1
  80. package/dist/routes/pages/chat.d.ts.map +1 -1
  81. package/dist/routes/pages/chat.js +62 -10
  82. package/dist/routes/pages/chat.js.map +1 -1
  83. package/dist/server/lib/agent-pack-store.d.ts +24 -0
  84. package/dist/server/lib/agent-pack-store.d.ts.map +1 -0
  85. package/dist/server/lib/agent-pack-store.js +22 -0
  86. package/dist/server/lib/agent-pack-store.js.map +1 -0
  87. package/dist/server/lib/dispatch-store.d.ts.map +1 -1
  88. package/dist/server/lib/dispatch-store.js +4 -0
  89. package/dist/server/lib/dispatch-store.js.map +1 -1
  90. package/dist/server/lib/mcp-gateway.d.ts +11 -0
  91. package/dist/server/lib/mcp-gateway.d.ts.map +1 -1
  92. package/dist/server/lib/mcp-gateway.js +155 -9
  93. package/dist/server/lib/mcp-gateway.js.map +1 -1
  94. package/dist/server/lib/workspace-resources-store.d.ts +15 -1
  95. package/dist/server/lib/workspace-resources-store.d.ts.map +1 -1
  96. package/dist/server/lib/workspace-resources-store.js +11 -2
  97. package/dist/server/lib/workspace-resources-store.js.map +1 -1
  98. package/dist/server/plugins/agent-chat.js +13 -0
  99. package/dist/server/plugins/agent-chat.js.map +1 -1
  100. package/dist/shared/feature-flags.d.ts +7 -0
  101. package/dist/shared/feature-flags.d.ts.map +1 -0
  102. package/dist/shared/feature-flags.js +12 -0
  103. package/dist/shared/feature-flags.js.map +1 -0
  104. package/dist/shared/workspace-sso.d.ts +36 -0
  105. package/dist/shared/workspace-sso.d.ts.map +1 -0
  106. package/dist/shared/workspace-sso.js +99 -0
  107. package/dist/shared/workspace-sso.js.map +1 -0
  108. package/package.json +5 -3
  109. package/src/actions/connect-external-agent.ts +92 -0
  110. package/src/actions/create-workspace-resource.ts +9 -2
  111. package/src/actions/create_workspace_app_embed_session.ts +32 -0
  112. package/src/actions/import-agent-pack.ts +146 -0
  113. package/src/actions/import-agent.ts +102 -0
  114. package/src/actions/index.spec.ts +13 -0
  115. package/src/actions/index.ts +10 -0
  116. package/src/actions/list-agent-pack.ts +43 -0
  117. package/src/actions/list-workspace-resource-options.ts +8 -1
  118. package/src/actions/list-workspace-resources.ts +8 -1
  119. package/src/actions/navigate.ts +1 -1
  120. package/src/actions/view-screen.spec.ts +29 -1
  121. package/src/actions/view-screen.ts +19 -1
  122. package/src/components/app-icon.spec.tsx +10 -0
  123. package/src/components/index.ts +1 -0
  124. package/src/components/layout/Layout.spec.tsx +2 -0
  125. package/src/components/layout/Layout.tsx +59 -171
  126. package/src/components/simple-agents-panel.spec.tsx +73 -0
  127. package/src/components/simple-agents-panel.tsx +1226 -0
  128. package/src/components/workspace-app-host.spec.tsx +204 -0
  129. package/src/components/workspace-app-host.tsx +359 -0
  130. package/src/db/migrations.spec.ts +5 -1
  131. package/src/db/migrations.ts +28 -1
  132. package/src/db/schema.ts +1 -1
  133. package/src/hooks/use-navigation-state.spec.ts +25 -0
  134. package/src/hooks/use-navigation-state.ts +11 -0
  135. package/src/lib/agent-pack.spec.ts +47 -0
  136. package/src/lib/agent-pack.ts +226 -0
  137. package/src/lib/simple-agent-profile.spec.ts +77 -0
  138. package/src/lib/simple-agent-profile.ts +247 -0
  139. package/src/routes/index.spec.ts +1 -0
  140. package/src/routes/pages/agents.tsx +21 -1
  141. package/src/routes/pages/apps.$appId.tsx +3 -240
  142. package/src/routes/pages/chat.spec.tsx +62 -0
  143. package/src/routes/pages/chat.tsx +117 -9
  144. package/src/server/lib/agent-pack-store.ts +35 -0
  145. package/src/server/lib/dispatch-store.ts +8 -0
  146. package/src/server/lib/mcp-gateway.spec.ts +141 -0
  147. package/src/server/lib/mcp-gateway.ts +227 -15
  148. package/src/server/lib/workspace-resources-store.ts +9 -2
  149. package/src/server/plugins/agent-chat.ts +13 -0
  150. package/src/shared/feature-flags.ts +13 -0
  151. package/src/shared/workspace-sso.ts +118 -0
@@ -0,0 +1,9 @@
1
+ export declare function isPendingWorkspaceResourceApproval(result: unknown): boolean;
2
+ export declare function handleAgentPackMutationSuccess(result: unknown, options: {
3
+ appliedMessage: string;
4
+ approvalMessage: string;
5
+ onApplied: () => void;
6
+ notify?: (message: string) => void;
7
+ }): void;
8
+ export declare function SimpleAgentsPanel(): import("node_modules/@types/react/index.js").JSX.Element;
9
+ //# sourceMappingURL=simple-agents-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-agents-panel.d.ts","sourceRoot":"","sources":["../../src/components/simple-agents-panel.tsx"],"names":[],"mappings":"AAuGA,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,OAAO,WAQjE;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,OAAO,EACf,OAAO,EAAE;IACP,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,QASF;AAygCD,wBAAgB,iBAAiB,6DA+DhC"}
@@ -0,0 +1,405 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { navigateWithAgentChatViewTransition, sendToAgentChat, } from "@agent-native/core/client/agent-chat";
3
+ import { useActionMutation, useActionQuery, } from "@agent-native/core/client/hooks";
4
+ import { parseCustomAgentProfile } from "@agent-native/core/resources/metadata";
5
+ import { IconAdjustmentsHorizontal, IconChevronDown, IconEdit, IconFileImport, IconFolder, IconLayoutGrid, IconMessageCircle, IconPlugConnected, IconPlus, IconTrash, IconUpload, IconUser, } from "@tabler/icons-react";
6
+ import { useEffect, useRef, useState, } from "react";
7
+ import { useNavigate } from "react-router";
8
+ import { toast } from "sonner";
9
+ import { buildSimpleAgentContent, slugifyAgentName, } from "../lib/simple-agent-profile.js";
10
+ import { ActionQueryError } from "./action-query-error.js";
11
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "./ui/alert-dialog.js";
12
+ import { Badge } from "./ui/badge.js";
13
+ import { Button } from "./ui/button.js";
14
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "./ui/collapsible.js";
15
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "./ui/dialog.js";
16
+ import { Input } from "./ui/input.js";
17
+ import { Label } from "./ui/label.js";
18
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "./ui/select.js";
19
+ import { Skeleton } from "./ui/skeleton.js";
20
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs.js";
21
+ import { Textarea } from "./ui/textarea.js";
22
+ export function isPendingWorkspaceResourceApproval(result) {
23
+ if (!result || typeof result !== "object")
24
+ return false;
25
+ const mutation = result;
26
+ return (mutation.status === "pending" &&
27
+ typeof mutation.changeType === "string" &&
28
+ mutation.changeType.startsWith("workspace-resource."));
29
+ }
30
+ export function handleAgentPackMutationSuccess(result, options) {
31
+ const notify = options.notify || ((message) => toast.success(message));
32
+ if (isPendingWorkspaceResourceApproval(result)) {
33
+ notify(options.approvalMessage);
34
+ return;
35
+ }
36
+ notify(options.appliedMessage);
37
+ options.onApplied();
38
+ }
39
+ function profileFields(resource) {
40
+ if (!resource) {
41
+ return {
42
+ name: "",
43
+ description: "",
44
+ instructions: "# Role\n\nDescribe how this agent should work.\n",
45
+ model: "inherit",
46
+ tools: "inherit",
47
+ scope: "all",
48
+ };
49
+ }
50
+ const profile = parseCustomAgentProfile(resource.content, resource.path);
51
+ return {
52
+ name: profile?.name || resource.name,
53
+ description: profile?.description || resource.description || "",
54
+ instructions: profile?.instructions || resource.content,
55
+ model: profile?.model || "inherit",
56
+ tools: profile?.tools || "inherit",
57
+ scope: resource.scope,
58
+ };
59
+ }
60
+ function AgentEditorDialog({ resource, trigger, onSaved }) {
61
+ const isEditing = Boolean(resource);
62
+ const [open, setOpen] = useState(false);
63
+ const [name, setName] = useState("");
64
+ const [description, setDescription] = useState("");
65
+ const [instructions, setInstructions] = useState("");
66
+ const [model, setModel] = useState("inherit");
67
+ const [tools, setTools] = useState("inherit");
68
+ const [scope, setScope] = useState("all");
69
+ const [advancedOpen, setAdvancedOpen] = useState(false);
70
+ useEffect(() => {
71
+ if (!open)
72
+ return;
73
+ const fields = profileFields(resource);
74
+ setName(fields.name);
75
+ setDescription(fields.description);
76
+ setInstructions(fields.instructions);
77
+ setModel(fields.model);
78
+ setTools(fields.tools);
79
+ setScope(fields.scope);
80
+ setAdvancedOpen(fields.model !== "inherit" || fields.tools !== "inherit");
81
+ }, [open, resource]);
82
+ const create = useActionMutation("create-workspace-resource", {
83
+ onSuccess: () => {
84
+ toast.success("Agent created");
85
+ setOpen(false);
86
+ onSaved?.();
87
+ },
88
+ onError: (error) => toast.error(error.message),
89
+ });
90
+ const update = useActionMutation("update-workspace-resource", {
91
+ onSuccess: () => {
92
+ toast.success("Agent updated");
93
+ setOpen(false);
94
+ onSaved?.();
95
+ },
96
+ onError: (error) => toast.error(error.message),
97
+ });
98
+ const pending = create.isPending || update.isPending;
99
+ const canSave = Boolean(name.trim() && instructions.trim() && !pending);
100
+ function save() {
101
+ const content = buildSimpleAgentContent({
102
+ name,
103
+ description,
104
+ model,
105
+ tools,
106
+ instructions,
107
+ });
108
+ if (resource) {
109
+ update.mutate({
110
+ id: resource.id,
111
+ name: name.trim(),
112
+ description: description.trim(),
113
+ content,
114
+ scope,
115
+ });
116
+ return;
117
+ }
118
+ create.mutate({
119
+ kind: "agent",
120
+ name: name.trim(),
121
+ description: description.trim() || undefined,
122
+ path: `agents/${slugifyAgentName(name)}.md`,
123
+ content,
124
+ scope,
125
+ });
126
+ }
127
+ return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: trigger || (_jsxs(Button, { children: [_jsx(IconPlus, { size: 16 }), "Create agent"] })) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: isEditing ? "Manage agent" : "Create agent" }), _jsx(DialogDescription, { className: "sr-only", children: isEditing
128
+ ? "Update this reusable agent profile."
129
+ : "Create a reusable agent profile." })] }), _jsxs("div", { className: "flex flex-col gap-4 py-2", children: [_jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "simple-agent-name", children: "Name" }), _jsx(Input, { id: "simple-agent-name", value: name, onChange: (event) => setName(event.target.value), placeholder: "User Research" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "simple-agent-scope", children: "Availability" }), _jsxs(Select, { value: scope, onValueChange: (value) => setScope(value), children: [_jsx(SelectTrigger, { id: "simple-agent-scope", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps" })] })] })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "simple-agent-description", children: "Description" }), _jsx(Input, { id: "simple-agent-description", value: description, onChange: (event) => setDescription(event.target.value), placeholder: "Synthesizes user research into clear insights" })] }), _jsxs(Collapsible, { open: advancedOpen, onOpenChange: setAdvancedOpen, children: [_jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "group -ml-2 gap-1.5 text-muted-foreground", children: [_jsx(IconAdjustmentsHorizontal, { size: 15 }), "Advanced", _jsx(IconChevronDown, { className: "transition-transform group-data-[state=open]:rotate-180", size: 15 })] }) }), _jsx(CollapsibleContent, { className: "pt-3", children: _jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "simple-agent-model", children: "Model" }), _jsx(Input, { id: "simple-agent-model", value: model, onChange: (event) => setModel(event.target.value), placeholder: "inherit" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "simple-agent-tools", children: "Tools" }), _jsx(Input, { id: "simple-agent-tools", value: tools, onChange: (event) => setTools(event.target.value), placeholder: "inherit" })] })] }) })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "simple-agent-instructions", children: "Instructions" }), _jsx(Textarea, { id: "simple-agent-instructions", value: instructions, onChange: (event) => setInstructions(event.target.value), rows: 12, className: "font-mono text-sm", placeholder: "# Role\\n\\nDescribe how this agent should work." })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: save, disabled: !canSave, children: pending
130
+ ? "Saving..."
131
+ : isEditing
132
+ ? "Save changes"
133
+ : "Create agent" }) })] })] }));
134
+ }
135
+ function AgentPackDialog({ resource, onChanged, trigger, }) {
136
+ const [open, setOpen] = useState(false);
137
+ const [selectedId, setSelectedId] = useState(resource.id);
138
+ const [content, setContent] = useState(resource.content);
139
+ const [addOpen, setAddOpen] = useState(false);
140
+ const [newPath, setNewPath] = useState("");
141
+ const [newKind, setNewKind] = useState("agent-file");
142
+ const [newContent, setNewContent] = useState("");
143
+ const query = useActionQuery("list-agent-pack", { agentId: resource.id }, { enabled: open });
144
+ const update = useActionMutation("update-workspace-resource", {
145
+ onSuccess: (result) => {
146
+ handleAgentPackMutationSuccess(result, {
147
+ appliedMessage: "Pack file updated",
148
+ approvalMessage: "Pack file update queued for approval",
149
+ onApplied: () => {
150
+ void query.refetch();
151
+ onChanged?.();
152
+ },
153
+ });
154
+ },
155
+ onError: (error) => toast.error(error.message),
156
+ });
157
+ const create = useActionMutation("create-workspace-resource", {
158
+ onSuccess: (result) => {
159
+ handleAgentPackMutationSuccess(result, {
160
+ appliedMessage: "Pack file added",
161
+ approvalMessage: "Pack file addition queued for approval",
162
+ onApplied: () => {
163
+ setAddOpen(false);
164
+ setNewPath("");
165
+ setNewContent("");
166
+ void query.refetch();
167
+ onChanged?.();
168
+ },
169
+ });
170
+ },
171
+ onError: (error) => toast.error(error.message),
172
+ });
173
+ const remove = useActionMutation("delete-workspace-resource", {
174
+ onSuccess: () => {
175
+ toast.success("Pack file removed");
176
+ setSelectedId(resource.id);
177
+ void query.refetch();
178
+ onChanged?.();
179
+ },
180
+ onError: (error) => toast.error(error.message),
181
+ });
182
+ const files = query.data
183
+ ? [{ ...query.data.profile, kind: "agent" }, ...query.data.files]
184
+ : [];
185
+ const selected = files.find((file) => file.id === selectedId) ?? files[0];
186
+ useEffect(() => {
187
+ if (!open)
188
+ return;
189
+ setSelectedId(resource.id);
190
+ }, [open, resource.id]);
191
+ useEffect(() => {
192
+ if (!selected)
193
+ return;
194
+ setSelectedId(selected.id);
195
+ setContent(selected.content);
196
+ }, [selected?.id, selected?.content]);
197
+ function addFile() {
198
+ const relativePath = newPath.trim().replaceAll("\\", "/");
199
+ if (!relativePath ||
200
+ relativePath.startsWith("/") ||
201
+ relativePath.includes("..") ||
202
+ relativePath.split("/").some((part) => !part || part === ".")) {
203
+ toast.error("Use a relative pack path without ..");
204
+ return;
205
+ }
206
+ const packPath = newKind === "skill" && !relativePath.startsWith("skills/")
207
+ ? `skills/${relativePath}`
208
+ : relativePath;
209
+ const name = packPath.split("/").pop() || packPath;
210
+ create.mutate({
211
+ kind: newKind,
212
+ name,
213
+ path: `${query.data?.root || `agents/${slugifyAgentName(resource.name)}`}/${packPath}`,
214
+ content: newContent,
215
+ scope: resource.scope,
216
+ });
217
+ }
218
+ return (_jsxs(Dialog, { open: open, onOpenChange: (nextOpen) => {
219
+ setOpen(nextOpen);
220
+ if (!nextOpen)
221
+ setAddOpen(false);
222
+ }, children: [_jsx(DialogTrigger, { asChild: true, children: trigger || (_jsxs(Button, { variant: "ghost", size: "sm", children: [_jsx(IconFolder, { size: 15 }), "Pack"] })) }), _jsxs(DialogContent, { className: "max-w-4xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Agent pack" }), _jsx(DialogDescription, { className: "sr-only", children: "Edit the profile, reference files, context, and skills that belong to this agent." })] }), _jsxs("div", { className: "grid min-h-0 gap-4 md:grid-cols-[220px_minmax(0,1fr)]", children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Files" }), _jsxs(Dialog, { open: addOpen, onOpenChange: setAddOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(IconPlus, { size: 14 }), "Add"] }) }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add pack file" }), _jsx(DialogDescription, { className: "sr-only", children: "Add a text reference or agent-owned skill to this pack." })] }), _jsxs("div", { className: "flex flex-col gap-4 py-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "agent-pack-file-path", children: "Path" }), _jsx(Input, { id: "agent-pack-file-path", value: newPath, onChange: (event) => setNewPath(event.target.value), placeholder: "context/brief.md" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "agent-pack-file-kind", children: "Type" }), _jsxs(Select, { value: newKind, onValueChange: (value) => setNewKind(value), children: [_jsx(SelectTrigger, { id: "agent-pack-file-kind", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "agent-file", children: "Reference file" }), _jsx(SelectItem, { value: "skill", children: "Skill" })] })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "agent-pack-file-content", children: "Content" }), _jsx(Textarea, { id: "agent-pack-file-content", value: newContent, onChange: (event) => setNewContent(event.target.value), rows: 8, className: "font-mono text-sm" })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: addFile, disabled: !newPath.trim() || create.isPending, children: create.isPending ? "Adding..." : "Add file" }) })] })] })] }), query.isLoading ? (_jsx(Skeleton, { className: "h-24 w-full" })) : (_jsx("div", { className: "flex flex-col gap-1", children: files.map((file) => (_jsx(Button, { type: "button", variant: selected?.id === file.id ? "secondary" : "ghost", className: "h-auto w-full justify-start px-2 py-2 text-left", onClick: () => setSelectedId(file.id), children: _jsx("span", { className: "min-w-0 truncate text-xs", children: file.path.replace(`${query.data?.root || ""}/`, "") }) }, file.id))) }))] }), _jsxs("div", { className: "flex min-w-0 flex-col gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium", children: selected?.path || "Select a file" }), selected && selected.kind !== "agent" ? (_jsx(Badge, { variant: "outline", children: selected.kind === "skill" ? "Skill" : "Reference" })) : null] }), _jsxs("div", { className: "flex items-center gap-1", children: [selected && selected.kind !== "agent" ? (_jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", children: [_jsx(IconTrash, { size: 15 }), "Remove"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Remove this pack file?" }), _jsx(AlertDialogDescription, { children: "The file will no longer be available to this agent." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { onClick: () => remove.mutate({ id: selected.id }), disabled: remove.isPending, children: "Remove" })] })] })] })) : null, _jsx(Button, { size: "sm", onClick: () => selected && update.mutate({ id: selected.id, content }), disabled: !selected ||
223
+ update.isPending ||
224
+ content === selected.content, children: update.isPending ? "Saving..." : "Save file" })] })] }), _jsx(Textarea, { value: content, onChange: (event) => setContent(event.target.value), disabled: !selected, rows: 18, className: "min-h-[360px] font-mono text-sm" })] })] })] })] }));
225
+ }
226
+ function ImportAgentDialog({ onImported }) {
227
+ const [open, setOpen] = useState(false);
228
+ const [mode, setMode] = useState("file");
229
+ const [source, setSource] = useState("");
230
+ const [fileName, setFileName] = useState("");
231
+ const [scope, setScope] = useState("all");
232
+ const [url, setUrl] = useState("");
233
+ const [endpointName, setEndpointName] = useState("");
234
+ const [endpointDescription, setEndpointDescription] = useState("");
235
+ const [packFiles, setPackFiles] = useState([]);
236
+ const [packName, setPackName] = useState("");
237
+ const [packWarnings, setPackWarnings] = useState([]);
238
+ const fileRef = useRef(null);
239
+ const folderRef = useRef(null);
240
+ const importAgent = useActionMutation("import-agent", {
241
+ onSuccess: (result) => {
242
+ toast.success(result.status === "unchanged"
243
+ ? "Agent already imported"
244
+ : "Agent imported");
245
+ if (result.warnings?.length) {
246
+ toast.info(result.warnings.join(" "));
247
+ }
248
+ setOpen(false);
249
+ onImported?.();
250
+ },
251
+ onError: (error) => toast.error(error.message),
252
+ });
253
+ const connect = useActionMutation("connect-external-agent", {
254
+ onSuccess: () => {
255
+ toast.success("Agent connected");
256
+ setOpen(false);
257
+ onImported?.();
258
+ },
259
+ onError: (error) => toast.error(error.message),
260
+ });
261
+ const importPack = useActionMutation("import-agent-pack", {
262
+ onSuccess: (result) => {
263
+ toast.success(result.status === "pending-approval"
264
+ ? "Pack sent for approval"
265
+ : result.status === "unchanged"
266
+ ? "Agent pack already imported"
267
+ : "Agent pack imported");
268
+ if (result.warnings?.length)
269
+ toast.info(result.warnings.join(" "));
270
+ setOpen(false);
271
+ onImported?.();
272
+ },
273
+ onError: (error) => toast.error(error.message),
274
+ });
275
+ useEffect(() => {
276
+ if (!folderRef.current)
277
+ return;
278
+ folderRef.current.setAttribute("webkitdirectory", "");
279
+ folderRef.current.setAttribute("directory", "");
280
+ }, [mode, open]);
281
+ function reset() {
282
+ setMode("file");
283
+ setSource("");
284
+ setFileName("");
285
+ setScope("all");
286
+ setUrl("");
287
+ setEndpointName("");
288
+ setEndpointDescription("");
289
+ setPackFiles([]);
290
+ setPackName("");
291
+ setPackWarnings([]);
292
+ }
293
+ async function handleFile(event) {
294
+ const file = event.target.files?.[0];
295
+ if (!file)
296
+ return;
297
+ setFileName(file.name);
298
+ setSource(await file.text());
299
+ }
300
+ async function handleFolder(event) {
301
+ const selectedFiles = Array.from(event.target.files ?? []);
302
+ if (selectedFiles.length === 0)
303
+ return;
304
+ const warnings = [];
305
+ const textExtensions = /\.(md|markdown|txt|json|yaml|yml|csv|html|xml|toml|ts|tsx|js|mjs|py|sh)$/i;
306
+ const pack = await Promise.all(selectedFiles.map(async (file) => {
307
+ const path = file.webkitRelativePath ||
308
+ file.name;
309
+ if (!textExtensions.test(path)) {
310
+ warnings.push(`Skipped non-text file: ${path}`);
311
+ return null;
312
+ }
313
+ return { path, content: await file.text() };
314
+ }));
315
+ const files = pack.filter((file) => Boolean(file));
316
+ setPackFiles(files);
317
+ setPackName(files[0]?.path.split("/")[0] || "Selected folder");
318
+ setPackWarnings(warnings);
319
+ }
320
+ return (_jsxs(Dialog, { open: open, onOpenChange: (nextOpen) => {
321
+ setOpen(nextOpen);
322
+ if (!nextOpen)
323
+ reset();
324
+ }, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", children: [_jsx(IconFileImport, { size: 16 }), "Import or connect"] }) }), _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Import an agent" }), _jsx(DialogDescription, { className: "sr-only", children: "Import a Claude or JSON agent definition, or connect an external agent endpoint." })] }), _jsxs(Tabs, { value: mode, onValueChange: (value) => setMode(value), children: [_jsxs(TabsList, { className: "w-full justify-start", children: [_jsx(TabsTrigger, { value: "file", children: "Agent file" }), _jsx(TabsTrigger, { value: "folder", children: "Agent folder" }), _jsx(TabsTrigger, { value: "endpoint", children: "Connect endpoint" })] }), _jsxs(TabsContent, { value: "file", className: "flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsxs(Button, { type: "button", variant: "outline", onClick: () => fileRef.current?.click(), children: [_jsx(IconUpload, { size: 16 }), "Choose file"] }), _jsx("input", { ref: fileRef, type: "file", accept: ".md,.markdown,.json,.txt", className: "hidden", onChange: (event) => void handleFile(event) }), _jsx("span", { className: "text-xs text-muted-foreground", children: fileName || "Claude .md or JSON agent definition" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "import-agent-source", children: "Definition" }), _jsx(Textarea, { id: "import-agent-source", value: source, onChange: (event) => setSource(event.target.value), rows: 12, className: "font-mono text-sm", placeholder: "Paste a Claude-style agent file or a JSON definition" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "import-agent-scope", children: "Availability" }), _jsxs(Select, { value: scope, onValueChange: (value) => setScope(value), children: [_jsx(SelectTrigger, { id: "import-agent-scope", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps" })] })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => importAgent.mutate({
325
+ source,
326
+ fileName: fileName || undefined,
327
+ scope,
328
+ }), disabled: !source.trim() || importAgent.isPending, children: importAgent.isPending ? "Importing..." : "Import agent" }) })] }), _jsxs(TabsContent, { value: "folder", className: "flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsxs(Button, { type: "button", variant: "outline", onClick: () => folderRef.current?.click(), children: [_jsx(IconFolder, { size: 16 }), "Choose folder"] }), _jsx("input", { ref: folderRef, type: "file", multiple: true, className: "hidden", onChange: (event) => void handleFolder(event) }), _jsx("span", { className: "text-xs text-muted-foreground", children: packName
329
+ ? `${packName} · ${packFiles.length} files`
330
+ : "Claude Project or Cowork-style folder" })] }), packWarnings.length > 0 ? (_jsx("div", { className: "rounded-lg border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-xs text-amber-800 dark:text-amber-200", children: packWarnings.join(" ") })) : null, _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "import-agent-pack-scope", children: "Availability" }), _jsxs(Select, { value: scope, onValueChange: (value) => setScope(value), children: [_jsx(SelectTrigger, { id: "import-agent-pack-scope", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "All apps" }), _jsx(SelectItem, { value: "selected", children: "Selected apps" })] })] })] }), _jsx(DialogFooter, { children: _jsx(Button, { onClick: () => importPack.mutate({ files: packFiles, scope }), disabled: packFiles.length === 0 || importPack.isPending, children: importPack.isPending ? "Importing..." : "Import agent pack" }) })] }), _jsxs(TabsContent, { value: "endpoint", className: "flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "external-agent-url", children: "Endpoint URL" }), _jsx(Input, { id: "external-agent-url", value: url, onChange: (event) => setUrl(event.target.value), placeholder: "https://agent.example.com" })] }), _jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "external-agent-name", children: "Name" }), _jsx(Input, { id: "external-agent-name", value: endpointName, onChange: (event) => setEndpointName(event.target.value), placeholder: "Research partner" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Availability" }), _jsx("div", { className: "flex h-10 items-center", children: _jsx(Badge, { variant: "secondary", children: "Workspace" }) })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "external-agent-description", children: "Description" }), _jsx(Input, { id: "external-agent-description", value: endpointDescription, onChange: (event) => setEndpointDescription(event.target.value), placeholder: "Optional" })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Dispatch stores the public endpoint only. Authenticate it after connecting." }), _jsx(DialogFooter, { children: _jsxs(Button, { onClick: () => connect.mutate({
331
+ url,
332
+ name: endpointName || undefined,
333
+ description: endpointDescription || undefined,
334
+ scope: "shared",
335
+ }), disabled: !url.trim() || connect.isPending, children: [_jsx(IconPlugConnected, { size: 16 }), connect.isPending ? "Connecting..." : "Connect agent"] }) })] })] })] })] }));
336
+ }
337
+ function DeleteAgentButton({ resource, onDeleted, }) {
338
+ const remove = useActionMutation("delete-workspace-resource", {
339
+ onSuccess: () => {
340
+ toast.success("Agent removed");
341
+ onDeleted?.();
342
+ },
343
+ onError: (error) => toast.error(error.message),
344
+ });
345
+ return (_jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": `Remove ${resource.name}`, children: _jsx(IconTrash, { size: 16 }) }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { children: ["Remove ", resource.name, "?"] }), _jsx(AlertDialogDescription, { children: "This removes the reusable profile from the workspace apps." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { onClick: () => remove.mutate({ id: resource.id }), disabled: remove.isPending, children: "Remove" })] })] })] }));
346
+ }
347
+ function AgentRow({ resource, onDeleted, onSaved, }) {
348
+ const navigate = useNavigate();
349
+ const packQuery = useActionQuery("list-agent-pack", { agentId: resource.id }, { enabled: false });
350
+ const promote = useActionMutation("start-workspace-app-creation", {
351
+ onSuccess: (result) => {
352
+ if (result.mode === "local-agent") {
353
+ sendToAgentChat({
354
+ message: result.prompt ?? result.message,
355
+ submit: true,
356
+ type: "code",
357
+ newTab: true,
358
+ reuseEmptyTab: true,
359
+ });
360
+ toast.success("Sent to the local agent");
361
+ return;
362
+ }
363
+ if (result.mode === "builder") {
364
+ toast.success("App build started", {
365
+ description: result.message,
366
+ action: result.url
367
+ ? {
368
+ label: "Open in Builder",
369
+ onClick: () => window.open(result.url, "_blank", "noopener,noreferrer"),
370
+ }
371
+ : undefined,
372
+ });
373
+ return;
374
+ }
375
+ toast.error(result.message);
376
+ },
377
+ onError: (error) => toast.error(error.message),
378
+ });
379
+ function chat() {
380
+ navigateWithAgentChatViewTransition(navigate, `/chat?agent=${encodeURIComponent(resource.path)}`);
381
+ }
382
+ async function buildApp() {
383
+ const pack = await packQuery.refetch();
384
+ if (pack.error || !pack.data) {
385
+ toast.error(pack.error?.message || "Could not load the agent pack");
386
+ return;
387
+ }
388
+ promote.mutate({
389
+ appId: slugifyAgentName(resource.name),
390
+ description: resource.description || undefined,
391
+ prompt: `Turn the "${resource.name}" workspace agent into a focused workspace app. Preserve its role and instructions, make the app its usable face, and keep the original reusable agent profile available.`,
392
+ resourceIds: [resource.id, ...pack.data.files.map((file) => file.id)],
393
+ });
394
+ }
395
+ return (_jsxs("div", { className: "flex items-start gap-3 rounded-xl border bg-card px-4 py-3", children: [_jsx("div", { className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: _jsx(IconUser, { size: 18 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: resource.name }), _jsx(Badge, { variant: "outline", children: resource.scope === "all" ? "All apps" : "Selected apps" })] }), resource.description ? (_jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: resource.description })) : null, _jsx("div", { className: "mt-1 font-mono text-[11px] text-muted-foreground/70", children: resource.path })] }), _jsxs("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-1", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: chat, "aria-label": `Chat with ${resource.name}`, children: [_jsx(IconMessageCircle, { size: 15 }), "Chat"] }), _jsxs(Button, { variant: "ghost", size: "sm", onClick: () => void buildApp(), disabled: promote.isPending, "aria-label": `Build an app for ${resource.name}`, children: [_jsx(IconLayoutGrid, { size: 15 }), promote.isPending ? "Starting..." : "Build app"] }), _jsx(AgentPackDialog, { resource: resource, onChanged: onSaved, trigger: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": `Manage files for ${resource.name}`, children: _jsx(IconFolder, { size: 16 }) }) }), _jsx(AgentEditorDialog, { resource: resource, onSaved: onSaved, trigger: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": `Edit ${resource.name}`, children: _jsx(IconEdit, { size: 16 }) }) }), _jsx(DeleteAgentButton, { resource: resource, onDeleted: onDeleted })] })] }));
396
+ }
397
+ export function SimpleAgentsPanel() {
398
+ const query = useActionQuery("list-workspace-resources", { kind: "agent" });
399
+ const agents = query.data ?? [];
400
+ if (query.isError) {
401
+ return (_jsx(ActionQueryError, { error: query.error, onRetry: () => void query.refetch() }));
402
+ }
403
+ return (_jsxs("section", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsx(ImportAgentDialog, { onImported: () => void query.refetch() }), _jsx(AgentEditorDialog, { onSaved: () => void query.refetch() })] }), query.isLoading && agents.length === 0 ? (_jsx("div", { className: "flex flex-col gap-3", children: [0, 1, 2].map((item) => (_jsxs("div", { className: "rounded-xl border bg-card px-4 py-3", children: [_jsx(Skeleton, { className: "h-4 w-1/3" }), _jsx(Skeleton, { className: "mt-2 h-3 w-2/3" })] }, item))) })) : agents.length > 0 ? (_jsx("div", { className: "flex flex-col gap-2", children: agents.map((agent) => (_jsx(AgentRow, { resource: agent, onDeleted: () => void query.refetch(), onSaved: () => void query.refetch() }, agent.id))) })) : (_jsxs("div", { className: "rounded-xl border border-dashed px-6 py-14 text-center", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: "No agents yet" }), _jsxs("div", { className: "mt-4 flex flex-wrap justify-center gap-2", children: [_jsx(AgentEditorDialog, { onSaved: () => void query.refetch(), trigger: _jsxs(Button, { children: [_jsx(IconPlus, { size: 16 }), "Create an agent"] }) }), _jsx(ImportAgentDialog, { onImported: () => void query.refetch() })] })] }))] }));
404
+ }
405
+ //# sourceMappingURL=simple-agents-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-agents-panel.js","sourceRoot":"","sources":["../../src/components/simple-agents-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n navigateWithAgentChatViewTransition,\n sendToAgentChat,\n} from \"@agent-native/core/client/agent-chat\";\nimport {\n useActionMutation,\n useActionQuery,\n} from \"@agent-native/core/client/hooks\";\nimport { parseCustomAgentProfile } from \"@agent-native/core/resources/metadata\";\nimport {\n IconAdjustmentsHorizontal,\n IconChevronDown,\n IconEdit,\n IconFileImport,\n IconFolder,\n IconLayoutGrid,\n IconMessageCircle,\n IconPlugConnected,\n IconPlus,\n IconTrash,\n IconUpload,\n IconUser,\n} from \"@tabler/icons-react\";\nimport {\n useEffect,\n useRef,\n useState,\n type ChangeEvent,\n type ReactNode,\n} from \"react\";\nimport { useNavigate } from \"react-router\";\nimport { toast } from \"sonner\";\n\nimport {\n buildSimpleAgentContent,\n slugifyAgentName,\n} from \"../lib/simple-agent-profile.js\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"./ui/alert-dialog\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"./ui/collapsible\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"./ui/dialog\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"./ui/select\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./ui/tabs\";\nimport { Textarea } from \"./ui/textarea\";\n\ninterface WorkspaceAgentResource {\n id: string;\n name: string;\n description: string | null;\n path: string;\n content: string;\n scope: \"all\" | \"selected\";\n updatedAt: number;\n}\n\ninterface AgentPackFileResource extends WorkspaceAgentResource {\n kind: \"agent-file\" | \"skill\";\n}\n\ninterface AgentPackResponse {\n profile: WorkspaceAgentResource;\n root: string;\n files: AgentPackFileResource[];\n}\n\ninterface AgentPackFileInput {\n path: string;\n content: string;\n}\n\nexport function isPendingWorkspaceResourceApproval(result: unknown) {\n if (!result || typeof result !== \"object\") return false;\n const mutation = result as { status?: unknown; changeType?: unknown };\n return (\n mutation.status === \"pending\" &&\n typeof mutation.changeType === \"string\" &&\n mutation.changeType.startsWith(\"workspace-resource.\")\n );\n}\n\nexport function handleAgentPackMutationSuccess(\n result: unknown,\n options: {\n appliedMessage: string;\n approvalMessage: string;\n onApplied: () => void;\n notify?: (message: string) => void;\n },\n) {\n const notify = options.notify || ((message) => toast.success(message));\n if (isPendingWorkspaceResourceApproval(result)) {\n notify(options.approvalMessage);\n return;\n }\n notify(options.appliedMessage);\n options.onApplied();\n}\n\ninterface AgentEditorProps {\n resource?: WorkspaceAgentResource;\n trigger?: ReactNode;\n onSaved?: () => void;\n}\n\nfunction profileFields(resource?: WorkspaceAgentResource) {\n if (!resource) {\n return {\n name: \"\",\n description: \"\",\n instructions: \"# Role\\n\\nDescribe how this agent should work.\\n\",\n model: \"inherit\",\n tools: \"inherit\",\n scope: \"all\" as const,\n };\n }\n\n const profile = parseCustomAgentProfile(resource.content, resource.path);\n return {\n name: profile?.name || resource.name,\n description: profile?.description || resource.description || \"\",\n instructions: profile?.instructions || resource.content,\n model: profile?.model || \"inherit\",\n tools: profile?.tools || \"inherit\",\n scope: resource.scope,\n };\n}\n\nfunction AgentEditorDialog({ resource, trigger, onSaved }: AgentEditorProps) {\n const isEditing = Boolean(resource);\n const [open, setOpen] = useState(false);\n const [name, setName] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [instructions, setInstructions] = useState(\"\");\n const [model, setModel] = useState(\"inherit\");\n const [tools, setTools] = useState(\"inherit\");\n const [scope, setScope] = useState<\"all\" | \"selected\">(\"all\");\n const [advancedOpen, setAdvancedOpen] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n const fields = profileFields(resource);\n setName(fields.name);\n setDescription(fields.description);\n setInstructions(fields.instructions);\n setModel(fields.model);\n setTools(fields.tools);\n setScope(fields.scope);\n setAdvancedOpen(fields.model !== \"inherit\" || fields.tools !== \"inherit\");\n }, [open, resource]);\n\n const create = useActionMutation(\"create-workspace-resource\", {\n onSuccess: () => {\n toast.success(\"Agent created\");\n setOpen(false);\n onSaved?.();\n },\n onError: (error) => toast.error(error.message),\n });\n const update = useActionMutation(\"update-workspace-resource\", {\n onSuccess: () => {\n toast.success(\"Agent updated\");\n setOpen(false);\n onSaved?.();\n },\n onError: (error) => toast.error(error.message),\n });\n\n const pending = create.isPending || update.isPending;\n const canSave = Boolean(name.trim() && instructions.trim() && !pending);\n\n function save() {\n const content = buildSimpleAgentContent({\n name,\n description,\n model,\n tools,\n instructions,\n });\n if (resource) {\n update.mutate({\n id: resource.id,\n name: name.trim(),\n description: description.trim(),\n content,\n scope,\n });\n return;\n }\n create.mutate({\n kind: \"agent\",\n name: name.trim(),\n description: description.trim() || undefined,\n path: `agents/${slugifyAgentName(name)}.md`,\n content,\n scope,\n });\n }\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger asChild>\n {trigger || (\n <Button>\n <IconPlus size={16} />\n Create agent\n </Button>\n )}\n </DialogTrigger>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>\n {isEditing ? \"Manage agent\" : \"Create agent\"}\n </DialogTitle>\n <DialogDescription className=\"sr-only\">\n {isEditing\n ? \"Update this reusable agent profile.\"\n : \"Create a reusable agent profile.\"}\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-4 py-2\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"simple-agent-name\">Name</Label>\n <Input\n id=\"simple-agent-name\"\n value={name}\n onChange={(event) => setName(event.target.value)}\n placeholder=\"User Research\"\n />\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"simple-agent-scope\">Availability</Label>\n <Select\n value={scope}\n onValueChange={(value: \"all\" | \"selected\") => setScope(value)}\n >\n <SelectTrigger id=\"simple-agent-scope\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n <SelectItem value=\"selected\">Selected apps</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"simple-agent-description\">Description</Label>\n <Input\n id=\"simple-agent-description\"\n value={description}\n onChange={(event) => setDescription(event.target.value)}\n placeholder=\"Synthesizes user research into clear insights\"\n />\n </div>\n <Collapsible open={advancedOpen} onOpenChange={setAdvancedOpen}>\n <CollapsibleTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"group -ml-2 gap-1.5 text-muted-foreground\"\n >\n <IconAdjustmentsHorizontal size={15} />\n Advanced\n <IconChevronDown\n className=\"transition-transform group-data-[state=open]:rotate-180\"\n size={15}\n />\n </Button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"pt-3\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"simple-agent-model\">Model</Label>\n <Input\n id=\"simple-agent-model\"\n value={model}\n onChange={(event) => setModel(event.target.value)}\n placeholder=\"inherit\"\n />\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"simple-agent-tools\">Tools</Label>\n <Input\n id=\"simple-agent-tools\"\n value={tools}\n onChange={(event) => setTools(event.target.value)}\n placeholder=\"inherit\"\n />\n </div>\n </div>\n </CollapsibleContent>\n </Collapsible>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"simple-agent-instructions\">Instructions</Label>\n <Textarea\n id=\"simple-agent-instructions\"\n value={instructions}\n onChange={(event) => setInstructions(event.target.value)}\n rows={12}\n className=\"font-mono text-sm\"\n placeholder=\"# Role\\n\\nDescribe how this agent should work.\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button onClick={save} disabled={!canSave}>\n {pending\n ? \"Saving...\"\n : isEditing\n ? \"Save changes\"\n : \"Create agent\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction AgentPackDialog({\n resource,\n onChanged,\n trigger,\n}: {\n resource: WorkspaceAgentResource;\n onChanged?: () => void;\n trigger?: ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const [selectedId, setSelectedId] = useState(resource.id);\n const [content, setContent] = useState(resource.content);\n const [addOpen, setAddOpen] = useState(false);\n const [newPath, setNewPath] = useState(\"\");\n const [newKind, setNewKind] = useState<\"agent-file\" | \"skill\">(\"agent-file\");\n const [newContent, setNewContent] = useState(\"\");\n const query = useActionQuery<AgentPackResponse>(\n \"list-agent-pack\",\n { agentId: resource.id },\n { enabled: open },\n );\n const update = useActionMutation(\"update-workspace-resource\", {\n onSuccess: (result) => {\n handleAgentPackMutationSuccess(result, {\n appliedMessage: \"Pack file updated\",\n approvalMessage: \"Pack file update queued for approval\",\n onApplied: () => {\n void query.refetch();\n onChanged?.();\n },\n });\n },\n onError: (error) => toast.error(error.message),\n });\n const create = useActionMutation(\"create-workspace-resource\", {\n onSuccess: (result) => {\n handleAgentPackMutationSuccess(result, {\n appliedMessage: \"Pack file added\",\n approvalMessage: \"Pack file addition queued for approval\",\n onApplied: () => {\n setAddOpen(false);\n setNewPath(\"\");\n setNewContent(\"\");\n void query.refetch();\n onChanged?.();\n },\n });\n },\n onError: (error) => toast.error(error.message),\n });\n const remove = useActionMutation(\"delete-workspace-resource\", {\n onSuccess: () => {\n toast.success(\"Pack file removed\");\n setSelectedId(resource.id);\n void query.refetch();\n onChanged?.();\n },\n onError: (error) => toast.error(error.message),\n });\n\n const files = query.data\n ? [{ ...query.data.profile, kind: \"agent\" as const }, ...query.data.files]\n : [];\n const selected = files.find((file) => file.id === selectedId) ?? files[0];\n\n useEffect(() => {\n if (!open) return;\n setSelectedId(resource.id);\n }, [open, resource.id]);\n\n useEffect(() => {\n if (!selected) return;\n setSelectedId(selected.id);\n setContent(selected.content);\n }, [selected?.id, selected?.content]);\n\n function addFile() {\n const relativePath = newPath.trim().replaceAll(\"\\\\\", \"/\");\n if (\n !relativePath ||\n relativePath.startsWith(\"/\") ||\n relativePath.includes(\"..\") ||\n relativePath.split(\"/\").some((part) => !part || part === \".\")\n ) {\n toast.error(\"Use a relative pack path without ..\");\n return;\n }\n const packPath =\n newKind === \"skill\" && !relativePath.startsWith(\"skills/\")\n ? `skills/${relativePath}`\n : relativePath;\n const name = packPath.split(\"/\").pop() || packPath;\n create.mutate({\n kind: newKind,\n name,\n path: `${query.data?.root || `agents/${slugifyAgentName(resource.name)}`}/${packPath}`,\n content: newContent,\n scope: resource.scope,\n });\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(nextOpen) => {\n setOpen(nextOpen);\n if (!nextOpen) setAddOpen(false);\n }}\n >\n <DialogTrigger asChild>\n {trigger || (\n <Button variant=\"ghost\" size=\"sm\">\n <IconFolder size={15} />\n Pack\n </Button>\n )}\n </DialogTrigger>\n <DialogContent className=\"max-w-4xl\">\n <DialogHeader>\n <DialogTitle>Agent pack</DialogTitle>\n <DialogDescription className=\"sr-only\">\n Edit the profile, reference files, context, and skills that belong\n to this agent.\n </DialogDescription>\n </DialogHeader>\n <div className=\"grid min-h-0 gap-4 md:grid-cols-[220px_minmax(0,1fr)]\">\n <div className=\"flex min-w-0 flex-col gap-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Files\n </span>\n <Dialog open={addOpen} onOpenChange={setAddOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus size={14} />\n Add\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Add pack file</DialogTitle>\n <DialogDescription className=\"sr-only\">\n Add a text reference or agent-owned skill to this pack.\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-4 py-2\">\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"agent-pack-file-path\">Path</Label>\n <Input\n id=\"agent-pack-file-path\"\n value={newPath}\n onChange={(event) => setNewPath(event.target.value)}\n placeholder=\"context/brief.md\"\n />\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"agent-pack-file-kind\">Type</Label>\n <Select\n value={newKind}\n onValueChange={(value: \"agent-file\" | \"skill\") =>\n setNewKind(value)\n }\n >\n <SelectTrigger id=\"agent-pack-file-kind\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"agent-file\">\n Reference file\n </SelectItem>\n <SelectItem value=\"skill\">Skill</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"agent-pack-file-content\">Content</Label>\n <Textarea\n id=\"agent-pack-file-content\"\n value={newContent}\n onChange={(event) => setNewContent(event.target.value)}\n rows={8}\n className=\"font-mono text-sm\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button\n onClick={addFile}\n disabled={!newPath.trim() || create.isPending}\n >\n {create.isPending ? \"Adding...\" : \"Add file\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n {query.isLoading ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : (\n <div className=\"flex flex-col gap-1\">\n {files.map((file) => (\n <Button\n key={file.id}\n type=\"button\"\n variant={selected?.id === file.id ? \"secondary\" : \"ghost\"}\n className=\"h-auto w-full justify-start px-2 py-2 text-left\"\n onClick={() => setSelectedId(file.id)}\n >\n <span className=\"min-w-0 truncate text-xs\">\n {file.path.replace(`${query.data?.root || \"\"}/`, \"\")}\n </span>\n </Button>\n ))}\n </div>\n )}\n </div>\n <div className=\"flex min-w-0 flex-col gap-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">\n {selected?.path || \"Select a file\"}\n </div>\n {selected && selected.kind !== \"agent\" ? (\n <Badge variant=\"outline\">\n {selected.kind === \"skill\" ? \"Skill\" : \"Reference\"}\n </Badge>\n ) : null}\n </div>\n <div className=\"flex items-center gap-1\">\n {selected && selected.kind !== \"agent\" ? (\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\">\n <IconTrash size={15} />\n Remove\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n Remove this pack file?\n </AlertDialogTitle>\n <AlertDialogDescription>\n The file will no longer be available to this agent.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => remove.mutate({ id: selected.id })}\n disabled={remove.isPending}\n >\n Remove\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n ) : null}\n <Button\n size=\"sm\"\n onClick={() =>\n selected && update.mutate({ id: selected.id, content })\n }\n disabled={\n !selected ||\n update.isPending ||\n content === selected.content\n }\n >\n {update.isPending ? \"Saving...\" : \"Save file\"}\n </Button>\n </div>\n </div>\n <Textarea\n value={content}\n onChange={(event) => setContent(event.target.value)}\n disabled={!selected}\n rows={18}\n className=\"min-h-[360px] font-mono text-sm\"\n />\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction ImportAgentDialog({ onImported }: { onImported?: () => void }) {\n const [open, setOpen] = useState(false);\n const [mode, setMode] = useState<\"file\" | \"folder\" | \"endpoint\">(\"file\");\n const [source, setSource] = useState(\"\");\n const [fileName, setFileName] = useState(\"\");\n const [scope, setScope] = useState<\"all\" | \"selected\">(\"all\");\n const [url, setUrl] = useState(\"\");\n const [endpointName, setEndpointName] = useState(\"\");\n const [endpointDescription, setEndpointDescription] = useState(\"\");\n const [packFiles, setPackFiles] = useState<AgentPackFileInput[]>([]);\n const [packName, setPackName] = useState(\"\");\n const [packWarnings, setPackWarnings] = useState<string[]>([]);\n const fileRef = useRef<HTMLInputElement>(null);\n const folderRef = useRef<HTMLInputElement>(null);\n\n const importAgent = useActionMutation(\"import-agent\", {\n onSuccess: (result: { status: string; warnings?: string[] }) => {\n toast.success(\n result.status === \"unchanged\"\n ? \"Agent already imported\"\n : \"Agent imported\",\n );\n if (result.warnings?.length) {\n toast.info(result.warnings.join(\" \"));\n }\n setOpen(false);\n onImported?.();\n },\n onError: (error) => toast.error(error.message),\n });\n const connect = useActionMutation(\"connect-external-agent\", {\n onSuccess: () => {\n toast.success(\"Agent connected\");\n setOpen(false);\n onImported?.();\n },\n onError: (error) => toast.error(error.message),\n });\n const importPack = useActionMutation(\"import-agent-pack\", {\n onSuccess: (result: { status: string; warnings?: string[] }) => {\n toast.success(\n result.status === \"pending-approval\"\n ? \"Pack sent for approval\"\n : result.status === \"unchanged\"\n ? \"Agent pack already imported\"\n : \"Agent pack imported\",\n );\n if (result.warnings?.length) toast.info(result.warnings.join(\" \"));\n setOpen(false);\n onImported?.();\n },\n onError: (error) => toast.error(error.message),\n });\n\n useEffect(() => {\n if (!folderRef.current) return;\n folderRef.current.setAttribute(\"webkitdirectory\", \"\");\n folderRef.current.setAttribute(\"directory\", \"\");\n }, [mode, open]);\n\n function reset() {\n setMode(\"file\");\n setSource(\"\");\n setFileName(\"\");\n setScope(\"all\");\n setUrl(\"\");\n setEndpointName(\"\");\n setEndpointDescription(\"\");\n setPackFiles([]);\n setPackName(\"\");\n setPackWarnings([]);\n }\n\n async function handleFile(event: ChangeEvent<HTMLInputElement>) {\n const file = event.target.files?.[0];\n if (!file) return;\n setFileName(file.name);\n setSource(await file.text());\n }\n\n async function handleFolder(event: ChangeEvent<HTMLInputElement>) {\n const selectedFiles = Array.from(event.target.files ?? []);\n if (selectedFiles.length === 0) return;\n const warnings: string[] = [];\n const textExtensions =\n /\\.(md|markdown|txt|json|yaml|yml|csv|html|xml|toml|ts|tsx|js|mjs|py|sh)$/i;\n const pack = await Promise.all(\n selectedFiles.map(async (file) => {\n const path =\n (file as File & { webkitRelativePath?: string }).webkitRelativePath ||\n file.name;\n if (!textExtensions.test(path)) {\n warnings.push(`Skipped non-text file: ${path}`);\n return null;\n }\n return { path, content: await file.text() };\n }),\n );\n const files = pack.filter((file): file is AgentPackFileInput =>\n Boolean(file),\n );\n setPackFiles(files);\n setPackName(files[0]?.path.split(\"/\")[0] || \"Selected folder\");\n setPackWarnings(warnings);\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(nextOpen) => {\n setOpen(nextOpen);\n if (!nextOpen) reset();\n }}\n >\n <DialogTrigger asChild>\n <Button variant=\"outline\">\n <IconFileImport size={16} />\n Import or connect\n </Button>\n </DialogTrigger>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Import an agent</DialogTitle>\n <DialogDescription className=\"sr-only\">\n Import a Claude or JSON agent definition, or connect an external\n agent endpoint.\n </DialogDescription>\n </DialogHeader>\n <Tabs\n value={mode}\n onValueChange={(value) =>\n setMode(value as \"file\" | \"folder\" | \"endpoint\")\n }\n >\n <TabsList className=\"w-full justify-start\">\n <TabsTrigger value=\"file\">Agent file</TabsTrigger>\n <TabsTrigger value=\"folder\">Agent folder</TabsTrigger>\n <TabsTrigger value=\"endpoint\">Connect endpoint</TabsTrigger>\n </TabsList>\n <TabsContent value=\"file\" className=\"flex flex-col gap-4 py-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => fileRef.current?.click()}\n >\n <IconUpload size={16} />\n Choose file\n </Button>\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".md,.markdown,.json,.txt\"\n className=\"hidden\"\n onChange={(event) => void handleFile(event)}\n />\n <span className=\"text-xs text-muted-foreground\">\n {fileName || \"Claude .md or JSON agent definition\"}\n </span>\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"import-agent-source\">Definition</Label>\n <Textarea\n id=\"import-agent-source\"\n value={source}\n onChange={(event) => setSource(event.target.value)}\n rows={12}\n className=\"font-mono text-sm\"\n placeholder=\"Paste a Claude-style agent file or a JSON definition\"\n />\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"import-agent-scope\">Availability</Label>\n <Select\n value={scope}\n onValueChange={(value: \"all\" | \"selected\") => setScope(value)}\n >\n <SelectTrigger id=\"import-agent-scope\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n <SelectItem value=\"selected\">Selected apps</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <DialogFooter>\n <Button\n onClick={() =>\n importAgent.mutate({\n source,\n fileName: fileName || undefined,\n scope,\n })\n }\n disabled={!source.trim() || importAgent.isPending}\n >\n {importAgent.isPending ? \"Importing...\" : \"Import agent\"}\n </Button>\n </DialogFooter>\n </TabsContent>\n <TabsContent value=\"folder\" className=\"flex flex-col gap-4 py-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => folderRef.current?.click()}\n >\n <IconFolder size={16} />\n Choose folder\n </Button>\n <input\n ref={folderRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={(event) => void handleFolder(event)}\n />\n <span className=\"text-xs text-muted-foreground\">\n {packName\n ? `${packName} · ${packFiles.length} files`\n : \"Claude Project or Cowork-style folder\"}\n </span>\n </div>\n {packWarnings.length > 0 ? (\n <div className=\"rounded-lg border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-xs text-amber-800 dark:text-amber-200\">\n {packWarnings.join(\" \")}\n </div>\n ) : null}\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"import-agent-pack-scope\">Availability</Label>\n <Select\n value={scope}\n onValueChange={(value: \"all\" | \"selected\") => setScope(value)}\n >\n <SelectTrigger id=\"import-agent-pack-scope\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All apps</SelectItem>\n <SelectItem value=\"selected\">Selected apps</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <DialogFooter>\n <Button\n onClick={() => importPack.mutate({ files: packFiles, scope })}\n disabled={packFiles.length === 0 || importPack.isPending}\n >\n {importPack.isPending ? \"Importing...\" : \"Import agent pack\"}\n </Button>\n </DialogFooter>\n </TabsContent>\n <TabsContent value=\"endpoint\" className=\"flex flex-col gap-4 py-4\">\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"external-agent-url\">Endpoint URL</Label>\n <Input\n id=\"external-agent-url\"\n value={url}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://agent.example.com\"\n />\n </div>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"external-agent-name\">Name</Label>\n <Input\n id=\"external-agent-name\"\n value={endpointName}\n onChange={(event) => setEndpointName(event.target.value)}\n placeholder=\"Research partner\"\n />\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label>Availability</Label>\n <div className=\"flex h-10 items-center\">\n <Badge variant=\"secondary\">Workspace</Badge>\n </div>\n </div>\n </div>\n <div className=\"flex flex-col gap-2\">\n <Label htmlFor=\"external-agent-description\">Description</Label>\n <Input\n id=\"external-agent-description\"\n value={endpointDescription}\n onChange={(event) => setEndpointDescription(event.target.value)}\n placeholder=\"Optional\"\n />\n </div>\n <p className=\"text-xs text-muted-foreground\">\n Dispatch stores the public endpoint only. Authenticate it after\n connecting.\n </p>\n <DialogFooter>\n <Button\n onClick={() =>\n connect.mutate({\n url,\n name: endpointName || undefined,\n description: endpointDescription || undefined,\n scope: \"shared\",\n })\n }\n disabled={!url.trim() || connect.isPending}\n >\n <IconPlugConnected size={16} />\n {connect.isPending ? \"Connecting...\" : \"Connect agent\"}\n </Button>\n </DialogFooter>\n </TabsContent>\n </Tabs>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction DeleteAgentButton({\n resource,\n onDeleted,\n}: {\n resource: WorkspaceAgentResource;\n onDeleted?: () => void;\n}) {\n const remove = useActionMutation(\"delete-workspace-resource\", {\n onSuccess: () => {\n toast.success(\"Agent removed\");\n onDeleted?.();\n },\n onError: (error) => toast.error(error.message),\n });\n\n return (\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Remove ${resource.name}`}\n >\n <IconTrash size={16} />\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Remove {resource.name}?</AlertDialogTitle>\n <AlertDialogDescription>\n This removes the reusable profile from the workspace apps.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => remove.mutate({ id: resource.id })}\n disabled={remove.isPending}\n >\n Remove\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n\nfunction AgentRow({\n resource,\n onDeleted,\n onSaved,\n}: {\n resource: WorkspaceAgentResource;\n onDeleted?: () => void;\n onSaved?: () => void;\n}) {\n const navigate = useNavigate();\n const packQuery = useActionQuery<AgentPackResponse>(\n \"list-agent-pack\",\n { agentId: resource.id },\n { enabled: false },\n );\n const promote = useActionMutation<\n AgentAppCreationResult,\n AgentAppCreationInput\n >(\"start-workspace-app-creation\", {\n onSuccess: (result) => {\n if (result.mode === \"local-agent\") {\n sendToAgentChat({\n message: result.prompt ?? result.message,\n submit: true,\n type: \"code\",\n newTab: true,\n reuseEmptyTab: true,\n });\n toast.success(\"Sent to the local agent\");\n return;\n }\n if (result.mode === \"builder\") {\n toast.success(\"App build started\", {\n description: result.message,\n action: result.url\n ? {\n label: \"Open in Builder\",\n onClick: () =>\n window.open(result.url, \"_blank\", \"noopener,noreferrer\"),\n }\n : undefined,\n });\n return;\n }\n toast.error(result.message);\n },\n onError: (error) => toast.error(error.message),\n });\n\n function chat() {\n navigateWithAgentChatViewTransition(\n navigate,\n `/chat?agent=${encodeURIComponent(resource.path)}`,\n );\n }\n\n async function buildApp() {\n const pack = await packQuery.refetch();\n if (pack.error || !pack.data) {\n toast.error(pack.error?.message || \"Could not load the agent pack\");\n return;\n }\n promote.mutate({\n appId: slugifyAgentName(resource.name),\n description: resource.description || undefined,\n prompt: `Turn the \"${resource.name}\" workspace agent into a focused workspace app. Preserve its role and instructions, make the app its usable face, and keep the original reusable agent profile available.`,\n resourceIds: [resource.id, ...pack.data.files.map((file) => file.id)],\n });\n }\n\n return (\n <div className=\"flex items-start gap-3 rounded-xl border bg-card px-4 py-3\">\n <div className=\"flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <IconUser size={18} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {resource.name}\n </span>\n <Badge variant=\"outline\">\n {resource.scope === \"all\" ? \"All apps\" : \"Selected apps\"}\n </Badge>\n </div>\n {resource.description ? (\n <div className=\"mt-1 text-sm text-muted-foreground\">\n {resource.description}\n </div>\n ) : null}\n <div className=\"mt-1 font-mono text-[11px] text-muted-foreground/70\">\n {resource.path}\n </div>\n </div>\n <div className=\"flex shrink-0 flex-wrap items-center justify-end gap-1\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={chat}\n aria-label={`Chat with ${resource.name}`}\n >\n <IconMessageCircle size={15} />\n Chat\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void buildApp()}\n disabled={promote.isPending}\n aria-label={`Build an app for ${resource.name}`}\n >\n <IconLayoutGrid size={15} />\n {promote.isPending ? \"Starting...\" : \"Build app\"}\n </Button>\n <AgentPackDialog\n resource={resource}\n onChanged={onSaved}\n trigger={\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Manage files for ${resource.name}`}\n >\n <IconFolder size={16} />\n </Button>\n }\n />\n <AgentEditorDialog\n resource={resource}\n onSaved={onSaved}\n trigger={\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Edit ${resource.name}`}\n >\n <IconEdit size={16} />\n </Button>\n }\n />\n <DeleteAgentButton resource={resource} onDeleted={onDeleted} />\n </div>\n </div>\n );\n}\n\ninterface AgentAppCreationInput {\n appId: string;\n description?: string;\n prompt: string;\n resourceIds: string[];\n}\n\ninterface AgentAppCreationResult {\n mode: \"builder\" | \"local-agent\" | \"builder-unavailable\" | \"coming-soon\";\n message: string;\n prompt?: string;\n url?: string;\n}\n\nexport function SimpleAgentsPanel() {\n const query = useActionQuery<WorkspaceAgentResource[]>(\n \"list-workspace-resources\",\n { kind: \"agent\" },\n );\n const agents = query.data ?? [];\n\n if (query.isError) {\n return (\n <ActionQueryError\n error={query.error}\n onRetry={() => void query.refetch()}\n />\n );\n }\n\n return (\n <section className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center justify-end gap-2\">\n <ImportAgentDialog onImported={() => void query.refetch()} />\n <AgentEditorDialog onSaved={() => void query.refetch()} />\n </div>\n {query.isLoading && agents.length === 0 ? (\n <div className=\"flex flex-col gap-3\">\n {[0, 1, 2].map((item) => (\n <div key={item} className=\"rounded-xl border bg-card px-4 py-3\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"mt-2 h-3 w-2/3\" />\n </div>\n ))}\n </div>\n ) : agents.length > 0 ? (\n <div className=\"flex flex-col gap-2\">\n {agents.map((agent) => (\n <AgentRow\n key={agent.id}\n resource={agent}\n onDeleted={() => void query.refetch()}\n onSaved={() => void query.refetch()}\n />\n ))}\n </div>\n ) : (\n <div className=\"rounded-xl border border-dashed px-6 py-14 text-center\">\n <div className=\"text-sm font-medium text-foreground\">\n No agents yet\n </div>\n <div className=\"mt-4 flex flex-wrap justify-center gap-2\">\n <AgentEditorDialog\n onSaved={() => void query.refetch()}\n trigger={\n <Button>\n <IconPlus size={16} />\n Create an agent\n </Button>\n }\n />\n <ImportAgentDialog onImported={() => void query.refetch()} />\n </div>\n </div>\n )}\n </section>\n );\n}\n"]}