cbm-projects plugins are independent processes. This keeps the host ABI stable across operating systems and lets plugins use any implementation language.
Each installed plugin directory contains plugin.json:
{
"apiVersion": "cbm-projects.plugin/v1",
"name": "example",
"version": "1.0.0",
"description": "Example plugin",
"entrypoint": "cbm-plugin-example",
"platforms": ["darwin/arm64", "linux/amd64", "windows/amd64"],
"commands": ["hello"],
"hooks": ["doctor.check"],
"permissions": ["process:execute"],
"source": "https://github.com/example/plugin",
"license": "MIT",
"sha256": "optional-executable-sha256"
}An entrypoint may be absolute, relative to the manifest, or discoverable on PATH. A 64-character sha256 is verified before every invocation. URL plugin packages are ZIP archives and require a separate archive SHA-256 on plugin install.
The host checks plugin manifests in this order and keeps the first manifest for each name:
- Every directory in
CBM_PROJECTS_PLUGIN_DIR. - The user configuration directory's
pluginsfolder. - A
pluginsfolder next to thecbm-projectsexecutable. cbm-projects-pluginsbelow each PATH directory and../share/cbm-projects/pluginsrelative to it.- macOS:
/Library/Application Support/cbm-projects/pluginsand/usr/local/share/cbm-projects/plugins. - Linux:
/usr/local/lib/cbm-projects/plugins,/usr/lib/cbm-projects/plugins,/usr/local/share/cbm-projects/plugins, and/usr/share/cbm-projects/plugins. - Windows:
%ProgramData%\cbm-projects\plugins.
An entrypoint is resolved relative to its manifest, next to the host executable, then through PATH. This lets the official archive keep manifests under plugins/ while placing all executables together.
The host writes one request object to stdin:
{
"apiVersion": "cbm-projects.plugin/v1",
"action": "command",
"command": "hello",
"args": ["world"],
"locale": "en",
"configDir": "/user/config/cbm-projects",
"mcpPath": "/user/bin/codebase-memory-mcp",
"project": {"name": "demo", "path": "/code/demo"}
}Hook requests use "action":"hook" and an event field. The plugin writes exactly one response object to stdout and sends logs to stderr:
{
"status": "ok",
"message": "optional user-facing message",
"data": {"output": "optional command output"},
"diagnostics": []
}Use status: error and message for failures. Command/provider failures are fail-closed. Lifecycle hook failures are logged and fail-open. Hooks have a 15-second timeout; ordinary commands use the timeout selected by the host operation.
setup.detectsetup.configureproject.addedproject.removedindex.beforeindex.afterdoctor.check
Permissions are disclosures, not an operating-system sandbox. A plugin runs as the current user and can perform anything allowed to that user. Installation is explicit, remote ZIPs require SHA-256, and newly installed third-party plugins remain disabled until plugin enable records explicit approval.