Automatically generate plugin.yaml from Betty Framework registries
plugin.sync is the synchronization tool that generates plugin.yaml from Betty Framework's registry files. It ensures that Claude Code's plugin configuration stays in sync with registered skills, commands, and hooks.
Automates the generation of plugin.yaml to maintain consistency between:
registry/skills.json) – Active skills with entrypointsregistry/commands.json) – Slash commandsregistry/hooks.json) – Event-driven hooksplugin.yaml) – Claude Code plugin manifestThis eliminates manual editing of plugin.yaml and prevents drift between what's registered and what's exposed to Claude Code.
skills.json, commands.json, and hooks.jsonstatus: active and defined entrypointsplugin.yaml command formatpython skills/plugin.sync/plugin_sync.py
No arguments required - reads from standard registry locations.
/plugin/sync
The skill expects these registry files:
betty/
├── registry/
│ ├── skills.json # Registered skills
│ ├── commands.json # Registered commands
│ └── hooks.json # Registered hooks
└── plugin.yaml # Generated output
Reads JSON files from:
registry/skills.jsonregistry/commands.jsonregistry/hooks.jsonIf a registry file is missing, logs a warning and continues with available data.
For each skill in skills.json:
status: activeskills/{skill_name}/{handler}Creates a command entry for each active skill entrypoint:
- name: skill/validate
description: Validate a 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
For each handler reference:
skills/{skill_name}/{handler_filename}Preserves existing plugin.yaml metadata:
Replaces the commands section with generated entries.
Writes plugin.yaml with:
{
"ok": true,
"status": "success",
"output_path": "/home/user/betty/plugin.yaml",
"commands_generated": 18,
"warnings": []
}
{
"ok": true,
"status": "success",
"output_path": "/home/user/betty/plugin.yaml",
"commands_generated": 18,
"warnings": [
"Handler not found for 'api.validate': skills/api.validate/api_validate_missing.py",
"Skill 'test.broken' has entrypoint without handler"
]
}
{
"ok": false,
"status": "failed",
"error": "Failed to parse JSON from registry/skills.json: Expecting value: line 1 column 1"
}
The skill generates a plugin.yaml like this:
# Betty Framework - Claude Code Plugin
# Auto-generated by plugin.sync skill
# DO NOT EDIT MANUALLY - Run plugin.sync to regenerate