Status: Shipped 2026-05-13 via #44 (SPEC + PLAN + implementation), #45 (project pathPrefix hotfix), #46 (display-name map + inlineMarkdown filter + parser hygiene). Live at https://netresearch.github.io/claude-code-marketplace/. This document remains the canonical scope reference and is kept in sync with the deployed code.
Hinweis: Lokale Arbeitskopie war initial 30 Commits hinter
origin/main. Erst nachgit show origin/main:AGENTS.mdwurde der echte Regelkanon sichtbar. Die Entscheidungen unten reflektieren den Remote-Stand, nicht den initialen Stub.
- Repo-Identität:
github.com/netresearch/claude-code-marketplace, Default-Branchmain, GitHub Pages aktiv (Build-Typeworkflow), Deploy-Pipeline in.github/workflows/pages.yml. - Hosting-Pfad:
https://netresearch.github.io/claude-code-marketplace/. Keine Custom-Domain. - Sprache: Volle Zweisprachigkeit (DE + EN) auf allen Seiten. Default-Locale = EN (
/en/..., plus Root/→ 302 zu Accept-Language-Match oder fallback EN). DE unter/de/.... Bidirektionales<link rel="alternate" hreflang>. - Marketplace-Regeln — drei Quellen:
- Anthropic-Spec (code.claude.com/docs/en/plugin-marketplaces) — Pflichten für
marketplace.json(Schema, kebab-case, reservierte Namen, Install-Syntax, owner-Attribution). Keine Vorgaben für Pages-Content. AGENTS.md(Repo-Regeln) — Pflichten für Pages-Inhalte + Marketplace-Pflege:- § GitHub Pages policy: Marketplace soll Pages-Site als kanonische Discovery- & Storytelling-Schicht publizieren.
- § Marketplace as canonical discovery hub: Pages besitzt Landing-Pages, Cross-Links, Related Skills, indexable detail pages.
- § Required fields per skill entry: 13 Pflichtfelder pro Skill.
- § Canonical categories: Enum mit 7 Werten —
development · devops · security · design · workflow · productivity · document. - § No orphan skills: Jeder Skill mit Category + Use case + Related Skills + Repo + Install + Canonical Landing URL.
- § SEO and discovery rules: erster Satz = Problem; keine generische AI-Boilerplate; Tech explizit benennen; Description ≤300 (target) / ≤500 (hard cap); Descriptions unique.
- § Mirroring rule: skill-spezifische Metadaten kommen aus den Skill-Repos. Heute: README-Sections (
## Use cases,## Expected outputs,## Context requirements,## Related skills, plus die toleranten Aliase insite/scripts/parse-readme.js). Mittelfristig: optionale Discovery-Felder direkt in derSKILL.md-Frontmatter jedes Skill-Repos (z. B.useCases:,relatedSkills:,expectedOutputs:) — eine eigenständigediscovery.yamlist bewusst nicht vorgesehen, weil SKILL.md bereits Frontmatter trägt und Agent-Skills-Spec-Felder beliebig erweiterbar sind (unbekannte Keys werden von kompatiblen Agents ignoriert). Marketplace konsumiert, dupliziert nicht. - § Agent workflow checklist (marketplace changes): 7-Punkte-Checkliste vor PR-Abschluss, inkl.
./scripts/validate.shlokal laufen. - Hinweis: Frühere Feb-5-Version von AGENTS.md erwähnte
bd(beads) + „Landing the Plane" — beides ist inca6a379NICHT mehr enthalten und damit kein Mandat. Tracking erfolgt über das Claude Code Task feature (TaskCreate/TaskUpdate/TaskList).
scripts/validate.sh— mechanischer Guard: erzwingt Category-Enum, Slug-Regex (^[a-z0-9][a-z0-9-]{0,63}$), Description-Limits, Eindeutigkeit, README-Catalog-Row pro Slug.
- Anthropic-Spec (code.claude.com/docs/en/plugin-marketplaces) — Pflichten für
- Stack: Eleventy 3.x + Eleventy-i18n-Plugin + Vanilla CSS + max. 5 KB Vanilla JS. Build-Time-Fetch der Skill-Repo-READMEs via GitHub-API.
- Brand: Aus
netresearch-branding-skill— Turquoise#2F99A4, Orange#FF4D00, Raleway + Open Sans (self-hosted WOFF2). Tokens via Skill-Tool-Invocation während Implementation. - Datenquellen (mit Mirroring-Rule-konformer Konsumation):
- Primär:
.claude-plugin/marketplace.json(40 Plugins, 7 Categories) — liefert Slug, Name, EN-Description, Category, Repo. - Sekundär: Skill-Repo-READMEs (build-time gefetcht via GitHub API) — liefert Use cases, Expected outputs, Context requirements, Related Skills.
- Tertiär: README-Themen-Gruppierung (TYPO3 / OroCommerce / Code Quality & Security / DevOps / Productivity / Meta) als Presentation Groups für die Landing — orthogonal zum Category-Enum, das SEO + Schema.org-
applicationCategoryträgt. - Fallback bei fehlenden Feldern: dokumentierte „N/A (justified)"-Einträge in §Known marketplace overrides der SPEC + AGENTS.md.
- Primär:
- Plugin-Detail-Pages: Phase 1, AGENTS.md-konform. Pro Skill stabile canonical URL
/<lang>/skills/<slug>/. Inhalt aus marketplace.json + Skill-Repo-README (build-time aggregiert). - Analytics: Keine clientseitigen Analytics. Statistik aus GitHub-Repo-Insights (built-in, kein Tracking-Code, kein Cookie-Banner-Bedarf).
- Visuals: Reines Typografie-Layout — große Headings, Whitespace, Brand-Farb-Akzent, max. 24×24px SVG-Icons. Keine bildhaften Illustrationen.
- Hero: Kein Team-Foto. Abstraktes SVG-Hero-Element (Code-Pattern / geometrische Komposition in Brand-Farben).
- Badges: OpenSSF-Scorecard, License, Last-Updated im Footer.
- Internal Marketplace: wird nicht auf der öffentlichen Page erwähnt (
git.netresearch.de/coding-ai/marketplace.gitbleibt rein intern). - DE-Inhalte: wo aus Quelle nicht ableitbar, wird der
german-technical-writing-skillfür Stil/Register herangezogen. Die DE-Variante ist nicht „übersetztes Englisch", sondern eigenständiger Text in deutschem Technical-Register.
Eine statische, narrative Landing-Page auf GitHub Pages, die den Netresearch Claude Code Marketplace (netresearch/claude-code-marketplace) als kuratiertes Skill-Ökosystem präsentiert — nicht als trockene Plugin-Tabelle, sondern als Geschichte: „Wie Netresearch-Engineers ihre Workflows mit Agent Skills automatisieren — und wie deine das auch tun können."
- Primär: TYPO3- und PHP-Engineers, die einen AI-Coding-Workflow aufsetzen und vertrauenswürdige, kuratierte Skills suchen. Treffen die Page über Google, Twitter/X-Posts, Vorträge, README-Links.
- Sekundär: Entscheider (Tech Leads, CTOs), die Netresearch als Dienstleister evaluieren und sehen wollen, dass das Team aktiv im AI-Tooling-Space arbeitet.
- Tertiär: Andere Agent-Skill-Autoren, die das Repo als Referenz nehmen.
| Dimension | Zielwert | Messung |
|---|---|---|
| Lighthouse Performance (Desktop preset, simulated 4G) | ≥ 0.9 (Phase 1 gate); ≥ 0.95 (Phase 2 target) | Lighthouse CI in PR-Checks |
| Lighthouse Accessibility | ≥ 0.9 (Phase 1 gate); 1.0 (Phase 2 target after brand contrast review) | Lighthouse CI |
| Lighthouse Best Practices | ≥ 0.9 (Phase 1 gate); ≥ 0.95 (Phase 2 target) | Lighthouse CI |
| Lighthouse SEO | ≥ 0.9 (Phase 1 gate); ≥ 0.95 (Phase 2 target) | Lighthouse CI |
| LCP (Largest Contentful Paint) | < 2.0 s auf 4G | Web Vitals |
| CLS (Cumulative Layout Shift) | < 0.05 | Web Vitals |
| TBT (Total Blocking Time) | < 100 ms | Lighthouse |
| Page-Size (gzipped HTML+CSS+JS) | < 50 KB initial | curl -sH 'accept-encoding: gzip' |
| JavaScript-Bytes | ≤ 5 KB (nur progressive Enhancement, keine Frameworks) | Build-Bericht |
| HTML-Validität | 0 Errors | W3C Validator (CI) |
| WCAG-Kontrast | AA über das gesamte UI | axe-core CI-Run |
| SEO-Indizierbarkeit | Alle Pages in Sitemap, kein noindex außer 404 |
Sitemap-Check |
| Plugin-Datenkonformität | Anzeige spiegelt marketplace.json 1:1 |
Build-Diff gegen Schema |
| Install-Befehl | Exakt /plugin marketplace add netresearch/claude-code-marketplace (kopierbar mit einem Klick) |
Manueller Check |
| Komponente | Wahl | Begründung |
|---|---|---|
| Static Site Generator | Eleventy 3.x + @11ty/eleventy-plugin-i18n |
Liest .claude-plugin/marketplace.json direkt; nativer i18n-Support via @@locale@@/permalink-Variablen; kein Runtime-JS; perfekt Lighthouse-tauglich. |
| Templating | Nunjucks (Eleventy-Default) | Iteration über Plugins, einfache i18n-Strukturen. |
| CSS | Vanilla CSS, ein Stylesheet, inlined critical CSS | Kein Framework. Brand-Tokens aus netresearch-branding-skill. |
| JavaScript | Vanilla, ≤ 5 KB | Copy-to-Clipboard mit lokalisiertem „Copied/Kopiert"-Feedback und Accept-Language-Redirect auf der Root-Seite. Page funktioniert ohne JS vollständig (Root-Redirect hat Meta-Refresh + Fallback-Links). |
| Fonts | Raleway + Open Sans, self-hosted (subsetted WOFF2) | Kein Google-Fonts-Fetch → besser Lighthouse + DSGVO. Subset auf Latin Extended. |
| README-Fetch | Build-Time, Node-Skript via @octokit/rest mit GITHUB_TOKEN |
Holt READMEs aller 40 Skill-Repos einmal pro Build; Markdown-Parser (marked) extrahiert ## Use cases, ## Related Skills, ## Expected outputs, ## Context requirements. Toleranter Parser mit klar definierten Fallbacks für jede Skill, in der die Section fehlt. |
| Caching | cache/skills-readme/{slug}.json in CI-Cache |
Spart API-Quota + Build-Zeit; ETag-basiert via Octokit If-None-Match. |
| Build-Output | _site/ (Eleventy-Default), deploy via Pages-Action |
Standard-Pfad. |
| CI/CD | GitHub Actions: actions/configure-pages@v5 + actions/deploy-pages@v4 |
Native GitHub-Pages-Deployment via Actions (nicht via gh-pages-Branch). |
| Lighthouse-Gate | treosh/lighthouse-ci-action@v12 |
Blockierender Check pro PR. Audit auf Landing + repräsentativer Detail-Page. |
| HTML-Validierung | html-validate lokal + CI |
Pflicht-Check. |
| A11y-Gate | @axe-core/cli + Pa11y CI auf Landing + 3 zufälligen Detail-Pages |
Repräsentativer Sample. |
| Node-Version | lts/* (.nvmrc) |
Reproducible Builds. |
| Package-Manager | npm | Match zu anderen Netresearch-Repos. |
Alle Skripte aus site/package.json (CWD: site/):
# Setup (einmalig)
npm install
# Vollständiger Build wie in CI: README-Fetch → Linter → Eleventy → hreflang-Check
npm run build:all
# Schneller Eleventy-Only-Build gegen den vorhandenen Cache (prebuild läuft
# `check:categories` + `og:generate` automatisch davor)
npm run build
# Build-once ohne prebuild-Hooks (für IDE-Integrationen)
npm run build:once
# Lokale Entwicklung mit Live-Reload (http://localhost:8080)
npm run dev
# Statisches Vorschau-Hosting nach Build (falls Dev-Server nicht passt)
npm run preview
# Skill-Repo-READMEs holen (ETag-cached); braucht GITHUB_TOKEN für Auth
GITHUB_TOKEN=$(gh auth token) npm run fetch:readmes
# OG-Images neu generieren (Sharp + SVG-Template, 41 PNGs)
npm run og:generate
# AGENTS.md-Compliance-Checks (jeder einzeln + chained)
npm run check # = categories && orphans && seo (advisory)
npm run check:categories # blocking — 7-Werte-Enum
npm run check:orphans # blocking — 13 Pflichtfelder pro Skill
npm run check:seo # advisory — banned phrases, weak openings, description length
npm run check:hreflang # blocking (post-build) — EN↔DE-Paare + Disk-Existenz
# Build-Artefakte aufräumen
npm run cleanLighthouse läuft ausschließlich in CI gegen die gestagte .lhci-site/claude-code-marketplace/-Struktur (siehe .github/workflows/pages.yml + lighthouserc.json); lokal kein eigenes Lighthouse-Script.
/ Marketplace-Root (UNVERÄNDERT)
├── .claude-plugin/
│ └── marketplace.json Single Source of Truth (40 Plugins) — NICHT verschieben
├── scripts/
│ └── validate.sh Existierendes Validation-Skript — UNVERÄNDERT
├── README.md UNVERÄNDERT (oder ergänzt um Link auf Page am Ende)
├── AGENTS.md UNVERÄNDERT
│
├── SPEC.md ← Diese Datei
│
├── site/ ← NEU: Eleventy-Quellen
│ ├── .eleventy.js Eleventy-Config (Datenquellen, Eleventy-Filter-Funktionen wie `titleCase` / `inlineMarkdown` / `skillsInGroup`, pathPrefix, i18n)
│ ├── package.json
│ ├── package-lock.json
│ ├── .nvmrc
│ │
│ ├── scripts/
│ │ ├── fetch-readmes.js Octokit-basierter Fetch aller 40 Skill-Repo-READMEs (ETag-Cache)
│ │ ├── parse-readme.js Markdown→JSON, extrahiert Use cases / Related Skills / Expected outputs / Context requirements; filtert Sub-Heading-Leaks
│ │ ├── generate-og-images.js Sharp + SVG-Template → 41 OG-PNGs (1 Landing + 40 per Skill)
│ │ ├── check-orphans.js Validator: alle 13 AGENTS.md-Pflichtfelder (blocking + advisory)
│ │ ├── check-categories.js Erzwingt 7-Werte-Category-Enum
│ │ ├── check-seo-copy.js Banned-phrases / Weak-openings / Description-Length (advisory)
│ │ └── check-hreflang.js Verifiziert EN↔DE-Paare und dass jeder hreflang-Href on-disk auflöst
│ │
│ ├── lighthouserc.json Live im Repo-Root (lhci-Server mountet `.lhci-site/`)
│ │
│ ├── src/
│ │ ├── _data/
│ │ │ ├── _helpers/ Unterordner mit Underscore-Prefix — Eleventy ignoriert den gesamten Tree als Datenquelle, daher braucht die Datei darin keinen eigenen Underscore.
│ │ │ │ └── display-name.js Zentraler Resolver (von `marketplace.js` und `skills.js` importiert)
│ │ │ ├── marketplace.js Liest ../.claude-plugin/marketplace.json
│ │ │ ├── skills.js Merge marketplace.json + fetched READMEs → kanonische Skill-Objects
│ │ │ ├── skillsBySlug.js Slug-indizierter Lookup für Related-Skill-Cross-Links
│ │ │ ├── displayNames.json Kuratierte Anzeige-Namen (TYPO3 DDEV, OroCommerce, GitHub Project, …)
│ │ │ ├── descriptions_de.json Per-Slug DE-Descriptions (eigenständig getextet, kein Übersetzungs-Echo)
│ │ │ ├── i18n/
│ │ │ │ ├── en.json UI-Strings + Storytelling-Copy EN
│ │ │ │ └── de.json UI-Strings + Storytelling-Copy DE (eigenständig verfasst, nicht maschinell)
│ │ │ ├── categories.js 7-Werte-Enum + DE/EN-Labels
│ │ │ ├── groups.js Themen-Gruppen aus README (TYPO3 / OroCommerce / …) + DE/EN-Labels
│ │ │ ├── overrides.json Known Marketplace Overrides (AGENTS.md §Known marketplace overrides)
│ │ │ └── site.json Site-Metadaten, OG-Defaults, Repo-URL (Host-only; pathPrefix wird im Template via Eleventy `url`-Filter eingesetzt)
│ │ │
│ │ ├── _includes/
│ │ │ ├── layouts/
│ │ │ │ ├── base.njk HTML-Skeleton, lang-Attribut dynamisch, hreflang-Pärchen, OG/Twitter/JSON-LD
│ │ │ │ ├── landing.njk
│ │ │ │ └── skill.njk Detail-Page-Layout (one per skill)
│ │ │ └── partials/
│ │ │ ├── header.njk Mit Lang-Switcher
│ │ │ ├── footer.njk Mit Badges (Scorecard, License, Last-Updated)
│ │ │ ├── skill-card.njk
│ │ │ ├── install-block.njk
│ │ │ ├── related-skills.njk
│ │ │ └── breadcrumbs.njk
│ │ │
│ │ ├── assets/
│ │ │ ├── css/
│ │ │ │ ├── tokens.css Brand-Tokens (CSS Custom Properties) aus netresearch-branding-skill
│ │ │ │ └── main.css Layout + Komponenten
│ │ │ ├── fonts/ WOFF2-Subsets Raleway + Open Sans (Latin + Latin-Ext)
│ │ │ ├── img/ SVG-Icons (24×24), OG-Image-Templates (1200×630)
│ │ │ └── js/
│ │ │ └── enhance.js Copy-to-Clipboard mit locale-aware „Copied/Kopiert"-Flash, Lang-Switcher-Memo
│ │ │
│ │ ├── en/
│ │ │ ├── index.njk EN-Landing
│ │ │ ├── skills/
│ │ │ │ └── {{ slug }}.njk Pagination-driven: 1 Page pro Skill (canonical /en/skills/<slug>/)
│ │ │ ├── about.njk
│ │ │ └── 404.njk
│ │ │
│ │ ├── de/
│ │ │ ├── index.njk DE-Landing (eigenständig getextet, kein Übersetzungs-Echo)
│ │ │ ├── skills/
│ │ │ │ └── {{ slug }}.njk Pagination-driven: 1 Page pro Skill (canonical /de/skills/<slug>/)
│ │ │ ├── about.njk
│ │ │ └── 404.njk
│ │ │
│ │ ├── index.njk Root: serverless Accept-Language-Redirect via <meta http-equiv> + JS-Enhancement; Fallback-Link auf /en/ und /de/
│ │ ├── sitemap.xml.njk Beide Locales, alle Skill-Detail-Pages
│ │ └── robots.txt
│ │
│ └── tests/
│ ├── lighthouse/ lighthouserc.json (Budget + Assertions, Landing + 3 Detail-Pages)
│ ├── a11y/ pa11y-config.json
│ └── parser/ Unit-Tests für parse-readme.js
│
└── .github/
└── workflows/
├── validate.yml UNVERÄNDERT
├── security.yml UNVERÄNDERT
└── pages.yml ← NEU: Fetch READMEs + Eleventy-Build + Lighthouse-CI + Pages-Deploy
Begründung der Trennung: Alles Page-bezogene lebt in site/. Repo-Root bleibt sauber, .claude-plugin/marketplace.json an oberster Stelle, kein Build-Artefakt im Root.
- Semantisches HTML5:
<main>,<article>,<nav>,<section>,<header>,<footer>. - Eine
<h1>pro Page. Heading-Hierarchie ohne Sprünge. - Bilder mit explizitem
width+height(verhindert CLS) undloading="lazy"außer LCP-Bild. - Externe Links:
rel="noopener"wenntarget="_blank".
- CSS Custom Properties in
tokens.css, Layout-Code inmain.css. - Mobile-First, Breakpoints in
em(375 / 640 / 1024 / 1440). - Keine
!important. Keine Inline-Styles außer Critical CSS im<head>. - BEM-light (
block__element--modifier) für Komponenten-Klassen.
Beispiel — Plugin-Card-Markup (Nunjucks → HTML):
{# site/src/_includes/partials/plugin-card.njk #}
<article class="plugin-card plugin-card--{{ plugin.category }}">
<header class="plugin-card__header">
<h3 class="plugin-card__title">
<a href="https://github.com/{{ plugin.source.repo }}"
rel="noopener"
aria-label="View {{ plugin.name }} source repository on GitHub">
{{ plugin.name }}
</a>
</h3>
<span class="plugin-card__category" aria-label="Category">
{{ plugin.category | capitalize }}
</span>
</header>
<p class="plugin-card__description">{{ plugin.description }}</p>
<footer class="plugin-card__footer">
<code class="plugin-card__install">/plugin install {{ plugin.name }}@netresearch-claude-code-marketplace</code>
<button type="button" class="copy-btn"
data-copy="/plugin install {{ plugin.name }}@netresearch-claude-code-marketplace"
aria-label="Copy install command for {{ plugin.name }}">
Copy
</button>
</footer>
</article>- ES2022, keine Build-Steps (kein Bundler — Browser lädt ein einziges Modul).
deferauf<script>im<head>.- Feature-Detection für
navigator.clipboard, sonst Fallback aufprompt(). - Keine externen Bibliotheken.
| Test-Layer | Tool | Was wird geprüft | Wann |
|---|---|---|---|
| HTML-Validität | html-validate |
Alle _site/**/*.html valide |
PR + Push |
| CSS-Linting | stylelint-config-standard |
Konsistenz, keine Errors | PR + Push |
| JavaScript-Linting | eslint (vanilla preset) |
Syntax + Style | PR + Push |
| Marketplace-JSON | Existierendes scripts/validate.sh |
Schema, Categories-Enum, Slug-Regex, Description-Limits, README-Catalog-Row | PR + Push (unverändert) |
| Build smoke test | npm run build |
Generiert _site/ ohne Errors, alle 40 Skill-Cards rendern, 40 EN- + 40 DE-Detail-Pages existieren |
PR + Push |
| README-Parser-Tests | Jest oder Node-Test-Runner | Robust gegen fehlende Sections, korrekte Markdown→JSON-Konversion | PR + Push |
| AGENTS.md Compliance Check (No-Orphan) | site/scripts/check-orphans.js |
Pro Skill: Category ∈ Enum, ≥1 Use case, Related Skills (oder dokumentiertes „none (justified)"), Repo-Link, Install-Pfad, Canonical Landing URL — siehe AGENTS.md §No orphan skills | PR + Push (blocking) |
| AGENTS.md SEO-Copy Check | Eigener Lint-Script | Verbietet Boilerplate-Phrasen („ultimate assistant", „supercharge…"), prüft Tech-Name-Präsenz | PR + Push (warning, manuelle Review) |
| Lighthouse Performance/A11y/SEO | treosh/lighthouse-ci-action@v12 |
Budget aus Objective auf Landing und auf 3 randomly-picked Detail-Pages | PR + Push (blocking) |
| Accessibility deep-scan | @axe-core/cli + Pa11y |
Keine WCAG-2.1-AA-Verletzungen | PR + Push |
| Sitemap-Validität | Eigener Check | Alle EN- + DE-URLs enthalten, jeder <url> hat <xhtml:link rel='alternate' hreflang> für die andere Sprache |
PR + Push |
| hreflang-Konsistenz | Eigener Check | Jede EN-Page verweist auf existierende DE-Counterpart und umgekehrt; x-default gesetzt |
PR + Push |
| OG/Twitter-Tags | Eigener Check-Skript | Pro Page: og:title, og:description, og:image, og:url, og:locale, og:locale:alternate, twitter:card |
PR + Push |
| Broken-Link-Check | lychee GitHub Action |
Keine 404 in internen/externen Links, alle Skill-Repo-Links lösen auf | Nightly Cron + PR |
| Structured-Data-Validität | Eigener Check via Schema.org-Validator | JSON-LD Organization, WebSite, CollectionPage, SoftwareApplication pro Skill, BreadcrumbList korrekt |
PR + Push |
| Visual regression | Optional Phase-2 | — | — |
Coverage-Ziel: Jeder im Objective genannte Erfolgs-Wert + jede AGENTS.md-Pflicht hat einen automatisierten Check.
Die Page erzählt statt zu listen — getrennt für EN und DE, mit eigenständig verfasstem DE-Text (kein maschinelles Echo).
| Section | Story-Beat EN | Story-Beat DE |
|---|---|---|
| Hero | „You ship code. Your agent should know your stack." | „Du lieferst Software. Dein Agent kennt deinen Stack." |
| The problem | „Generic AI doesn't know TYPO3 conventions, PSR-12 quirks, or your DDEV setup." | „Generische AI kennt deine TYPO3-Konventionen nicht, nicht eure PSR-12-Eigenheiten, nicht euer DDEV-Setup." |
| The marketplace | „40 curated skills. One install. Works in Claude Code, Cursor, Copilot, Codex, Gemini CLI, Amp, Goose, OpenCode." | „40 kuratierte Skills. Ein Install. Funktioniert in 8+ Agents." |
| By category | „Pick by what you ship." — Grid über die 7 canonical Categories, jeweils mit Themen-Gruppen-Heading (TYPO3 / OroCommerce / …). | „Wähle nach Lieferobjekt." — gleiche Struktur. |
| The story | „Built by Netresearch — a TYPO3 agency in Leipzig running production for LMS, e-Commerce, enterprise CMS." | „Gebaut von Netresearch — TYPO3-Agentur in Leipzig, die LMS, e-Commerce und Enterprise-CMS produktiv betreibt." |
| How it works | 3 Schritte: Add → Install → Use. Code kopierbar. Plus alternative npx skills add ... für Non-Claude-Agents. |
gleiche Struktur. |
| Open standard | „Agent Skills spec — portable across tools." Link zu agentskills.io. | „Agent-Skills-Spec — portabel zwischen Tools." |
| CTA Footer | „Star the repo. Open an issue. Submit a skill." + Badges. | „Repo starren. Issue eröffnen. Skill einreichen." + Badges. |
| Block | Inhalt (Quelle) |
|---|---|
| Breadcrumb | Home / Skills / <Category> / <Skill> mit BreadcrumbList-JSON-LD. |
| H1: Display Name | aus _data/displayNames.json (kuratierter Map, z. B. typo3-ddev → „TYPO3 DDEV"); unbekannte Slugs fallen auf split-and-capitalize zurück. |
| Problem statement | erster Satz der description aus marketplace.json (AGENTS.md §SEO copy: „first sentence states the concrete problem"). |
| Full description | restliche description + ggf. extrahierter README-Lead. |
| Install block | /plugin install <slug>@netresearch-claude-code-marketplace + alternativ npx skills add .... Copy-Buttons. |
| Category badge | Canonical Category (aus 7-Werte-Enum), als visuelles Label. Keine clientseitige Filter-UI; Discovery erfolgt heute via Themen-Gruppen-Anker auf der Landing. |
| Use cases | Bullets aus Skill-Repo-README ## Use cases-Section. Fallback: aggregiert aus marketplace.json + Themen-Gruppen-Kontext. |
| Expected outputs | aus README ## Expected outputs oder Fallback. |
| Context requirements | aus README ## Context requirements oder Fallback. |
| Related Skills | aus README oder abgeleitet via derive-related.js (Category-Match + Themen-Gruppe). Falls keine echten Verwandten existieren: explizit „No closely related skills in this marketplace yet — see the full catalog." Niemals erfunden. |
| Repository link | aus marketplace.json source.repo. |
| Tags | aus marketplace.json tags (falls existiert) oder abgeleitet. |
| Lang-Switcher | Link auf /<other-lang>/skills/<slug>/ mit hreflang. |
| JSON-LD | SoftwareApplication mit name, description, applicationCategory, url, sameAs (Repo-URL), author (Organization=Netresearch). |
<title>: ≤ 60 Zeichen, Format{{ page.title }} · Netresearch Skills Marketplace.<meta name="description">: ≤ 155 Zeichen, pro Page individuell, pro Sprache eigenständig getextet.<link rel="canonical">auf jeder Page (locale-spezifisch).- Hreflang-Pärchen: jede EN-Page hat
<link rel="alternate" hreflang="en">und<link rel="alternate" hreflang="de">zur DE-Counterpart.<link rel="alternate" hreflang="x-default" href="…/en/…">. Konsistenz via Test. sitemap.xmlmit<xhtml:link rel="alternate" hreflang>pro<url>.robots.txtmit Sitemap-Verweis.<html lang="en">bzw.<html lang="de">dynamisch.- Strukturierte URLs:
/en/,/en/skills/<slug>/,/en/about/, analog/de/. - Trailing-Slash konsistent (alle Pages mit
/).
- Organization auf jeder Page (Netresearch DTT GmbH,
sameAs: Twitter, LinkedIn, GitHub-Org). - WebSite auf den Landing-Pages (ohne
SearchAction, da clientseitige Suche heute nicht existiert — Phase-2-Kandidat). - CollectionPage + ItemList auf Landing mit allen 40 Skills als
SoftwareApplication-Refs. - SoftwareApplication pro Skill auf Detail-Page:
name,description(lokalisierte Variante),applicationCategory(mappt auf Category-Enum),url(canonical Detail-URL),sameAs(Repo-URL),author(Organization=Netresearch),softwareHelp(Repo-README-URL). - BreadcrumbList auf Detail-Pages und About-Page.
- OG-Image: 1200×630, build-time per Sharp generiert aus SVG-Template pro Skill (titel + category badge). Landing nutzt generisches OG-Image mit „40 skills".
- Twitter:
summary_large_image. - og:type:
websitefür Landings,articlefür Detail-Pages,profilefür About. - og:locale:
en_USbzw.de_DE, plusog:locale:alternatezur anderen Sprache.
- 404-Pages haben
<meta name="robots" content="noindex">. - Skill-externe Repos werden nicht in
sitemap.xmlaufgenommen (nur eigene URLs). - Root
/redirected/nutzt<meta http-equiv="refresh">auf/en/als Sicherheitsnetz (Accept-Language ist auf statischem Hosting nicht serverseitig auswertbar; JS-Enhancement schaltet auf DE wenn Browser-Localede*ist).
| Hebel | Umsetzung |
|---|---|
| Critical CSS inlined | ~3 KB für Hero im <head>, Rest via <link rel="preload"> + media="print"-Switch. |
| Fonts | WOFF2-Subsets, font-display: swap, <link rel="preload" as="font" crossorigin> für den initial sichtbaren Cut. |
| Bilder | SVG wo möglich. PNG/JPG mit width/height, loading="lazy" außer LCP. AVIF/WebP optional. |
| JS | defer, optional ganz weglassbar. |
| HTTP | GitHub Pages liefert HTTP/2, gzip + brotli automatisch. |
| Third Party | NULL Third-Party-Skripte (kein Analytics in Phase 1; Plausible Phase 2 wenn gewünscht). |
| Resource Hints | <link rel="preconnect" href="https://github.com"> für CTA-Klicks. |
| Cache | Asset-Pfade mit Content-Hash für 1-Jahr-Cache (z. B. main.abc123.css). |
| No layout shift | aspect-ratio auf allen Media-Wrappers. |
- Alle Plugin-Daten aus
.claude-plugin/marketplace.jsonlesen. Keine duplizierte Pflege. - HTML semantisch + WCAG-AA.
- Build-Output
_site/ignorieren in.gitignore. - Lighthouse-Gate als blocking PR-Check.
- Conventional Commits (
feat(site):,fix(site):,chore(site):). - DCO-Sign-off + signierte Commits (
-S --signoff). - Tracking + Workflow:
- Implementierungs-Arbeit über das Claude Code Task feature tracken — eine Task pro Sub-Phase (2a–2g) mit Komponenten als Description.
- PRs statt Direct-Push auf
main(per User-Memoryfeedback_always_use_prs.md) — pro Sub-Phase ein Branch + PR. - AGENTS.md
ca6a379§Agent workflow checklist (marketplace changes) vor jedem PR-Abschluss durchlaufen: 13-Felder-Check, DACH-DE-Description-Check, No-Orphan-Check, SEO-erster-Satz-Check, Related-Skills-Real-or-Justified-Check, Link-Resolve-Check,./scripts/validate.shlokal. - bd (beads): ist kein Team-Tool mehr (in
ca6a379nicht mehr erwähnt)..beads/-Verzeichnis ist Legacy-State, bleibt unangetastet.
- Custom-Domain einrichten (
skills.netresearch.deo. ä.) — bedeutet DNS-Änderung + CNAME-File. - Analytics einbauen (Plausible, Matomo, GA4) — DSGVO-Implikationen.
- Plugin-Detail-Pages mit READMEs aus Source-Repos pullen — Build-Komplexität ↑.
- Internationalisierung (DE zusätzlich zu EN).
- Newsletter-Signup oder Lead-Form.
- Bilder von Mitarbeitenden (DSGVO + Einwilligung).
- Externe Schriften statt selbst-gehostet.
.claude-plugin/marketplace.jsonaus dem Root verschieben oder umbenennen — würde/plugin marketplace add netresearch/claude-code-marketplacebrechen.- README oder AGENTS.md überschreiben.
- Plugin-Daten manuell in HTML hardcoden (Drift garantiert).
- Tracking-Pixel, Third-Party-Scripts, Google Fonts, Google Analytics, Tag-Manager.
- Cookies oder LocalStorage ohne Notwendigkeit (= ohne Cookie-Banner-Bedarf bleiben).
- AI-Attribution in Commits (per Netresearch-CLAUDE.md).
- Marketplace-Name in Pages-Texten umbenennen — er ist als
netresearch-claude-code-marketplace(kebab-case, slug ausmarketplace.json:name) verankert.
- Install-Befehl exakt:
/plugin marketplace add netresearch/claude-code-marketplace(GitHubowner/repo-Shorthand wie in Anthropic-Doku). - Plugin-Install exakt:
/plugin install <name>@netresearch-claude-code-marketplace(Slug ausmarketplace.json.name, nicht aus Repo-Name). - Reservierte Namen nicht impersoniert: Page macht klar, dass dies eine community/vendor Marketplace ist, kein Anthropic-Official.
- Plugin-Identitäten unverändert: Slugs, Categories, EN-Descriptions, Repo-URLs werden aus JSON gelesen.
- § Marketplace as canonical discovery hub: Pages ist die kanonische Discovery-Surface. Jede Skill bekommt eine stabile, indexable Detail-Page mit canonical URL
/<lang>/skills/<slug>/. - § Required fields per skill entry: Jede Detail-Page füllt alle 13 Pflichtfelder oder markiert „N/A (justified)" in §Known marketplace overrides unten:
- Slug — aus marketplace.json
- Display Name — aus Slug abgeleitet (Title-Case)
- Repository URL — aus marketplace.json
- Install URL — gerendert auf Detail-Page
- EN Description — aus marketplace.json
- DE Description — eigenständig getextet (mit Hilfe von
german-technical-writing-skill) - Category — aus marketplace.json, aus Enum
- Tags — aus README oder abgeleitet
- Use cases — aus README oder Fallback
- Expected outputs — aus README oder Fallback
- Context requirements — aus README oder Fallback
- Related Skills — aus README oder via
derive-related.jsoder „none (justified)" - Canonical landing page URL — generierte URL
/<lang>/skills/<slug>/
- § Canonical categories: ausschließlich
development · devops · security · design · workflow · productivity · document. Page-Code nutzt das Enum, kein freier Text. - § No orphan skills:
site/scripts/check-orphans.jsprüft pre-build, dass jede Skill alle 6 Pflicht-Verbindungen hat. - § SEO and discovery rules: Erster Satz jeder Detail-Page-Description = Problem-Aussage. Verbotsliste Boilerplate-Phrasen wird von Lint-Skript geprüft. Tech-Namen explizit (TYPO3, PHP, OroCommerce, …).
- § Mirroring rule: Skill-spezifische Inhalte werden aus Skill-Repos konsumiert, nicht dupliziert. Detail-Pages linken zum Skill-Repo, kopieren keine prozeduralen READMEs.
- § Known marketplace overrides: intentionale Abweichungen (z. B. fehlende Quell-Daten) werden in einer dedizierten Tabelle dokumentiert (siehe §13).
- Owner-Attribution: „Netresearch DTT GmbH" im Footer + im JSON-LD
Organization-Block, in beiden Sprachen.
| Frage | Antwort | Begründung |
|---|---|---|
| Custom-Domain? | Nein | User-Entscheidung 2026-05-13 |
| Analytics? | Nein (nur GitHub-Repo-Insights) | User-Entscheidung — keine Extra-Tools, kein Tracking |
| Sprache? | DE + EN bilingual (überholt: ursprünglich „EN only" — Decision revidiert 2026-05-13 nach AGENTS.md-Reconciliation, siehe §1.3 und §1.4 Bullet 6) | AGENTS.md §Required fields per skill entry (DE-Description Pflicht für DACH-Skills) |
| Plugin-Detail-Pages? | Phase 1 (überholt: ursprünglich „Phase 2" — Decision revidiert 2026-05-13 nach AGENTS.md-Reconciliation, siehe §1.8) | AGENTS.md §Marketplace as canonical discovery hub („indexable detail pages") |
| Story-Visual? | Reines Typografie-Layout | Default akzeptiert |
| Team-Foto? | Kein Foto, abstraktes SVG-Hero | Default akzeptiert (DSGVO-frei) |
| Badges? | Ja (Scorecard, License, Updated) | User-Entscheidung |
| Internal Marketplace erwähnen? | Nein, rein extern | User-Entscheidung |
Verbleibende offene Punkte: keine. Spec ausgeliefert; Phase-2-Wünsche siehe §14.
Status nach #44/#45/#46-Merge:
-
npm run buildläuft fehlerfrei lokal und in CI. -
_site/enthält: Root-Redirect + 2× Landing (/en/,/de/) + 80× Skill-Detail-Pages + 2× 404 + Sitemap + Robots — insgesamt 85 HTML-Pages. - Alle 40 Skills haben eine canonical Detail-Page
/<lang>/skills/<slug>/(AGENTS.md §Marketplace as canonical discovery hub). - No-Orphan-Check grün: 40/40 Skills bestehen die blocking Rules; ein dokumentierter Override (
orocommerce.relatedSkills = "none (justified)"). - Hreflang-Konsistenz-Check grün: 83 indexierbare Pages, 0 Pair-Gaps, jeder Href löst auf eine gebaute
index.htmlauf. - Categories ausschließlich aus 7-Werte-Enum (
development · devops · security · design · workflow · productivity · document) — vonscripts/validate.sh+check-categories.jsdoppelt enforced. - Descriptions: alle ≤ 500 Zeichen (hard cap), 15 advisory Warnings für > 300 Zeichen (Phase-2-Aufräumarbeit).
- SEO-Copy-Lint advisory: 25/40 Skills clean; verbleibende 15 sind die zu langen Descriptions.
- Lighthouse-CI Phase-1-Gate: Performance / A11y / Best-Practices / SEO ≥ 0.9 auf Landings + 3 random Detail-Pages, beide Locales. (Phase-2-Target ≥ 0.95 / 1.0 a11y dokumentiert in §14.)
-
gh api repos/netresearch/claude-code-marketplace/pageslieferthttps://netresearch.github.io/claude-code-marketplace/,build_type: workflow. -
curl .../marketplace.jsonweiterhin valide JSON —scripts/validate.shläuft unverändert grün. - DCO + Signierte Commits + SonarCloud + Dependency-Review + gitleaks + betterleaks alle grün auf jedem PR.
- JSON-LD-Validität:
Organization,WebSite,CollectionPage + ItemList,SoftwareApplication(inkl.inLanguage),BreadcrumbList— Schema.org-Validator clean. - Manuelle Smoke-Tests:
- Hero-CTA kopiert
/plugin marketplace add netresearch/claude-code-marketplace; flasht „Copied" (EN) bzw. „Kopiert" (DE). - Pro Skill-Detail-Page: Plugin-Install-Befehl
/plugin install <slug>@netresearch-claude-code-marketplace1-Klick-kopierbar. - Lang-Switcher zwischen
/en/skills/<slug>/↔/de/skills/<slug>/funktioniert. - Markdown-Inhalte aus Skill-Repo-READMEs (Bold, Links, Code-Spans) rendern korrekt — keine literalen
**oder rohen[text](url)mehr. - Display-Namen mit Acronymen (
TYPO3 DDEV,TYPO3 CKEditor 5,OroCommerce,GitHub Project). - Page rendert ohne JS (Progressive Enhancement); Reduced-Motion-Preference respektiert.
- Hero-CTA kopiert
- Existierende Marketplace-CI (
scripts/validate.sh) unverändert und grün (40 Plugins valid). - Existierende Security-Workflows (
security.yml) unverändert und grün. - README hat „Discover"-Section mit Link auf die Live-Page.
- Implementierungs-Arbeit über 7 Sub-Phase-Tasks (2a–2g) + 3 Post-Ship-Fix-Tasks getrackt; alle completed.
- PR-Hygiene: 22 Review-Comments auf #44, 5 auf #45 (Nunjucks
~), 7 auf #46 (Code-Span-Protection, URL-Allowlist, displayName-Dedup) — alle resolved.
Diese Tabelle dokumentiert intentionale Abweichungen vom „one canonical source per fact"-Prinzip. Sie wird sowohl in der SPEC als auch in AGENTS.md gepflegt (bei Bedarf — initial leer bei Phase-1-Start):
| Slug | Field | Marketplace value (Page) | Reason | Decided |
|---|---|---|---|---|
| (empty at Phase 1 start; populated when build encounters missing source data) |
Pflicht-Workflow bei Override-Erstellung: Wenn build-time-Fetch eine README-Section nicht findet und kein automatisches Fallback greift, generiert site/scripts/parse-readme.js einen Override-Eintrag mit Reason „README section absent on YYYY-MM-DD" und committet ihn als Artifact für Review.
Phase-2-Auslieferung (siehe PR #48):
- ✅ Clientseitige Volltext-Suche — pre-built JSON-Index pro Locale (
/<lang>/search-index.json), ~40 KB, vanilla JS~3 KBmehr, in-place Card-Filtering mitaria-live-Status, debounced auf 80 ms.WebSite + SearchAction-JSON-LD auf beiden Landings. - ✅ Visual-Regression via Playwright (chromium-desktop, 1280×800), 5 Snapshots (Landings EN/DE + 3 Detail-Pages), maxDiffPixelRatio 0.005, im CI-Workflow als blocking job zwischen
buildunddeploy. - ✅ Skill-Versionen — Latest-Release-Tag pro Skill-Repo wird zur Build-Zeit via Octokit (
getLatestRelease) gefetcht und als verlinktes Badge auf der Detail-Page gerendert. Repos ohne Releases werden silently geskippt. - ✅ Lighthouse Phase-2-Targets scharf geschaltet: Performance/Best-Practices ≥ 0.95, A11y = 1.0, SEO = 1.0. Brand-Turquoise auf
--color-primary-dark(5.3:1) für sämtliche Text/Button-Vorder- und -Hintergründe migriert. - ✅ 15 überlange Descriptions in
marketplace.jsonauf ≤300 Zeichen gekürzt (SEO-Snippet-Friendly), Linter zeigt jetzt 0 Warnings.
Verbleibender Phase-2-Kandidat (eigene Initiative, nicht Pages):
SKILL.md-Frontmatter als Discovery-Quelle (useCases:,relatedSkills:,expectedOutputs:,contextRequirements:als optionale Felder). Ersetzt das README-Parsing, mirroring-konform, kein separates Artefakt nötig. Voraussetzung: AGENTS.md / skill-repo-skill aktualisieren, dass diese Felder erlaubt + erwartet sind. Multi-Repo-PR-Kampagne über alle 40 Skill-Repos.
Bewusst nicht vorgesehen (für die Discussion-Schließung dokumentiert): Login/Skill-Submission-Form, Newsletter, RSS-Feed, dynamische API-Endpoints, serverseitige Logik. Das ist ein statischer Discovery-Hub — wer einen Skill einreichen will, öffnet eine PR gegen marketplace.json. Weitere Sprachen jenseits DE+EN sind heute kein Bedarf.
Plan-/Phase-Status: ausgeliefert — siehe Header. PLAN.md hält die technische Implementierungs-Sequenz fest. Tracking lief über Claude Code Task feature (TaskCreate/TaskUpdate).