Start HereAI Integration

AI Integration

TAW ships a working toolkit for AI coding agents, not just documentation for them — skills, live introspection, direct field read/write with a mandatory safety model, static analysis, and CI, in the same spirit as Laravel Boost.

Point an agent at a TAW project, not just docs about one

TAW isn't just documented for AI coding assistants — it ships a working toolkit for them. An agent working in a TAW project can scaffold blocks, assemble full pages, implement Figma designs, populate real content, sync with the upstream scaffold, and inspect the live site's actual current state, not just read about how to do those things.

Two separate, independently-versioned sources of truth back all of this — don't conflate them:

  • taw-theme — the canonical scaffold. Synced into a client site via the update-theme skill.
  • taw/core — the framework package. Synced via composer update taw/core.

Architecture docs, picked up automatically

Any LLM-powered coding tool reads these on its own — no manual pointer needed:

FileRead by
AGENTS.mdClaude Code, Cursor, and generic agents — the comprehensive architecture guide
CLAUDE.mdClaude Code specifically
.github/copilot-instructions.mdGitHub Copilot
.windsurfrulesWindsurf / Codeium

AGENTS.md is the deepest of the four and the one the others point back to for full detail — if you're deciding where to add something, it goes there first.


Claude Code skills

Invoked by name (/make-metablock, etc.) or triggered automatically by a plain-language request that matches. Live in .claude/skills/, synced into client sites the same way as the rest of the framework-owned scaffold.

make-metablock

"add a pricing table section" → a fully wired MetaBlock: class, metabox fields, template, styles. Also accepts a pasted/attached screenshot as the design source.

build-page

"build a homepage with hero, features, and a contact form" → an entire page assembled from existing and newly-scaffolded blocks. Accepts a text brief, a Figma URL, or a screenshot.

figma-to-block

"implement this Figma design" → a block whose markup and metabox fields match the design exactly, driven by the Figma MCP tools — reference code, screenshot, and asset URLs, not eyeballed guesses.

populate-content

"fill in the team_members repeater on the About page with this list" → writes real field values via fields:set, with a mandatory dry-run + confirmation safety model (see below) before any risky write.

update-theme

"update the theme" → copies a small, precisely-delimited set of framework-owned paths (functions.php, .claude/skills/, bin/, CI config) from the canonical taw-theme repo. Direct file sync, no git merge, no shared history required — never touches your Blocks/, templates, or content.

project-init

"onboard this new client project" → picks up right after the first push: verifies gh CLI auth, enables and smoke-tests the GitHub Actions permission framework-sync.yml needs to open pull requests, then walks through optional integrations (Turnstile, email, CSS Studio, Visual Editor) as explicit yes/no questions instead of leaving them to be discovered later.

sync-remote

"sync with remote, please" → the standard pull → compare → resolve → push flow: fetches and compares against origin, reconciles diverged history via a real merge (never rebase, never a guessed conflict resolution), optionally runs phpstan, and always confirms before the final push.

studio

Applies live CSS Studio visual edits made in the browser back into source files.

export-static

"export the site as static" → a self-contained HTML/CSS/JS bundle for edge hosting (Cloudflare Pages, Vercel), via php bin/taw export:static. Forms and search deliberately stay live against WordPress rather than being frozen into the export.

audit-seo

"audit SEO for page 42" (or the whole site) → extracts a post's text-bearing copy and SEO meta (title tag, meta description, social image — Yoast-aware) via php bin/taw seo:extract, analyzes keyword presence, copywriting impact, and readability, then asks whether to apply directly or generate a shareable client-approval report before — only with explicit approval — writing rewrites back via php bin/taw seo:inject.

How the design-to-page skills compose

build-page orchestrates section-by-section decisions and delegates the actual block work:

  • A text-brief section → make-metablock
  • A Figma-sourced section → figma-to-block
  • A screenshot-sourced section → make-metablock (which also accepts screenshots directly)

For a Figma or screenshot brief, build-page asks once, for the whole page, whether to populate real extracted content, leave fields as template fallbacks, or fill with Lorem Ipsum placeholder content — then passes that answer down so individual section builds don't ask again. Any actual content write goes through populate-content, never a direct meta write from inside make-metablock/figma-to-block themselves.


Live introspection — php bin/taw inspect

Reports the site's actual current state: registered blocks and their real metabox field schemas, registered forms, the installed taw/core version, whether MetaboxOrder is locked. An agent queries this instead of reconstructing it by grepping PHP source — which can drift from what's actually registered at runtime.

php bin/taw inspect          # human-readable summary
php bin/taw inspect --json   # machine-readable

Direct field read/write — php bin/taw fields:get / fields:set

Read or write any Metabox/OptionsPage field's value directly, sanitized with the exact same rules a real admin form save uses — the same primitive VisualEditorEndpoint uses for its own REST-driven saves. No hand-encoding a repeater's JSON shape, no guessing which sanitizer applies to which field type.

php bin/taw fields:get 42 team_members --json                        # repeater comes back as a decoded array
php bin/taw fields:set 42 hero_heading "Welcome" --dry-run           # preview the sanitized result without writing

This is what turns "build this page from a Figma design" into something that can also populate the content, not just scaffold empty fields.

Content-writing safety model

Writing content is inherently higher-stakes than scaffolding it, so every skill that writes via fields:set follows a mandatory model — documented once, referenced everywhere it applies, not duplicated per skill:

Dry run, always

Never call fields:set for real without having already seen the --dry-run sanitized preview.

Confirm before overwriting non-empty content

Read the current value with fields:get first; if non-empty, show old vs. new side by side and get explicit confirmation — even if the existing content looks like a placeholder, it may be real.

Confirm before writing to a published post

Regardless of whether the target field is currently empty — a live, publicly-visible post is inherently higher-stakes than a draft.

One confirmation per batch, not per field

Show the entire plan — every post, field, and value that will change — before writing any of it. Never silently expand scope mid-batch.

Extra scrutiny on raw-HTML fields

wysiwyg fields (and anything with 'sanitize' => 'code') get flagged specifically when the source content came from outside the conversation — wp_kses_post() is deliberately permissive.

Never touches core post data

fields:set only ever writes Metabox/OptionsPage meta — never post_title, post_content, or post_status. A request implying a core-post-data change is treated as separate and higher-risk.

No wildcard mass-edits

Every post ID and field a batch operation will touch is enumerated and shown up front — never "every page matching X" without listing what that actually resolves to.

fields:set itself has no interactive confirmation built in — it's a raw primitive, usable from scripts, not just an AI agent. All of the above is agent-level policy (enforced by the calling skill), the same way this project's git-push confirmation is a policy the agent follows, not something git itself enforces.


WP-CLI — live site data access

bin/taw covers the framework (scaffolding, introspection, and now field-level content). For everything else — posts, users, terms, transients, arbitrary PHP via wp eval, an interactive wp shell — use WordPress's own official CLI. It's a host-level tool, not bundled by this theme, but present on virtually every real WordPress host and every local dev environment.

Full walkthrough, including the Local by Flywheel connection quirk that makes a bare wp command fail with a DB connection error even though the site works fine in the browser, is in the TAW Theme page.


CI, not just convention

.github/workflows/ci.yml runs two jobs on every push/PR:

  • composer validate and php -l across the repo
  • A dedicated check that every MetaBlock::getData() matches the exact signature the framework requires — a mismatch there is a site-wide PHP fatal, not a cosmetic bug, since every block auto-loads on every request
  • PHPStan (level 5, WordPress-aware via szepeviktor/phpstan-wordpress) over Blocks/ and inc/
  • A dynamic smoke test: a second job spins up a real WordPress + MySQL environment, activates the theme, creates a real post, and renders every registered block + form against it (bin/ci/smoke-test.php) — catching runtime errors (undefined function calls, template/data mismatches) that none of the static checks above can see

An agent doesn't have to trust its own read of a change — CI catches both static mistakes (a signature typo, a type error) and runtime ones (a block that only fails once it actually executes) that could slip through a plausible-looking diff.


Live documentation lookup

The mcp__taw-docs__search_documentation MCP tool, when available, searches this documentation site's current indexed content directly — hybrid semantic + keyword search — rather than requiring a URL guess or a stale cached answer.


External WordPress skill references

For general WordPress capabilities this framework doesn't already own an abstraction for, AGENTS.md/CLAUDE.md point at specific skills from WordPress/agent-skills: wp-phpstan (the source for the PHPStan setup above), wp-performance, wp-wpcli-and-ops, wp-playground. Deliberately not referenced: wp-block-development and wp-block-themes — those teach native Gutenberg blocks and theme.json, both of which TAW replaces with its own MetaBlock/Block system and Vite pipeline. Following them would fight this framework's conventions, not extend them.