Claude Code Plugin Compatibility
Wave 8 opened Neo to the Claude Code plugin ecosystem. CC-shaped plugins load and dispatch under Neo without modification; the GitHub installer (/plugins install --from <github-repo>) clones and installs them in one step.
This document describes:
- Which CC manifest fields Neo consumes today vs accepts-but-ignores.
- How to install a CC plugin from GitHub.
- What's intentionally out of scope.
For the general plugin reference (Neo-native plugins, bundled templates, the /plugins command surface), see README.md.
Field handling
| Manifest field | Status in Neo | Notes |
|---|---|---|
name, version, description, author | Consumed | Identity. Same as Neo-native plugins. |
skills | Consumed | Same dispatch as Neo skills (registers via SkillsLoader). |
commands | Consumed | Same dispatch as Neo commands (slash-command registry). |
hooks | Consumed | Same dispatch as Neo hooks (lifecycle handlers). |
mcpServers | Consumed | Same dispatch as Neo MCP servers. |
outputStyles | Consumed | Same dispatch as Neo output styles. |
settings | Consumed | Allowlisted merge into runtime settings. |
agents | Consumed | Wired to Neo's existing delegate runtime (src/tools/delegate.ts, src/runtime/agent-definitions.ts). Conventional agents/<id>.md is auto-detected; explicit agents field in the manifest also supported (single path or array of paths). Plugin-supplied agents are merged with user-level agents from ~/.neo/agents/ at boot; an id collision between the two raises a startup error with both source paths. |
channels | Accepted, not dispatched | Neo has no MCP channel transport. Manifest field survives validation and is available on plugin.manifest.channels if a future wave consumes it. |
lspServers | Accepted, not dispatched | Neo has no LSP integration. |
userConfig | Accepted, not dispatched | Install-time prompts are deferred. The manifest field is preserved on plugin.manifest.userConfig; the values are not surfaced to the user during install. |
dependencies | Accepted, not dispatched | Neo has no plugin-dependency resolver. |
homepage, repository, license, keywords | Accepted, not dispatched | Pure metadata. homepage is intentionally z.string() rather than z.string().url() because real CC plugins ship bare strings ("github.com/foo") without protocol. |
| Any unknown top-level field | Silently stripped | Matches CC behavior (claude-code-src/src/utils/plugins/schemas.ts:884-898, Zod default .strip()). |
Installing a CC plugin from GitHub
/plugins install --from <owner>/<repo>
/plugins install --from <owner>/<repo>/<subdir>Examples:
/plugins install --from anthropics/claude-plugins-official/code-review
/plugins install --from acme/my-pluginBehavior:
- Clones the repo with
git clone --depth=1into a scratch dir under~/.neo/marketplace/<owner>__<repo>/(the scratch dir is wiped on every install — there is no persistent cache). - Reads
plugin.jsonfrom the repo root (or the subdir, if provided) and validates it againstPluginManifestSchema. - Copies the plugin into
~/.neo/plugins/<plugin-name>/(where<plugin-name>is the manifestnamefield, not the repo name). - Appends
<plugin-name>toenabledPluginsin~/.neo/settings.json(deduplicated). - Reports the install path and the source URL.
The plugin is dispatched in-process as part of install (Wave 5 Phase 5) — /plugins list / /plugins status reflect it immediately, no restart required.
Collisions
If <plugin-name> is already installed, --from silently overwrites without requiring --force. The user-facing message announces the overwrite. This matches CC's "settings intent wins" pattern at claude-code-src/src/utils/plugins/marketplaceManager.ts:1873-1875 — when a user explicitly passes a source URL, they have opted in to whatever is at that source. (The bundled-template install path, /plugins install <name> without --from, still requires --force because that path is intended for first-time install of a curated template, not for updates.)
Authentication
Neo uses plain git, not gh. Public repos clone without authentication. For private repos, Neo relies on your ambient git credentials (credential helper, SSH agent, etc.). The clone runs with GIT_TERMINAL_PROMPT=0 and GIT_ASKPASS='' so that a missing credential fails fast instead of hanging the 60-second timeout — make sure your credentials are configured non-interactively (e.g., via the OS credential manager) before installing from a private repo.
Slug rules
Owner and repo names must match /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/ (GitHub's actual naming rules — alphanumeric, hyphen, underscore, dot, with a non-special first character). Subdir paths must not be absolute and must not contain .. (path-traversal guard).
What's intentionally out of scope
- Cowork connectors (
claudeai-proxy-backed services like Anthropic-hosted Google Workspace): closed-source, not portable. ghCLI as the clone backend:gitis universal;ghadds an install dependency many users do not have.- A persistent marketplace cache with TTL /
--refreshflag: scratch-on-every-install is simpler and avoids stale-fork bugs. Re-add if friction emerges. - A real
~/.neo/marketplaces/config with named sources, like CC'smarketplaceManager: deferred. The current--frominstaller takes a one-off URL per invocation. agentsinvocation via the delegate tool from--from-installed plugins: works (the agent gets registered intocreateDelegateTool's available-agents set at boot), but there is no plugin-scoped namespacing of agent ids — a plugin that shipsagents/reviewer.mdwill collide with a user-level~/.neo/agents/reviewer.md. Resolution is "rename one or the other" until namespacing lands in a future wave.
End-to-end verification
The integration test at tests/plugins/cc-compat-integration.test.ts loads five CC-shaped fixture plugins and asserts:
- Each manifest validates with at least one CC-only field present.
- Consumed fields (
agents,commands,hooks,skills) get dispatched into mock subsystem adapters. - Accepted-but-not-dispatched fields (
channels,userConfig,dependencies,homepage,repository,license,keywords) survive onplugin.manifestwithout errors or warnings. - Loading all five together produces no cross-plugin conflict.
The fixtures live under tests/plugins/fixtures/cc-compat/ and are CC-shaped (not real CC plugins — license and maintenance reasons). Real CC plugins from anthropics/claude-plugins-official and similar repos are expected to install and dispatch the same way; user-reported field gaps will be addressed by extending src/plugins/types.ts.