Building Better Workflows with Claude and WordPress Studio

One of the most beneficial aspects of Claude and agentic development is being able to give it a persistent memory of how to interact with the codebase and what the codebase is. This will let you work faster and more efficiently — after all, wouldn’t you work faster if you were given an introduction to a codebase instead of just shown the code and told to ‘figure it out’?

For my own setup, I love working with WordPress Studio — it’s tightly integrated with Playground behind the scenes, and runs off an SQLite database, which makes it far less intrusive and likely to conflict with other local development environments or servers you may already have running — and trivial to sync between environments!

.claude/settings.json

Firstly, you can mitigate some of the interruptions about Claude prompting you for permission to do specific tasks, but granting them explicitly in advance. For example, we can add the following rules:

settings.json
JSON
{
"permissions": {
"allow": [
"WebFetch(domain:SITESUBDOMAIN.wp.local)",
"WebFetch(domain:wordpress.org)",
"Bash(sqlite3 wp-content/database/.ht.sqlite:*)",
"Bash(studio:*)"
]
}
}

Which will enable Claude to do things without needing to stop and confirm as frequently. Some of these might not make too much sense yet, but we’ll get to them below!

CLAUDE.md

CLAUDE.md is a file giving Claude a rough overview of what’s going on and directives. The sort of thing you want Claude to know and remember, but don’t want to have to repeat yourself on.

CLAUDE.md
Markdown
@AGENTS.md

There is also a movement to do a more general AGENTS.md file — most of these would cross-apply, and you can in fact include them in AGENTS.md and just include that in CLAUDE.md via

CLAUDE.md
Markdown
## What This Repository Is
A WordPress 6.9.4 development environment using SQLite as the database backend, managed by [WordPress Studio](https://developer.wordpress.com/docs/developer-tools/studio/cli/). The active development focus is the `plugin-name` Gutenberg block plugin, which does things.
**Local URL:** https://SITESUBDOMAIN.wp.local/

A high-level summary of the installation and how Claude can interact with it. Providing a local URL to be queried lets it check front-end output as needed, instead of constantly asking you for the current state or handling contingent decision paths that aren’t actually relevant.

CLAUDE.md
Markdown
## Environment Management (WordPress Studio)
The local server is managed by WordPress Studio. Key CLI commands:
```bash
studio site start # Start the local site
studio site stop # Stop the local site
studio site status # Check if the site is running
studio wp <wp-cli-command> # Run WP-CLI commands in the Studio context (no separate WP-CLI install needed)
```
Full CLI reference: https://developer.wordpress.com/docs/developer-tools/studio/cli/

Make sure to enable Studio CLI in Studio’s settings! Once that’s up and running, enabling WP-CLI through Studio can open up a world of tooling for Claude to use and run your setup.

CLAUDE.md
Markdown
## Plugin Development (plugin-name)
All plugin source lives in `wp-content/plugins/plugin-name/`. This directory has its own git repository.
@wp-content/plugins/plugin-name/CLAUDE.md

I tend to work off a repository hosting the plugin itself, rather than the whole install in the repository. This lets the plugin host its own `CLAUDE.md` file that gets included in the root and describes the plugin’s inner workings, without duplicating that here and having multiple locations to keep updated.

CLAUDE.md
Markdown
## Architecture
### Database
Uses SQLite instead of MySQL. The database file is at `wp-content/database/.ht.sqlite`. The SQLite Database Integration plugin (`wp-content/mu-plugins/sqlite-database-integration/`) provides the driver via the `wp-content/db.php` drop-in.
The system `sqlite3` binary is available and can be used to query the database directly when needed:
```bash
sqlite3 wp-content/database/.ht.sqlite "SELECT * FROM wp_options WHERE option_name = 'siteurl';"
```

Often it’s easier to have Claude look directly at the database to validate assumptions or check why something’s linking the way it is. Rather than have it rediscover how to each time, let’s just give it a quick summary and directions for how-to!

A Plugin’s CLAUDE.md

As we saw above, it’s often useful to include the plugin’s CLAUDE.md in the installation’s — it may only dig two directories down to discover them on its own and miss something in wp-content/plugins/plugin-name/ otherwise.

wp-content/plugins/plugin-name/CLAUDE.md
Markdown
## Architecture

This will vary from project to project — honestly, the easiest way to generate it is probably to have Claude generate phpdoc syntax for all your files and functions that don’t have it yet and then ask Claude to document it for you. This may not be perfect, but it’ll generally make a point of noting the salient details that it would want to find in the future.

wp-content/plugins/plugin-name/CLAUDE.md
Markdown
## Build System
Uses `@wordpress/scripts` (wraps webpack + Babel). The `--blocks-manifest` flag auto-generates `build/blocks-manifest.php`.
```bash
npm run build # Production build
npm run start # Development watch mode
npm run lint:js # JavaScript lint
npm run lint:css # CSS/SCSS lint
npm run format # Auto-format code
npm run plugin-zip # Create distributable zip
```
> Always run a build before testing PHP-side block registration changes — the manifest is generated at build time.
## PHP Linting (WPCS / PHPCS)
PHP coding standards are enforced via [WordPress Coding Standards](https://github.com/WordPress/WordPress-Coding-Standards). Config is in `phpcs.xml.dist`.
```bash
composer install # First time — installs PHPCS + WPCS into vendor/
composer lint:php # Run PHPCS
composer lint:php:fix # Run PHPCBF (auto-fix)
```

Document your build system, along with relevant commands for Claude to use.

wp-content/plugins/plugin-name/CLAUDE.md
Markdown
## Code Style
This project follows **WordPress Core coding standards** throughout, enforced by linting.
### PHP
- [WordPress PHP Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/): Yoda conditions, `array()` (not `[]`), tabs for indentation, spaces inside parentheses, `snake_case` for functions/variables, `PascalCase` for classes.
- Escape all output (`esc_html__()`, `esc_url()`, `esc_attr()`). Sanitize all input (`sanitize_text_field()`, `wp_unslash()`). Use `check_admin_referer()` for nonce verification before processing POST data.
- No direct database calls; use WordPress option and transient APIs.
### JavaScript / JSX
- [WordPress JavaScript Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/): tabs for indentation, spaces inside braces and parentheses, single quotes.
- Use `const`/`let`, never `var`.
- All user-visible strings must be wrapped in `__()` or `sprintf()` from `@wordpress/i18n`. `sprintf()` calls require a `/* translators: ... */` comment **inside the same JSX expression block** as the call (not on a separate line).
- Avoid flanking whitespace in translation strings — use `{ ' ' }` for explicit spaces between JSX nodes.
- `/* global SomeGlobal */` comments are required for browser globals not in the default ESLint environment (e.g. `MutationObserver`), and for WP-localized script globals (e.g. `bolPardot`).
### CSS / SCSS
- [WordPress CSS Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/css/): tabs for indentation, space before `{`, lowercase properties.
- Order pseudo-class selectors least-specific first: `&:disabled` before `&:focus` before `&:hover`.
- Avoid `input, textarea` combined rules when textarea needs additional properties — use separate blocks to satisfy `no-descending-specificity`.
- Use CSS custom property fallback chains: block-level `--bol-*` first, then `--global-palette*` (Kadence, if active), then `--wp--preset--*`, then a hardcoded default. Never rely on any single source being present.

It’s worthwhile to set up not only this but also something like Prettier to normalize things as you go — and doing so will avoid some IDEs accidentally using spaces instead of tabs or the like and leading to inconsistencies and extra fixer commits down the road.

wp-content/plugins/plugin-name/CLAUDE.md
Markdown
## Debugging approach
- **Check actual output before speculating.** When diagnosing a frontend issue, make an HTTP request to the local site (`https://pardot.wp.local/`) and inspect the rendered HTML or loaded CSS first. This is faster and more reliable than reasoning about what the output might be.
- **Ask the user questions early.** If a problem has multiple possible causes, ask a targeted question rather than running through all hypotheses. The user can often point you straight to the answer.

I’ve seen Claude get incredibly introspective sometimes — it will consider if the bug being reported actually existed, it will do entire rabbit holes of considering potential problems on a five minute loop, when it could just ask me a five second question and continue on.

Agentics can’t take Vyvanse, so we’ll try to keep it on task and have it communicate when it needs to.

wp-content/plugins/plugin-name/CLAUDE.md
Markdown
## Before marking any task as done
1. Run **both** linters and fix any reported issues:
```bash
npm run lint:js && npm run lint:css
composer lint:php
```
2. If the task adds or changes user-visible behaviour, update the **Help tab** in `includes/class-bol-admin-page.php` (`render_help_tab()`).
3. Update **`CLAUDE.md`** and **`.github/copilot-instructions.md`** with any architectural changes.
4. If any translatable strings were added, changed, or removed (in PHP or JS), regenerate the POT file:
```bash
studio wp --path=/Users/georgestephanis/Studio/pardot i18n make-pot wp-content/plugins/big-orange-pardot wp-content/plugins/big-orange-pardot/languages/big-orange-pardot.pot --domain=big-orange-pardot
```

Modern projects have many moving parts — and something like this helps to keep all the associated bits linked together properly and updated as needed.

The easiest way to set up WPCS is just to ask Claude (or Copilot, or others) to do it for you.

Conclusion

Hopefully this will give you some useful ideas for how to optimize your workflows and build tools. Have I missed some useful steps that you’ve found beneficial? Please let me know in the comments below and share your expertise with everyone!

Comments

Leave a comment