Skill Installation¶
Skills from the opendatahub-io/skills-registry are pre-installed into every runner and sandbox image at build time. Each harness (Claude Code, OpenCode, Codex) uses a different installation mechanism that matches the tool's native plugin system.
Claude Code: plugin seed¶
Claude Code images use the official plugin seed mechanism. At build time, native CLI commands populate a seed directory that Claude Code reads at startup without re-cloning anything.
Build-time flow¶
The Containerfile runs two steps as the non-root user:
RUN git config --global url."https://github.com/".insteadOf "git@github.com:" \
&& export CLAUDE_CODE_PLUGIN_CACHE_DIR=/home/agent-ci/.claude-seed \
&& export DISABLE_AUTOUPDATER=1 \
&& claude plugin marketplace add opendatahub-io/skills-registry \
&& agentic-ci install-plugins \
&& git config --global --unset-all url."https://github.com/".insteadOf
claude plugin marketplace add— registers the skills-registry marketplace and clones it into the seed directory.agentic-ci install-plugins— reads the marketplace.json, callsclaude plugin install <name>@<marketplace>for each plugin, and generates the plugin-skills manifest.
The git config override forces HTTPS cloning since the container has no
SSH keys. It is removed at the end of the same RUN layer so the final
image has clean git config.
Runtime¶
Two environment variables control plugin loading:
| Variable | Purpose |
|---|---|
CLAUDE_CODE_PLUGIN_SEED_DIR |
Points to the pre-built seed directory. Claude Code reads it on startup (read-only, no auto-updates). |
CLAUDE_CODE_SYNC_PLUGIN_INSTALL |
Set to 1. Required for skills to load synchronously in non-interactive (-p) mode. |
Seed directory structure¶
~/.claude-seed/
known_marketplaces.json
installed_plugins.json
marketplaces/
opendatahub-skills/ # full git clone of skills-registry
.claude-plugin/
marketplace.json
cache/
opendatahub-skills/
odh-git/0.1.0/ # plugins/odh-git subdirectory (git-subdir source)
skills/git-shallow-clone/
SKILL.md
code-review-skills/0.1.0/
skills/gitlab-code-review/
SKILL.md
scripts/review.py
...
OpenCode: file-based skill discovery¶
OpenCode has no native marketplace or seed mechanism. It discovers skills
by scanning directories for SKILL.md files. The build copies skill
directories from each plugin repo into OpenCode's global skills path.
Build-time flow¶
RUN git clone --depth 1 --quiet https://github.com/opendatahub-io/skills-registry.git /tmp/skills-registry \
&& agentic-ci install-plugins --harness opencode \
--marketplace-json /tmp/skills-registry/.claude-plugin/marketplace.json \
&& rm -rf /tmp/skills-registry
agentic-ci install-plugins --harness opencode reads the marketplace.json, then for each plugin:
- Clones the plugin's source repo.
- Copies skill directories to
~/.config/opencode/skills/. Uses explicitskillspaths from the marketplace entry when present (e.g."skills": ["./.claude/skills"]forrhoai-security-reviewer), otherwise falls back to standard paths (.claude/skills/,.agents/skills/,.opencode/skills/,skills/). The.agents/skills/fallback applies to OpenCode installs as well as Codex compatibility installs. - Records the plugin→skill mapping in the plugin-skills manifest.
Skills directory structure¶
~/.config/opencode/skills/
git-shallow-clone/
SKILL.md
code-review/
SKILL.md
gitlab-code-review/
SKILL.md
scripts/review.py
...
All skills are flat in one directory — no plugin namespacing. OpenCode
discovers them by scanning for SKILL.md files.
Codex: native plugins with legacy compatibility¶
Codex has a native plugin and marketplace system. At build time,
agentic-ci install-plugins --harness codex --marketplace-json <path> adds the
marketplace with codex plugin marketplace add, installs its native Codex
plugins, and records their bundled skills in the plugin-skills manifest.
The existing skills registry also contains legacy Claude-compatible
marketplaces whose packages do not yet include Codex plugin manifests. If
Codex reports no native packages for such a marketplace, agentic-ci clones the
entries and installs their skills under $CODEX_HOME/skills.
The marketplace clone is kept in the image at
$CODEX_HOME/marketplaces/skills-registry. Codex records it as a local
marketplace source, and codex plugin list (which enable-plugins runs at
container start) fails if that directory is missing. The manifest records the
install path that codex plugin add --json reports, because
codex plugin list --json does not include one.
agentic-ci does not yet provide an images/runner/codex image. Codex runner
images are user-supplied through --image or CODEX_CONTAINER_IMAGE and must
include the codex binary until that directory exists.
Plugin-skills manifest¶
Both install scripts generate a manifest at
/usr/local/share/agentic-ci/plugin-skills.manifest.json that maps
plugin names to the skills they contain:
{
"odh-git": ["aipcc-commit-suggest", "gist-upload", "git-shallow-clone", ...],
"code-review-skills": ["gitlab-code-review"],
"rfe-creator": ["rfe.create", "rfe.review", ...]
}
Each entry lists the skills the harness actually loads from that plugin,
not every SKILL.md in its repository:
- Claude Code: the direct children of the plugin's
skills/directory, plus the paths declared by the marketplace entry or.claude-plugin/plugin.json. Symlinks are followed inside the plugin. - Codex native plugins: the
skillspaths from the plugin manifest, orskills/when it declares none, searched recursively. - OpenCode and the Codex compatibility layer: the skills copied into the skills directory.
Plugins that provide no skills are left out.
For Claude Code, the manifest is informational (debugging, auditing).
For OpenCode and Codex, the manifest is functional — enable-plugins uses it
to apply per-skill filtering at runtime (see below).
Filtering plugins at runtime¶
The AGENT_ENABLED_PLUGINS environment variable controls which plugins
are active. If unset, all plugins are enabled. If set to a
comma-separated list of plugin names, only those plugins are active.
# Enable only odh-git — all other plugins are disabled
AGENT_ENABLED_PLUGINS=odh-git agentic-ci run "do something" ...
# Enable two plugins
AGENT_ENABLED_PLUGINS=odh-git,code-review-skills agentic-ci run ...
The ODH AI Helpers skills ship as focused odh-* plugins (odh-git,
odh-jira, odh-python-packaging, ...). The deprecated odh-ai-helpers
umbrella that re-exports them under the old odh-ai-helpers:* names only
works under Claude Code: its skills are symlinks, which the OpenCode and
Codex installs skip. Enable the odh-* plugins you need instead.
How filtering works¶
The enable-plugins script runs at container startup (called by
entrypoint.sh for Podman, or by the env script for OpenShell). It
reads AGENT_ENABLED_PLUGINS and AGENT_TOOL to decide which mechanism
to use:
Claude Code (AGENT_TOOL=claude): Sets enabledPlugins entries to
false in ~/.claude/settings.json for unwanted plugins. Claude Code
reads this at startup and skips disabled plugins.
OpenCode (AGENT_TOOL=opencode): Reads the plugin-skills manifest
to find which skills belong to unwanted plugins, then removes unwanted skill
directories from the ephemeral runtime filesystem before OpenCode starts.
Codex (AGENT_TOOL=codex): Uses codex plugin list/remove for native
plugins and removes only manifest-managed compatibility skills for unwanted
plugins from $CODEX_HOME/skills. Personal skills that are not managed by the
manifest are left intact.
Error handling¶
If a requested plugin name doesn't match any installed plugin, the script exits with an error and reports which names were unmatched:
Under OpenCode and the Codex skills compatibility layer, a plugin that installed no skills is unknown too, since skills are all they install. Claude Code and native Codex plugins can also carry MCP servers, hooks or agents, so there an enabled plugin with no skills in the manifest only prints a warning:
Plugins without skills¶
The image build ends with one line naming every marketplace plugin that installed no skills, whether its install failed, its skills path no longer exists, or (OpenCode) its skill names collide with a plugin installed earlier:
MCP-only plugins and bundles such as pf-mcp and patternfly are expected
here. Anything else usually means the skills-registry entry needs fixing.
CLI subcommands¶
Plugin installation and filtering are agentic-ci subcommands
(implemented in src/agentic_ci/plugins.py):
| Command | When | Purpose |
|---|---|---|
agentic-ci install-plugins |
Build time | Install plugins for Claude Code (reads seed dir), OpenCode, or Codex (--marketplace-json <path>) |
agentic-ci enable-plugins |
Runtime | Filter active plugins based on AGENT_ENABLED_PLUGINS |
The container entrypoint (images/runner/shared/entrypoint.sh) calls
agentic-ci enable-plugins at startup. For OpenShell sandboxes, the env
script calls it before the agent runs.
Adding skills without rebuilding¶
Mount a directory containing SKILL.md files and point Claude Code at it:
podman run --rm \
-v ./my-skills:/opt/extra-skills:ro \
-e CLAUDE_CODE_PLUGIN_SEED_DIR=/opt/extra-skills \
quay.io/aipcc/agentic-ci/claude-runner:latest
For OpenCode, mount into the skills directory directly: