@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.
Files changed (58) hide show
  1. package/lib/AdminApp.d.ts +3 -1
  2. package/lib/AdminApp.d.ts.map +1 -1
  3. package/lib/components/AdminTopBar.d.ts +6 -0
  4. package/lib/components/AdminTopBar.d.ts.map +1 -0
  5. package/lib/components/CollectionCard.d.ts.map +1 -1
  6. package/lib/components/DetailPage.d.ts.map +1 -1
  7. package/lib/components/EndpointPanel.d.ts.map +1 -1
  8. package/lib/components/HeroSection.d.ts.map +1 -1
  9. package/lib/components/ResourceCard.d.ts.map +1 -1
  10. package/lib/components/ResourceSection.d.ts.map +1 -1
  11. package/lib/components/SearchBar.d.ts.map +1 -1
  12. package/lib/components/SummaryBadge.d.ts.map +1 -1
  13. package/lib/components/index.d.ts +6 -5
  14. package/lib/components/index.d.ts.map +1 -1
  15. package/lib/components/typeVariants.d.ts +5 -0
  16. package/lib/components/typeVariants.d.ts.map +1 -0
  17. package/lib/hooks.d.ts +1 -1
  18. package/lib/hooks.d.ts.map +1 -1
  19. package/lib/pages/HomePage.d.ts.map +1 -1
  20. package/lib/pages/InteractionCollection.d.ts.map +1 -1
  21. package/lib/pages/InteractionDetail.d.ts.map +1 -1
  22. package/lib/pages/SkillCollection.d.ts.map +1 -1
  23. package/lib/pages/SkillDetail.d.ts.map +1 -1
  24. package/lib/pages/TemplateCollection.d.ts.map +1 -1
  25. package/lib/pages/TemplateDetail.d.ts.map +1 -1
  26. package/lib/pages/ToolCollection.d.ts.map +1 -1
  27. package/lib/pages/TypeCollection.d.ts.map +1 -1
  28. package/lib/pages/TypeDetail.d.ts.map +1 -1
  29. package/lib/tools-admin-ui.js +410 -377
  30. package/lib/tools-admin-ui.js.map +1 -1
  31. package/package.json +8 -4
  32. package/src/AdminApp.tsx +21 -17
  33. package/src/components/AdminTopBar.tsx +39 -0
  34. package/src/components/CollectionCard.tsx +18 -13
  35. package/src/components/DetailPage.tsx +20 -11
  36. package/src/components/EndpointPanel.tsx +16 -7
  37. package/src/components/HeroSection.tsx +51 -45
  38. package/src/components/ResourceCard.tsx +23 -18
  39. package/src/components/ResourceSection.tsx +7 -5
  40. package/src/components/SearchBar.tsx +8 -6
  41. package/src/components/SummaryBadge.tsx +4 -3
  42. package/src/components/index.ts +6 -5
  43. package/src/components/typeVariants.ts +18 -0
  44. package/src/dev/index.css +13 -0
  45. package/src/dev/main.tsx +5 -2
  46. package/src/hooks.ts +2 -1
  47. package/src/pages/HomePage.tsx +18 -15
  48. package/src/pages/InteractionCollection.tsx +25 -27
  49. package/src/pages/InteractionDetail.tsx +35 -34
  50. package/src/pages/SkillCollection.tsx +29 -32
  51. package/src/pages/SkillDetail.tsx +31 -41
  52. package/src/pages/TemplateCollection.tsx +25 -21
  53. package/src/pages/TemplateDetail.tsx +18 -17
  54. package/src/pages/ToolCollection.tsx +22 -16
  55. package/src/pages/TypeCollection.tsx +32 -24
  56. package/src/pages/TypeDetail.tsx +16 -18
  57. package/src/theme.css +12 -0
  58. package/src/admin.css +0 -650
@@ -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 AdminContext = createContext(void 0);
187
- function useAdminContext() {
188
- const ctx = useContext(AdminContext);
189
- if (!ctx) throw new Error("useAdminContext must be used within AdminApp");
190
- return ctx;
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: "vta-endpoint", children: [
201
- /* @__PURE__ */ jsx("div", { className: "vta-endpoint-label", children: label }),
202
- /* @__PURE__ */ jsxs("div", { className: "vta-endpoint-box", children: [
203
- /* @__PURE__ */ jsx("code", { className: "vta-endpoint-code", children: path }),
204
- /* @__PURE__ */ jsx("button", { onClick: handleCopy, className: "vta-copy-btn", title: "Copy full URL", children: copied ? "✓" : "⧉" })
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("span", { className: "vta-badge", children: [
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("header", { className: "vta-hero", children: [
239
- /* @__PURE__ */ jsxs("div", { className: "vta-hero-main", children: [
240
- /* @__PURE__ */ jsxs("div", { className: "vta-hero-identity", children: [
241
- /* @__PURE__ */ jsx("div", { className: "vta-hero-logo", children: getInitials(title) }),
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: "vta-hero-eyebrow", children: "Tools Server" }),
244
- /* @__PURE__ */ jsx("h1", { className: "vta-hero-title", children: title })
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: "vta-hero-tagline", children: "Discover the tools, skills, interactions, and content types exposed by this server." }),
248
- /* @__PURE__ */ jsx("div", { className: "vta-hero-summary", children: badgeLabels.map(({ type, label }) => /* @__PURE__ */ jsx(SummaryBadge, { count: counts[type] || 0, label }, type)) }),
249
- /* @__PURE__ */ jsxs("div", { className: "vta-hero-links", children: [
250
- /* @__PURE__ */ jsxs("a", { href: "/app/", target: "_blank", className: "vta-link-primary", children: [
251
- /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
252
- /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
253
- /* @__PURE__ */ jsx("line", { x1: "9", y1: "3", x2: "9", y2: "21" })
254
- ] }),
255
- "UI Plugin Dev"
256
- ] }),
257
- /* @__PURE__ */ jsxs("a", { href: "/lib/plugin.js", className: "vta-link-secondary", children: [
258
- /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
259
- /* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
260
- /* @__PURE__ */ jsx("polyline", { points: "7 10 12 15 17 10" }),
261
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
262
- ] }),
263
- "Plugin Bundle"
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: "vta-hero-panel", children: [
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: "vta-hero-hint", children: [
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: "vta-hero-version", children: [
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: "vta-search", children: [
404
+ return /* @__PURE__ */ jsxs("div", { className: "mb-7", children: [
289
405
  /* @__PURE__ */ jsx(
290
- "input",
406
+ Input,
291
407
  {
292
408
  type: "search",
293
409
  value,
294
- onChange: (e) => onChange(e.target.value),
410
+ onChange,
295
411
  placeholder: placeholder || "Search collections...",
296
- className: "vta-search-input",
412
+ className: "max-w-sm rounded-full",
297
413
  autoComplete: "off"
298
414
  }
299
415
  ),
300
- hasQuery && !noResults && /* @__PURE__ */ jsxs("p", { className: "vta-search-hint", children: [
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: "vta-search-empty", children: "No resources match this search." })
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: "vta-root", children: [
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
- /* Search mode: show individual resource cards */
402
- sections.map((section, i) => {
403
- const sectionItems = filtered.filter((r) => r.type === section.type);
404
- return /* @__PURE__ */ jsx(
405
- ResourceSection,
406
- {
407
- title: section.title,
408
- subtitle: section.subtitle,
409
- resources: sectionItems,
410
- showDivider: i > 0
411
- },
412
- section.type
413
- );
414
- })
415
- ) : (
416
- /* Browse mode: show collection cards grouped by type */
417
- sections.map((section, i) => {
418
- const sectionCollections = collections.filter((c) => c.type === section.type);
419
- const mcpResources = section.type === "mcp" ? resources.filter((r) => r.type === "mcp") : [];
420
- if (sectionCollections.length === 0 && mcpResources.length === 0) return null;
421
- return /* @__PURE__ */ jsxs("section", { children: [
422
- i > 0 && /* @__PURE__ */ jsx("hr", { className: "vta-divider" }),
423
- /* @__PURE__ */ jsxs("div", { children: [
424
- /* @__PURE__ */ jsxs("h2", { className: "vta-section-title", children: [
425
- section.title,
426
- /* @__PURE__ */ jsxs("span", { className: "vta-section-count", children: [
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__ */ jsxs("div", { className: "vta-card-grid", children: [
436
- sectionCollections.map((col) => /* @__PURE__ */ jsx(CollectionCard, { collection: col }, `${col.type}:${col.name}`)),
437
- mcpResources.map((r) => /* @__PURE__ */ jsxs("div", { className: "vta-card", children: [
438
- /* @__PURE__ */ jsx("span", { className: "vta-card-type vta-card-type--mcp", children: "mcp" }),
439
- /* @__PURE__ */ jsx("div", { className: "vta-card-title", children: r.title }),
440
- /* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: r.description || "No description" }),
441
- r.url && /* @__PURE__ */ jsx("div", { className: "vta-card-url", children: r.url })
442
- ] }, r.name))
443
- ] })
444
- ] }, section.type);
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, isLoading, error } = useFetch(
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 (isLoading) {
460
- return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading collection..." });
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: "vta-card-grid", children: interactions.map((inter) => /* @__PURE__ */ jsx(
476
- NavLink,
477
- {
478
- href: `/interactions/${collection}/${inter.name}`,
479
- className: "vta-card-link",
480
- children: /* @__PURE__ */ jsxs("div", { className: "vta-card vta-card--link", children: [
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, isLoading, error } = useFetch(
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 (isLoading) {
510
- return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading interaction..." });
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: "vta-detail-section", children: [
531
- /* @__PURE__ */ jsx("h2", { children: "Prompts" }),
532
- interaction.prompts.map((prompt, i) => /* @__PURE__ */ jsxs("div", { className: "vta-detail-card", children: [
533
- /* @__PURE__ */ jsxs("div", { className: "vta-detail-card-header", children: [
534
- /* @__PURE__ */ jsx("span", { className: `vta-detail-role vta-detail-role--${prompt.role}`, children: prompt.role }),
535
- prompt.name && /* @__PURE__ */ jsx("span", { className: "vta-detail-prompt-name", children: prompt.name })
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: "vta-detail-code", children: prompt.content })
538
- ] }, i))
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: "vta-detail-section", children: [
541
- /* @__PURE__ */ jsx("h2", { children: "Result Schema" }),
542
- /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: JSON.stringify(interaction.result_schema, null, 2) })
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: "vta-detail-section", children: [
545
- /* @__PURE__ */ jsx("h2", { children: "Agent Runner" }),
546
- /* @__PURE__ */ jsxs("div", { className: "vta-detail-flags", children: [
547
- agent_runner_options.is_agent && /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: "Agent" }),
548
- agent_runner_options.is_tool && /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: "Tool" }),
549
- agent_runner_options.is_skill && /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: "Skill" })
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, isLoading, error } = useFetch(
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 (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading collection..." });
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: "vta-detail-section", children: [
624
- /* @__PURE__ */ jsx("h2", { children: "Widgets" }),
625
- /* @__PURE__ */ jsx("div", { className: "vta-detail-flags", children: collectionWidgets.map((w) => /* @__PURE__ */ jsxs("span", { className: "vta-detail-flag", children: [
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: "vta-card-url", style: { marginLeft: "0.5rem" }, children: [
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: "vta-card-grid", children: data.tools.map((skill) => {
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
- NavLink,
638
- {
639
- href: `/skills/${collection}/${displayName}`,
640
- className: "vta-card-link",
641
- children: /* @__PURE__ */ jsxs("div", { className: "vta-card vta-card--link", children: [
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, isLoading, error } = useFetch(
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 (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading skill..." });
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: "vta-detail-section", children: [
682
- /* @__PURE__ */ jsx("h2", { children: "Widgets" }),
683
- /* @__PURE__ */ jsx("div", { className: "vta-detail-flags", children: skill.widgets.map((w) => /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: w }, w)) })
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: "vta-detail-section", children: [
686
- /* @__PURE__ */ jsx("h2", { children: "Scripts" }),
687
- /* @__PURE__ */ jsx("div", { className: "vta-detail-flags", children: skill.scripts.map((s) => /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: s }, s)) })
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: "vta-detail-section", children: [
690
- /* @__PURE__ */ jsx("h2", { children: "Related Tools" }),
691
- /* @__PURE__ */ jsx("div", { className: "vta-detail-flags", children: skill.related_tools.map((t) => /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: t }, t)) })
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: "vta-detail-section", children: [
694
- /* @__PURE__ */ jsx("h2", { children: "Execution" }),
695
- /* @__PURE__ */ jsxs("div", { className: "vta-detail-flags", children: [
696
- /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: skill.execution.language }),
697
- skill.execution.packages?.map((p) => /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: p }, p))
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: "vta-detail-section", children: [
701
- /* @__PURE__ */ jsxs("h2", { children: [
702
- "Instructions ",
703
- skill.content_type === "jst" && /* @__PURE__ */ jsx("span", { className: "vta-tag", children: "JST template" })
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: "vta-detail-code", children: skill.instructions })
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: "vta-detail-section", children: [
708
- /* @__PURE__ */ jsx("h2", { children: "Input Schema" }),
709
- /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: JSON.stringify(skill.input_schema, null, 2) })
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 TypeCollection() {
721
+ function TemplateCollection() {
716
722
  const collection = useParams("collection");
717
723
  const { baseUrl } = useAdminContext();
718
- const { data: types, isLoading, error } = useFetch(
719
- () => fetch(`${baseUrl}/types/${collection}`).then((r) => {
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 (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading collection..." });
726
- if (error || !types) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
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: "type",
740
+ type: "template",
735
741
  title: collection,
736
- description: `${types.length} content type${types.length !== 1 ? "s" : ""} in this collection.`,
737
- children: /* @__PURE__ */ jsx("div", { className: "vta-card-grid", children: types.map((t) => {
738
- const typeName = t.id?.split(":")[1] || t.name;
739
- return /* @__PURE__ */ jsx(
740
- NavLink,
741
- {
742
- href: `/types/${collection}/${typeName}`,
743
- className: "vta-card-link",
744
- children: /* @__PURE__ */ jsxs("div", { className: "vta-card vta-card--link", children: [
745
- /* @__PURE__ */ jsx("span", { className: "vta-card-type vta-card-type--type", children: "type" }),
746
- /* @__PURE__ */ jsx("div", { className: "vta-card-title", children: t.name }),
747
- /* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: t.description || "No description" }),
748
- t.tags && t.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "vta-card-tags", children: t.tags.map((tag) => /* @__PURE__ */ jsx("span", { className: "vta-tag", children: tag }, tag)) }),
749
- /* @__PURE__ */ jsxs("div", { className: "vta-card-url", children: [
750
- t.is_chunkable && "chunkable",
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 TypeDetail() {
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: typeDef, isLoading, error } = useFetch(
768
- () => fetch(`${baseUrl}/types/${collection}/${name}`).then((r) => {
769
- if (!r.ok) throw new Error(`Failed to load type: ${r.statusText}`);
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 (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading type..." });
775
- if (error || !typeDef) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
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: "type",
784
- title: typeDef.name,
785
- description: typeDef.description,
786
- tags: typeDef.tags,
787
- backHref: `/types/${collection}`,
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
- (typeDef.is_chunkable || typeDef.strict_mode) && /* @__PURE__ */ jsx("div", { className: "vta-detail-section", children: /* @__PURE__ */ jsxs("div", { className: "vta-detail-flags", children: [
790
- typeDef.is_chunkable && /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: "Chunkable" }),
791
- typeDef.strict_mode && /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: "Strict Mode" })
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
- typeDef.table_layout && typeDef.table_layout.length > 0 && /* @__PURE__ */ jsxs("div", { className: "vta-detail-section", children: [
798
- /* @__PURE__ */ jsx("h2", { children: "Table Layout" }),
799
- /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: JSON.stringify(typeDef.table_layout, null, 2) })
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 TemplateCollection() {
800
+ function ToolCollection() {
806
801
  const collection = useParams("collection");
807
802
  const { baseUrl } = useAdminContext();
808
- const { data: templates, isLoading, error } = useFetch(
809
- () => fetch(`${baseUrl}/templates/${collection}`).then((r) => {
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 (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading collection..." });
816
- if (error || !templates) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
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: "template",
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: `${templates.length} template${templates.length !== 1 ? "s" : ""} in this collection.`,
827
- children: /* @__PURE__ */ jsx("div", { className: "vta-card-grid", children: templates.map((tmpl) => /* @__PURE__ */ jsx(
828
- NavLink,
829
- {
830
- href: `/templates/${collection}/${tmpl.name}`,
831
- className: "vta-card-link",
832
- children: /* @__PURE__ */ jsxs("div", { className: "vta-card vta-card--link", children: [
833
- /* @__PURE__ */ jsx("div", { className: "vta-card-type vta-card-type--template", children: tmpl.type || "template" }),
834
- /* @__PURE__ */ jsx("div", { className: "vta-card-title", children: tmpl.title || tmpl.name }),
835
- /* @__PURE__ */ jsx("div", { className: "vta-card-desc", children: tmpl.description || "No description" }),
836
- tmpl.tags && tmpl.tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "vta-card-tags", children: tmpl.tags.map((tag) => /* @__PURE__ */ jsx("span", { className: "vta-tag", children: tag }, tag)) })
837
- ] })
838
- },
839
- tmpl.name
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 TemplateDetail() {
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: template, isLoading, error } = useFetch(
850
- () => fetch(`${baseUrl}/templates/${collection}/${name}`).then((r) => {
851
- if (!r.ok) throw new Error(`Failed to load template: ${r.statusText}`);
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 (isLoading) return /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading template..." });
857
- if (error || !template) return /* @__PURE__ */ jsxs("div", { className: "vta-error", children: [
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: "template",
866
- title: template.title || template.name,
867
- description: template.description,
868
- tags: template.tags,
869
- backHref: `/templates/${collection}`,
901
+ type: "type",
902
+ title: typeDef.name,
903
+ description: typeDef.description,
904
+ tags: typeDef.tags,
905
+ backHref: `/types/${collection}`,
870
906
  children: [
871
- /* @__PURE__ */ jsx("div", { className: "vta-detail-section", children: /* @__PURE__ */ jsx("div", { className: "vta-detail-flags", children: /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: template.type }) }) }),
872
- template.assets && template.assets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "vta-detail-section", children: [
873
- /* @__PURE__ */ jsx("h2", { children: "Assets" }),
874
- /* @__PURE__ */ jsx("div", { className: "vta-detail-flags", children: template.assets.map((asset) => /* @__PURE__ */ jsx("span", { className: "vta-detail-flag", children: asset.split("/").pop() }, asset)) })
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: "vta-detail-section", children: [
877
- /* @__PURE__ */ jsx("h2", { children: "Instructions" }),
878
- /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: template.instructions })
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__ */ jsxs(Fragment, { children: [
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__ */ jsxs(Fragment, { children: [
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
- return /* @__PURE__ */ jsxs(Fragment, { children: [
919
- /* @__PURE__ */ jsx("style", { children: adminStyles }),
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,