Plugin System
Purpose
Define the plugin architecture that allows extending wai with additional capabilities, including YAML-based configuration, hook points, command pass-through, and built-in plugins for common tools.
Problem Statement
As the wai tool matures, the diversity of user needs for specialized functionality and integrations will grow. Without a robust extension mechanism, wai risks becoming either bloated from incorporating every niche feature request, or insufficient for users with specific workflow demands. A plugin system is a foundational Type 1 architectural decision needed to prevent core bloat, meet community-driven and user-specific extension needs, and keep the core tool lean, focused, and maintainable.
Design Rationale
YAML-Based Plugin Configuration
Plugins are configured via YAML files in .wai/plugins/, replacing the earlier TOML-based manifest approach. YAML provides better support for complex nested structures like hook definitions and command mappings. Each plugin declares:
- Detector patterns: How to detect if the plugin’s tool is present (e.g.,
.beads/directory,.git/directory) - Commands: CLI commands the plugin provides or passes through to external tools
- Hooks: Event handlers for project lifecycle events
Hook Points
Plugins can respond to lifecycle events through defined hook points. This is a Type 1 decision establishing the integration pattern:
on_project_create— called when a new project is createdon_phase_transition— called when a project changes phaseon_handoff_generate— called when generating a handoff documenton_status— called when displaying project status
Built-in Plugins
Three plugins ship with wai as built-ins:
- beads — detects
.beads/directory, provides issue data for handoffs and status - openspec — detects
openspec/directory, provides spec change data - git — detects
.git/directory, provides commit history and status
Command Pass-Through
Plugins can register commands that pass through to external CLIs. For example, wai beads list delegates to bd list --json. This provides a unified interface while leveraging existing tools.
Scope and Requirements
This spec covers the plugin configuration format, lifecycle hooks, command routing, and built-in plugin definitions.
Non-Goals
- Plugin registry or marketplace
- Plugin sandboxing or security model
- Plugin versioning or dependency resolution
- Remote plugin installation
Requirement: Plugin Configuration
Plugins SHALL be configured via YAML files in .wai/plugins/.
Scenario: Plugin config format
- WHEN a plugin is defined
- THEN its configuration file follows this format:
name: beads description: Integration with beads issue tracker detector: type: directory path: .beads/ commands: - name: list description: List beads issues passthrough: bd list --json - name: show description: Show beads issue details passthrough: bd show hooks: on_handoff_generate: command: bd list --status=open --json inject_as: open_issues on_status: command: bd stats --json inject_as: beads_status
Requirement: Plugin Detection
Plugins SHALL auto-detect whether their associated tool is present.
Scenario: Auto-detect on init
- WHEN user runs
wai init - THEN the system checks each built-in plugin’s detector pattern
- AND enables plugins whose tools are detected
Scenario: Detector types
- WHEN a plugin has a directory detector
- THEN the system checks for the specified directory relative to project root
- WHEN a plugin has a file detector
- THEN the system checks for the specified file
Requirement: Plugin Hooks
Plugins SHALL respond to lifecycle events through hook points.
Scenario: Hook execution
- WHEN a lifecycle event occurs (e.g., project creation, phase transition)
- THEN the system calls all registered hooks for that event
- AND collects hook output for use by the triggering command
Scenario: Handoff enrichment
- WHEN generating a handoff
- THEN the system calls
on_handoff_generatehooks on all enabled plugins - AND injects the collected data into the handoff template
Requirement: Command Pass-Through
Plugins SHALL support routing CLI commands to external tools.
Scenario: Plugin command execution
- WHEN user runs
wai <plugin-name> <command> - THEN the system looks up the command in the plugin’s command list
- AND executes the passthrough command
Scenario: Safe mode passthrough
- WHEN user passes
--safe - THEN the system refuses passthrough commands unless the plugin command is explicitly marked
read_only: true - AND returns a diagnostic error that suggests rerunning without
--safe
Scenario: Non-interactive passthrough
- WHEN user passes
--no-input - THEN the system refuses passthrough commands that would prompt for input and returns a diagnostic error
Requirement: Plugin Management
The CLI SHALL support listing, enabling, and disabling plugins.
Scenario: List plugins
- WHEN user runs
wai plugin list - THEN the system shows all known plugins with their status (enabled/disabled/not detected)
Scenario: List plugins as JSON
- WHEN user runs
wai plugin list --json - THEN the system outputs JSON containing plugin name, status, and detector metadata
Scenario: Enable plugin
- WHEN user runs
wai plugin enable <name> - THEN the system enables the specified plugin
Scenario: Disable plugin
- WHEN user runs
wai plugin disable <name> - THEN the system disables the specified plugin without removing its configuration