This document describes how WTFB plugins extend the template and how the selection policy determines which capabilities are active.
WTFB uses a layered architecture where:
- Template provides the foundation (agents, skills, commands, hooks)
- Plugins add, extend, or replace template capabilities
- Selection Policy determines which capabilities are active based on configuration
┌─────────────────────────────────────────────────────────┐
│ Writer's Project │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Plugin Layer (optional) │ │
│ │ wtfb-screenwriting, wtfb-novel-writing, etc. │ │
│ └───────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Template Layer (foundation) │ │
│ │ 11 agents, 24 skills, 30 commands, hooks │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
A WTFB plugin follows the Claude Code plugin conventions:
wtfb-screenwriting/
├── .claude-plugin/
│ └── plugin.json # Plugin manifest
├── agents/ # Additional agents (optional)
├── skills/
│ ├── advanced-structure/
│ │ └── SKILL.md
│ └── showrunner-workflow/
│ └── SKILL.md
├── commands/ # Additional commands (optional)
├── hooks/ # Additional hooks (optional)
└── README.md
.claude-plugin/plugin.json:
{
"name": "wtfb-screenwriting",
"version": "1.0.0",
"description": "Professional screenwriting enhancements for WTFB",
"author": "Words To Film By <dev@wordstofilmby.com>",
"wtfb": {
"namespace": "wtfb-screenwriting",
"compat": {
"template": ">=1.0.0 <2.0.0"
}
}
}Every capability has a canonical identifier (wtfbId) that uniquely identifies it:
| Layer | Namespace | Example |
|---|---|---|
| Template | wtfb: |
wtfb:story-structure |
| Marketplace | {plugin}: |
wtfb-screenwriting:advanced-structure |
| Capability | wtfbId Required? |
|---|---|
| Skills | REQUIRED |
| Commands | RECOMMENDED |
| Hooks | OPTIONAL |
| Agents | OPTIONAL |
Plugin capabilities declare their relationship to template capabilities:
New capability with no template dependency:
---
name: showrunner-workflow
wtfbId: wtfb-screenwriting:showrunner-workflow
provides: true
---Additive enhancement (both available):
---
name: advanced-structure
wtfbId: wtfb-screenwriting:advanced-structure
extends:
wtfbId: wtfb:story-structure
---Explicit override (premium supersedes base):
---
name: story-structure-pro
wtfbId: wtfb-screenwriting:story-structure-pro
replaces:
wtfbId: wtfb:story-structure
---/plugin install wtfb-screenwriting@github.com/bybren-llc/cheddarfox-claude-marketplace/plugins/screenwriting
This updates .wtfb/project.json:
{
"plugins": {
"installed": ["wtfb-screenwriting"],
"precedence": ["wtfb-screenwriting"]
}
}/plugin list
/plugin remove wtfb-screenwriting
Precedence is controlled in .wtfb/project.json:
{
"plugins": {
"installed": ["wtfb-screenwriting", "wtfb-film-production"],
"precedence": ["wtfb-screenwriting", "wtfb-film-production"]
}
}- Template loads first (foundation layer)
- Plugins load in precedence order
- Relationship type determines behavior:
provides: New capability addedextends: Both base and enhanced availablereplaces: Premium supersedes base
- Later in precedence wins for conflicts
- If
precedencearray missing: use installation order - If compatibility check fails: skip capability, log warning
The orchestrator (Session Manager) follows this algorithm:
1. Load all template capabilities into registry
2. For each installed plugin (in precedence order):
a. For each capability in plugin:
i. Check compatibility (compat.template range)
ii. Check dependencies (requires)
iii. Based on relationship:
- provides: Add to registry
- extends: Add to registry, mark as "enhanced" version
- replaces: Replace base in registry
3. When capability requested:
a. Look up by wtfbId
b. If "extends" exists and user in "pro mode": prefer enhanced
c. Otherwise: use whatever is in registry
| Capability | extends | replaces | Notes |
|---|---|---|---|
| Skills | ✓ | ✓ | Primary extension point |
| Commands | ✓ | Prefer parallel | Add premium commands alongside |
| Hooks | Minimal | Minimal | Keep auditable |
| Agents | Add new | Not allowed | Don't replace template agents |
mkdir -p my-plugin/.claude-plugin
mkdir -p my-plugin/skills/my-skillmy-plugin/.claude-plugin/plugin.json:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "My custom WTFB plugin",
"wtfb": {
"namespace": "my-plugin",
"compat": {
"template": ">=1.0.0"
}
}
}my-plugin/skills/my-skill/SKILL.md:
---
name: my-skill
wtfbId: my-plugin:my-skill
description: My custom skill description.
provides: true
compat:
template: ">=1.0.0"
---
# My Skill
Skill content here.- Add plugin to your project's
.wtfb/project.json:{ "plugins": { "installed": ["my-plugin"], "precedence": ["my-plugin"] } } - Run
/plugin listto verify - Test your skill with the appropriate invocation
Contact the WTFB team to submit your plugin for review and inclusion in the marketplace.
Plugins are validated for:
- Schema: All skills have valid
wtfbId - Contract: Exactly one of
provides,extends, orreplaces - Uniqueness: No duplicate
wtfbIdwithin plugin - References:
extends.wtfbIdandreplaces.wtfbIdreference valid template capabilities - Compatibility:
compat.templaterange is valid
| Error | Cause | Fix |
|---|---|---|
| Missing wtfbId | Skill lacks canonical ID | Add wtfbId: {namespace}:{name} |
| Multiple relationships | Both extends and replaces | Choose one relationship type |
| Invalid reference | extends/replaces points to non-existent capability | Check template wtfbId exists |
| Compatibility mismatch | Template version out of range | Update compat.template |
The WTFB architecture supports multiple independent marketplaces (official and third-party) through namespace isolation and precedence control.
Each marketplace uses a unique namespace prefix:
Template (Hub): wtfb:story-structure
Official Plugin: wtfb-screenwriting:advanced-structure
Third-Party Plugin: acme-writing:custom-beats
This prevents identifier collisions. A project can install plugins from multiple sources without conflicts.
When plugins provide overlapping capabilities, the project owner controls resolution:
{
"plugins": {
"installed": ["wtfb-screenwriting", "acme-writing"],
"precedence": ["acme-writing", "wtfb-screenwriting"]
}
}Later entries in precedence win for capabilities with the same base wtfbId.
| Scenario | Resolution |
|---|---|
Two plugins provides same wtfbId |
Error: duplicate capability |
Two plugins extends same base |
Both available; precedence determines default |
Two plugins replaces same base |
Later in precedence wins |
| Plugin extends non-existent base | Error: invalid reference |
- Use a unique vendor namespace (e.g.,
acme-writing:) - Never use reserved namespaces (
wtfb:,wtfb-screenwriting:, etc.) - Declare relationships explicitly (
provides,extends,replaces) - Include
compat.templateversion range
See Capability Contract - Third-Party Plugin Author Rules for full specification.
- Capability Contract - Schema and rules for capabilities
- User Access Tiers - Who gets what features
- Template & Marketplace Relationship - Ecosystem overview