Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
a285938
chore: move the v1 plugin
aryanjasala Oct 1, 2026
d26005e
Refactor build strcutre to remove assets/src and add src/ and assets/…
pratik-londhe4 May 27, 2026
ed18535
PSR4 migration and WP Framework Integration (#661)
pratik-londhe4 May 27, 2026
985628e
feat: migrate eslint config
Swanand01 May 28, 2026
78944dd
feat: update deps
Swanand01 May 28, 2026
982fbd6
fix: remove @wordpress ignore
Swanand01 May 28, 2026
8cbc0c4
Fix Blocks getting copied over by wp-scripts in js/blocks
pratik-londhe4 May 27, 2026
3e77790
fix: revert the ranges
Swanand01 May 29, 2026
e981a49
Merge pull request #665 from rtCamp/feat/build-structure-refactor
pratik-londhe4 May 28, 2026
12517eb
chore: format
Swanand01 May 29, 2026
edce9e2
chore: format
Swanand01 May 29, 2026
d49ccae
chore: add package-lock
Swanand01 May 29, 2026
0764b1b
fix: order in package.json
Swanand01 May 29, 2026
e55790f
Merge pull request #666 from rtCamp/feat/update-tooling-versions
Swanand01 May 29, 2026
7bd0365
refactor(assets)!: replace AssetLoaderTrait with AssetLoader class (#…
aryanjasala Jun 4, 2026
81889e2
feat(components): wire framework ComponentLoader
aryanjasala Jun 4, 2026
e605df0
feat: add Copilot/AI instructions and framework instruction sync (#670)
aryanjasala Jun 7, 2026
8ea01e7
refactor(templates): consume the framework TemplateLoader class (#672)
aryanjasala Jun 11, 2026
1b267c7
feat(encryption): add a shared Encryption service over the framework …
aryanjasala Jun 11, 2026
8740bec
Add test matrix for the PHPUnit tests
pratik-londhe4 Jun 15, 2026
0b9826c
feat: block HMR, BrowserSync, recursive asset builds (#674)
pratik-londhe4 Jun 14, 2026
6f341aa
Update test matrix minimum version
pratik-londhe4 Jun 15, 2026
81c9937
chore: doc updates + BS enable/disable from env (#679)
pratik-londhe4 Jun 14, 2026
fe59334
Merge pull request #680 from rtCamp/feat/ci-php-wp-matrix
pratik-londhe4 Jun 16, 2026
1624757
refactor: name asset handles via AssetLoader::handle() (#705)
aryanjasala Jun 19, 2026
f88568c
feat(scaffold): delegate plugin setup to the shared wp-framework engi…
aryanjasala Jun 22, 2026
b44505d
docs: AGENTS-first instructions, README refresh, built-in AI skills (…
AnuragVasanwala Jun 22, 2026
c4378f0
docs: update README and internal testing guide with npm installation …
AnuragVasanwala Jun 22, 2026
399c8e6
fix(deps): pin eslint to 9.39.4; correct internal-testing recipe
AnuragVasanwala Jun 22, 2026
2f1811c
ci: fix FP-3 (private dep) + harden build-test-measure workflow
aryanjasala Jul 20, 2026
b954e59
chore(deps): pin rtcamp/wp-framework to ^1.0
aryanjasala Jul 27, 2026
002cb89
Revert "ci: fix FP-3 (private dep) + harden build-test-measure workflow"
aryanjasala Jul 20, 2026
da7b3a8
Merge remote-tracking branch 'origin/feature-plugin-skeleton-v2' into…
aryanjasala Jul 29, 2026
f8a0ef0
chore: pre-public hardening — license, pin CI actions, tidy README (v…
aryanjasala Jul 29, 2026
19151cc
chore(deps): pin rtcamp/wp-framework to ^1.0 (#734)
aryanjasala Jul 29, 2026
dc61420
chore(deps): bump rtcamp/wp-framework lock to v1.0.1
aryanjasala Jul 29, 2026
37511c2
feat: land the v2 pilot foundation on feature-plugin-skeleton-v2 (con…
aryanjasala Jul 29, 2026
0f5e5b7
chore(deps): bump rtcamp/wp-framework lock to v1.0.1 (#735)
aryanjasala Jul 29, 2026
43db2ca
fix(lint): declare the WordPress packages the blocks import, clear ES…
aryanjasala Jul 29, 2026
7dd8926
fix(deps): consume the rtCamp lint configs as wp-tooling subpaths (#737)
aryanjasala Jul 29, 2026
ebcd42f
fix(deps): consume the rtCamp npm packages from their split branches
aryanjasala Jul 29, 2026
3c89406
Merge pull request #738 from rtCamp/fix/eslint-example-blocks
aryanjasala Jul 29, 2026
d2110c2
Merge pull request #739 from rtCamp/chore/npm-branch-splits
aryanjasala Jul 29, 2026
636f80a
fix(deps): resolve the rtCamp coding standards from their released mi…
aryanjasala Jul 29, 2026
05c59a7
feat(init): add opt-in dev-tools feature to the scaffold config (#745)
Adi-ty Sep 11, 2026
13e01c7
docs(dev-tools): demo prompts and e2e check for the wp-dev-tools loop…
Adi-ty Sep 25, 2026
59c007c
docs: add Features Plugin Skeleton guides (#758)
divyarajmasani Sep 28, 2026
9a00259
chore: rename wp-framework to wp-primitives, features-plugin-skeleton…
aryanjasala Oct 1, 2026
e324949
chore(ai): resync primitives-php instructions from wp-primitives 2.0
aryanjasala Oct 1, 2026
4d1c0fe
fix(blocks): give the interactive example the plugin's text domain an…
aryanjasala Oct 1, 2026
5a2c0e6
refactor(js): replace the console.log demos in the starter entries
aryanjasala Oct 1, 2026
78f96ab
fix(assets): register the editor script and style only when the build…
aryanjasala Oct 1, 2026
dda6850
chore: test against current WordPress and fix the Tailwind dependency…
aryanjasala Oct 1, 2026
90fd570
docs: point the guides and the docs workflow at main
aryanjasala Oct 1, 2026
5f8e732
style(js): make every JS file pass the shared lint
aryanjasala Oct 1, 2026
d918ede
build(lint): accept Tailwind v4 at-rules in stylelint
aryanjasala Oct 1, 2026
ce62f47
ci: run Test and Measure on pushes to main
aryanjasala Oct 1, 2026
d8aa31d
fix(shortcode): render a title or content of "0"
aryanjasala Oct 1, 2026
79f2370
fix(blocks): style the example blocks and guard their templates
aryanjasala Oct 1, 2026
b7e0872
fix(scripts): keep npm run lint and npm test to the checks
aryanjasala Oct 1, 2026
4a17210
fix(hmr): move the block dev server off the wp-env port
aryanjasala Oct 1, 2026
712325d
fix(graphify): find the uv-managed interpreter by package
aryanjasala Oct 1, 2026
bcb707b
docs: point at wp-primitives 2.0 and drop resolved gaps
aryanjasala Oct 1, 2026
fecb16d
fix(hmr): give the plugin its own block dev server port
aryanjasala Oct 1, 2026
cc9c8f7
docs(npmrc): describe the public git install of the @rtcamp packages
aryanjasala Oct 1, 2026
c2b8e9f
fix(util): keep get_data() inside inc/data
aryanjasala Oct 1, 2026
d0dc836
fix(graphify): report only an installed graphify, and drop stale doc …
aryanjasala Oct 1, 2026
a156ace
fix(dev-server): read port settings as whole numbers only
aryanjasala Oct 1, 2026
73069d4
build(composer): lock rtcamp/wp-primitives in place of wp-framework
AnuragVasanwala Oct 1, 2026
844d8ef
chore: add aryanjasala and AnuragVasanwala as code owners
aryanjasala Oct 1, 2026
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
1 change: 1 addition & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends @wordpress/browserslist-config
21 changes: 21 additions & 0 deletions .claude/skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# AI skills

Skills for AI assistants (Claude Code, Cursor, and any tool that reads the Claude Code skill convention) that drive this plugin's setup and the `@rtcamp/wp-tooling` scaffold engine. Each skill is a directory with a `SKILL.md` (frontmatter `name:` + `description:`, portable Markdown body).

| Skill | Invoke | What it does |
|---|---|---|
| [`init/`](init/SKILL.md) | `/init` | Turn this cloned skeleton into a named project and manage it afterwards: rename the starter tokens, keep/remove the example sets, toggle optional features (Tailwind, HMR, Dev Tools). Drives `npm run init`. |
| [`scaffold/`](scaffold/SKILL.md) | `/scaffold` | Add one feature (CPT, taxonomy, block, REST controller, shortcode, cron, CLI, settings page, user role, service, CI workflow) via `npx wp-tooling add`, TDD-first. |
| [`setup/`](setup/SKILL.md) | `/setup` | Generic tooling bootstrap for plugins and themes, shipped with `@rtcamp/wp-tooling`. Not a personalization path for this skeleton; use `/init`. |

`init` is skeleton-specific. `scaffold` tracks `@rtcamp/wp-tooling` and introspects the project, so it stays correct as the layout evolves. `setup` has no Copilot counterpart.

Developer-facing descriptions of both routes are in [docs/initialization.md](../../docs/initialization.md) and [docs/scaffolding.md](../../docs/scaffolding.md).

**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).

## 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 without approval. `init` additionally never runs a destructive setup without confirming the resolved values against a clean working tree.

Consented exceptions to the package-manager rule: `npm run init` (the project's own setup script), and the `npm install`/`composer install` `init` runs at the start of setup. After any code change, the skills refresh the LOCAL graph with `graphify update .`; they never commit it and never run the cross-repo `/graphify . --update` or `merge-graphs` (see [AGENTS.md](../../AGENTS.md)).
118 changes: 118 additions & 0 deletions .claude/skills/init/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
name: init
description: Set up this cloned plugin-elementary into a named project, or manage its identity and capabilities later. Installs dependencies (`npm install`, `composer install`), then drives `npm run init`. Always confirms before destructive or install steps; expects a clean working tree.
---

# init

Two jobs: **bootstrap + setup** a fresh clone into a real plugin, or **manage** an already-set-up project. Always interactive: gather inputs first, confirm the resolved plan, then act. This skill is a thin front end for `npm run init` - it does not reimplement what the engine already asks for.

## Use for
- First run: install dependencies, rename starter tokens, pick capabilities to keep.
- First run WITH a feature brief: after rename + capabilities, implement the described features by chaining to the **scaffold** skill (TDD), replacing the matching `Example*` placeholders (step 5).
- Later: rename / re-prefix, toggle features (Tailwind, HMR, Dev Tools).

## Do not use for
- Adding a feature class → the **scaffold** skill (`npx wp-tooling add`).
- Bug fixes, refactors, hand-written features.
- Re-running init to change capabilities after first setup. Removal is one-shot (markers are consumed); a second run leaves dangling `Main::CLASSES` refs. Set the set ONCE; change it later via scaffold.

## Be interactive (required)
Ask the developer for every input the chosen path needs, in ONE batched message, before acting. Never assume a project name. Show derived values back in that same exchange. Wait for explicit consent before any install, file rewrite, or destructive step. If an answer is missing, ask; do not guess.

## Plan and announce (required) - developer experience first
1. **State the plan up front** in one short message: the mode (setup / manage) and the ordered steps for THIS request - detect mode -> install deps -> ask + run init -> (setup with a brief) hand each feature to the scaffold skill.
2. **Maintain a live TODO list** (`TodoWrite` in Claude Code): one entry per planned step, exactly one `in_progress` at a time.
3. **Announce each step with a short title** and report its outcome in one line. Never go silent during a long step.

## Steps

### 1. Detect mode
```bash
test -f .wp-scaffold.json && echo manage || echo setup
```
No `.wp-scaffold.json` → **setup**. Present → **manage** (read it for current identity; `npm run init -- --list` shows feature status).

### 2. Install dependencies
With consent, run:
```bash
npm install
composer install
```
Skip either that's already installed and current. If consent is declined, surface both as developer actions and stop - init cannot run without them.

Then verify a clean working tree (`git status`) - init rewrites files irreversibly, and a clean tree is the only undo. If dirty, ask to commit/stash.

### 3. Ask, confirm, run - one step
`npm run init` is a single command; don't turn gathering its inputs into a multi-round-trip wizard.

**Setup:** in ONE message ask for project name (required, e.g. `Acme Blog` → namespace `Acme_Blog\Features`, package `rtcamp/acme-blog-features`, text domain, prefixes, main file - show these back), version (default `1.0.0`), which capability sets to remove, and which features to enable (defaults: keep all sets, `hmr` on, `tailwind` and `dev-tools` off - see Capability model). The engine derives the tokens itself; do not read the engine source (`identity.js` etc.) - the mapping above is the contract, and the graph answers any deeper question (see the graphify policy in `AGENTS.md`).

**Manage:** ask which of identity / features to change. It's a single flag on an existing project - no wizard needed.

Get explicit consent on the resolved values (init is destructive), then run:
```bash
# Setup:
npm run init -- --name="Acme Blog" --version=1.0.0 --yes \
--remove-examples=cron,rest --features=hmr,tailwind,dev-tools
# Manage:
npm run init -- --list
npm run init -- --enable=dev-tools --yes
npm run init -- --features=hmr --yes # exact enabled set (empty = none)
```
- `--keep-examples` keeps all; `--remove-examples` (no value) removes all; `--remove-examples=a,b` removes listed keys.
- `--features=a,b` sets the exact enabled set; `--enable`/`--disable` are deltas.
- `--yes` requires `--name`. For the guided wizard, run bare `npm run init` (space toggles, enter confirms) - the wizard already asks everything above, so prefer it over hand-building flags when the developer has no strong opinion on the exact command.
- `npm run init` also runs `npm run sync-ai`; that is expected.

**Setup WITH a feature brief - clear the briefed examples in THIS step (not a separate round-trip):** keep the capabilities the brief needs (do NOT list them in `--remove-examples`); remove every other capability. Then, batched with the init run, strip the kept-briefed capabilities of their demo code so scaffold can fill them: for each, delete the `Example*` class file(s) under `inc/Modules/<Kind>/`, delete `tests/php/<Cap>Test.php`, and set that module's `get_classes()` to `return [];` (drop the example `use` imports). The module stays wired in `Main::CLASSES` - only its example contents go, leaving an empty, already-wired module ready for scaffold. Example: brief = Testimonial CPT + Industry taxonomy + draft REST -> keep `post-types`/`taxonomies`/`rest`, `--remove-examples=blocks,shortcodes,cli,cron,settings,roles,cache,transients,admin`, then empty the PostTypes/Taxonomies/REST modules.

### 4. After init
- Tailwind enabled → developer runs `npm install` (it added `src/css/tailwind.css`, `postcss.config.js`, and pinned `@rtcamp/tailwind-config`).
- Dev Tools enabled → it's still a private package (`rtcamp/wp-dev-tools`, VCS-sourced): developer runs `composer update rtcamp/wp-dev-tools`, which may need GitHub auth, then `npm run dev:connect`.
- `composer dump-autoload` (engine runs it when `composer.json` is present).
- Trust the engine's own output to verify (it reports the removed sets, drops their `Main::CLASSES` lines and tests, and regenerates the autoloader). To confirm a symbol or reference, run a single `graphify query`/`affected` against the graph - never grep `Main.php`/`inc/` to check removal.
- If you hand-edited PHP and are NOT handing off to scaffold (e.g. a manage-mode dangling `Main::CLASSES` cleanup), run `composer lint` on the change and fix it. When a brief follows (step 5), leave the lint/PHPStan/test gates to the scaffold skill - init does not run them.
- **Refresh the LOCAL graph** with `graphify update .` (plugin slice, tree-sitter, no API, seconds). **Never commit or push `graphify-out/graph.json`** - the committed file is a maintainer-maintained cross-repo baseline (rebuilt and pushed when this or a shared repo changes); your local refresh stays local. Do NOT run the cross-repo `/graphify . --update` subagent or `merge-graphs` (expensive; clobbers the baseline). If graphify is not installed, say so in one line; do not block.
- Report: new identity, capabilities removed/kept, features toggled, outstanding developer actions.

### 5. Implement the brief by handing off to scaffold (setup only, when features were described)
By this point step 3 has already emptied the briefed capabilities (their `Example*` classes/tests are deleted and the modules are empty but still wired in `Main::CLASSES`). init's remaining job is purely to **hand each described feature to the scaffold skill** - it does NOT build the class, write or run tests, set up the test env (`npm run wp-env start`), or run the lint/PHPStan gates. The **scaffold skill takes over** and owns all of that.

For each described feature, **invoke the scaffold skill**, passing the brief (e.g. a `testimonial` CPT; an `industry` taxonomy attached to `testimonial`; a REST controller that creates testimonials in `draft`). The scaffold skill owns conventions, the `wp-tooling add` call, wiring into the already-present module, the TDD loop, test execution, and the gates - report its result; do not duplicate that work here.

**Pass your findings to scaffold (speeds it up).** init has already resolved the project identity while renaming, so hand those values to the scaffold skill in the same message instead of making it re-derive them. State explicitly: the resolved **PHP namespace root** (e.g. `Acme\Testimonials`), **base_path** (`inc`), **tests_namespace** (e.g. `Acme\Testimonials\Tests`), **tests_path** (`tests/php`), **text_domain** and **slug** (e.g. `testimonial-features`), the **plugin display name**, and **which capabilities step 3 kept-and-emptied** (their `inc/Modules/<Kind>/` folders already exist and are wired in `Main::CLASSES`, so scaffold wires into them rather than creating a module). With these provided, the scaffold skill skips its own `composer.json` / plugin-header / `Main.php` discovery reads. It still reads source files when it needs exact code (the graph and a handoff are for orientation, not a substitute for reading).

For a kept capability the brief did NOT mention, leave its `Example*` but tell the developer it is demo-only, not for deployment, and offer to scaffold a real class or drop the capability.

End state: init has renamed, trimmed capabilities, and emptied the briefed examples (step 3); the scaffold skill has implemented the real features.

## Capability model
ONE "Select the capabilities to include" prompt. Each is keep-or-remove; removing deletes it entirely (concrete classes, `inc/Modules/<X>.php`, its `Main::CLASSES` line, coupled Core regions, feature deps).

| Category | Keys |
|---|---|
| Content | `post-types`, `taxonomies` |
| Editor & Front-end | `blocks`, `shortcodes`, `tailwind` (feature) |
| APIs & Automation | `rest`, `cli`, `cron` |
| Admin | `settings`, `admin`, `roles` |
| Utilities | `cache`, `transients` |
| Developer Tooling | `test-measure` (CI workflow), `hmr` (feature), `dev-tools` (feature) |

Sets are kept by default; pass keys to `--remove-examples` to drop. Features: `hmr` on, `tailwind` and `dev-tools` off; toggle via `--features`/`--enable`/`--disable`. `dev-tools` (`rtcamp/wp-dev-tools`, runtime telemetry over MCP - Query Monitor + the MCP Adapter) is the one feature still sourced from a private VCS repo; enabling it needs GitHub auth on `composer update` (see step 4). Everything else here installs from public registries.

### Changing capabilities after setup
Add later → scaffold skill / `npx wp-tooling add <category>/<slug>` (writes the class, wires the module). Remove later → delete its `inc/Modules/<X>/` classes + `Main::CLASSES` line by hand. Toggle a feature any time via `npm run init -- --enable=<key>`/`--disable=<key>`. Do not re-run init to change the capability set.

## Hard rules
- **BASE (see AGENTS.md guardrails):** never run history/remote `git`/`gh` (commit, push, `branch -D`, `reset --hard`, PR, issue comment, `gh secret set`) - print them as developer actions. Never do a destructive operation outside this plugin directory.
- Never commit or push `graphify-out/graph.json`; local graph refreshes stay local.
- Package managers only with consent: `npm install`, `composer install` (step 2), and `npm run init`. Outside those, surface install commands as developer actions.
- Never run a destructive init without confirming resolved values, on a clean tree.
- Never commit, push, open PRs, or edit `.wp-scaffold.json` by hand.
- Never invent flags. Supported: `--name`, `--version`, `--yes`, `--keep-examples`, `--remove-examples[=...]`, `--features`, `--enable`, `--disable`, `--reinit`, `--list`, `--clean`, `--help`. Run `npm run init -- --help` if unsure.

## Reference
- Engine: `@rtcamp/wp-tooling/init` (via `bin/init.js`). Capability map: `bin/scaffold.config.js`. Dev Tools feature: `bin/features/dev-tools.js`.
- Conventions renamed into: `AGENTS.md`, `.github/instructions/structure.instructions.md`.
- Graphify policy: `AGENTS.md`.
Loading
Loading