@getcatalystiq/agent-plane-ui 0.1.27 → 0.1.29
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/agent-identity-tab-BP5MPDYZ.js +2 -0
- package/dist/{agent-identity-tab-HADOCEAN.cjs → agent-identity-tab-YGMVWOWT.cjs} +2 -2
- package/dist/{chunk-7EBIKKRM.cjs → chunk-HGSMFQH7.cjs} +1 -5
- package/dist/{chunk-UMNJ5SV6.js → chunk-WUTZ6WUU.js} +1 -5
- package/dist/editor.cjs +2 -2
- package/dist/editor.d.cts +1 -5
- package/dist/editor.d.ts +1 -5
- package/dist/editor.js +1 -1
- package/dist/index.cjs +213 -23
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +213 -23
- package/package.json +1 -1
- package/dist/agent-identity-tab-LROKQ7HM.js +0 -2
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkHGSMFQH7_cjs = require('./chunk-HGSMFQH7.cjs');
|
|
4
4
|
require('./chunk-XXF4U7WL.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "AgentIdentityTab", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkHGSMFQH7_cjs.AgentIdentityTab; }
|
|
11
11
|
});
|
|
@@ -214,11 +214,7 @@ function AgentIdentityTab({
|
|
|
214
214
|
onSave: handleSave,
|
|
215
215
|
title: "SoulSpec",
|
|
216
216
|
saveLabel: saving ? "Saving..." : "Save Identity",
|
|
217
|
-
|
|
218
|
-
newFileTemplate: {
|
|
219
|
-
filename: "CUSTOM.md",
|
|
220
|
-
content: "# Custom\n\nAdd custom identity content...\n"
|
|
221
|
-
},
|
|
217
|
+
fixedStructure: true,
|
|
222
218
|
savedVersion
|
|
223
219
|
}
|
|
224
220
|
) }),
|
|
@@ -212,11 +212,7 @@ function AgentIdentityTab({
|
|
|
212
212
|
onSave: handleSave,
|
|
213
213
|
title: "SoulSpec",
|
|
214
214
|
saveLabel: saving ? "Saving..." : "Save Identity",
|
|
215
|
-
|
|
216
|
-
newFileTemplate: {
|
|
217
|
-
filename: "CUSTOM.md",
|
|
218
|
-
content: "# Custom\n\nAdd custom identity content...\n"
|
|
219
|
-
},
|
|
215
|
+
fixedStructure: true,
|
|
220
216
|
savedVersion
|
|
221
217
|
}
|
|
222
218
|
) }),
|
package/dist/editor.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkVZ43ATC5_cjs = require('./chunk-VZ43ATC5.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkHGSMFQH7_cjs = require('./chunk-HGSMFQH7.cjs');
|
|
5
5
|
var chunkXXF4U7WL_cjs = require('./chunk-XXF4U7WL.cjs');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var CodeMirror = require('@uiw/react-codemirror');
|
|
@@ -187,6 +187,6 @@ Object.defineProperty(exports, "FileTreeEditor", {
|
|
|
187
187
|
});
|
|
188
188
|
Object.defineProperty(exports, "AgentIdentityTab", {
|
|
189
189
|
enumerable: true,
|
|
190
|
-
get: function () { return
|
|
190
|
+
get: function () { return chunkHGSMFQH7_cjs.AgentIdentityTab; }
|
|
191
191
|
});
|
|
192
192
|
exports.PluginEditorPage = PluginEditorPage;
|
package/dist/editor.d.cts
CHANGED
|
@@ -50,12 +50,8 @@ interface AgentIdentityTabProps {
|
|
|
50
50
|
onSave: (files: FlatFile[]) => Promise<void>;
|
|
51
51
|
title?: string;
|
|
52
52
|
saveLabel?: string;
|
|
53
|
-
addFolderLabel?: string;
|
|
54
|
-
newFileTemplate?: {
|
|
55
|
-
filename: string;
|
|
56
|
-
content: string;
|
|
57
|
-
};
|
|
58
53
|
savedVersion?: number;
|
|
54
|
+
fixedStructure?: boolean;
|
|
59
55
|
}>;
|
|
60
56
|
/** Called after a successful save so the host can refresh data. */
|
|
61
57
|
onSaved?: () => void;
|
package/dist/editor.d.ts
CHANGED
|
@@ -50,12 +50,8 @@ interface AgentIdentityTabProps {
|
|
|
50
50
|
onSave: (files: FlatFile[]) => Promise<void>;
|
|
51
51
|
title?: string;
|
|
52
52
|
saveLabel?: string;
|
|
53
|
-
addFolderLabel?: string;
|
|
54
|
-
newFileTemplate?: {
|
|
55
|
-
filename: string;
|
|
56
|
-
content: string;
|
|
57
|
-
};
|
|
58
53
|
savedVersion?: number;
|
|
54
|
+
fixedStructure?: boolean;
|
|
59
55
|
}>;
|
|
60
56
|
/** Called after a successful save so the host can refresh data. */
|
|
61
57
|
onSaved?: () => void;
|
package/dist/editor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useApi, Skeleton, FileTreeEditor, Card, CardHeader, CardTitle, CardContent } from './chunk-CE2RHDPY.js';
|
|
2
2
|
export { FileTreeEditor } from './chunk-CE2RHDPY.js';
|
|
3
|
-
export { AgentIdentityTab } from './chunk-
|
|
3
|
+
export { AgentIdentityTab } from './chunk-WUTZ6WUU.js';
|
|
4
4
|
import { useNavigation, useAgentPlaneClient, Badge, Button } from './chunk-XFI227OB.js';
|
|
5
5
|
import { useState, useCallback } from 'react';
|
|
6
6
|
import CodeMirror from '@uiw/react-codemirror';
|
package/dist/index.cjs
CHANGED
|
@@ -3361,7 +3361,8 @@ function FileTreeEditor2({
|
|
|
3361
3361
|
saveLabel = "Save",
|
|
3362
3362
|
addFolderLabel = "Folder",
|
|
3363
3363
|
newFileTemplate = { filename: "SKILL.md", content: "---\nname: New Skill\ndescription: Describe when this skill should be triggered\n---\n\n# Instructions\n\nDescribe what this skill does...\n" },
|
|
3364
|
-
savedVersion
|
|
3364
|
+
savedVersion,
|
|
3365
|
+
fixedStructure = false
|
|
3365
3366
|
}) {
|
|
3366
3367
|
const [files, setFiles] = React.useState(initialFiles);
|
|
3367
3368
|
const [selectedPath, setSelectedPath] = React.useState(
|
|
@@ -3476,7 +3477,7 @@ function FileTreeEditor2({
|
|
|
3476
3477
|
node.name,
|
|
3477
3478
|
"/"
|
|
3478
3479
|
] }),
|
|
3479
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3480
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3480
3481
|
"button",
|
|
3481
3482
|
{
|
|
3482
3483
|
onClick: (e) => {
|
|
@@ -3502,7 +3503,7 @@ function FileTreeEditor2({
|
|
|
3502
3503
|
onClick: () => setSelectedPath(file.path),
|
|
3503
3504
|
children: [
|
|
3504
3505
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate", children: fileName }),
|
|
3505
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3506
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3506
3507
|
"button",
|
|
3507
3508
|
{
|
|
3508
3509
|
onClick: (e) => {
|
|
@@ -3518,7 +3519,7 @@ function FileTreeEditor2({
|
|
|
3518
3519
|
file.path
|
|
3519
3520
|
);
|
|
3520
3521
|
}),
|
|
3521
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: `${(depth + 1) * 16 + 8}px` }, className: "py-1 pr-2", children: addingFileInDir === node.fullPath ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1", children: [
|
|
3522
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: `${(depth + 1) * 16 + 8}px` }, className: "py-1 pr-2", children: addingFileInDir === node.fullPath ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1", children: [
|
|
3522
3523
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3523
3524
|
chunkXXF4U7WL_cjs.Input,
|
|
3524
3525
|
{
|
|
@@ -3558,7 +3559,7 @@ function FileTreeEditor2({
|
|
|
3558
3559
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-64 shrink-0 border border-border rounded-md overflow-hidden", children: [
|
|
3559
3560
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 bg-muted/50 border-b border-border flex items-center justify-between", children: [
|
|
3560
3561
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: title }),
|
|
3561
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3562
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3562
3563
|
"button",
|
|
3563
3564
|
{
|
|
3564
3565
|
onClick: () => setShowAddFolder(!showAddFolder),
|
|
@@ -3570,7 +3571,7 @@ function FileTreeEditor2({
|
|
|
3570
3571
|
}
|
|
3571
3572
|
)
|
|
3572
3573
|
] }),
|
|
3573
|
-
showAddFolder && !readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 border-b border-border flex gap-1", children: [
|
|
3574
|
+
showAddFolder && !readOnly && !fixedStructure && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 border-b border-border flex gap-1", children: [
|
|
3574
3575
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3575
3576
|
chunkXXF4U7WL_cjs.Input,
|
|
3576
3577
|
{
|
|
@@ -3593,7 +3594,7 @@ function FileTreeEditor2({
|
|
|
3593
3594
|
onClick: () => setSelectedPath(file.path),
|
|
3594
3595
|
children: [
|
|
3595
3596
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate", children: file.path }),
|
|
3596
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3597
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3597
3598
|
"button",
|
|
3598
3599
|
{
|
|
3599
3600
|
onClick: (e) => {
|
|
@@ -3629,17 +3630,193 @@ function FileTreeEditor2({
|
|
|
3629
3630
|
] })
|
|
3630
3631
|
] });
|
|
3631
3632
|
}
|
|
3633
|
+
function TabButton({ label, active, onClick }) {
|
|
3634
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3635
|
+
"button",
|
|
3636
|
+
{
|
|
3637
|
+
onClick,
|
|
3638
|
+
className: `relative pb-2 text-sm font-medium transition-colors ${active ? "text-foreground" : "text-muted-foreground hover:text-foreground"}`,
|
|
3639
|
+
children: [
|
|
3640
|
+
label,
|
|
3641
|
+
active && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground rounded-full" })
|
|
3642
|
+
]
|
|
3643
|
+
}
|
|
3644
|
+
);
|
|
3645
|
+
}
|
|
3646
|
+
function ImportSkillDialog({ open, onOpenChange, onImported, existingFolders }) {
|
|
3647
|
+
const client = chunkXXF4U7WL_cjs.useAgentPlaneClient();
|
|
3648
|
+
const [tab, setTab] = React.useState("all");
|
|
3649
|
+
const [entries, setEntries] = React.useState([]);
|
|
3650
|
+
const [loading, setLoading] = React.useState(false);
|
|
3651
|
+
const [error, setError] = React.useState("");
|
|
3652
|
+
const [search, setSearch] = React.useState("");
|
|
3653
|
+
const [selected, setSelected] = React.useState(null);
|
|
3654
|
+
const [preview, setPreview] = React.useState("");
|
|
3655
|
+
const [previewLoading, setPreviewLoading] = React.useState(false);
|
|
3656
|
+
const [importing, setImporting] = React.useState(false);
|
|
3657
|
+
const [importError, setImportError] = React.useState("");
|
|
3658
|
+
const [url, setUrl] = React.useState("");
|
|
3659
|
+
const [urlImporting, setUrlImporting] = React.useState(false);
|
|
3660
|
+
React.useEffect(() => {
|
|
3661
|
+
if (!open) return;
|
|
3662
|
+
setLoading(true);
|
|
3663
|
+
setError("");
|
|
3664
|
+
setSelected(null);
|
|
3665
|
+
setPreview("");
|
|
3666
|
+
client.skillsDirectory.list(tab).then((data) => setEntries(data)).catch((err) => setError(err instanceof Error ? err.message : "Failed to load skills")).finally(() => setLoading(false));
|
|
3667
|
+
}, [tab, open, client]);
|
|
3668
|
+
const filtered = React.useMemo(() => {
|
|
3669
|
+
if (!search.trim()) return entries;
|
|
3670
|
+
const q = search.toLowerCase();
|
|
3671
|
+
return entries.filter(
|
|
3672
|
+
(e) => e.name.toLowerCase().includes(q) || e.owner.toLowerCase().includes(q) || e.repo.toLowerCase().includes(q)
|
|
3673
|
+
);
|
|
3674
|
+
}, [entries, search]);
|
|
3675
|
+
async function handleSelect(entry) {
|
|
3676
|
+
setSelected(entry);
|
|
3677
|
+
setPreviewLoading(true);
|
|
3678
|
+
setPreview("");
|
|
3679
|
+
setImportError("");
|
|
3680
|
+
try {
|
|
3681
|
+
const content = await client.skillsDirectory.preview(entry.owner, entry.repo, entry.skill);
|
|
3682
|
+
setPreview(content);
|
|
3683
|
+
} catch (err) {
|
|
3684
|
+
setPreview(`Failed to load preview: ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
3685
|
+
} finally {
|
|
3686
|
+
setPreviewLoading(false);
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
async function handleImport() {
|
|
3690
|
+
if (!selected) return;
|
|
3691
|
+
setImporting(true);
|
|
3692
|
+
setImportError("");
|
|
3693
|
+
try {
|
|
3694
|
+
const result = await client.skillsDirectory.import({
|
|
3695
|
+
owner: selected.owner,
|
|
3696
|
+
repo: selected.repo,
|
|
3697
|
+
skill_name: selected.skill
|
|
3698
|
+
});
|
|
3699
|
+
if (existingFolders.includes(result.folder)) {
|
|
3700
|
+
setImportError(`Skill folder "${result.folder}" already exists. Remove it first or rename.`);
|
|
3701
|
+
return;
|
|
3702
|
+
}
|
|
3703
|
+
if (result.warnings.length > 0) {
|
|
3704
|
+
setImportError(`Imported with warnings: ${result.warnings.join("; ")}`);
|
|
3705
|
+
}
|
|
3706
|
+
onImported({ folder: result.folder, files: result.files });
|
|
3707
|
+
onOpenChange(false);
|
|
3708
|
+
resetState();
|
|
3709
|
+
} catch (err) {
|
|
3710
|
+
setImportError(err instanceof Error ? err.message : "Failed to import skill");
|
|
3711
|
+
} finally {
|
|
3712
|
+
setImporting(false);
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
async function handleUrlImport() {
|
|
3716
|
+
if (!url.trim()) return;
|
|
3717
|
+
setUrlImporting(true);
|
|
3718
|
+
setImportError("");
|
|
3719
|
+
try {
|
|
3720
|
+
const result = await client.skillsDirectory.import({ url: url.trim() });
|
|
3721
|
+
if (existingFolders.includes(result.folder)) {
|
|
3722
|
+
setImportError(`Skill folder "${result.folder}" already exists. Remove it first or rename.`);
|
|
3723
|
+
return;
|
|
3724
|
+
}
|
|
3725
|
+
onImported({ folder: result.folder, files: result.files });
|
|
3726
|
+
onOpenChange(false);
|
|
3727
|
+
resetState();
|
|
3728
|
+
} catch (err) {
|
|
3729
|
+
setImportError(err instanceof Error ? err.message : "Failed to import skill");
|
|
3730
|
+
} finally {
|
|
3731
|
+
setUrlImporting(false);
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
function resetState() {
|
|
3735
|
+
setTab("all");
|
|
3736
|
+
setSearch("");
|
|
3737
|
+
setSelected(null);
|
|
3738
|
+
setPreview("");
|
|
3739
|
+
setUrl("");
|
|
3740
|
+
setError("");
|
|
3741
|
+
setImportError("");
|
|
3742
|
+
}
|
|
3743
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Dialog, { open, onOpenChange: (v) => {
|
|
3744
|
+
onOpenChange(v);
|
|
3745
|
+
if (!v) resetState();
|
|
3746
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkXXF4U7WL_cjs.DialogContent, { className: "max-w-2xl max-h-[80vh] flex flex-col", children: [
|
|
3747
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkXXF4U7WL_cjs.DialogHeader, { children: [
|
|
3748
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.DialogTitle, { children: "Import from skills.sh" }),
|
|
3749
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.DialogDescription, { children: "Browse the open skills directory and import skills into this agent." })
|
|
3750
|
+
] }),
|
|
3751
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkXXF4U7WL_cjs.DialogBody, { className: "flex-1 overflow-hidden flex flex-col gap-4", children: [
|
|
3752
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
|
|
3753
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabButton, { label: "All Time", active: tab === "all", onClick: () => setTab("all") }),
|
|
3754
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabButton, { label: "Trending", active: tab === "trending", onClick: () => setTab("trending") }),
|
|
3755
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabButton, { label: "Hot", active: tab === "hot", onClick: () => setTab("hot") })
|
|
3756
|
+
] }),
|
|
3757
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Input, { placeholder: "Search skills...", value: search, onChange: (e) => setSearch(e.target.value) }),
|
|
3758
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: error }),
|
|
3759
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex gap-4 min-h-0", children: [
|
|
3760
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1/2 overflow-y-auto border border-muted-foreground/25 rounded-lg", children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-sm text-muted-foreground", children: "Loading skills..." }) : filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-sm text-muted-foreground", children: search ? "No skills match your search" : "No skills found" }) : filtered.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3761
|
+
"button",
|
|
3762
|
+
{
|
|
3763
|
+
onClick: () => handleSelect(entry),
|
|
3764
|
+
className: `w-full text-left px-3 py-2 border-b border-muted-foreground/10 hover:bg-muted/50 transition-colors ${selected?.skill === entry.skill && selected?.owner === entry.owner ? "bg-muted/50" : ""}`,
|
|
3765
|
+
children: [
|
|
3766
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm truncate", children: entry.name }),
|
|
3767
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
3768
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground truncate", children: [
|
|
3769
|
+
entry.owner,
|
|
3770
|
+
"/",
|
|
3771
|
+
entry.repo
|
|
3772
|
+
] }),
|
|
3773
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground font-mono ml-2 shrink-0", children: entry.installs })
|
|
3774
|
+
] })
|
|
3775
|
+
]
|
|
3776
|
+
},
|
|
3777
|
+
`${entry.owner}/${entry.repo}/${entry.skill}`
|
|
3778
|
+
)) }),
|
|
3779
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1/2 overflow-y-auto border border-muted-foreground/25 rounded-lg p-3", children: !selected ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: "Select a skill to preview" }) : previewLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: "Loading preview..." }) : /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs whitespace-pre-wrap break-words font-mono", children: preview }) })
|
|
3780
|
+
] }),
|
|
3781
|
+
importError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: importError }),
|
|
3782
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-muted-foreground/25 pt-3", children: /* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.FormField, { label: "Or paste a skills.sh URL", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
3783
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3784
|
+
chunkXXF4U7WL_cjs.Input,
|
|
3785
|
+
{
|
|
3786
|
+
value: url,
|
|
3787
|
+
onChange: (e) => setUrl(e.target.value),
|
|
3788
|
+
placeholder: "skills.sh/owner/repo/skill",
|
|
3789
|
+
onKeyDown: (e) => e.key === "Enter" && handleUrlImport(),
|
|
3790
|
+
className: "flex-1"
|
|
3791
|
+
}
|
|
3792
|
+
),
|
|
3793
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Button, { size: "sm", variant: "outline", onClick: handleUrlImport, disabled: urlImporting || !url.trim(), children: urlImporting ? "Importing..." : "Import URL" })
|
|
3794
|
+
] }) }) })
|
|
3795
|
+
] }),
|
|
3796
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkXXF4U7WL_cjs.DialogFooter, { children: [
|
|
3797
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Button, { variant: "outline", size: "sm", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
3798
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Button, { size: "sm", onClick: handleImport, disabled: !selected || importing || previewLoading, children: importing ? "Importing..." : "Import Selected" })
|
|
3799
|
+
] })
|
|
3800
|
+
] }) });
|
|
3801
|
+
}
|
|
3632
3802
|
function AgentSkillManager({ agentId, initialSkills, onSaved }) {
|
|
3633
3803
|
const client = chunkXXF4U7WL_cjs.useAgentPlaneClient();
|
|
3804
|
+
const [importOpen, setImportOpen] = React.useState(false);
|
|
3805
|
+
const [extraSkills, setExtraSkills] = React.useState([]);
|
|
3806
|
+
const allSkills = React.useMemo(() => [...initialSkills, ...extraSkills], [initialSkills, extraSkills]);
|
|
3634
3807
|
const initialFiles = React.useMemo(
|
|
3635
|
-
() =>
|
|
3808
|
+
() => allSkills.flatMap(
|
|
3636
3809
|
(s) => s.files.map((f) => ({
|
|
3637
3810
|
path: s.folder === "(root)" ? f.path : `${s.folder}/${f.path}`,
|
|
3638
3811
|
content: f.content
|
|
3639
3812
|
}))
|
|
3640
3813
|
),
|
|
3641
|
-
[
|
|
3814
|
+
[allSkills]
|
|
3642
3815
|
);
|
|
3816
|
+
const existingFolders = React.useMemo(() => allSkills.map((s) => s.folder), [allSkills]);
|
|
3817
|
+
const handleImported = React.useCallback((skill) => {
|
|
3818
|
+
setExtraSkills((prev) => [...prev, skill]);
|
|
3819
|
+
}, []);
|
|
3643
3820
|
const handleSave = React.useCallback(async (files) => {
|
|
3644
3821
|
const folderMap = /* @__PURE__ */ new Map();
|
|
3645
3822
|
for (const file of files) {
|
|
@@ -3658,22 +3835,35 @@ function AgentSkillManager({ agentId, initialSkills, onSaved }) {
|
|
|
3658
3835
|
}
|
|
3659
3836
|
const skills = Array.from(folderMap.entries()).map(([folder, files2]) => ({ folder, files: files2 }));
|
|
3660
3837
|
await client.agents.update(agentId, { skills });
|
|
3838
|
+
setExtraSkills([]);
|
|
3661
3839
|
onSaved?.();
|
|
3662
3840
|
}, [agentId, client, onSaved]);
|
|
3663
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3841
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3842
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Button, { size: "sm", variant: "outline", onClick: () => setImportOpen(true), children: "Import from skills.sh" }) }),
|
|
3843
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3844
|
+
FileTreeEditor2,
|
|
3845
|
+
{
|
|
3846
|
+
initialFiles,
|
|
3847
|
+
onSave: handleSave,
|
|
3848
|
+
title: "Skills",
|
|
3849
|
+
saveLabel: "Save Skills",
|
|
3850
|
+
addFolderLabel: "Skill",
|
|
3851
|
+
newFileTemplate: {
|
|
3852
|
+
filename: "SKILL.md",
|
|
3853
|
+
content: "---\nname: New Skill\ndescription: Describe when this skill should be triggered\n---\n\n# Instructions\n\nDescribe what this skill does...\n"
|
|
3854
|
+
}
|
|
3674
3855
|
}
|
|
3675
|
-
|
|
3676
|
-
|
|
3856
|
+
),
|
|
3857
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3858
|
+
ImportSkillDialog,
|
|
3859
|
+
{
|
|
3860
|
+
open: importOpen,
|
|
3861
|
+
onOpenChange: setImportOpen,
|
|
3862
|
+
onImported: handleImported,
|
|
3863
|
+
existingFolders
|
|
3864
|
+
}
|
|
3865
|
+
)
|
|
3866
|
+
] });
|
|
3677
3867
|
}
|
|
3678
3868
|
function AgentPluginManager({ agentId, initialPlugins, onSaved }) {
|
|
3679
3869
|
const client = chunkXXF4U7WL_cjs.useAgentPlaneClient();
|
|
@@ -4069,7 +4259,7 @@ function AgentA2aInfo({
|
|
|
4069
4259
|
] })
|
|
4070
4260
|
] });
|
|
4071
4261
|
}
|
|
4072
|
-
var AgentIdentityTab = React.lazy(() => import('./agent-identity-tab-
|
|
4262
|
+
var AgentIdentityTab = React.lazy(() => import('./agent-identity-tab-YGMVWOWT.cjs').then((m) => ({ default: m.AgentIdentityTab })));
|
|
4073
4263
|
function AgentDetailPage({ agentId, a2aBaseUrl, tenantSlug, adminApiBaseUrl, adminApiKey }) {
|
|
4074
4264
|
const { LinkComponent, basePath } = chunkXXF4U7WL_cjs.useNavigation();
|
|
4075
4265
|
const { mutate } = swr.useSWRConfig();
|
package/dist/index.d.cts
CHANGED
|
@@ -7,6 +7,22 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
|
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
8
8
|
import { DailyAgentStat } from './charts.cjs';
|
|
9
9
|
|
|
10
|
+
/** Skills directory types. */
|
|
11
|
+
interface SkillDirectoryEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
owner: string;
|
|
14
|
+
repo: string;
|
|
15
|
+
skill: string;
|
|
16
|
+
installs: string;
|
|
17
|
+
}
|
|
18
|
+
interface ImportedSkillResult {
|
|
19
|
+
folder: string;
|
|
20
|
+
files: Array<{
|
|
21
|
+
path: string;
|
|
22
|
+
content: string;
|
|
23
|
+
}>;
|
|
24
|
+
warnings: string[];
|
|
25
|
+
}
|
|
10
26
|
/** Minimal stream event types used by the playground UI. */
|
|
11
27
|
interface PlaygroundTextDeltaEvent {
|
|
12
28
|
type: "text_delta";
|
|
@@ -155,6 +171,17 @@ interface AgentPlaneClient {
|
|
|
155
171
|
toolkits(): Promise<unknown[]>;
|
|
156
172
|
tools(toolkit: string): Promise<unknown[]>;
|
|
157
173
|
};
|
|
174
|
+
skillsDirectory: {
|
|
175
|
+
list(tab?: "all" | "trending" | "hot"): Promise<SkillDirectoryEntry[]>;
|
|
176
|
+
preview(owner: string, repo: string, skill: string): Promise<string>;
|
|
177
|
+
import(params: {
|
|
178
|
+
owner: string;
|
|
179
|
+
repo: string;
|
|
180
|
+
skill_name: string;
|
|
181
|
+
} | {
|
|
182
|
+
url: string;
|
|
183
|
+
}): Promise<ImportedSkillResult>;
|
|
184
|
+
};
|
|
158
185
|
pluginMarketplaces: {
|
|
159
186
|
list(): Promise<unknown[]>;
|
|
160
187
|
get(marketplaceId: string): Promise<unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,22 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
|
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
8
8
|
import { DailyAgentStat } from './charts.js';
|
|
9
9
|
|
|
10
|
+
/** Skills directory types. */
|
|
11
|
+
interface SkillDirectoryEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
owner: string;
|
|
14
|
+
repo: string;
|
|
15
|
+
skill: string;
|
|
16
|
+
installs: string;
|
|
17
|
+
}
|
|
18
|
+
interface ImportedSkillResult {
|
|
19
|
+
folder: string;
|
|
20
|
+
files: Array<{
|
|
21
|
+
path: string;
|
|
22
|
+
content: string;
|
|
23
|
+
}>;
|
|
24
|
+
warnings: string[];
|
|
25
|
+
}
|
|
10
26
|
/** Minimal stream event types used by the playground UI. */
|
|
11
27
|
interface PlaygroundTextDeltaEvent {
|
|
12
28
|
type: "text_delta";
|
|
@@ -155,6 +171,17 @@ interface AgentPlaneClient {
|
|
|
155
171
|
toolkits(): Promise<unknown[]>;
|
|
156
172
|
tools(toolkit: string): Promise<unknown[]>;
|
|
157
173
|
};
|
|
174
|
+
skillsDirectory: {
|
|
175
|
+
list(tab?: "all" | "trending" | "hot"): Promise<SkillDirectoryEntry[]>;
|
|
176
|
+
preview(owner: string, repo: string, skill: string): Promise<string>;
|
|
177
|
+
import(params: {
|
|
178
|
+
owner: string;
|
|
179
|
+
repo: string;
|
|
180
|
+
skill_name: string;
|
|
181
|
+
} | {
|
|
182
|
+
url: string;
|
|
183
|
+
}): Promise<ImportedSkillResult>;
|
|
184
|
+
};
|
|
158
185
|
pluginMarketplaces: {
|
|
159
186
|
list(): Promise<unknown[]>;
|
|
160
187
|
get(marketplaceId: string): Promise<unknown>;
|
package/dist/index.js
CHANGED
|
@@ -3337,7 +3337,8 @@ function FileTreeEditor2({
|
|
|
3337
3337
|
saveLabel = "Save",
|
|
3338
3338
|
addFolderLabel = "Folder",
|
|
3339
3339
|
newFileTemplate = { filename: "SKILL.md", content: "---\nname: New Skill\ndescription: Describe when this skill should be triggered\n---\n\n# Instructions\n\nDescribe what this skill does...\n" },
|
|
3340
|
-
savedVersion
|
|
3340
|
+
savedVersion,
|
|
3341
|
+
fixedStructure = false
|
|
3341
3342
|
}) {
|
|
3342
3343
|
const [files, setFiles] = useState(initialFiles);
|
|
3343
3344
|
const [selectedPath, setSelectedPath] = useState(
|
|
@@ -3452,7 +3453,7 @@ function FileTreeEditor2({
|
|
|
3452
3453
|
node.name,
|
|
3453
3454
|
"/"
|
|
3454
3455
|
] }),
|
|
3455
|
-
!readOnly && /* @__PURE__ */ jsx(
|
|
3456
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsx(
|
|
3456
3457
|
"button",
|
|
3457
3458
|
{
|
|
3458
3459
|
onClick: (e) => {
|
|
@@ -3478,7 +3479,7 @@ function FileTreeEditor2({
|
|
|
3478
3479
|
onClick: () => setSelectedPath(file.path),
|
|
3479
3480
|
children: [
|
|
3480
3481
|
/* @__PURE__ */ jsx("span", { className: "text-xs truncate", children: fileName }),
|
|
3481
|
-
!readOnly && /* @__PURE__ */ jsx(
|
|
3482
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsx(
|
|
3482
3483
|
"button",
|
|
3483
3484
|
{
|
|
3484
3485
|
onClick: (e) => {
|
|
@@ -3494,7 +3495,7 @@ function FileTreeEditor2({
|
|
|
3494
3495
|
file.path
|
|
3495
3496
|
);
|
|
3496
3497
|
}),
|
|
3497
|
-
!readOnly && /* @__PURE__ */ jsx("div", { style: { paddingLeft: `${(depth + 1) * 16 + 8}px` }, className: "py-1 pr-2", children: addingFileInDir === node.fullPath ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
|
|
3498
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsx("div", { style: { paddingLeft: `${(depth + 1) * 16 + 8}px` }, className: "py-1 pr-2", children: addingFileInDir === node.fullPath ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
|
|
3498
3499
|
/* @__PURE__ */ jsx(
|
|
3499
3500
|
Input,
|
|
3500
3501
|
{
|
|
@@ -3534,7 +3535,7 @@ function FileTreeEditor2({
|
|
|
3534
3535
|
/* @__PURE__ */ jsxs("div", { className: "w-64 shrink-0 border border-border rounded-md overflow-hidden", children: [
|
|
3535
3536
|
/* @__PURE__ */ jsxs("div", { className: "p-2 bg-muted/50 border-b border-border flex items-center justify-between", children: [
|
|
3536
3537
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: title }),
|
|
3537
|
-
!readOnly && /* @__PURE__ */ jsxs(
|
|
3538
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsxs(
|
|
3538
3539
|
"button",
|
|
3539
3540
|
{
|
|
3540
3541
|
onClick: () => setShowAddFolder(!showAddFolder),
|
|
@@ -3546,7 +3547,7 @@ function FileTreeEditor2({
|
|
|
3546
3547
|
}
|
|
3547
3548
|
)
|
|
3548
3549
|
] }),
|
|
3549
|
-
showAddFolder && !readOnly && /* @__PURE__ */ jsxs("div", { className: "p-2 border-b border-border flex gap-1", children: [
|
|
3550
|
+
showAddFolder && !readOnly && !fixedStructure && /* @__PURE__ */ jsxs("div", { className: "p-2 border-b border-border flex gap-1", children: [
|
|
3550
3551
|
/* @__PURE__ */ jsx(
|
|
3551
3552
|
Input,
|
|
3552
3553
|
{
|
|
@@ -3569,7 +3570,7 @@ function FileTreeEditor2({
|
|
|
3569
3570
|
onClick: () => setSelectedPath(file.path),
|
|
3570
3571
|
children: [
|
|
3571
3572
|
/* @__PURE__ */ jsx("span", { className: "text-xs truncate", children: file.path }),
|
|
3572
|
-
!readOnly && /* @__PURE__ */ jsx(
|
|
3573
|
+
!readOnly && !fixedStructure && /* @__PURE__ */ jsx(
|
|
3573
3574
|
"button",
|
|
3574
3575
|
{
|
|
3575
3576
|
onClick: (e) => {
|
|
@@ -3605,17 +3606,193 @@ function FileTreeEditor2({
|
|
|
3605
3606
|
] })
|
|
3606
3607
|
] });
|
|
3607
3608
|
}
|
|
3609
|
+
function TabButton({ label, active, onClick }) {
|
|
3610
|
+
return /* @__PURE__ */ jsxs(
|
|
3611
|
+
"button",
|
|
3612
|
+
{
|
|
3613
|
+
onClick,
|
|
3614
|
+
className: `relative pb-2 text-sm font-medium transition-colors ${active ? "text-foreground" : "text-muted-foreground hover:text-foreground"}`,
|
|
3615
|
+
children: [
|
|
3616
|
+
label,
|
|
3617
|
+
active && /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 bottom-0 h-0.5 bg-foreground rounded-full" })
|
|
3618
|
+
]
|
|
3619
|
+
}
|
|
3620
|
+
);
|
|
3621
|
+
}
|
|
3622
|
+
function ImportSkillDialog({ open, onOpenChange, onImported, existingFolders }) {
|
|
3623
|
+
const client = useAgentPlaneClient();
|
|
3624
|
+
const [tab, setTab] = useState("all");
|
|
3625
|
+
const [entries, setEntries] = useState([]);
|
|
3626
|
+
const [loading, setLoading] = useState(false);
|
|
3627
|
+
const [error, setError] = useState("");
|
|
3628
|
+
const [search, setSearch] = useState("");
|
|
3629
|
+
const [selected, setSelected] = useState(null);
|
|
3630
|
+
const [preview, setPreview] = useState("");
|
|
3631
|
+
const [previewLoading, setPreviewLoading] = useState(false);
|
|
3632
|
+
const [importing, setImporting] = useState(false);
|
|
3633
|
+
const [importError, setImportError] = useState("");
|
|
3634
|
+
const [url, setUrl] = useState("");
|
|
3635
|
+
const [urlImporting, setUrlImporting] = useState(false);
|
|
3636
|
+
useEffect(() => {
|
|
3637
|
+
if (!open) return;
|
|
3638
|
+
setLoading(true);
|
|
3639
|
+
setError("");
|
|
3640
|
+
setSelected(null);
|
|
3641
|
+
setPreview("");
|
|
3642
|
+
client.skillsDirectory.list(tab).then((data) => setEntries(data)).catch((err) => setError(err instanceof Error ? err.message : "Failed to load skills")).finally(() => setLoading(false));
|
|
3643
|
+
}, [tab, open, client]);
|
|
3644
|
+
const filtered = useMemo(() => {
|
|
3645
|
+
if (!search.trim()) return entries;
|
|
3646
|
+
const q = search.toLowerCase();
|
|
3647
|
+
return entries.filter(
|
|
3648
|
+
(e) => e.name.toLowerCase().includes(q) || e.owner.toLowerCase().includes(q) || e.repo.toLowerCase().includes(q)
|
|
3649
|
+
);
|
|
3650
|
+
}, [entries, search]);
|
|
3651
|
+
async function handleSelect(entry) {
|
|
3652
|
+
setSelected(entry);
|
|
3653
|
+
setPreviewLoading(true);
|
|
3654
|
+
setPreview("");
|
|
3655
|
+
setImportError("");
|
|
3656
|
+
try {
|
|
3657
|
+
const content = await client.skillsDirectory.preview(entry.owner, entry.repo, entry.skill);
|
|
3658
|
+
setPreview(content);
|
|
3659
|
+
} catch (err) {
|
|
3660
|
+
setPreview(`Failed to load preview: ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
3661
|
+
} finally {
|
|
3662
|
+
setPreviewLoading(false);
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
async function handleImport() {
|
|
3666
|
+
if (!selected) return;
|
|
3667
|
+
setImporting(true);
|
|
3668
|
+
setImportError("");
|
|
3669
|
+
try {
|
|
3670
|
+
const result = await client.skillsDirectory.import({
|
|
3671
|
+
owner: selected.owner,
|
|
3672
|
+
repo: selected.repo,
|
|
3673
|
+
skill_name: selected.skill
|
|
3674
|
+
});
|
|
3675
|
+
if (existingFolders.includes(result.folder)) {
|
|
3676
|
+
setImportError(`Skill folder "${result.folder}" already exists. Remove it first or rename.`);
|
|
3677
|
+
return;
|
|
3678
|
+
}
|
|
3679
|
+
if (result.warnings.length > 0) {
|
|
3680
|
+
setImportError(`Imported with warnings: ${result.warnings.join("; ")}`);
|
|
3681
|
+
}
|
|
3682
|
+
onImported({ folder: result.folder, files: result.files });
|
|
3683
|
+
onOpenChange(false);
|
|
3684
|
+
resetState();
|
|
3685
|
+
} catch (err) {
|
|
3686
|
+
setImportError(err instanceof Error ? err.message : "Failed to import skill");
|
|
3687
|
+
} finally {
|
|
3688
|
+
setImporting(false);
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3691
|
+
async function handleUrlImport() {
|
|
3692
|
+
if (!url.trim()) return;
|
|
3693
|
+
setUrlImporting(true);
|
|
3694
|
+
setImportError("");
|
|
3695
|
+
try {
|
|
3696
|
+
const result = await client.skillsDirectory.import({ url: url.trim() });
|
|
3697
|
+
if (existingFolders.includes(result.folder)) {
|
|
3698
|
+
setImportError(`Skill folder "${result.folder}" already exists. Remove it first or rename.`);
|
|
3699
|
+
return;
|
|
3700
|
+
}
|
|
3701
|
+
onImported({ folder: result.folder, files: result.files });
|
|
3702
|
+
onOpenChange(false);
|
|
3703
|
+
resetState();
|
|
3704
|
+
} catch (err) {
|
|
3705
|
+
setImportError(err instanceof Error ? err.message : "Failed to import skill");
|
|
3706
|
+
} finally {
|
|
3707
|
+
setUrlImporting(false);
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
function resetState() {
|
|
3711
|
+
setTab("all");
|
|
3712
|
+
setSearch("");
|
|
3713
|
+
setSelected(null);
|
|
3714
|
+
setPreview("");
|
|
3715
|
+
setUrl("");
|
|
3716
|
+
setError("");
|
|
3717
|
+
setImportError("");
|
|
3718
|
+
}
|
|
3719
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (v) => {
|
|
3720
|
+
onOpenChange(v);
|
|
3721
|
+
if (!v) resetState();
|
|
3722
|
+
}, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-2xl max-h-[80vh] flex flex-col", children: [
|
|
3723
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
3724
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Import from skills.sh" }),
|
|
3725
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "Browse the open skills directory and import skills into this agent." })
|
|
3726
|
+
] }),
|
|
3727
|
+
/* @__PURE__ */ jsxs(DialogBody, { className: "flex-1 overflow-hidden flex flex-col gap-4", children: [
|
|
3728
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
3729
|
+
/* @__PURE__ */ jsx(TabButton, { label: "All Time", active: tab === "all", onClick: () => setTab("all") }),
|
|
3730
|
+
/* @__PURE__ */ jsx(TabButton, { label: "Trending", active: tab === "trending", onClick: () => setTab("trending") }),
|
|
3731
|
+
/* @__PURE__ */ jsx(TabButton, { label: "Hot", active: tab === "hot", onClick: () => setTab("hot") })
|
|
3732
|
+
] }),
|
|
3733
|
+
/* @__PURE__ */ jsx(Input, { placeholder: "Search skills...", value: search, onChange: (e) => setSearch(e.target.value) }),
|
|
3734
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error }),
|
|
3735
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-hidden flex gap-4 min-h-0", children: [
|
|
3736
|
+
/* @__PURE__ */ jsx("div", { className: "w-1/2 overflow-y-auto border border-muted-foreground/25 rounded-lg", children: loading ? /* @__PURE__ */ jsx("div", { className: "p-4 text-sm text-muted-foreground", children: "Loading skills..." }) : filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-sm text-muted-foreground", children: search ? "No skills match your search" : "No skills found" }) : filtered.map((entry) => /* @__PURE__ */ jsxs(
|
|
3737
|
+
"button",
|
|
3738
|
+
{
|
|
3739
|
+
onClick: () => handleSelect(entry),
|
|
3740
|
+
className: `w-full text-left px-3 py-2 border-b border-muted-foreground/10 hover:bg-muted/50 transition-colors ${selected?.skill === entry.skill && selected?.owner === entry.owner ? "bg-muted/50" : ""}`,
|
|
3741
|
+
children: [
|
|
3742
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-sm truncate", children: entry.name }),
|
|
3743
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center", children: [
|
|
3744
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground truncate", children: [
|
|
3745
|
+
entry.owner,
|
|
3746
|
+
"/",
|
|
3747
|
+
entry.repo
|
|
3748
|
+
] }),
|
|
3749
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground font-mono ml-2 shrink-0", children: entry.installs })
|
|
3750
|
+
] })
|
|
3751
|
+
]
|
|
3752
|
+
},
|
|
3753
|
+
`${entry.owner}/${entry.repo}/${entry.skill}`
|
|
3754
|
+
)) }),
|
|
3755
|
+
/* @__PURE__ */ jsx("div", { className: "w-1/2 overflow-y-auto border border-muted-foreground/25 rounded-lg p-3", children: !selected ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "Select a skill to preview" }) : previewLoading ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "Loading preview..." }) : /* @__PURE__ */ jsx("pre", { className: "text-xs whitespace-pre-wrap break-words font-mono", children: preview }) })
|
|
3756
|
+
] }),
|
|
3757
|
+
importError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: importError }),
|
|
3758
|
+
/* @__PURE__ */ jsx("div", { className: "border-t border-muted-foreground/25 pt-3", children: /* @__PURE__ */ jsx(FormField, { label: "Or paste a skills.sh URL", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
3759
|
+
/* @__PURE__ */ jsx(
|
|
3760
|
+
Input,
|
|
3761
|
+
{
|
|
3762
|
+
value: url,
|
|
3763
|
+
onChange: (e) => setUrl(e.target.value),
|
|
3764
|
+
placeholder: "skills.sh/owner/repo/skill",
|
|
3765
|
+
onKeyDown: (e) => e.key === "Enter" && handleUrlImport(),
|
|
3766
|
+
className: "flex-1"
|
|
3767
|
+
}
|
|
3768
|
+
),
|
|
3769
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", variant: "outline", onClick: handleUrlImport, disabled: urlImporting || !url.trim(), children: urlImporting ? "Importing..." : "Import URL" })
|
|
3770
|
+
] }) }) })
|
|
3771
|
+
] }),
|
|
3772
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
3773
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
3774
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", onClick: handleImport, disabled: !selected || importing || previewLoading, children: importing ? "Importing..." : "Import Selected" })
|
|
3775
|
+
] })
|
|
3776
|
+
] }) });
|
|
3777
|
+
}
|
|
3608
3778
|
function AgentSkillManager({ agentId, initialSkills, onSaved }) {
|
|
3609
3779
|
const client = useAgentPlaneClient();
|
|
3780
|
+
const [importOpen, setImportOpen] = useState(false);
|
|
3781
|
+
const [extraSkills, setExtraSkills] = useState([]);
|
|
3782
|
+
const allSkills = useMemo(() => [...initialSkills, ...extraSkills], [initialSkills, extraSkills]);
|
|
3610
3783
|
const initialFiles = useMemo(
|
|
3611
|
-
() =>
|
|
3784
|
+
() => allSkills.flatMap(
|
|
3612
3785
|
(s) => s.files.map((f) => ({
|
|
3613
3786
|
path: s.folder === "(root)" ? f.path : `${s.folder}/${f.path}`,
|
|
3614
3787
|
content: f.content
|
|
3615
3788
|
}))
|
|
3616
3789
|
),
|
|
3617
|
-
[
|
|
3790
|
+
[allSkills]
|
|
3618
3791
|
);
|
|
3792
|
+
const existingFolders = useMemo(() => allSkills.map((s) => s.folder), [allSkills]);
|
|
3793
|
+
const handleImported = useCallback((skill) => {
|
|
3794
|
+
setExtraSkills((prev) => [...prev, skill]);
|
|
3795
|
+
}, []);
|
|
3619
3796
|
const handleSave = useCallback(async (files) => {
|
|
3620
3797
|
const folderMap = /* @__PURE__ */ new Map();
|
|
3621
3798
|
for (const file of files) {
|
|
@@ -3634,22 +3811,35 @@ function AgentSkillManager({ agentId, initialSkills, onSaved }) {
|
|
|
3634
3811
|
}
|
|
3635
3812
|
const skills = Array.from(folderMap.entries()).map(([folder, files2]) => ({ folder, files: files2 }));
|
|
3636
3813
|
await client.agents.update(agentId, { skills });
|
|
3814
|
+
setExtraSkills([]);
|
|
3637
3815
|
onSaved?.();
|
|
3638
3816
|
}, [agentId, client, onSaved]);
|
|
3639
|
-
return /* @__PURE__ */
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3817
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3818
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsx(Button, { size: "sm", variant: "outline", onClick: () => setImportOpen(true), children: "Import from skills.sh" }) }),
|
|
3819
|
+
/* @__PURE__ */ jsx(
|
|
3820
|
+
FileTreeEditor2,
|
|
3821
|
+
{
|
|
3822
|
+
initialFiles,
|
|
3823
|
+
onSave: handleSave,
|
|
3824
|
+
title: "Skills",
|
|
3825
|
+
saveLabel: "Save Skills",
|
|
3826
|
+
addFolderLabel: "Skill",
|
|
3827
|
+
newFileTemplate: {
|
|
3828
|
+
filename: "SKILL.md",
|
|
3829
|
+
content: "---\nname: New Skill\ndescription: Describe when this skill should be triggered\n---\n\n# Instructions\n\nDescribe what this skill does...\n"
|
|
3830
|
+
}
|
|
3650
3831
|
}
|
|
3651
|
-
|
|
3652
|
-
|
|
3832
|
+
),
|
|
3833
|
+
/* @__PURE__ */ jsx(
|
|
3834
|
+
ImportSkillDialog,
|
|
3835
|
+
{
|
|
3836
|
+
open: importOpen,
|
|
3837
|
+
onOpenChange: setImportOpen,
|
|
3838
|
+
onImported: handleImported,
|
|
3839
|
+
existingFolders
|
|
3840
|
+
}
|
|
3841
|
+
)
|
|
3842
|
+
] });
|
|
3653
3843
|
}
|
|
3654
3844
|
function AgentPluginManager({ agentId, initialPlugins, onSaved }) {
|
|
3655
3845
|
const client = useAgentPlaneClient();
|
|
@@ -4045,7 +4235,7 @@ function AgentA2aInfo({
|
|
|
4045
4235
|
] })
|
|
4046
4236
|
] });
|
|
4047
4237
|
}
|
|
4048
|
-
var AgentIdentityTab = lazy(() => import('./agent-identity-tab-
|
|
4238
|
+
var AgentIdentityTab = lazy(() => import('./agent-identity-tab-BP5MPDYZ.js').then((m) => ({ default: m.AgentIdentityTab })));
|
|
4049
4239
|
function AgentDetailPage({ agentId, a2aBaseUrl, tenantSlug, adminApiBaseUrl, adminApiKey }) {
|
|
4050
4240
|
const { LinkComponent, basePath } = useNavigation();
|
|
4051
4241
|
const { mutate } = useSWRConfig();
|
package/package.json
CHANGED