From b62ede1bd62be5813f13f577ef4a998ff006f1ad Mon Sep 17 00:00:00 2001 From: Cosmo Date: Sun, 5 Jul 2026 20:55:45 -0400 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20add=20/plugins=20page=20=E2=80=94?= =?UTF-8?q?=20agent=20plugin=20marketplace=20showcase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New /plugins page showcasing all 4 Recoup plugins with install commands - Plugin cards with capabilities, skill counts, audience, GitHub links - Copy-to-clipboard install commands for Claude Code/Cowork/Codex/Cursor - How it works section (Install → Connect → Go) - CTA to docs and pricing - Added Plugins to header nav and footer product section - Copy extracted to lib/copy/plugins.ts (single source of truth pattern) --- app/plugins/layout.tsx | 17 +++ app/plugins/page.tsx | 234 +++++++++++++++++++++++++++++++++++++++++ lib/copy/plugins.ts | 125 ++++++++++++++++++++++ lib/nav.ts | 2 + 4 files changed, 378 insertions(+) create mode 100644 app/plugins/layout.tsx create mode 100644 app/plugins/page.tsx create mode 100644 lib/copy/plugins.ts diff --git a/app/plugins/layout.tsx b/app/plugins/layout.tsx new file mode 100644 index 0000000..24673f2 --- /dev/null +++ b/app/plugins/layout.tsx @@ -0,0 +1,17 @@ +import type { Metadata } from "next"; +import { buildPageMetadata } from "@/lib/seo"; + +export const metadata: Metadata = buildPageMetadata({ + title: "Agent Plugins for Music | Recoup", + description: + "Install Recoup plugins into Claude Code, Cowork, Codex, or Cursor. Artist research, content creation, catalog deals, and more — powered by the Recoup API.", + path: "/plugins", +}); + +export default function PluginsLayout({ + children, +}: { + children: React.ReactNode; +}) { + return <>{children}; +} diff --git a/app/plugins/page.tsx b/app/plugins/page.tsx new file mode 100644 index 0000000..b2f75e9 --- /dev/null +++ b/app/plugins/page.tsx @@ -0,0 +1,234 @@ +"use client"; + +import { useState, useEffect, useRef } from "react"; +import Link from "next/link"; +import { ArrowRight, Copy, Check, Terminal } from "lucide-react"; +import { pluginsCopy } from "@/lib/copy/plugins"; +import type { Plugin } from "@/lib/copy/plugins"; + +/* ── reveal-on-scroll ── */ +function useReveal() { + const ref = useRef(null); + const [v, setV] = useState(false); + useEffect(() => { + const el = ref.current; + if (!el) return; + const io = new IntersectionObserver( + ([e]) => { + if (e.isIntersecting) { + setV(true); + io.disconnect(); + } + }, + { threshold: 0.08 }, + ); + io.observe(el); + return () => io.disconnect(); + }, []); + return { + ref, + cls: `transition-all duration-[900ms] ease-[cubic-bezier(.16,1,.3,1)] ${ + v ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10" + }`, + }; +} + +/* ── copy button ── */ +function CopyButton({ text }: { text: string }) { + const [copied, setCopied] = useState(false); + return ( + + ); +} + +/* ── plugin card ── */ +function PluginCard({ plugin, index }: { plugin: Plugin; index: number }) { + const { ref, cls } = useReveal(); + return ( +
+
+ {/* Header */} +
+
+

{plugin.name}

+ + {plugin.skillCount} skill{plugin.skillCount !== 1 ? "s" : ""} + {" · "} + {plugin.audience} + +
+ + GitHub → + +
+ + {/* Description */} +

+ {plugin.description} +

+ + {/* Capabilities */} +
    + {plugin.capabilities.map((cap) => ( +
  • + + {cap} +
  • + ))} +
+ + {/* Install command */} +
+ + {plugin.installCommand} + +
+
+
+ ); +} + +/* ── step card ── */ +function StepCard({ + step, + index, +}: { + step: (typeof pluginsCopy.steps)[number]; + index: number; +}) { + const { ref, cls } = useReveal(); + return ( +
+
+
+ {step.number} +
+

{step.title}

+

+ {step.description} +

+
+
+ ); +} + +/* ── page ── */ +export default function PluginsPage() { + const c = pluginsCopy; + + return ( +
+ {/* Hero */} +
+
+ Plugin Marketplace +
+

+ {c.title} +

+

+ {c.subtitle} +

+ + {/* Compatible-with badges */} +
+ {c.compatibleWith.map((tool) => ( + + {tool} + + ))} +
+
+ + {/* Plugin grid */} +
+ {c.plugins.map((plugin, i) => ( + + ))} +
+ + {/* How it works */} +
+

+ How it works +

+
+ {c.steps.map((step, i) => ( + + ))} +
+
+ + {/* CTA */} +
+
+

+ Ready to plug in? +

+

+ Get your API key, install a plugin, and let your AI agent run your + music business. +

+
+ + Get API Key + + + View Pricing + +
+
+
+
+ ); +} diff --git a/lib/copy/plugins.ts b/lib/copy/plugins.ts new file mode 100644 index 0000000..2eea651 --- /dev/null +++ b/lib/copy/plugins.ts @@ -0,0 +1,125 @@ +/** + * Plugins page copy — single source of truth for the plugin showcase. + */ + +export interface Plugin { + id: string; + name: string; + description: string; + skillCount: number; + capabilities: string[]; + installCommand: string; + repo: string; + /** Which tier of customer this targets */ + audience: string; +} + +export const pluginsCopy = { + title: "Agent Plugins for Music", + subtitle: + "Install a plugin. Your AI agent gets music industry superpowers. Works with Claude Code, Cowork, Codex, and Cursor.", + + plugins: [ + { + id: "research", + name: "Research", + description: + "Artist analytics, audience insights, competitive analysis, playlist intelligence, and trend detection. The foundation for any music business decision.", + skillCount: 7, + capabilities: [ + "Artist research & briefs", + "Audience demographics & cities", + "Competitive landscape", + "Playlist intelligence", + "Trend detection", + "Web intelligence", + "People outreach", + ], + installCommand: + "claude plugin install https://github.com/recoupable/recoup-research-plugin", + repo: "https://github.com/recoupable/recoup-research-plugin", + audience: "Labels, managers, distributors", + }, + { + id: "content", + name: "Content", + description: + "Generate release strategy content, social posts, and short-form video scripts. Your agent becomes your marketing team.", + skillCount: 3, + capabilities: [ + "Content creation workflows", + "Social post generation", + "Short-form video scripts", + ], + installCommand: + "claude plugin install https://github.com/recoupable/recoup-content-plugin", + repo: "https://github.com/recoupable/recoup-content-plugin", + audience: "Labels, managers, artists", + }, + { + id: "catalogs", + name: "Catalog Deals", + description: + "Turn a messy seller data room into a source-cited deal package. Royalty normalization, rights review, valuation analysis, financing underwriting, and IC memos — all agent-driven.", + skillCount: 17, + capabilities: [ + "Data room ingestion & normalization", + "Catalog valuation & analysis", + "Rights & ownership review", + "Royalty audit", + "Seller prep & cleanup", + "Financing underwriting", + "IC memo generation", + "Deal dashboard (HTML)", + ], + installCommand: + "claude plugin install https://github.com/recoupable/recoup-catalogs-plugin", + repo: "https://github.com/recoupable/recoup-catalogs-plugin", + audience: "Catalog acquirers, investors, lenders", + }, + { + id: "platform", + name: "Platform", + description: + "Onboarding and diagnostics. Your agent's starting point — validates credentials, discovers capabilities, and runs health checks.", + skillCount: 2, + capabilities: [ + "Guided onboarding flow", + "API key validation", + "Plugin discovery & recommendations", + "Health check & diagnostics", + ], + installCommand: + "claude plugin install https://github.com/recoupable/recoup-platform-plugin", + repo: "https://github.com/recoupable/recoup-platform-plugin", + audience: "Everyone — start here", + }, + ] satisfies Plugin[], + + compatibleWith: [ + "Claude Code", + "Claude Cowork", + "Codex", + "Cursor", + ], + + steps: [ + { + number: "1", + title: "Install", + description: "One command. Plugin loads into your AI tool of choice.", + }, + { + number: "2", + title: "Connect", + description: + "Set your Recoup API key. Get one free at developers.recoupable.com.", + }, + { + number: "3", + title: "Go", + description: + "Ask your agent anything about music. It now has the data and workflows to deliver.", + }, + ], +} as const; diff --git a/lib/nav.ts b/lib/nav.ts index 956cf3b..f26ab98 100644 --- a/lib/nav.ts +++ b/lib/nav.ts @@ -5,6 +5,7 @@ import { siteConfig } from "@/lib/config"; export const nav: readonly { label: string; href: string; external?: boolean }[] = [ + { label: "Plugins", href: "/plugins" }, { label: "Results", href: "/results" }, { label: "Pricing", href: "/pricing" }, { label: "Docs", href: siteConfig.docsUrl, external: true }, @@ -17,6 +18,7 @@ export const footerNav = { items: [ { label: "Platform", href: "/platform" }, { label: "Pricing", href: "/pricing" }, + { label: "Plugins", href: "/plugins" }, { label: "Docs", href: siteConfig.docsUrl, external: true }, ], }, From d4ea588d6105132de3775eb7f7702eb10b9f832d Mon Sep 17 00:00:00 2001 From: Recoupable Date: Sun, 5 Jul 2026 21:03:58 -0400 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20add=20/compare=20page=20=E2=80=94?= =?UTF-8?q?=20BYOA=20agent=20plugins=20vs=20dashboards?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/compare/layout.tsx | 18 +++++ app/compare/page.tsx | 156 +++++++++++++++++++++++++++++++++++++++++ lib/copy/compare.ts | 93 ++++++++++++++++++++++++ lib/nav.ts | 2 + 4 files changed, 269 insertions(+) create mode 100644 app/compare/layout.tsx create mode 100644 app/compare/page.tsx create mode 100644 lib/copy/compare.ts diff --git a/app/compare/layout.tsx b/app/compare/layout.tsx new file mode 100644 index 0000000..bf794f8 --- /dev/null +++ b/app/compare/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from "next"; +import { siteConfig } from "@/lib/config"; +import { buildPageMetadata } from "@/lib/seo"; + +export const metadata: Metadata = buildPageMetadata({ + title: `Dashboards vs Agent Plugins — Why BYOA Wins | ${siteConfig.name}`, + description: + "Compare traditional music AI dashboards to Recoup's agent-native plugins. See why labels are switching from another app to tools that work inside Claude, Cursor, and Codex.", + path: "/compare", +}); + +export default function CompareLayout({ + children, +}: { + children: React.ReactNode; +}) { + return <>{children}; +} diff --git a/app/compare/page.tsx b/app/compare/page.tsx new file mode 100644 index 0000000..9ff384b --- /dev/null +++ b/app/compare/page.tsx @@ -0,0 +1,156 @@ +"use client"; + +import { useState, useEffect, useRef } from "react"; +import Link from "next/link"; +import { ArrowRight, Zap, Monitor } from "lucide-react"; +import { compareCopy } from "@/lib/copy/compare"; + +/* ── reveal-on-scroll ── */ +function useReveal() { + const ref = useRef(null); + const [v, setV] = useState(false); + useEffect(() => { + const el = ref.current; + if (!el) return; + const io = new IntersectionObserver( + ([e]) => { + if (e.isIntersecting) { + setV(true); + io.disconnect(); + } + }, + { threshold: 0.08 }, + ); + io.observe(el); + return () => io.disconnect(); + }, []); + return { + ref, + cls: `transition-all duration-[900ms] ease-[cubic-bezier(.16,1,.3,1)] ${ + v ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10" + }`, + }; +} + +export default function ComparePage() { + const c = compareCopy; + const hero = useReveal(); + const table = useReveal(); + const why = useReveal(); + const cta = useReveal(); + + return ( +
+ {/* ── Hero ── */} +
+
+

+ The BYOA Advantage +

+

+ {c.title} +

+

+ {c.subtitle} +

+

+ “{c.heroQuote}” +

+
+
+ + {/* ── Comparison Table ── */} +
+
+
+ {/* Header */} +
+
+   +
+
+ + Agent Plugins +
+
+ + Dashboards +
+
+ + {/* Rows */} + {c.sections[0].rows.map((row, i) => ( +
+
+ {row.category} +
+
+ {row.byoa} +
+
+ {row.dashboard} +
+
+ ))} +
+
+
+ + {/* ── Why It Matters ── */} +
+
+

+ {c.whyItMatters.title} +

+
+ {c.whyItMatters.points.map((point) => ( +
+

+ {point.heading} +

+

+ {point.body} +

+
+ ))} +
+
+
+ + {/* ── CTA ── */} +
+
+

+ {c.cta.title} +

+

+ {c.cta.description} +

+
+ + {c.cta.primary.label} + + + + {c.cta.secondary.label} + +
+
+
+
+ ); +} diff --git a/lib/copy/compare.ts b/lib/copy/compare.ts new file mode 100644 index 0000000..8276ff6 --- /dev/null +++ b/lib/copy/compare.ts @@ -0,0 +1,93 @@ +/** + * Compare page copy — BYOA vs Dashboard approach. + * Single source of truth for the comparison page. + */ + +export interface ComparisonRow { + category: string; + byoa: string; + dashboard: string; +} + +export const compareCopy = { + title: "Dashboards vs. Agent Plugins", + subtitle: + "Every other music AI company built another dashboard. We built tools that work inside your agent — Claude, Cursor, Codex, or whatever comes next.", + heroQuote: + "The last thing your team needs is another tab to manage.", + + sections: [ + { + id: "comparison", + title: "Side by side", + rows: [ + { + category: "Where it runs", + byoa: "Inside Claude, Cursor, Codex — tools your team already uses", + dashboard: "Another web app with its own login, UI, and learning curve", + }, + { + category: "Workflow", + byoa: "Ask your agent → it calls Recoup tools → results appear in your conversation", + dashboard: "Open the app → navigate menus → copy data → paste into your workflow", + }, + { + category: "Integration", + byoa: "One install command. Works with any agent that supports MCP or plugins.", + dashboard: "Custom integrations, API wrappers, or manual import/export", + }, + { + category: "Content creation", + byoa: "Agent generates, posts, and tracks — hands-free loop", + dashboard: "Generate in one tool, download, upload to another, schedule manually", + }, + { + category: "Research", + byoa: "Ask a question in natural language → structured report with sources", + dashboard: "Navigate to analytics tab, filter, export CSV, analyze yourself", + }, + { + category: "Team adoption", + byoa: "If they can talk to an AI, they can use Recoup", + dashboard: "Training sessions, onboarding docs, feature walkthroughs", + }, + { + category: "Scales with AI", + byoa: "Better agents = better results from the same plugins, automatically", + dashboard: "Platform has to rebuild its own AI features from scratch", + }, + { + category: "Lock-in", + byoa: "Switch agents anytime. Your tools travel with you.", + dashboard: "Your workflows live inside their UI. Switching = starting over.", + }, + ] as ComparisonRow[], + }, + ], + + whyItMatters: { + title: "Why this matters for music companies", + points: [ + { + heading: "Labels are already using AI agents", + body: "Your A&R team uses Claude. Your marketing team uses Cursor. Your analysts use Codex. Recoup plugins meet them where they already work — no new app to learn.", + }, + { + heading: "One install replaces a content agency", + body: "Labels paying $5,000/month for content creation agencies are replacing them with Recoup's content plugin. Same output, fraction of the cost, instant turnaround.", + }, + { + heading: "Agent-native means future-proof", + body: "When Claude 5 ships, or when your team switches to a new agent, your Recoup plugins still work. Dashboard companies have to rebuild. You don't.", + }, + ], + }, + + cta: { + title: "See it in action", + description: + "Install a plugin in 30 seconds. No meetings, no demos, no contracts.", + primary: { label: "Browse Plugins", href: "/plugins" }, + secondary: { label: "View Pricing", href: "/pricing" }, + }, +} as const; diff --git a/lib/nav.ts b/lib/nav.ts index f26ab98..81133a3 100644 --- a/lib/nav.ts +++ b/lib/nav.ts @@ -6,6 +6,7 @@ import { siteConfig } from "@/lib/config"; export const nav: readonly { label: string; href: string; external?: boolean }[] = [ { label: "Plugins", href: "/plugins" }, + { label: "Compare", href: "/compare" }, { label: "Results", href: "/results" }, { label: "Pricing", href: "/pricing" }, { label: "Docs", href: siteConfig.docsUrl, external: true }, @@ -30,6 +31,7 @@ export const footerNav = { { label: "AI Playbook", href: "/playbook" }, { label: "ROI Calculator", href: "/calculator" }, { label: "AI Readiness Audit", href: "/audit" }, + { label: "BYOA vs Dashboards", href: "/compare" }, { label: "Records", href: "/records" }, ], },