A WordPress plugin that reimagines /wp-admin as a desktop operating system. Admin screens open as draggable, resizable, minimizable windows on a desktop, with a left-edge dock built from the admin menu. Purely opt-in per user — the classic admin stays untouched for everyone else, and deactivating the plugin restores vanilla Core exactly.
Zero Core patches. Every feature is wired through public WordPress hooks.
Per-user opt-in
Admin-bar toggle sets the desktop_mode_mode user meta. A dedicated /desktop-mode/ portal URL auto-enables desktop mode for first-time visitors (gated by desktop_mode_portal_auto_enable) and the admin_init redirect sends opted-in users from /wp-admin/ to the portal (desktop_mode_admin_redirect_to_portal).
Desktop shell
Fixed-viewport desktop that overlays /wp-admin: wallpaper area, unified dock (placement picked in OS Settings — left / right / bottom, default bottom), right-column widget layer, and full windowing system. desktop_mode_mode_init, desktop_mode_shell_before / _after, and the desktop_mode_shell_config filter are the main extension points.
Window system — iframe + native
Iframe windows load admin pages with ?wp_desktop=1 (chromeless mode). Native windows render directly in the parent DOM via desktop_mode_register_window() / wp.desktop.registerWindow() — multi-tab native windows are supported through desktop_mode_register_window_tab(). Both types share drag, resize, minimize, maximize, close, fullscreen, and detach-to-new-tab.
Dock
One unified rail hosting every admin menu — core and plugin alike — plus shell-level system tiles. Placement (left / right / bottom) is the user's OS Settings preference. Core menus are ordered before plugin menus; per-item hiding via desktop_mode_dock_placement ('hidden'). Per-item multi-window support via desktop_mode_dock_item_multi. Letter-badge icon fallback for plugins without icon art.
Virtual desktops (“Spaces”) Multiple desktops per user, each with its own window set. Overview grid (zoom-out view) surfaces the Spaces switcher, thumbnails, and create/close controls.
Arrange & snap
Admin-bar Arrange menu: Cascade, Tile, Overview, Snap to grid. Plugins contribute custom entries via desktop_mode_arrange_menu_items and react to clicks via desktop-mode.arrange.custom-action. Tile grid dimensions and snap cell size are both filterable.
Wallpaper registry
Server- and client-side registration (desktop_mode_register_wallpaper() / wp.desktop.registerWallpaper()). CSS presets + canvas (WebGL/2D) wallpapers with collision-aware surface data (wp.desktop.getWallpaperSurfaces()) for snow/rain/physics effects. In-panel renderEditor callback for custom controls, shared vendor-module loader (pixijs pre-registered).
Widgets
Right-column floating cards, optionally draggable / resizable outside the column. desktop_mode_register_widget() / wp.desktop.registerWidget(). Built-in clock. User placement persists per-user in localStorage.
Desktop icons
Wallpaper-layer shortcuts via desktop_mode_register_icon() — targets a registered native window or an admin URL.
AI Assistant + slash commands
Cmd+K palette backed by an OpenAI agentic loop whose search_posts / search_pages / search_comments tools run WordPress's native keyword search. Admin-configured API key + model picker. The only automatic AI analysis is comment spam scoring (on comment save), which feeds the comments-window spam score; posts, pages, and terms are not analyzed. wp.desktop.registerCommand() adds slash commands with autocomplete (suggest()), confirm dialogs (ctx.confirm()), and full lifecycle hooks (before-run / after-run / error). Built-in /open [window] is extensible via desktop-mode.open-command.items.
Palette registry
Cmd+K cycles through all registered palettes (wp.desktop.registerPalette()) — the AI assistant is palette 0 by default; additional plugin overlays share the shortcut.
Cross-frame drag bridge Media-library attachments drag across iframe boundaries via coordinated postMessage. Site-wide toggle through the Extended Options REST endpoint.
Toast notifications
Shell-level toasts rendered via the <wpd-toast> component. Plugins register their own tone/icon via the desktop_mode_toast_types filter. Iframe pages raise a toast through the desktop-mode-notification bridge message — it survives the iframe's own lifecycle.
OS Settings
Native-window settings panel: wallpaper picker (with HD-only media filter), accent color swatches + custom gradient editor, dock size slider, AI platform config, and per-user default-on-startup window. Persisted via /desktop-mode/v1/os-settings.
Session persistence
Full window stack (including desktops, focus, state) is debounce-saved to /desktop-mode/v1/session and restored without layout flicker. Viewport-shrink clamping keeps off-screen windows reachable.
postMessage bridge
Typed messages for title changes, navigation (same-origin validated), focus, color-scheme sync, screen-meta panels (Screen Options / Help), external-link capture, iframe-ready handshake, and observability (iframe-error, iframe-network).
UI component library
~25 <wpd-*> web components (wpd-button, wpd-menu, wpd-panel, wpd-range-field, wpd-swatch, wpd-toast, wpd-tabs, …) available to plugin authors — rendered server-side via desktop_mode_component() or imported in TS.
i18n
Full gettext coverage across PHP and TypeScript; Spanish translation shipped. Strings go through wp.i18n (__, _x, _n, sprintf) directly — no shell-specific re-export.
Component registration API
Stable desktop_mode_register_* functions for windows, widgets, wallpapers, icons, and window tabs. All return true / WP_Error with documented error codes.
Public hook API
Comprehensive PHP and JS hook surface — dock items, placement, multi-window, native-window lifecycle, widget lifecycle, wallpaper lifecycle + surfaces, window lifecycle, iframe observability, arrange actions, virtual-desktop transitions, palette registration, command lifecycle, batch close, AI prompt + model + post-type filters, accents, toast types, default wallpaper. See docs/hooks-reference.md and docs/javascript-reference.md.
wp.desktop.mode = 'desktop' | 'tablet' | 'mobile' surface.See docs/architecture.md for how the pieces fit together and docs/hooks-reference.md for the hook surface (current and planned).
``` . ├── desktop-mode.php # bootstrap: header, constants, require_once of includes/ ├── includes/ # PHP subsystems │ ├── helpers.php admin-bar.php ajax.php │ ├── assets.php render.php portal.php │ ├── session.php default-window.php components.php │ ├── os-settings.php extended-options.php │ ├── accents.php wallpapers.php toast-types.php │ ├── media-query.php │ └── ai-copilot/ # AI assistant (OpenAI client, analysis, search, jobs) ├── assets/ # hand-authored CSS + JS build output │ ├── css/ desktop.css, windows.css, dock.css, chromeless.css, variables.css │ └── js/ Vite bundles (gitignored; regenerate with npm run build) — only │ admin-bar.js and media-library-enhanced.js are hand-written and tracked ├── src/ # TypeScript source — compiled by Vite │ ├── desktop.ts / dock.ts / hooks.ts / commands.ts / palette-registry.ts │ ├── ai-assistant/ + drag-bridge.ts / toast.ts / desktop-icons.ts │ ├── native-windows.ts / built-in-commands.ts / public-api.ts / types.ts │ ├── window/ # Window class — DOM, pointer, tabs, iframe bridge │ ├── window-manager/ # stack, desktops, arrange, snap, overview │ ├── wallpapers/ # registry, layer, surfaces, server sync, vendor loader │ ├── widgets/ # registry, layer, frame, picker, storage │ ├── settings/ # OS Settings panel sections │ ├── ui/ # web components │ ├── modules/ # vendor-script lazy-loader │ └── plugins/ # built-in demos (animated-logo-wallpaper) ├── docs/ # developer-facing docs (source of truth for plugin authors) ├── extensions/ # bundled sibling plugins (see "Bundled extensions" below) ├── tests/ # PHPUnit + Vitest ├── languages/ # .po / .mo (es shipped)
$ claude mcp add desktop-mode \
-- python -m otcore.mcp_server <graph>