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

Plugins

A plugin bundles several extensions into one installable package: skills, MCP servers, hooks, and related assets that ship and update together. Reach for a plugin when you want to share a whole capability at once instead of wiring each piece by hand. See Connectors for the current integration surface (MCP, plugins, hooks, and skills).

Plugin Structure

Every plugin is a directory with a .claude-plugin/plugin.json manifest file (the Claude Code-compatible path). The manifest describes the plugin’s metadata and lists its integration points.

Plugin Manifest (plugin.json)

Veyyon reads these fields from plugin.json:

FieldTypeDescription
nameStringThe unique name of the plugin. Lowercase ASCII alphanumerics with interior dots and hyphens (no leading/trailing separator, no underscores), at most 64 characters.
versionStringThe version of the plugin (optional). When omitted, the installed version resolves in this order: marketplace catalog entry version, then this manifest or package.json, then the source git SHA truncated to 7 characters, then "0.0.0".
descriptionStringA description of the plugin (optional).
skillsString or Array of StringsPath or paths to directories containing skill definitions (optional).
commands / slash-commandsString or Array of StringsPath or paths to command definitions (optional).

Other plugin content loads from conventional locations rather than manifest fields: MCP servers from a .mcp.json file at the plugin root, and hooks from .ts or .js modules under the plugin’s hooks/pre/ and hooks/post/ directories. A hook is loaded as an extension module and must default-export a factory, so a shell script placed in those directories is discovered but not run; veyyon reports each one it had to skip.

Marketplaces

Marketplaces are collections of plugins. A marketplace is a directory or Git repository containing a marketplace.json catalog manifest.

Veyyon checks the following relative paths under a marketplace root to locate its catalog manifest:

  1. .veyyon-plugin/marketplace.json (preferred)
  2. .claude-plugin/marketplace.json (Claude Code-compatible fallback)

The marketplace catalog requires a name, an owner.name, and a plugins list. Each plugin entry requires only a name and a source; optional entry metadata includes description, version, author, homepage, repository, license, keywords, category, tags, strict, and embedded capability fields (commands, agents, hooks, mcpServers, lspServers, dapAdapters). A source can point to a local directory, a Git repository (with optional branch, tag, commit ref, or subdirectory path), a URL, or an npm package.

File Locations

Plugin install state is profile-scoped under ~/.veyyon/profiles/<profile>/plugins/ (default profile: profiles/default/plugins/). Config root is relocatable with VEYYON_CONFIG_DIR.

PathDescription
~/.veyyon/profiles/<profile>/plugins/installed_plugins.jsonUser-scope marketplace install registry
~/.veyyon/profiles/<profile>/plugins/node_modules/npm/git/link plugin packages
~/.veyyon/profiles/<profile>/plugins/cache/Cached marketplace catalogs and plugin trees
~/.veyyon/profiles/<profile>/plugins/veyyon-plugins.lock.jsonEnabled state, selected features and stored settings for every npm, git and linked plugin
Project .veyyon/plugins/installed_plugins.jsonProject-scope marketplace installs

Command Line Interface

You can manage plugins and marketplaces using the veyyon plugin and veyyon plugin marketplace command groups.

Managing Plugins

Install a Plugin

veyyon plugin install accepts four kinds of target:

TargetFormExample
Marketplacename@marketplacesample@debug
npmname, @scope/name, either with @version@veyyon/[email protected]
Gitgithub:user/repo, gitlab:, bitbucket:, codeberg:, sourcehut:/srht:, or a full git URL, each with an optional #refgithub:user/repo#v1.0
Local patha path to the plugin’s own directory./path/to/plugin
$ veyyon plugin install sample@debug
$ veyyon plugin install @veyyon/exa
$ veyyon plugin install github:user/repo#v1.0
$ veyyon plugin install ./path/to/plugin

A local path is linked rather than copied: veyyon symlinks the directory into the profile’s node_modules, so edits to the source appear without a reinstall. veyyon plugin link <path> does the same thing, and either verb works.

Use --force to reinstall over an existing install and --scope user|project to choose the install scope. --scope applies to marketplace installs only; npm, git and local installs warn and ignore it. --json prints the installation result as JSON for npm, git and link installs; marketplace installs ignore it.

--dry-run resolves the target and reports the name and version it resolves to, without writing a dependency, a lockfile entry or a node_modules entry:

$ veyyon plugin install github:sindresorhus/slugify --dry-run
[dry-run] Would install @sindresorhus/slugify@github:sindresorhus/slugify#7c318bd

A git target’s package name comes from the repository, not the spec, so a dry run is how you learn the name a git plugin will install under. A target that cannot be resolved — an unpublished npm name, a version that does not exist, a private or missing repository — fails with the resolver’s output and exits 1. A dry run proves the target resolves; it does not prove the package is a veyyon plugin, because nothing is unpacked and no manifest is read.

List Plugins

List installed plugins and their statuses.

$ veyyon plugin list

Options:

  • --json: Print the output as JSON.

Uninstall a Plugin

Uninstall a plugin from local cache and config. Pass the name veyyon plugin list shows, which for a git or local plugin is the package’s own name rather than the spec you installed it with.

$ veyyon plugin uninstall sample@debug
$ veyyon plugin uninstall @veyyon/exa
$ veyyon plugin uninstall linked-plugin

Every install route is removable by the same command. Uninstalling a linked plugin removes the symlink and the plugin’s stored settings, and leaves the directory it pointed at untouched: that is your working copy, not veyyon’s.

Use the --json flag to return the removal result as JSON for npm plugins; marketplace uninstalls ignore it.

To keep a plugin installed but inert, use veyyon plugin disable <name>, which leaves it listed and reversible with enable.

Check Plugin Health

Report what is wrong with your plugin installation, and optionally repair it.

$ veyyon plugin doctor
$ veyyon plugin doctor --fix
$ veyyon plugin doctor --json

Each check reports ok, a warning, or an error. doctor exits 1 when any error is left unrepaired and 0 otherwise, so you can gate a script on it. Warnings never affect the exit code, and an error that --fix repaired does not either. --json prints the checks as an array instead of the human-readable report.

On a machine with no plugins installed every check is ok: nothing is missing, because nothing was ever installed. That is the state a fresh install is in, and doctor is quiet about it on purpose.

The checks are:

  • plugins_directory, package_manifest, node_modules: the three things a plugin install needs. Each one distinguishes “not created yet” from “there but unreadable”. The first is normal and reports ok; the second is an error stating the path, because a plugins directory whose permissions have been mangled looks identical to an empty one from the outside and the fix is chmod, not a reinstall. A profile holding only linked plugins has no package.json, because linking writes no dependency; package_manifest reports ok and states how many linked plugins are present.
  • plugin:<name>: one per installed plugin. An error means the package is missing from node_modules or has no package.json. A warning means it loaded but contains no plugin manifest, so veyyon can see the package and cannot use it.
  • plugin:<name>:tools, :hooks, :extension:<path>: an entry point the manifest names and the package does not contain.
  • plugin:<name>:feature:<feature>: a feature you enabled that the plugin’s manifest does not define, usually because the plugin dropped it in an update. A warning, since the plugin still works.
  • orphan:<name>: a plugin your config enables that is not installed. A warning, since your config is intact and only the package is gone.
  • plugin_config, installed_registry: reported only when one of those files cannot be read. doctor continues and reports the rest, so one unreadable file does not cost you the whole report.

--fix repairs what can be repaired without a decision: it runs an install for a missing package, drops an orphaned config entry, and removes an enabled feature the manifest does not define. A check that was repaired is reported. Everything else is left for you, because the remedy depends on what you meant.

Managing Marketplaces

Add a Marketplace

Add a local path or Git repository to your configured marketplace sources.

$ veyyon plugin marketplace add ./path/to/marketplace
$ veyyon plugin marketplace add owner/repo
$ veyyon plugin marketplace add https://github.com/owner/repo

List Marketplaces

List all configured marketplaces and their sources.

$ veyyon plugin marketplace list

Update Marketplaces

Fetch the latest revisions for configured Git marketplaces. Omit the marketplace name to update all configured Git marketplaces.

$ veyyon plugin marketplace update
$ veyyon plugin marketplace update debug

Remove a Marketplace

Remove a configured marketplace by name.

$ veyyon plugin marketplace remove debug

The plugin marketplace subcommands print human-readable output only; --json has no effect on them.

TUI Integration

Slash Commands

  • /plugins: Lists installed npm and link plugins.
  • /extensions: Opens the Extension Control Center dashboard, which shows plugin-provided skills, tools, and hooks alongside everything else that is loaded.

The Plugins tab of /settings lists installed npm and marketplace plugins and toggles each one on or off. Browsing and installing happen through the veyyon plugin CLI.

Registry Files

Marketplace and plugin state is not kept in config.yml. Two JSON registries, managed by the veyyon plugin CLI (and the /settings Plugins tab for the enabled toggle; edit through those, not by hand):

  • marketplaces.json (~/.veyyon/profiles/<profile>/marketplaces.json, the profile root beside agent/ and plugins/): which catalogs you have added. Each entry records the marketplace name, sourceType, sourceUri, catalogPath, and added/updated timestamps.
  • installed_plugins.json (under the plugins dir): which plugins are installed. Each entry is keyed <plugin_name>@<marketplace_name> and records the install scope (user or project), installPath, version, install/update timestamps, the source git commit, and an enabled toggle.

The one plugin-related key that does live in config.yml is marketplace.autoUpdate, which controls the startup update check. It runs in the background, so it never delays the first paint, and it takes one of three values:

  • notify (the default) refreshes any marketplace catalog older than a day, compares your installed versions against it, and prints one line with how many updates are available. Install them with veyyon plugin upgrade (all) or veyyon plugin upgrade <name>@<marketplace>.
  • auto does the same check and installs the updates itself, then prints one line with how many landed. The running session keeps the versions it loaded at startup, so restart to use the new ones.
  • off skips the check entirely and contacts no marketplace.

A check that fails, usually because you are offline, is written to the log and does not interrupt the session.

Plugins are installed through the veyyon plugin CLI above, there is no model-facing plugin-install tool. For task-shaped recipes that combine plugins with MCP and skills, see Task guides.