Skip to content

Latest commit

 

History

History
280 lines (199 loc) · 16.8 KB

File metadata and controls

280 lines (199 loc) · 16.8 KB

ARCHITECTURE.md

Bird's-eye view of the Claude Code Plugins Marketplace repository. Last updated: 2026-05-21

Overview

This repository is a curated, multi-runtime plugin marketplace maintained by Passion Factory. It aggregates plugins from multiple sources — external git submodules, vendor-synced skill repositories, auto-converted Gemini CLI extensions, and hand-crafted built-in plugins — into a single installable marketplace that targets three AI coding runtimes:

Runtime Primary install command
Claude Code /plugin marketplace add pleaseai/claude-code-plugins then /plugin install <name>@pleaseai
Codex CLI Codex marketplace auto-generated at .agents/plugins/marketplace.json
Google Antigravity File-based install — copy plugins/<name>/ into Antigravity's plugins location

The Claude Code plugin manifest (.claude-plugin/plugin.json) is the source of truth. Codex and Antigravity manifests are auto-generated from it via scripts/multi-format.ts. Shared assets (skills/, commands/, hooks/) live once per plugin and are referenced by every runtime — only the manifest layer differs.

The codebase is structured as a Turborepo monorepo using Bun workspaces. It contains a Nuxt 4 web frontend for browsing plugins, shared configuration packages, and a CLI-driven pipeline (scripts/cli.ts) that manages the lifecycle of syncing, generating, and validating plugin artifacts.

Entry Points

File / Path Purpose
.claude-plugin/marketplace.json Start here. The Claude Code marketplace manifest — defines all installable plugins, their metadata, and source locations
.agents/plugins/marketplace.json Codex marketplace — auto-generated from the Claude marketplace, scoped to locally maintained plugins
scripts/cli.ts Plugin management CLI: init (add submodules), sync (generate artifacts), check (upstream updates), cleanup (remove stale), multi-format (Codex + Antigravity manifests)
scripts/meta.ts Source registry — declares all plugin sources (Types 1-4) and their mappings
scripts/multi-format.ts Codex + Antigravity manifest generator — converts the Claude manifest into per-runtime artifacts
apps/web/nuxt.config.ts Web marketplace application entry point (Nuxt 4)
turbo.json Turborepo task pipeline configuration
package.json Root workspace definition — workspaces: packages/*, apps/*, plugins/*

Module Structure

claude-code-plugins/
├── .claude-plugin/          # Claude Code marketplace manifest
├── .agents/                 # Codex marketplace + plugin staging (auto-generated)
├── apps/
│   └── web/                 # Nuxt 4 marketplace frontend
├── docs/                    # Development standards & guides
├── external-plugins/        # Type 4: Git submodules (read-only sources)
├── hooks/                   # Repository-level Claude Code hooks
├── packages/                # Shared configuration packages
├── plugins/                 # All installable plugin artifacts (multi-runtime)
├── scripts/                 # Build tooling & sync pipeline
├── sources/                 # Type 1: Documentation submodules for skill generation
└── vendor/                  # Type 2/3: Vendor skill submodules

.claude-plugin/

Contains marketplace.json — the single source of truth for which plugins are available in the Claude Code marketplace. Each entry specifies the plugin's name, description, category, keywords, and source location. This file is hand-authored; the Codex marketplace at .agents/plugins/marketplace.json is derived from it.

.agents/

Codex CLI workspace directory. Contains:

  • plugins/marketplace.json — Codex marketplace, auto-generated from .claude-plugin/marketplace.json (local plugins only)
  • plugins/<name>/ (only for Codex-only staging when needed)
  • skills/ — skills.sh-managed installations (tracked by root skills-lock.json)

The marketplace file here is regenerated by bun scripts/cli.ts multi-format. Do not hand-edit.

apps/web/

Nuxt 4 (Vue 3) web application for browsing the marketplace. Uses Nuxt UI v4 for components, Nuxt Content for markdown pages, and better-sqlite3 for local data. Deployed as a static site via bun run generate.

docs/

Development standards and reference documentation for human contributors. Not user-facing — these guide contributors:

  • commit-convention.md — Conventional commit rules
  • STANDARDS.md — Engineering quality standards
  • TDD.md, TESTING.md — Testing methodology
  • plugins.md — Plugin development guide
  • skills-generator.md — Skill generation workflow
  • adr/ — Architecture Decision Records
  • lessons-learned/ — Post-implementation notes

docs/ vs .please/docs/: docs/ contains standards and guides written for human contributors. .please/docs/ is the AI agent knowledge base — product context, decisions, and workflows maintained for Claude Code's please-setup plugin. They serve different audiences and are not interchangeable.

external-plugins/

Read-only git submodules containing Type 4 plugins: external projects that are either Gemini CLI extensions or standalone Claude Code plugins. These are the canonical upstream sources. The sync pipeline reads from here and generates artifacts into plugins/.

Current external plugins: chrome-devtools-mcp, code-review, firebase, flutter, google-workspace, grafana, nanobanana, open-aware, playwright-cli, postgres, security, spec-kit.

hooks/

Repository-level Claude Code hooks. hooks.json defines a SessionStart hook that loads context via context.sh. These hooks apply to the marketplace repository itself, not to individual plugins.

packages/

Shared configuration packages published under the @pleaseai scope:

Package Purpose
eslint-config Shared ESLint configuration (extends @antfu/eslint-config)
typescript-config Shared tsconfig.json base
vitest-config Shared Vitest configuration

plugins/

The output directory. Contains all installable plugin artifacts, whether manually maintained or auto-generated. Each plugin ships manifests for all three runtimes so the same directory can be installed into Claude Code, Codex, or Antigravity:

plugins/<name>/
├── .claude-plugin/
│   └── plugin.json       # Claude Code manifest (source of truth — hand-authored)
├── .codex-plugin/
│   └── plugin.json       # Codex manifest (auto-generated)
├── plugin.json           # Antigravity marker file (auto-generated, root-level)
├── .mcp.json             # Codex MCP config (auto-generated, only when inline mcpServers)
├── mcp_config.json       # Antigravity MCP config (auto-generated, only when inline mcpServers)
├── hooks.json            # Antigravity hooks mirror (auto-generated from hooks/hooks.json)
├── hooks/                # Plugin-specific hooks (shared across runtimes)
│   └── hooks.json        # Claude Code auto-loads this; Antigravity mirror lives at root
├── skills/               # Skill definitions (SKILL.md — universal format)
├── commands/             # Slash commands (markdown — Claude Code + Codex)
└── SYNC.md               # Present if auto-generated by skills:sync (do not edit)

Only .claude-plugin/plugin.json and the shared asset directories are hand-authored. Everything else is regenerated by bun scripts/cli.ts multi-format. See scripts/multi-format.ts for the field-by-field conversion rules.

Plugin categories by origin:

  • Manually maintained: gatekeeper, plugin-dev — hand-crafted, fully controlled
  • Type 1 (Generated): vue, nuxt, vitest, vite, etc. — skills generated from official documentation submodules via /generate-skill
  • Type 2 (Vendor-synced): slidev, vueuse, prisma, better-auth, etc. — skills synced from upstream vendor skill repositories
  • Type 3 (Manual copy): antfu — hand-written skills copied from vendor/antfu-skills/
  • Type 4 (Extension-synced): google-workspace — auto-converted from Gemini CLI extensions in external-plugins/

Files with a SYNC.md marker are auto-generated and will be overwritten on the next bun run skills:sync. Do not edit them manually.

scripts/

Build tooling for the plugin pipeline:

File Purpose
cli.ts Main CLI — init, sync, check, cleanup, multi-format commands
meta.ts Source registry — Type 1 submodules, Type 2 vendors, Type 4 extensions
extension-helpers.ts Gemini CLI extension conversion utilities (TOML parsing, MCP path conversion)
multi-format.ts Codex + Antigravity manifest generator — converts the Claude manifest, splits inline mcpServers into companion files, mirrors hooks for Antigravity
generate-antfu-plugins.ts Generate plugin manifests for antfu-style plugins
*.test.ts Unit tests for the scripts

sources/

Git submodules of official documentation repositories (Type 1). Used as raw input for the /generate-skill command, which reads the docs and produces skill files in plugins/. Contains repos like vuejs/docs, nuxt/nuxt, vitejs/vite, vitest-dev/vitest.

vendor/

Git submodules of vendor skill repositories (Types 2 and 3). These are projects that maintain their own skills/ directory. The sync pipeline copies skills from vendor repos into the corresponding plugins/<name>/skills/ directory.

Plugin Type System

The marketplace distinguishes four plugin source types, managed through scripts/meta.ts:

Type Source Artifact Location Sync Method
Type 1 sources/<name>/ (docs repos) plugins/<name>/skills/ /generate-skill (manual)
Type 2 vendor/<name>/ (skill repos) plugins/<name>/skills/ bun run skills:sync (auto)
Type 3 vendor/antfu-skills/ plugins/antfu/skills/ bun run skills:sync (copy)
Type 4 external-plugins/<name>/ plugins/<name>/ bun run skills:sync (convert)

Data flow for Type 4 (extension sync):

external-plugins/<name>/           →  plugins/<name>/
  gemini-extension.json            →  .claude-plugin/plugin.json
  commands/*.toml                  →  commands/*.md
  <contextFileName>                →  hooks/ + context file

Multi-Runtime Manifest System

Plugins target three runtimes from a single source directory. The Claude Code manifest is hand-authored; the rest is generated.

Runtime Manifest path MCP companion file Hooks file Marketplace
Claude Code (source of truth) .claude-plugin/plugin.json inline mcpServers hooks/hooks.json (auto-loaded) .claude-plugin/marketplace.json
Codex CLI .codex-plugin/plugin.json .mcp.json (uses hooks/ directory) .agents/plugins/marketplace.json
Antigravity plugin.json (root) mcp_config.json hooks.json (root) (file-based — no marketplace registry)

Conversion rules (implemented in scripts/multi-format.ts):

  • Claude → Codex

    • Inline mcpServers extracted to .mcp.json; manifest field becomes "./.mcp.json"
    • hooks manifest field is dropped (Codex validation rejects it; the hooks/ directory still functions)
    • Codex-specific interface block (displayName, capabilities, defaultPrompt, category) synthesised from the marketplace entry
    • Version coerced to strict semver (MAJOR.MINOR.PATCH); falls back to 1.0.0 for date-stamp versions
    • Author email stripped to avoid leaking contributor addresses into downstream artifacts
  • Claude → Antigravity

    • Flat root manifest; only name is required, other fields preserved when present
    • Inline mcpServers extracted to mcp_config.json
    • hooks/hooks.json content mirrored to root hooks.json
    • skills/ reused as-is (same SKILL.md schema)

Generation:

bun scripts/cli.ts multi-format
# or:
bun run plugins:multi-format

Writes are idempotent — writeIfChanged() skips files whose content already matches, so re-running produces no diff when nothing has changed. The Codex marketplace at .agents/plugins/marketplace.json is also regenerated, filtered to local plugins (source: "./plugins/...").

Collision handling: a few plugins (bun, plugin-dev) historically use a root-level plugin.json as their Claude Code manifest. The generator detects this and skips writing an Antigravity manifest there — both runtimes can read the same file.

Architecture Invariants

These rules must be maintained. Violating them will break the sync pipeline or marketplace integrity.

  1. Never edit auto-generated files. Any file in plugins/ that has a SYNC.md marker is managed by the sync pipeline. The same rule applies to .codex-plugin/plugin.json, root plugin.json, .mcp.json, mcp_config.json, root hooks.json, and .agents/plugins/marketplace.json — all are produced by multi-format. Manual edits will be overwritten. To modify, change the Claude Code source manifest and re-run.

  2. external-plugins/ is read-only. These are git submodules pointing to upstream repos. Changes must be made in the upstream repository and pulled via git submodule update.

  3. Every installable plugin must be in marketplace.json. The Claude marketplace manifest is the single source of truth for what users can install. A plugin existing in plugins/ but absent from marketplace.json is not installable, and will also not appear in the auto-generated Codex marketplace.

  4. Plugin manifests live at .claude-plugin/plugin.json. This exact path is required by Claude Code and is the source of truth for Codex/Antigravity generation. The handful of plugins using root-level plugin.json (e.g. bun, plugin-dev) are a legacy exception — new plugins should use .claude-plugin/plugin.json.

4a. The Claude manifest is the source of truth. Codex and Antigravity manifests must never be authored independently. If a runtime needs a field that the Claude manifest doesn't carry, extend the marketplace entry or the converter in scripts/multi-format.ts instead of hand-editing the generated output.

  1. hooks/hooks.json is auto-loaded. Claude Code automatically discovers hooks/hooks.json in each plugin. Do NOT reference it in plugin.json's hooks field — that field is for additional hook files only.

  2. Skills over SessionStart hooks. New plugins should use skills (skills/<name>/SKILL.md) for context injection rather than SessionStart hooks. Skills are loaded on-demand, saving tokens.

  3. Workspace packages use @pleaseai scope. Shared packages in packages/ are scoped as @pleaseai/<name> and referenced with workspace:* protocol.

  4. Conventional commits enforced. All commits must follow conventional commit format. Husky pre-commit hooks and commitlint validate this automatically.

  5. Node 22.x required. The .nvmrc specifies Node 22. The web app and build tooling depend on Node 22 features.

Cross-Cutting Concerns

Testing

  • Framework: Vitest 4.x with shared configuration from @pleaseai/vitest-config
  • Scope: packages/ and apps/ have separate Vitest project configurations
  • Scripts tests: scripts/*.test.ts run in Node environment
  • Integration tests: Separated from unit tests, run via bun run test:integration
  • Coverage: V8 provider, reports in text/JSON/HTML/lcov formats

Build & CI

  • Turborepo orchestrates all tasks: build, test, lint, e2e
  • Release Please manages versioning across all packages and plugins via release-please-config.json
  • Plugin versions are bumped in both package.json and .claude-plugin/plugin.json (via extra-files config)

Linting & Formatting

  • ESLint with @antfu/eslint-config — shared via @pleaseai/eslint-config
  • Prettier for formatting
  • ESLint cache enabled for performance (turbo.json outputs .eslintcache)

Plugin Validation

claude plugin validate <path-to-plugin-dir>
claude plugin validate .claude-plugin/marketplace.json

Always validate after creating or modifying plugins.

Development Commands

bun install                    # Install all dependencies
bun run dev                    # Start web app dev server
bun run test                   # Run all unit tests via Turborepo
bun run lint                   # Lint all workspaces
bun run build                  # Build all workspaces
bun run skills:init            # Add submodules from meta.ts
bun run skills:sync            # Sync vendor skills + convert extensions
bun run skills:check           # Check for upstream updates
bun run skills:cleanup         # Remove stale submodules and skills
bun run plugins:multi-format   # Generate Codex + Antigravity manifests from Claude source