# Dual-Publish Plugin Conversion Guide Converting skills to support both Nix deployment (cross-agent) AND Claude plugin system. > **Architecture Decision:** See [ADR-005](adr/005-dual-publish-plugin-architecture.md) for rationale. ## Why Dual-Publish? | System | Pros | Cons | |--------|------|------| | **Our Nix system** | Cross-agent (Gemini, OpenCode), system-level | No hooks, manual distribution | | **Claude plugins** | Marketplace, hooks, `/plugin install` UX | Claude Code only | **Decision:** Maintain both. Cross-agent support is important (see skills-bo8). ## Background: emes Architecture The [emes org](https://github.com/evil-mind-evil-sword) builds modular AI agent tools: - **tissue**: Git-native issue tracking (machine-first) - **idle**: Quality gate (blocks exit until reviewer approves) - **jwz**: Async messaging with identity/git context - **marketplace**: Plugin distribution registry ## Key Principles (from emes) 1. **Pull context on-demand** - Don't inject large prompts upfront 2. **Mechanical enforcement** - Use hooks, not prompt instructions 3. **References over inline** - Point to files, don't embed content 4. **Machine-first interfaces** - JSON output, non-interactive ## Dual-Publish Directory Structure **Before (Nix-only):** ``` skills/my-skill/ ├── SKILL.md # Instructions with YAML frontmatter ├── README.md # Human docs └── scripts/ # Supporting scripts (optional) ``` **After (Dual-publish):** ``` skills/my-skill/ ├── .claude-plugin/ │ └── plugin.json # Claude plugin metadata ├── skills/ │ └── my-skill.md # Claude auto-discovery (copy of SKILL.md) ├── hooks/ │ └── hooks.json # Optional Claude lifecycle hooks ├── SKILL.md # Nix deployment (Gemini, OpenCode, etc.) ├── README.md └── scripts/ ``` **Both paths lead to the same skill content:** - Nix: `~/.claude/skills/my-skill/SKILL.md` - Claude plugin: Auto-discovered from `skills/my-skill.md` ## plugin.json Schema ```json { "name": "my-skill", "description": "Brief description", "version": "1.0.0", "author": { "name": "author-name" }, "license": "MIT", "keywords": ["keyword1", "keyword2"], "hooks": { "SessionStart": [...], "PostToolUse": [...] } } ``` ## Conversion Checklist - [ ] Create `.claude-plugin/plugin.json` with metadata - [ ] Copy `SKILL.md` to `skills/.md` - [ ] Add hooks if skill needs lifecycle events - [ ] Keep original `SKILL.md` for Nix deployment - [ ] Test with `/plugin install ./path/to/skill` - [ ] Register in marketplace.json (optional) ## Hook Events Available hook events: - `SessionStart` - On session begin - `SessionEnd` - On session end - `PreToolUse` - Before tool execution - `PostToolUse` - After tool execution - `PreCompact` - Before context compaction - `UserPromptSubmit` - On user message - `Stop` - When agent stops - `SubagentStop` - When subagent stops - `Notification` - On notifications ## Example: Quality Gate (idle pattern) For skills that need review before completion: ```json { "hooks": { "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "check-review-status.sh" } ] } ] } } ``` ## Testing ```bash # Install locally /plugin install ./skills/my-skill # Or add to marketplace and install /plugin marketplace add owner/repo /plugin install my-skill@marketplace-name ``` ## Dual Deployment We maintain both: 1. **Nix deployment** (system-level) - Uses `SKILL.md` at root 2. **Plugin discovery** (Claude Code) - Uses `skills/.md` This allows skills to work in both environments.