@vertesia/tools-admin-ui 1.0.0-dev.20260227.112605Z → 1.0.0-dev.20260305.083323Z
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/lib/AdminApp.d.ts +3 -1
- package/lib/AdminApp.d.ts.map +1 -1
- package/lib/components/AdminTopBar.d.ts +6 -0
- package/lib/components/AdminTopBar.d.ts.map +1 -0
- package/lib/components/CollectionCard.d.ts.map +1 -1
- package/lib/components/DetailPage.d.ts.map +1 -1
- package/lib/components/EndpointPanel.d.ts.map +1 -1
- package/lib/components/HeroSection.d.ts.map +1 -1
- package/lib/components/ResourceCard.d.ts.map +1 -1
- package/lib/components/ResourceSection.d.ts.map +1 -1
- package/lib/components/SearchBar.d.ts.map +1 -1
- package/lib/components/SummaryBadge.d.ts.map +1 -1
- package/lib/components/index.d.ts +6 -5
- package/lib/components/index.d.ts.map +1 -1
- package/lib/components/typeVariants.d.ts +5 -0
- package/lib/components/typeVariants.d.ts.map +1 -0
- package/lib/hooks.d.ts +1 -1
- package/lib/hooks.d.ts.map +1 -1
- package/lib/pages/HomePage.d.ts.map +1 -1
- package/lib/pages/InteractionCollection.d.ts.map +1 -1
- package/lib/pages/InteractionDetail.d.ts.map +1 -1
- package/lib/pages/SkillCollection.d.ts.map +1 -1
- package/lib/pages/SkillDetail.d.ts.map +1 -1
- package/lib/pages/TemplateCollection.d.ts.map +1 -1
- package/lib/pages/TemplateDetail.d.ts.map +1 -1
- package/lib/pages/ToolCollection.d.ts.map +1 -1
- package/lib/pages/TypeCollection.d.ts.map +1 -1
- package/lib/pages/TypeDetail.d.ts.map +1 -1
- package/lib/tools-admin-ui.js +410 -377
- package/lib/tools-admin-ui.js.map +1 -1
- package/package.json +8 -4
- package/src/AdminApp.tsx +21 -17
- package/src/components/AdminTopBar.tsx +39 -0
- package/src/components/CollectionCard.tsx +18 -13
- package/src/components/DetailPage.tsx +20 -11
- package/src/components/EndpointPanel.tsx +16 -7
- package/src/components/HeroSection.tsx +51 -45
- package/src/components/ResourceCard.tsx +23 -18
- package/src/components/ResourceSection.tsx +7 -5
- package/src/components/SearchBar.tsx +8 -6
- package/src/components/SummaryBadge.tsx +4 -3
- package/src/components/index.ts +6 -5
- package/src/components/typeVariants.ts +18 -0
- package/src/dev/index.css +13 -0
- package/src/dev/main.tsx +5 -2
- package/src/hooks.ts +2 -1
- package/src/pages/HomePage.tsx +18 -15
- package/src/pages/InteractionCollection.tsx +25 -27
- package/src/pages/InteractionDetail.tsx +35 -34
- package/src/pages/SkillCollection.tsx +29 -32
- package/src/pages/SkillDetail.tsx +31 -41
- package/src/pages/TemplateCollection.tsx +25 -21
- package/src/pages/TemplateDetail.tsx +18 -17
- package/src/pages/ToolCollection.tsx +22 -16
- package/src/pages/TypeCollection.tsx +32 -24
- package/src/pages/TypeDetail.tsx +16 -18
- package/src/theme.css +12 -0
- package/src/admin.css +0 -650
package/lib/tools-admin-ui.js
CHANGED
|
@@ -1,8 +1,40 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ModeToggle, Avatar, Button, useFetch, Card, CardContent, Badge, DotBadge, Separator, Input, Spinner } from "@vertesia/ui/core";
|
|
2
3
|
import { NavLink, useParams, NestedRouterProvider, RouteComponent } from "@vertesia/ui/router";
|
|
3
|
-
import { useFetch } from "@vertesia/ui/core";
|
|
4
4
|
import { createContext, useContext, useState, useMemo } from "react";
|
|
5
5
|
import { useUserSession } from "@vertesia/ui/session";
|
|
6
|
+
import { LogOut, ArrowLeft, Check, Copy, LayoutDashboard, Download } from "lucide-react";
|
|
7
|
+
const AdminContext = createContext(void 0);
|
|
8
|
+
function useAdminContext() {
|
|
9
|
+
const ctx = useContext(AdminContext);
|
|
10
|
+
if (!ctx) throw new Error("useAdminContext must be used within AdminApp");
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
function AdminTopBar({ title }) {
|
|
14
|
+
const { user, logout } = useUserSession();
|
|
15
|
+
return /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-40 flex h-14 items-center justify-between border-b border-border bg-background px-6", children: [
|
|
16
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
17
|
+
/* @__PURE__ */ jsx("div", { className: "flex size-8 items-center justify-center rounded-lg bg-primary text-xs font-semibold uppercase tracking-wider text-primary-foreground", children: title.split(/\s+/).map((w) => w[0]).filter(Boolean).slice(0, 2).join("") }),
|
|
18
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", children: title })
|
|
19
|
+
] }),
|
|
20
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
21
|
+
/* @__PURE__ */ jsx(ModeToggle, { label: false }),
|
|
22
|
+
user && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23
|
+
/* @__PURE__ */ jsx(Avatar, { size: "sm", name: user.name, color: "bg-primary" }),
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
Button,
|
|
26
|
+
{
|
|
27
|
+
variant: "outline",
|
|
28
|
+
size: "sm",
|
|
29
|
+
onClick: () => logout(),
|
|
30
|
+
alt: "Sign out",
|
|
31
|
+
children: /* @__PURE__ */ jsx(LogOut, { className: "size-4" })
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
] })
|
|
35
|
+
] })
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
6
38
|
function formatTitle(name) {
|
|
7
39
|
return name.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
8
40
|
}
|
|
@@ -183,11 +215,51 @@ function useResourceData(baseUrl, mcpEndpoints) {
|
|
|
183
215
|
);
|
|
184
216
|
}, [baseUrl, mcpEndpoints]);
|
|
185
217
|
}
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
218
|
+
const TYPE_VARIANTS = {
|
|
219
|
+
tool: "bg-blue-100 text-blue-800 dark:bg-blue-500/15 dark:text-blue-300",
|
|
220
|
+
skill: "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/15 dark:text-emerald-300",
|
|
221
|
+
interaction: "bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300",
|
|
222
|
+
type: "bg-gray-100 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300",
|
|
223
|
+
template: "bg-violet-100 text-violet-800 dark:bg-violet-500/15 dark:text-violet-300",
|
|
224
|
+
mcp: "bg-pink-100 text-pink-800 dark:bg-pink-500/15 dark:text-pink-300"
|
|
225
|
+
};
|
|
226
|
+
const ROLE_VARIANTS = {
|
|
227
|
+
system: "bg-blue-100 text-blue-800 dark:bg-blue-500/15 dark:text-blue-300",
|
|
228
|
+
user: "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/15 dark:text-emerald-300",
|
|
229
|
+
assistant: "bg-violet-100 text-violet-800 dark:bg-violet-500/15 dark:text-violet-300",
|
|
230
|
+
safety: "bg-pink-100 text-pink-800 dark:bg-pink-500/15 dark:text-pink-300",
|
|
231
|
+
tool: "bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300"
|
|
232
|
+
};
|
|
233
|
+
function CollectionCard({ collection }) {
|
|
234
|
+
const href = `/${collection.type}s/${collection.name}`;
|
|
235
|
+
return /* @__PURE__ */ jsx(NavLink, { href, className: "block no-underline", children: /* @__PURE__ */ jsx(Card, { className: "cursor-pointer transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
236
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS[collection.type] ?? ""}`, children: collection.type }),
|
|
237
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: collection.title }),
|
|
238
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: collection.description || "No description" }),
|
|
239
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 font-mono text-xs text-muted-foreground", children: [
|
|
240
|
+
collection.count,
|
|
241
|
+
" ",
|
|
242
|
+
collection.count === 1 ? "item" : "items"
|
|
243
|
+
] })
|
|
244
|
+
] }) }) });
|
|
245
|
+
}
|
|
246
|
+
function DetailPage({ type, title, description, tags, backHref = "/", children }) {
|
|
247
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl px-7 py-10", children: [
|
|
248
|
+
/* @__PURE__ */ jsxs("nav", { className: "mb-5 flex items-center gap-4", children: [
|
|
249
|
+
backHref !== "/" && /* @__PURE__ */ jsx(NavLink, { href: "/", className: "text-sm text-primary hover:opacity-75", children: "Home" }),
|
|
250
|
+
/* @__PURE__ */ jsxs(NavLink, { href: backHref, className: "flex items-center gap-1 text-sm text-primary hover:opacity-75", children: [
|
|
251
|
+
/* @__PURE__ */ jsx(ArrowLeft, { className: "size-3.5" }),
|
|
252
|
+
"Back"
|
|
253
|
+
] })
|
|
254
|
+
] }),
|
|
255
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
256
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS[type] ?? ""}`, children: type }),
|
|
257
|
+
/* @__PURE__ */ jsx("h1", { className: "-tracking-wide text-3xl font-bold text-foreground", children: title }),
|
|
258
|
+
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm leading-relaxed text-muted-foreground", children: description }),
|
|
259
|
+
tags && tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-1.5", children: tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tag)) })
|
|
260
|
+
] }),
|
|
261
|
+
children
|
|
262
|
+
] });
|
|
191
263
|
}
|
|
192
264
|
function EndpointPanel({ label, path }) {
|
|
193
265
|
const [copied, setCopied] = useState(false);
|
|
@@ -197,18 +269,26 @@ function EndpointPanel({ label, path }) {
|
|
|
197
269
|
setCopied(true);
|
|
198
270
|
setTimeout(() => setCopied(false), 1500);
|
|
199
271
|
}
|
|
200
|
-
return /* @__PURE__ */ jsxs("div", { className: "
|
|
201
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
202
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
203
|
-
/* @__PURE__ */ jsx("code", { className: "
|
|
204
|
-
/* @__PURE__ */ jsx(
|
|
272
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
273
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 text-[0.7rem] font-medium uppercase tracking-widest text-primary", children: label }),
|
|
274
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-muted-background px-3 py-2", children: [
|
|
275
|
+
/* @__PURE__ */ jsx("code", { className: "flex-1 font-mono text-sm text-foreground", children: path }),
|
|
276
|
+
/* @__PURE__ */ jsx(
|
|
277
|
+
Button,
|
|
278
|
+
{
|
|
279
|
+
variant: "ghost",
|
|
280
|
+
size: "xs",
|
|
281
|
+
onClick: handleCopy,
|
|
282
|
+
"aria-label": "Copy full URL",
|
|
283
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" })
|
|
284
|
+
}
|
|
285
|
+
)
|
|
205
286
|
] })
|
|
206
287
|
] });
|
|
207
288
|
}
|
|
208
289
|
function SummaryBadge({ count, label }) {
|
|
209
290
|
if (count === 0) return null;
|
|
210
|
-
return /* @__PURE__ */ jsxs(
|
|
211
|
-
/* @__PURE__ */ jsx("span", { className: "vta-badge-dot" }),
|
|
291
|
+
return /* @__PURE__ */ jsxs(DotBadge, { variant: "success", children: [
|
|
212
292
|
count,
|
|
213
293
|
" ",
|
|
214
294
|
label,
|
|
@@ -235,131 +315,112 @@ const badgeLabels = [
|
|
|
235
315
|
];
|
|
236
316
|
function HeroSection({ title, version, resources }) {
|
|
237
317
|
const counts = countByType(resources);
|
|
238
|
-
return /* @__PURE__ */ jsxs("
|
|
239
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
240
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
241
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
318
|
+
return /* @__PURE__ */ jsx(Card, { className: "mb-10 overflow-hidden border bg-linear-to-br from-card to-muted-background", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 p-6 md:flex-row md:items-start md:justify-between", children: [
|
|
319
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3", children: [
|
|
320
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
321
|
+
/* @__PURE__ */ jsx("div", { className: "flex size-14 items-center justify-center rounded-xl bg-linear-to-br from-sky-400 to-indigo-500 text-sm font-semibold uppercase tracking-wider text-white shadow-lg", children: getInitials(title) }),
|
|
242
322
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
243
|
-
/* @__PURE__ */ jsx("p", { className: "
|
|
244
|
-
/* @__PURE__ */ jsx("h1", { className: "
|
|
323
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-widest text-muted-foreground", children: "Tools Server" }),
|
|
324
|
+
/* @__PURE__ */ jsx("h1", { className: "-tracking-wide text-2xl font-bold text-foreground", children: title })
|
|
245
325
|
] })
|
|
246
326
|
] }),
|
|
247
|
-
/* @__PURE__ */ jsx("p", { className: "
|
|
248
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
249
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
250
|
-
/* @__PURE__ */ jsxs(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
327
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Discover the tools, skills, interactions, and content types exposed by this server." }),
|
|
328
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: badgeLabels.map(({ type, label }) => /* @__PURE__ */ jsx(SummaryBadge, { count: counts[type] || 0, label }, type)) }),
|
|
329
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-3 pt-1", children: [
|
|
330
|
+
/* @__PURE__ */ jsxs(
|
|
331
|
+
"a",
|
|
332
|
+
{
|
|
333
|
+
href: "/app/",
|
|
334
|
+
target: "_blank",
|
|
335
|
+
rel: "noopener noreferrer",
|
|
336
|
+
className: "inline-flex h-8 items-center gap-2 rounded bg-primary px-3 text-xs font-medium text-white shadow-xs hover:bg-primary/90",
|
|
337
|
+
children: [
|
|
338
|
+
/* @__PURE__ */ jsx(LayoutDashboard, { className: "size-4" }),
|
|
339
|
+
"UI Plugin Dev"
|
|
340
|
+
]
|
|
341
|
+
}
|
|
342
|
+
),
|
|
343
|
+
/* @__PURE__ */ jsxs(
|
|
344
|
+
"a",
|
|
345
|
+
{
|
|
346
|
+
href: "/lib/plugin.js",
|
|
347
|
+
className: "inline-flex h-8 items-center gap-2 rounded bg-primary/5 px-3 text-xs font-medium text-primary shadow-xs hover:bg-primary/10 dark:bg-primary/10 dark:hover:bg-primary/20",
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ jsx(Download, { className: "size-4" }),
|
|
350
|
+
"Plugin Bundle"
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
)
|
|
265
354
|
] })
|
|
266
355
|
] }),
|
|
267
|
-
/* @__PURE__ */ jsxs("aside", { className: "
|
|
356
|
+
/* @__PURE__ */ jsxs("aside", { className: "min-w-55 max-w-65 shrink-0", children: [
|
|
268
357
|
/* @__PURE__ */ jsx(EndpointPanel, { label: "Base endpoint", path: "/api" }),
|
|
269
358
|
/* @__PURE__ */ jsx(EndpointPanel, { label: "Package endpoint", path: "/api/package" }),
|
|
270
|
-
/* @__PURE__ */ jsxs("p", { className: "
|
|
359
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: [
|
|
271
360
|
"Use ",
|
|
272
|
-
/* @__PURE__ */ jsx("strong", { children: "POST /api/tools/<collection>" }),
|
|
361
|
+
/* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "POST /api/tools/<collection>" }),
|
|
273
362
|
" or",
|
|
274
363
|
" ",
|
|
275
|
-
/* @__PURE__ */ jsx("strong", { children: "POST /api/skills/<collection>" }),
|
|
364
|
+
/* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "POST /api/skills/<collection>" }),
|
|
276
365
|
" to call these from your apps or agents."
|
|
277
366
|
] }),
|
|
278
|
-
/* @__PURE__ */ jsxs("p", { className: "
|
|
367
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
|
|
279
368
|
"v",
|
|
280
369
|
version
|
|
281
370
|
] })
|
|
282
371
|
] })
|
|
372
|
+
] }) });
|
|
373
|
+
}
|
|
374
|
+
function ResourceCard({ resource }) {
|
|
375
|
+
return /* @__PURE__ */ jsx(Card, { className: "transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
376
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS[resource.type] ?? ""}`, children: resource.type }),
|
|
377
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: resource.title }),
|
|
378
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: resource.description || "No description" }),
|
|
379
|
+
resource.tags && resource.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-1", children: resource.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tag)) }),
|
|
380
|
+
resource.url && /* @__PURE__ */ jsx("div", { className: "mt-2 truncate font-mono text-xs text-muted-foreground", children: resource.url })
|
|
381
|
+
] }) });
|
|
382
|
+
}
|
|
383
|
+
function ResourceSection({ title, subtitle, resources, showDivider }) {
|
|
384
|
+
if (resources.length === 0) return null;
|
|
385
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
386
|
+
showDivider && /* @__PURE__ */ jsx(Separator, { className: "my-8" }),
|
|
387
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
388
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold text-foreground", children: [
|
|
389
|
+
title,
|
|
390
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-2 text-sm font-normal text-muted-foreground", children: [
|
|
391
|
+
"(",
|
|
392
|
+
resources.length,
|
|
393
|
+
")"
|
|
394
|
+
] })
|
|
395
|
+
] }),
|
|
396
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: subtitle })
|
|
397
|
+
] }),
|
|
398
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: resources.map((r) => /* @__PURE__ */ jsx(ResourceCard, { resource: r }, `${r.type}:${r.name}`)) })
|
|
283
399
|
] });
|
|
284
400
|
}
|
|
285
401
|
function SearchBar({ value, onChange, placeholder, resultCount, totalCount }) {
|
|
286
402
|
const hasQuery = value.trim().length > 0;
|
|
287
403
|
const noResults = hasQuery && resultCount === 0;
|
|
288
|
-
return /* @__PURE__ */ jsxs("div", { className: "
|
|
404
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-7", children: [
|
|
289
405
|
/* @__PURE__ */ jsx(
|
|
290
|
-
|
|
406
|
+
Input,
|
|
291
407
|
{
|
|
292
408
|
type: "search",
|
|
293
409
|
value,
|
|
294
|
-
onChange
|
|
410
|
+
onChange,
|
|
295
411
|
placeholder: placeholder || "Search collections...",
|
|
296
|
-
className: "
|
|
412
|
+
className: "max-w-sm rounded-full",
|
|
297
413
|
autoComplete: "off"
|
|
298
414
|
}
|
|
299
415
|
),
|
|
300
|
-
hasQuery && !noResults && /* @__PURE__ */ jsxs("p", { className: "
|
|
416
|
+
hasQuery && !noResults && /* @__PURE__ */ jsxs("p", { className: "mt-1.5 text-xs text-muted-foreground", children: [
|
|
301
417
|
"Showing ",
|
|
302
418
|
resultCount,
|
|
303
419
|
" of ",
|
|
304
420
|
totalCount,
|
|
305
421
|
" resources"
|
|
306
422
|
] }),
|
|
307
|
-
noResults && /* @__PURE__ */ jsx("p", { className: "
|
|
308
|
-
] });
|
|
309
|
-
}
|
|
310
|
-
function ResourceCard({ resource }) {
|
|
311
|
-
return /* @__PURE__ */ jsxs("div", { className: "vta-card", children: [
|
|
312
|
-
/* @__PURE__ */ jsx("span", { className: `vta-card-type vta-card-type--${resource.type}`, children: resource.type }),
|
|
313
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-title", children: resource.title }),
|
|
314
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: resource.description || "No description" }),
|
|
315
|
-
resource.tags && resource.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "vta-card-tags", children: resource.tags.map((tag) => /* @__PURE__ */ jsx("span", { className: "vta-tag", children: tag }, tag)) }),
|
|
316
|
-
resource.url && /* @__PURE__ */ jsx("div", { className: "vta-card-url", children: resource.url })
|
|
317
|
-
] });
|
|
318
|
-
}
|
|
319
|
-
function ResourceSection({ title, subtitle, resources, showDivider }) {
|
|
320
|
-
if (resources.length === 0) return null;
|
|
321
|
-
return /* @__PURE__ */ jsxs("section", { children: [
|
|
322
|
-
showDivider && /* @__PURE__ */ jsx("hr", { className: "vta-divider" }),
|
|
323
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
324
|
-
/* @__PURE__ */ jsxs("h2", { className: "vta-section-title", children: [
|
|
325
|
-
title,
|
|
326
|
-
/* @__PURE__ */ jsxs("span", { className: "vta-section-count", children: [
|
|
327
|
-
"(",
|
|
328
|
-
resources.length,
|
|
329
|
-
")"
|
|
330
|
-
] })
|
|
331
|
-
] }),
|
|
332
|
-
/* @__PURE__ */ jsx("p", { className: "vta-section-subtitle", children: subtitle })
|
|
333
|
-
] }),
|
|
334
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-grid", children: resources.map((r) => /* @__PURE__ */ jsx(ResourceCard, { resource: r }, `${r.type}:${r.name}`)) })
|
|
335
|
-
] });
|
|
336
|
-
}
|
|
337
|
-
function CollectionCard({ collection }) {
|
|
338
|
-
const href = `/${collection.type}s/${collection.name}`;
|
|
339
|
-
return /* @__PURE__ */ jsx(NavLink, { href, className: "vta-card-link", children: /* @__PURE__ */ jsxs("div", { className: "vta-card vta-card--link", children: [
|
|
340
|
-
/* @__PURE__ */ jsx("span", { className: `vta-card-type vta-card-type--${collection.type}`, children: collection.type }),
|
|
341
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-title", children: collection.title }),
|
|
342
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: collection.description || "No description" }),
|
|
343
|
-
/* @__PURE__ */ jsxs("div", { className: "vta-card-url", children: [
|
|
344
|
-
collection.count,
|
|
345
|
-
" ",
|
|
346
|
-
collection.count === 1 ? "item" : "items"
|
|
347
|
-
] })
|
|
348
|
-
] }) });
|
|
349
|
-
}
|
|
350
|
-
function DetailPage({ type, title, description, tags, backHref = "/", children }) {
|
|
351
|
-
return /* @__PURE__ */ jsxs("div", { className: "vta-root", children: [
|
|
352
|
-
/* @__PURE__ */ jsxs("nav", { className: "vta-detail-nav", children: [
|
|
353
|
-
backHref !== "/" && /* @__PURE__ */ jsx(NavLink, { href: "/", className: "vta-detail-back", children: "Home" }),
|
|
354
|
-
/* @__PURE__ */ jsx(NavLink, { href: backHref, className: "vta-detail-back", children: "← Back" })
|
|
355
|
-
] }),
|
|
356
|
-
/* @__PURE__ */ jsxs("div", { className: "vta-detail-header", children: [
|
|
357
|
-
/* @__PURE__ */ jsx("span", { className: `vta-card-type vta-card-type--${type}`, children: type }),
|
|
358
|
-
/* @__PURE__ */ jsx("h1", { className: "vta-detail-title", children: title }),
|
|
359
|
-
description && /* @__PURE__ */ jsx("p", { className: "vta-detail-desc", children: description }),
|
|
360
|
-
tags && tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "vta-card-tags", children: tags.map((tag) => /* @__PURE__ */ jsx("span", { className: "vta-tag", children: tag }, tag)) })
|
|
361
|
-
] }),
|
|
362
|
-
children
|
|
423
|
+
noResults && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-destructive", children: "No resources match this search." })
|
|
363
424
|
] });
|
|
364
425
|
}
|
|
365
426
|
const sections = [
|
|
@@ -378,7 +439,7 @@ function HomePage() {
|
|
|
378
439
|
[resources, search]
|
|
379
440
|
);
|
|
380
441
|
const isSearching = search.trim().length > 0;
|
|
381
|
-
return /* @__PURE__ */ jsxs("div", { className: "
|
|
442
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl px-7 py-10", children: [
|
|
382
443
|
/* @__PURE__ */ jsx(
|
|
383
444
|
HeroSection,
|
|
384
445
|
{
|
|
@@ -397,95 +458,81 @@ function HomePage() {
|
|
|
397
458
|
totalCount: resources.length
|
|
398
459
|
}
|
|
399
460
|
),
|
|
400
|
-
isSearching ? (
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
/*
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
"(",
|
|
428
|
-
sectionCollections.length,
|
|
429
|
-
sectionCollections.length === 1 ? " collection" : " collections",
|
|
430
|
-
")"
|
|
431
|
-
] })
|
|
432
|
-
] }),
|
|
433
|
-
/* @__PURE__ */ jsx("p", { className: "vta-section-subtitle", children: section.subtitle })
|
|
461
|
+
isSearching ? sections.map((section, i) => {
|
|
462
|
+
const sectionItems = filtered.filter((r) => r.type === section.type);
|
|
463
|
+
return /* @__PURE__ */ jsx(
|
|
464
|
+
ResourceSection,
|
|
465
|
+
{
|
|
466
|
+
title: section.title,
|
|
467
|
+
subtitle: section.subtitle,
|
|
468
|
+
resources: sectionItems,
|
|
469
|
+
showDivider: i > 0
|
|
470
|
+
},
|
|
471
|
+
section.type
|
|
472
|
+
);
|
|
473
|
+
}) : sections.map((section, i) => {
|
|
474
|
+
const sectionCollections = collections.filter((c) => c.type === section.type);
|
|
475
|
+
const mcpResources = section.type === "mcp" ? resources.filter((r) => r.type === "mcp") : [];
|
|
476
|
+
if (sectionCollections.length === 0 && mcpResources.length === 0) return null;
|
|
477
|
+
return /* @__PURE__ */ jsxs("section", { children: [
|
|
478
|
+
i > 0 && /* @__PURE__ */ jsx(Separator, { className: "my-8" }),
|
|
479
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
480
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold text-foreground", children: [
|
|
481
|
+
section.title,
|
|
482
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-2 text-sm font-normal text-muted-foreground", children: [
|
|
483
|
+
"(",
|
|
484
|
+
sectionCollections.length,
|
|
485
|
+
sectionCollections.length === 1 ? " collection" : " collections",
|
|
486
|
+
")"
|
|
487
|
+
] })
|
|
434
488
|
] }),
|
|
435
|
-
/* @__PURE__ */
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
489
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: section.subtitle })
|
|
490
|
+
] }),
|
|
491
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [
|
|
492
|
+
sectionCollections.map((col) => /* @__PURE__ */ jsx(CollectionCard, { collection: col }, `${col.type}:${col.name}`)),
|
|
493
|
+
mcpResources.map((r) => /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border bg-card p-5 shadow-sm", children: [
|
|
494
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.mcp}`, children: "mcp" }),
|
|
495
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: r.title }),
|
|
496
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: r.description || "No description" }),
|
|
497
|
+
r.url && /* @__PURE__ */ jsx("div", { className: "mt-2 truncate font-mono text-xs text-muted-foreground", children: r.url })
|
|
498
|
+
] }, r.name))
|
|
499
|
+
] })
|
|
500
|
+
] }, section.type);
|
|
501
|
+
})
|
|
447
502
|
] });
|
|
448
503
|
}
|
|
449
504
|
function InteractionCollection() {
|
|
450
505
|
const collection = useParams("collection");
|
|
451
506
|
const { baseUrl } = useAdminContext();
|
|
452
|
-
const { data: interactions,
|
|
507
|
+
const { data: interactions, error } = useFetch(
|
|
453
508
|
() => fetch(`${baseUrl}/interactions/${collection}`).then((r) => {
|
|
454
509
|
if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
|
|
455
510
|
return r.json();
|
|
456
511
|
}),
|
|
457
512
|
[baseUrl, collection]
|
|
458
513
|
);
|
|
459
|
-
if (
|
|
460
|
-
return /* @__PURE__ */
|
|
461
|
-
}
|
|
462
|
-
if (error || !interactions) {
|
|
463
|
-
return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
|
|
514
|
+
if (error) {
|
|
515
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
464
516
|
"Failed to load collection “",
|
|
465
517
|
collection,
|
|
466
518
|
"”."
|
|
467
519
|
] });
|
|
468
520
|
}
|
|
521
|
+
if (!interactions) {
|
|
522
|
+
return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
523
|
+
}
|
|
469
524
|
return /* @__PURE__ */ jsx(
|
|
470
525
|
DetailPage,
|
|
471
526
|
{
|
|
472
527
|
type: "interaction",
|
|
473
528
|
title: collection,
|
|
474
529
|
description: `${interactions.length} interaction${interactions.length !== 1 ? "s" : ""} in this collection.`,
|
|
475
|
-
children: /* @__PURE__ */ jsx("div", { className: "
|
|
476
|
-
|
|
477
|
-
{
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
/* @__PURE__ */ jsx("span", { className: "vta-card-type vta-card-type--interaction", children: "interaction" }),
|
|
482
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-title", children: inter.title || inter.name }),
|
|
483
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: inter.description || "No description" }),
|
|
484
|
-
inter.tags && inter.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "vta-card-tags", children: inter.tags.map((tag) => /* @__PURE__ */ jsx("span", { className: "vta-tag", children: tag }, tag)) })
|
|
485
|
-
] })
|
|
486
|
-
},
|
|
487
|
-
inter.id
|
|
488
|
-
)) })
|
|
530
|
+
children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: interactions.map((inter) => /* @__PURE__ */ jsx(NavLink, { href: `/interactions/${collection}/${inter.name}`, className: "block no-underline", children: /* @__PURE__ */ jsx(Card, { className: "cursor-pointer transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
531
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.interaction}`, children: "interaction" }),
|
|
532
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: inter.title || inter.name }),
|
|
533
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: inter.description || "No description" }),
|
|
534
|
+
inter.tags && inter.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-1", children: inter.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { children: tag }, tag)) })
|
|
535
|
+
] }) }) }, inter.id)) })
|
|
489
536
|
}
|
|
490
537
|
);
|
|
491
538
|
}
|
|
@@ -495,7 +542,7 @@ function InteractionDetail() {
|
|
|
495
542
|
const collection = params.collection;
|
|
496
543
|
const name = params.name;
|
|
497
544
|
const { baseUrl } = useAdminContext();
|
|
498
|
-
const { data: interaction,
|
|
545
|
+
const { data: interaction, error } = useFetch(
|
|
499
546
|
() => client.getRawJWT().then((token) => fetch(`${baseUrl}/interactions/${collection}/${name}`, {
|
|
500
547
|
headers: {
|
|
501
548
|
Authorization: `Bearer ${token}`
|
|
@@ -506,16 +553,16 @@ function InteractionDetail() {
|
|
|
506
553
|
}),
|
|
507
554
|
[baseUrl, collection, name]
|
|
508
555
|
);
|
|
509
|
-
if (
|
|
510
|
-
return /* @__PURE__ */
|
|
511
|
-
}
|
|
512
|
-
if (error || !interaction) {
|
|
513
|
-
return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
|
|
556
|
+
if (error) {
|
|
557
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
514
558
|
"Failed to load interaction “",
|
|
515
559
|
name,
|
|
516
560
|
"”."
|
|
517
561
|
] });
|
|
518
562
|
}
|
|
563
|
+
if (!interaction) {
|
|
564
|
+
return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
565
|
+
}
|
|
519
566
|
const { agent_runner_options } = interaction;
|
|
520
567
|
const hasAgentFlags = agent_runner_options && (agent_runner_options.is_agent || agent_runner_options.is_tool || agent_runner_options.is_skill);
|
|
521
568
|
return /* @__PURE__ */ jsxs(
|
|
@@ -527,72 +574,39 @@ function InteractionDetail() {
|
|
|
527
574
|
tags: interaction.tags,
|
|
528
575
|
backHref: `/interactions/${collection}`,
|
|
529
576
|
children: [
|
|
530
|
-
interaction.prompts && interaction.prompts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "
|
|
531
|
-
/* @__PURE__ */ jsx("h2", { children: "Prompts" }),
|
|
532
|
-
interaction.prompts.map((prompt
|
|
533
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
534
|
-
/* @__PURE__ */ jsx("span", { className: `
|
|
535
|
-
prompt.name && /* @__PURE__ */ jsx("span", { className: "
|
|
577
|
+
interaction.prompts && interaction.prompts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
578
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Prompts" }),
|
|
579
|
+
interaction.prompts.map((prompt) => /* @__PURE__ */ jsx(Card, { className: "mb-3", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-4", children: [
|
|
580
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
581
|
+
/* @__PURE__ */ jsx("span", { className: `rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${ROLE_VARIANTS[prompt.role] ?? ""}`, children: prompt.role }),
|
|
582
|
+
prompt.name && /* @__PURE__ */ jsx("span", { className: "text-sm italic text-muted-foreground", children: prompt.name })
|
|
536
583
|
] }),
|
|
537
|
-
/* @__PURE__ */ jsx("pre", { className: "
|
|
538
|
-
] },
|
|
584
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: prompt.content })
|
|
585
|
+
] }) }, `${prompt.role}-${prompt.name ?? ""}`))
|
|
539
586
|
] }),
|
|
540
|
-
interaction.result_schema && /* @__PURE__ */ jsxs("div", { className: "
|
|
541
|
-
/* @__PURE__ */ jsx("h2", { children: "Result Schema" }),
|
|
542
|
-
/* @__PURE__ */ jsx("pre", { className: "
|
|
587
|
+
interaction.result_schema && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
588
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Result Schema" }),
|
|
589
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: JSON.stringify(interaction.result_schema, null, 2) })
|
|
543
590
|
] }),
|
|
544
|
-
hasAgentFlags && /* @__PURE__ */ jsxs("div", { className: "
|
|
545
|
-
/* @__PURE__ */ jsx("h2", { children: "Agent Runner" }),
|
|
546
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
547
|
-
agent_runner_options.is_agent && /* @__PURE__ */ jsx(
|
|
548
|
-
agent_runner_options.is_tool && /* @__PURE__ */ jsx(
|
|
549
|
-
agent_runner_options.is_skill && /* @__PURE__ */ jsx(
|
|
591
|
+
hasAgentFlags && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
592
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Agent Runner" }),
|
|
593
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
594
|
+
agent_runner_options.is_agent && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Agent" }),
|
|
595
|
+
agent_runner_options.is_tool && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Tool" }),
|
|
596
|
+
agent_runner_options.is_skill && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Skill" })
|
|
550
597
|
] })
|
|
551
598
|
] })
|
|
552
599
|
]
|
|
553
600
|
}
|
|
554
601
|
);
|
|
555
602
|
}
|
|
556
|
-
function ToolCollection() {
|
|
557
|
-
const collection = useParams("collection");
|
|
558
|
-
const { baseUrl } = useAdminContext();
|
|
559
|
-
const { data, isLoading, error } = useFetch(
|
|
560
|
-
() => fetch(`${baseUrl}/tools/${collection}`).then((r) => {
|
|
561
|
-
if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
|
|
562
|
-
return r.json();
|
|
563
|
-
}),
|
|
564
|
-
[baseUrl, collection]
|
|
565
|
-
);
|
|
566
|
-
if (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading collection..." });
|
|
567
|
-
if (error || !data) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
|
|
568
|
-
"Failed to load tool collection “",
|
|
569
|
-
collection,
|
|
570
|
-
"”."
|
|
571
|
-
] });
|
|
572
|
-
return /* @__PURE__ */ jsx(
|
|
573
|
-
DetailPage,
|
|
574
|
-
{
|
|
575
|
-
type: "tool",
|
|
576
|
-
title: data.title || collection,
|
|
577
|
-
description: data.description || `${data.tools.length} tool${data.tools.length !== 1 ? "s" : ""} in this collection.`,
|
|
578
|
-
children: data.tools.map((tool) => /* @__PURE__ */ jsxs("div", { className: "vta-detail-card", children: [
|
|
579
|
-
/* @__PURE__ */ jsxs("div", { className: "vta-detail-card-header", children: [
|
|
580
|
-
/* @__PURE__ */ jsx("span", { className: "vta-card-type vta-card-type--tool", children: "tool" }),
|
|
581
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-title", children: tool.name })
|
|
582
|
-
] }),
|
|
583
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: tool.description || "No description" }),
|
|
584
|
-
tool.input_schema && /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: JSON.stringify(tool.input_schema, null, 2) })
|
|
585
|
-
] }, tool.name))
|
|
586
|
-
}
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
603
|
function skillDisplayName(name) {
|
|
590
604
|
return name.startsWith("learn_") ? name.slice(6) : name;
|
|
591
605
|
}
|
|
592
606
|
function SkillCollection() {
|
|
593
607
|
const collection = useParams("collection");
|
|
594
608
|
const { baseUrl } = useAdminContext();
|
|
595
|
-
const { data,
|
|
609
|
+
const { data, error } = useFetch(
|
|
596
610
|
() => fetch(`${baseUrl}/skills/${collection}`).then((r) => {
|
|
597
611
|
if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
|
|
598
612
|
return r.json();
|
|
@@ -607,12 +621,12 @@ function SkillCollection() {
|
|
|
607
621
|
if (!widgetsData?.widgets) return [];
|
|
608
622
|
return Object.entries(widgetsData.widgets).filter(([_, w]) => w.collection === collection).map(([name, w]) => ({ name, ...w }));
|
|
609
623
|
}, [widgetsData, collection]);
|
|
610
|
-
if (
|
|
611
|
-
if (error || !data) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
|
|
624
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
612
625
|
"Failed to load skill collection “",
|
|
613
626
|
collection,
|
|
614
627
|
"”."
|
|
615
628
|
] });
|
|
629
|
+
if (!data) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
616
630
|
return /* @__PURE__ */ jsxs(
|
|
617
631
|
DetailPage,
|
|
618
632
|
{
|
|
@@ -620,33 +634,25 @@ function SkillCollection() {
|
|
|
620
634
|
title: data.title || collection,
|
|
621
635
|
description: data.description || `${data.tools.length} skill${data.tools.length !== 1 ? "s" : ""} in this collection.`,
|
|
622
636
|
children: [
|
|
623
|
-
collectionWidgets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "
|
|
624
|
-
/* @__PURE__ */ jsx("h2", { children: "Widgets" }),
|
|
625
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
637
|
+
collectionWidgets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
638
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Widgets" }),
|
|
639
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: collectionWidgets.map((w) => /* @__PURE__ */ jsxs(Badge, { variant: "success", children: [
|
|
626
640
|
w.name,
|
|
627
|
-
/* @__PURE__ */ jsxs("span", { className: "
|
|
641
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-2 font-mono text-xs opacity-70", children: [
|
|
628
642
|
"(skill: ",
|
|
629
643
|
w.skill,
|
|
630
644
|
")"
|
|
631
645
|
] })
|
|
632
646
|
] }, w.name)) })
|
|
633
647
|
] }),
|
|
634
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
648
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: data.tools.map((skill) => {
|
|
635
649
|
const displayName = skillDisplayName(skill.name);
|
|
636
|
-
return /* @__PURE__ */ jsx(
|
|
637
|
-
|
|
638
|
-
{
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
/* @__PURE__ */ jsx("span", { className: "vta-card-type vta-card-type--skill", children: "skill" }),
|
|
643
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-title", children: displayName }),
|
|
644
|
-
/* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: skill.description || "No description" }),
|
|
645
|
-
skill.related_tools && skill.related_tools.length > 0 && /* @__PURE__ */ jsx("div", { className: "vta-card-tags", children: skill.related_tools.map((t) => /* @__PURE__ */ jsx("span", { className: "vta-tag", children: t }, t)) })
|
|
646
|
-
] })
|
|
647
|
-
},
|
|
648
|
-
skill.name
|
|
649
|
-
);
|
|
650
|
+
return /* @__PURE__ */ jsx(NavLink, { href: `/skills/${collection}/${displayName}`, className: "block no-underline", children: /* @__PURE__ */ jsx(Card, { className: "cursor-pointer transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
651
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.skill}`, children: "skill" }),
|
|
652
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: displayName }),
|
|
653
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: skill.description || "No description" }),
|
|
654
|
+
skill.related_tools && skill.related_tools.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-1", children: skill.related_tools.map((t) => /* @__PURE__ */ jsx(Badge, { children: t }, t)) })
|
|
655
|
+
] }) }) }, skill.name);
|
|
650
656
|
}) })
|
|
651
657
|
]
|
|
652
658
|
}
|
|
@@ -657,19 +663,19 @@ function SkillDetail() {
|
|
|
657
663
|
const collection = params.collection;
|
|
658
664
|
const name = params.name;
|
|
659
665
|
const { baseUrl } = useAdminContext();
|
|
660
|
-
const { data: skill,
|
|
666
|
+
const { data: skill, error } = useFetch(
|
|
661
667
|
() => fetch(`${baseUrl}/skills/${collection}/${name}`).then((r) => {
|
|
662
668
|
if (!r.ok) throw new Error(`Failed to load skill: ${r.statusText}`);
|
|
663
669
|
return r.json();
|
|
664
670
|
}),
|
|
665
671
|
[baseUrl, collection, name]
|
|
666
672
|
);
|
|
667
|
-
if (
|
|
668
|
-
if (error || !skill) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
|
|
673
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
669
674
|
"Failed to load skill “",
|
|
670
675
|
name,
|
|
671
676
|
"”."
|
|
672
677
|
] });
|
|
678
|
+
if (!skill) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
673
679
|
return /* @__PURE__ */ jsxs(
|
|
674
680
|
DetailPage,
|
|
675
681
|
{
|
|
@@ -678,210 +684,242 @@ function SkillDetail() {
|
|
|
678
684
|
description: skill.description,
|
|
679
685
|
backHref: `/skills/${collection}`,
|
|
680
686
|
children: [
|
|
681
|
-
skill.widgets && skill.widgets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "
|
|
682
|
-
/* @__PURE__ */ jsx("h2", { children: "Widgets" }),
|
|
683
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
687
|
+
skill.widgets && skill.widgets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
688
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Widgets" }),
|
|
689
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: skill.widgets.map((w) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: w }, w)) })
|
|
684
690
|
] }),
|
|
685
|
-
skill.scripts && skill.scripts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "
|
|
686
|
-
/* @__PURE__ */ jsx("h2", { children: "Scripts" }),
|
|
687
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
691
|
+
skill.scripts && skill.scripts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
692
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Scripts" }),
|
|
693
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: skill.scripts.map((s) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: s }, s)) })
|
|
688
694
|
] }),
|
|
689
|
-
skill.related_tools && skill.related_tools.length > 0 && /* @__PURE__ */ jsxs("div", { className: "
|
|
690
|
-
/* @__PURE__ */ jsx("h2", { children: "Related Tools" }),
|
|
691
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
695
|
+
skill.related_tools && skill.related_tools.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
696
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Related Tools" }),
|
|
697
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: skill.related_tools.map((t) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: t }, t)) })
|
|
692
698
|
] }),
|
|
693
|
-
skill.execution && /* @__PURE__ */ jsxs("div", { className: "
|
|
694
|
-
/* @__PURE__ */ jsx("h2", { children: "Execution" }),
|
|
695
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
696
|
-
/* @__PURE__ */ jsx(
|
|
697
|
-
skill.execution.packages?.map((p) => /* @__PURE__ */ jsx(
|
|
699
|
+
skill.execution && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
700
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Execution" }),
|
|
701
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
702
|
+
/* @__PURE__ */ jsx(Badge, { variant: "success", children: skill.execution.language }),
|
|
703
|
+
skill.execution.packages?.map((p) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: p }, p))
|
|
698
704
|
] })
|
|
699
705
|
] }),
|
|
700
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
701
|
-
/* @__PURE__ */ jsxs("h2", { children: [
|
|
702
|
-
"Instructions
|
|
703
|
-
skill.content_type === "jst" && /* @__PURE__ */ jsx(
|
|
706
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
707
|
+
/* @__PURE__ */ jsxs("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: [
|
|
708
|
+
"Instructions",
|
|
709
|
+
skill.content_type === "jst" && /* @__PURE__ */ jsx(Badge, { className: "ml-2", children: "JST template" })
|
|
704
710
|
] }),
|
|
705
|
-
/* @__PURE__ */ jsx("pre", { className: "
|
|
711
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: skill.instructions })
|
|
706
712
|
] }),
|
|
707
|
-
skill.input_schema && /* @__PURE__ */ jsxs("div", { className: "
|
|
708
|
-
/* @__PURE__ */ jsx("h2", { children: "Input Schema" }),
|
|
709
|
-
/* @__PURE__ */ jsx("pre", { className: "
|
|
713
|
+
skill.input_schema && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
714
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Input Schema" }),
|
|
715
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: JSON.stringify(skill.input_schema, null, 2) })
|
|
710
716
|
] })
|
|
711
717
|
]
|
|
712
718
|
}
|
|
713
719
|
);
|
|
714
720
|
}
|
|
715
|
-
function
|
|
721
|
+
function TemplateCollection() {
|
|
716
722
|
const collection = useParams("collection");
|
|
717
723
|
const { baseUrl } = useAdminContext();
|
|
718
|
-
const { data:
|
|
719
|
-
() => fetch(`${baseUrl}/
|
|
724
|
+
const { data: templates, error } = useFetch(
|
|
725
|
+
() => fetch(`${baseUrl}/templates/${collection}`).then((r) => {
|
|
720
726
|
if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
|
|
721
727
|
return r.json();
|
|
722
728
|
}),
|
|
723
729
|
[baseUrl, collection]
|
|
724
730
|
);
|
|
725
|
-
if (
|
|
726
|
-
|
|
727
|
-
"Failed to load type collection “",
|
|
731
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
732
|
+
"Failed to load template collection “",
|
|
728
733
|
collection,
|
|
729
734
|
"”."
|
|
730
735
|
] });
|
|
736
|
+
if (!templates) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
731
737
|
return /* @__PURE__ */ jsx(
|
|
732
738
|
DetailPage,
|
|
733
739
|
{
|
|
734
|
-
type: "
|
|
740
|
+
type: "template",
|
|
735
741
|
title: collection,
|
|
736
|
-
description: `${
|
|
737
|
-
children: /* @__PURE__ */ jsx("div", { className: "
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
className:
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
t.is_chunkable && t.strict_mode && " · ",
|
|
752
|
-
t.strict_mode && "strict"
|
|
753
|
-
] })
|
|
754
|
-
] })
|
|
755
|
-
},
|
|
756
|
-
t.name
|
|
757
|
-
);
|
|
758
|
-
}) })
|
|
742
|
+
description: `${templates.length} template${templates.length !== 1 ? "s" : ""} in this collection.`,
|
|
743
|
+
children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: templates.map((tmpl) => /* @__PURE__ */ jsx(
|
|
744
|
+
NavLink,
|
|
745
|
+
{
|
|
746
|
+
href: `/templates/${collection}/${tmpl.name}`,
|
|
747
|
+
className: "no-underline",
|
|
748
|
+
children: /* @__PURE__ */ jsx(Card, { className: "h-full transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
749
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.template}`, children: tmpl.type || "template" }),
|
|
750
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: tmpl.title || tmpl.name }),
|
|
751
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: tmpl.description || "No description" }),
|
|
752
|
+
tmpl.tags && tmpl.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-1.5", children: tmpl.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tag)) })
|
|
753
|
+
] }) })
|
|
754
|
+
},
|
|
755
|
+
tmpl.name
|
|
756
|
+
)) })
|
|
759
757
|
}
|
|
760
758
|
);
|
|
761
759
|
}
|
|
762
|
-
function
|
|
760
|
+
function TemplateDetail() {
|
|
763
761
|
const params = useParams();
|
|
764
762
|
const collection = params.collection;
|
|
765
763
|
const name = params.name;
|
|
766
764
|
const { baseUrl } = useAdminContext();
|
|
767
|
-
const { data:
|
|
768
|
-
() => fetch(`${baseUrl}/
|
|
769
|
-
if (!r.ok) throw new Error(`Failed to load
|
|
765
|
+
const { data: template, error } = useFetch(
|
|
766
|
+
() => fetch(`${baseUrl}/templates/${collection}/${name}`).then((r) => {
|
|
767
|
+
if (!r.ok) throw new Error(`Failed to load template: ${r.statusText}`);
|
|
770
768
|
return r.json();
|
|
771
769
|
}),
|
|
772
770
|
[baseUrl, collection, name]
|
|
773
771
|
);
|
|
774
|
-
if (
|
|
775
|
-
|
|
776
|
-
"Failed to load type “",
|
|
772
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
773
|
+
"Failed to load template “",
|
|
777
774
|
name,
|
|
778
775
|
"”."
|
|
779
776
|
] });
|
|
777
|
+
if (!template) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
780
778
|
return /* @__PURE__ */ jsxs(
|
|
781
779
|
DetailPage,
|
|
782
780
|
{
|
|
783
|
-
type: "
|
|
784
|
-
title:
|
|
785
|
-
description:
|
|
786
|
-
tags:
|
|
787
|
-
backHref: `/
|
|
781
|
+
type: "template",
|
|
782
|
+
title: template.title || template.name,
|
|
783
|
+
description: template.description,
|
|
784
|
+
tags: template.tags,
|
|
785
|
+
backHref: `/templates/${collection}`,
|
|
788
786
|
children: [
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
typeDef.object_schema && /* @__PURE__ */ jsxs("div", { className: "vta-detail-section", children: [
|
|
794
|
-
/* @__PURE__ */ jsx("h2", { children: "Object Schema" }),
|
|
795
|
-
/* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: JSON.stringify(typeDef.object_schema, null, 2) })
|
|
787
|
+
/* @__PURE__ */ jsx("div", { className: "mb-8", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: /* @__PURE__ */ jsx(Badge, { variant: "success", children: template.type }) }) }),
|
|
788
|
+
template.assets && template.assets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
789
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Assets" }),
|
|
790
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: template.assets.map((asset) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: asset.split("/").pop() }, asset)) })
|
|
796
791
|
] }),
|
|
797
|
-
|
|
798
|
-
/* @__PURE__ */ jsx("h2", {
|
|
799
|
-
/* @__PURE__ */ jsx("pre", { className: "
|
|
792
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
793
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Instructions" }),
|
|
794
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: template.instructions })
|
|
800
795
|
] })
|
|
801
796
|
]
|
|
802
797
|
}
|
|
803
798
|
);
|
|
804
799
|
}
|
|
805
|
-
function
|
|
800
|
+
function ToolCollection() {
|
|
806
801
|
const collection = useParams("collection");
|
|
807
802
|
const { baseUrl } = useAdminContext();
|
|
808
|
-
const { data
|
|
809
|
-
() => fetch(`${baseUrl}/
|
|
803
|
+
const { data, error } = useFetch(
|
|
804
|
+
() => fetch(`${baseUrl}/tools/${collection}`).then((r) => {
|
|
810
805
|
if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
|
|
811
806
|
return r.json();
|
|
812
807
|
}),
|
|
813
808
|
[baseUrl, collection]
|
|
814
809
|
);
|
|
815
|
-
if (
|
|
816
|
-
|
|
817
|
-
"Failed to load template collection “",
|
|
810
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
811
|
+
"Failed to load tool collection “",
|
|
818
812
|
collection,
|
|
819
813
|
"”."
|
|
820
814
|
] });
|
|
815
|
+
if (!data) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
821
816
|
return /* @__PURE__ */ jsx(
|
|
822
817
|
DetailPage,
|
|
823
818
|
{
|
|
824
|
-
type: "
|
|
819
|
+
type: "tool",
|
|
820
|
+
title: data.title || collection,
|
|
821
|
+
description: data.description || `${data.tools.length} tool${data.tools.length !== 1 ? "s" : ""} in this collection.`,
|
|
822
|
+
children: data.tools.map((tool) => /* @__PURE__ */ jsx(Card, { className: "mb-4", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
823
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
824
|
+
/* @__PURE__ */ jsx("span", { className: `inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.tool}`, children: "tool" }),
|
|
825
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-card-foreground", children: tool.name })
|
|
826
|
+
] }),
|
|
827
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: tool.description || "No description" }),
|
|
828
|
+
tool.input_schema && /* @__PURE__ */ jsx("pre", { className: "mt-3 whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: JSON.stringify(tool.input_schema, null, 2) })
|
|
829
|
+
] }) }, tool.name))
|
|
830
|
+
}
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
function TypeCollection() {
|
|
834
|
+
const collection = useParams("collection");
|
|
835
|
+
const { baseUrl } = useAdminContext();
|
|
836
|
+
const { data: types, error } = useFetch(
|
|
837
|
+
() => fetch(`${baseUrl}/types/${collection}`).then((r) => {
|
|
838
|
+
if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
|
|
839
|
+
return r.json();
|
|
840
|
+
}),
|
|
841
|
+
[baseUrl, collection]
|
|
842
|
+
);
|
|
843
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
844
|
+
"Failed to load type collection “",
|
|
845
|
+
collection,
|
|
846
|
+
"”."
|
|
847
|
+
] });
|
|
848
|
+
if (!types) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
849
|
+
return /* @__PURE__ */ jsx(
|
|
850
|
+
DetailPage,
|
|
851
|
+
{
|
|
852
|
+
type: "type",
|
|
825
853
|
title: collection,
|
|
826
|
-
description: `${
|
|
827
|
-
children: /* @__PURE__ */ jsx("div", { className: "
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
/* @__PURE__ */ jsx(
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
854
|
+
description: `${types.length} content type${types.length !== 1 ? "s" : ""} in this collection.`,
|
|
855
|
+
children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: types.map((t) => {
|
|
856
|
+
const typeName = t.id?.split(":")[1] || t.name;
|
|
857
|
+
return /* @__PURE__ */ jsx(
|
|
858
|
+
NavLink,
|
|
859
|
+
{
|
|
860
|
+
href: `/types/${collection}/${typeName}`,
|
|
861
|
+
className: "no-underline",
|
|
862
|
+
children: /* @__PURE__ */ jsx(Card, { className: "h-full transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
|
|
863
|
+
/* @__PURE__ */ jsx("span", { className: `mb-2 inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.type}`, children: "type" }),
|
|
864
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: t.name }),
|
|
865
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: t.description || "No description" }),
|
|
866
|
+
t.tags && t.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-1.5", children: t.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tag)) }),
|
|
867
|
+
(t.is_chunkable || t.strict_mode) && /* @__PURE__ */ jsxs("div", { className: "mt-2 truncate font-mono text-xs text-muted-foreground", children: [
|
|
868
|
+
t.is_chunkable && "chunkable",
|
|
869
|
+
t.is_chunkable && t.strict_mode && " · ",
|
|
870
|
+
t.strict_mode && "strict"
|
|
871
|
+
] })
|
|
872
|
+
] }) })
|
|
873
|
+
},
|
|
874
|
+
t.name
|
|
875
|
+
);
|
|
876
|
+
}) })
|
|
841
877
|
}
|
|
842
878
|
);
|
|
843
879
|
}
|
|
844
|
-
function
|
|
880
|
+
function TypeDetail() {
|
|
845
881
|
const params = useParams();
|
|
846
882
|
const collection = params.collection;
|
|
847
883
|
const name = params.name;
|
|
848
884
|
const { baseUrl } = useAdminContext();
|
|
849
|
-
const { data:
|
|
850
|
-
() => fetch(`${baseUrl}/
|
|
851
|
-
if (!r.ok) throw new Error(`Failed to load
|
|
885
|
+
const { data: typeDef, error } = useFetch(
|
|
886
|
+
() => fetch(`${baseUrl}/types/${collection}/${name}`).then((r) => {
|
|
887
|
+
if (!r.ok) throw new Error(`Failed to load type: ${r.statusText}`);
|
|
852
888
|
return r.json();
|
|
853
889
|
}),
|
|
854
890
|
[baseUrl, collection, name]
|
|
855
891
|
);
|
|
856
|
-
if (
|
|
857
|
-
|
|
858
|
-
"Failed to load template “",
|
|
892
|
+
if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
|
|
893
|
+
"Failed to load type “",
|
|
859
894
|
name,
|
|
860
895
|
"”."
|
|
861
896
|
] });
|
|
897
|
+
if (!typeDef) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
862
898
|
return /* @__PURE__ */ jsxs(
|
|
863
899
|
DetailPage,
|
|
864
900
|
{
|
|
865
|
-
type: "
|
|
866
|
-
title:
|
|
867
|
-
description:
|
|
868
|
-
tags:
|
|
869
|
-
backHref: `/
|
|
901
|
+
type: "type",
|
|
902
|
+
title: typeDef.name,
|
|
903
|
+
description: typeDef.description,
|
|
904
|
+
tags: typeDef.tags,
|
|
905
|
+
backHref: `/types/${collection}`,
|
|
870
906
|
children: [
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
/* @__PURE__ */ jsx("
|
|
874
|
-
|
|
907
|
+
(typeDef.is_chunkable || typeDef.strict_mode) && /* @__PURE__ */ jsx("div", { className: "mb-8", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
908
|
+
typeDef.is_chunkable && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Chunkable" }),
|
|
909
|
+
typeDef.strict_mode && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Strict Mode" })
|
|
910
|
+
] }) }),
|
|
911
|
+
typeDef.object_schema && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
912
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Object Schema" }),
|
|
913
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: JSON.stringify(typeDef.object_schema, null, 2) })
|
|
875
914
|
] }),
|
|
876
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
877
|
-
/* @__PURE__ */ jsx("h2", { children: "
|
|
878
|
-
/* @__PURE__ */ jsx("pre", { className: "
|
|
915
|
+
typeDef.table_layout && typeDef.table_layout.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
916
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Table Layout" }),
|
|
917
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word rounded-lg border border-border bg-muted-background p-4 font-mono text-sm text-foreground", children: JSON.stringify(typeDef.table_layout, null, 2) })
|
|
879
918
|
] })
|
|
880
919
|
]
|
|
881
920
|
}
|
|
882
921
|
);
|
|
883
922
|
}
|
|
884
|
-
const adminStyles = "/**\n * Self-contained styles for the admin panel.\n * All classes are prefixed with `vta-` (Vertesia Tools Admin) to avoid\n * polluting the plugin app CSS or the host page.\n */\n\n/* ── Root container ─────────────────────────────────────────────── */\n\n.vta-root {\n max-width: 1120px;\n margin: 0 auto;\n padding: 2.5rem 1.75rem;\n font-family: system-ui, -apple-system, sans-serif;\n color: #0f172a;\n line-height: 1.5;\n}\n\n/* ── Hero header ────────────────────────────────────────────────── */\n\n.vta-hero {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 2.25rem;\n padding: 1.75rem 2rem;\n margin-bottom: 2.5rem;\n border-radius: 1.25rem;\n background: linear-gradient(135deg, #ffffff, #f3f4ff);\n border: 1px solid #e5e7eb;\n box-shadow:\n 0 18px 40px rgba(15, 23, 42, 0.08),\n 0 0 0 1px rgba(248, 250, 252, 0.8);\n}\n\n.vta-hero-main {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.vta-hero-identity {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.vta-hero-logo {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n border-radius: 14px;\n background: radial-gradient(circle at 30% 0, #38bdf8, #6366f1);\n box-shadow:\n 0 0 0 1px rgba(15, 23, 42, 0.85),\n 0 12px 30px rgba(37, 99, 235, 0.6);\n font-size: 1.1rem;\n font-weight: 650;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: #eff6ff;\n}\n\n.vta-hero-eyebrow {\n font-size: 0.75rem;\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: #6b7280;\n margin: 0;\n}\n\n.vta-hero-title {\n font-size: 1.9rem;\n font-weight: 650;\n letter-spacing: -0.03em;\n color: #0f172a;\n margin: 0;\n}\n\n.vta-hero-tagline {\n font-size: 0.95rem;\n color: #4b5563;\n margin: 0;\n}\n\n.vta-hero-summary {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n font-size: 0.8rem;\n color: #6b7280;\n}\n\n.vta-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.15rem 0.55rem;\n border-radius: 999px;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n}\n\n.vta-badge-dot {\n width: 6px;\n height: 6px;\n border-radius: 999px;\n display: inline-block;\n background: #22c55e;\n}\n\n.vta-hero-links {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n margin-top: 0.25rem;\n}\n\n.vta-link-primary,\n.vta-link-secondary {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n font-size: 0.875rem;\n font-weight: 500;\n text-decoration: none;\n color: white;\n transition: opacity 0.15s;\n}\n\n.vta-link-primary { background: #3b82f6; }\n.vta-link-secondary { background: #10b981; }\n.vta-link-primary:hover { opacity: 0.88; }\n.vta-link-secondary:hover { opacity: 0.88; }\n\n/* ── Hero aside panel ───────────────────────────────────────────── */\n\n.vta-hero-panel {\n min-width: 220px;\n max-width: 260px;\n flex-shrink: 0;\n}\n\n.vta-endpoint {\n margin-bottom: 0.75rem;\n}\n\n.vta-endpoint-label {\n font-size: 0.7rem;\n letter-spacing: 0.13em;\n text-transform: uppercase;\n color: #1d4ed8;\n margin-bottom: 0.35rem;\n}\n\n.vta-endpoint-box {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: #f3f4f6;\n padding: 0.5rem 0.75rem;\n border-radius: 0.5rem;\n border: 1px solid #e5e7eb;\n}\n\n.vta-endpoint-code {\n flex: 1;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 0.82rem;\n color: #111827;\n}\n\n.vta-copy-btn {\n background: #e5e7eb;\n border: none;\n padding: 0.35rem;\n border-radius: 4px;\n cursor: pointer;\n color: #6b7280;\n font-size: 0.8rem;\n line-height: 1;\n transition: all 0.15s;\n}\n\n.vta-copy-btn:hover {\n background: #d1d5db;\n color: #374151;\n}\n\n.vta-hero-hint {\n margin-top: 0.6rem;\n font-size: 0.8rem;\n color: #6b7280;\n line-height: 1.4;\n}\n\n.vta-hero-hint strong {\n color: #111827;\n}\n\n.vta-hero-version {\n font-size: 0.75rem;\n color: #9ca3af;\n margin-top: 0.25rem;\n}\n\n/* ── Search bar ─────────────────────────────────────────────────── */\n\n.vta-search {\n margin-bottom: 1.75rem;\n}\n\n.vta-search-input {\n width: 100%;\n max-width: 360px;\n padding: 0.55rem 0.75rem;\n border-radius: 999px;\n border: 1px solid #e5e7eb;\n background: #ffffff;\n color: #111827;\n font-size: 0.9rem;\n font-family: inherit;\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.04);\n box-sizing: border-box;\n}\n\n.vta-search-input::placeholder { color: #9ca3af; }\n\n.vta-search-input:focus {\n outline: none;\n border-color: #60a5fa;\n box-shadow:\n 0 0 0 1px rgba(59, 130, 246, 0.4),\n 0 6px 18px rgba(37, 99, 235, 0.18);\n}\n\n.vta-search-hint {\n font-size: 0.75rem;\n color: #9ca3af;\n margin-top: 0.4rem;\n}\n\n.vta-search-empty {\n font-size: 0.85rem;\n color: #ef4444;\n margin-top: 0.5rem;\n}\n\n/* ── Section ────────────────────────────────────────────────────── */\n\n.vta-divider {\n border: none;\n border-top: 1px solid #e5e7eb;\n margin: 2rem 0;\n}\n\n.vta-section-title {\n font-size: 1.4rem;\n font-weight: 600;\n letter-spacing: 0.03em;\n color: #0f172a;\n margin: 0 0 0.25rem 0;\n}\n\n.vta-section-count {\n font-size: 0.85rem;\n font-weight: 400;\n color: #9ca3af;\n margin-left: 0.5rem;\n}\n\n.vta-section-subtitle {\n font-size: 0.8rem;\n color: #6b7280;\n margin: 0 0 1rem 0;\n}\n\n/* ── Resource card grid ─────────────────────────────────────────── */\n\n.vta-card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 1.5rem;\n}\n\n.vta-card {\n background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.12), transparent 75%),\n #ffffff;\n padding: 1.25rem 1.35rem;\n border-radius: 14px;\n box-shadow:\n 0 14px 30px rgba(15, 23, 42, 0.06),\n 0 0 0 1px rgba(248, 250, 252, 0.9);\n border: 1px solid #e5e7eb;\n transition: transform 0.15s, box-shadow 0.15s;\n}\n\n.vta-card:hover {\n transform: translateY(-3px);\n box-shadow:\n 0 18px 40px rgba(15, 23, 42, 0.10),\n 0 0 0 1px rgba(59, 130, 246, 0.6);\n}\n\n.vta-card-type {\n display: inline-block;\n font-size: 0.7rem;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n padding: 0.15rem 0.55rem;\n border-radius: 999px;\n margin-bottom: 0.6rem;\n}\n\n/* Type-specific badge colours */\n.vta-card-type--tool { background: #dbeafe; color: #1e40af; }\n.vta-card-type--skill { background: #d1fae5; color: #065f46; }\n.vta-card-type--interaction { background: #fef3c7; color: #92400e; }\n.vta-card-type--type { background: #f3f4f6; color: #374151; }\n.vta-card-type--template { background: #ede9fe; color: #5b21b6; }\n.vta-card-type--mcp { background: #fce7f3; color: #9d174d; }\n\n.vta-card-title {\n font-weight: 600;\n font-size: 1.05rem;\n color: #0f172a;\n margin-bottom: 0.25rem;\n}\n\n.vta-card-desc {\n font-size: 0.875rem;\n color: #6b7280;\n margin-bottom: 0.5rem;\n}\n\n.vta-card-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n margin-bottom: 0.4rem;\n}\n\n.vta-tag {\n font-size: 0.7rem;\n padding: 0.1rem 0.5rem;\n border-radius: 999px;\n background: #fef3c7;\n color: #92400e;\n}\n\n.vta-card-url {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 0.75rem;\n color: #9ca3af;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ── Card link wrapper ─────────────────────────────────────────── */\n\n.vta-card-link {\n text-decoration: none;\n color: inherit;\n display: block;\n}\n\n.vta-card--link {\n cursor: pointer;\n}\n\n/* ── Detail page ───────────────────────────────────────────────── */\n\n.vta-detail-nav {\n display: flex;\n align-items: center;\n gap: 1rem;\n margin-bottom: 1.25rem;\n}\n\n.vta-detail-back {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.875rem;\n color: #3b82f6;\n text-decoration: none;\n transition: opacity 0.15s;\n}\n\n.vta-detail-back:hover {\n opacity: 0.75;\n}\n\n.vta-detail-header {\n margin-bottom: 2rem;\n}\n\n.vta-detail-title {\n font-size: 1.75rem;\n font-weight: 650;\n letter-spacing: -0.02em;\n color: #0f172a;\n margin: 0.5rem 0 0.25rem;\n}\n\n.vta-detail-desc {\n font-size: 0.95rem;\n color: #4b5563;\n margin: 0 0 0.75rem;\n line-height: 1.6;\n}\n\n.vta-detail-section {\n margin-bottom: 2rem;\n}\n\n.vta-detail-section h2 {\n font-size: 1.15rem;\n font-weight: 600;\n color: #0f172a;\n margin: 0 0 0.75rem;\n}\n\n.vta-detail-card {\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n padding: 1rem 1.25rem;\n margin-bottom: 0.75rem;\n}\n\n.vta-detail-card-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.5rem;\n}\n\n.vta-detail-role {\n display: inline-block;\n font-size: 0.7rem;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n padding: 0.15rem 0.55rem;\n border-radius: 999px;\n}\n\n.vta-detail-role--system { background: #dbeafe; color: #1e40af; }\n.vta-detail-role--user { background: #d1fae5; color: #065f46; }\n.vta-detail-role--assistant { background: #ede9fe; color: #5b21b6; }\n.vta-detail-role--safety { background: #fce7f3; color: #9d174d; }\n.vta-detail-role--tool { background: #fef3c7; color: #92400e; }\n\n.vta-detail-prompt-name {\n font-size: 0.8rem;\n color: #6b7280;\n font-style: italic;\n}\n\n.vta-detail-code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 0.82rem;\n line-height: 1.6;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 0.75rem 1rem;\n margin: 0;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-word;\n color: #111827;\n}\n\n.vta-detail-flags {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.vta-detail-flag {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.25rem 0.65rem;\n border-radius: 999px;\n font-size: 0.8rem;\n font-weight: 500;\n background: #d1fae5;\n color: #065f46;\n}\n\n/* ── Loading / error states ─────────────────────────────────────── */\n\n.vta-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 16rem;\n color: #9ca3af;\n font-size: 1rem;\n}\n\n.vta-error {\n padding: 1.5rem;\n color: #ef4444;\n font-size: 0.95rem;\n}\n\n/* ── Responsive ─────────────────────────────────────────────────── */\n\n@media (max-width: 768px) {\n .vta-root { padding: 1.75rem 1.25rem; }\n .vta-hero { flex-direction: column; padding: 1.5rem 1.35rem; }\n .vta-hero-panel { max-width: 100%; width: 100%; }\n}\n\n/* ── Dark mode ──────────────────────────────────────────────────── */\n\n@media (prefers-color-scheme: dark) {\n .vta-root { color: #e5e7eb; }\n\n .vta-hero {\n background: linear-gradient(135deg, rgba(15, 23, 42, 0.98), rgba(15, 23, 42, 0.92));\n border-color: rgba(148, 163, 184, 0.45);\n box-shadow:\n 0 24px 60px rgba(15, 23, 42, 0.85),\n 0 0 0 1px rgba(15, 23, 42, 0.75);\n }\n\n .vta-hero-eyebrow { color: #9ca3af; }\n .vta-hero-title { color: #f9fafb; }\n .vta-hero-tagline { color: #cbd5f5; }\n .vta-hero-summary { color: #9ca3af; }\n\n .vta-badge {\n background: rgba(15, 23, 42, 0.95);\n border-color: rgba(148, 163, 184, 0.45);\n }\n\n .vta-endpoint-label { color: #93c5fd; }\n\n .vta-endpoint-box {\n background: rgba(31, 41, 55, 0.95);\n border-color: rgba(148, 163, 184, 0.6);\n }\n\n .vta-endpoint-code { color: #e5e7eb; }\n\n .vta-copy-btn {\n background: rgba(55, 65, 81, 0.95);\n color: #e5e7eb;\n }\n .vta-copy-btn:hover {\n background: rgba(75, 85, 99, 0.98);\n color: #f9fafb;\n }\n\n .vta-hero-hint { color: #9ca3af; }\n .vta-hero-hint strong { color: #e5e7eb; }\n\n .vta-search-input {\n background: rgba(15, 23, 42, 0.96);\n border-color: rgba(55, 65, 81, 0.9);\n color: #e5e7eb;\n box-shadow:\n 0 6px 16px rgba(15, 23, 42, 0.9),\n 0 0 0 1px rgba(15, 23, 42, 0.9);\n }\n .vta-search-input::placeholder { color: #6b7280; }\n .vta-search-input:focus {\n border-color: #60a5fa;\n box-shadow:\n 0 0 0 1px rgba(59, 130, 246, 0.7),\n 0 10px 26px rgba(30, 64, 175, 0.7);\n }\n\n .vta-search-hint { color: #9ca3af; }\n .vta-divider { border-top-color: rgba(148, 163, 184, 0.4); }\n .vta-section-title { color: #e5e7eb; }\n\n .vta-card {\n background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.12), transparent 75%),\n rgba(15, 23, 42, 0.9);\n box-shadow:\n 0 14px 30px rgba(15, 23, 42, 0.8),\n 0 0 0 1px rgba(15, 23, 42, 0.85);\n border-color: rgba(148, 163, 184, 0.5);\n }\n .vta-card:hover {\n box-shadow:\n 0 18px 40px rgba(15, 23, 42, 0.9),\n 0 0 0 1px rgba(59, 130, 246, 0.8);\n }\n\n .vta-card-title { color: #e5e7eb; }\n .vta-card-desc { color: #9ca3af; }\n .vta-card-url { color: #6b7280; }\n\n .vta-card-type--tool { background: rgba(59, 130, 246, 0.15); color: #93c5fd; }\n .vta-card-type--skill { background: rgba(16, 185, 129, 0.15); color: #6ee7b7; }\n .vta-card-type--interaction { background: rgba(245, 158, 11, 0.15); color: #fcd34d; }\n .vta-card-type--type { background: rgba(107, 114, 128, 0.2); color: #d1d5db; }\n .vta-card-type--template { background: rgba(139, 92, 246, 0.15); color: #c4b5fd; }\n .vta-card-type--mcp { background: rgba(236, 72, 153, 0.15); color: #f9a8d4; }\n\n .vta-tag {\n background: rgba(250, 204, 21, 0.12);\n color: #facc15;\n }\n\n /* Detail page dark mode */\n .vta-detail-back { color: #60a5fa; }\n\n .vta-detail-title { color: #f9fafb; }\n .vta-detail-desc { color: #cbd5e1; }\n\n .vta-detail-section h2 { color: #e5e7eb; }\n\n .vta-detail-card {\n background: rgba(15, 23, 42, 0.9);\n border-color: rgba(148, 163, 184, 0.5);\n }\n\n .vta-detail-role--system { background: rgba(59, 130, 246, 0.15); color: #93c5fd; }\n .vta-detail-role--user { background: rgba(16, 185, 129, 0.15); color: #6ee7b7; }\n .vta-detail-role--assistant { background: rgba(139, 92, 246, 0.15); color: #c4b5fd; }\n .vta-detail-role--safety { background: rgba(236, 72, 153, 0.15); color: #f9a8d4; }\n .vta-detail-role--tool { background: rgba(245, 158, 11, 0.15); color: #fcd34d; }\n\n .vta-detail-prompt-name { color: #9ca3af; }\n\n .vta-detail-code {\n background: rgba(15, 23, 42, 0.95);\n border-color: rgba(148, 163, 184, 0.4);\n color: #e5e7eb;\n }\n\n .vta-detail-flag {\n background: rgba(16, 185, 129, 0.15);\n color: #6ee7b7;\n }\n}\n";
|
|
885
923
|
const routes = [
|
|
886
924
|
{ path: "/", Component: HomePage },
|
|
887
925
|
{ path: "/interactions/:collection", Component: InteractionCollection },
|
|
@@ -903,20 +941,15 @@ function AdminApp({ baseUrl = "/api" }) {
|
|
|
903
941
|
const isLoading = loadingInfo || loadingData;
|
|
904
942
|
const error = infoError || dataError;
|
|
905
943
|
if (isLoading) {
|
|
906
|
-
return /* @__PURE__ */
|
|
907
|
-
/* @__PURE__ */ jsx("style", { children: adminStyles }),
|
|
908
|
-
/* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading..." })
|
|
909
|
-
] });
|
|
944
|
+
return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
|
|
910
945
|
}
|
|
911
946
|
if (error) {
|
|
912
|
-
return /* @__PURE__ */
|
|
913
|
-
/* @__PURE__ */ jsx("style", { children: adminStyles }),
|
|
914
|
-
/* @__PURE__ */ jsx("div", { className: "vta-error", children: "Failed to load server info. Is the API running?" })
|
|
915
|
-
] });
|
|
947
|
+
return /* @__PURE__ */ jsx("div", { className: "p-6 text-destructive", children: "Failed to load server info. Is the API running?" });
|
|
916
948
|
}
|
|
917
949
|
if (!serverInfo || !resourceData) return null;
|
|
918
|
-
|
|
919
|
-
|
|
950
|
+
const title = serverInfo.message.replace("Vertesia Tools API", "Tools Server");
|
|
951
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-background text-foreground", children: [
|
|
952
|
+
/* @__PURE__ */ jsx(AdminTopBar, { title }),
|
|
920
953
|
/* @__PURE__ */ jsx(AdminContext.Provider, { value: {
|
|
921
954
|
serverInfo,
|
|
922
955
|
collections: resourceData.collections,
|