Files
gh-epieczko-betty/skills/plugin.build/SKILL.md
2025-11-29 18:26:08 +08:00

733 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: Plugin Build
description: Bundle plugin directory into a deployable Claude Code plugin package
---
# plugin.build
## Overview
**plugin.build** is the packaging tool that bundles your Betty Framework plugin into a distributable archive ready for deployment to Claude Code. It validates all entrypoints, gathers necessary files, and creates versioned packages with checksums.
## Purpose
Automates the creation of deployable plugin packages by:
- **Validating** all declared entrypoints and handler files
- **Gathering** all necessary plugin files (skills, utilities, registries)
- **Packaging** into `.tar.gz` or `.zip` archives
- **Generating** checksums for package verification
- **Reporting** validation results and build metrics
This eliminates manual packaging errors and ensures consistent, reproducible plugin distributions.
## What It Does
1. **Loads plugin.yaml**: Reads the plugin configuration
2. **Validates Entrypoints**: Checks that all command handlers exist on disk
3. **Gathers Files**: Collects skills, utilities, registries, and documentation
4. **Creates Package**: Bundles everything into a versioned archive
5. **Calculates Checksums**: Generates MD5 and SHA256 hashes
6. **Generates Manifest**: Creates manifest.json with entrypoint summary and checksums
7. **Creates Preview**: Generates plugin.preview.yaml for review before deployment
8. **Generates Report**: Outputs detailed build metrics as JSON
9. **Reports Issues**: Identifies missing files or validation errors
## Usage
### Basic Usage
```bash
python skills/plugin.build/plugin_build.py
```
Builds with defaults:
- Plugin: `./plugin.yaml`
- Format: `tar.gz`
- Output: `./dist/`
### Via Betty CLI
```bash
/plugin/build
```
### Custom Plugin Path
```bash
python skills/plugin.build/plugin_build.py /path/to/plugin.yaml
```
### Specify Output Format
```bash
python skills/plugin.build/plugin_build.py --format=zip
```
```bash
python skills/plugin.build/plugin_build.py --format=tar.gz
```
### Custom Output Directory
```bash
python skills/plugin.build/plugin_build.py --output-dir=/tmp/packages
```
### Full Options
```bash
python skills/plugin.build/plugin_build.py \
/custom/path/plugin.yaml \
--format=zip \
--output-dir=/var/packages
```
## Command-Line Arguments
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `plugin_path` | Positional | `./plugin.yaml` | Path to plugin.yaml file |
| `--format` | Option | `tar.gz` | Package format (tar.gz or zip) |
| `--output-dir` | Option | `./dist` | Output directory for packages |
## Output Files
### Package Archive
**Naming convention**: `{plugin-name}-{version}.{format}`
Examples:
- `betty-framework-1.0.0.tar.gz`
- `betty-framework-1.0.0.zip`
**Location**: `{output-dir}/{package-name}.{format}`
### Manifest File
**Naming convention**: `manifest.json`
**Location**: `{output-dir}/manifest.json`
Contains plugin metadata, entrypoint summary, and package checksums. This is the primary file for plugin distribution and installation.
### Plugin Preview
**Naming convention**: `plugin.preview.yaml`
**Location**: `{output-dir}/plugin.preview.yaml`
Contains the current plugin configuration for review before deployment. Useful for comparing changes or validating the plugin structure.
### Build Report
**Naming convention**: `{plugin-name}-{version}-build-report.json`
Example:
- `betty-framework-1.0.0-build-report.json`
**Location**: `{output-dir}/{package-name}-build-report.json`
## Package Structure
The generated archive contains:
```
betty-framework-1.0.0/
├── plugin.yaml # Plugin manifest
├── requirements.txt # Python dependencies
├── README.md # Documentation (if exists)
├── LICENSE # License file (if exists)
├── CHANGELOG.md # Change log (if exists)
├── betty/ # Core utility package
│ ├── __init__.py
│ ├── config.py
│ ├── validation.py
│ ├── logging_utils.py
│ ├── file_utils.py
│ └── errors.py
├── registry/ # Registry files
│ ├── skills.json
│ ├── commands.json
│ ├── hooks.json
│ └── agents.json
└── skills/ # All active skills
├── api.define/
│ ├── skill.yaml
│ ├── SKILL.md
│ └── api_define.py
├── api.validate/
│ ├── skill.yaml
│ ├── SKILL.md
│ └── api_validate.py
└── ... (all other skills)
```
## Manifest Schema
The `manifest.json` file is the primary metadata file for plugin distribution:
```json
{
"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": {
"homepage": "https://github.com/epieczko/betty",
"repository": "https://github.com/epieczko/betty",
"documentation": "https://github.com/epieczko/betty/tree/main/docs",
"tags": ["framework", "api-development", "workflow"],
"generated_at": "2025-10-23T12:34:56.789012+00:00"
},
"requirements": {
"python": ">=3.11",
"packages": ["pyyaml"]
},
"permissions": ["filesystem:read", "filesystem:write", "process:execute"],
"package": {
"filename": "betty-framework-1.0.0.tar.gz",
"size_bytes": 245760,
"checksums": {
"md5": "a1b2c3d4e5f6...",
"sha256": "1234567890abcdef..."
}
},
"entrypoints": [
{
"command": "skill/define",
"handler": "skills/skill.define/skill_define.py",
"runtime": "python"
}
],
"commands_count": 18,
"agents": [
{
"name": "api.designer",
"description": "Design APIs with iterative refinement"
}
]
}
```
## Build Report Schema
```json
{
"build_timestamp": "2025-10-23T12:34:56.789012+00:00",
"plugin": {
"name": "betty-framework",
"version": "1.0.0",
"description": "Betty Framework - Structured AI-assisted engineering"
},
"validation": {
"total_commands": 18,
"valid_entrypoints": 18,
"missing_files": [],
"has_errors": false
},
"package": {
"path": "/home/user/betty/dist/betty-framework-1.0.0.tar.gz",
"size_bytes": 245760,
"size_human": "240.00 KB",
"files_count": 127,
"format": "tar.gz",
"checksums": {
"md5": "a1b2c3d4e5f6...",
"sha256": "1234567890abcdef..."
}
},
"entrypoints": [
{
"command": "skill/define",
"handler": "skills/skill.define/skill_define.py",
"runtime": "python",
"path": "/home/user/betty/skills/skill.define/skill_define.py"
}
]
}
```
## Outputs
### Success Response
```json
{
"ok": true,
"status": "success",
"package_path": "/home/user/betty/dist/betty-framework-1.0.0.tar.gz",
"report_path": "/home/user/betty/dist/betty-framework-1.0.0-build-report.json",
"build_report": { ... }
}
```
### Success with Warnings
```json
{
"ok": false,
"status": "success_with_warnings",
"package_path": "/home/user/betty/dist/betty-framework-1.0.0.tar.gz",
"report_path": "/home/user/betty/dist/betty-framework-1.0.0-build-report.json",
"build_report": {
"validation": {
"missing_files": [
"Command 'api.broken': handler not found at skills/api.broken/api_broken.py"
],
"has_errors": true
}
}
}
```
### Failure Response
```json
{
"ok": false,
"status": "failed",
"error": "plugin.yaml not found: /home/user/betty/plugin.yaml"
}
```
## Behavior
### 1. Plugin Loading
Reads and parses `plugin.yaml`:
- Validates YAML syntax
- Extracts plugin name, version, description
- Identifies all command entrypoints
### 2. Entrypoint Validation
For each command in `plugin.yaml`:
- Extracts handler script path
- Checks file existence on disk
- Reports valid and missing handlers
- Logs validation results
**Valid entrypoint**:
```yaml
- name: skill/validate
handler:
runtime: python
script: skills/skill.define/skill_define.py
```
**Missing handler** (reports warning):
```yaml
- name: broken/command
handler:
runtime: python
script: skills/broken/missing.py # File doesn't exist
```
### 3. File Gathering
Automatically includes:
**Always included**:
- `plugin.yaml` Plugin manifest
- `skills/*/` All skill directories referenced in commands
- `betty/` Core utility package
- `registry/*.json` All registry files
**Conditionally included** (if exist):
- `requirements.txt` Python dependencies
- `README.md` Plugin documentation
- `LICENSE` License file
- `CHANGELOG.md` Version history
**Excluded**:
- `__pycache__/` directories
- `.pyc` compiled Python files
- Hidden files (starting with `.`)
- Build artifacts and temporary files
### 4. Package Creation
**tar.gz format**:
- GZIP compression
- Preserves file permissions
- Cross-platform compatible
- Standard for Python packages
**zip format**:
- ZIP compression
- Wide compatibility
- Good for Windows environments
- Easy to extract without CLI tools
### 5. Checksum Generation
Calculates two checksums:
**MD5**: Fast, widely supported
```
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
```
**SHA256**: Cryptographically secure
```
1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
```
Use checksums to verify package integrity after download or transfer.
## Examples
### Example 1: Standard Build
**Scenario**: Build Betty Framework plugin for distribution
```bash
# Ensure plugin.yaml is up to date
/plugin/sync
# Build the package
/plugin/build
```
**Output**:
```
INFO: 🏗️ Starting plugin build...
INFO: 📄 Plugin: /home/user/betty/plugin.yaml
INFO: 📦 Format: tar.gz
INFO: 📁 Output: /home/user/betty/dist
INFO: ✅ Loaded plugin.yaml from /home/user/betty/plugin.yaml
INFO: 📝 Validating 18 command entrypoints...
INFO: 📦 Gathering files from 16 skill directories...
INFO: 📦 Adding betty/ utility package...
INFO: 📦 Adding registry/ files...
INFO: 📦 Total files to package: 127
INFO: 🗜️ Creating tar.gz archive: /home/user/betty/dist/betty-framework-1.0.0.tar.gz
INFO: 🔐 Calculating checksums...
INFO: MD5: a1b2c3d4e5f6...
INFO: SHA256: 1234567890ab...
INFO: 📊 Build report: /home/user/betty/dist/betty-framework-1.0.0-build-report.json
INFO: 📋 Manifest: /home/user/betty/dist/manifest.json
INFO: 📋 Preview file created: /home/user/betty/dist/plugin.preview.yaml
INFO:
============================================================
INFO: 🎉 BUILD COMPLETE
============================================================
INFO: 📦 Package: /home/user/betty/dist/betty-framework-1.0.0.tar.gz
INFO: 📊 Report: /home/user/betty/dist/betty-framework-1.0.0-build-report.json
INFO: 📋 Manifest: /home/user/betty/dist/manifest.json
INFO: 👁️ Preview: /home/user/betty/dist/plugin.preview.yaml
INFO: ✅ Commands: 18/18
INFO: 📏 Size: 240.00 KB
INFO: 📝 Files: 127
============================================================
```
### Example 2: Build as ZIP
**Scenario**: Create Windows-friendly package
```bash
python skills/plugin.build/plugin_build.py --format=zip
```
**Result**: `dist/betty-framework-1.0.0.zip`
### Example 3: Build with Custom Output
**Scenario**: Build to specific release directory
```bash
python skills/plugin.build/plugin_build.py \
--format=tar.gz \
--output-dir=releases/v1.0.0
```
**Result**:
- `releases/v1.0.0/betty-framework-1.0.0.tar.gz`
- `releases/v1.0.0/betty-framework-1.0.0-build-report.json`
### Example 4: Detecting Missing Handlers
**Scenario**: Some handlers are missing
```bash
# Remove a handler file
rm skills/api.validate/api_validate.py
# Try to build
/plugin/build
```
**Output**:
```
INFO: 📝 Validating 18 command entrypoints...
WARNING: ❌ skill/api/validate: skills/api.validate/api_validate.py (not found)
INFO: ⚠️ Found 1 missing files:
INFO: - Command 'skill/api/validate': handler not found at skills/api.validate/api_validate.py
INFO: 📦 Gathering files from 15 skill directories...
...
INFO: ============================================================
INFO: 🎉 BUILD COMPLETE
INFO: ============================================================
INFO: ✅ Commands: 17/18
INFO: ⚠️ Warnings: 1
```
**Exit code**: 1 (failure due to validation errors)
### Example 5: Build Workflow
**Scenario**: Complete release workflow
```bash
# 1. Update registries
/registry/update
# 2. Sync plugin.yaml
/plugin/sync
# 3. Build package
/plugin/build
# 4. Verify package
tar -tzf dist/betty-framework-1.0.0.tar.gz | head -20
# 5. Check build report
cat dist/betty-framework-1.0.0-build-report.json | jq .
```
## Integration
### With plugin.sync
Always sync before building:
```bash
/plugin/sync && /plugin/build
```
### With Workflows
Include in release workflow:
```yaml
# workflows/plugin_release.yaml
name: plugin_release
version: 1.0.0
description: Release workflow for Betty Framework plugin
steps:
- skill: registry.update
description: Update all registries
- skill: plugin.sync
description: Generate plugin.yaml
- skill: plugin.build
args: ["--format=tar.gz"]
description: Build tar.gz package
- skill: plugin.build
args: ["--format=zip"]
description: Build zip package
```
### With CI/CD
Add to GitHub Actions:
```yaml
# .github/workflows/release.yml
- name: Build Plugin Package
run: |
python skills/plugin.sync/plugin_sync.py
python skills/plugin.build/plugin_build.py --format=tar.gz
python skills/plugin.build/plugin_build.py --format=zip
- name: Upload Packages
uses: actions/upload-artifact@v3
with:
name: plugin-packages
path: dist/betty-framework-*
```
## Validation Rules
### Entrypoint Validation
**Valid entrypoint**:
- Command name is defined
- Handler section exists
- Handler script path is specified
- Handler file exists on disk
- Runtime is specified
**Invalid entrypoint** (triggers warning):
- Missing handler script path
- Handler file doesn't exist
- Empty command name
### File Gathering Rules
**Skill directories included if**:
- Referenced in at least one command handler
- Contains valid handler file
**Files excluded**:
- Python cache files (`__pycache__`, `.pyc`)
- Hidden files (`.git`, `.env`, etc.)
- Build artifacts (`dist/`, `build/`)
- IDE files (`.vscode/`, `.idea/`)
## Common Errors
| Error | Cause | Solution |
|-------|-------|----------|
| "plugin.yaml not found" | Missing plugin.yaml | Run `/plugin/sync` first |
| "Invalid YAML" | Syntax error in plugin.yaml | Fix YAML syntax |
| "Unsupported output format" | Invalid --format value | Use `tar.gz` or `zip` |
| "Handler not found" | Missing handler file | Create handler or fix path |
| "Permission denied" | Cannot write to output dir | Check directory permissions |
## Files Read
- `plugin.yaml` Plugin manifest
- `skills/*/skill.yaml` Skill manifests (indirect via handlers)
- `skills/*/*.py` Handler scripts
- `betty/*.py` Utility modules
- `registry/*.json` Registry files
- `requirements.txt` Dependencies (if exists)
- `README.md`, `LICENSE`, `CHANGELOG.md` Documentation (if exist)
## Files Modified
- `{output-dir}/{plugin-name}-{version}.{format}` Created package archive
- `{output-dir}/{plugin-name}-{version}-build-report.json` Created build report
- `{output-dir}/manifest.json` Created plugin manifest with checksums and entrypoints
- `{output-dir}/plugin.preview.yaml` Created plugin preview for review
## Exit Codes
- **0**: Success (all handlers valid, package created)
- **1**: Failure (missing handlers or build error)
## Logging
Logs build progress with emojis for clarity:
```
INFO: 🏗️ Starting plugin build...
INFO: 📄 Plugin: /home/user/betty/plugin.yaml
INFO: ✅ Loaded plugin.yaml
INFO: 📝 Validating entrypoints...
INFO: 📦 Gathering files...
INFO: 🗜️ Creating tar.gz archive...
INFO: 🔐 Calculating checksums...
INFO: 📊 Build report written
INFO: 🎉 BUILD COMPLETE
```
## Best Practices
1. **Always Sync First**: Run `/plugin/sync` before `/plugin/build`
2. **Validate Before Building**: Ensure all skills are registered and active
3. **Check Build Reports**: Review validation warnings before distribution
4. **Verify Checksums**: Use checksums to verify package integrity
5. **Version Consistently**: Match plugin version with git tags
6. **Test Extraction**: Verify packages extract correctly
7. **Document Changes**: Keep CHANGELOG.md updated
## Troubleshooting
### Missing Files in Package
**Problem**: Expected files not in archive
**Solutions**:
- Ensure files exist in source directory
- Check that skills are referenced in commands
- Verify files aren't excluded (e.g., `.pyc`, `__pycache__`)
- Check file permissions
### Handler Validation Failures
**Problem**: Handlers marked as missing but files exist
**Solutions**:
- Verify exact path in plugin.yaml matches file location
- Check case sensitivity in file paths
- Ensure handler files have correct names
- Run `/plugin/sync` to update paths
### Package Size Too Large
**Problem**: Archive file is very large
**Solutions**:
- Remove unused skills from plugin.yaml
- Check for accidentally included large files
- Review skill directories for unnecessary data
- Consider splitting into multiple plugins
### Build Fails with Permission Error
**Problem**: Cannot write to output directory
**Solutions**:
- Create output directory with proper permissions
- Check disk space availability
- Verify write access to output directory
- Try different output directory with `--output-dir`
## Architecture
### Skill Category
**Infrastructure** Plugin.build is part of the distribution layer, preparing plugins for deployment.
### Design Principles
- **Validation First**: Check all handlers before packaging
- **Complete Packages**: Include all necessary dependencies
- **Reproducible**: Same source creates identical packages
- **Verifiable**: Checksums ensure package integrity
- **Transparent**: Detailed reporting of included files
- **Flexible**: Support multiple archive formats
### Package Philosophy
The package includes everything needed to run the plugin:
- **Skills**: All command handlers and manifests
- **Utilities**: Core betty package for shared functionality
- **Registries**: Skill, command, and hook definitions
- **Dependencies**: Python requirements
- **Documentation**: README, LICENSE, CHANGELOG
This creates a self-contained, portable plugin distribution.
## See Also
- **plugin.sync** Generate plugin.yaml ([SKILL.md](../plugin.sync/SKILL.md))
- **skill.define** Validate and register skills ([SKILL.md](../skill.define/SKILL.md))
- **registry.update** Update registries ([SKILL.md](../registry.update/SKILL.md))
- **Betty Distribution** Plugin marketplace guide ([docs/distribution.md](../../docs/distribution.md))
## Dependencies
- **plugin.sync**: Generate plugin.yaml before building
- **betty.config**: Configuration constants and paths
- **betty.logging_utils**: Logging infrastructure
## Status
**Active** Production-ready infrastructure skill
## Version History
- **0.1.0** (Oct 2025) Initial implementation with tar.gz/zip support, validation, and checksums