Skip to content

Plugin Marketplaces

A plugin marketplace is a plugin directory file used to distribute and manage CodeBuddy extensions. It is a JSON-formatted configuration file that lists available plugins and their source information.

Core Features

  • Centralized Discovery: Browse plugins from multiple sources in one place
  • Version Management: Automatically track and update plugin versions
  • Auto-Update: Support enabling auto-update to periodically sync marketplace content
  • Team Distribution: Share required plugins within organizations
  • Flexible Sources: Support for Git repositories, GitHub repositories, local paths, and HTTP URLs

Runtime Projection and Management Ownership

Agent CLI's initial plugin projection is cache-first: the process reads only enabledPlugins from each settings scope, the installed_plugins.json registry, and the immutable plugin cache referenced by that registry. The initial projection does not scan marketplaces, access remote sources, or repair or migrate on-disk state. The dependency closure of enabled plugins is also resolved only from the same registry and cache.

An Agent CLI runtime with management permissions starts one background reconcile after the initial projection is committed. It synchronizes marketplaces, installs missing plugins, migrates legacy caches, applies policies, and cleans up orphaned state. After committing, it submits the active plugin snapshot through the same serialized transaction queue so that management and projection passes do not overlap. Within the transaction, MCP/LSP and Product projections are prepared in parallel; after the Product projection is committed, Command, Output Style, and Agent are rebuilt in parallel. If the active snapshot produced by the background reconcile is unchanged, downstream components are not reprojected; when it changes, only affected components are refreshed. After the initial projection assumes management ownership, a change to the persisted enabledPlugins or extraKnownMarketplaces content immediately queues a full configured reconcile in the same long-running runtime. Direct edits to settings files from outside the process are also handled by ConfigWatchService, which invalidates the cache and emits the same settings change. Repeated changes are coalesced through generation + single-flight, so cache materialization does not need to wait until the next task is created.

install and enable have different semantics. An explicit plugin install synchronously resolves dependencies, writes to the versioned cache/<marketplace>/<plugin>/<version>, commits installed_plugins.json, and writes the enabled state by standard default. plugin enable only declares desired state: even if the plugin can already be discovered from a Marketplace but has not yet been installed, the enable operation does not write the cache or registry. After a short-lived plugin enable command exits, the next regular Agent startup performs the reconcile; in a long-running Host, the settings-change reconcile described above immediately takes over materialization. This matches Claude Code's install/enable/startup boundary.

plugin update likewise follows the immutable semantics of the versioned cache. If the version declared by the Marketplace matches the currently installed version, it is treated as up to date without rewriting the cache, registry, or dependency state. When the declared version changes, a new version directory is written and the registry is switched atomically, while existing Sessions continue to reference the old directory. Only an unknown cache for which neither a declared version nor a Git SHA can actually be obtained may attempt an in-place refresh. If other Session markers still exist, the old contents and their payload metadata are retained and the refresh is deferred to a later update/reconcile; a safe deferral is not returned as HTTP 500. This matches Claude Code's update/cache boundary.

Long-running hosts can also call POST /api/v1/plugins/reconcile to idempotently materialize the complete configured state declared by Product/settings and rebuild the runtime projection afterward. This endpoint does not accept a host name, marketplace name, or local path, so it does not create a WorkBuddy-specific management branch. Concurrent requests share the same underlying pass. HTTP waiters have a fixed upper bound; a timeout or client disconnect ends only the current wait and does not cancel the underlying materialization, which remains protected by a cross-process lock. Later requests can still join or retry. Marketplace/cache state that was atomically committed before a strict aggregate failure is projected first as a partial/last-good state. When the same route receives a body containing requiredPluginIds, its semantics are the opposite: it only projects and strictly validates the already committed roots and dependency closure; it does not install plugins, update Marketplaces, or write cache/registry/settings. If a startup/settings producer is already running, validation may join that existing flight once and then recheck. Validation itself never creates a new management write merely because a task is starting.

Regular TUI, --print, headless, stream-json, ACP, and serve invocations share the same initial boundary: at startup they build the complete runtime projection from the committed registry/cache and wait for that projection to complete before the first actual Agent dispatch. They do not insert a foreground Marketplace download based on the protocol mode or defer downstream projection until a Session control request. A missing cache or load failure for one plugin only leaves that plugin absent and records a plugin error; other plugins and the Agent continue to run. The background reconcile restores the missing plugin and reprojects after committing it. Hosts such as WorkBuddy that declare explicit required roots for the current Session should prepare the cache during configuration/install/startup and perform only read-only validation before starting the worker. After the process starts, it consumes that committed state directly instead of repeating reconcile before session/new|load|resume. With explicit --no-plugin-management, Agent CLI builds the complete projection only from the existing registry/cache and performs no management writes.

A Directory Marketplace follows standard installation semantics: the marketplace registration record retains the source directory, but installed plugins still go through standard dependency resolution, are materialized into cache/<marketplace>/<plugin>/<version>, and are then committed to installed_plugins.json. At runtime, plugins are loaded only from that versioned snapshot; the mutable marketplace source is not treated directly as an installed plugin. Directory and remote marketplaces declared by Product reuse this flow, and processes with management permissions idempotently restore missing cache/registry state.

--no-plugin-management is a generic explicit read-only switch intended only for special runtimes where the host can already guarantee a complete registry/cache closure. In this mode, marketplace and plugin installation, update, removal, enablement, disablement, and repair APIs are rejected before any I/O. Regular CLI and Session runtimes retain standard management capabilities by default; Agent CLI does not switch to this mode automatically based on host branding or topology.

Marketplace write operations acquire cross-process locks by source → stable storage name. An add operation holds the source lock before any clone, download, or swap and checks again for duplicates by normalized source while holding the lock, closing the TOCTOU window between concurrent check and install operations. A remote add first writes to a separate staging directory and cleans up the old directory only after the registry commit succeeds. Concurrent updates in the same process share one remote synchronization, while cross-process update and remove operations follow the same lock order. Removing a marketplace cleans up all of its registry/settings records in user, project, and local scopes, along with orphaned caches, plugin configuration, and MCP OAuth credentials. Product-managed built-in marketplaces cannot be removed or replaced through ordinary operations.

Remote marketplaces also have a single lifecycle owned by Agent CLI: Product declares only source, url, and optional versionUrl and autoUpdate values. ZIP sources check freshness in the order versionUrl → ZIP URL version → ETag/Last-Modified; routine automatic updates do not clear this check metadata or force a download. ZIP freshness applies only when marketplace.json and every local plugin directory declared in it are complete. Any missing directory bypasses the version/ETag short-circuit and downloads a complete snapshot again. Both ZIP and URL sources finish downloading and fully validating their manifests in a separate directory before atomically replacing the live source. If any plugin manifest in a URL source fails validation, the entire refresh fails and no partial directory is published. Git sources likewise perform a shallow clone and full manifest validation next to the live checkout, then use backup + rename to promote it atomically only after a new commit is ready. The same commit is a no-op, and clone, authentication, network, or manifest failures preserve the old checkout. If any remote registry record points to a missing or incomplete local source snapshot, the background reconcile treats it as requiring rematerialization rather than considering it installed merely because the source metadata matches. If a declarative Directory source is temporarily unavailable, its registration record and existing plugin cache are conservatively retained instead of overwriting the last-good state with an empty directory. A failed refresh does not commit a new marketplace record or rewrite the installed registry/cache; the existing version continues to run as last-good. Installed plugins from a marketplace are rematerialized only when its source content actually changes. Declarative source replacement and recovery from interrupted state reuse the same materialization path instead of changing only marketplace metadata and leaving an old plugin cache behind. force is only for explicit user recovery or diagnostics, not an alternative host updater.

Stable marketplace names declared by Product take precedence over historical URL-derived aliases for the same source: the standard registration transaction retires an old alias after committing the new record. Agent CLI does not recognize WorkBuddy, Desktop, or any other platform brand; hosts should not maintain an additional version file, timer, or forced-refresh RPC.

Using Plugin Marketplaces

Prerequisites

  • CodeBuddy installed and running
  • Basic understanding of JSON file format
  • For creating a marketplace: Git repository or local development environment

Adding a Plugin Marketplace

1. Add a GitHub Marketplace

bash
/plugin marketplace add owner/repo

The repository must contain a .codebuddy-plugin/marketplace.json file.

2. Add a Git Repository Marketplace

bash
# HTTPS format
/plugin marketplace add https://gitlab.com/company/plugins.git

# SSH format (git@)
/plugin marketplace add git@gitlab.com:company/plugins.git

# .git suffix format
/plugin marketplace add https://example.com/repo.git

3. Add a Local Marketplace (for development)

bash
# Add a local directory containing .codebuddy-plugin/marketplace.json
/plugin marketplace add ./my-marketplace

# Directly add a marketplace.json file path
/plugin marketplace add ./path/to/marketplace.json

4. Add an HTTP Marketplace

bash
# Add a remote marketplace.json via URL
/plugin marketplace add https://url.of/marketplace.json

Installing Plugins from a Marketplace

bash
# Install from a known marketplace
/plugin install plugin-name@marketplace-name

# Interactively browse available plugins
/plugin

Verifying Marketplace Installation

  1. List Marketplaces: Run /plugin marketplace list to confirm the marketplace was added
  2. Browse Plugins: Use /plugin to view available plugins in the marketplace
  3. Test Installation: Try installing a plugin to verify the marketplace is working properly

Team Configuration

Automatically Install Team Marketplaces

Configure in .codebuddy/settings.json:

json
{
  "extraKnownMarketplaces": {
    "team-tools": {
      "source": {
        "source": "github",
        "repo": "your-org/codebuddy-plugins"
      }
    },
    "project-specific": {
      "source": {
        "source": "git",
        "url": "https://git.company.com/project-plugins.git"
      }
    }
  },
  "enabledPlugins": {
    "plugin-a@team-tools": true,
    "plugin-b@team-tools": true
  }
}

When team members start CodeBuddy, the system automatically installs these marketplaces and the plugins specified in the enabledPlugins field.

Automatic Installation Flow

  1. Startup Detection: CodeBuddy automatically detects the configuration file on startup
  2. Marketplace Installation: Automatically installs marketplaces from extraKnownMarketplaces that are not yet installed
  3. Plugin Installation: Automatically installs enabled plugins from enabledPlugins that are not yet installed
  4. Background Execution: The installation process executes asynchronously in the background without blocking the startup flow
  5. Logging: The installation process logs detailed information, viewable with --debug

Creating Your Own Marketplace

Prerequisites for Creation

  • Git repository (GitHub, GitLab, or other git hosting service)
  • Understanding of JSON file format
  • One or more plugins to distribute

Creating the Marketplace File

Create .codebuddy-plugin/marketplace.json in the repository root:

json
{
  "name": "company-tools",
  "owner": {
    "name": "DevTools Team",
    "email": "[email protected]"
  },
  "plugins": [
    {
      "name": "code-formatter",
      "source": "./plugins/formatter",
      "description": "Automatic code formatting on save",
      "version": "2.1.0"
    },
    {
      "name": "deployment-tools",
      "source": {
        "source": "github",
        "repo": "company/deploy-plugin"
      },
      "description": "Deployment automation tools"
    }
  ]
}

Marketplace Schema

Required Fields

FieldTypeDescription
namestringMarketplace identifier (kebab-case, no spaces)
ownerobjectMarketplace maintainer information
pluginsarrayList of available plugins

Optional Metadata Fields

FieldTypeDescription
descriptionstringBrief marketplace description
versionstringMarketplace version

Plugin Entry Configuration

Required Fields

FieldTypeDescription
namestringPlugin identifier (kebab-case, no spaces)
sourcestring/objectPlugin source location
descriptionstringBrief plugin description

Optional Metadata Fields

FieldTypeDescription
versionstringPlugin version
authorobjectPlugin author information
homepagestringPlugin homepage or documentation URL
repositorystringSource code repository URL
licensestringSPDX license identifier (e.g., MIT, Apache-2.0)
keywordsarrayTags for plugin discovery and categorization
categorystringPlugin category
strictbooleanRequire plugin.json in plugin folder (default: true)

Component Configuration Fields

FieldTypeDescription
commandsstring/arrayCustom path to command files or directories
agentsstring/arrayCustom path to agent files
skillsstring/arrayCustom path to skill files
hooksstring/objectCustom hooks configuration or hooks file path
mcpServersstring/objectMCP server configuration or MCP config path

About the strict field:

  • strict: true (default): Plugin must contain a plugin.json manifest file, marketplace fields supplement these values
  • strict: false: plugin.json is optional. If missing, the marketplace entry serves as the complete plugin manifest

Plugin Source Types

1. Relative Path (Local)

For plugins in the same repository:

json
{
  "name": "my-plugin",
  "source": "./plugins/my-plugin",
  "description": "My local plugin"
}

2. GitHub Repository

json
{
  "name": "github-plugin",
  "source": {
    "source": "github",
    "repo": "owner/plugin-repo"
  },
  "description": "Plugin from GitHub"
}

3. Git URL

json
{
  "name": "git-plugin",
  "source": {
    "source": "url",
    "url": "https://gitlab.com/team/plugin.git"
  },
  "description": "Plugin from Git URL"
}

Advanced Plugin Entry Example

json
{
  "name": "enterprise-tools",
  "source": {
    "source": "github",
    "repo": "company/enterprise-plugin"
  },
  "description": "Enterprise workflow automation tools",
  "version": "2.1.0",
  "author": {
    "name": "Enterprise Team",
    "email": "[email protected]"
  },
  "homepage": "https://docs.company.com/plugins/enterprise-tools",
  "repository": "https://github.com/company/enterprise-plugin",
  "license": "MIT",
  "keywords": ["enterprise", "workflow", "automation"],
  "category": "productivity",
  "commands": [
    "./commands/core/",
    "./commands/enterprise/",
    "./commands/experimental/preview.md"
  ],
  "agents": [
    "./agents/security-reviewer.md",
    "./agents/compliance-checker.md"
  ],
  "skills": [
    "./skills/deployment.md",
    "./skills/monitoring.md"
  ],
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{
          "type": "command",
          "command": "${CODEBUDDY_PLUGIN_ROOT}/scripts/validate.sh"
        }]
      }
    ]
  },
  "mcpServers": {
    "enterprise-db": {
      "command": "${CODEBUDDY_PLUGIN_ROOT}/servers/db-server",
      "args": ["--config", "${CODEBUDDY_PLUGIN_ROOT}/config.json"]
    }
  },
  "strict": false
}

Note: ${CODEBUDDY_PLUGIN_ROOT} is an environment variable that resolves to the plugin's installation directory.

Hosting and Distributing Marketplaces

Steps:

  1. Create a repository: Set up a new repository for the marketplace
  2. Add the marketplace file: Create .codebuddy-plugin/marketplace.json and define plugins
  3. Share with your team: Team members add it using /plugin marketplace add owner/repo

Advantages: Built-in version control, issue tracking, and team collaboration features

2. Hosting on Other Git Services

Any git hosting service can be used for marketplace distribution. For example, using GitLab:

bash
/plugin marketplace add https://gitlab.com/company/plugins.git

3. Hosting via HTTP URL

You can host the marketplace.json file on any HTTP(S) server:

bash
/plugin marketplace add https://example.com/path/to/marketplace.json

4. Using Local Marketplaces for Development

Test marketplaces locally before distribution:

bash
# Add a local marketplace for testing
/plugin marketplace add ./my-local-marketplace

# Test plugin installation
/plugin install test-plugin@my-local-marketplace

Marketplace Management Operations

List Known Marketplaces

bash
/plugin marketplace list

Displays all configured marketplaces along with their sources and status.

Update Marketplace Metadata

bash
/plugin marketplace update marketplace-name

Refreshes the plugin list and metadata from the marketplace source.

Remove a Marketplace

bash
/plugin marketplace remove marketplace-name

Removes the marketplace from configuration.

⚠️ Warning: Removing a marketplace will uninstall all plugins installed from it.

Managing Auto-Updates

You can enable auto-update functionality for marketplaces, where CodeBuddy automatically checks and updates enabled marketplaces on startup.

How to Enable:

  1. Run the /plugin command to enter plugin management interface
  2. Select "Marketplaces" to view the marketplace list
  3. Select the marketplace you want to configure
  4. Select "Enable auto-update" or "Disable auto-update" to toggle the status

Auto-Update Mechanism:

  • Executed with a 5-second delay on startup, does not affect main flow
  • Only updates marketplaces that haven't been updated in over 24 hours
  • Updates between multiple marketplaces are spaced 2 seconds apart to avoid resource contention
  • Update failures do not affect other marketplaces, errors are logged

Priority: The CODEBUDDY_AUTO_UPDATE_THIRD_PARTY_MARKETPLACES environment variable takes precedence over an individual marketplace's UI toggle.

Implementation Details

Marketplace Types

CodeBuddy supports the following marketplace types:

  1. Directory (Local Directory): Load plugins from the local filesystem
  2. GitHub: Clone and update plugins from GitHub repositories
  3. Git: Clone and update plugins from any Git repository
  4. URL (HTTP): Download marketplace.json from HTTP(S) URLs

Marketplace Factory Pattern

The MarketplaceFactory creates different marketplace instances based on configuration:

typescript
// Create the corresponding marketplace instance based on source type
switch (sourceType) {
    case MarketplaceType.Directory:
        marketplace = new DirectoryMarketplace();
        break;
    case MarketplaceType.Github:
    case MarketplaceType.Git:
        marketplace = new GithubMarketplace();
        break;
    case MarketplaceType.URL:
        marketplace = new HttpMarketplace();
        break;
    default:
        marketplace = new BaseMarketplace();
        break;
}

Installation Flow

  1. Parse Source: Determine marketplace type based on input string (local path, GitHub repo, Git URL, HTTP URL)
  2. Download/Clone: Download or clone marketplace content based on marketplace type
  3. Read Manifest: Parse the .codebuddy-plugin/marketplace.json file
  4. Save Configuration: Save marketplace information to local storage
  5. Update Cache: Refresh plugin cache and marketplace list

Plugin Installers

CodeBuddy uses plugin installers (PluginInstaller) to handle different plugin source types:

  • Local Installer: Handles relative path plugins
  • Git Installer: Handles GitHub and Git URL plugins

Each installer implements the following methods:

  • support(source): Determine if this plugin source is supported
  • isInstalled(plugin, targetDir): Check if the plugin is already installed
  • install(plugin, targetDir): Install the plugin
  • update(plugin, installedPath): Update the plugin

Troubleshooting

Common Issues

1. Marketplace Fails to Load

Symptoms: Cannot add marketplace or cannot see its plugins

Solutions:

  • Verify the marketplace URL is accessible
  • Check that .codebuddy-plugin/marketplace.json exists at the specified path
  • Ensure JSON syntax is valid
  • For private repositories, confirm you have access permissions

2. Plugin Installation Fails

Symptoms: Marketplace displays but plugin installation fails

Solutions:

  • Verify the plugin source URL is accessible
  • Check that the plugin directory contains required files
  • For GitHub sources, ensure the repository is public or you have access
  • Manually test the plugin source by cloning/downloading

3. Git Operations Fail

Symptoms: Errors when cloning or pulling repositories

Solutions:

  • Ensure Git is installed and available in the command line
  • Check network connection and proxy settings
  • Verify Git credentials are configured correctly
  • Use the --debug flag to view detailed logs

Relative Path Issues in URL-Based Marketplaces

A URL-based marketplace is a catalog distribution mechanism: Agent CLI fetches marketplace.json and fetches plugin.json for relative-path entries, but it cannot recursively mirror arbitrary plugin files through HTTP directory listings. Therefore, relative paths can be used only by plugins whose functionality is fully inlined in the manifest. Plugins that include skills, commands, hooks, or local code should declare a materializable remote source such as Git or NPM in their entries, or publish the entire marketplace through Git or ZIP. This makes the boundary between the catalog and plugin payload explicit and prevents a downloaded plugin.json from being mistaken for a complete plugin directory.

Debugging Tips

  1. Enable Debug Logging:
bash
codebuddy --debug
  1. Manually Verify Marketplace File:
bash
# Check marketplace.json format
cat .codebuddy-plugin/marketplace.json | jq
  1. Test Git Clone:
bash
# Manually test if Git clone succeeds
git clone https://github.com/owner/repo.git /tmp/test-clone

Next Steps

For Marketplace Users

  • Discover community marketplaces: Search for CodeBuddy plugin collections on GitHub
  • Contribute feedback: Report issues and suggest improvements to marketplace maintainers
  • Share useful marketplaces: Help your team discover valuable plugin collections

For Marketplace Creators

  • Build plugin collections: Create themed marketplaces around specific use cases
  • Establish versioning: Implement clear versioning and update strategies
  • Community engagement: Gather feedback and maintain an active marketplace community
  • Documentation: Provide clear README files explaining marketplace contents

For Organizations

  • Private marketplaces: Set up internal marketplaces for proprietary tools
  • Governance policies: Establish plugin approval and security review guidelines
  • Training resources: Help teams effectively discover and adopt useful plugins