# wallpaper-engine-web-dev-kit API Reference
> Version: 0.1.0 | Last updated: 2026-07-27
## Table of Contents
1. [createWeDevKit() — Factory Function](#createwedevkit--factory-function)
2. [DevKitInstance — Top-Level Instance](#devkitinstance--top-level-instance)
3. [MediaController — Media Integration Control](#mediacontroller--media-integration-control)
4. [RgbController — RGB Data Access](#rgbcontroller--rgb-data-access)
5. [LifecycleController — Lifecycle Control](#lifecyclecontroller--lifecycle-control)
6. [PropertiesController — Property Configuration](#propertiescontroller--property-configuration)
7. [Mp3PlayerController — MP3 Spectrum Player](#mp3playercontroller--mp3-spectrum-player)
8. [Type Reference](#type-reference)
9. [Build-Time Injection API](#build-time-injection-api)
10. [Agent Usage Examples](#agent-usage-examples)
---
## createWeDevKit() — Factory Function
Creates a WE Dev Kit instance, injecting all WE runtime simulation APIs in one call.
### Signature
```typescript
function createWeDevKit(options?: DevKitConfig): DevKitInstance
```
### Options (DevKitConfig)
| Field | Type | Default | Description |
|---|---|---|---|
| `enabled` | `boolean` | `true` | Master switch |
| `autoDetect` | `boolean` | `true` | Auto-detect real WE environment and skip |
| `audio` | `boolean \| AudioConfig` | `true` | Audio simulation config |
| `media` | `boolean \| MediaConfig` | `true` | Media integration simulation config |
| `properties` | `boolean` | `true` | Property listener polyfill |
| `rgb` | `boolean` | `true` | RGB LED simulation |
| `lifecycle` | `boolean` | `true` | Lifecycle events |
| `panel` | `boolean \| PanelConfig` | `true` | Control panel. Set to `false` to disable entirely |
#### AudioConfig
| Field | Type | Default | Description |
|---|---|---|---|
| `amplitude` | `number` | `0.6` | Amplitude 0–1 |
| `bassBoost` | `number` | `1.2` | Bass gain |
| `variationSpeed` | `number` | `1.0` | Variation speed |
| `frameRate` | `number` | `30` | Frame rate |
#### MediaConfig
| Field | Type | Default | Description |
|---|---|---|---|
| `tracks` | `MockTrack[]` | `[]` | Custom track library (empty = use 5 built-in tracks) |
| `autoCycle` | `boolean` | `true` | Auto-rotate tracks; when `false`, playback stops at track end |
| `cycleIntervalMs` | `number` | `8000` | Rotation interval (ms); fallback period for tracks without a valid duration |
#### PanelConfig
| Field | Type | Default | Description |
|---|---|---|---|
| `position` | `{ x: number; y: number }` | `{ x: 0, y: 0 }` | Panel initial position |
| `collapsed` | `boolean` | `false` | Start collapsed |
| `theme` | `'light' \| 'dark'` | `'dark'` | Theme |
### Examples
```typescript
// Basic usage (all features enabled)
const kit = createWeDevKit();
// Disable panel entirely (API only)
const kit = createWeDevKit({ panel: false });
// Enable panel and RGB only
const kit = createWeDevKit({ audio: false, media: false });
// Fine-grained config
const kit = createWeDevKit({
panel: { position: { x: 100, y: 50 }, theme: 'dark' },
audio: { amplitude: 0.8, bassBoost: 1.5, frameRate: 60 },
media: { autoCycle: true, cycleIntervalMs: 5000 },
});
// HTML script tag mode (IIFE)
//
//
```
---
## DevKitInstance — Top-Level Instance
The instance object returned by `createWeDevKit()`.
### Top-Level Methods
| Method | Signature | Description |
|---|---|---|
| `destroy` | `(): void` | Destroy all mocks, restore original state (JS timers, CSS, window globals) |
| `togglePanel` | `(): void` | Toggle control panel visibility |
| `getConfig` | `(): Readonly` | Get current config (read-only snapshot) |
| `pushProperties` | `(props: Record): void` | Manually trigger a property push (calls `applyUserProperties`) |
| `pushAudioFrame` | `(): void` | Manually trigger audio data push |
| `nextTrack` | `(): void` | Manually skip to next track |
| `setAudioEnabled` | `(enabled: boolean): void` | Set audio data input on/off (auto zero-fade on disable) |
### State
```typescript
interface DevKitState {
isLoaded: boolean; // Whether loaded
isPanelVisible: boolean; // Whether panel is visible
currentTrackIndex: number; // Current track index
playbackState: PlaybackState; // Playback state
isRgbPluginLoaded: boolean; // Whether RGB plugin is loaded (dynamic getter)
isAudioEnabled: boolean; // Whether audio input is enabled
}
```
> All `state` fields use lazy getters and always reflect the latest value.
### Sub-Controllers
| Field | Type | Description |
|---|---|---|
| `media` | `MediaController` | Media integration control |
| `rgb` | `RgbController` | RGB data access |
| `lifecycle` | `LifecycleController` | Lifecycle control |
| `properties` | `PropertiesController` | Property configuration |
---
## MediaController — Media Integration Control
Fully simulates all 5 WE Media Integration listeners + constants. Built-in library of 5 tracks (Jay Chou, Daft Punk, JJ Lin, Ludovico Einaudi, G.E.M.), each with a gradient SVG cover.
### Methods
#### Playback Control
| Method | Description | WE Behavior |
|---|---|---|
| `play()` | Play/resume | Pushes `wallpaperRegisterMediaPlaybackListener` state change |
| `pause()` | Pause | `PLAYING` → `PAUSED` |
| `stop()` | Stop | Any state → `STOPPED`, resets position |
**Behavior details:**
- Calling `play()` from `stopped`: pushes `STOPPED` then `PLAYING`, also pushes metadata and thumbnail
- Calling `play()` from `paused`: only pushes `PLAYING`, no metadata re-push
- Calling `pause()` from `playing`: only pushes `PAUSED`
#### Track Navigation
| Method | Description |
|---|---|
| `nextTrack()` | Next track (cycles) |
| `prevTrack()` | Previous track (cycles) |
| `setTrack(index)` | Jump to track at index |
**Behavior details:**
- Track changes do not send `STOPPED` (avoids UI flicker)
- Only updates metadata and thumbnail events
- Playback state unchanged
#### Custom Metadata
| Method | Description |
|---|---|
| `setCustomTrack({ title, artist, ... })` | Override current track metadata without changing track |
| `setCustomThumbnail(dataUri)` | Set custom cover art, auto-extracts dominant colors |
#### Seek Control
| Method | Description |
|---|---|
| `seek(pct)` | Seek to percentage 0–100 |
| `getPosition()` | Get current position (seconds) |
#### Read-Only Properties
| Property | Type | Description |
|---|---|---|
| `currentIndex` | `number` | Current track index |
| `playbackState` | `'playing' \| 'paused' \| 'stopped'` | Current playback state |
| `tracks` | `MockTrack[]` | Full track list |
### MockTrack Structure
```typescript
interface MockTrack {
title: string; // Title
artist: string; // Artist
album?: string; // Album name
genre?: string; // Genre
duration?: number; // Duration in seconds (default 240)
thumbnail?: string; // Base64 data URI cover
primaryColor?: string; // Primary color
secondaryColor?: string; // Secondary color
tertiaryColor?: string; // Tertiary color
textColor?: string; // Text color
highContrastColor?: string; // High-contrast color
}
```
### WE Event Mapping
| Controller Method | WE Listener Triggered | Event Type |
|---|---|---|
| `play()` | `wallpaperRegisterMediaPlaybackListener` | `MediaPlaybackEvent` |
| `pause()` | `wallpaperRegisterMediaPlaybackListener` | `MediaPlaybackEvent` |
| `stop()` | `wallpaperRegisterMediaPlaybackListener` | `MediaPlaybackEvent` |
| `setTrack()` / `nextTrack()` / `prevTrack()` | `wallpaperRegisterMediaPropertiesListener` + `wallpaperRegisterMediaThumbnailListener` + `wallpaperRegisterMediaTimelineListener` | `MediaPropertiesEvent` + `MediaThumbnailEvent` + `MediaTimelineEvent` |
| `seek()` | `wallpaperRegisterMediaTimelineListener` | `MediaTimelineEvent` |
| Progress update (every 100ms) | `wallpaperRegisterMediaTimelineListener` | `MediaTimelineEvent` |
| Initial push | `wallpaperRegisterMediaStatusListener` | `MediaStatusEvent` |
### Constants
`window.wallpaperMediaIntegration` contains:
```typescript
{
PLAYBACK_PLAYING: 0,
PLAYBACK_PAUSED: 1,
PLAYBACK_STOPPED: 2,
}
```
---
## RgbController — RGB Data Access
Intercepts `window.wpPlugins.led.setAllDevicesByImageData` calls (WE LED plugin interface), providing decoded data access and manual simulation.
### Methods
| Method | Return | Description |
|---|---|---|
| `getLastFrame()` | `RgbFrameData \| null` | Get last frame raw data |
| `getDecodedImageData()` | `ImageData \| null` | Decode to canvas ImageData (usable with `ctx.putImageData()`) |
| `getPalette()` | `{ color: string; ratio: number }[]` | Get last frame palette (up to 8 colors) |
| `onFrame(callback)` | `() => void` | Register frame callback, returns unsubscription function |
| `simulateFrame(width?, height?, pixelData?)` | `void` | Manually simulate an RGB frame |
### RgbFrameData Structure
```typescript
interface RgbFrameData {
width: number; // Pixel width
height: number; // Pixel height
pixels: number[]; // RGB pixel array [r0,g0,b0, r1,g1,b1, ...]
palette: { // Palette (descending by ratio)
color: string; // Hex color like "#4A90D9"
ratio: number; // Ratio 0–1
}[];
}
```
### Internal Mechanism
1. **Frame capture**: When a project sends LED data via `window.wpPlugins.led.setAllDevicesByImageData(imageData, width, height)`, it is automatically decoded and stored
2. **ImageData decoding**: RGB pixel array → canvas `ImageData` (with alpha channel), ready for `ctx.putImageData()`
3. **Palette extraction**: Divides image into 10×10 grid cells, averages color per cell, quantizes to 16 levels, aggregates top 8 colors
4. **Manual simulation**: Use `simulateFrame()` to generate test data without a real plugin
### Example
```typescript
// Get and draw last frame
const frame = kit.rgb.getLastFrame();
if (frame) {
const imgData = kit.rgb.getDecodedImageData();
canvas.getContext('2d')!.putImageData(imgData!, 0, 0);
console.log('Palette:', kit.rgb.getPalette());
}
// Listen to frames
const unsub = kit.rgb.onFrame(({ width, height, pixels, palette }) => {
console.log(`RGB frame: ${width}x${height}, ${palette.length} colors`);
});
// Unsubscribe
unsub();
// Manually simulate a frame
kit.rgb.simulateFrame(100, 20);
```
---
## LifecycleController — Lifecycle Control
Simulates WE pause/resume/FPS change lifecycle operations. All hijacked native JS timer functions are **automatically restored** on `destroy()`.
### Methods
| Method | Description | WE Behavior |
|---|---|---|
| `pause()` | Simulate WE wallpaper pause | Calls `wallpaperPropertyListener.setPaused(true)` |
| `resume()` | Simulate WE wallpaper resume | Calls `wallpaperPropertyListener.setPaused(false)` |
| `setFps(fps)` | Simulate FPS limit change | Calls `wallpaperPropertyListener.applyGeneralProperties({ fps })` |
### Read-Only Property
| Property | Type | Description |
|---|---|---|
| `isPaused` | `boolean` | Whether currently paused |
### Full Pause Behavior
`kit.lifecycle.pause()` synchronously performs:
1. **Call project callback**: Invokes any registered `wallpaperPropertyListener.setPaused(true)`
2. **CSS animation pause**: Adds class `wpxPausePseudoAnimationAll` to `` and injects a `