102 lines
4.4 KiB
Markdown
102 lines
4.4 KiB
Markdown
# Beaver Skill Plugins
|
|
|
|
Declarative skill plugins let an operator mirror skills from a local plugin package into Beaver's managed skill lifecycle. V1 plugins are data packages only: Beaver reads manifests and skill files, but it does not execute plugin Python code, install dependencies, or run arbitrary hooks.
|
|
|
|
## Package Layout
|
|
|
|
A plugin package is a directory containing `beaver.plugin.json` and one or more skill directories:
|
|
|
|
```text
|
|
my-plugin/
|
|
beaver.plugin.json
|
|
skills/
|
|
my-skill/
|
|
SKILL.md
|
|
templates/
|
|
example.md
|
|
```
|
|
|
|
Manifest example:
|
|
|
|
```json
|
|
{
|
|
"schema_version": 1,
|
|
"id": "my-plugin",
|
|
"name": "My Plugin",
|
|
"version": "1.0.0",
|
|
"skills": [
|
|
{ "name": "my-skill", "path": "skills/my-skill" }
|
|
]
|
|
}
|
|
```
|
|
|
|
IDs and skill names use lowercase identifiers with letters, digits, `_`, and `-`. Skill paths must stay inside the plugin package, cannot use symlinks, and must contain a regular `SKILL.md`.
|
|
|
|
## Discovery
|
|
|
|
Beaver discovers plugin manifests from:
|
|
|
|
- the workspace `plugins/` directory;
|
|
- configured `plugins.search_paths` entries in Beaver config.
|
|
|
|
Discovery only records available packages. Operators must explicitly enable a plugin before its skills are mirrored.
|
|
|
|
## Mirroring
|
|
|
|
When a plugin is enabled, Beaver stages immutable upstream snapshots, safety-checks every declared skill, then publishes each mirrored skill as a normal workspace skill version. The first mirror becomes `v0001` and carries plugin provenance:
|
|
|
|
- `source_kind: plugin`;
|
|
- plugin id and plugin version;
|
|
- upstream content hash;
|
|
- upstream full-tree hash.
|
|
|
|
If a skill with the same name already exists and is not plugin-owned, enable fails without publishing any plugin skill.
|
|
|
|
## Hashing And Supporting Files
|
|
|
|
Beaver tracks two hashes:
|
|
|
|
- content hash: normalized `SKILL.md` content;
|
|
- tree hash: `SKILL.md` plus supporting files, relative paths, sizes, bytes, and executable-bit state.
|
|
|
|
Mtime, owner, group, and non-executable mode bits do not affect the tree hash. Beaver metadata files such as `version.json` and `upstream.json` are excluded.
|
|
|
|
Supporting files are copied into Beaver-managed skill versions. Local revisions inherit supporting files from their base version; uploaded supporting files can override inherited files. Plugin update drafts copy supporting files from the referenced upstream snapshot when published. Divergent supporting-file edits are blocked by the publish gate until resolved.
|
|
|
|
## Upgrade Flow
|
|
|
|
When an enabled plugin version changes, sync compares:
|
|
|
|
- accepted upstream tree;
|
|
- current Beaver skill tree;
|
|
- newly discovered upstream tree.
|
|
|
|
Possible outcomes:
|
|
|
|
- unchanged: no candidate;
|
|
- already applied: state is reconciled without a draft;
|
|
- fast forward: Beaver creates a `plugin_skill_update` candidate that can draft the exact upstream content without an LLM;
|
|
- three-way: Beaver creates a `plugin_skill_update` candidate using old upstream, current local, and new upstream inputs.
|
|
|
|
Plugin update candidates go through the same draft, safety, replay evaluation, review, publish, and rollback flow as learned skills. Three-way plugin updates require a plugin preservation report showing local and upstream sections were preserved and conflicts were resolved.
|
|
|
|
## Lifecycle Controls
|
|
|
|
Pause and resume affect updates only. Paused plugins keep current mirrored skills active and suppress new update candidates until resumed.
|
|
|
|
Disable requires explicit confirmation to disable linked skills. It disables the plugin and its linked Beaver skills, but keeps historical versions on disk.
|
|
|
|
Adopt detaches a mirrored skill from the plugin and keeps the skill active as a managed Beaver skill. Future plugin updates no longer apply to that skill.
|
|
|
|
## Recovery
|
|
|
|
If a previously enabled plugin package is removed or becomes undiscoverable, sync marks the plugin `missing`. Current Beaver skills remain active; updates are suspended until the package returns or the operator disables/adopts the skills.
|
|
|
|
If publication succeeds but the plugin state acknowledgement fails, the next sync reconciles state from the published draft provenance and clears the pending candidate.
|
|
|
|
Workspace writes are serialized by the shared workspace write lock. Boot-time auto-sync uses the same lock and defers safely if another writer is active.
|
|
|
|
## V1 Boundary
|
|
|
|
V1 does not execute plugin code. This keeps install and sync deterministic, avoids dependency side effects, and leaves tool execution to Beaver's existing MCP/tool runtime.
|