@getcatalystiq/agent-plane-ui 0.1.4 → 0.1.6
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/code-editor-E7L6Y3LM.js +35 -0
- package/dist/code-editor-ZD5ZILTM.cjs +41 -0
- package/dist/index.cjs +489 -239
- package/dist/index.d.cts +1 -7
- package/dist/index.d.ts +1 -7
- package/dist/index.js +490 -240
- package/package.json +22 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React3 from 'react';
|
|
2
|
-
import React3__default, { createContext, useRef, useMemo, useContext, useState, useCallback, useEffect } from 'react';
|
|
2
|
+
import React3__default, { createContext, lazy, useRef, useMemo, useContext, useState, useCallback, useEffect, Suspense } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import useSWR, { useSWRConfig } from 'swr';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
@@ -3073,129 +3073,389 @@ function AgentConnectorsManager({ agentId, toolkits: initialToolkits, composioAl
|
|
|
3073
3073
|
)
|
|
3074
3074
|
] });
|
|
3075
3075
|
}
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
const
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3076
|
+
var CodeEditor = lazy(() => import('./code-editor-E7L6Y3LM.js'));
|
|
3077
|
+
function buildTree(files) {
|
|
3078
|
+
const rootFiles = [];
|
|
3079
|
+
const dirMap = /* @__PURE__ */ new Map();
|
|
3080
|
+
function ensureDir(dirPath) {
|
|
3081
|
+
const existing = dirMap.get(dirPath);
|
|
3082
|
+
if (existing) return existing;
|
|
3083
|
+
const parts = dirPath.split("/");
|
|
3084
|
+
const node = {
|
|
3085
|
+
name: parts[parts.length - 1],
|
|
3086
|
+
fullPath: dirPath,
|
|
3087
|
+
children: [],
|
|
3088
|
+
files: []
|
|
3089
|
+
};
|
|
3090
|
+
dirMap.set(dirPath, node);
|
|
3091
|
+
if (parts.length > 1) {
|
|
3092
|
+
const parentPath = parts.slice(0, -1).join("/");
|
|
3093
|
+
const parent = ensureDir(parentPath);
|
|
3094
|
+
if (!parent.children.some((c) => c.fullPath === dirPath)) {
|
|
3095
|
+
parent.children.push(node);
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
return node;
|
|
3099
|
+
}
|
|
3100
|
+
for (const file of files) {
|
|
3101
|
+
const slashIdx = file.path.lastIndexOf("/");
|
|
3102
|
+
if (slashIdx === -1) {
|
|
3103
|
+
rootFiles.push(file);
|
|
3104
|
+
} else {
|
|
3105
|
+
const dirPath = file.path.slice(0, slashIdx);
|
|
3106
|
+
const dir = ensureDir(dirPath);
|
|
3107
|
+
dir.files.push(file);
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
const topLevel = [];
|
|
3111
|
+
for (const node of dirMap.values()) {
|
|
3112
|
+
if (!node.fullPath.includes("/")) {
|
|
3113
|
+
topLevel.push(node);
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
function sortNode(node) {
|
|
3117
|
+
node.children.sort((a, b) => a.name.localeCompare(b.name));
|
|
3118
|
+
node.files.sort((a, b) => a.path.localeCompare(b.path));
|
|
3119
|
+
node.children.forEach(sortNode);
|
|
3120
|
+
}
|
|
3121
|
+
topLevel.forEach(sortNode);
|
|
3122
|
+
topLevel.sort((a, b) => a.name.localeCompare(b.name));
|
|
3123
|
+
rootFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
3124
|
+
return { rootFiles, rootDirs: topLevel };
|
|
3125
|
+
}
|
|
3126
|
+
function collectAllDirPaths(nodes) {
|
|
3127
|
+
const paths = /* @__PURE__ */ new Set();
|
|
3128
|
+
function walk(node) {
|
|
3129
|
+
paths.add(node.fullPath);
|
|
3130
|
+
node.children.forEach(walk);
|
|
3131
|
+
}
|
|
3132
|
+
nodes.forEach(walk);
|
|
3133
|
+
return paths;
|
|
3134
|
+
}
|
|
3135
|
+
function FileTreeEditor({
|
|
3136
|
+
initialFiles,
|
|
3137
|
+
onSave,
|
|
3138
|
+
onChange,
|
|
3139
|
+
readOnly = false,
|
|
3140
|
+
hideSave = false,
|
|
3141
|
+
title = "Files",
|
|
3142
|
+
saveLabel = "Save",
|
|
3143
|
+
addFolderLabel = "Folder",
|
|
3144
|
+
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" },
|
|
3145
|
+
savedVersion
|
|
3146
|
+
}) {
|
|
3087
3147
|
const [files, setFiles] = useState(initialFiles);
|
|
3088
|
-
const [selectedPath, setSelectedPath] = useState(
|
|
3148
|
+
const [selectedPath, setSelectedPath] = useState(
|
|
3149
|
+
initialFiles.length > 0 ? initialFiles[0].path : null
|
|
3150
|
+
);
|
|
3089
3151
|
const [saving, setSaving] = useState(false);
|
|
3090
|
-
const [
|
|
3152
|
+
const [expanded, setExpanded] = useState(() => {
|
|
3153
|
+
const { rootDirs } = buildTree(initialFiles);
|
|
3154
|
+
return collectAllDirPaths(rootDirs);
|
|
3155
|
+
});
|
|
3156
|
+
const [showAddFolder, setShowAddFolder] = useState(false);
|
|
3157
|
+
const [newFolderName, setNewFolderName] = useState("");
|
|
3158
|
+
const [addingFileInDir, setAddingFileInDir] = useState(null);
|
|
3091
3159
|
const [newFileName, setNewFileName] = useState("");
|
|
3160
|
+
const [savedSnapshot, setSavedSnapshot] = useState(() => JSON.stringify(initialFiles));
|
|
3161
|
+
useEffect(() => {
|
|
3162
|
+
const snap = JSON.stringify(initialFiles);
|
|
3163
|
+
setSavedSnapshot(snap);
|
|
3164
|
+
setFiles(initialFiles);
|
|
3165
|
+
const { rootDirs } = buildTree(initialFiles);
|
|
3166
|
+
setExpanded(collectAllDirPaths(rootDirs));
|
|
3167
|
+
}, [initialFiles]);
|
|
3168
|
+
useEffect(() => {
|
|
3169
|
+
if (savedVersion !== void 0 && savedVersion > 0) {
|
|
3170
|
+
setSavedSnapshot(JSON.stringify(files));
|
|
3171
|
+
}
|
|
3172
|
+
}, [savedVersion]);
|
|
3173
|
+
const onChangeRef = useRef(onChange);
|
|
3174
|
+
onChangeRef.current = onChange;
|
|
3175
|
+
useEffect(() => {
|
|
3176
|
+
if (onChangeRef.current && JSON.stringify(files) !== savedSnapshot) {
|
|
3177
|
+
onChangeRef.current(files);
|
|
3178
|
+
}
|
|
3179
|
+
}, [files, savedSnapshot]);
|
|
3092
3180
|
const isDirty = useMemo(
|
|
3093
|
-
() => JSON.stringify(files) !==
|
|
3094
|
-
[files,
|
|
3181
|
+
() => JSON.stringify(files) !== savedSnapshot,
|
|
3182
|
+
[files, savedSnapshot]
|
|
3183
|
+
);
|
|
3184
|
+
const tree = useMemo(() => buildTree(files), [files]);
|
|
3185
|
+
const activeFile = useMemo(
|
|
3186
|
+
() => selectedPath ? files.find((f) => f.path === selectedPath) ?? null : null,
|
|
3187
|
+
[files, selectedPath]
|
|
3095
3188
|
);
|
|
3096
|
-
const
|
|
3097
|
-
|
|
3098
|
-
setFiles((prev) => prev.map((f) => f.path ===
|
|
3189
|
+
const handleEditorChange = useCallback((value) => {
|
|
3190
|
+
if (readOnly || !selectedPath) return;
|
|
3191
|
+
setFiles((prev) => prev.map((f) => f.path === selectedPath ? { ...f, content: value } : f));
|
|
3192
|
+
}, [readOnly, selectedPath]);
|
|
3193
|
+
function toggleExpand(dirPath) {
|
|
3194
|
+
setExpanded((prev) => {
|
|
3195
|
+
const next = new Set(prev);
|
|
3196
|
+
if (next.has(dirPath)) next.delete(dirPath);
|
|
3197
|
+
else next.add(dirPath);
|
|
3198
|
+
return next;
|
|
3199
|
+
});
|
|
3200
|
+
}
|
|
3201
|
+
function addFolder() {
|
|
3202
|
+
const name = newFolderName.trim();
|
|
3203
|
+
if (!name) return;
|
|
3204
|
+
const filePath = `${name}/${newFileTemplate.filename}`;
|
|
3205
|
+
if (files.some((f) => f.path === filePath)) return;
|
|
3206
|
+
const content = newFileTemplate.content.replace("# New", `# ${name}`);
|
|
3207
|
+
setFiles((prev) => [...prev, { path: filePath, content }]);
|
|
3208
|
+
setSelectedPath(filePath);
|
|
3209
|
+
setExpanded((prev) => /* @__PURE__ */ new Set([...prev, name]));
|
|
3210
|
+
setNewFolderName("");
|
|
3211
|
+
setShowAddFolder(false);
|
|
3212
|
+
}
|
|
3213
|
+
function removeDir(dirPath) {
|
|
3214
|
+
const prefix = dirPath + "/";
|
|
3215
|
+
const affectedFiles = files.filter((f) => f.path.startsWith(prefix));
|
|
3216
|
+
if (affectedFiles.length === 0) return;
|
|
3217
|
+
if (!confirm(`Remove "${dirPath}" and all ${affectedFiles.length} file(s)?`)) return;
|
|
3218
|
+
setFiles((prev) => prev.filter((f) => !f.path.startsWith(prefix)));
|
|
3219
|
+
if (selectedPath && selectedPath.startsWith(prefix)) setSelectedPath(null);
|
|
3220
|
+
}
|
|
3221
|
+
function removeFile(filePath) {
|
|
3222
|
+
const fileName = filePath.split("/").pop() ?? filePath;
|
|
3223
|
+
if (!confirm(`Remove file "${fileName}"?`)) return;
|
|
3224
|
+
setFiles((prev) => prev.filter((f) => f.path !== filePath));
|
|
3225
|
+
if (selectedPath === filePath) setSelectedPath(null);
|
|
3099
3226
|
}
|
|
3100
|
-
function
|
|
3227
|
+
function addFileInDir(dirPath) {
|
|
3101
3228
|
const name = newFileName.trim();
|
|
3102
|
-
if (!name
|
|
3103
|
-
const
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3229
|
+
if (!name) return;
|
|
3230
|
+
const filePath = dirPath ? `${dirPath}/${name}` : name;
|
|
3231
|
+
if (files.some((f) => f.path === filePath)) return;
|
|
3232
|
+
setFiles((prev) => [...prev, { path: filePath, content: "" }]);
|
|
3233
|
+
setSelectedPath(filePath);
|
|
3107
3234
|
setNewFileName("");
|
|
3235
|
+
setAddingFileInDir(null);
|
|
3108
3236
|
}
|
|
3109
|
-
function
|
|
3110
|
-
setFiles((prev) => prev.filter((f) => f.path !== path));
|
|
3111
|
-
if (selectedPath === path) {
|
|
3112
|
-
setSelectedPath(files.find((f) => f.path !== path)?.path ?? null);
|
|
3113
|
-
}
|
|
3114
|
-
}
|
|
3115
|
-
const handleSave = useCallback(async () => {
|
|
3237
|
+
async function handleSave() {
|
|
3116
3238
|
setSaving(true);
|
|
3117
3239
|
try {
|
|
3118
|
-
|
|
3119
|
-
for (const file of files) {
|
|
3120
|
-
const slashIdx = file.path.lastIndexOf("/");
|
|
3121
|
-
if (slashIdx === -1) {
|
|
3122
|
-
const existing = folderMap.get("(root)") ?? [];
|
|
3123
|
-
existing.push({ path: file.path, content: file.content });
|
|
3124
|
-
folderMap.set("(root)", existing);
|
|
3125
|
-
} else {
|
|
3126
|
-
const folder = file.path.slice(0, slashIdx);
|
|
3127
|
-
const fileName = file.path.slice(slashIdx + 1);
|
|
3128
|
-
const existing = folderMap.get(folder) ?? [];
|
|
3129
|
-
existing.push({ path: fileName, content: file.content });
|
|
3130
|
-
folderMap.set(folder, existing);
|
|
3131
|
-
}
|
|
3132
|
-
}
|
|
3133
|
-
const skills = Array.from(folderMap.entries()).map(([folder, files2]) => ({ folder, files: files2 }));
|
|
3134
|
-
await client.agents.update(agentId, { skills });
|
|
3135
|
-
onSaved?.();
|
|
3240
|
+
await onSave(files);
|
|
3136
3241
|
} finally {
|
|
3137
3242
|
setSaving(false);
|
|
3138
3243
|
}
|
|
3139
|
-
}
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
/* @__PURE__ */
|
|
3144
|
-
/* @__PURE__ */ jsx(Button, { size: "sm", onClick: handleSave, disabled: saving || !isDirty, children: saving ? "Saving..." : "Save Skills" })
|
|
3145
|
-
] }) }),
|
|
3146
|
-
addingFile && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
3147
|
-
/* @__PURE__ */ jsx(
|
|
3148
|
-
Input,
|
|
3149
|
-
{
|
|
3150
|
-
value: newFileName,
|
|
3151
|
-
onChange: (e) => setNewFileName(e.target.value),
|
|
3152
|
-
placeholder: "folder/SKILL.md",
|
|
3153
|
-
className: "max-w-xs text-sm",
|
|
3154
|
-
onKeyDown: (e) => e.key === "Enter" && addFile()
|
|
3155
|
-
}
|
|
3156
|
-
),
|
|
3157
|
-
/* @__PURE__ */ jsx(Button, { size: "sm", onClick: addFile, children: "Add" }),
|
|
3158
|
-
/* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: () => {
|
|
3159
|
-
setAddingFile(false);
|
|
3160
|
-
setNewFileName("");
|
|
3161
|
-
}, children: "Cancel" })
|
|
3162
|
-
] }),
|
|
3163
|
-
files.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: 'No skills defined. Click "Add File" to create a skill.' }) : /* @__PURE__ */ jsxs("div", { className: "flex gap-4 min-h-[300px]", children: [
|
|
3164
|
-
/* @__PURE__ */ jsx("div", { className: "w-48 shrink-0 border-r border-border pr-3 space-y-1", children: files.map((f) => /* @__PURE__ */ jsxs(
|
|
3244
|
+
}
|
|
3245
|
+
function renderTreeNode(node, depth) {
|
|
3246
|
+
const isExpanded = expanded.has(node.fullPath);
|
|
3247
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3248
|
+
/* @__PURE__ */ jsxs(
|
|
3165
3249
|
"div",
|
|
3166
3250
|
{
|
|
3167
|
-
className:
|
|
3168
|
-
|
|
3251
|
+
className: "flex items-center justify-between cursor-pointer hover:bg-muted/50 py-1 pr-2",
|
|
3252
|
+
style: { paddingLeft: `${depth * 16 + 8}px` },
|
|
3253
|
+
onClick: () => toggleExpand(node.fullPath),
|
|
3169
3254
|
children: [
|
|
3170
|
-
/* @__PURE__ */
|
|
3171
|
-
|
|
3255
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium text-xs truncate flex items-center gap-1", children: [
|
|
3256
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: isExpanded ? "\u25BE" : "\u25B8" }),
|
|
3257
|
+
node.name,
|
|
3258
|
+
"/"
|
|
3259
|
+
] }),
|
|
3260
|
+
!readOnly && /* @__PURE__ */ jsx(
|
|
3172
3261
|
"button",
|
|
3173
3262
|
{
|
|
3174
|
-
type: "button",
|
|
3175
3263
|
onClick: (e) => {
|
|
3176
3264
|
e.stopPropagation();
|
|
3177
|
-
|
|
3265
|
+
removeDir(node.fullPath);
|
|
3178
3266
|
},
|
|
3179
|
-
className: "
|
|
3267
|
+
className: "text-muted-foreground hover:text-destructive text-xs ml-1 shrink-0",
|
|
3180
3268
|
children: "\xD7"
|
|
3181
3269
|
}
|
|
3182
3270
|
)
|
|
3183
3271
|
]
|
|
3184
|
-
},
|
|
3185
|
-
f.path
|
|
3186
|
-
)) }),
|
|
3187
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: selectedFile ? /* @__PURE__ */ jsx(
|
|
3188
|
-
Textarea,
|
|
3189
|
-
{
|
|
3190
|
-
value: selectedFile.content,
|
|
3191
|
-
onChange: (e) => updateFileContent(selectedFile.path, e.target.value),
|
|
3192
|
-
className: "h-full min-h-[300px] font-mono text-xs resize-y",
|
|
3193
|
-
placeholder: "Enter skill content..."
|
|
3194
3272
|
}
|
|
3195
|
-
)
|
|
3273
|
+
),
|
|
3274
|
+
isExpanded && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3275
|
+
node.children.map((child) => renderTreeNode(child, depth + 1)),
|
|
3276
|
+
node.files.map((file) => {
|
|
3277
|
+
const fileName = file.path.split("/").pop() ?? file.path;
|
|
3278
|
+
return /* @__PURE__ */ jsxs(
|
|
3279
|
+
"div",
|
|
3280
|
+
{
|
|
3281
|
+
className: `flex items-center justify-between cursor-pointer hover:bg-muted/30 py-1 pr-2 ${selectedPath === file.path ? "bg-primary/10 text-primary" : ""}`,
|
|
3282
|
+
style: { paddingLeft: `${(depth + 1) * 16 + 8}px` },
|
|
3283
|
+
onClick: () => setSelectedPath(file.path),
|
|
3284
|
+
children: [
|
|
3285
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs truncate", children: fileName }),
|
|
3286
|
+
!readOnly && /* @__PURE__ */ jsx(
|
|
3287
|
+
"button",
|
|
3288
|
+
{
|
|
3289
|
+
onClick: (e) => {
|
|
3290
|
+
e.stopPropagation();
|
|
3291
|
+
removeFile(file.path);
|
|
3292
|
+
},
|
|
3293
|
+
className: "text-muted-foreground hover:text-destructive text-xs ml-1 shrink-0",
|
|
3294
|
+
children: "\xD7"
|
|
3295
|
+
}
|
|
3296
|
+
)
|
|
3297
|
+
]
|
|
3298
|
+
},
|
|
3299
|
+
file.path
|
|
3300
|
+
);
|
|
3301
|
+
}),
|
|
3302
|
+
!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: [
|
|
3303
|
+
/* @__PURE__ */ jsx(
|
|
3304
|
+
Input,
|
|
3305
|
+
{
|
|
3306
|
+
value: newFileName,
|
|
3307
|
+
onChange: (e) => setNewFileName(e.target.value),
|
|
3308
|
+
placeholder: "file.md",
|
|
3309
|
+
className: "h-6 text-xs",
|
|
3310
|
+
onKeyDown: (e) => e.key === "Enter" && addFileInDir(node.fullPath),
|
|
3311
|
+
autoFocus: true
|
|
3312
|
+
}
|
|
3313
|
+
),
|
|
3314
|
+
/* @__PURE__ */ jsx(Button, { onClick: () => addFileInDir(node.fullPath), size: "sm", className: "h-6 text-xs px-2", children: "+" })
|
|
3315
|
+
] }) : /* @__PURE__ */ jsx(
|
|
3316
|
+
"button",
|
|
3317
|
+
{
|
|
3318
|
+
onClick: () => {
|
|
3319
|
+
setAddingFileInDir(node.fullPath);
|
|
3320
|
+
setNewFileName("");
|
|
3321
|
+
},
|
|
3322
|
+
className: "text-xs text-primary hover:underline",
|
|
3323
|
+
children: "+ File"
|
|
3324
|
+
}
|
|
3325
|
+
) })
|
|
3326
|
+
] })
|
|
3327
|
+
] }, node.fullPath);
|
|
3328
|
+
}
|
|
3329
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3330
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
3331
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
3332
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: title }),
|
|
3333
|
+
isDirty && !readOnly && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "text-xs", children: "Unsaved changes" }),
|
|
3334
|
+
readOnly && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: "Read-only" })
|
|
3335
|
+
] }),
|
|
3336
|
+
!readOnly && !hideSave && /* @__PURE__ */ jsx(Button, { onClick: handleSave, disabled: saving || !isDirty, size: "sm", children: saving ? "Saving..." : saveLabel })
|
|
3337
|
+
] }),
|
|
3338
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4 min-h-[500px]", children: [
|
|
3339
|
+
/* @__PURE__ */ jsxs("div", { className: "w-64 shrink-0 border border-border rounded-md overflow-hidden", children: [
|
|
3340
|
+
/* @__PURE__ */ jsxs("div", { className: "p-2 bg-muted/50 border-b border-border flex items-center justify-between", children: [
|
|
3341
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: title }),
|
|
3342
|
+
!readOnly && /* @__PURE__ */ jsxs(
|
|
3343
|
+
"button",
|
|
3344
|
+
{
|
|
3345
|
+
onClick: () => setShowAddFolder(!showAddFolder),
|
|
3346
|
+
className: "text-xs text-primary hover:underline",
|
|
3347
|
+
children: [
|
|
3348
|
+
"+ ",
|
|
3349
|
+
addFolderLabel
|
|
3350
|
+
]
|
|
3351
|
+
}
|
|
3352
|
+
)
|
|
3353
|
+
] }),
|
|
3354
|
+
showAddFolder && !readOnly && /* @__PURE__ */ jsxs("div", { className: "p-2 border-b border-border flex gap-1", children: [
|
|
3355
|
+
/* @__PURE__ */ jsx(
|
|
3356
|
+
Input,
|
|
3357
|
+
{
|
|
3358
|
+
value: newFolderName,
|
|
3359
|
+
onChange: (e) => setNewFolderName(e.target.value),
|
|
3360
|
+
placeholder: "folder-name",
|
|
3361
|
+
className: "h-7 text-xs",
|
|
3362
|
+
onKeyDown: (e) => e.key === "Enter" && addFolder(),
|
|
3363
|
+
autoFocus: true
|
|
3364
|
+
}
|
|
3365
|
+
),
|
|
3366
|
+
/* @__PURE__ */ jsx(Button, { onClick: addFolder, size: "sm", className: "h-7 text-xs px-2", children: "Add" })
|
|
3367
|
+
] }),
|
|
3368
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm overflow-y-auto", children: [
|
|
3369
|
+
tree.rootFiles.map((file) => /* @__PURE__ */ jsxs(
|
|
3370
|
+
"div",
|
|
3371
|
+
{
|
|
3372
|
+
className: `flex items-center justify-between cursor-pointer hover:bg-muted/30 py-1 pr-2 ${selectedPath === file.path ? "bg-primary/10 text-primary" : ""}`,
|
|
3373
|
+
style: { paddingLeft: "8px" },
|
|
3374
|
+
onClick: () => setSelectedPath(file.path),
|
|
3375
|
+
children: [
|
|
3376
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs truncate", children: file.path }),
|
|
3377
|
+
!readOnly && /* @__PURE__ */ jsx(
|
|
3378
|
+
"button",
|
|
3379
|
+
{
|
|
3380
|
+
onClick: (e) => {
|
|
3381
|
+
e.stopPropagation();
|
|
3382
|
+
removeFile(file.path);
|
|
3383
|
+
},
|
|
3384
|
+
className: "text-muted-foreground hover:text-destructive text-xs ml-1 shrink-0",
|
|
3385
|
+
children: "\xD7"
|
|
3386
|
+
}
|
|
3387
|
+
)
|
|
3388
|
+
]
|
|
3389
|
+
},
|
|
3390
|
+
file.path
|
|
3391
|
+
)),
|
|
3392
|
+
tree.rootDirs.map((node) => renderTreeNode(node, 0)),
|
|
3393
|
+
files.length === 0 && /* @__PURE__ */ 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.` })
|
|
3394
|
+
] })
|
|
3395
|
+
] }),
|
|
3396
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 border border-border rounded-md overflow-hidden", children: activeFile ? /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col", children: [
|
|
3397
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 bg-muted/50 border-b border-border text-xs text-muted-foreground", children: activeFile.path }),
|
|
3398
|
+
/* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex-1 animate-pulse bg-muted/50" }), children: /* @__PURE__ */ jsx(
|
|
3399
|
+
CodeEditor,
|
|
3400
|
+
{
|
|
3401
|
+
value: activeFile.content,
|
|
3402
|
+
onChange: handleEditorChange,
|
|
3403
|
+
filename: activeFile.path
|
|
3404
|
+
}
|
|
3405
|
+
) })
|
|
3406
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "h-full flex items-center justify-center text-muted-foreground text-sm", children: [
|
|
3407
|
+
"Select a file to ",
|
|
3408
|
+
readOnly ? "view" : "edit"
|
|
3409
|
+
] }) })
|
|
3196
3410
|
] })
|
|
3197
3411
|
] });
|
|
3198
3412
|
}
|
|
3413
|
+
function AgentSkillManager({ agentId, initialSkills, onSaved }) {
|
|
3414
|
+
const client = useAgentPlaneClient();
|
|
3415
|
+
const initialFiles = useMemo(
|
|
3416
|
+
() => initialSkills.flatMap(
|
|
3417
|
+
(s) => s.files.map((f) => ({
|
|
3418
|
+
path: s.folder === "(root)" ? f.path : `${s.folder}/${f.path}`,
|
|
3419
|
+
content: f.content
|
|
3420
|
+
}))
|
|
3421
|
+
),
|
|
3422
|
+
[initialSkills]
|
|
3423
|
+
);
|
|
3424
|
+
const handleSave = useCallback(async (files) => {
|
|
3425
|
+
const folderMap = /* @__PURE__ */ new Map();
|
|
3426
|
+
for (const file of files) {
|
|
3427
|
+
const slashIdx = file.path.lastIndexOf("/");
|
|
3428
|
+
if (slashIdx === -1) {
|
|
3429
|
+
const existing = folderMap.get("(root)") ?? [];
|
|
3430
|
+
existing.push({ path: file.path, content: file.content });
|
|
3431
|
+
folderMap.set("(root)", existing);
|
|
3432
|
+
} else {
|
|
3433
|
+
const folder = file.path.slice(0, slashIdx);
|
|
3434
|
+
const fileName = file.path.slice(slashIdx + 1);
|
|
3435
|
+
const existing = folderMap.get(folder) ?? [];
|
|
3436
|
+
existing.push({ path: fileName, content: file.content });
|
|
3437
|
+
folderMap.set(folder, existing);
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
const skills = Array.from(folderMap.entries()).map(([folder, files2]) => ({ folder, files: files2 }));
|
|
3441
|
+
await client.agents.update(agentId, { skills });
|
|
3442
|
+
onSaved?.();
|
|
3443
|
+
}, [agentId, client, onSaved]);
|
|
3444
|
+
return /* @__PURE__ */ jsx(
|
|
3445
|
+
FileTreeEditor,
|
|
3446
|
+
{
|
|
3447
|
+
initialFiles,
|
|
3448
|
+
onSave: handleSave,
|
|
3449
|
+
title: "Skills",
|
|
3450
|
+
saveLabel: "Save Skills",
|
|
3451
|
+
addFolderLabel: "Skill",
|
|
3452
|
+
newFileTemplate: {
|
|
3453
|
+
filename: "SKILL.md",
|
|
3454
|
+
content: "---\nname: New Skill\ndescription: Describe when this skill should be triggered\n---\n\n# Instructions\n\nDescribe what this skill does...\n"
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
);
|
|
3458
|
+
}
|
|
3199
3459
|
function AgentPluginManager({ agentId, initialPlugins, onSaved }) {
|
|
3200
3460
|
const client = useAgentPlaneClient();
|
|
3201
3461
|
const [plugins, setPlugins] = useState(initialPlugins);
|
|
@@ -3351,141 +3611,6 @@ function AgentPluginManager({ agentId, initialPlugins, onSaved }) {
|
|
|
3351
3611
|
] })
|
|
3352
3612
|
] });
|
|
3353
3613
|
}
|
|
3354
|
-
var FREQUENCIES = [
|
|
3355
|
-
{ value: "manual", label: "Manual (no schedule)" },
|
|
3356
|
-
{ value: "hourly", label: "Hourly" },
|
|
3357
|
-
{ value: "daily", label: "Daily" },
|
|
3358
|
-
{ value: "weekdays", label: "Weekdays (Mon-Fri)" },
|
|
3359
|
-
{ value: "weekly", label: "Weekly" }
|
|
3360
|
-
];
|
|
3361
|
-
var DAYS_OF_WEEK = [
|
|
3362
|
-
{ value: 0, label: "Sunday" },
|
|
3363
|
-
{ value: 1, label: "Monday" },
|
|
3364
|
-
{ value: 2, label: "Tuesday" },
|
|
3365
|
-
{ value: 3, label: "Wednesday" },
|
|
3366
|
-
{ value: 4, label: "Thursday" },
|
|
3367
|
-
{ value: 5, label: "Friday" },
|
|
3368
|
-
{ value: 6, label: "Saturday" }
|
|
3369
|
-
];
|
|
3370
|
-
function formatTimeForInput(time) {
|
|
3371
|
-
if (!time) return "09:00";
|
|
3372
|
-
return time.slice(0, 5);
|
|
3373
|
-
}
|
|
3374
|
-
function AgentScheduleForm({ initialSchedules, timezone }) {
|
|
3375
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-muted-foreground/25 p-5", children: [
|
|
3376
|
-
/* @__PURE__ */ jsx(SectionHeader, { title: "Schedules", children: /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
3377
|
-
"Timezone: ",
|
|
3378
|
-
timezone
|
|
3379
|
-
] }) }),
|
|
3380
|
-
initialSchedules.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground py-4", children: "No schedules configured." }) : /* @__PURE__ */ jsx("div", { className: "space-y-4", children: initialSchedules.map((schedule) => /* @__PURE__ */ jsx(
|
|
3381
|
-
ScheduleCard,
|
|
3382
|
-
{
|
|
3383
|
-
schedule,
|
|
3384
|
-
timezone
|
|
3385
|
-
},
|
|
3386
|
-
schedule.id
|
|
3387
|
-
)) })
|
|
3388
|
-
] });
|
|
3389
|
-
}
|
|
3390
|
-
function ScheduleCard({
|
|
3391
|
-
schedule,
|
|
3392
|
-
timezone
|
|
3393
|
-
}) {
|
|
3394
|
-
const [frequency, setFrequency] = useState(schedule.frequency);
|
|
3395
|
-
const [time, setTime] = useState(formatTimeForInput(schedule.time));
|
|
3396
|
-
const [dayOfWeek, setDayOfWeek] = useState(schedule.day_of_week ?? 1);
|
|
3397
|
-
const [prompt, setPrompt] = useState(schedule.prompt ?? "");
|
|
3398
|
-
const [enabled, setEnabled] = useState(schedule.enabled);
|
|
3399
|
-
const [name, setName] = useState(schedule.name ?? "");
|
|
3400
|
-
const showTimePicker = ["daily", "weekdays", "weekly"].includes(frequency);
|
|
3401
|
-
const showDayPicker = frequency === "weekly";
|
|
3402
|
-
const canEnable = frequency !== "manual";
|
|
3403
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded border border-muted-foreground/15 p-4 space-y-3", children: [
|
|
3404
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
3405
|
-
/* @__PURE__ */ jsx(
|
|
3406
|
-
Input,
|
|
3407
|
-
{
|
|
3408
|
-
value: name,
|
|
3409
|
-
onChange: (e) => setName(e.target.value),
|
|
3410
|
-
placeholder: "Schedule name (optional)",
|
|
3411
|
-
className: "max-w-xs text-sm"
|
|
3412
|
-
}
|
|
3413
|
-
),
|
|
3414
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: canEnable && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
3415
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: enabled ? "Enabled" : "Disabled" }),
|
|
3416
|
-
/* @__PURE__ */ jsx(
|
|
3417
|
-
"button",
|
|
3418
|
-
{
|
|
3419
|
-
type: "button",
|
|
3420
|
-
role: "switch",
|
|
3421
|
-
"aria-checked": enabled,
|
|
3422
|
-
onClick: () => setEnabled(!enabled),
|
|
3423
|
-
className: `relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${enabled ? "bg-primary" : "bg-muted"}`,
|
|
3424
|
-
children: /* @__PURE__ */ jsx(
|
|
3425
|
-
"span",
|
|
3426
|
-
{
|
|
3427
|
-
className: `pointer-events-none inline-block h-4 w-4 transform rounded-full bg-background shadow-lg ring-0 transition-transform ${enabled ? "translate-x-4" : "translate-x-0"}`
|
|
3428
|
-
}
|
|
3429
|
-
)
|
|
3430
|
-
}
|
|
3431
|
-
)
|
|
3432
|
-
] }) })
|
|
3433
|
-
] }),
|
|
3434
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
3435
|
-
/* @__PURE__ */ jsx(FormField, { label: "Frequency", children: /* @__PURE__ */ jsx(
|
|
3436
|
-
Select,
|
|
3437
|
-
{
|
|
3438
|
-
value: frequency,
|
|
3439
|
-
onChange: (e) => {
|
|
3440
|
-
const newFreq = e.target.value;
|
|
3441
|
-
setFrequency(newFreq);
|
|
3442
|
-
if (newFreq === "manual") setEnabled(false);
|
|
3443
|
-
else setEnabled(true);
|
|
3444
|
-
},
|
|
3445
|
-
children: FREQUENCIES.map((f) => /* @__PURE__ */ jsx("option", { value: f.value, children: f.label }, f.value))
|
|
3446
|
-
}
|
|
3447
|
-
) }),
|
|
3448
|
-
showTimePicker && /* @__PURE__ */ jsx(FormField, { label: `Time (${timezone})`, children: /* @__PURE__ */ jsx(
|
|
3449
|
-
Input,
|
|
3450
|
-
{
|
|
3451
|
-
type: "time",
|
|
3452
|
-
value: time,
|
|
3453
|
-
onChange: (e) => setTime(e.target.value)
|
|
3454
|
-
}
|
|
3455
|
-
) }),
|
|
3456
|
-
showDayPicker && /* @__PURE__ */ jsx(FormField, { label: "Day of Week", children: /* @__PURE__ */ jsx(
|
|
3457
|
-
Select,
|
|
3458
|
-
{
|
|
3459
|
-
value: dayOfWeek.toString(),
|
|
3460
|
-
onChange: (e) => setDayOfWeek(parseInt(e.target.value)),
|
|
3461
|
-
children: DAYS_OF_WEEK.map((d) => /* @__PURE__ */ jsx("option", { value: d.value, children: d.label }, d.value))
|
|
3462
|
-
}
|
|
3463
|
-
) })
|
|
3464
|
-
] }),
|
|
3465
|
-
frequency !== "manual" && /* @__PURE__ */ jsx(FormField, { label: "Prompt", children: /* @__PURE__ */ jsx(
|
|
3466
|
-
Textarea,
|
|
3467
|
-
{
|
|
3468
|
-
value: prompt,
|
|
3469
|
-
onChange: (e) => setPrompt(e.target.value),
|
|
3470
|
-
rows: 3,
|
|
3471
|
-
placeholder: "Enter the prompt to send on each scheduled run...",
|
|
3472
|
-
className: "resize-y min-h-[60px]"
|
|
3473
|
-
}
|
|
3474
|
-
) }),
|
|
3475
|
-
(schedule.last_run_at || schedule.next_run_at) && /* @__PURE__ */ jsxs("div", { className: "flex gap-6 text-sm text-muted-foreground pt-1", children: [
|
|
3476
|
-
schedule.last_run_at && /* @__PURE__ */ jsxs("div", { children: [
|
|
3477
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Last run:" }),
|
|
3478
|
-
" ",
|
|
3479
|
-
/* @__PURE__ */ jsx(LocalDate, { value: schedule.last_run_at })
|
|
3480
|
-
] }),
|
|
3481
|
-
schedule.next_run_at && /* @__PURE__ */ jsxs("div", { children: [
|
|
3482
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Next run:" }),
|
|
3483
|
-
" ",
|
|
3484
|
-
/* @__PURE__ */ jsx(LocalDate, { value: schedule.next_run_at })
|
|
3485
|
-
] })
|
|
3486
|
-
] })
|
|
3487
|
-
] });
|
|
3488
|
-
}
|
|
3489
3614
|
function AgentRuns({ agentId }) {
|
|
3490
3615
|
const { LinkComponent, basePath } = useNavigation();
|
|
3491
3616
|
const { data, error, isLoading } = useApi(
|
|
@@ -3725,7 +3850,7 @@ function AgentA2aInfo({
|
|
|
3725
3850
|
] })
|
|
3726
3851
|
] });
|
|
3727
3852
|
}
|
|
3728
|
-
function AgentDetailPage({ agentId, a2aBaseUrl, tenantSlug
|
|
3853
|
+
function AgentDetailPage({ agentId, a2aBaseUrl, tenantSlug }) {
|
|
3729
3854
|
const { LinkComponent, basePath } = useNavigation();
|
|
3730
3855
|
const { mutate } = useSWRConfig();
|
|
3731
3856
|
const cacheKey = `agent-${agentId}`;
|
|
@@ -3828,16 +3953,6 @@ function AgentDetailPage({ agentId, a2aBaseUrl, tenantSlug, timezone = "UTC" })
|
|
|
3828
3953
|
}
|
|
3829
3954
|
)
|
|
3830
3955
|
},
|
|
3831
|
-
{
|
|
3832
|
-
label: "Schedules",
|
|
3833
|
-
content: /* @__PURE__ */ jsx(
|
|
3834
|
-
AgentScheduleForm,
|
|
3835
|
-
{
|
|
3836
|
-
initialSchedules: [],
|
|
3837
|
-
timezone
|
|
3838
|
-
}
|
|
3839
|
-
)
|
|
3840
|
-
},
|
|
3841
3956
|
{
|
|
3842
3957
|
label: "Runs",
|
|
3843
3958
|
content: /* @__PURE__ */ jsx(AgentRuns, { agentId: agent.id })
|
|
@@ -3847,5 +3962,140 @@ function AgentDetailPage({ agentId, a2aBaseUrl, tenantSlug, timezone = "UTC" })
|
|
|
3847
3962
|
)
|
|
3848
3963
|
] });
|
|
3849
3964
|
}
|
|
3965
|
+
var FREQUENCIES = [
|
|
3966
|
+
{ value: "manual", label: "Manual (no schedule)" },
|
|
3967
|
+
{ value: "hourly", label: "Hourly" },
|
|
3968
|
+
{ value: "daily", label: "Daily" },
|
|
3969
|
+
{ value: "weekdays", label: "Weekdays (Mon-Fri)" },
|
|
3970
|
+
{ value: "weekly", label: "Weekly" }
|
|
3971
|
+
];
|
|
3972
|
+
var DAYS_OF_WEEK = [
|
|
3973
|
+
{ value: 0, label: "Sunday" },
|
|
3974
|
+
{ value: 1, label: "Monday" },
|
|
3975
|
+
{ value: 2, label: "Tuesday" },
|
|
3976
|
+
{ value: 3, label: "Wednesday" },
|
|
3977
|
+
{ value: 4, label: "Thursday" },
|
|
3978
|
+
{ value: 5, label: "Friday" },
|
|
3979
|
+
{ value: 6, label: "Saturday" }
|
|
3980
|
+
];
|
|
3981
|
+
function formatTimeForInput(time) {
|
|
3982
|
+
if (!time) return "09:00";
|
|
3983
|
+
return time.slice(0, 5);
|
|
3984
|
+
}
|
|
3985
|
+
function AgentScheduleForm({ initialSchedules, timezone }) {
|
|
3986
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-muted-foreground/25 p-5", children: [
|
|
3987
|
+
/* @__PURE__ */ jsx(SectionHeader, { title: "Schedules", children: /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
3988
|
+
"Timezone: ",
|
|
3989
|
+
timezone
|
|
3990
|
+
] }) }),
|
|
3991
|
+
initialSchedules.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground py-4", children: "No schedules configured." }) : /* @__PURE__ */ jsx("div", { className: "space-y-4", children: initialSchedules.map((schedule) => /* @__PURE__ */ jsx(
|
|
3992
|
+
ScheduleCard,
|
|
3993
|
+
{
|
|
3994
|
+
schedule,
|
|
3995
|
+
timezone
|
|
3996
|
+
},
|
|
3997
|
+
schedule.id
|
|
3998
|
+
)) })
|
|
3999
|
+
] });
|
|
4000
|
+
}
|
|
4001
|
+
function ScheduleCard({
|
|
4002
|
+
schedule,
|
|
4003
|
+
timezone
|
|
4004
|
+
}) {
|
|
4005
|
+
const [frequency, setFrequency] = useState(schedule.frequency);
|
|
4006
|
+
const [time, setTime] = useState(formatTimeForInput(schedule.time));
|
|
4007
|
+
const [dayOfWeek, setDayOfWeek] = useState(schedule.day_of_week ?? 1);
|
|
4008
|
+
const [prompt, setPrompt] = useState(schedule.prompt ?? "");
|
|
4009
|
+
const [enabled, setEnabled] = useState(schedule.enabled);
|
|
4010
|
+
const [name, setName] = useState(schedule.name ?? "");
|
|
4011
|
+
const showTimePicker = ["daily", "weekdays", "weekly"].includes(frequency);
|
|
4012
|
+
const showDayPicker = frequency === "weekly";
|
|
4013
|
+
const canEnable = frequency !== "manual";
|
|
4014
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded border border-muted-foreground/15 p-4 space-y-3", children: [
|
|
4015
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
4016
|
+
/* @__PURE__ */ jsx(
|
|
4017
|
+
Input,
|
|
4018
|
+
{
|
|
4019
|
+
value: name,
|
|
4020
|
+
onChange: (e) => setName(e.target.value),
|
|
4021
|
+
placeholder: "Schedule name (optional)",
|
|
4022
|
+
className: "max-w-xs text-sm"
|
|
4023
|
+
}
|
|
4024
|
+
),
|
|
4025
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: canEnable && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
4026
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: enabled ? "Enabled" : "Disabled" }),
|
|
4027
|
+
/* @__PURE__ */ jsx(
|
|
4028
|
+
"button",
|
|
4029
|
+
{
|
|
4030
|
+
type: "button",
|
|
4031
|
+
role: "switch",
|
|
4032
|
+
"aria-checked": enabled,
|
|
4033
|
+
onClick: () => setEnabled(!enabled),
|
|
4034
|
+
className: `relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${enabled ? "bg-primary" : "bg-muted"}`,
|
|
4035
|
+
children: /* @__PURE__ */ jsx(
|
|
4036
|
+
"span",
|
|
4037
|
+
{
|
|
4038
|
+
className: `pointer-events-none inline-block h-4 w-4 transform rounded-full bg-background shadow-lg ring-0 transition-transform ${enabled ? "translate-x-4" : "translate-x-0"}`
|
|
4039
|
+
}
|
|
4040
|
+
)
|
|
4041
|
+
}
|
|
4042
|
+
)
|
|
4043
|
+
] }) })
|
|
4044
|
+
] }),
|
|
4045
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
4046
|
+
/* @__PURE__ */ jsx(FormField, { label: "Frequency", children: /* @__PURE__ */ jsx(
|
|
4047
|
+
Select,
|
|
4048
|
+
{
|
|
4049
|
+
value: frequency,
|
|
4050
|
+
onChange: (e) => {
|
|
4051
|
+
const newFreq = e.target.value;
|
|
4052
|
+
setFrequency(newFreq);
|
|
4053
|
+
if (newFreq === "manual") setEnabled(false);
|
|
4054
|
+
else setEnabled(true);
|
|
4055
|
+
},
|
|
4056
|
+
children: FREQUENCIES.map((f) => /* @__PURE__ */ jsx("option", { value: f.value, children: f.label }, f.value))
|
|
4057
|
+
}
|
|
4058
|
+
) }),
|
|
4059
|
+
showTimePicker && /* @__PURE__ */ jsx(FormField, { label: `Time (${timezone})`, children: /* @__PURE__ */ jsx(
|
|
4060
|
+
Input,
|
|
4061
|
+
{
|
|
4062
|
+
type: "time",
|
|
4063
|
+
value: time,
|
|
4064
|
+
onChange: (e) => setTime(e.target.value)
|
|
4065
|
+
}
|
|
4066
|
+
) }),
|
|
4067
|
+
showDayPicker && /* @__PURE__ */ jsx(FormField, { label: "Day of Week", children: /* @__PURE__ */ jsx(
|
|
4068
|
+
Select,
|
|
4069
|
+
{
|
|
4070
|
+
value: dayOfWeek.toString(),
|
|
4071
|
+
onChange: (e) => setDayOfWeek(parseInt(e.target.value)),
|
|
4072
|
+
children: DAYS_OF_WEEK.map((d) => /* @__PURE__ */ jsx("option", { value: d.value, children: d.label }, d.value))
|
|
4073
|
+
}
|
|
4074
|
+
) })
|
|
4075
|
+
] }),
|
|
4076
|
+
frequency !== "manual" && /* @__PURE__ */ jsx(FormField, { label: "Prompt", children: /* @__PURE__ */ jsx(
|
|
4077
|
+
Textarea,
|
|
4078
|
+
{
|
|
4079
|
+
value: prompt,
|
|
4080
|
+
onChange: (e) => setPrompt(e.target.value),
|
|
4081
|
+
rows: 3,
|
|
4082
|
+
placeholder: "Enter the prompt to send on each scheduled run...",
|
|
4083
|
+
className: "resize-y min-h-[60px]"
|
|
4084
|
+
}
|
|
4085
|
+
) }),
|
|
4086
|
+
(schedule.last_run_at || schedule.next_run_at) && /* @__PURE__ */ jsxs("div", { className: "flex gap-6 text-sm text-muted-foreground pt-1", children: [
|
|
4087
|
+
schedule.last_run_at && /* @__PURE__ */ jsxs("div", { children: [
|
|
4088
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Last run:" }),
|
|
4089
|
+
" ",
|
|
4090
|
+
/* @__PURE__ */ jsx(LocalDate, { value: schedule.last_run_at })
|
|
4091
|
+
] }),
|
|
4092
|
+
schedule.next_run_at && /* @__PURE__ */ jsxs("div", { children: [
|
|
4093
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Next run:" }),
|
|
4094
|
+
" ",
|
|
4095
|
+
/* @__PURE__ */ jsx(LocalDate, { value: schedule.next_run_at })
|
|
4096
|
+
] })
|
|
4097
|
+
] })
|
|
4098
|
+
] });
|
|
4099
|
+
}
|
|
3850
4100
|
|
|
3851
4101
|
export { AdminTable, AdminTableHead, AdminTableRow, AgentA2aInfo, AgentConnectorsManager, AgentDetailPage, AgentEditForm, AgentListPage, AgentPlaneProvider, AgentPluginManager, AgentRuns, AgentScheduleForm, AgentSkillManager, Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, ConfirmDialog, CopyButton, DashboardPage, DetailPageHeader, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, EmptyRow, FormError, FormField, Input, LocalDate, McpServerListPage, MetricCard, ModelSelector, PaginationBar, PluginMarketplaceDetailPage, PluginMarketplaceListPage, RunDetailPage, RunListPage, RunSourceBadge, RunStatusBadge, SectionHeader, Select, SettingsPage, Skeleton, Tabs, Textarea, Th, ToolkitMultiselect, TranscriptViewer, badgeVariants, buttonVariants, cn, parsePaginationParams, useAgentPlaneClient, useApi, useAuthError, useNavigation };
|