@vertesia/tools-admin-ui 1.0.0-dev.20260227.112605Z → 1.0.0

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 (65) 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/ActivityCollection.d.ts +2 -0
  20. package/lib/pages/ActivityCollection.d.ts.map +1 -0
  21. package/lib/pages/HomePage.d.ts.map +1 -1
  22. package/lib/pages/InteractionCollection.d.ts.map +1 -1
  23. package/lib/pages/InteractionDetail.d.ts.map +1 -1
  24. package/lib/pages/SkillCollection.d.ts.map +1 -1
  25. package/lib/pages/SkillDetail.d.ts.map +1 -1
  26. package/lib/pages/TemplateCollection.d.ts.map +1 -1
  27. package/lib/pages/TemplateDetail.d.ts.map +1 -1
  28. package/lib/pages/ToolCollection.d.ts.map +1 -1
  29. package/lib/pages/TypeCollection.d.ts.map +1 -1
  30. package/lib/pages/TypeDetail.d.ts.map +1 -1
  31. package/lib/tools-admin-ui.js +481 -379
  32. package/lib/tools-admin-ui.js.map +1 -1
  33. package/lib/types.d.ts +8 -3
  34. package/lib/types.d.ts.map +1 -1
  35. package/package.json +8 -4
  36. package/src/AdminApp.tsx +23 -17
  37. package/src/components/AdminTopBar.tsx +39 -0
  38. package/src/components/CollectionCard.tsx +20 -14
  39. package/src/components/DetailPage.tsx +20 -11
  40. package/src/components/EndpointPanel.tsx +16 -7
  41. package/src/components/HeroSection.tsx +52 -45
  42. package/src/components/ResourceCard.tsx +23 -18
  43. package/src/components/ResourceSection.tsx +7 -5
  44. package/src/components/SearchBar.tsx +8 -6
  45. package/src/components/SummaryBadge.tsx +4 -3
  46. package/src/components/index.ts +6 -5
  47. package/src/components/typeVariants.ts +19 -0
  48. package/src/dev/env.ts +3 -3
  49. package/src/dev/index.css +13 -0
  50. package/src/dev/main.tsx +11 -5
  51. package/src/hooks.ts +5 -3
  52. package/src/pages/ActivityCollection.tsx +67 -0
  53. package/src/pages/HomePage.tsx +19 -15
  54. package/src/pages/InteractionCollection.tsx +25 -27
  55. package/src/pages/InteractionDetail.tsx +35 -34
  56. package/src/pages/SkillCollection.tsx +29 -32
  57. package/src/pages/SkillDetail.tsx +31 -41
  58. package/src/pages/TemplateCollection.tsx +25 -21
  59. package/src/pages/TemplateDetail.tsx +18 -17
  60. package/src/pages/ToolCollection.tsx +22 -16
  61. package/src/pages/TypeCollection.tsx +32 -24
  62. package/src/pages/TypeDetail.tsx +16 -18
  63. package/src/theme.css +12 -0
  64. package/src/types.ts +34 -1
  65. 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, Badge, Spinner, Card, CardContent, DotBadge, Separator, Input } 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
  }
@@ -21,7 +53,7 @@ function countPerCollection(items, collections, extractCollection) {
21
53
  }
22
54
  return counts;
23
55
  }
24
- function buildResourceData(interactionsResp, toolsResp, skillsResp, typesResp, templatesResp, mcpEndpoints) {
56
+ function buildResourceData(interactionsResp, toolsResp, skillsResp, activitiesResp, typesResp, templatesResp, mcpEndpoints) {
25
57
  const collections = [];
26
58
  const resources = [];
27
59
  const interCounts = countPerCollection(
@@ -94,6 +126,29 @@ function buildResourceData(interactionsResp, toolsResp, skillsResp, typesResp, t
94
126
  url: skill.url
95
127
  });
96
128
  }
129
+ const actCounts = countPerCollection(
130
+ activitiesResp.activities,
131
+ activitiesResp.collections,
132
+ (a) => a.collection
133
+ );
134
+ for (const col of activitiesResp.collections) {
135
+ collections.push({
136
+ name: col.name,
137
+ title: col.title || formatTitle(col.name),
138
+ description: col.description || "",
139
+ type: "activity",
140
+ count: actCounts.get(col.name) || 0
141
+ });
142
+ }
143
+ for (const act of activitiesResp.activities) {
144
+ resources.push({
145
+ name: act.name,
146
+ title: act.title || formatTitle(act.name),
147
+ description: act.description || "",
148
+ type: "activity",
149
+ url: act.url
150
+ });
151
+ }
97
152
  const typeCounts = countPerCollection(
98
153
  typesResp.types,
99
154
  typesResp.collections,
@@ -176,18 +231,101 @@ function useResourceData(baseUrl, mcpEndpoints) {
176
231
  fetchJson("interactions"),
177
232
  fetchJson("tools"),
178
233
  fetchJson("skills"),
234
+ fetchJson("activities"),
179
235
  fetchJson("types"),
180
236
  fetchJson("templates")
181
237
  ]).then(
182
- ([interactions, tools, skills, types, templates]) => buildResourceData(interactions, tools, skills, types, templates, mcpEndpoints)
238
+ ([interactions, tools, skills, activities, types, templates]) => buildResourceData(interactions, tools, skills, activities, types, templates, mcpEndpoints)
183
239
  );
184
240
  }, [baseUrl, mcpEndpoints]);
185
241
  }
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;
242
+ const TYPE_VARIANTS = {
243
+ tool: "bg-blue-100 text-blue-800 dark:bg-blue-500/15 dark:text-blue-300",
244
+ skill: "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/15 dark:text-emerald-300",
245
+ interaction: "bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300",
246
+ type: "bg-gray-100 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300",
247
+ template: "bg-violet-100 text-violet-800 dark:bg-violet-500/15 dark:text-violet-300",
248
+ activity: "bg-rose-100 text-rose-800 dark:bg-rose-500/15 dark:text-rose-300",
249
+ mcp: "bg-pink-100 text-pink-800 dark:bg-pink-500/15 dark:text-pink-300"
250
+ };
251
+ const ROLE_VARIANTS = {
252
+ system: "bg-blue-100 text-blue-800 dark:bg-blue-500/15 dark:text-blue-300",
253
+ user: "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/15 dark:text-emerald-300",
254
+ assistant: "bg-violet-100 text-violet-800 dark:bg-violet-500/15 dark:text-violet-300",
255
+ safety: "bg-pink-100 text-pink-800 dark:bg-pink-500/15 dark:text-pink-300",
256
+ tool: "bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300"
257
+ };
258
+ function DetailPage({ type, title, description, tags, backHref = "/", children }) {
259
+ return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl px-7 py-10", children: [
260
+ /* @__PURE__ */ jsxs("nav", { className: "mb-5 flex items-center gap-4", children: [
261
+ backHref !== "/" && /* @__PURE__ */ jsx(NavLink, { href: "/", className: "text-sm text-primary hover:opacity-75", children: "Home" }),
262
+ /* @__PURE__ */ jsxs(NavLink, { href: backHref, className: "flex items-center gap-1 text-sm text-primary hover:opacity-75", children: [
263
+ /* @__PURE__ */ jsx(ArrowLeft, { className: "size-3.5" }),
264
+ "Back"
265
+ ] })
266
+ ] }),
267
+ /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
268
+ /* @__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 }),
269
+ /* @__PURE__ */ jsx("h1", { className: "-tracking-wide text-3xl font-bold text-foreground", children: title }),
270
+ description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm leading-relaxed text-muted-foreground", children: description }),
271
+ 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)) })
272
+ ] }),
273
+ children
274
+ ] });
275
+ }
276
+ function ActivityCollection() {
277
+ const collection = useParams("collection");
278
+ const { baseUrl } = useAdminContext();
279
+ const { data, error } = useFetch(
280
+ () => fetch(`${baseUrl}/activities/${collection}`).then((r) => {
281
+ if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
282
+ return r.json();
283
+ }),
284
+ [baseUrl, collection]
285
+ );
286
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
287
+ "Failed to load activity collection “",
288
+ collection,
289
+ "”."
290
+ ] });
291
+ if (!data) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
292
+ return /* @__PURE__ */ jsx(
293
+ DetailPage,
294
+ {
295
+ type: "activity",
296
+ title: data.title || collection,
297
+ description: data.description || `${data.activities.length} activit${data.activities.length !== 1 ? "ies" : "y"} in this collection.`,
298
+ children: data.activities.map((activity) => /* @__PURE__ */ jsx(Card, { className: "mb-4", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
299
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
300
+ /* @__PURE__ */ jsx("span", { className: `inline-block rounded-full px-2 py-0.5 text-[0.7rem] font-semibold uppercase tracking-wide ${TYPE_VARIANTS.activity}`, children: "activity" }),
301
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-card-foreground", children: activity.name })
302
+ ] }),
303
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: activity.description || "No description" }),
304
+ activity.input_schema && /* @__PURE__ */ jsxs("div", { className: "mt-3", children: [
305
+ /* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Input Schema" }),
306
+ /* @__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(activity.input_schema, null, 2) })
307
+ ] }),
308
+ activity.output_schema && /* @__PURE__ */ jsxs("div", { className: "mt-3", children: [
309
+ /* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Output Schema" }),
310
+ /* @__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(activity.output_schema, null, 2) })
311
+ ] })
312
+ ] }) }, activity.name))
313
+ }
314
+ );
315
+ }
316
+ function CollectionCard({ collection }) {
317
+ const plural = collection.type === "activity" ? "activities" : `${collection.type}s`;
318
+ const href = `/${plural}/${collection.name}`;
319
+ 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: [
320
+ /* @__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 }),
321
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: collection.title }),
322
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: collection.description || "No description" }),
323
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 font-mono text-xs text-muted-foreground", children: [
324
+ collection.count,
325
+ " ",
326
+ collection.count === 1 ? "item" : "items"
327
+ ] })
328
+ ] }) }) });
191
329
  }
192
330
  function EndpointPanel({ label, path }) {
193
331
  const [copied, setCopied] = useState(false);
@@ -197,18 +335,26 @@ function EndpointPanel({ label, path }) {
197
335
  setCopied(true);
198
336
  setTimeout(() => setCopied(false), 1500);
199
337
  }
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 ? "✓" : "⧉" })
338
+ return /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
339
+ /* @__PURE__ */ jsx("div", { className: "mb-1 text-[0.7rem] font-medium uppercase tracking-widest text-primary", children: label }),
340
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-muted-background px-3 py-2", children: [
341
+ /* @__PURE__ */ jsx("code", { className: "flex-1 font-mono text-sm text-foreground", children: path }),
342
+ /* @__PURE__ */ jsx(
343
+ Button,
344
+ {
345
+ variant: "ghost",
346
+ size: "xs",
347
+ onClick: handleCopy,
348
+ "aria-label": "Copy full URL",
349
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" })
350
+ }
351
+ )
205
352
  ] })
206
353
  ] });
207
354
  }
208
355
  function SummaryBadge({ count, label }) {
209
356
  if (count === 0) return null;
210
- return /* @__PURE__ */ jsxs("span", { className: "vta-badge", children: [
211
- /* @__PURE__ */ jsx("span", { className: "vta-badge-dot" }),
357
+ return /* @__PURE__ */ jsxs(DotBadge, { variant: "success", children: [
212
358
  count,
213
359
  " ",
214
360
  label,
@@ -227,6 +373,7 @@ function countByType(resources) {
227
373
  }
228
374
  const badgeLabels = [
229
375
  { type: "tool", label: "tool" },
376
+ { type: "activity", label: "activity" },
230
377
  { type: "skill", label: "skill" },
231
378
  { type: "interaction", label: "interaction" },
232
379
  { type: "type", label: "content type" },
@@ -235,135 +382,117 @@ const badgeLabels = [
235
382
  ];
236
383
  function HeroSection({ title, version, resources }) {
237
384
  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) }),
385
+ 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: [
386
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3", children: [
387
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
388
+ /* @__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
389
  /* @__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 })
390
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-widest text-muted-foreground", children: "Tools Server" }),
391
+ /* @__PURE__ */ jsx("h1", { className: "-tracking-wide text-2xl font-bold text-foreground", children: title })
245
392
  ] })
246
393
  ] }),
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
- ] })
394
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Discover the tools, skills, interactions, and content types exposed by this server." }),
395
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: badgeLabels.map(({ type, label }) => /* @__PURE__ */ jsx(SummaryBadge, { count: counts[type] || 0, label }, type)) }),
396
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-3 pt-1", children: [
397
+ /* @__PURE__ */ jsxs(
398
+ "a",
399
+ {
400
+ href: "/app/",
401
+ target: "_blank",
402
+ rel: "noopener noreferrer",
403
+ 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",
404
+ children: [
405
+ /* @__PURE__ */ jsx(LayoutDashboard, { className: "size-4" }),
406
+ "UI Plugin Dev"
407
+ ]
408
+ }
409
+ ),
410
+ /* @__PURE__ */ jsxs(
411
+ "a",
412
+ {
413
+ href: "/lib/plugin.js",
414
+ 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",
415
+ children: [
416
+ /* @__PURE__ */ jsx(Download, { className: "size-4" }),
417
+ "Plugin Bundle"
418
+ ]
419
+ }
420
+ )
265
421
  ] })
266
422
  ] }),
267
- /* @__PURE__ */ jsxs("aside", { className: "vta-hero-panel", children: [
423
+ /* @__PURE__ */ jsxs("aside", { className: "min-w-55 max-w-65 shrink-0", children: [
268
424
  /* @__PURE__ */ jsx(EndpointPanel, { label: "Base endpoint", path: "/api" }),
269
425
  /* @__PURE__ */ jsx(EndpointPanel, { label: "Package endpoint", path: "/api/package" }),
270
- /* @__PURE__ */ jsxs("p", { className: "vta-hero-hint", children: [
426
+ /* @__PURE__ */ jsxs("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: [
271
427
  "Use ",
272
- /* @__PURE__ */ jsx("strong", { children: "POST /api/tools/<collection>" }),
428
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "POST /api/tools/<collection>" }),
273
429
  " or",
274
430
  " ",
275
- /* @__PURE__ */ jsx("strong", { children: "POST /api/skills/<collection>" }),
431
+ /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: "POST /api/skills/<collection>" }),
276
432
  " to call these from your apps or agents."
277
433
  ] }),
278
- /* @__PURE__ */ jsxs("p", { className: "vta-hero-version", children: [
434
+ /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
279
435
  "v",
280
436
  version
281
437
  ] })
282
438
  ] })
439
+ ] }) });
440
+ }
441
+ function ResourceCard({ resource }) {
442
+ return /* @__PURE__ */ jsx(Card, { className: "transition-all hover:-translate-y-0.5 hover:shadow-md", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
443
+ /* @__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 }),
444
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: resource.title }),
445
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: resource.description || "No description" }),
446
+ 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)) }),
447
+ resource.url && /* @__PURE__ */ jsx("div", { className: "mt-2 truncate font-mono text-xs text-muted-foreground", children: resource.url })
448
+ ] }) });
449
+ }
450
+ function ResourceSection({ title, subtitle, resources, showDivider }) {
451
+ if (resources.length === 0) return null;
452
+ return /* @__PURE__ */ jsxs("section", { children: [
453
+ showDivider && /* @__PURE__ */ jsx(Separator, { className: "my-8" }),
454
+ /* @__PURE__ */ jsxs("div", { children: [
455
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold text-foreground", children: [
456
+ title,
457
+ /* @__PURE__ */ jsxs("span", { className: "ml-2 text-sm font-normal text-muted-foreground", children: [
458
+ "(",
459
+ resources.length,
460
+ ")"
461
+ ] })
462
+ ] }),
463
+ /* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: subtitle })
464
+ ] }),
465
+ /* @__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
466
  ] });
284
467
  }
285
468
  function SearchBar({ value, onChange, placeholder, resultCount, totalCount }) {
286
469
  const hasQuery = value.trim().length > 0;
287
470
  const noResults = hasQuery && resultCount === 0;
288
- return /* @__PURE__ */ jsxs("div", { className: "vta-search", children: [
471
+ return /* @__PURE__ */ jsxs("div", { className: "mb-7", children: [
289
472
  /* @__PURE__ */ jsx(
290
- "input",
473
+ Input,
291
474
  {
292
475
  type: "search",
293
476
  value,
294
- onChange: (e) => onChange(e.target.value),
477
+ onChange,
295
478
  placeholder: placeholder || "Search collections...",
296
- className: "vta-search-input",
479
+ className: "max-w-sm rounded-full",
297
480
  autoComplete: "off"
298
481
  }
299
482
  ),
300
- hasQuery && !noResults && /* @__PURE__ */ jsxs("p", { className: "vta-search-hint", children: [
483
+ hasQuery && !noResults && /* @__PURE__ */ jsxs("p", { className: "mt-1.5 text-xs text-muted-foreground", children: [
301
484
  "Showing ",
302
485
  resultCount,
303
486
  " of ",
304
487
  totalCount,
305
488
  " resources"
306
489
  ] }),
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
490
+ noResults && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-destructive", children: "No resources match this search." })
363
491
  ] });
364
492
  }
365
493
  const sections = [
366
494
  { type: "tool", title: "Tools", subtitle: "Remote tools available to agents via Vertesia." },
495
+ { type: "activity", title: "Activities", subtitle: "Remote activities for DSL workflows, invoked via HTTP." },
367
496
  { type: "skill", title: "Skills", subtitle: "Reusable instructions and scripts packaged as tools." },
368
497
  { type: "interaction", title: "Interactions", subtitle: "Conversation blueprints surfaced in the Vertesia UI." },
369
498
  { type: "type", title: "Content Types", subtitle: "Schema definitions for structured content in the data store." },
@@ -378,7 +507,7 @@ function HomePage() {
378
507
  [resources, search]
379
508
  );
380
509
  const isSearching = search.trim().length > 0;
381
- return /* @__PURE__ */ jsxs("div", { className: "vta-root", children: [
510
+ return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl px-7 py-10", children: [
382
511
  /* @__PURE__ */ jsx(
383
512
  HeroSection,
384
513
  {
@@ -397,95 +526,81 @@ function HomePage() {
397
526
  totalCount: resources.length
398
527
  }
399
528
  ),
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 })
529
+ isSearching ? sections.map((section, i) => {
530
+ const sectionItems = filtered.filter((r) => r.type === section.type);
531
+ return /* @__PURE__ */ jsx(
532
+ ResourceSection,
533
+ {
534
+ title: section.title,
535
+ subtitle: section.subtitle,
536
+ resources: sectionItems,
537
+ showDivider: i > 0
538
+ },
539
+ section.type
540
+ );
541
+ }) : sections.map((section, i) => {
542
+ const sectionCollections = collections.filter((c) => c.type === section.type);
543
+ const mcpResources = section.type === "mcp" ? resources.filter((r) => r.type === "mcp") : [];
544
+ if (sectionCollections.length === 0 && mcpResources.length === 0) return null;
545
+ return /* @__PURE__ */ jsxs("section", { children: [
546
+ i > 0 && /* @__PURE__ */ jsx(Separator, { className: "my-8" }),
547
+ /* @__PURE__ */ jsxs("div", { children: [
548
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold text-foreground", children: [
549
+ section.title,
550
+ /* @__PURE__ */ jsxs("span", { className: "ml-2 text-sm font-normal text-muted-foreground", children: [
551
+ "(",
552
+ sectionCollections.length,
553
+ sectionCollections.length === 1 ? " collection" : " collections",
554
+ ")"
555
+ ] })
434
556
  ] }),
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
- )
557
+ /* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: section.subtitle })
558
+ ] }),
559
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [
560
+ sectionCollections.map((col) => /* @__PURE__ */ jsx(CollectionCard, { collection: col }, `${col.type}:${col.name}`)),
561
+ mcpResources.map((r) => /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border bg-card p-5 shadow-sm", children: [
562
+ /* @__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" }),
563
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: r.title }),
564
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: r.description || "No description" }),
565
+ r.url && /* @__PURE__ */ jsx("div", { className: "mt-2 truncate font-mono text-xs text-muted-foreground", children: r.url })
566
+ ] }, r.name))
567
+ ] })
568
+ ] }, section.type);
569
+ })
447
570
  ] });
448
571
  }
449
572
  function InteractionCollection() {
450
573
  const collection = useParams("collection");
451
574
  const { baseUrl } = useAdminContext();
452
- const { data: interactions, isLoading, error } = useFetch(
575
+ const { data: interactions, error } = useFetch(
453
576
  () => fetch(`${baseUrl}/interactions/${collection}`).then((r) => {
454
577
  if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
455
578
  return r.json();
456
579
  }),
457
580
  [baseUrl, collection]
458
581
  );
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: [
582
+ if (error) {
583
+ return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
464
584
  "Failed to load collection “",
465
585
  collection,
466
586
  "”."
467
587
  ] });
468
588
  }
589
+ if (!interactions) {
590
+ return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
591
+ }
469
592
  return /* @__PURE__ */ jsx(
470
593
  DetailPage,
471
594
  {
472
595
  type: "interaction",
473
596
  title: collection,
474
597
  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
- )) })
598
+ 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: [
599
+ /* @__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" }),
600
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: inter.title || inter.name }),
601
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: inter.description || "No description" }),
602
+ 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)) })
603
+ ] }) }) }, inter.id)) })
489
604
  }
490
605
  );
491
606
  }
@@ -495,7 +610,7 @@ function InteractionDetail() {
495
610
  const collection = params.collection;
496
611
  const name = params.name;
497
612
  const { baseUrl } = useAdminContext();
498
- const { data: interaction, isLoading, error } = useFetch(
613
+ const { data: interaction, error } = useFetch(
499
614
  () => client.getRawJWT().then((token) => fetch(`${baseUrl}/interactions/${collection}/${name}`, {
500
615
  headers: {
501
616
  Authorization: `Bearer ${token}`
@@ -506,16 +621,16 @@ function InteractionDetail() {
506
621
  }),
507
622
  [baseUrl, collection, name]
508
623
  );
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: [
624
+ if (error) {
625
+ return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
514
626
  "Failed to load interaction “",
515
627
  name,
516
628
  "”."
517
629
  ] });
518
630
  }
631
+ if (!interaction) {
632
+ return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
633
+ }
519
634
  const { agent_runner_options } = interaction;
520
635
  const hasAgentFlags = agent_runner_options && (agent_runner_options.is_agent || agent_runner_options.is_tool || agent_runner_options.is_skill);
521
636
  return /* @__PURE__ */ jsxs(
@@ -527,72 +642,39 @@ function InteractionDetail() {
527
642
  tags: interaction.tags,
528
643
  backHref: `/interactions/${collection}`,
529
644
  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 })
645
+ interaction.prompts && interaction.prompts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
646
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Prompts" }),
647
+ interaction.prompts.map((prompt) => /* @__PURE__ */ jsx(Card, { className: "mb-3", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-4", children: [
648
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
649
+ /* @__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 }),
650
+ prompt.name && /* @__PURE__ */ jsx("span", { className: "text-sm italic text-muted-foreground", children: prompt.name })
536
651
  ] }),
537
- /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: prompt.content })
538
- ] }, i))
652
+ /* @__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 })
653
+ ] }) }, `${prompt.role}-${prompt.name ?? ""}`))
539
654
  ] }),
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) })
655
+ interaction.result_schema && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
656
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Result Schema" }),
657
+ /* @__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
658
  ] }),
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" })
659
+ hasAgentFlags && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
660
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Agent Runner" }),
661
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
662
+ agent_runner_options.is_agent && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Agent" }),
663
+ agent_runner_options.is_tool && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Tool" }),
664
+ agent_runner_options.is_skill && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Skill" })
550
665
  ] })
551
666
  ] })
552
667
  ]
553
668
  }
554
669
  );
555
670
  }
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
671
  function skillDisplayName(name) {
590
672
  return name.startsWith("learn_") ? name.slice(6) : name;
591
673
  }
592
674
  function SkillCollection() {
593
675
  const collection = useParams("collection");
594
676
  const { baseUrl } = useAdminContext();
595
- const { data, isLoading, error } = useFetch(
677
+ const { data, error } = useFetch(
596
678
  () => fetch(`${baseUrl}/skills/${collection}`).then((r) => {
597
679
  if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
598
680
  return r.json();
@@ -607,12 +689,12 @@ function SkillCollection() {
607
689
  if (!widgetsData?.widgets) return [];
608
690
  return Object.entries(widgetsData.widgets).filter(([_, w]) => w.collection === collection).map(([name, w]) => ({ name, ...w }));
609
691
  }, [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: [
692
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
612
693
  "Failed to load skill collection “",
613
694
  collection,
614
695
  "”."
615
696
  ] });
697
+ if (!data) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
616
698
  return /* @__PURE__ */ jsxs(
617
699
  DetailPage,
618
700
  {
@@ -620,33 +702,25 @@ function SkillCollection() {
620
702
  title: data.title || collection,
621
703
  description: data.description || `${data.tools.length} skill${data.tools.length !== 1 ? "s" : ""} in this collection.`,
622
704
  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: [
705
+ collectionWidgets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
706
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Widgets" }),
707
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: collectionWidgets.map((w) => /* @__PURE__ */ jsxs(Badge, { variant: "success", children: [
626
708
  w.name,
627
- /* @__PURE__ */ jsxs("span", { className: "vta-card-url", style: { marginLeft: "0.5rem" }, children: [
709
+ /* @__PURE__ */ jsxs("span", { className: "ml-2 font-mono text-xs opacity-70", children: [
628
710
  "(skill: ",
629
711
  w.skill,
630
712
  ")"
631
713
  ] })
632
714
  ] }, w.name)) })
633
715
  ] }),
634
- /* @__PURE__ */ jsx("div", { className: "vta-card-grid", children: data.tools.map((skill) => {
716
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: data.tools.map((skill) => {
635
717
  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
- );
718
+ 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: [
719
+ /* @__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" }),
720
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: displayName }),
721
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: skill.description || "No description" }),
722
+ 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)) })
723
+ ] }) }) }, skill.name);
650
724
  }) })
651
725
  ]
652
726
  }
@@ -657,19 +731,19 @@ function SkillDetail() {
657
731
  const collection = params.collection;
658
732
  const name = params.name;
659
733
  const { baseUrl } = useAdminContext();
660
- const { data: skill, isLoading, error } = useFetch(
734
+ const { data: skill, error } = useFetch(
661
735
  () => fetch(`${baseUrl}/skills/${collection}/${name}`).then((r) => {
662
736
  if (!r.ok) throw new Error(`Failed to load skill: ${r.statusText}`);
663
737
  return r.json();
664
738
  }),
665
739
  [baseUrl, collection, name]
666
740
  );
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: [
741
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
669
742
  "Failed to load skill “",
670
743
  name,
671
744
  "”."
672
745
  ] });
746
+ if (!skill) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
673
747
  return /* @__PURE__ */ jsxs(
674
748
  DetailPage,
675
749
  {
@@ -678,215 +752,248 @@ function SkillDetail() {
678
752
  description: skill.description,
679
753
  backHref: `/skills/${collection}`,
680
754
  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)) })
755
+ skill.widgets && skill.widgets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
756
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Widgets" }),
757
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: skill.widgets.map((w) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: w }, w)) })
684
758
  ] }),
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)) })
759
+ skill.scripts && skill.scripts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
760
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Scripts" }),
761
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: skill.scripts.map((s) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: s }, s)) })
688
762
  ] }),
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)) })
763
+ skill.related_tools && skill.related_tools.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
764
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Related Tools" }),
765
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: skill.related_tools.map((t) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: t }, t)) })
692
766
  ] }),
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))
767
+ skill.execution && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
768
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Execution" }),
769
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
770
+ /* @__PURE__ */ jsx(Badge, { variant: "success", children: skill.execution.language }),
771
+ skill.execution.packages?.map((p) => /* @__PURE__ */ jsx(Badge, { variant: "success", children: p }, p))
698
772
  ] })
699
773
  ] }),
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" })
774
+ /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
775
+ /* @__PURE__ */ jsxs("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: [
776
+ "Instructions",
777
+ skill.content_type === "jst" && /* @__PURE__ */ jsx(Badge, { className: "ml-2", children: "JST template" })
704
778
  ] }),
705
- /* @__PURE__ */ jsx("pre", { className: "vta-detail-code", children: skill.instructions })
779
+ /* @__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
780
  ] }),
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) })
781
+ skill.input_schema && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
782
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Input Schema" }),
783
+ /* @__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
784
  ] })
711
785
  ]
712
786
  }
713
787
  );
714
788
  }
715
- function TypeCollection() {
789
+ function TemplateCollection() {
716
790
  const collection = useParams("collection");
717
791
  const { baseUrl } = useAdminContext();
718
- const { data: types, isLoading, error } = useFetch(
719
- () => fetch(`${baseUrl}/types/${collection}`).then((r) => {
792
+ const { data: templates, error } = useFetch(
793
+ () => fetch(`${baseUrl}/templates/${collection}`).then((r) => {
720
794
  if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
721
795
  return r.json();
722
796
  }),
723
797
  [baseUrl, collection]
724
798
  );
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 “",
799
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
800
+ "Failed to load template collection ",
728
801
  collection,
729
802
  "”."
730
803
  ] });
804
+ if (!templates) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
731
805
  return /* @__PURE__ */ jsx(
732
806
  DetailPage,
733
807
  {
734
- type: "type",
808
+ type: "template",
735
809
  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
- }) })
810
+ description: `${templates.length} template${templates.length !== 1 ? "s" : ""} in this collection.`,
811
+ 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(
812
+ NavLink,
813
+ {
814
+ href: `/templates/${collection}/${tmpl.name}`,
815
+ className: "no-underline",
816
+ 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: [
817
+ /* @__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" }),
818
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: tmpl.title || tmpl.name }),
819
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: tmpl.description || "No description" }),
820
+ 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)) })
821
+ ] }) })
822
+ },
823
+ tmpl.name
824
+ )) })
759
825
  }
760
826
  );
761
827
  }
762
- function TypeDetail() {
828
+ function TemplateDetail() {
763
829
  const params = useParams();
764
830
  const collection = params.collection;
765
831
  const name = params.name;
766
832
  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}`);
833
+ const { data: template, error } = useFetch(
834
+ () => fetch(`${baseUrl}/templates/${collection}/${name}`).then((r) => {
835
+ if (!r.ok) throw new Error(`Failed to load template: ${r.statusText}`);
770
836
  return r.json();
771
837
  }),
772
838
  [baseUrl, collection, name]
773
839
  );
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 “",
840
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
841
+ "Failed to load template ",
777
842
  name,
778
843
  "”."
779
844
  ] });
845
+ if (!template) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
780
846
  return /* @__PURE__ */ jsxs(
781
847
  DetailPage,
782
848
  {
783
- type: "type",
784
- title: typeDef.name,
785
- description: typeDef.description,
786
- tags: typeDef.tags,
787
- backHref: `/types/${collection}`,
849
+ type: "template",
850
+ title: template.title || template.name,
851
+ description: template.description,
852
+ tags: template.tags,
853
+ backHref: `/templates/${collection}`,
788
854
  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) })
855
+ /* @__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 }) }) }),
856
+ template.assets && template.assets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
857
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Assets" }),
858
+ /* @__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
859
  ] }),
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) })
860
+ /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
861
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Instructions" }),
862
+ /* @__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
863
  ] })
801
864
  ]
802
865
  }
803
866
  );
804
867
  }
805
- function TemplateCollection() {
868
+ function ToolCollection() {
806
869
  const collection = useParams("collection");
807
870
  const { baseUrl } = useAdminContext();
808
- const { data: templates, isLoading, error } = useFetch(
809
- () => fetch(`${baseUrl}/templates/${collection}`).then((r) => {
871
+ const { data, error } = useFetch(
872
+ () => fetch(`${baseUrl}/tools/${collection}`).then((r) => {
810
873
  if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
811
874
  return r.json();
812
875
  }),
813
876
  [baseUrl, collection]
814
877
  );
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 “",
878
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
879
+ "Failed to load tool collection ",
818
880
  collection,
819
881
  "”."
820
882
  ] });
883
+ if (!data) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
821
884
  return /* @__PURE__ */ jsx(
822
885
  DetailPage,
823
886
  {
824
- type: "template",
887
+ type: "tool",
888
+ title: data.title || collection,
889
+ description: data.description || `${data.tools.length} tool${data.tools.length !== 1 ? "s" : ""} in this collection.`,
890
+ children: data.tools.map((tool) => /* @__PURE__ */ jsx(Card, { className: "mb-4", children: /* @__PURE__ */ jsxs(CardContent, { className: "p-5", children: [
891
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
892
+ /* @__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" }),
893
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-card-foreground", children: tool.name })
894
+ ] }),
895
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: tool.description || "No description" }),
896
+ 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) })
897
+ ] }) }, tool.name))
898
+ }
899
+ );
900
+ }
901
+ function TypeCollection() {
902
+ const collection = useParams("collection");
903
+ const { baseUrl } = useAdminContext();
904
+ const { data: types, error } = useFetch(
905
+ () => fetch(`${baseUrl}/types/${collection}`).then((r) => {
906
+ if (!r.ok) throw new Error(`Failed to load collection: ${r.statusText}`);
907
+ return r.json();
908
+ }),
909
+ [baseUrl, collection]
910
+ );
911
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
912
+ "Failed to load type collection “",
913
+ collection,
914
+ "”."
915
+ ] });
916
+ if (!types) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
917
+ return /* @__PURE__ */ jsx(
918
+ DetailPage,
919
+ {
920
+ type: "type",
825
921
  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
- )) })
922
+ description: `${types.length} content type${types.length !== 1 ? "s" : ""} in this collection.`,
923
+ children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: types.map((t) => {
924
+ const typeName = t.id?.split(":")[1] || t.name;
925
+ return /* @__PURE__ */ jsx(
926
+ NavLink,
927
+ {
928
+ href: `/types/${collection}/${typeName}`,
929
+ className: "no-underline",
930
+ 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: [
931
+ /* @__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" }),
932
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-card-foreground", children: t.name }),
933
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-muted-foreground", children: t.description || "No description" }),
934
+ 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)) }),
935
+ (t.is_chunkable || t.strict_mode) && /* @__PURE__ */ jsxs("div", { className: "mt-2 truncate font-mono text-xs text-muted-foreground", children: [
936
+ t.is_chunkable && "chunkable",
937
+ t.is_chunkable && t.strict_mode && " · ",
938
+ t.strict_mode && "strict"
939
+ ] })
940
+ ] }) })
941
+ },
942
+ t.name
943
+ );
944
+ }) })
841
945
  }
842
946
  );
843
947
  }
844
- function TemplateDetail() {
948
+ function TypeDetail() {
845
949
  const params = useParams();
846
950
  const collection = params.collection;
847
951
  const name = params.name;
848
952
  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}`);
953
+ const { data: typeDef, error } = useFetch(
954
+ () => fetch(`${baseUrl}/types/${collection}/${name}`).then((r) => {
955
+ if (!r.ok) throw new Error(`Failed to load type: ${r.statusText}`);
852
956
  return r.json();
853
957
  }),
854
958
  [baseUrl, collection, name]
855
959
  );
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 “",
960
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "p-6 text-destructive", children: [
961
+ "Failed to load type ",
859
962
  name,
860
963
  "”."
861
964
  ] });
965
+ if (!typeDef) return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
862
966
  return /* @__PURE__ */ jsxs(
863
967
  DetailPage,
864
968
  {
865
- type: "template",
866
- title: template.title || template.name,
867
- description: template.description,
868
- tags: template.tags,
869
- backHref: `/templates/${collection}`,
969
+ type: "type",
970
+ title: typeDef.name,
971
+ description: typeDef.description,
972
+ tags: typeDef.tags,
973
+ backHref: `/types/${collection}`,
870
974
  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)) })
975
+ (typeDef.is_chunkable || typeDef.strict_mode) && /* @__PURE__ */ jsx("div", { className: "mb-8", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
976
+ typeDef.is_chunkable && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Chunkable" }),
977
+ typeDef.strict_mode && /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Strict Mode" })
978
+ ] }) }),
979
+ typeDef.object_schema && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
980
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Object Schema" }),
981
+ /* @__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
982
  ] }),
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 })
983
+ typeDef.table_layout && typeDef.table_layout.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
984
+ /* @__PURE__ */ jsx("h2", { className: "mb-3 text-lg font-semibold text-foreground", children: "Table Layout" }),
985
+ /* @__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
986
  ] })
880
987
  ]
881
988
  }
882
989
  );
883
990
  }
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
991
  const routes = [
886
992
  { path: "/", Component: HomePage },
887
993
  { path: "/interactions/:collection", Component: InteractionCollection },
888
994
  { path: "/interactions/:collection/:name", Component: InteractionDetail },
889
995
  { path: "/tools/:collection", Component: ToolCollection },
996
+ { path: "/activities/:collection", Component: ActivityCollection },
890
997
  { path: "/skills/:collection", Component: SkillCollection },
891
998
  { path: "/skills/:collection/:name", Component: SkillDetail },
892
999
  { path: "/types/:collection", Component: TypeCollection },
@@ -903,20 +1010,15 @@ function AdminApp({ baseUrl = "/api" }) {
903
1010
  const isLoading = loadingInfo || loadingData;
904
1011
  const error = infoError || dataError;
905
1012
  if (isLoading) {
906
- return /* @__PURE__ */ jsxs(Fragment, { children: [
907
- /* @__PURE__ */ jsx("style", { children: adminStyles }),
908
- /* @__PURE__ */ jsx("div", { className: "vta-loading", children: "Loading..." })
909
- ] });
1013
+ return /* @__PURE__ */ jsx("div", { className: "flex h-64 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx(Spinner, {}) });
910
1014
  }
911
1015
  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
- ] });
1016
+ return /* @__PURE__ */ jsx("div", { className: "p-6 text-destructive", children: "Failed to load server info. Is the API running?" });
916
1017
  }
917
1018
  if (!serverInfo || !resourceData) return null;
918
- return /* @__PURE__ */ jsxs(Fragment, { children: [
919
- /* @__PURE__ */ jsx("style", { children: adminStyles }),
1019
+ const title = serverInfo.message.replace("Vertesia Tools API", "Tools Server");
1020
+ return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-background text-foreground", children: [
1021
+ /* @__PURE__ */ jsx(AdminTopBar, { title }),
920
1022
  /* @__PURE__ */ jsx(AdminContext.Provider, { value: {
921
1023
  serverInfo,
922
1024
  collections: resourceData.collections,