Oogle Manager
Oogle Manager — the control plane for Oogle products on a WordPress site.
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/neumanc/oogle-manager/archive/refs/heads/main.zipThe central control plane for Oogle products on a WordPress site.
Install oogle-manager.zip through Plugins → Add Plugin → Upload Plugin,
activate it, and WordPress gains a top-level Oogle menu:
- Dashboard — every Oogle product on the site with installed / active / version / update state, plus live status from Oogle MCP AI and the site's environment.
- Products — the same products with lifecycle actions: Install, Update, Activate, Deactivate, and a Check for updates button.
Installs and updates come straight from each product's GitHub Releases and are
performed by WordPress's own Plugin_Upgrader / Theme_Upgrader. Oogle Manager
never extracts archives itself, never accepts a package URL from a request, and
only ever installs products from its built-in trusted catalog.
Version 0.1.0 (pre-release) · Requires WordPress 6.9+ and PHP 8.1+ · GPL-2.0-or-later
The Oogle ecosystem
| Product | Role | Depends on Manager? |
|---|---|---|
| Oogle Manager (this plugin) | Control plane and product manager | — |
| Oogle Theme | Independent parent block theme; updates itself from GitHub | No |
| Oogle MCP AI | Independent, secure MCP/AI interface for WordPress | No |
Dependency direction is one way: Manager reads the other products through WordPress APIs and one documented function; they know nothing about Manager and behave identically whether Manager is installed, active or absent. Deactivating or deleting Manager changes nothing about them. See ARCHITECTURE.md.
Not in this family: the site-specific plugin also called "Oogle Core"
(oogle-core/oogle-core.php) that some Oogle-built sites run for their own
business logic. This plugin was renamed from Oogle Core to Oogle Manager on
2026-09-21 so the two cannot collide; Manager never manages or replaces it.
Responsibility boundaries are in ARCHITECTURE.md §1.
Requirements
| Requirement | Version |
|---|---|
| WordPress | 6.9 or newer (developed and tested on 7.1) |
| PHP | 8.1 or newer (tested on 8.1 and 8.4) |
| Outbound HTTPS | to api.github.com, raw.githubusercontent.com and github.com (release lookups and downloads) |
Oogle Manager stores no settings. Its only persistent data are short-lived transients (cached release lookups, one-shot notices), removed on uninstall.
What the screens show
For each product the registry answers, from WordPress's own APIs, whether it is
installed (get_plugins() / wp_get_theme()), active (is_plugin_active(),
get_stylesheet() / get_template() — a parent theme counts as active when
the active child theme uses it), which version, and — from the product's
GitHub Releases — which version is the latest, whether it is newer than the
installed one, and whether this server meets its Requires PHP /
Requires at least.
Oogle MCP AI additionally contributes live rows (abilities enabled, read-only
mode, MCP Adapter detection, registered ability count, audit logging) through
its public oogle_mcp_ai_status() function, with links to its settings and
audit log.
Installing and updating products
| Action | Capability required | What happens |
|---|---|---|
| Install | install_plugins / install_themes |
Latest release is re-fetched and validated, downloaded with core's safe HTTP client, verified against the release's .sha256 sidecar when one is published, then installed by Plugin_Upgrader::install() / Theme_Upgrader::install(). Never activates. |
| Update | update_plugins / update_themes |
Same, only when the release is strictly newer than the installed version; applied with Plugin_Upgrader::upgrade() / Theme_Upgrader::upgrade(), so WordPress's temp-backup/rollback applies. Downgrades are never offered. |
| Activate | activate_plugins / switch_themes |
activate_plugin() / switch_theme() after validate_theme_requirements(). |
| Deactivate | activate_plugins |
deactivate_plugins(). Themes cannot be deactivated. |
| Check for updates | manage_options |
Re-reads every product's latest release, bypassing the six-hour cache. |
All actions are admin-post.php forms with a nonce bound to the exact action
and product, run under WordPress's upgrader lock so two administrators cannot
modify files at once, and are refused when DISALLOW_FILE_MODS is set.
Updates for installed Oogle products also appear on Dashboard → Updates
and the Plugins / Themes screens: Manager answers WordPress's
update_plugins_github.com / update_themes_github.com filters (fired
because each product declares Update URI: https://github.com/…) from the
trusted catalog's validated release, at a late priority and only when nothing
earlier already answered. Oogle Theme's own updater therefore keeps precedence;
Oogle MCP AI (which has no updater of its own) becomes updatable through the
standard WordPress screens as long as Manager is active, and by ZIP upload otherwise.
Trusted catalog
src/Product/Catalog.php is the only place that knows which official products
exist and where their releases live:
| Slug | Type | Repository | Asset |
|---|---|---|---|
oogle-manager |
plugin | neumanc/oogle-manager |
oogle-manager.zip |
oogle-theme |
theme | neumanc/oogle-theme |
oogle-theme.zip |
oogle-mcp-ai |
plugin | neumanc/oogle-mcp-ai |
oogle-mcp-ai.zip |
A product's release must be a published (non-draft, non-prerelease) GitHub
Release tagged vX.Y.Z with an asset named <directory>.zip (or
<directory>-X.Y.Z.zip) whose single top-level folder is the product
directory. GitHub's automatic "Source code" archives are ignored. An optional
<asset>.sha256 asset is verified before installation.
A private repository cannot be installed from: WordPress's downloader has no credentials. Oogle MCP AI's repository is private at the time of writing, so Manager shows it but reports "GitHub returned HTTP 404" until the repository is public and has a release.
Optional GitHub token
define( 'OOGLE_GITHUB_TOKEN', '…' ); in wp-config.php raises the GitHub
API rate limit for hosts that share an IP address. It is sent to
api.github.com only, never to any other host, filtered URL or redirect
target, and never used for downloads.
Hooks
| Hook | Type | Purpose |
|---|---|---|
oogle_manager_products |
filter | Register additional products (arrays or Product objects) to show on the dashboard. Registered products are detected and displayed but are never installable or updatable through Manager (trusted is forced to false). Slugs colliding with official products are ignored. |
oogle_manager_product_details |
filter | Add label/value rows under an active product on the dashboard: array( 'label' => …, 'value' => …, 'state' => 'ok'\|'warn'\|'' ). Receives $rows, $slug, $status. |
oogle_manager_release_api_url |
filter | Releases API URL per product (tests, mirrors). |
oogle_manager_release_header_url |
filter | URL of a release's header file (used to read its requirements). |
oogle_manager_release_request_args |
filter | wp_remote_get() arguments for release lookups (proxy, timeout). Redirects and the token host allow-list are enforced after this filter. |
Public PHP surface: Oogle\Manager\Plugin::instance()->registry() returns the
Registry; everything else in the namespace should be treated as internal
until 1.0.
Development
npm install # installs @wordpress/env
npm run env:start # WordPress + MySQL in Docker (dev on :8888, tests on :8889)
npm run composer -- install # PHPUnit, WPCS inside the tests container
npm run lint # PHPCS (WordPress Coding Standards + PHPCompatibility 8.1+)
npm run test # PHPUnit against the WordPress core test suite
npm run zip # build/oogle-manager-<version>.zip (runtime files only)
Tests run against real WordPress (the core PHPUnit suite): fixture plugins and
themes are written to the real plugin/theme directories, activation goes through
activate_plugin() / switch_theme(), and installs run the real
Plugin_Upgrader with the download short-circuited to a local ZIP. GitHub is
never contacted from tests.
Repository layout:
oogle-manager.php bootstrap, version guard, deactivation
uninstall.php removes cached transients
src/
Product/ Product (catalog entry), Catalog (trusted list + filter),
LocalState + Detector (WordPress detection), ProductStatus, Registry
Release/ ReleaseSource interface, GitHubReleaseSource, Release
Install/ Installer (lifecycle actions), SilentSkin, Result
Update/ UpdateFilters (update_*_github.com answers)
Integration/ McpAi (reads oogle_mcp_ai_status())
Admin/ Admin (menu + screens), Actions (admin-post), Notices, views/
Support/ Version
assets/css/admin.css
tests/phpunit/
License
GPL-2.0-or-later. See LICENSE.