Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ Skills for AI assistants (Claude Code, Cursor, and any tool that reads the Claud

`init` is theme-specific. `scaffold` tracks `@rtcamp/wp-tooling` and introspects the project, so it stays correct as the layout evolves. [`setup/`](setup/SKILL.md) (`/setup`) is the generic natural-language tooling bootstrapper for empty/existing projects. Use `/init` to personalize this skeleton; `/setup` does not replace its identity and capability flow.

**Copilot parity:** `init` and `scaffold` also exist for GitHub Copilot as prompt files in [`.github/prompts/`](../../.github/prompts/) (`/init`, `/scaffold`), kept consistent with these skills. Shared conventions and the knowledge-graph (graphify) policy live in [`AGENTS.md`](../../AGENTS.md).
**Copilot parity:** `init` and `scaffold` also exist for GitHub Copilot as prompt files in [the maintained Copilot prompts](https://github.com/rtCamp/theme-elementary/tree/main/.github/prompts) (`/init`, `/scaffold`), kept consistent with these skills. Shared conventions and the knowledge-graph (graphify) policy live in [`AGENTS.md`](../../AGENTS.md).

## Safety

These skills are opinionated about safety and never: run a package manager or `npm run build` without consent; read, log, or transmit secret values; apply cross-file wiring without showing the diff and getting consent; or commit, push, or open PRs. `init` additionally never runs a destructive setup without confirming the resolved values against a clean working tree.

Dependency installation and `npm run init` require consent. The init skill uses the declared dependencies; Composer's install hook already runs npm. Sibling dependency checkouts are maintainer work. After file changes, refresh the local graph with `graphify update .`.

Cleanup currently removes `.github`, including Copilot prompts; `sync-ai` restores only generated framework instructions. The Claude skills remain. Review these removals before personalizing a clone.
Cleanup removes the Copilot-specific files under `.github` (`copilot-instructions.md`, `prompts/`, `instructions/`); issue templates, the PR template, `dependabot.yml`, `release.yml`, and workflows stay. `sync-ai` restores only generated framework instructions. The Claude skills remain. Review these removals before personalizing a clone.
4 changes: 2 additions & 2 deletions .claude/skills/init/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: init
description: Set up this cloned theme-elementary into a named theme, or manage its identity and capabilities later. Installs the declared public dependencies, accounting for the Composer npm hook. Drives `npm run init`. Always confirms before destructive or install steps; expects a clean working tree.
description: Set up this cloned theme-elementary into a named theme, or manage its identity and capabilities later. Installs the declared dependencies, accounting for the Composer npm hook. Drives `npm run init`. Always confirms before destructive or install steps; expects a clean working tree.
---

# init
Expand Down Expand Up @@ -49,7 +49,7 @@ This theme's Composer `post-install-cmd` runs `npm i`; do not immediately repeat
### 3. Preconditions (verify; do not silently fix)
- `node_modules/@rtcamp/wp-tooling` exists (the engine needs it). If missing, surface the required installation command and stop.
- Clean working tree (`git status`). Init rewrites files irreversibly; a clean tree is the only undo. If dirty, ask to commit/stash.
- Setup only: confirm this is a clone meant to become a new theme, not the maintained skeleton. Manage mode operates on an already-personalized project.
- Setup only: confirm this is a clone meant to become a new theme, not the maintained starter theme. Manage mode operates on an already-personalized project.

### 4. Gather inputs
**Setup:** theme name (required, e.g. `Acme Blog` → namespace `rtCamp\Theme\Acme_Blog`, package `rtcamp/acme-blog`, text domain, constant/function/CSS prefixes, the `style.css` + `functions.php` headers; show these back); version (default `1.0.0`); which example sets to remove and which features to enable (defaults: keep all sets, hmr on, tailwind and dev-tools off). The engine derives the tokens itself; do not read the engine source to work them out - the mapping above is the contract, and the graph answers any deeper question (see the graphify policy in `AGENTS.md`).
Expand Down
10 changes: 5 additions & 5 deletions .claude/skills/scaffold/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: Add a scaffold (PHP class, dynamic block, shortcode, settings page,

Drive `@rtcamp/wp-tooling`. Map the developer's request to a scaffold, derive test cases first, invoke the engine, expand tests, implement to green, report.

This skill is the canonical wp-tooling scaffold skill, tailored to this theme's structure (`inc/Modules/<Kind>`, namespace `<Root>\Modules\<Kind>`, tests in `tests/php/`) and the private-package pilot. **Wiring difference from a plugin:** this theme lists every class directly in `inc/Main.php` `Main::CLASSES` (no per-kind `AbstractModule` with a `get_classes()` array), so a new artifact's `::class` line is inserted into `Main::CLASSES` (and a `use` import added), not into a module file.
This skill is the canonical wp-tooling scaffold skill, tailored to this theme's structure (`inc/Modules/<Kind>`, namespace `<Root>\Modules\<Kind>`, tests in `tests/php/`). **Wiring difference from a plugin:** this theme lists every class directly in `inc/Main.php` `Main::CLASSES` (no per-kind `AbstractModule` with a `get_classes()` array), so a new artifact's `::class` line is inserted into `Main::CLASSES` (and a `use` import added), not into a module file.

## Use for

Expand Down Expand Up @@ -132,7 +132,7 @@ Result shape: `{ scaffold, engine, developer, ai, warnings }`.
| Block | Action |
|---|---|
| `engine.wrote` / `engine.skipped` | Already on disk. Report. |
| `developer.install.composer` / `developer.install.npm` | Print as copy-paste command. **Never run `composer require` / `npm install`.** Pilot notes: npm installs need `npm install --install-links`; the framework (`rtcamp/wp-framework`) already ships, so ignore a `composer require rtcamp/wp-framework` suggestion. |
| `developer.install.composer` / `developer.install.npm` | Print as copy-paste command. **Never run `composer require` / `npm install`.** The framework (`rtcamp/wp-framework`) already ships; do not repeat its installation. Use the theme's documented dependency setup. |
| `developer.secrets` | Print as `gh secret set` checklist. **Never read/write/log/transmit values.** |
| `ai.wiring` | Adaptive wiring with consent (see 6a). |
| `ai.tests` | Mandatory expansion under TDD loop (see 7). |
Expand Down Expand Up @@ -195,16 +195,16 @@ Then report:
- Wiring applied: `inc/Main.php` line, the `Main::CLASSES` entry + `use` import added.
- Tests authored and pass count per file.
- Lint + PHPStan result.
- Outstanding developer actions: composer / npm installs (pilot: `--install-links`), `npm run build` (blocks), secrets to set, branch-protection note (CI).
- Outstanding developer actions: composer / npm installs, `npm run build:prod` (blocks), secrets to set, branch-protection note (CI).

## Pilot environment + engine quirks (this theme)
## Theme environment and generated-code checks

**Test env + linters (`wp-env`):**
- Always use `npx wp-env` (or `node_modules/.bin/wp-env`), never bare `wp-env`.
- **Run PHP linters inside wp-env (PHP 8.2).** The host PHP may be newer than the pinned `wp-coding-standards/wpcs` supports, which makes the sniffs throw deprecation errors and abort. Run e.g. `npx wp-env run cli --env-cwd=/var/www/html/wp-content/themes/$(basename "$PWD") -- vendor/bin/phpcs <files>` (PHPStan tolerates newer PHP, so `composer phpstan` is fine on the host).
- If `wp-env start` reports a port already allocated, start on free alternates: `WP_ENV_PORT=8890 WP_ENV_TESTS_PORT=8891 npm run wp-env start` (find a free pair with `lsof -nP -iTCP:<port> -sTCP:LISTEN`). The theme's default ports are 5890 (dev) / 5891 (tests).
- `wp-env start` can flake on a transient image pull (TLS timeout); one retry is allowed, and exit 0 does not mean "up" - confirm the start output reports success.
- `pretest:php` runs `composer install` in the `cli` container; if `npm run test:php` fails on it, run PHPUnit directly: `npx wp-env run cli --env-cwd=/var/www/html/wp-content/themes/$(basename "$PWD") -- vendor/bin/phpunit -c phpunit.xml.dist`.
- `pretest:php` runs `composer install --no-interaction --no-scripts` in `tests-cli`. Resolve installation errors before testing; see [Local development](../../../docs/local-development.md#check-a-change) for the tested commands.

**Generated-code quirks (write the code right up front; these survive `composer phpcs:fix`):**
- **Fully-qualify WP global classes** (`\WP_Error`, `\WP_REST_Request`, `\WP_REST_Response`) everywhere they appear - in code AND docblocks - with NO `use` statement for them. Reason: `composer phpcs:fix` force-qualifies `WP_Error` (Slevomat `FullyQualifiedExceptions` treats `*Error` as an exception) and then strips the now-unused imports, including docblock-only ones; PHPStan (scanning `inc/`) then reports `class.notFound`. Writing them fully-qualified avoids the fix -> phpstan round-trip.
Expand Down
2 changes: 1 addition & 1 deletion .github/prompts/init.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Follow the theme-specific [init skill](../../.claude/skills/init/SKILL.md) as th

Gather missing setup or manage inputs in one message, show derived values and the resolved command, and wait for consent before installation or rewriting. Do not assume a theme name. Use Copilot's task surface to track the workflow where available.

- Fresh setup: `composer install` already invokes npm installation. The declared wp-tooling and wp-framework sources are public; no pilot sibling clone or registry token is required.
- Fresh setup: `composer install` invokes npm installation. If Composer runs with `--no-scripts`, run `npm install` separately.
- Defaults: retain examples, HMR on, Tailwind and Dev Tools off. Dev Tools is an optional private dependency with its own access requirement.
- `--list` (optionally `--json`) and help are read-only and do not run `sync-ai`.
- `--yes` needs `--name` only in setup mode. Manage-mode feature toggles need no name.
Expand Down
87 changes: 87 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Documentation

on:
push:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation action was updated, check the final workflow here,

https://github.com/rtCamp/wp-framework/blob/main/.github/workflows/documentation.yml

branches: [theme-elementary-v2]
paths:
- 'docs/**'
- 'README.md'
- 'DEVELOPMENT.md'
- 'CONTRIBUTING.md'
- '.github/workflows/documentation.yml'
pull_request:
branches: [theme-elementary-v2]
paths:
- 'docs/**'
- 'README.md'
- 'DEVELOPMENT.md'
- 'CONTRIBUTING.md'
- '.github/workflows/documentation.yml'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: documentation-${{ github.event_name == 'pull_request' && github.ref || 'production' }}
cancel-in-progress: true

jobs:
build:
name: Build documentation
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
pages: read
steps:
- name: Checkout documentation
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Read Pages configuration
id: pages
if: >-
(github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
github.ref_type == 'branch' && github.ref_name == 'theme-elementary-v2'
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0

- name: Build documentation
id: docs
uses: rtCamp/action-docusaurus-build@b671d6800c68a74da8913edb9321422fe8afaedc
with:
site-title: Theme Elementary
site-url: ${{ steps.pages.outputs.origin }}
base-url: ${{ steps.pages.outputs.base_url && format('{0}/', steps.pages.outputs.base_path) || '' }}
sidebar: >-
["index", "getting-started", "initialization", "local-development", "features", "scaffolding"]

- name: Upload GitHub Pages artifact
if: >-
(github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
github.ref_type == 'branch' && github.ref_name == 'theme-elementary-v2'
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: ${{ steps.docs.outputs.build-directory }}
include-hidden-files: true

deploy:
name: Deploy documentation
needs: build
if: >-
(github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
github.ref_type == 'branch' && github.ref_name == 'theme-elementary-v2'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ feature, TDD-first), exist for both assistants and must stay in step:

## Knowledge graph (graphify)

The repo keeps a queryable code graph in `graphify-out/` (`graph.json` + `GRAPH_REPORT.md`) covering this theme (and, optionally, the `wp-framework`/`wp-tooling` it builds on). Use it to understand the codebase, and keep it current. Tell the user each graphify step in <=30 words (50 max). Only the `init`/`scaffold` agentic tools run these commands; Copilot review does not. Setup detail: `docs/knowledge-graph.md`.
The repo keeps a queryable code graph in `graphify-out/` (`graph.json` + `GRAPH_REPORT.md`) covering this theme (and, optionally, the `wp-framework`/`wp-tooling` it builds on). Use it to understand the codebase, and keep it current. Tell the user each graphify step in <=30 words (50 max). Only the `init`/`scaffold` agentic tools run these commands; Copilot review does not. Setup detail: `docs/internal/knowledge-graph.md`.

**Graph-first: do not read source files to understand them when the graph can answer.** Before opening a file to learn what a symbol does, how a subsystem works, or how the theme wires together - including `wp-tooling` engine internals (token derivation, capability removal, etc.) - query the graph (`/graphify query "<q>"`, `explain "<symbol>"`, `path "A" "B"`). You almost never need to read engine source: the engine is a black box these skills invoke, and the skill already documents the outcome (how a theme name becomes namespace/package/prefixes). Read a file only when the graph does not answer, or when you need exact code to edit.

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Before reading source files to answer questions about architecture, symbols, cal
- Use the `/graphify` skill, or the CLI: `graphify query "<question>"`, `graphify path "A" "B"`, `graphify explain "<symbol>"`, `graphify affected "<symbol>"`.
- The graph is structural (tree-sitter, local, no API key). Read files only when the graph does not answer.

Regenerate after large changes; recipe in [docs/knowledge-graph.md](docs/knowledge-graph.md).
Regenerate after large changes; recipe in [docs/internal/knowledge-graph.md](docs/internal/knowledge-graph.md).

Claude-specific notes:
- _(none currently; keep Claude overrides here if they ever diverge from AGENTS.md)_
31 changes: 12 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,28 @@ starter theme built on the `rtcamp/wp-framework` package.

## Development setup

Requires the Node version in `.nvmrc` (`nvm use`) and PHP 8.2+.
Use [Getting started](docs/getting-started.md) for dependency installation and
[Local development](docs/local-development.md) for the daily environment,
build, and verification workflow. The project requires the Node version in
`.nvmrc` and PHP 8.2+.

```bash
nvm use
composer install # PHP dependencies + tooling (PHPCS, PHPStan)
npm install # build toolchain
```
For release validation, local dependency work, and documentation publishing, use
the [maintainer guidance](docs/internal/README.md).

## Building assets

```bash
npm start # watch build (blocks + assets)
npm run build:prod # production build
```
Use [Local development](docs/local-development.md#edit-source-and-see-the-result)
for watch builds and [the delivery build](docs/local-development.md#build-for-delivery)
for production output.

## Before you open a PR

Run the checks — all must pass:

```bash
npm run lint:all # PHP (PHPCS) + JS (ESLint) + CSS (Stylelint)
composer phpstan # static analysis
npm test # JS + PHP test suites (PHP runs via @wordpress/env)
```
Run the relevant focused tests and lint commands in
[Local development](docs/local-development.md#check-a-change); all must pass.

## Pull request checklist

- [ ] `npm run lint:all` and `composer phpstan` pass.
- [ ] `npm test` passes.
- [ ] The relevant focused tests and lint commands pass.
- [ ] New/changed behavior is covered by tests.
- [ ] Commits follow [Conventional Commits](https://www.conventionalcommits.org/).

Expand Down
Loading
Loading