Plugin Architecture¶
The toolkit is organized into independent plugins that can be selectively installed per team or department.
How plugins work¶
A plugin is a directory inside plugins/ that contains agents, skills, commands, and optionally hooks. Each plugin has a plugin.json that declares its metadata and components.
plugins/
├── registry.json # Declares all available plugins
├── vt-base/ # Required base plugin
│ ├── .claude-plugin/
│ │ ├── plugin.json
│ │ ├── skill-symlinks.manifest
│ │ ├── command-symlinks.manifest
│ │ └── hook-symlinks.manifest
│ ├── agents/
│ ├── skills/
│ ├── commands/
│ ├── hooks/
│ └── scripts/
└── finance/ # Optional department plugin
├── .claude-plugin/
│ ├── plugin.json
│ └── skill-symlinks.manifest
├── skills/
├── agents/
└── commands/
Plugin registry¶
The plugins/registry.json file declares all available plugins:
{
"plugins": {
"vt-base": {
"path": "plugins/vt-base",
"required": true,
"version": "3.14.0"
},
"finance": {
"path": "plugins/finance",
"required": false,
"version": "1.0.0",
"depends_on": ["vt-base"]
}
}
}
Core standards plugin¶
The vt-base plugin is required and provides:
- All 7 orchestrators
- Unified Product Development workflow (Product Design + Development phases)
- Knowledge Work phases (legacy, redirects to unified workflow via
deliverable_typesdispatch) - Security hooks (secret scanning, security lint)
- Core review agents
- The complete learning loop (journal, consolidate, compound)
Every other plugin depends on vt-base.
Department plugins¶
Department plugins add domain-specific capabilities on top of the core:
| Plugin | Example skills | For |
|---|---|---|
finance |
financial-reporting, budget-planning, compliance-sox | Finance team |
support |
ticket-triage, customer-response, escalation-workflow | Support team |
marketing |
content-calendar, campaign-brief, brand-voice | Marketing team |
Department plugins can include:
- Skills — domain knowledge and workflows
- Agents — specialized reviewers or researchers
- Commands — entry points into department workflows
- Hooks — optional domain-specific quality gates
Dependencies¶
Department plugins declare their dependencies in plugin.json:
{
"name": "finance",
"version": "1.0.0",
"depends_on": ["vt-base"],
"description": "Financial reporting and compliance skills"
}
When installing a department plugin, setup.sh automatically installs its dependencies.
Installation model¶
Each plugin carries its own manifest files that define what gets symlinked:
skill-symlinks.manifest— maps skill names to SKILL.md filescommand-symlinks.manifest— maps command names to command fileshook-symlinks.manifest— maps hook scripts (optional)
The setup.sh script reads these manifests and creates the appropriate symlinks in ~/.claude/.
Toolkit-only fields in plugin.json¶
plugin.json serves two readers with different schemas, and only one of them is Claude Code.
Claude Code recognises a fixed set of fields (name, version, description, author,
homepage, repository, license, keywords, …). Everything else it ignores at load time.
Running claude plugin validate . reports each extra field as:
❯ plugins[0] plugin.json → manifests: Unknown field 'manifests'. Claude Code ignores it at load time.
These six fields are deliberate toolkit-only semantics, read by setup.sh and the toolkit's
own generators, never by Claude Code:
| Field | Read by | Purpose |
|---|---|---|
required |
setup.sh |
Marks the plugin as non-removable (vt-base) |
depends_on |
setup.sh |
Installs dependencies first (see Dependencies) |
skill_prefix |
setup.sh, skill tooling |
The plugin's namespace (vt-c-, vt-d-, …) |
manifests |
setup.sh |
Which symlink manifests to process |
components |
setup.sh |
Declares what the plugin ships |
orchestrators |
agent tooling | Phase-orchestrator agents this plugin provides |
The resulting warnings are expected and safe to leave. Warnings do not block installation;
only errors do. Do not "fix" them by deleting the fields — setup.sh depends on them.
What must never go here is data with a schema-invalid shape. A workflows key once lived in
vt-base/plugin.json and was a hard error, not a warning, which made the plugin uninstallable
(BUG-032). It now lives at the top level of plugins/registry.json, which is toolkit-owned and
outside the vendor schema — the correct home for any new toolkit-only structure.
Deleting it was itself a trap worth remembering: generate-skill-map.sh was its only reader, so
removing the key silently emptied four documented workflow pipelines while the test guarding it
(a "workflows" substring check) kept passing against "workflows": {}. Moving data out of a
manifest means finding its readers first, and a substring assertion over generated output
cannot tell "populated" from "empty".
Creating your own plugin¶
See Creating Plugins for a step-by-step guide.