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:
{ "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.
@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
What This Repository IsA WordPress 6.9.4 development environment using SQLite as the database backend, managed by WordPress Studiohttps://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.
Environment Management (WordPress Studio)The local server is managed by WordPress Studio. Key CLI commands:bashstudio site start # Start the local sitestudio site stop # Stop the local sitestudio site status # Check if the site is runningstudio 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.
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.
Architecture DatabaseUses 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:bashsqlite3 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.
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.
Build SystemUses @wordpress/scripts (wraps webpack + Babel). The --blocks-manifest flag auto-generates build/blocks-manifest.php.bashnpm run build # Production buildnpm run start # Development watch modenpm run lint:js # JavaScript lintnpm run lint:css # CSS/SCSS lintnpm run format # Auto-format codenpm 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 Standardshttps://github.com/WordPress/WordPress-Coding-Standards. Config is in phpcs.xml.dist.bashcomposer install # First time — installs PHPCS + WPCS into vendor/composer lint:php # Run PHPCScomposer lint:php:fix # Run PHPCBF (auto-fix)
Document your build system, along with relevant commands for Claude to use.
Code StyleThis project follows WordPress Core coding standards throughout, enforced by linting. PHP WordPress PHP Coding Standardshttps://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 Standardshttps://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 Standardshttps://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.
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.
Before marking any task as done Run both linters and fix any reported issues:bashnpm run lint:js && npm run lint:csscomposer lint:php If the task adds or changes user-visible behaviour, update the Help tab in includes/class-bol-admin-page.php (render_help_tab()). Update CLAUDE.md and .github/copilot-instructions.md with any architectural changes. If any translatable strings were added, changed, or removed (in PHP or JS), regenerate the POT file:bashstudio 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!


Leave a comment