Skip to content

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 fieldStatus in NeoNotes
name, version, description, authorConsumedIdentity. Same as Neo-native plugins.
skillsConsumedSame dispatch as Neo skills (registers via SkillsLoader).
commandsConsumedSame dispatch as Neo commands (slash-command registry).
hooksConsumedSame dispatch as Neo hooks (lifecycle handlers).
mcpServersConsumedSame dispatch as Neo MCP servers.
outputStylesConsumedSame dispatch as Neo output styles.
settingsConsumedAllowlisted merge into runtime settings.
agentsConsumedWired 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.
channelsAccepted, not dispatchedNeo has no MCP channel transport. Manifest field survives validation and is available on plugin.manifest.channels if a future wave consumes it.
lspServersAccepted, not dispatchedNeo has no LSP integration.
userConfigAccepted, not dispatchedInstall-time prompts are deferred. The manifest field is preserved on plugin.manifest.userConfig; the values are not surfaced to the user during install.
dependenciesAccepted, not dispatchedNeo has no plugin-dependency resolver.
homepage, repository, license, keywordsAccepted, not dispatchedPure 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 fieldSilently strippedMatches 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-plugin

Behavior:

  1. Clones the repo with git clone --depth=1 into a scratch dir under ~/.neo/marketplace/<owner>__<repo>/ (the scratch dir is wiped on every install — there is no persistent cache).
  2. Reads plugin.json from the repo root (or the subdir, if provided) and validates it against PluginManifestSchema.
  3. Copies the plugin into ~/.neo/plugins/<plugin-name>/ (where <plugin-name> is the manifest name field, not the repo name).
  4. Appends <plugin-name> to enabledPlugins in ~/.neo/settings.json (deduplicated).
  5. 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.
  • gh CLI as the clone backend: git is universal; gh adds an install dependency many users do not have.
  • A persistent marketplace cache with TTL / --refresh flag: 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's marketplaceManager: deferred. The current --from installer takes a one-off URL per invocation.
  • agents invocation via the delegate tool from --from-installed plugins: works (the agent gets registered into createDelegateTool's available-agents set at boot), but there is no plugin-scoped namespacing of agent ids — a plugin that ships agents/reviewer.md will 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 on plugin.manifest without 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.