Architecture
Overview
Section titled “Overview”The Warcraft II Notifications Plugin is an OpenCode plugin that enhances the development experience by playing authentic Warcraft II unit sounds when the IDE session goes idle. The plugin is built with TypeScript and uses the Bun runtime for optimal performance.
System Architecture
Section titled “System Architecture”Component Architecture
Section titled “Component Architecture”1. Plugin Entry Point (index.ts)
Section titled “1. Plugin Entry Point (index.ts)”Purpose: Exports the main plugin interface to OpenCode.
Responsibilities:
- Export
NotificationPluginas the primary plugin interface - Serve as the entry point for OpenCode plugin loading
Dependencies: notification.ts
2. Notification Controller (notification.ts)
Section titled “2. Notification Controller (notification.ts)”Purpose: Core plugin logic that orchestrates event handling and notification delivery.
Key Responsibilities:
- Listen for OpenCode session idle events
- Load plugin configuration
- Install bundled sounds on first run
- Select random sounds based on faction preference
- Play sounds using platform-specific commands
- Display toast notifications via OpenCode TUI
- Extract and format session summaries
Event Flow:
Configuration Integration:
- Reads
soundsDirfrom plugin configuration - Reads
factionpreference (alliance/horde/both) - Reads
showDescriptionInToastpreference (default: true) - Falls back to platform-specific defaults
3. Schema Validator (schema-validator.ts)
Section titled “3. Schema Validator (schema-validator.ts)”Purpose: Validates plugin configuration against JSON schema at runtime using Zod.
Key Responsibilities:
- Validate configuration structure and values
- Provide detailed, actionable error messages
- Support both error-throwing and non-throwing validation modes
- Ensure type safety for configuration objects
Validation Flow:
Validation Rules:
faction: Must be'alliance','horde', or'both'(optional)soundsDir: Must be a string (optional)showDescriptionInToast: Must be a boolean (optional, default: true)- No unrecognized keys allowed (strict mode)
Error Message Format:
[Warcraft Notifications] Configuration validation failed: - faction: Invalid enum value. Must be one of: 'alliance', 'horde', 'both' Configuration file: /path/to/.opencode/plugin.jsonPerformance: Validation completes in <0.1ms, meeting the <100ms requirement.
4. Plugin Configuration (plugin-config.ts)
Section titled “4. Plugin Configuration (plugin-config.ts)”Purpose: Manages plugin configuration loading, validation, and default directory resolution.
Key Features:
Configuration Schema:
interface WarcraftNotificationConfig { soundsDir?: string; // Custom sound storage directory faction?: 'alliance' | 'horde' | 'both'; // Faction preference}Platform-Specific Defaults:
- macOS:
~/Library/Application Support/opencode/storage/plugin/<package-name>/sounds - Linux:
~/.local/share/opencode/storage/plugin/<package-name>/sounds - Windows (planned):
%APPDATA%\opencode\storage\plugin\<package-name>
Note: Windows support is planned for a future release. Currently supported: macOS and Linux.
Environment Variable Overrides:
SOUNDS_DATA_DIR: Override default data directorySOUNDS_BASE_URL: Override download base URL (legacy)
5. Sound Manager (sounds.ts)
Section titled “5. Sound Manager (sounds.ts)”Purpose: Manages sound file selection, path resolution, and faction-based filtering.
Sound Organization:
Key Functions:
getRandomSoundFromFaction(faction): Select random sound by factiongetRandomSoundPathFromFaction(faction, dataDir): Get full path to random sounddetermineSoundFaction(filename): Determine faction from filenamesoundExists(filename, faction, dataDir): Check if sound file existsgetSoundsByFaction(faction): Get all sounds for a faction
Faction Detection Logic:
// Horde sounds start with specific prefixesif ( filename.startsWith('orc_') || filename.startsWith('death_knight_') || filename.startsWith('dragon_') || filename.startsWith('goblin_sapper_') || filename.startsWith('ogre_') || filename.startsWith('troll_') || filename.startsWith('horde_ship_')) { return 'horde';}// Default to alliancereturn 'alliance';6. Bundled Sounds Manager (bundled-sounds.ts)
Section titled “6. Bundled Sounds Manager (bundled-sounds.ts)”Purpose: Handles installation and verification of bundled sound files.
Installation Flow:
Key Features:
- Non-destructive: Never overwrites existing files
- Faction-aware: Organizes sounds into alliance/ and horde/ subdirectories
- Idempotent: Safe to run multiple times
- Error-tolerant: Continues on individual file failures
Directory Structure:
<dataDir>/├── alliance/│ ├── human_selected1.wav│ ├── knight_acknowledge1.wav│ ├── elf_selected1.wav│ └── ... (50+ files)└── horde/ ├── orc_selected1.wav ├── death_knight_acknowledge1.wav ├── dragon_selected1.wav └── ... (50+ files)7. Sound Data Module (sound-data/)
Section titled “7. Sound Data Module (sound-data/)”Purpose: Centralized sound metadata and file list management.
Module Structure:
Data Structure:
// Alliance sound entry example{ filename: 'human_selected1.wav', path: 'human_selected1.wav', description: 'Human unit selected - "Yes, my lord?"'}
// Horde sound entry example{ filename: 'orc_selected1.wav', path: 'orc_selected1.wav', description: 'Orc unit selected - "Zug zug!"'}Key Functions:
buildSoundsToDownload(faction, baseUrl): Build download list for factionbuildAllSoundsToDownload(baseUrl): Build complete download listgetSoundFileList(faction?): Get list of expected filenamesgetSoundCounts(): Get sound counts by faction
Data Flow
Section titled “Data Flow”Plugin Initialization Flow
Section titled “Plugin Initialization Flow”Idle Notification Flow
Section titled “Idle Notification Flow”Platform Integration
Section titled “Platform Integration”macOS Integration
Section titled “macOS Integration”Commands Used:
# Play soundafplay /path/to/sound.wav
# Display notificationosascript -e 'display notification "summary" with title "opencode"'Linux Integration
Section titled “Linux Integration”Commands Used:
# Play soundcanberra-gtk-play --id=message
# Display notificationnotify-send 'opencode' 'summary'Configuration Precedence
Section titled “Configuration Precedence”Priority Order (highest to lowest):
- Project-specific
.opencode/plugin.jsonsoundsDirsetting - Global
~/.config/opencode/plugin.jsonsoundsDirsetting SOUNDS_DATA_DIRenvironment variable- Platform-specific default directory
Testing Architecture
Section titled “Testing Architecture”Test Structure
Section titled “Test Structure”Test Categories:
- Unit Tests: Test individual functions in isolation
- Integration Tests: Test component interactions
- Edge Case Tests: Test boundary conditions and unusual inputs
- Failure Tests: Test error handling and recovery
Test Utilities (test-utils.ts):
- Mock file system operations
- Mock environment variables
- Mock platform detection
- Create temporary test directories
Security Considerations
Section titled “Security Considerations”File System Security
Section titled “File System Security”Security Measures:
- No overwrites: Existing files are never overwritten
- Directory validation: All paths are validated before use
- Permission checks: File operations respect system permissions
- No network operations: All sounds are bundled, no runtime downloads
Configuration Security
Section titled “Configuration Security”- No code execution: Configuration is pure JSON data
- Path sanitization: All paths are sanitized before use
- Environment isolation: Environment variables are scoped appropriately
Performance Considerations
Section titled “Performance Considerations”Lazy Loading
Section titled “Lazy Loading”Optimization Strategies:
- Sound cache: Verified sounds are cached to avoid repeated checks
- Lazy installation: Sounds are only installed on first run
- Minimal file I/O: File operations are minimized and cached
Memory Management
Section titled “Memory Management”- Small footprint: Plugin maintains minimal state
- No sound buffering: Sounds are played directly from disk
- Efficient data structures: Sound lists use const arrays
Extension Points
Section titled “Extension Points”Adding New Sounds
Section titled “Adding New Sounds”Adding New Factions
Section titled “Adding New Factions”To add a new faction (e.g., “neutral”):
-
Update types (
plugin-config.ts):export type Faction = 'alliance' | 'horde' | 'neutral' | 'both'; -
Create sound data (
sound-data/neutral.ts):export const neutralSoundEntries: SoundEntry[] = [{ filename: 'neutral_sound1.wav', path: 'neutral_sound1.wav', description: '...' },]; -
Update sound manager (
sounds.ts):export const neutralSounds = {/* ... */};export const getSoundsByFaction = (faction: Faction): string[] => {switch (faction) {case 'neutral':return Object.values(neutralSounds).flat();// ...}}; -
Update bundled sounds (
bundled-sounds.ts):- Add neutral faction detection logic
- Update installation to handle neutral/ subdirectory
Deployment Architecture
Section titled “Deployment Architecture”NPM Package Structure
Section titled “NPM Package Structure”@pantheon-ai/opencode-warcraft-notifications/├── index.ts # Entry point├── src/ # Source code│ ├── notification.ts│ ├── plugin-config.ts│ ├── sounds.ts│ ├── bundled-sounds.ts│ └── sound-data/├── data/ # Bundled sounds│ ├── alliance/│ └── horde/├── docs/ # Documentation├── package.json└── README.mdInstallation Flow
Section titled “Installation Flow”Monitoring and Debugging
Section titled “Monitoring and Debugging”Debug Mode
Section titled “Debug Mode”Enable debug logging with:
DEBUG_OPENCODE=1 opencodeDebug Output:
- Configuration loading attempts
- Sound installation progress
- File operation results
- Error details
Common Issues
Section titled “Common Issues”Future Architecture Considerations
Section titled “Future Architecture Considerations”Potential Enhancements
Section titled “Potential Enhancements”-
Custom Sound Packs
- Support for user-provided sound packs
- Sound pack marketplace integration
-
Advanced Configuration
- Per-event sound mapping
- Volume control
- Sound categories (selected vs. acknowledge)
-
Analytics
- Track most played sounds
- Usage statistics
- Performance metrics
-
Multi-platform Expansion
- Windows support
- Web-based OpenCode support
- Mobile notifications
Document Version: 1.0
Last Updated: 2025-11-10
Maintained By: Pantheon AI Team