Cross-Host Plugin Manifest Architecture for Claude Code, Codex, Factory Droid, and Pi
The diagram-design repository implements a unified cross-host plugin manifest architecture that allows Claude Code, Codex, Factory Droid, and Pi to consume the same skill through host-specific hidden manifest directories while maintaining a single source of truth in skills/diagram-design/.
The cathrynlavery/diagram-design repository solves the challenge of distributing a single skill across multiple AI coding hosts by employing a shared root directory with synchronized host-specific manifests. This architecture eliminates code duplication while ensuring each host can discover and load the plugin through its native mechanism. The implementation relies on hidden configuration directories and automated version management scripts to keep all manifests consistent, as documented in ADR 0008.
Core Architecture Principles
Single Skill Root Directory
All host-specific commands, assets, and reference files live under skills/diagram-design/. The file skills/diagram-design/SKILL.md serves as the canonical entry point that every host references when loading the plugin. This centralized structure ensures that updates to commands or documentation propagate immediately to all supported hosts without requiring file synchronization across multiple directories.
Host-Specific Manifest Directories
Three of the four hosts require dedicated hidden directories containing identical plugin.json manifests:
- Claude Code:
.claude-plugin/plugin.json - Codex:
.codex-plugin/plugin.json - Factory Droid:
.factory-plugin/plugin.json
Each manifest contains the same metadata fields including identity, description, version, author, repository, and keywords. These JSON files point back to the shared skill root, allowing each host to locate skills/diagram-design/ while maintaining their own installation metadata.
Pi Discovery Mechanism
Pi operates differently from the other hosts by treating the repository root as a package and discovering the skill via the skills/ folder without requiring a hidden manifest. When users run pi install <clone-path>, Pi automatically scans for skill directories and loads the configuration from SKILL.md. This design eliminates the need for a .pi-plugin directory while maintaining compatibility with the shared architecture.
Manifest Synchronization Strategy
Automated Version Bumping
The repository uses scripts/bump-plugin-version.py to synchronize version numbers across all three host manifests simultaneously. This Python script reads the current version from one manifest, increments it according to semantic versioning rules (patch, minor, or major), and writes the identical new version to .claude-plugin/plugin.json, .codex-plugin/plugin.json, and .factory-plugin/plugin.json. Running this script ensures that the version metadata never drifts between hosts during releases.
# Conceptual implementation based on bump-plugin-version.py
import json
import pathlib
def bump_version(version: str, part: str) -> str:
major, minor, patch = map(int, version.split('.'))
if part == "major":
major += 1; minor = 0; patch = 0
elif part == "minor":
minor += 1; patch = 0
else: # patch
patch += 1
return f"{major}.{minor}.{patch}"
root = pathlib.Path('.')
manifest_paths = [
root / '.claude-plugin' / 'plugin.json',
root / '.codex-plugin' / 'plugin.json',
root / '.factory-plugin' / 'plugin.json',
]
# Update all manifests atomically
with open(manifest_paths[0]) as f:
current = json.load(f)['version']
new_version = bump_version(current, 'minor')
for path in manifest_paths:
with open(path, 'r+') as f:
data = json.load(f)
data['version'] = new_version
f.seek(0)
json.dump(data, f, indent=2)
f.truncate()
CI Verification Gates
The continuous integration pipeline runs scripts/verify-plugin-package.py to enforce manifest integrity. This script performs two critical validations: it checks that all three plugin.json files contain identical version numbers, and it verifies that pull request authors have not manually modified manifest versions using the --require-no-bump flag. If a PR contains version changes, the CI gate rejects the submission, ensuring that only the automated release process can modify version metadata.
# CI pipeline verification step
python3 scripts/verify-plugin-package.py --require-no-bump origin/main
Implementation Details
Manifest JSON Structure
Each host manifest follows an identical schema that defines the plugin metadata. The name, displayName, and description fields remain consistent across .claude-plugin/plugin.json, .codex-plugin/plugin.json, and .factory-plugin/plugin.json, ensuring uniform marketplace presentation.
{
"name": "diagram-design",
"displayName": "Diagram Design",
"description": "Editorial-quality diagram generator",
"version": "2.5.0",
"author": "cathrynlavery",
"repository": "https://github.com/cathrynlavery/diagram-design",
"license": "MIT",
"keywords": ["diagram", "svg", "html"]
}
Command Exposure
Slash commands such as /export-diagram and /import-mermaid are defined once in the commands/ folder within skills/diagram-design/. Because each host's manifest points to the same skill root directory, these commands become automatically available across Claude Code, Codex, Factory Droid, and Pi without requiring host-specific command definitions. This single-source approach eliminates maintenance overhead when adding new functionality.
Client Profile Isolation
The architecture supports host-specific customization through client profiles stored in skills/diagram-design/references/profiles.md. These profiles allow users to maintain custom style-guide.md configurations without modifying the shared skill files. Because profiles live outside the plugin directory structure, updates to the core skill never overwrite user customizations, preserving a clean separation between shared code and personal preferences.
Summary
- The architecture uses host-specific hidden directories (
.claude-plugin,.codex-plugin,.factory-plugin) containing identicalplugin.jsonmanifests to satisfy each host's discovery mechanism while sharing a single skill root. - Pi uniquely discovers the skill by scanning the repository's
skills/folder without requiring a hidden manifest directory. - Version synchronization is enforced by
scripts/bump-plugin-version.py, which atomically updates all three manifests, whilescripts/verify-plugin-package.pyprevents manual version drift in pull requests. - Commands are defined once in
skills/diagram-design/commands/and exposed to all hosts through the shared root directory structure. - Client profiles enable per-host customization without risking overwrite during skill updates, storing user preferences separately from core plugin files.
Frequently Asked Questions
Why does Pi not require a hidden manifest directory like the other hosts?
Pi implements a repository-scanning discovery mechanism that treats the repository root as a package and automatically locates skill directories within the skills/ folder. Unlike Claude Code, Codex, and Factory Droid—which require explicit manifest files to register plugins—Pi identifies valid skills by detecting SKILL.md entries, eliminating the need for a .pi-plugin/plugin.json file while maintaining full compatibility with the shared architecture.
How does the repository prevent version numbers from drifting between host manifests?
The repository employs scripts/bump-plugin-version.py to perform atomic version updates across all three manifest files simultaneously during the release process. Additionally, the CI pipeline runs scripts/verify-plugin-package.py --require-no-bump on every pull request to reject any manual modifications to version fields, ensuring that only the automated release workflow can increment versions and guaranteeing strict synchronization between .claude-plugin/plugin.json, .codex-plugin/plugin.json, and .factory-plugin/plugin.json.
Where are the actual skill commands defined for cross-host consumption?
All commands reside in the commands/ subdirectory within skills/diagram-design/, with skills/diagram-design/SKILL.md serving as the canonical entry point that each host manifest references. Because every host's plugin.json points to the same skill root directory, slash commands like /export-diagram become immediately available across Claude Code, Codex, Factory Droid, and Pi without requiring duplicate command definitions in host-specific locations.
Can users customize plugin behavior for individual hosts without modifying shared files?
Yes, the architecture supports host-specific customization through client profiles documented in skills/diagram-design/references/profiles.md. Users can create custom style-guide.md files and other configurations that reside outside the core plugin directory structure, ensuring that updates to the shared skill files never overwrite personal settings while allowing each host to load appropriate customizations during initialization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →