);
diff --git a/showcase/components/AppShell.tsx b/showcase/components/AppShell.tsx
index 4a996e17..5257aafa 100644
--- a/showcase/components/AppShell.tsx
+++ b/showcase/components/AppShell.tsx
@@ -4,6 +4,7 @@ import { useEffect, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import type { Language, Tier, Protocol } from "@/lib/types";
+import { languageTags } from "@/lib/types";
import {
Menu,
Chevron,
@@ -107,7 +108,7 @@ export default function AppShell({
{it.title}
{it.featured ? : null}
- {it.language}
+ {languageTags(it.language).join(" · ")}
);
})}
diff --git a/showcase/components/DiscoverPanel.tsx b/showcase/components/DiscoverPanel.tsx
index 4fc81af3..5f271a45 100644
--- a/showcase/components/DiscoverPanel.tsx
+++ b/showcase/components/DiscoverPanel.tsx
@@ -137,22 +137,6 @@ export default function DiscoverPanel({ run }: { run: DiscoverRun }) {
return (
- {/* guided-tour video — watch the concept, then run it live below */}
- {run.video ? (
-
-
-
- {run.video.caption} · {run.video.duration}
-
-
- ) : null}
-
{/* readout */}
diff --git a/showcase/content/tutorials.ts b/showcase/content/tutorials.ts
index 57e6cade..8c2e38df 100644
--- a/showcase/content/tutorials.ts
+++ b/showcase/content/tutorials.ts
@@ -568,7 +568,7 @@ weather.ensureCity # prompt — guide the LLM to request weather`,
tagline:
"The half that comes before payment: the same live catalog of pay-per-use AI agents, read three ways — by eye, by an agent, and by a crawler. Public, unauthenticated, and free to read.",
protocol: "catalog",
- language: "ts",
+ language: "agnostic",
tier: "discover",
repoPath: "catalog/discover-the-catalog/",
learn: {
diff --git a/showcase/lib/types.ts b/showcase/lib/types.ts
index ad03b227..26994ff0 100644
--- a/showcase/lib/types.ts
+++ b/showcase/lib/types.ts
@@ -2,7 +2,7 @@
// One shape for all tutorials → uniform pages out of wildly different READMEs.
export type Protocol = "x402" | "mcp" | "langchain" | "catalog";
-export type Language = "ts" | "py" | "autonomous";
+export type Language = "ts" | "py" | "autonomous" | "agnostic";
export type Tier = "live" | "recap" | "discover";
export interface CodeSample {
@@ -141,4 +141,17 @@ export const LANGUAGE_LABEL: Record = {
ts: "ts",
py: "py",
autonomous: "autonomous",
+ // Required (Record is total) but unreachable for chips: languageTags() returns
+ // LANGUAGE_TAGS["agnostic"] instead. The rendered text lives there, not here.
+ agnostic: "agnostic",
};
+
+// A tutorial's language, as the chip(s) to show. Most languages are one chip; a
+// language-agnostic tutorial is labelled by the interfaces it teaches instead — its own
+// chip each (e.g. "mcp", "api"). Single source of truth for every render site.
+const LANGUAGE_TAGS: Partial> = {
+ agnostic: ["mcp", "api"],
+};
+export function languageTags(language: Language): string[] {
+ return LANGUAGE_TAGS[language] ?? [LANGUAGE_LABEL[language]];
+}