skills/docs/emes-conversion-guide.md
dan a84066c1dd docs: add ADR-005 for dual-publish plugin architecture
Captures the decision to maintain both:
- Nix deployment (cross-agent: Gemini, OpenCode)
- Claude plugin system (hooks, marketplace)

Documents trade-offs, consequences, and mitigations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 11:44:15 -08:00

3.7 KiB

Dual-Publish Plugin Conversion Guide

Converting skills to support both Nix deployment (cross-agent) AND Claude plugin system.

Architecture Decision: See ADR-005 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 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

{
  "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/<name>.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:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "check-review-status.sh"
          }
        ]
      }
    ]
  }
}

Testing

# 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/<name>.md

This allows skills to work in both environments.