Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


name: authoring-marketplaces description: Use when creating a new veyyon marketplace. Covers marketplace.json schema, source types, install commands, and publishing.

Authoring Marketplaces

A marketplace is a Git repository (or local directory) that contains a catalog file at either .veyyon-plugin/marketplace.json (preferred for veyyon-specific catalogs) or .claude-plugin/marketplace.json (Claude Code-compatible; used as the fallback). Anyone can author one. Users add it with veyyon plugin marketplace add owner/repo and then install individual plugins from it.

Minimum viable marketplace

my-marketplace/
  .claude-plugin/
    marketplace.json
  plugins/
    my-plugin/
      skills/
        my-skill/
          SKILL.md
{
  "name": "my-marketplace",
  "owner": { "name": "Your Name" },
  "plugins": [
    {
      "name": "my-plugin",
      "description": "What it does",
      "source": "./plugins/my-plugin"
    }
  ]
}

Push to GitHub. Users install with:

veyyon plugin marketplace add your-github-username/my-marketplace
veyyon plugin install my-plugin@my-marketplace

marketplace.json schema

The catalog file lives at either .veyyon-plugin/marketplace.json or .claude-plugin/marketplace.json in the repository root. veyyon prefers the .veyyon-plugin/ path and falls back to the Claude path; a repository may publish both to expose tool-specific catalogs from a single source tree.

Top-level fields

FieldRequiredDescription
nameyesMarketplace name. Lowercase alphanumeric, hyphens, dots. Must start and end with alphanumeric. Max 64 chars.
owneryesObject with at minimum owner.name (string)
owner.nameyesMarketplace owner name
owner.emailnoOwner contact email
pluginsyesArray of plugin entries (see below)
metadata.descriptionnoShort description of the marketplace
metadata.versionnoCatalog metadata version string
metadata.pluginRootnoString prepended to all relative plugin source paths
extra top-level fieldsnoPreserved by the parser but not used by marketplace install/runtime logic

Plugin entry fields

FieldRequiredDescription
nameyesPlugin name (same naming rules as marketplace name)
sourceyesWhere to find the plugin, string or object (see source types below)
descriptionnoShort plugin description
versionnoVersion string
authorno{ name, email? }
homepagenoURL
categorynoe.g. development, productivity, security
tags / keywordsnoArrays of string tags/keywords
repositorynoRepository URL
licensenoLicense string
strictnoBoolean plugin metadata flag
commands, agents, hooks, mcpServers, lspServersnoCapability metadata used by plugin tooling and selectors

Full catalog example

{
  "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
  "name": "acme-plugins",
  "owner": {
    "name": "Acme Corp",
    "email": "[email protected]"
  },
  "metadata": {
    "description": "Official Acme plugins for Veyyon"
  },
  "plugins": [
    {
      "name": "acme-linter",
      "description": "Enforce Acme coding standards",
      "category": "development",
      "source": "./plugins/linter"
    },
    {
      "name": "acme-deploy",
      "description": "One-command deploy to Acme cloud",
      "category": "devops",
      "source": {
        "source": "github",
        "repo": "acme-corp/veyyon-deploy-plugin",
        "ref": "main"
      }
    }
  ]
}

Plugin source types

1. Relative path string

Points to a subdirectory inside the marketplace repository itself. Must start with ./.

"source": "./plugins/my-plugin"

The path is resolved relative to the marketplace repository root. Path traversal outside the repo root is rejected.

Use metadata.pluginRoot to avoid repeating a common prefix:

{
  "metadata": { "pluginRoot": "./plugins" },
  "plugins": [
    { "name": "plugin-a", "source": "./plugin-a" },
    { "name": "plugin-b", "source": "./plugin-b" }
  ]
}

2. Git URL

A full Git repository URL. Optionally pin to a branch/tag (ref) or exact commit (sha):

"source": {
  "source": "url",
  "url": "https://github.com/org/my-plugin.git",
  "ref": "main",
  "sha": "a1b2c3d4..."
}

3. GitHub shorthand

Shorthand for GitHub repositories. Functionally equivalent to a Git URL but more concise:

"source": {
  "source": "github",
  "repo": "org/my-plugin",
  "ref": "v2.1.0",
  "sha": "a1b2c3d4..."
}

4. Git subdirectory (monorepo)

For plugins living inside a subdirectory of a larger repository. url accepts a full HTTPS URL or a GitHub owner/repo shorthand:

"source": {
  "source": "git-subdir",
  "url": "https://github.com/org/monorepo.git",
  "path": "packages/my-plugin",
  "ref": "main",
  "sha": "a1b2c3d4..."
}

The path must resolve inside the cloned repository, directory escape is rejected.

5. NPM package

Declares the plugin as an npm package. version is optional:

"source": {
  "source": "npm",
  "package": "@acme/veyyon-plugin",
  "version": "1.2.0"
}

Note: npm plugin sources are declared in the schema but installation support is not yet fully implemented. Use Git-based sources for plugins that need to work today.

Plugin structure

A plugin directory (regardless of source type) ships its content in conventional locations, all optional:

my-plugin/
  skills/<name>/SKILL.md   ← skills
  commands/*.md            ← slash commands
  agents/*.md              ← subagent definitions
  hooks/pre/, hooks/post/  ← hooks
  tools/                   ← custom tools
  .mcp.json                ← MCP server definitions
  package.json             ← optional; its version is a fallback when the catalog entry has no version
  README.md                ← recommended: description + usage

Note: extension modules declared via package.json veyyon.extensions (legacy omp/pi) load from marketplace installs exactly as they do from npm-installed or veyyon plugin linked plugins: the install symlinks the cached plugin into the runtime node_modules tree that the extension loader enumerates.

Install command

veyyon plugin install name@marketplace-name
veyyon plugin install --force name@marketplace-name     # reinstall
veyyon plugin install --scope project name@marketplace  # project-scoped

Add the marketplace first:

veyyon plugin marketplace add owner/repo
veyyon plugin install name@marketplace-name

Scope behavior:

  • user (default): installed in ~/.veyyon/profiles/default/plugins/installed_plugins.json, available in all projects
  • project: installed in <project>/.veyyon/plugins/installed_plugins.json, available only in that project

Project-scoped installs shadow user-scoped installs of the same plugin name.

Naming rules

Marketplace names and plugin names must:

  • Contain only lowercase letters, digits, hyphens (-), and dots (.)
  • Start and end with a lowercase letter or digit
  • Be at most 64 characters

Plugin IDs (name@marketplace) must be at most 128 characters total.

Valid: my-plugin, code-review, acme.tools, ai-v2 Invalid: -bad-start, bad-end-, .dot-start, Under_score, HAS_CAPS

Publishing workflow

  1. Create marketplace.json at .veyyon-plugin/marketplace.json (veyyon-only) or .claude-plugin/marketplace.json (shared with Claude Code) in a new Git repo.
  2. Add plugin entries pointing to subdirectories (or external sources).
  3. Push to GitHub.
  4. Share the owner/repo string. Users add it with veyyon plugin marketplace add owner/repo.
  5. When you update the catalog, users run veyyon plugin marketplace update your-marketplace-name to pull the latest.

To test locally before publishing:

veyyon plugin marketplace add ./path/to/my-marketplace

Local path sources also accept ~/ and absolute paths.

Further reading

  • docs/handbook/src/features/marketplace.md: marketplace system internals, on-disk layout, command reference
  • docs/handbook/src/features/extensions-authoring.md: how to author the extension modules inside plugins
  • packages/coding-agent/examples/mini-marketplace/: minimal working marketplace example