For developers & agencies
Plain PHP you can read, hooks you can use
You never need any of this to use NiroCoder. But if you build sites for a living: every extension is ordinary WordPress PHP in one folder with full version history, and the plugin has a REST API, 9 actions and 18 filters behind it.
On disk
One folder per extension, nothing hidden
Generated code lives in wp-content/nirocoder/extensions/<slug>/. The manifest is the source of truth; code/ is what runs; history/ keeps every version.
- Every PHP file declares namespace NiroCoder\Ext\<Studly>; so extensions never collide
- Extensions load on plugins_loaded at priority 20, after every regular plugin, before init
- Each one runs in an isolated scope with only $nirocoder_ext (slug, dir, url, version)
- Writes are atomic and path-checked; OPcache is invalidated for every PHP file written
- On Nginx, deny web access to wp-content/nirocoder/, the bundled .htaccess covers Apache and LiteSpeed
wp-content/nirocoder/ extensions/ books-catalog/ manifest.json name, type, risk, status, version, plan, dependencies, security report, last error code/ the live, checked files extension.php staging/ generated code waiting for the check history/ <YmdHis>-v<N>-<created|updated|undo>/ trash/ removed extensions logs/ nirocoder_ext_log() outputFive helpers every extension can use
Deliberately small. No per-extension constants, so nothing collides or lingers after an extension is turned off.
| Setting | Default | What it does |
|---|---|---|
| nirocoder_ext_dir( $slug ) | string | Absolute path to the extension’s code/ folder. |
| nirocoder_ext_url( $slug ) | string | URL of code/, for enqueuing the extension’s own CSS and JS. |
| nirocoder_ext_option( $slug, $key, $default ) | mixed | Read from the extension’s private store. |
| nirocoder_ext_update_option( $slug, $key, $value ) | bool | Write to it, one non-autoloaded option per extension. |
| nirocoder_ext_log( $slug, $message ) | void | Append to logs/<slug>.log; rotates at 1 MB and keeps 5 files. |
nirocoder_ext_dir( $slug )
string
Absolute path to the extension’s code/ folder.
nirocoder_ext_url( $slug )
string
URL of code/, for enqueuing the extension’s own CSS and JS.
nirocoder_ext_option( $slug, $key, $default )
mixed
Read from the extension’s private store.
nirocoder_ext_update_option( $slug, $key, $value )
bool
Write to it, one non-autoloaded option per extension.
nirocoder_ext_log( $slug, $message )
void
Append to logs/<slug>.log; rotates at 1 MB and keeps 5 files.
REST API
nirocoder/v1
The admin app runs on it, so anything the screens do, you can script. Every route requires manage_options; authenticate with the REST nonce or an application password.
- AI
- GET /ai/state · POST /ai/register · /ai/verify · /ai/resend · /ai/reset · GET /ai/usage
- Site
- GET /site/context · POST /site/context/rescan
- Chats
- GET|POST /chats · GET|PATCH|DELETE /chats/{id} · POST /chats/{id}/messages · POST …/messages/{mid}/cancel
- Extensions
- GET /extensions · POST /extensions/build · POST /extensions/pause-all · GET|DELETE /extensions/{slug} · GET …/files · …/error · …/build · POST …/activate · …/deactivate · …/undo · …/cancel · …/export
- Settings
- GET|POST /settings, the AI group is read-only through this route
- Activity
- GET /activity, paged, up to 200 per page, filter by extension_slug
Hooks & filters
9 actions, 18 filters
Ordinary WordPress hooks, for reacting to an extension being built, turned on or stopped, tuning the security check, or swapping the AI client.
Actions
- nirocoder_extension_built( $slug, $manifest, $is_new )
- A build passed the check and its code is live in code/.
- nirocoder_extension_blocked( $slug, $report, $is_new )
- The security check stopped a build. Nothing on the site changed.
- nirocoder_extension_activated( $slug, $manifest )
- An extension was turned on.
- nirocoder_extension_deactivated( $slug, $manifest )
- An extension was turned off.
- nirocoder_extension_stopped( $slug, $error, $auto_stop )
- A crash was recorded, the place to send your own alert.
- nirocoder_extension_undone( $slug, $restored_version, $manifest )
- An extension was rolled back to its previous version.
- nirocoder_extension_removed( $slug, $trash_dir )
- An extension was moved to the trash.
- nirocoder_extensions_paused( $paused )
- Pause all was turned on or off.
- nirocoder_extension_exported( $slug, $result, $snapshot )
- An export .zip was written, before it is downloaded.
Filters
- nirocoder_security_rules
- Add or remove rules from the local security check.
- nirocoder_security_php_binary
- The php binary used for php -l; false forces PHP’s own parser.
- nirocoder_missing_dependencies
- Adjust which required plugins count as missing.
- nirocoder_activate_smoke
- Turn off the safe test that loads an extension in a separate process before it goes live.
- nirocoder_smoke_php_binary
- The PHP CLI binary for that safe test; an empty string skips it.
- nirocoder_activate_probe
- Turn the post-activation loopback check off.
- nirocoder_ai_client
- Supply your own AI client.
- nirocoder_ai_mock_delay
- Delay for the offline mock’s responses.
- nirocoder_controllers
- Add or replace the plugin’s controllers.
- nirocoder_load_public_assets
- Opt in to the plugin’s public assets.
- nirocoder_get_posts
- Filter the posts helper’s results.
- nirocoder_export_allowed
- Override whether the current plan may export.
- nirocoder_export_slug
- The exported plugin’s folder name.
- nirocoder_export_header
- Header fields of the exported plugin.
- nirocoder_export_files
- The final file map of an export.
- nirocoder_export_license
- Default license of an export.
- nirocoder_updater_enabled
- Turn off update checks against NiroSuite.
- nirocoder_update_url
- Point the update feed somewhere else, such as a staging site.
Export as plugin
Take any extension with you
On a paid plan, export downloads a standard, installable plugin .zip that runs without NiroCoder. It is built locally and costs no credits. The free trial can build and run extensions but not export them.
- Re-checked on export: files that no longer pass are refused
- Never includes the manifest, history, logs, option data or any key
- Same input, same zip, entries are sorted with a fixed timestamp
- Steps aside with a notice if the same extension is active in NiroCoder
- Provided as is: no auto-stop, Pause all, history, undo or Fix with AI
nirocoder-books-catalog/ nirocoder-books-catalog.php header + bootstrap includes/runtime.php the five nirocoder_ext_* helpers readme.txt code/ the extension’s files, verbatimQuestions
The files are on disk and readable, but NiroCoder manages them: the next change with AI or an undo replaces code/. To own the code outright, export the extension as a plugin (a paid-plan feature) and edit that.
PHP 7.4 or later. The admin app needs WordPress 6.6 or later; the plugin is tested up to the version in its readme.
On plugins_loaded at priority 20, after every regular plugin has booted and before init. An extension can register post types, hooks, shortcodes and admin screens exactly as a plugin would.
There is no code viewer in wp-admin yet. The files are on disk under wp-content/nirocoder/extensions/<slug>/code/, and GET /nirocoder/v1/extensions/{slug}/files returns them to an administrator.
Hook into nirocoder_extension_stopped. It passes the slug, the error (message, file, line, type, time) and whether auto-stop turned the extension off, so you can send it to email, Slack or your error tracker.
Yes. Add define( 'NIROCODER_AI_MOCK', true ); to wp-config.php and connect with any key that starts with mock-. NiroCoder then uses an offline mock with scripted scenarios, including a build the security check blocks. It is meant for demos, screenshots and tests, not for building real features.
Not yet. The admin screens run on the nirocoder/v1 REST API, so you can script the same actions with an application password instead.
Read the code it writes
Install NiroCoder, build something small, and open wp-content/nirocoder/extensions/.