@agent-native/dispatch 0.25.1 → 0.26.0
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.
- package/dist/actions/provider-api-register.d.ts +11 -11
- package/dist/components/create-app-popover.d.ts +7 -2
- package/dist/components/create-app-popover.d.ts.map +1 -1
- package/dist/components/create-app-popover.js +4 -3
- package/dist/components/create-app-popover.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +42 -2
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/components/simple-agents-panel.d.ts +4 -1
- package/dist/components/simple-agents-panel.d.ts.map +1 -1
- package/dist/components/simple-agents-panel.js +46 -13
- package/dist/components/simple-agents-panel.js.map +1 -1
- package/dist/components/workspace-app-host.d.ts +3 -1
- package/dist/components/workspace-app-host.d.ts.map +1 -1
- package/dist/components/workspace-app-host.js +11 -2
- package/dist/components/workspace-app-host.js.map +1 -1
- package/package.json +3 -3
- package/src/components/create-app-popover.spec.tsx +9 -1
- package/src/components/create-app-popover.tsx +9 -1
- package/src/components/index.ts +1 -0
- package/src/components/layout/Layout.app-chat.spec.ts +22 -0
- package/src/components/layout/Layout.tsx +72 -3
- package/src/components/simple-agents-panel.spec.tsx +81 -1
- package/src/components/simple-agents-panel.tsx +156 -71
- package/src/components/workspace-app-host.tsx +30 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
1
2
|
export declare function isPendingWorkspaceResourceApproval(result: unknown): boolean;
|
|
2
3
|
export declare function handleAgentPackMutationSuccess(result: unknown, options: {
|
|
3
4
|
appliedMessage: string;
|
|
@@ -5,5 +6,7 @@ export declare function handleAgentPackMutationSuccess(result: unknown, options:
|
|
|
5
6
|
onApplied: () => void;
|
|
6
7
|
notify?: (message: string) => void;
|
|
7
8
|
}): void;
|
|
8
|
-
export declare function SimpleAgentsPanel(
|
|
9
|
+
export declare function SimpleAgentsPanel({ title, }?: {
|
|
10
|
+
title?: ReactNode;
|
|
11
|
+
}): import("node_modules/@types/react/index.js").JSX.Element;
|
|
9
12
|
//# sourceMappingURL=simple-agents-panel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-agents-panel.d.ts","sourceRoot":"","sources":["../../src/components/simple-agents-panel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"simple-agents-panel.d.ts","sourceRoot":"","sources":["../../src/components/simple-agents-panel.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAqGf,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;AAkjCD,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,GACN,GAAE;IACD,KAAK,CAAC,EAAE,SAAS,CAAC;CACd,4DA4EL"}
|
|
@@ -2,23 +2,42 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { navigateWithAgentChatViewTransition, sendToAgentChat, } from "@agent-native/core/client/agent-chat";
|
|
3
3
|
import { useActionMutation, useActionQuery, } from "@agent-native/core/client/hooks";
|
|
4
4
|
import { parseCustomAgentProfile } from "@agent-native/core/resources/metadata";
|
|
5
|
-
import { IconAdjustmentsHorizontal, IconChevronDown, IconEdit, IconFileImport, IconFolder, IconLayoutGrid, IconMessageCircle, IconPlugConnected, IconPlus, IconTrash, IconUpload,
|
|
5
|
+
import { IconAdjustmentsHorizontal, IconChevronDown, IconDotsVertical, IconEdit, IconFileImport, IconFolder, IconLayoutGrid, IconMessageCircle, IconPlugConnected, IconPlus, IconTrash, IconUpload, } from "@tabler/icons-react";
|
|
6
6
|
import { useEffect, useRef, useState, } from "react";
|
|
7
7
|
import { useNavigate } from "react-router";
|
|
8
8
|
import { toast } from "sonner";
|
|
9
9
|
import { buildSimpleAgentContent, slugifyAgentName, } from "../lib/simple-agent-profile.js";
|
|
10
10
|
import { ActionQueryError } from "./action-query-error.js";
|
|
11
|
+
import { AppIcon } from "./app-icon.js";
|
|
11
12
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "./ui/alert-dialog.js";
|
|
12
13
|
import { Badge } from "./ui/badge.js";
|
|
13
14
|
import { Button } from "./ui/button.js";
|
|
14
15
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "./ui/collapsible.js";
|
|
15
16
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "./ui/dialog.js";
|
|
17
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "./ui/dropdown-menu.js";
|
|
16
18
|
import { Input } from "./ui/input.js";
|
|
17
19
|
import { Label } from "./ui/label.js";
|
|
18
20
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "./ui/select.js";
|
|
19
21
|
import { Skeleton } from "./ui/skeleton.js";
|
|
20
22
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs.js";
|
|
21
23
|
import { Textarea } from "./ui/textarea.js";
|
|
24
|
+
const AGENT_ICON_KEYS = [
|
|
25
|
+
"brain",
|
|
26
|
+
"users",
|
|
27
|
+
"filetext",
|
|
28
|
+
"chartbar",
|
|
29
|
+
"route",
|
|
30
|
+
"listcheck",
|
|
31
|
+
"code",
|
|
32
|
+
"messagecircle",
|
|
33
|
+
];
|
|
34
|
+
function agentIconKey(resource) {
|
|
35
|
+
let hash = 0;
|
|
36
|
+
for (const character of `${resource.id}:${resource.name}`) {
|
|
37
|
+
hash = (hash * 31 + character.charCodeAt(0)) | 0;
|
|
38
|
+
}
|
|
39
|
+
return AGENT_ICON_KEYS[Math.abs(hash) % AGENT_ICON_KEYS.length];
|
|
40
|
+
}
|
|
22
41
|
export function isPendingWorkspaceResourceApproval(result) {
|
|
23
42
|
if (!result || typeof result !== "object")
|
|
24
43
|
return false;
|
|
@@ -57,9 +76,11 @@ function profileFields(resource) {
|
|
|
57
76
|
scope: resource.scope,
|
|
58
77
|
};
|
|
59
78
|
}
|
|
60
|
-
function AgentEditorDialog({ resource, trigger, onSaved }) {
|
|
79
|
+
function AgentEditorDialog({ resource, trigger, onSaved, open: controlledOpen, onOpenChange: controlledOnOpenChange, }) {
|
|
61
80
|
const isEditing = Boolean(resource);
|
|
62
|
-
const [
|
|
81
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
82
|
+
const open = controlledOpen ?? uncontrolledOpen;
|
|
83
|
+
const setOpen = controlledOnOpenChange ?? setUncontrolledOpen;
|
|
63
84
|
const [name, setName] = useState("");
|
|
64
85
|
const [description, setDescription] = useState("");
|
|
65
86
|
const [instructions, setInstructions] = useState("");
|
|
@@ -124,7 +145,7 @@ function AgentEditorDialog({ resource, trigger, onSaved }) {
|
|
|
124
145
|
scope,
|
|
125
146
|
});
|
|
126
147
|
}
|
|
127
|
-
return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: trigger
|
|
148
|
+
return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [trigger ? (_jsx(DialogTrigger, { asChild: true, children: trigger })) : controlledOpen === undefined ? (_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { size: "sm", children: [_jsx(IconPlus, { size: 16 }), "Create agent"] }) })) : null, _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
149
|
? "Update this reusable agent profile."
|
|
129
150
|
: "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
151
|
? "Saving..."
|
|
@@ -132,8 +153,10 @@ function AgentEditorDialog({ resource, trigger, onSaved }) {
|
|
|
132
153
|
? "Save changes"
|
|
133
154
|
: "Create agent" }) })] })] }));
|
|
134
155
|
}
|
|
135
|
-
function AgentPackDialog({ resource, onChanged, trigger, }) {
|
|
136
|
-
const [
|
|
156
|
+
function AgentPackDialog({ resource, onChanged, trigger, open: controlledOpen, onOpenChange: controlledOnOpenChange, }) {
|
|
157
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
158
|
+
const open = controlledOpen ?? uncontrolledOpen;
|
|
159
|
+
const setOpen = controlledOnOpenChange ?? setUncontrolledOpen;
|
|
137
160
|
const [selectedId, setSelectedId] = useState(resource.id);
|
|
138
161
|
const [content, setContent] = useState(resource.content);
|
|
139
162
|
const [addOpen, setAddOpen] = useState(false);
|
|
@@ -219,7 +242,7 @@ function AgentPackDialog({ resource, onChanged, trigger, }) {
|
|
|
219
242
|
setOpen(nextOpen);
|
|
220
243
|
if (!nextOpen)
|
|
221
244
|
setAddOpen(false);
|
|
222
|
-
}, children: [_jsx(DialogTrigger, { asChild: true, children: trigger
|
|
245
|
+
}, children: [trigger ? (_jsx(DialogTrigger, { asChild: true, children: trigger })) : controlledOpen === undefined ? (_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", children: [_jsx(IconFolder, { size: 15 }), "Pack"] }) })) : null, _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
246
|
update.isPending ||
|
|
224
247
|
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
248
|
}
|
|
@@ -321,7 +344,7 @@ function ImportAgentDialog({ onImported }) {
|
|
|
321
344
|
setOpen(nextOpen);
|
|
322
345
|
if (!nextOpen)
|
|
323
346
|
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({
|
|
347
|
+
}, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", 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
348
|
source,
|
|
326
349
|
fileName: fileName || undefined,
|
|
327
350
|
scope,
|
|
@@ -334,7 +357,10 @@ function ImportAgentDialog({ onImported }) {
|
|
|
334
357
|
scope: "shared",
|
|
335
358
|
}), disabled: !url.trim() || connect.isPending, children: [_jsx(IconPlugConnected, { size: 16 }), connect.isPending ? "Connecting..." : "Connect agent"] }) })] })] })] })] }));
|
|
336
359
|
}
|
|
337
|
-
function DeleteAgentButton({ resource, onDeleted, }) {
|
|
360
|
+
function DeleteAgentButton({ resource, onDeleted, open: controlledOpen, onOpenChange: controlledOnOpenChange, }) {
|
|
361
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
362
|
+
const open = controlledOpen ?? uncontrolledOpen;
|
|
363
|
+
const setOpen = controlledOnOpenChange ?? setUncontrolledOpen;
|
|
338
364
|
const remove = useActionMutation("delete-workspace-resource", {
|
|
339
365
|
onSuccess: () => {
|
|
340
366
|
toast.success("Agent removed");
|
|
@@ -342,10 +368,13 @@ function DeleteAgentButton({ resource, onDeleted, }) {
|
|
|
342
368
|
},
|
|
343
369
|
onError: (error) => toast.error(error.message),
|
|
344
370
|
});
|
|
345
|
-
return (
|
|
371
|
+
return (_jsx(AlertDialog, { open: open, onOpenChange: setOpen, children: _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
372
|
}
|
|
347
373
|
function AgentRow({ resource, onDeleted, onSaved, }) {
|
|
348
374
|
const navigate = useNavigate();
|
|
375
|
+
const [packOpen, setPackOpen] = useState(false);
|
|
376
|
+
const [editorOpen, setEditorOpen] = useState(false);
|
|
377
|
+
const [deleteOpen, setDeleteOpen] = useState(false);
|
|
349
378
|
const packQuery = useActionQuery("list-agent-pack", { agentId: resource.id }, { enabled: false });
|
|
350
379
|
const promote = useActionMutation("start-workspace-app-creation", {
|
|
351
380
|
onSuccess: (result) => {
|
|
@@ -392,14 +421,18 @@ function AgentRow({ resource, onDeleted, onSaved, }) {
|
|
|
392
421
|
resourceIds: [resource.id, ...pack.data.files.map((file) => file.id)],
|
|
393
422
|
});
|
|
394
423
|
}
|
|
395
|
-
return (_jsxs("div", { className: "flex items-start gap-3 rounded-
|
|
424
|
+
return (_jsxs("div", { className: "flex min-w-0 items-start gap-3 rounded-2xl border bg-card px-4 py-4", children: [_jsx(AppIcon, { id: resource.id, name: resource.name, icon: agentIconKey(resource), size: "sm" }), _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] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: chat, "aria-label": `Chat with ${resource.name}`, children: [_jsx(IconMessageCircle, { size: 15 }), "Chat"] }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": `More actions for ${resource.name}`, title: "More actions", children: _jsx(IconDotsVertical, { size: 16 }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-48", children: [_jsxs(DropdownMenuItem, { onSelect: () => {
|
|
425
|
+
void buildApp();
|
|
426
|
+
}, disabled: promote.isPending, children: [_jsx(IconLayoutGrid, { className: "me-2 size-4" }), promote.isPending ? "Starting..." : "Build app"] }), _jsxs(DropdownMenuItem, { onSelect: () => setPackOpen(true), children: [_jsx(IconFolder, { className: "me-2 size-4" }), "Manage files"] }), _jsxs(DropdownMenuItem, { onSelect: () => setEditorOpen(true), children: [_jsx(IconEdit, { className: "me-2 size-4" }), "Edit"] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onSelect: () => setDeleteOpen(true), children: [_jsx(IconTrash, { className: "me-2 size-4" }), "Remove"] })] })] }), _jsx(AgentPackDialog, { resource: resource, onChanged: onSaved, open: packOpen, onOpenChange: setPackOpen }), _jsx(AgentEditorDialog, { resource: resource, onSaved: onSaved, open: editorOpen, onOpenChange: setEditorOpen }), _jsx(DeleteAgentButton, { resource: resource, onDeleted: onDeleted, open: deleteOpen, onOpenChange: setDeleteOpen })] })] }));
|
|
396
427
|
}
|
|
397
|
-
export function SimpleAgentsPanel() {
|
|
428
|
+
export function SimpleAgentsPanel({ title, } = {}) {
|
|
398
429
|
const query = useActionQuery("list-workspace-resources", { kind: "agent" });
|
|
399
430
|
const agents = query.data ?? [];
|
|
431
|
+
const refreshAgents = () => void query.refetch();
|
|
432
|
+
const importAction = _jsx(ImportAgentDialog, { onImported: refreshAgents });
|
|
400
433
|
if (query.isError) {
|
|
401
434
|
return (_jsx(ActionQueryError, { error: query.error, onRetry: () => void query.refetch() }));
|
|
402
435
|
}
|
|
403
|
-
return (_jsxs("section", { className: "flex flex-col gap-4", children: [_jsxs("div", { className:
|
|
436
|
+
return (_jsxs("section", { className: "flex flex-col gap-4", children: [title || agents.length > 0 ? (_jsxs("div", { className: `flex flex-wrap items-center gap-3 ${title ? "justify-between" : "justify-end"}`, children: [title ? (_jsx("h2", { className: "text-base font-medium text-foreground", children: title })) : null, agents.length > 0 ? (_jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [importAction, _jsx(AgentEditorDialog, { onSaved: refreshAgents })] })) : null] })) : null, query.isLoading && agents.length === 0 ? (_jsx("div", { className: "grid gap-3 md:grid-cols-2", children: [0, 1, 2].map((item) => (_jsxs("div", { className: "rounded-2xl border bg-card px-4 py-4", 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: "grid gap-3 md:grid-cols-2", children: agents.map((agent) => (_jsx(AgentRow, { resource: agent, onDeleted: () => void query.refetch(), onSaved: () => void query.refetch() }, agent.id))) })) : (_jsxs("div", { className: "rounded-2xl border border-dashed bg-card px-4 py-12 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: refreshAgents, trigger: _jsxs(Button, { size: "sm", children: [_jsx(IconPlus, { size: 16 }), "Create an agent"] }) }), importAction] })] }))] }));
|
|
404
437
|
}
|
|
405
438
|
//# sourceMappingURL=simple-agents-panel.js.map
|