@getcatalystiq/agent-plane-ui 0.1.18 → 0.1.20
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-ETPM6LQN.js +2 -0
- package/dist/agent-identity-tab-F4MU2HP2.cjs +11 -0
- package/dist/chunk-CE2RHDPY.js +422 -0
- package/dist/chunk-CHJL4MZI.cjs +277 -0
- package/dist/chunk-L45SI32F.js +275 -0
- package/dist/chunk-VZ43ATC5.cjs +454 -0
- package/dist/{chunk-P4N2P42X.js → chunk-XFI227OB.js} +77 -46
- package/dist/{chunk-4XBBDUSZ.cjs → chunk-XXF4U7WL.cjs} +93 -64
- package/dist/editor.cjs +26 -387
- package/dist/editor.d.cts +50 -1
- package/dist/editor.d.ts +50 -1
- package/dist/editor.js +7 -374
- package/dist/index.cjs +583 -666
- package/dist/index.d.cts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +19 -125
- package/package.json +1 -1
package/dist/editor.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkVZ43ATC5_cjs = require('./chunk-VZ43ATC5.cjs');
|
|
4
|
+
var chunkCHJL4MZI_cjs = require('./chunk-CHJL4MZI.cjs');
|
|
5
|
+
var chunkXXF4U7WL_cjs = require('./chunk-XXF4U7WL.cjs');
|
|
4
6
|
var react = require('react');
|
|
5
7
|
var CodeMirror = require('@uiw/react-codemirror');
|
|
6
|
-
var langMarkdown = require('@codemirror/lang-markdown');
|
|
7
|
-
var langJavascript = require('@codemirror/lang-javascript');
|
|
8
8
|
var langJson = require('@codemirror/lang-json');
|
|
9
9
|
var themeOneDark = require('@codemirror/theme-one-dark');
|
|
10
10
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -13,378 +13,10 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
13
13
|
|
|
14
14
|
var CodeMirror__default = /*#__PURE__*/_interopDefault(CodeMirror);
|
|
15
15
|
|
|
16
|
-
function getLanguageExtension(filename) {
|
|
17
|
-
const ext = filename.split(".").pop()?.toLowerCase();
|
|
18
|
-
switch (ext) {
|
|
19
|
-
case "md":
|
|
20
|
-
return [langMarkdown.markdown()];
|
|
21
|
-
case "json":
|
|
22
|
-
return [langJson.json()];
|
|
23
|
-
case "js":
|
|
24
|
-
case "ts":
|
|
25
|
-
case "jsx":
|
|
26
|
-
case "tsx":
|
|
27
|
-
return [langJavascript.javascript({ typescript: ext === "ts" || ext === "tsx", jsx: ext === "jsx" || ext === "tsx" })];
|
|
28
|
-
default:
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function buildTree(files) {
|
|
33
|
-
const rootFiles = [];
|
|
34
|
-
const dirMap = /* @__PURE__ */ new Map();
|
|
35
|
-
function ensureDir(dirPath) {
|
|
36
|
-
const existing = dirMap.get(dirPath);
|
|
37
|
-
if (existing) return existing;
|
|
38
|
-
const parts = dirPath.split("/");
|
|
39
|
-
const node = {
|
|
40
|
-
name: parts[parts.length - 1] ?? dirPath,
|
|
41
|
-
fullPath: dirPath,
|
|
42
|
-
children: [],
|
|
43
|
-
files: []
|
|
44
|
-
};
|
|
45
|
-
dirMap.set(dirPath, node);
|
|
46
|
-
if (parts.length > 1) {
|
|
47
|
-
const parentPath = parts.slice(0, -1).join("/");
|
|
48
|
-
const parent = ensureDir(parentPath);
|
|
49
|
-
if (!parent.children.some((c) => c.fullPath === dirPath)) {
|
|
50
|
-
parent.children.push(node);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return node;
|
|
54
|
-
}
|
|
55
|
-
for (const file of files) {
|
|
56
|
-
const slashIdx = file.path.lastIndexOf("/");
|
|
57
|
-
if (slashIdx === -1) {
|
|
58
|
-
rootFiles.push(file);
|
|
59
|
-
} else {
|
|
60
|
-
const dirPath = file.path.slice(0, slashIdx);
|
|
61
|
-
const dir = ensureDir(dirPath);
|
|
62
|
-
dir.files.push(file);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const topLevel = [];
|
|
66
|
-
for (const node of dirMap.values()) {
|
|
67
|
-
if (!node.fullPath.includes("/")) {
|
|
68
|
-
topLevel.push(node);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function sortNode(node) {
|
|
72
|
-
node.children.sort((a, b) => a.name.localeCompare(b.name));
|
|
73
|
-
node.files.sort((a, b) => a.path.localeCompare(b.path));
|
|
74
|
-
node.children.forEach(sortNode);
|
|
75
|
-
}
|
|
76
|
-
topLevel.forEach(sortNode);
|
|
77
|
-
topLevel.sort((a, b) => a.name.localeCompare(b.name));
|
|
78
|
-
rootFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
79
|
-
return { rootFiles, rootDirs: topLevel };
|
|
80
|
-
}
|
|
81
|
-
function collectAllDirPaths(nodes) {
|
|
82
|
-
const paths = /* @__PURE__ */ new Set();
|
|
83
|
-
function walk(node) {
|
|
84
|
-
paths.add(node.fullPath);
|
|
85
|
-
node.children.forEach(walk);
|
|
86
|
-
}
|
|
87
|
-
nodes.forEach(walk);
|
|
88
|
-
return paths;
|
|
89
|
-
}
|
|
90
|
-
function FileTreeEditor({
|
|
91
|
-
initialFiles,
|
|
92
|
-
onSave,
|
|
93
|
-
onChange,
|
|
94
|
-
readOnly = false,
|
|
95
|
-
hideSave = false,
|
|
96
|
-
title = "Files",
|
|
97
|
-
saveLabel = "Save",
|
|
98
|
-
addFolderLabel = "Folder",
|
|
99
|
-
newFileTemplate = { filename: "SKILL.md", content: "# New\n\nDescribe this...\n" },
|
|
100
|
-
savedVersion
|
|
101
|
-
}) {
|
|
102
|
-
const [files, setFiles] = react.useState(initialFiles);
|
|
103
|
-
const [selectedPath, setSelectedPath] = react.useState(
|
|
104
|
-
initialFiles.length > 0 ? initialFiles[0]?.path ?? null : null
|
|
105
|
-
);
|
|
106
|
-
const [saving, setSaving] = react.useState(false);
|
|
107
|
-
const [expanded, setExpanded] = react.useState(() => {
|
|
108
|
-
const { rootDirs } = buildTree(initialFiles);
|
|
109
|
-
return collectAllDirPaths(rootDirs);
|
|
110
|
-
});
|
|
111
|
-
const [showAddFolder, setShowAddFolder] = react.useState(false);
|
|
112
|
-
const [newFolderName, setNewFolderName] = react.useState("");
|
|
113
|
-
const [addingFileInDir, setAddingFileInDir] = react.useState(null);
|
|
114
|
-
const [newFileName, setNewFileName] = react.useState("");
|
|
115
|
-
const [savedSnapshot, setSavedSnapshot] = react.useState(() => JSON.stringify(initialFiles));
|
|
116
|
-
react.useEffect(() => {
|
|
117
|
-
const snap = JSON.stringify(initialFiles);
|
|
118
|
-
setSavedSnapshot(snap);
|
|
119
|
-
setFiles(initialFiles);
|
|
120
|
-
const { rootDirs } = buildTree(initialFiles);
|
|
121
|
-
setExpanded(collectAllDirPaths(rootDirs));
|
|
122
|
-
}, [initialFiles]);
|
|
123
|
-
react.useEffect(() => {
|
|
124
|
-
if (savedVersion !== void 0 && savedVersion > 0) {
|
|
125
|
-
setSavedSnapshot(JSON.stringify(files));
|
|
126
|
-
}
|
|
127
|
-
}, [savedVersion]);
|
|
128
|
-
const onChangeRef = react.useRef(onChange);
|
|
129
|
-
onChangeRef.current = onChange;
|
|
130
|
-
react.useEffect(() => {
|
|
131
|
-
if (onChangeRef.current && JSON.stringify(files) !== savedSnapshot) {
|
|
132
|
-
onChangeRef.current(files);
|
|
133
|
-
}
|
|
134
|
-
}, [files, savedSnapshot]);
|
|
135
|
-
const isDirty = react.useMemo(
|
|
136
|
-
() => JSON.stringify(files) !== savedSnapshot,
|
|
137
|
-
[files, savedSnapshot]
|
|
138
|
-
);
|
|
139
|
-
const tree = react.useMemo(() => buildTree(files), [files]);
|
|
140
|
-
const activeFile = react.useMemo(
|
|
141
|
-
() => selectedPath ? files.find((f) => f.path === selectedPath) ?? null : null,
|
|
142
|
-
[files, selectedPath]
|
|
143
|
-
);
|
|
144
|
-
const handleEditorChange = react.useCallback((value) => {
|
|
145
|
-
if (readOnly || !selectedPath) return;
|
|
146
|
-
setFiles((prev) => prev.map((f) => f.path === selectedPath ? { ...f, content: value } : f));
|
|
147
|
-
}, [readOnly, selectedPath]);
|
|
148
|
-
function toggleExpand(dirPath) {
|
|
149
|
-
setExpanded((prev) => {
|
|
150
|
-
const next = new Set(prev);
|
|
151
|
-
if (next.has(dirPath)) {
|
|
152
|
-
next.delete(dirPath);
|
|
153
|
-
} else {
|
|
154
|
-
next.add(dirPath);
|
|
155
|
-
}
|
|
156
|
-
return next;
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
function addFolder() {
|
|
160
|
-
const name = newFolderName.trim();
|
|
161
|
-
if (!name) return;
|
|
162
|
-
const filePath = `${name}/${newFileTemplate.filename}`;
|
|
163
|
-
if (files.some((f) => f.path === filePath)) return;
|
|
164
|
-
const content = newFileTemplate.content.replace("# New", `# ${name}`);
|
|
165
|
-
setFiles((prev) => [...prev, { path: filePath, content }]);
|
|
166
|
-
setSelectedPath(filePath);
|
|
167
|
-
setExpanded((prev) => /* @__PURE__ */ new Set([...prev, name]));
|
|
168
|
-
setNewFolderName("");
|
|
169
|
-
setShowAddFolder(false);
|
|
170
|
-
}
|
|
171
|
-
function removeDir(dirPath) {
|
|
172
|
-
const prefix = dirPath + "/";
|
|
173
|
-
const affectedFiles = files.filter((f) => f.path.startsWith(prefix));
|
|
174
|
-
if (affectedFiles.length === 0) return;
|
|
175
|
-
if (!confirm(`Remove "${dirPath}" and all ${affectedFiles.length} file(s)?`)) return;
|
|
176
|
-
setFiles((prev) => prev.filter((f) => !f.path.startsWith(prefix)));
|
|
177
|
-
if (selectedPath && selectedPath.startsWith(prefix)) {
|
|
178
|
-
setSelectedPath(null);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function removeFile(filePath) {
|
|
182
|
-
const fileName = filePath.split("/").pop() ?? filePath;
|
|
183
|
-
if (!confirm(`Remove file "${fileName}"?`)) return;
|
|
184
|
-
setFiles((prev) => prev.filter((f) => f.path !== filePath));
|
|
185
|
-
if (selectedPath === filePath) {
|
|
186
|
-
setSelectedPath(null);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
function addFileInDir(dirPath) {
|
|
190
|
-
const name = newFileName.trim();
|
|
191
|
-
if (!name) return;
|
|
192
|
-
const filePath = dirPath ? `${dirPath}/${name}` : name;
|
|
193
|
-
if (files.some((f) => f.path === filePath)) return;
|
|
194
|
-
setFiles((prev) => [...prev, { path: filePath, content: "" }]);
|
|
195
|
-
setSelectedPath(filePath);
|
|
196
|
-
setNewFileName("");
|
|
197
|
-
setAddingFileInDir(null);
|
|
198
|
-
}
|
|
199
|
-
async function handleSave() {
|
|
200
|
-
setSaving(true);
|
|
201
|
-
try {
|
|
202
|
-
await onSave(files);
|
|
203
|
-
} finally {
|
|
204
|
-
setSaving(false);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
function renderTreeNode(node, depth) {
|
|
208
|
-
const isExpanded = expanded.has(node.fullPath);
|
|
209
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
210
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
211
|
-
"div",
|
|
212
|
-
{
|
|
213
|
-
className: `flex items-center justify-between cursor-pointer hover:bg-muted/50 py-1 pr-2`,
|
|
214
|
-
style: { paddingLeft: `${depth * 16 + 8}px` },
|
|
215
|
-
onClick: () => toggleExpand(node.fullPath),
|
|
216
|
-
children: [
|
|
217
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-xs truncate flex items-center gap-1", children: [
|
|
218
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: isExpanded ? "\u25BE" : "\u25B8" }),
|
|
219
|
-
node.name,
|
|
220
|
-
"/"
|
|
221
|
-
] }),
|
|
222
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
223
|
-
"button",
|
|
224
|
-
{
|
|
225
|
-
onClick: (e) => {
|
|
226
|
-
e.stopPropagation();
|
|
227
|
-
removeDir(node.fullPath);
|
|
228
|
-
},
|
|
229
|
-
className: "text-muted-foreground hover:text-destructive text-xs ml-1 shrink-0",
|
|
230
|
-
children: "\xD7"
|
|
231
|
-
}
|
|
232
|
-
)
|
|
233
|
-
]
|
|
234
|
-
}
|
|
235
|
-
),
|
|
236
|
-
isExpanded && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
237
|
-
node.children.map((child) => renderTreeNode(child, depth + 1)),
|
|
238
|
-
node.files.map((file) => {
|
|
239
|
-
const fileName = file.path.split("/").pop() ?? file.path;
|
|
240
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
241
|
-
"div",
|
|
242
|
-
{
|
|
243
|
-
className: `flex items-center justify-between cursor-pointer hover:bg-muted/30 py-1 pr-2 ${selectedPath === file.path ? "bg-primary/10 text-primary" : ""}`,
|
|
244
|
-
style: { paddingLeft: `${(depth + 1) * 16 + 8}px` },
|
|
245
|
-
onClick: () => setSelectedPath(file.path),
|
|
246
|
-
children: [
|
|
247
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate", children: fileName }),
|
|
248
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
249
|
-
"button",
|
|
250
|
-
{
|
|
251
|
-
onClick: (e) => {
|
|
252
|
-
e.stopPropagation();
|
|
253
|
-
removeFile(file.path);
|
|
254
|
-
},
|
|
255
|
-
className: "text-muted-foreground hover:text-destructive text-xs ml-1 shrink-0",
|
|
256
|
-
children: "\xD7"
|
|
257
|
-
}
|
|
258
|
-
)
|
|
259
|
-
]
|
|
260
|
-
},
|
|
261
|
-
file.path
|
|
262
|
-
);
|
|
263
|
-
}),
|
|
264
|
-
!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: [
|
|
265
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
266
|
-
chunk4XBBDUSZ_cjs.Input,
|
|
267
|
-
{
|
|
268
|
-
value: newFileName,
|
|
269
|
-
onChange: (e) => setNewFileName(e.target.value),
|
|
270
|
-
placeholder: "file.md",
|
|
271
|
-
className: "h-6 text-xs",
|
|
272
|
-
onKeyDown: (e) => e.key === "Enter" && addFileInDir(node.fullPath),
|
|
273
|
-
autoFocus: true
|
|
274
|
-
}
|
|
275
|
-
),
|
|
276
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk4XBBDUSZ_cjs.Button, { onClick: () => addFileInDir(node.fullPath), size: "sm", className: "h-6 text-xs px-2", children: "+" })
|
|
277
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
278
|
-
"button",
|
|
279
|
-
{
|
|
280
|
-
onClick: () => {
|
|
281
|
-
setAddingFileInDir(node.fullPath);
|
|
282
|
-
setNewFileName("");
|
|
283
|
-
},
|
|
284
|
-
className: "text-xs text-primary hover:underline",
|
|
285
|
-
children: "+ File"
|
|
286
|
-
}
|
|
287
|
-
) })
|
|
288
|
-
] })
|
|
289
|
-
] }, node.fullPath);
|
|
290
|
-
}
|
|
291
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
292
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
293
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
294
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold", children: title }),
|
|
295
|
-
isDirty && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(chunk4XBBDUSZ_cjs.Badge, { variant: "destructive", className: "text-xs", children: "Unsaved changes" }),
|
|
296
|
-
readOnly && /* @__PURE__ */ jsxRuntime.jsx(chunk4XBBDUSZ_cjs.Badge, { variant: "secondary", className: "text-xs", children: "Read-only" })
|
|
297
|
-
] }),
|
|
298
|
-
!readOnly && !hideSave && /* @__PURE__ */ jsxRuntime.jsx(chunk4XBBDUSZ_cjs.Button, { onClick: handleSave, disabled: saving || !isDirty, size: "sm", children: saving ? "Saving..." : saveLabel })
|
|
299
|
-
] }),
|
|
300
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 min-h-[500px]", children: [
|
|
301
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-64 shrink-0 border border-border rounded-md overflow-hidden", children: [
|
|
302
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 bg-muted/50 border-b border-border flex items-center justify-between", children: [
|
|
303
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: title }),
|
|
304
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
305
|
-
"button",
|
|
306
|
-
{
|
|
307
|
-
onClick: () => setShowAddFolder(!showAddFolder),
|
|
308
|
-
className: "text-xs text-primary hover:underline",
|
|
309
|
-
children: [
|
|
310
|
-
"+ ",
|
|
311
|
-
addFolderLabel
|
|
312
|
-
]
|
|
313
|
-
}
|
|
314
|
-
)
|
|
315
|
-
] }),
|
|
316
|
-
showAddFolder && !readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 border-b border-border flex gap-1", children: [
|
|
317
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
318
|
-
chunk4XBBDUSZ_cjs.Input,
|
|
319
|
-
{
|
|
320
|
-
value: newFolderName,
|
|
321
|
-
onChange: (e) => setNewFolderName(e.target.value),
|
|
322
|
-
placeholder: "folder-name",
|
|
323
|
-
className: "h-7 text-xs",
|
|
324
|
-
onKeyDown: (e) => e.key === "Enter" && addFolder(),
|
|
325
|
-
autoFocus: true
|
|
326
|
-
}
|
|
327
|
-
),
|
|
328
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk4XBBDUSZ_cjs.Button, { onClick: addFolder, size: "sm", className: "h-7 text-xs px-2", children: "Add" })
|
|
329
|
-
] }),
|
|
330
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm overflow-y-auto", children: [
|
|
331
|
-
tree.rootFiles.map((file) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
332
|
-
"div",
|
|
333
|
-
{
|
|
334
|
-
className: `flex items-center justify-between cursor-pointer hover:bg-muted/30 py-1 pr-2 ${selectedPath === file.path ? "bg-primary/10 text-primary" : ""}`,
|
|
335
|
-
style: { paddingLeft: "8px" },
|
|
336
|
-
onClick: () => setSelectedPath(file.path),
|
|
337
|
-
children: [
|
|
338
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate", children: file.path }),
|
|
339
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
340
|
-
"button",
|
|
341
|
-
{
|
|
342
|
-
onClick: (e) => {
|
|
343
|
-
e.stopPropagation();
|
|
344
|
-
removeFile(file.path);
|
|
345
|
-
},
|
|
346
|
-
className: "text-muted-foreground hover:text-destructive text-xs ml-1 shrink-0",
|
|
347
|
-
children: "\xD7"
|
|
348
|
-
}
|
|
349
|
-
)
|
|
350
|
-
]
|
|
351
|
-
},
|
|
352
|
-
file.path
|
|
353
|
-
)),
|
|
354
|
-
tree.rootDirs.map((node) => renderTreeNode(node, 0)),
|
|
355
|
-
files.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-3 text-xs text-muted-foreground", children: readOnly ? "No files." : `No ${title.toLowerCase()} yet. Add a ${addFolderLabel.toLowerCase()} to get started.` })
|
|
356
|
-
] })
|
|
357
|
-
] }),
|
|
358
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 border border-border rounded-md overflow-hidden", children: activeFile ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col", children: [
|
|
359
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 bg-muted/50 border-b border-border text-xs text-muted-foreground", children: activeFile.path }),
|
|
360
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
361
|
-
CodeMirror__default.default,
|
|
362
|
-
{
|
|
363
|
-
value: activeFile.content,
|
|
364
|
-
onChange: handleEditorChange,
|
|
365
|
-
readOnly,
|
|
366
|
-
theme: themeOneDark.oneDark,
|
|
367
|
-
extensions: getLanguageExtension(activeFile.path),
|
|
368
|
-
height: "100%",
|
|
369
|
-
className: "flex-1 overflow-auto",
|
|
370
|
-
basicSetup: {
|
|
371
|
-
lineNumbers: true,
|
|
372
|
-
foldGutter: true,
|
|
373
|
-
bracketMatching: true
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
)
|
|
377
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex items-center justify-center text-muted-foreground text-sm", children: [
|
|
378
|
-
"Select a file to ",
|
|
379
|
-
readOnly ? "view" : "edit"
|
|
380
|
-
] }) })
|
|
381
|
-
] }) })
|
|
382
|
-
] });
|
|
383
|
-
}
|
|
384
16
|
function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
385
|
-
const { LinkComponent, basePath } =
|
|
386
|
-
const client =
|
|
387
|
-
const { data: pluginFiles, error, isLoading } =
|
|
17
|
+
const { LinkComponent, basePath } = chunkXXF4U7WL_cjs.useNavigation();
|
|
18
|
+
const client = chunkXXF4U7WL_cjs.useAgentPlaneClient();
|
|
19
|
+
const { data: pluginFiles, error, isLoading } = chunkVZ43ATC5_cjs.useApi(
|
|
388
20
|
`marketplace-${marketplaceId}-plugin-files-${pluginName}`,
|
|
389
21
|
(c) => c.pluginMarketplaces.getPluginFiles(marketplaceId, pluginName)
|
|
390
22
|
);
|
|
@@ -442,9 +74,9 @@ function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
|
442
74
|
}
|
|
443
75
|
if (isLoading || !pluginFiles) {
|
|
444
76
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
445
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
446
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
447
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
77
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkVZ43ATC5_cjs.Skeleton, { className: "h-8 w-48" }),
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkVZ43ATC5_cjs.Skeleton, { className: "h-4 w-96" }),
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkVZ43ATC5_cjs.Skeleton, { className: "h-[500px] rounded-lg" })
|
|
448
80
|
] });
|
|
449
81
|
}
|
|
450
82
|
const tabs = [
|
|
@@ -464,7 +96,7 @@ function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
|
464
96
|
) }),
|
|
465
97
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
466
98
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold", children: pluginName }),
|
|
467
|
-
readOnly ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
99
|
+
readOnly ? /* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Badge, { variant: "outline", children: "Read-only" }) : /* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Badge, { variant: "secondary", children: "Editable" })
|
|
468
100
|
] })
|
|
469
101
|
] }),
|
|
470
102
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end border-b border-border", children: [
|
|
@@ -487,11 +119,11 @@ function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
|
487
119
|
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 ml-auto pb-2", children: [
|
|
488
120
|
saveError && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-destructive", children: saveError }),
|
|
489
121
|
success && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-green-500", children: success }),
|
|
490
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
122
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Button, { size: "sm", onClick: handleSaveAll, disabled: saving, children: saving ? "Pushing to GitHub..." : "Save All to GitHub" })
|
|
491
123
|
] })
|
|
492
124
|
] }),
|
|
493
125
|
activeTab === "agents" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
494
|
-
FileTreeEditor,
|
|
126
|
+
chunkVZ43ATC5_cjs.FileTreeEditor,
|
|
495
127
|
{
|
|
496
128
|
initialFiles: pluginFiles.agents,
|
|
497
129
|
onSave: noopSave,
|
|
@@ -505,7 +137,7 @@ function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
|
505
137
|
}
|
|
506
138
|
),
|
|
507
139
|
activeTab === "skills" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
508
|
-
FileTreeEditor,
|
|
140
|
+
chunkVZ43ATC5_cjs.FileTreeEditor,
|
|
509
141
|
{
|
|
510
142
|
initialFiles: pluginFiles.skills,
|
|
511
143
|
onSave: noopSave,
|
|
@@ -518,12 +150,12 @@ function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
|
518
150
|
savedVersion
|
|
519
151
|
}
|
|
520
152
|
),
|
|
521
|
-
activeTab === "connectors" && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
522
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
523
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
524
|
-
readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
153
|
+
activeTab === "connectors" && /* @__PURE__ */ jsxRuntime.jsxs(chunkVZ43ATC5_cjs.Card, { children: [
|
|
154
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkVZ43ATC5_cjs.CardHeader, { className: "flex flex-row items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
155
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkVZ43ATC5_cjs.CardTitle, { className: "text-base", children: "Connectors (.mcp.json)" }),
|
|
156
|
+
readOnly && /* @__PURE__ */ jsxRuntime.jsx(chunkXXF4U7WL_cjs.Badge, { variant: "secondary", className: "text-xs", children: "Read-only" })
|
|
525
157
|
] }) }),
|
|
526
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkVZ43ATC5_cjs.CardContent, { children: [
|
|
527
159
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border border-border rounded-md overflow-hidden", children: [
|
|
528
160
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 bg-muted/50 border-b border-border text-xs text-muted-foreground", children: ".mcp.json" }),
|
|
529
161
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -549,5 +181,12 @@ function PluginEditorPage({ marketplaceId, pluginName }) {
|
|
|
549
181
|
] });
|
|
550
182
|
}
|
|
551
183
|
|
|
552
|
-
exports
|
|
184
|
+
Object.defineProperty(exports, "FileTreeEditor", {
|
|
185
|
+
enumerable: true,
|
|
186
|
+
get: function () { return chunkVZ43ATC5_cjs.FileTreeEditor; }
|
|
187
|
+
});
|
|
188
|
+
Object.defineProperty(exports, "AgentIdentityTab", {
|
|
189
|
+
enumerable: true,
|
|
190
|
+
get: function () { return chunkCHJL4MZI_cjs.AgentIdentityTab; }
|
|
191
|
+
});
|
|
553
192
|
exports.PluginEditorPage = PluginEditorPage;
|
package/dist/editor.d.cts
CHANGED
|
@@ -28,4 +28,53 @@ interface PluginEditorPageProps {
|
|
|
28
28
|
}
|
|
29
29
|
declare function PluginEditorPage({ marketplaceId, pluginName }: PluginEditorPageProps): react_jsx_runtime.JSX.Element;
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
interface Agent {
|
|
32
|
+
id: string;
|
|
33
|
+
soul_md: string | null;
|
|
34
|
+
identity_md: string | null;
|
|
35
|
+
style_md: string | null;
|
|
36
|
+
agents_md: string | null;
|
|
37
|
+
heartbeat_md: string | null;
|
|
38
|
+
user_template_md: string | null;
|
|
39
|
+
examples_good_md: string | null;
|
|
40
|
+
examples_bad_md: string | null;
|
|
41
|
+
}
|
|
42
|
+
interface AgentIdentityTabProps {
|
|
43
|
+
agent: Agent;
|
|
44
|
+
/**
|
|
45
|
+
* The FileTreeEditor component from the /editor entry point.
|
|
46
|
+
* Pass it as a prop to keep CodeMirror out of the core bundle.
|
|
47
|
+
*/
|
|
48
|
+
FileTreeEditor: React.ComponentType<{
|
|
49
|
+
initialFiles: FlatFile[];
|
|
50
|
+
onSave: (files: FlatFile[]) => Promise<void>;
|
|
51
|
+
title?: string;
|
|
52
|
+
saveLabel?: string;
|
|
53
|
+
addFolderLabel?: string;
|
|
54
|
+
newFileTemplate?: {
|
|
55
|
+
filename: string;
|
|
56
|
+
content: string;
|
|
57
|
+
};
|
|
58
|
+
savedVersion?: number;
|
|
59
|
+
}>;
|
|
60
|
+
/** Called after a successful save so the host can refresh data. */
|
|
61
|
+
onSaved?: () => void;
|
|
62
|
+
/** Generate a SoulSpec for this agent. Returns a map of field-name/path to content. */
|
|
63
|
+
onGenerateSoul?: () => Promise<{
|
|
64
|
+
files: Record<string, string>;
|
|
65
|
+
}>;
|
|
66
|
+
/** Import a SoulSpec from the ClawSouls registry. */
|
|
67
|
+
onImportSoul?: (ref: string) => Promise<{
|
|
68
|
+
files: Record<string, string>;
|
|
69
|
+
}>;
|
|
70
|
+
/** Export the current SoulSpec as JSON. Returns file map + agent name. */
|
|
71
|
+
onExportSoul?: () => Promise<{
|
|
72
|
+
files: Record<string, string>;
|
|
73
|
+
name: string;
|
|
74
|
+
}>;
|
|
75
|
+
/** Publish the SoulSpec to the ClawSouls registry. */
|
|
76
|
+
onPublishSoul?: (owner: string) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
declare function AgentIdentityTab({ agent, FileTreeEditor, onSaved, onGenerateSoul, onImportSoul, onExportSoul, onPublishSoul, }: AgentIdentityTabProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
export { AgentIdentityTab, type AgentIdentityTabProps, FileTreeEditor, type FileTreeEditorProps, type FlatFile, PluginEditorPage, type PluginEditorPageProps };
|
package/dist/editor.d.ts
CHANGED
|
@@ -28,4 +28,53 @@ interface PluginEditorPageProps {
|
|
|
28
28
|
}
|
|
29
29
|
declare function PluginEditorPage({ marketplaceId, pluginName }: PluginEditorPageProps): react_jsx_runtime.JSX.Element;
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
interface Agent {
|
|
32
|
+
id: string;
|
|
33
|
+
soul_md: string | null;
|
|
34
|
+
identity_md: string | null;
|
|
35
|
+
style_md: string | null;
|
|
36
|
+
agents_md: string | null;
|
|
37
|
+
heartbeat_md: string | null;
|
|
38
|
+
user_template_md: string | null;
|
|
39
|
+
examples_good_md: string | null;
|
|
40
|
+
examples_bad_md: string | null;
|
|
41
|
+
}
|
|
42
|
+
interface AgentIdentityTabProps {
|
|
43
|
+
agent: Agent;
|
|
44
|
+
/**
|
|
45
|
+
* The FileTreeEditor component from the /editor entry point.
|
|
46
|
+
* Pass it as a prop to keep CodeMirror out of the core bundle.
|
|
47
|
+
*/
|
|
48
|
+
FileTreeEditor: React.ComponentType<{
|
|
49
|
+
initialFiles: FlatFile[];
|
|
50
|
+
onSave: (files: FlatFile[]) => Promise<void>;
|
|
51
|
+
title?: string;
|
|
52
|
+
saveLabel?: string;
|
|
53
|
+
addFolderLabel?: string;
|
|
54
|
+
newFileTemplate?: {
|
|
55
|
+
filename: string;
|
|
56
|
+
content: string;
|
|
57
|
+
};
|
|
58
|
+
savedVersion?: number;
|
|
59
|
+
}>;
|
|
60
|
+
/** Called after a successful save so the host can refresh data. */
|
|
61
|
+
onSaved?: () => void;
|
|
62
|
+
/** Generate a SoulSpec for this agent. Returns a map of field-name/path to content. */
|
|
63
|
+
onGenerateSoul?: () => Promise<{
|
|
64
|
+
files: Record<string, string>;
|
|
65
|
+
}>;
|
|
66
|
+
/** Import a SoulSpec from the ClawSouls registry. */
|
|
67
|
+
onImportSoul?: (ref: string) => Promise<{
|
|
68
|
+
files: Record<string, string>;
|
|
69
|
+
}>;
|
|
70
|
+
/** Export the current SoulSpec as JSON. Returns file map + agent name. */
|
|
71
|
+
onExportSoul?: () => Promise<{
|
|
72
|
+
files: Record<string, string>;
|
|
73
|
+
name: string;
|
|
74
|
+
}>;
|
|
75
|
+
/** Publish the SoulSpec to the ClawSouls registry. */
|
|
76
|
+
onPublishSoul?: (owner: string) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
declare function AgentIdentityTab({ agent, FileTreeEditor, onSaved, onGenerateSoul, onImportSoul, onExportSoul, onPublishSoul, }: AgentIdentityTabProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
export { AgentIdentityTab, type AgentIdentityTabProps, FileTreeEditor, type FileTreeEditorProps, type FlatFile, PluginEditorPage, type PluginEditorPageProps };
|