Claude Code Plugins

Community-maintained marketplace

Feedback

Plugin Manifest Sync

@epieczko/betty
0
0

Reconcile plugin.yaml with Betty Framework registries

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name Plugin Manifest Sync
description Reconcile plugin.yaml with Betty Framework registries

docs.sync.plugin_manifest

Overview

docs.sync.plugin_manifest is a validation and reconciliation tool that compares plugin.yaml against Betty Framework's registry files to ensure consistency and completeness. It identifies missing commands, orphaned entries, metadata mismatches, and suggests corrections.

Purpose

Ensures synchronization between:

  • Skill Registry (registry/skills.json) – Active skills with entrypoints
  • Command Registry (registry/commands.json) – Slash commands
  • Plugin Configuration (plugin.yaml) – Claude Code plugin manifest

This skill helps maintain plugin.yaml accuracy by detecting:

  • Active skills missing from plugin.yaml
  • Orphaned commands in plugin.yaml not found in registries
  • Metadata inconsistencies (permissions, runtime, handlers)
  • Missing metadata that should be added

What It Does

  1. Loads Registries: Reads skills.json and commands.json
  2. Loads Plugin: Reads current plugin.yaml
  3. Builds Indexes: Creates lookup tables for both registries and plugin
  4. Compares Entries: Identifies missing, orphaned, and mismatched commands
  5. Analyzes Metadata: Checks permissions, runtime, handlers, descriptions
  6. Generates Preview: Creates plugin.preview.yaml with suggested updates
  7. Creates Report: Outputs plugin_manifest_diff.md with detailed analysis
  8. Provides Summary: Displays key findings and recommendations

Usage

Basic Usage

python skills/docs.sync.plugin_manifest/plugin_manifest_sync.py

No arguments required - reads from standard locations.

Via Betty CLI

/docs/sync/plugin-manifest

Expected File Structure

betty/
├── registry/
│   ├── skills.json      # Source of truth for skills
│   └── commands.json    # Source of truth for commands
├── plugin.yaml          # Current plugin manifest
├── plugin.preview.yaml  # Generated preview (output)
└── plugin_manifest_diff.md  # Generated report (output)

Behavior

1. Registry Loading

Reads and parses:

  • registry/skills.json – All registered skills
  • registry/commands.json – All registered commands

Only processes entries with status: active.

2. Plugin Loading

Reads and parses:

  • plugin.yaml – Current plugin configuration

Extracts all command definitions.

3. Index Building

Registry Index: Maps command names to their registry sources

{
  "skill/define": {
    "type": "skill",
    "source": "skill.define",
    "skill": {...},
    "entrypoint": {...}
  },
  "api/validate": {
    "type": "skill",
    "source": "api.validate",
    "skill": {...},
    "entrypoint": {...}
  }
}

Plugin Index: Maps command names to plugin entries

{
  "skill/define": {
    "name": "skill/define",
    "handler": {...},
    "permissions": [...]
  }
}

4. Comparison Analysis

Performs four types of checks:

Missing Commands

Commands in registry but not in plugin.yaml:

- skill/create (active in registry, missing from plugin)
- api/validate (active in registry, missing from plugin)

Orphaned Commands

Commands in plugin.yaml but not in registry:

- old/deprecated (in plugin but not registered)
- test/removed (in plugin but removed from registry)

Metadata Mismatches

Commands present in both but with different metadata:

Runtime Mismatch:

- skill/define:
  - Registry: python
  - Plugin: node

Permission Mismatch:

- api/validate:
  - Missing: filesystem:read
  - Extra: network:write

Handler Mismatch:

- skill/create:
  - Registry: skills/skill.create/skill_create.py
  - Plugin: skills/skill.create/old_handler.py

Description Mismatch:

- agent/run:
  - Registry: "Execute a Betty agent..."
  - Plugin: "Run agent"

Missing Metadata Suggestions

Identifies registry entries missing recommended metadata:

- hook/define: Consider adding permissions metadata
- test/skill: Consider adding description

5. Preview Generation

Creates plugin.preview.yaml by:

  • Taking all active commands from registries
  • Converting to plugin.yaml format
  • Including all metadata from registries
  • Adding generation timestamp
  • Preserving existing plugin metadata (author, license, etc.)

6. Report Generation

Creates plugin_manifest_diff.md with:

  • Executive summary
  • Lists of missing commands
  • Lists of orphaned commands
  • Detailed metadata issues
  • Metadata suggestions

Outputs

Success Response

{
  "ok": true,
  "status": "success",
  "preview_path": "/home/user/betty/plugin.preview.yaml",
  "report_path": "/home/user/betty/plugin_manifest_diff.md",
  "reconciliation": {
    "missing_commands": [...],
    "orphaned_commands": [...],
    "metadata_issues": [...],
    "metadata_suggestions": [...],
    "total_registry_commands": 19,
    "total_plugin_commands": 18
  }
}

Console Output

============================================================
PLUGIN MANIFEST RECONCILIATION COMPLETE
============================================================

📊 Summary:
  - Commands in registry: 19
  - Commands in plugin.yaml: 18
  - Missing from plugin.yaml: 2
  - Orphaned in plugin.yaml: 1
  - Metadata issues: 3
  - Metadata suggestions: 2

📄 Output files:
  - Preview: /home/user/betty/plugin.preview.yaml
  - Diff report: /home/user/betty/plugin_manifest_diff.md

⚠️  2 command(s) missing from plugin.yaml:
    - registry/query (registry.query)
    - hook/simulate (hook.simulate)

⚠️  1 orphaned command(s) in plugin.yaml:
    - old/deprecated

✅ Review plugin_manifest_diff.md for full details
============================================================

Failure Response

{
  "ok": false,
  "status": "failed",
  "error": "Failed to parse JSON from registry/skills.json"
}

Generated Files

plugin.preview.yaml

Updated plugin manifest with all active registry commands:

# Betty Framework - Claude Code Plugin (Preview)
# Generated by docs.sync.plugin_manifest skill
# Review changes before applying to plugin.yaml

name: betty-framework
version: 1.0.0
description: Betty Framework - Structured AI-assisted engineering
author:
  name: RiskExec
  email: platform@riskexec.com
  url: https://github.com/epieczko/betty
license: MIT

metadata:
  generated_at: "2025-10-23T20:00:00.000000+00:00"
  generated_by: docs.sync.plugin_manifest skill
  command_count: 19

commands:
  - name: skill/define
    description: Validate a Claude Code skill manifest
    handler:
      runtime: python
      script: skills/skill.define/skill_define.py
    parameters:
      - name: manifest_path
        type: string
        required: true
        description: Path to skill.yaml file
    permissions:
      - filesystem:read
      - filesystem:write

  # ... more commands ...

plugin_manifest_diff.md

Detailed reconciliation report:

# Plugin Manifest Reconciliation Report
Generated: 2025-10-23T20:00:00.000000+00:00

## Summary
- Total commands in registry: 19
- Total commands in plugin.yaml: 18
- Missing from plugin.yaml: 2
- Orphaned in plugin.yaml: 1
- Metadata issues: 3
- Metadata suggestions: 2

## Missing Commands (in registry but not in plugin.yaml)
- **registry/query** (skill: registry.query)
- **hook/simulate** (skill: hook.simulate)

## Orphaned Commands (in plugin.yaml but not in registry)
- **old/deprecated**

## Metadata Issues
- **skill/create**: Permissions Mismatch
  - Missing: process:execute
  - Extra: network:http
- **api/validate**: Handler Mismatch
  - Registry: `skills/api.validate/api_validate.py`
  - Plugin: `skills/api.validate/validator.py`
- **agent/run**: Runtime Mismatch
  - Registry: `python`
  - Plugin: `node`

## Metadata Suggestions
- **hook/define** (permissions): Consider adding permissions metadata
- **test/skill** (description): Consider adding description

Examples

Example 1: Routine Sync Check

Scenario: Regular validation after making registry changes

# Make some registry updates
/skill/define skills/new.skill/skill.yaml

# Check for discrepancies
/docs/sync/plugin-manifest

# Review the report
cat plugin_manifest_diff.md

# If changes look good, apply them
cp plugin.preview.yaml plugin.yaml

Output:

============================================================
PLUGIN MANIFEST RECONCILIATION COMPLETE
============================================================

📊 Summary:
  - Commands in registry: 20
  - Commands in plugin.yaml: 19
  - Missing from plugin.yaml: 1
  - Orphaned in plugin.yaml: 0
  - Metadata issues: 0
  - Metadata suggestions: 0

⚠️  1 command(s) missing from plugin.yaml:
    - new/skill (new.skill)

✅ Review plugin_manifest_diff.md for full details

Example 2: Detecting Orphaned Commands

Scenario: A skill was removed from registry but command remains in plugin.yaml

# Remove skill from registry
rm -rf skills/deprecated.skill/

# Run reconciliation
/docs/sync/plugin-manifest

# Check report
cat plugin_manifest_diff.md

Output:

============================================================
PLUGIN MANIFEST RECONCILIATION COMPLETE
============================================================

📊 Summary:
  - Commands in registry: 18
  - Commands in plugin.yaml: 19
  - Missing from plugin.yaml: 0
  - Orphaned in plugin.yaml: 1
  - Metadata issues: 0
  - Metadata suggestions: 0

⚠️  1 orphaned command(s) in plugin.yaml:
    - deprecated/skill

✅ Review plugin_manifest_diff.md for full details

Example 3: Finding Metadata Mismatches

Scenario: Registry was updated but plugin.yaml wasn't synced

# Update skill permissions in registry
/skill/define skills/api.validate/skill.yaml

# Check for differences
/docs/sync/plugin-manifest

# Review specific mismatches
grep -A 5 "Metadata Issues" plugin_manifest_diff.md

Report Output:

## Metadata Issues
- **api/validate**: Permissions Mismatch
  - Missing: network:http
  - Extra: filesystem:write

Example 4: Pre-Commit Validation

Scenario: Validate plugin.yaml before committing changes

# Before committing
/docs/sync/plugin-manifest

# If discrepancies found, fix them
if [ $? -eq 0 ]; then
  # Review and apply changes
  diff plugin.yaml plugin.preview.yaml
  cp plugin.preview.yaml plugin.yaml
fi

# Commit changes
git add plugin.yaml
git commit -m "Sync plugin.yaml with registries"

Example 5: CI/CD Integration

Scenario: Automated validation in CI pipeline

# .github/workflows/validate-plugin.yml
name: Validate Plugin Manifest

on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Reconcile Plugin Manifest
        run: |
          python skills/docs.sync.plugin_manifest/plugin_manifest_sync.py

          # Check if there are discrepancies
          if grep -q "Missing from plugin.yaml: [1-9]" plugin_manifest_diff.md; then
            echo "❌ Plugin manifest has missing commands"
            cat plugin_manifest_diff.md
            exit 1
          fi

          if grep -q "Orphaned in plugin.yaml: [1-9]" plugin_manifest_diff.md; then
            echo "❌ Plugin manifest has orphaned commands"
            cat plugin_manifest_diff.md
            exit 1
          fi

          echo "✅ Plugin manifest is in sync"

Integration

With plugin.sync

Use reconciliation to verify before syncing:

# Check current state
/docs/sync/plugin-manifest

# Review differences
cat plugin_manifest_diff.md

# If satisfied, run full sync
/plugin/sync

With skill.define

Validate after defining skills:

# Define new skill
/skill/define skills/my.skill/skill.yaml

# Check plugin consistency
/docs/sync/plugin-manifest

# Apply changes if needed
cp plugin.preview.yaml plugin.yaml

With Hooks

Auto-check on registry changes:

# .claude/hooks.yaml
- event: on_file_save
  pattern: "registry/*.json"
  command: python skills/docs.sync.plugin_manifest/plugin_manifest_sync.py
  blocking: false
  description: Check plugin manifest sync when registries change

With Workflows

Include in skill lifecycle workflow:

# workflows/update_plugin.yaml
steps:
  - skill: skill.define
    args: ["skills/new.skill/skill.yaml"]

  - skill: docs.sync.plugin_manifest
    args: []

  - skill: plugin.sync
    args: []

What Gets Reported

✅ Detected Issues

  • Active skills missing from plugin.yaml
  • Orphaned commands in plugin.yaml
  • Runtime mismatches (python vs node)
  • Permission mismatches (missing or extra)
  • Handler path mismatches
  • Description mismatches
  • Missing metadata (permissions, descriptions)

❌ Not Detected

  • Draft/inactive skills (intentionally excluded)
  • Malformed YAML syntax (causes failure)
  • Handler file existence (use plugin.sync for that)
  • Parameter schema validation

Common Use Cases

Use Case When to Use
Pre-commit check Before committing plugin.yaml changes
Post-registry update After adding/updating skills in registry
CI/CD validation Automated pipeline checks
Manual audit Periodic manual review of plugin state
Debugging When commands aren't appearing as expected
Migration After major registry restructuring

Common Errors

Error Cause Solution
"Failed to parse JSON" Invalid JSON in registry Fix JSON syntax in registry files
"Failed to parse YAML" Invalid YAML in plugin.yaml Fix YAML syntax in plugin.yaml
"Registry file not found" Missing registry files Ensure registries exist in registry/
"Permission denied" Cannot write output files Check write permissions on directory
All commands missing Empty or invalid registries Verify registry files are populated

Files Read

  • registry/skills.json – Skill registry (source of truth)
  • registry/commands.json – Command registry (source of truth)
  • plugin.yaml – Current plugin manifest (for comparison)

Files Generated

  • plugin.preview.yaml – Updated plugin manifest preview
  • plugin_manifest_diff.md – Detailed reconciliation report

Exit Codes

  • 0: Success (reconciliation completed successfully)
  • 1: Failure (error during reconciliation)

Note: Discrepancies found are reported but don't cause failure (exit 0). Only parsing errors or system failures cause exit 1.

Logging

Logs reconciliation progress:

INFO: Starting plugin manifest reconciliation...
INFO: Loading registry files...
INFO: Loading plugin.yaml...
INFO: Building registry index...
INFO: Building plugin index...
INFO: Comparing registries with plugin.yaml...
INFO: Reconciling registries with plugin.yaml...
INFO: Generating updated plugin.yaml...
INFO: ✅ Written file to /home/user/betty/plugin.preview.yaml
INFO: Generating diff report...
INFO: ✅ Written diff report to /home/user/betty/plugin_manifest_diff.md

Best Practices

  1. Run Before Committing: Always check sync status before committing plugin.yaml
  2. Review Diff Report: Read the full report to understand all changes
  3. Validate Preview: Review plugin.preview.yaml before applying
  4. Include in CI: Add validation to your CI/CD pipeline
  5. Regular Audits: Run periodic checks even without changes
  6. Address Orphans: Remove orphaned commands promptly
  7. Fix Mismatches: Resolve metadata mismatches to maintain consistency
  8. Keep Registries Clean: Mark inactive skills as draft instead of deleting

Workflow Integration

Recommended Workflow

# 1. Define or update skills
/skill/define skills/my.skill/skill.yaml

# 2. Check for discrepancies
/docs/sync/plugin-manifest

# 3. Review the report
cat plugin_manifest_diff.md

# 4. Review the preview
diff plugin.yaml plugin.preview.yaml

# 5. Apply changes if satisfied
cp plugin.preview.yaml plugin.yaml

# 6. Commit changes
git add plugin.yaml registry/
git commit -m "Update plugin manifest"

Alternative: Auto-Sync Workflow

# 1. Define or update skills
/skill/define skills/my.skill/skill.yaml

# 2. Run full sync (overwrites plugin.yaml)
/plugin/sync

# 3. Validate the result
/docs/sync/plugin-manifest

# 4. If clean, commit
git add plugin.yaml registry/
git commit -m "Update plugin manifest"

Troubleshooting

Plugin.yaml Shows as Out of Sync

Problem: Reconciliation reports missing or orphaned commands

Solutions:

  1. Run /plugin/sync to regenerate plugin.yaml from registries
  2. Review and apply plugin.preview.yaml manually
  3. Check if skills are marked as active in registry
  4. Verify skills have entrypoints defined

Metadata Mismatches Reported

Problem: Registry and plugin have different permissions/runtime/handlers

Solutions:

  1. Update skill.yaml with correct metadata
  2. Run /skill/define to register changes
  3. Run /docs/sync/plugin-manifest to verify
  4. Apply plugin.preview.yaml or run /plugin/sync

Orphaned Commands Found

Problem: Commands in plugin.yaml not found in registry

Solutions:

  1. Check if skill was removed from registry
  2. Verify skill status is active in registry
  3. Re-register the skill if it should exist
  4. Remove from plugin.yaml if intentionally deprecated

Preview File Not Generated

Problem: plugin.preview.yaml missing after running skill

Solutions:

  1. Check write permissions on betty/ directory
  2. Verify registries are readable
  3. Check logs for errors
  4. Ensure plugin.yaml exists and is valid

Architecture

Skill Category

Documentation & Infrastructure – Maintains consistency between registry and plugin configuration layers.

Design Principles

  • Non-Destructive: Never modifies plugin.yaml directly
  • Comprehensive: Reports all types of discrepancies
  • Actionable: Provides preview file ready to apply
  • Transparent: Detailed report explains all findings
  • Idempotent: Can be run multiple times safely

See Also

  • plugin.sync – Generate plugin.yaml from registries (SKILL.md)
  • skill.define – Validate and register skills (SKILL.md)
  • registry.update – Update skill registry (SKILL.md)
  • Betty Architecture – Framework overview (betty-architecture.md)

Dependencies

  • plugin.sync: Plugin generation infrastructure
  • registry.update: Registry management
  • betty.config: Configuration constants and paths
  • betty.logging_utils: Logging infrastructure

Status

Active – Production-ready documentation and validation skill

Version History

  • 0.1.0 (Oct 2025) – Initial implementation with full reconciliation, preview generation, and diff reporting