CodeBuddy Plugin Reference
A complete technical reference for the CodeBuddy plugin system, covering component specifications, CLI commands, and development tools.
A plugin is a self-contained component directory that extends CodeBuddy with custom functionality. Plugin components include Skills, Agents, Hooks, MCP servers, and LSP servers.
I. Plugin Component Reference
1. Skills
Plugins extend CodeBuddy by adding skills, creating /name shortcuts that can be invoked by users or the AI assistant.
Location: The skills/ or commands/ directory under the plugin root.
File format: A skill is a directory containing a SKILL.md; a command is a plain Markdown file.
Directory structure:
skills/
├── pdf-processor/
│ ├── SKILL.md
│ ├── reference.md (optional)
│ └── scripts/ (optional)
└── code-reviewer/
└── SKILL.mdIntegration behavior:
- Skills and commands are discovered automatically when the plugin is installed.
- The AI assistant can invoke them automatically based on task context.
- Skills may include supporting files and scripts.
See Skills for details.
2. Agents
Plugins can provide specialized sub-agents for specific tasks, which the AI assistant can invoke automatically when appropriate.
Location: The agents/ directory under the plugin root.
Format: Markdown files describing the agent's capabilities.
Frontmatter configuration:
markdown
---
name: agent-name
description: The agent's expertise and when to invoke it
model: sonnet
effort: medium
maxTurns: 20
disallowedTools: Write, Edit
---
Detailed system prompt for the agent, describing its role, expertise, and behavior.Plugin agents support the following frontmatter fields: name, description, model, effort, maxTurns, tools, disallowedTools, skills, memory, background, and isolation. The only valid value for isolation is "worktree". For security reasons, plugin agents do not support the hooks, mcpServers, or permissionMode fields.
Integration:
- Agents appear in the
/agentsUI. - The AI assistant can auto-invoke agents based on task context.
- Users can also invoke agents manually.
- Plugin agents cooperate with built-in agents.
See Subagents for details.
3. Hooks
Plugins can provide event handlers that respond to CodeBuddy events automatically.
Location: hooks/hooks.json under the plugin root, or inline configuration in plugin.json.
Format: JSON configuration containing event matchers and actions.
Configuration example:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CODEBUDDY_PLUGIN_ROOT}/scripts/format-code.sh"
}
]
}
]
}
}Available events:
Plugin hooks respond to the same lifecycle events as user-defined hooks:
| Event | Trigger |
|---|---|
SessionStart | Session starts or resumes |
UserPromptSubmit | User submits a prompt, before AI processing |
PreToolUse | Before tool execution; can block |
PermissionRequest | When the permission dialog appears |
PermissionDenied | When a tool call is denied by the auto-mode classifier. Return {retry: true} to tell the model it can retry |
PostToolUse | After a tool call succeeds |
PostToolUseFailure | After a tool call fails |
Notification | When CodeBuddy sends a notification |
SubagentStart | When a sub-agent starts |
SubagentStop | When a sub-agent finishes |
TaskCreated | When a task is created via TaskCreate |
TaskCompleted | When a task is marked completed |
Stop | When the AI finishes its response |
StopFailure | When the turn ends due to an API error. Output and exit code are ignored |
TeammateIdle | When a teammate is about to go idle |
InstructionsLoaded | When CODEBUDDY.md or .codebuddy/rules/*.md files are loaded into context |
ConfigChange | When a configuration file changes during the session |
CwdChanged | When the working directory changes (e.g., the AI runs cd) |
FileChanged | When a watched file changes on disk. The matcher field specifies the filename to watch |
WorktreeCreate | When a worktree is created via --worktree or isolation: "worktree" |
WorktreeRemove | When a worktree is removed (session exit or sub-agent completion) |
PreCompact | Before context compaction |
PostCompact | After context compaction completes |
Elicitation | When an MCP server requests user input during a tool call |
ElicitationResult | After the user responds to an MCP elicitation, before the response is sent back to the server |
SessionEnd | When the session terminates |
Hook types:
command: Executes a shell command or script.http: Sends the event JSON as a POST request to a URL.prompt: Uses an LLM to evaluate a prompt (use the$ARGUMENTSplaceholder for context).agent: Runs an agent validator with tools, for complex validation tasks.
4. MCP Servers
Plugins can bundle Model Context Protocol (MCP) servers to connect CodeBuddy with external tools and services.
Location: .mcp.json under the plugin root, or inline configuration in plugin.json.
Format: Standard MCP server configuration.
Configuration example:
json
{
"mcpServers": {
"plugin-database": {
"command": "${CODEBUDDY_PLUGIN_ROOT}/servers/db-server",
"args": ["--config", "${CODEBUDDY_PLUGIN_ROOT}/config.json"],
"env": {
"DB_PATH": "${CODEBUDDY_PLUGIN_ROOT}/data"
}
},
"plugin-api-client": {
"command": "npx",
"args": ["@company/mcp-server", "--plugin-mode"],
"cwd": "${CODEBUDDY_PLUGIN_ROOT}"
}
}
}Integration behavior:
- MCP servers start automatically when the plugin is enabled.
- Servers appear as standard MCP tools in the toolkit.
- Server functionality integrates seamlessly with existing tools.
- Plugin servers can be configured independently of user-level MCP servers.
5. LSP Servers
Tip: Need an LSP plugin? You can install one from the official marketplace — search for "lsp" in the
/pluginDiscover tab. This section covers how to create LSP plugins for languages not provided by the official marketplace.
Plugins can provide Language Server Protocol (LSP) servers to give the AI assistant real-time code intelligence while working on a codebase.
LSP integration provides:
- Instant diagnostics: The AI assistant sees errors and warnings immediately after each edit.
- Code navigation: Go to definition, find references, and hover information.
- Language awareness: Type information and documentation for code symbols.
Location: An .lsp.json file under the plugin root, or inline configuration in plugin.json.
Format: JSON configuration mapping language server names to their configurations.
.lsp.json file format:
json
{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}Inline configuration in plugin.json:
json
{
"name": "my-plugin",
"lspServers": {
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}
}Required fields:
| Field | Description |
|---|---|
command | LSP binary to execute (must be on PATH) |
extensionToLanguage | Maps file extensions to language identifiers |
Optional fields:
| Field | Description |
|---|---|
args | Command-line arguments for the LSP server |
transport | Communication transport: stdio (default) or socket |
env | Environment variables to set when starting the server |
initializationOptions | Options passed to the server during initialization |
settings | Settings passed via workspace/didChangeConfiguration |
workspaceFolder | Workspace folder path for the server |
startupTimeout | Maximum time (ms) to wait for server startup |
shutdownTimeout | Maximum time (ms) to wait for graceful shutdown |
restartOnCrash | Whether to automatically restart after a crash |
maxRestarts | Maximum restart attempts before giving up |
Warning: You must install the language server binary separately. LSP plugins configure how CodeBuddy connects to a language server but do not include the server itself. If you see an
Executable not found in $PATHerror in the/pluginErrors tab, install the binary for your language.
Available LSP plugins:
| Plugin | Language Server | Install Command |
|---|---|---|
pyright-lsp | Pyright (Python) | pip install pyright or npm install -g pyright |
typescript-lsp | TypeScript Language Server | npm install -g typescript-language-server typescript |
rust-lsp | rust-analyzer | See rust-analyzer installation |
Install the language server first, then install the plugin from the marketplace.
II. Plugin Installation Scopes
When installing a plugin, choose a scope that determines where the plugin is available:
| Scope | Settings file | Use case |
|---|---|---|
user | ~/.codebuddy/settings.json | Personal plugin, available in all projects (default) |
project | .codebuddy/settings.json | Team plugin, shared via version control |
local | .codebuddy/settings.local.json | Project-specific plugin, gitignored |
managed | Managed settings | Managed plugins (read-only; updates only) |
Plugins use the same scoping system as other CodeBuddy configuration. See Settings for details.
III. Plugin Manifest Schema (plugin.json)
The .codebuddy-plugin/plugin.json file (or .workbuddy-plugin/plugin.json, .claude-plugin/plugin.json) defines plugin metadata and configuration. This section documents all supported fields and options.
The manifest is optional. If omitted, CodeBuddy auto-discovers components in the default locations and derives the plugin name from the directory name. Use a manifest when you need to provide metadata or customize component paths.
Complete Schema Example
json
{
"name": "plugin-name",
"version": "1.2.0",
"description": "Brief plugin description",
"author": {
"name": "Author name",
"email": "[email protected]",
"url": "https://github.com/author"
},
"homepage": "https://docs.example.com/plugin",
"repository": "https://github.com/author/plugin",
"license": "MIT",
"keywords": ["keyword1", "keyword2"],
"commands": ["./custom/commands/special.md"],
"agents": "./custom/agents/",
"skills": "./custom/skills/",
"hooks": "./config/hooks.json",
"mcpServers": "./mcp-config.json",
"outputStyles": "./styles/",
"lspServers": "./.lsp.json"
}Required Fields
If a manifest is included, name is the only required field.
| Field | Type | Description | Example |
|---|---|---|---|
name | string | Unique identifier (kebab-case, no spaces) | "deployment-tools" |
This name is used for component namespacing. For example, in the UI, the agent agent-creator from plugin plugin-dev will appear as plugin-dev:agent-creator.
Metadata Fields
| Field | Type | Description | Example |
|---|---|---|---|
version | string | Semantic version. If set in both the marketplace entry and plugin.json, plugin.json wins. Set in only one place. | "2.1.0" |
description | string | Short description of the plugin's purpose | "Deployment automation tools" |
author | object | Author information | {"name": "Dev Team", "email": "[email protected]"} |
homepage | string | Documentation URL | "https://docs.example.com" |
repository | string | Source code URL | "https://github.com/user/plugin" |
license | string | License identifier | "MIT", "Apache-2.0" |
keywords | array | Discovery tags | ["deployment", "ci-cd"] |
Component Path Fields
| Field | Type | Description | Example |
|---|---|---|---|
commands | string | array | Custom command file/directory (replaces default commands/) | "./custom/cmd.md" or ["./cmd1.md"] |
agents | string | array | Custom agent files (replaces default agents/) | "./custom/agents/reviewer.md" |
skills | string | array | Custom skill directories (replaces default skills/) | "./custom/skills/" |
hooks | string | array | object | Hook configuration path or inline configuration | "./my-extra-hooks.json" |
mcpServers | string | array | object | MCP configuration path or inline configuration | "./my-extra-mcp-config.json" |
outputStyles | string | array | Custom output style files/directories (replaces default output-styles/) | "./styles/" |
lspServers | string | array | object | LSP configuration path or inline configuration | "./.lsp.json" |
userConfig | object | Values CodeBuddy prompts the user to provide when enabling the plugin. See User Configuration | See below |
channels | array | Channel declarations for message injection. See Channels | See below |
User Configuration
The userConfig field declares values that CodeBuddy prompts the user to provide when the plugin is enabled. Use this instead of asking users to edit settings.json manually.
json
{
"userConfig": {
"api_endpoint": {
"description": "Your team's API endpoint",
"sensitive": false
},
"api_token": {
"description": "API authentication token",
"sensitive": true
}
}
}Keys must be valid identifiers. Each value can be substituted as ${user_config.KEY} in MCP and LSP server configs and hook commands, and (for non-sensitive values only) inside skill and agent content. Values are also exported as CODEBUDDY_PLUGIN_OPTION_<KEY> environment variables to plugin child processes.
Non-sensitive values are stored in pluginConfigs[<plugin-id>].options in settings.json. Sensitive values are stored in the system keychain (or in ~/.codebuddy/.credentials.json if the keychain is unavailable). Keychain storage is shared with OAuth tokens and has a total limit of around 2 KB, so sensitive values should be kept small.
Channels
The channels field lets a plugin declare one or more message channels used to inject content into the conversation. Each channel binds to an MCP server provided by the plugin.
json
{
"channels": [
{
"server": "telegram",
"userConfig": {
"bot_token": { "description": "Telegram bot token", "sensitive": true },
"owner_id": { "description": "Your Telegram user ID", "sensitive": false }
}
}
]
}The server field is required and must match a key in the plugin's mcpServers. The optional per-channel userConfig uses the same schema as the top-level one, letting you prompt for a bot token or owner ID when the plugin is enabled.
Path Behavior Rules
For commands, agents, skills, and outputStyles, a custom path replaces the default directory. If the manifest specifies commands, the default commands/ directory is not scanned. Hooks, MCP servers, and LSP servers have different semantics for handling multiple sources.
- All paths must be relative to the plugin root and start with
./. - Components under custom paths follow the same naming and namespacing rules.
- Multiple paths can be specified as an array.
- To keep the default directory and add more paths, include the default in the array:
"commands": ["./commands/", "./extras/deploy.md"].
Path examples:
json
{
"commands": [
"./specialized/deploy.md",
"./utilities/batch-process.md"
],
"agents": [
"./custom-agents/reviewer.md",
"./custom-agents/tester.md"
]
}Environment Variables
CodeBuddy provides two variables for referencing plugin paths. Both are substituted inline anywhere in skill content, agent content, hook commands, and MCP or LSP server configuration. Both are also exported as environment variables to hook processes and MCP/LSP server child processes.
${CODEBUDDY_PLUGIN_ROOT}: Absolute path to the plugin installation directory. Use it to reference scripts, binaries, and configuration files bundled with the plugin. This path changes when the plugin is updated, so files written here do not persist across updates.
Compatibility: The ${CLAUDE_PLUGIN_ROOT} variable name is also supported for compatibility with Claude Code plugins.
${CODEBUDDY_PLUGIN_DATA}: A persistent directory for plugin state that survives updates. Use it for installed dependencies (such as node_modules or Python virtual environments), generated code, caches, and any files that need to persist across plugin versions. The directory is created automatically on first reference.
Compatibility: The ${CLAUDE_PLUGIN_DATA} variable name is also supported.
json
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "${CODEBUDDY_PLUGIN_ROOT}/scripts/process.sh"
}
]
}
]
}
}Persistent Data Directory
The ${CODEBUDDY_PLUGIN_DATA} directory resolves to ~/.codebuddy/plugins/data/{id}/, where {id} is the plugin identifier with characters outside a-z, A-Z, 0-9, _, and - replaced by -. For example, a plugin installed as formatter@my-marketplace uses the directory ~/.codebuddy/plugins/data/formatter-my-marketplace/.
A common use is to install language dependencies once and reuse them across sessions and plugin updates. Because the data directory's lifetime outlasts any single plugin version, simply checking for directory existence does not detect when an update has changed the plugin's dependency manifest. The recommended pattern is to compare the bundled manifest with a copy in the data directory and reinstall when they differ.
The following SessionStart hook installs node_modules on first run, and reinstalls them whenever a plugin update includes a changed package.json:
json
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "diff -q \"${CODEBUDDY_PLUGIN_ROOT}/package.json\" \"${CODEBUDDY_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CODEBUDDY_PLUGIN_DATA}\" && cp \"${CODEBUDDY_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CODEBUDDY_PLUGIN_DATA}/package.json\""
}
]
}
]
}
}diff exits non-zero whenever the stored copy is missing or differs from the bundled copy, covering both the first run and dependency-changing updates. If npm install fails, the trailing rm removes the copied manifest so the next session retries.
Scripts bundled under ${CODEBUDDY_PLUGIN_ROOT} can run against the persisted node_modules:
json
{
"mcpServers": {
"routines": {
"command": "node",
"args": ["${CODEBUDDY_PLUGIN_ROOT}/server.js"],
"env": {
"NODE_PATH": "${CODEBUDDY_PLUGIN_DATA}/node_modules"
}
}
}
}When a plugin is uninstalled (from its last installation scope), the data directory is deleted automatically. The /plugin UI shows the directory size and prompts before deletion. The CLI deletes it by default; pass --keep-data to retain it.
IV. Plugin Cache and File Resolution
Plugins can be specified in two ways:
- Via
codebuddy --plugin-dir, valid for the current session only. - Via marketplace installation, valid for future sessions.
For security and validation, CodeBuddy copies marketplace plugins to the user's local plugin cache (~/.codebuddy/plugins/cache) rather than using them in place. Understanding this behavior is important when developing plugins that reference external files.
Path Traversal Restrictions
Installed plugins cannot reference files outside their own directory. Paths that traverse outside the plugin root (like ../shared-utils) do not work after installation because those external files are not copied into the cache.
Using External Dependencies
If a plugin needs access to files outside its directory, you can create symlinks inside the plugin directory that point to external files. Symlinks are preserved during the copy:
bash
# Inside the plugin directory
ln -s /path/to/shared-utils ./shared-utilsThe contents of the symlink are copied into the plugin cache. This provides flexibility while preserving the security benefits of the cache system.
V. Plugin Directory Structure
Standard Plugin Layout
A complete plugin follows this structure:
enterprise-plugin/
├── .codebuddy-plugin/ # Metadata directory (optional)
│ └── plugin.json # Plugin manifest
├── commands/ # Default commands location
│ ├── status.md
│ └── logs.md
├── agents/ # Default agents location
│ ├── security-reviewer.md
│ ├── performance-tester.md
│ └── compliance-checker.md
├── skills/ # Agent skills
│ ├── code-reviewer/
│ │ └── SKILL.md
│ └── pdf-processor/
│ ├── SKILL.md
│ └── scripts/
├── output-styles/ # Output style definitions
│ └── terse.md
├── hooks/ # Hook configuration
│ ├── hooks.json # Primary hook configuration
│ └── security-hooks.json # Additional hooks
├── bin/ # Plugin executables, added to PATH
│ └── my-tool # Callable as a bare command in the Bash tool
├── settings.json # Plugin default settings
├── .mcp.json # MCP server definitions
├── .lsp.json # LSP server configuration
├── scripts/ # Hook and utility scripts
│ ├── security-scan.sh
│ ├── format-code.py
│ └── deploy.js
├── LICENSE # License file
└── CHANGELOG.md # Version historyImportant: The
.codebuddy-plugin/directory contains theplugin.jsonfile. All other directories (commands/,agents/,skills/,output-styles/,hooks/) must live at the plugin root, not inside.codebuddy-plugin/. The.workbuddy-plugin/and.claude-plugin/directories are also supported for compatibility.
File Location Reference
| Component | Default location | Purpose |
|---|---|---|
| Manifest | .codebuddy-plugin/plugin.json | Plugin metadata and configuration (optional) |
| Commands | commands/ | Skill Markdown files (legacy; new skills use skills/) |
| Agents | agents/ | Sub-agent Markdown files |
| Skills | skills/ | Skills following the <name>/SKILL.md structure |
| Output styles | output-styles/ | Output style definitions |
| Hooks | hooks/hooks.json | Hook configuration |
| MCP servers | .mcp.json | MCP server definitions |
| LSP servers | .lsp.json | Language server configuration |
| Executables | bin/ | Executables added to the Bash tool PATH. When the plugin is enabled, files in this directory can be invoked as bare commands in any Bash tool call |
| Settings | settings.json | Default configuration applied when the plugin is enabled. Currently only agent settings are supported |
VI. CLI Command Reference
CodeBuddy provides CLI commands for non-interactive plugin management, suitable for scripting and automation.
plugin install
Install a plugin from an available marketplace.
bash
codebuddy plugin install <plugin> [options]Arguments:
<plugin>: Plugin name, orplugin-name@marketplace-nameto specify a particular marketplace.
Options:
| Option | Description | Default |
|---|---|---|
-s, --scope <scope> | Install scope: user, project, or local | user |
-h, --help | Show command help |
The scope determines which settings file the installed plugin is added to. For example, --scope project writes to enabledPlugins in .codebuddy/settings.json, making the plugin available to everyone who clones the project repository.
Examples:
bash
# Install at user scope (default)
codebuddy plugin install formatter@my-marketplace
# Install at project scope (shared with team)
codebuddy plugin install formatter@my-marketplace --scope project
# Install at local scope (gitignored)
codebuddy plugin install formatter@my-marketplace --scope localplugin uninstall
Remove an installed plugin.
bash
codebuddy plugin uninstall <plugin> [options]Arguments:
<plugin>: Plugin name, orplugin-name@marketplace-name.
Options:
| Option | Description | Default |
|---|---|---|
-s, --scope <scope> | Uninstall from scope: user, project, or local | user |
--keep-data | Preserve the plugin's persistent data directory | |
-h, --help | Show command help |
Aliases: remove, rm
By default, uninstalling from the last remaining scope also deletes the plugin's ${CODEBUDDY_PLUGIN_DATA} directory. Use --keep-data to preserve it — for example, when reinstalling after testing a new version.
plugin enable
Enable a disabled plugin.
bash
codebuddy plugin enable <plugin> [options]Arguments:
<plugin>: Plugin name, orplugin-name@marketplace-name.
Options:
| Option | Description | Default |
|---|---|---|
-s, --scope <scope> | Enable scope: user, project, or local | user |
-h, --help | Show command help |
plugin disable
Disable a plugin without uninstalling it.
bash
codebuddy plugin disable <plugin> [options]Arguments:
<plugin>: Plugin name, orplugin-name@marketplace-name.
Options:
| Option | Description | Default |
|---|---|---|
-s, --scope <scope> | Disable scope: user, project, or local | user |
-h, --help | Show command help |
plugin update
Update a plugin to the latest version.
bash
codebuddy plugin update <plugin> [options]Arguments:
<plugin>: Plugin name, orplugin-name@marketplace-name.
Options:
| Option | Description | Default |
|---|---|---|
-s, --scope <scope> | Update scope: user, project, local, or managed | user |
-h, --help | Show command help |
Marketplace Management
bash
# Add a marketplace
codebuddy plugin marketplace add <source> [--name <name>]
# List marketplaces
codebuddy plugin marketplace list
# Update a marketplace
codebuddy plugin marketplace update <name>
# Remove a marketplace
codebuddy plugin marketplace remove <name>Marketplace source formats:
bash
# Local directory
codebuddy plugin marketplace add /path/to/marketplace
# GitHub shorthand
codebuddy plugin marketplace add owner/repo
# Git URL
codebuddy plugin marketplace add https://github.com/owner/repo.git
# HTTP URL (marketplace.json)
codebuddy plugin marketplace add https://example.com/marketplace.jsonVII. Debugging and Development Tools
Debug Commands
Use codebuddy --debug to see plugin loading details:
What it shows:
- Which plugins are being loaded.
- Any errors in plugin manifests.
- Command, agent, and hook registration.
- MCP server initialization.
Common Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Plugin not loaded | Invalid plugin.json | Run codebuddy plugin validate or /plugin validate to check plugin.json, skill/agent/command frontmatter, and hooks/hooks.json for syntax and schema errors |
| Command not appearing | Wrong directory structure | Ensure commands/ is at the plugin root, not inside .codebuddy-plugin/ |
| Hook not firing | Script not executable | Run chmod +x script.sh |
| MCP server fails | Missing ${CODEBUDDY_PLUGIN_ROOT} | Use this variable for all plugin paths |
| Path errors | Using absolute paths | All paths must be relative and start with ./ |
LSP Executable not found in $PATH | Language server not installed | Install the binary (e.g., npm install -g typescript-language-server typescript) |
Common Error Messages
Manifest validation errors:
Invalid JSON syntax: Unexpected token } in JSON at position 142: Check for missing commas, trailing commas, or unquoted strings.Plugin has an invalid manifest file at .codebuddy-plugin/plugin.json. Validation errors: name: Required: Missing required field.Plugin has a corrupt manifest file at .codebuddy-plugin/plugin.json. JSON parse error: ...: JSON syntax error.
Plugin loading errors:
Warning: No commands found in plugin my-plugin custom directory: ./cmds. Expected .md files or SKILL.md in subdirectories.: The command path exists but contains no valid command files.Plugin directory not found at path: ./plugins/my-plugin. Check that the marketplace entry has the correct path.: Thesourcepath inmarketplace.jsonpoints to a non-existent directory.Plugin my-plugin has conflicting manifests: both plugin.json and marketplace entry specify components.: Remove duplicate component definitions, or removestrict: falsefrom the marketplace entry.
Hook Troubleshooting
Hook script not executing:
- Verify the script is executable:
chmod +x ./scripts/your-script.sh. - Check the shebang line: the first line should be
#!/bin/bashor#!/usr/bin/env bash. - Confirm the path uses
${CODEBUDDY_PLUGIN_ROOT}:"command": "${CODEBUDDY_PLUGIN_ROOT}/scripts/your-script.sh". - Test the script manually:
./scripts/your-script.sh.
Hook not firing on the expected event:
- Verify the event name (case-sensitive):
PostToolUse, notpostToolUse. - Check the matcher pattern matches the target tool:
"matcher": "Write|Edit"for file operations. - Confirm the hook type is valid:
command,http,prompt, oragent.
MCP Server Troubleshooting
Server does not start:
- Check that the command exists and is executable.
- Verify all paths use the
${CODEBUDDY_PLUGIN_ROOT}variable. - Check MCP server logs:
codebuddy --debugshows initialization errors. - Test the server manually outside of CodeBuddy.
Server tools do not appear:
- Ensure the server is correctly configured in
.mcp.jsonorplugin.json. - Verify that the server correctly implements the MCP protocol.
- Check for connection timeouts in the debug output.
Directory Structure Errors
Symptom: The plugin loads but components (commands, agents, hooks) are missing.
Correct structure: Components must be at the plugin root, not inside .codebuddy-plugin/. Only plugin.json belongs in .codebuddy-plugin/.
my-plugin/
├── .codebuddy-plugin/
│ └── plugin.json <- Only the manifest lives here
├── commands/ <- At root level
├── agents/ <- At root level
└── hooks/ <- At root levelIf components are inside .codebuddy-plugin/, move them up to the plugin root.
Debug checklist:
- Run
codebuddy --debugand look for "loading plugin" messages. - Verify that each component directory is listed in the debug output.
- Confirm that file permissions allow reading the plugin files.
VIII. Version Management Reference
Semantic Versioning
Follow semantic versioning for plugin releases:
json
{
"name": "my-plugin",
"version": "2.1.0"
}Version format: MAJOR.MINOR.PATCH
- MAJOR: Incompatible API changes.
- MINOR: Backwards-compatible feature additions.
- PATCH: Backwards-compatible bug fixes.
Best practices:
- Start the first stable release at
1.0.0. - Update the version in
plugin.jsonbefore distributing changes. - Record changes in a
CHANGELOG.mdfile. - Use pre-release versions (e.g.,
2.0.0-beta.1) for testing.
Note: CodeBuddy uses the version to decide whether a plugin needs updating. If you change plugin code without bumping the version in
plugin.json, existing users will not see the change due to caching.If the plugin is in a marketplace directory, you can manage versions via
marketplace.jsonand omit theversionfield fromplugin.json.
IX. Compatibility with Claude Code
The CodeBuddy plugin system is designed to be compatible with the Claude Code plugin specification, with the following differences:
Naming Differences
| Concept | Claude Code | CodeBuddy |
|---|---|---|
| Metadata directory | .claude-plugin/ | .codebuddy-plugin/ (priority), .workbuddy-plugin/, or .claude-plugin/ (compatible) |
| Environment variable | ${CLAUDE_PLUGIN_ROOT} | ${CODEBUDDY_PLUGIN_ROOT} (priority) or ${CLAUDE_PLUGIN_ROOT} (compatible) |
| Data directory variable | ${CLAUDE_PLUGIN_DATA} | ${CODEBUDDY_PLUGIN_DATA} (priority) or ${CLAUDE_PLUGIN_DATA} (compatible) |
Migration Guide
Migrating from Claude Code to CodeBuddy:
- Optionally rename
.claude-plugin/to.codebuddy-plugin/. - Optionally replace
${CLAUDE_PLUGIN_ROOT}with${CODEBUDDY_PLUGIN_ROOT}in scripts. - Optionally replace
${CLAUDE_PLUGIN_DATA}with${CODEBUDDY_PLUGIN_DATA}.
Note: Keeping the original names is fully compatible — CodeBuddy recognizes them automatically.