# Cross-Host Plugin Manifest Architecture for Claude Code, Codex, Factory Droid, and Pi

> Discover the cross-host plugin manifest architecture for Claude Code, Codex, Factory Droid, and Pi. This unified system streamlines skill consumption across multiple platforms from a single source.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: architecture
- Published: 2026-09-09

---

**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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/plugin.json) manifests:

- **Claude Code**: [`.claude-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.claude-plugin/plugin.json)
- **Codex**: [`.codex-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.codex-plugin/plugin.json)
- **Factory Droid**: [`.factory-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/.claude-plugin/plugin.json), [`.codex-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.codex-plugin/plugin.json), and [`.factory-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.factory-plugin/plugin.json). Running this script ensures that the version metadata never drifts between hosts during releases.

```python

# 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`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-plugin-package.py) to enforce manifest integrity. This script performs two critical validations: it checks that all three [`plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/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.

```bash

# 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`](https://github.com/cathrynlavery/diagram-design/blob/main/.claude-plugin/plugin.json), [`.codex-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.codex-plugin/plugin.json), and [`.factory-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.factory-plugin/plugin.json), ensuring uniform marketplace presentation.

```json
{
  "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`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/profiles.md). These profiles allow users to maintain custom [`style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/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 identical [`plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/plugin.json) manifests 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`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/bump-plugin-version.py), which atomically updates all three manifests, while [`scripts/verify-plugin-package.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-plugin-package.py) prevents 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`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) entries, eliminating the need for a [`.pi-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.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`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/.claude-plugin/plugin.json), [`.codex-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.codex-plugin/plugin.json), and [`.factory-plugin/plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/.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`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) serving as the canonical entry point that each host manifest references. Because every host's [`plugin.json`](https://github.com/cathrynlavery/diagram-design/blob/main/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`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/profiles.md). Users can create custom [`style-guide.md`](https://github.com/cathrynlavery/diagram-design/blob/main/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.