|
1 | 1 | # Copilot Instructions |
2 | 2 |
|
3 | | -## Project Overview |
| 3 | +Use this file as a quick execution guide for this repository. If instructions conflict, follow this precedence: |
4 | 4 |
|
5 | | -WP Sudo is a WordPress plugin that provides action-gated reauthentication. Dangerous operations (plugin activation, user deletion, critical settings changes, etc.) require password confirmation before they proceed — regardless of user role. |
| 5 | +1. `AGENTS.md` |
| 6 | +2. `CLAUDE.md` |
| 7 | +3. This file |
6 | 8 |
|
7 | | -- **Requirements:** WordPress 6.2+, PHP 8.0+ |
8 | | -- **Repository Type:** WordPress Plugin |
9 | | -- **Primary Language:** PHP, JavaScript |
10 | | -- **Frameworks:** WordPress, WordPress Block Editor (Gutenberg), @wordpress/scripts |
11 | | -- **Target Runtime:** WordPress 6.8+, PHP 8.1+ |
| 9 | +## Repository Snapshot |
12 | 10 |
|
13 | | -## Critical Build Instructions |
| 11 | +- Project: WP Sudo (WordPress plugin) |
| 12 | +- Runtime requirements: WordPress 6.2+, PHP 8.0+ |
| 13 | +- Plugin version source of truth: `wp-sudo.php` (`Version` header + `WP_SUDO_VERSION`) |
| 14 | +- Architecture center: `includes/class-gate.php` |
| 15 | +- Built-in gated actions: 32 rules (single-site + multisite) |
14 | 16 |
|
15 | | -### Environment Requirements |
| 17 | +## What This Plugin Does |
16 | 18 |
|
17 | | -- **PHP:** 8.1 or higher (plugin requires PHP 8.1+) |
18 | | -- **Composer:** 2.8.12 or higher |
| 19 | +WP Sudo requires reauthentication before dangerous actions execute (plugin/theme changes, user/role operations, key settings changes, etc.). It enforces this across admin UI, AJAX, REST, WP-CLI, Cron, XML-RPC, and WPGraphQL policy surfaces. |
19 | 20 |
|
20 | | -### Dependency Versions |
| 21 | +## Ground Rules For Changes |
21 | 22 |
|
22 | | -#### npm Packages |
23 | | -- **@wordpress/scripts:** 30.26.0 or higher |
| 23 | +- Follow TDD: write/adjust failing tests first, then production code. |
| 24 | +- Do not invent external plugin methods/classes/hooks/meta keys. |
| 25 | +- Verify external technical references against authoritative sources before writing docs or integration code. |
| 26 | +- Keep lifecycle behavior safe and idempotent (activation, deactivation, uninstall, upgrades). |
| 27 | +- Do not weaken capability checks, nonce checks, sanitization, or escaping. |
24 | 28 |
|
25 | | -#### Composer Packages |
26 | | -- **wp-coding-standards/wpcs:** 3.0 or higher |
| 29 | +## Correct Commands |
27 | 30 |
|
28 | | -### Dependency Installation |
| 31 | +### Setup |
29 | 32 |
|
30 | | -**ALWAYS install dependencies in this exact order before any build operations:** |
31 | | - |
32 | | -1. **npm dependencies (REQUIRED FIRST):** |
33 | | - ```bash |
34 | | - npm install |
35 | | - ``` |
36 | | - - Takes approximately 60 seconds on first install |
37 | | - - May show deprecation warnings (these are non-critical) |
38 | | - - May show 2 moderate severity vulnerabilities (these are from dev dependencies and are non-critical) |
39 | | - - Creates `node_modules/` directory (ignored by git) |
40 | | - |
41 | | -2. **Composer dependencies (for PHP linting only):** |
42 | | - ```bash |
43 | | - composer install —no-interaction |
44 | | - ``` |
45 | | - - Takes approximately 30-60 seconds |
46 | | - - May prompt for GitHub OAuth token if run interactively; use `—no-interaction` flag to avoid this |
47 | | - - Falls back to cloning from git cache if GitHub API rate limits are hit |
48 | | - - Creates `vendor/` directory (ignored by git) |
49 | | - - Installs WordPress Coding Standards (WPCS) for PHP linting |
50 | | - |
51 | | -#### Composer Commands |
52 | | - |
53 | | -```bash |
54 | | -composer install # Install dev dependencies |
55 | | -composer test # Run all unit tests (PHPUnit 9.6) |
56 | | -composer lint # Run PHPCS (WordPress-Extra + WordPress-Docs + WordPressVIPMinimum) |
57 | | -composer lint:fix # Auto-fix PHPCS violations |
58 | | -composer analyse # Run PHPStan level 6 (use --memory-limit=1G if needed) |
59 | | -composer sbom # Regenerate CycloneDX SBOM (bom.json) |
60 | | -``` |
61 | | - |
62 | | -No build step. No npm. No production dependencies — only dev dependencies. |
63 | | - |
64 | | -Always run `composer test` and `composer analyse` before committing. |
65 | | - |
66 | | -### Build Process |
67 | | - |
68 | | -**ALWAYS run build after making JavaScript/CSS changes:** |
69 | | - |
70 | | -```bash |
71 | | -npm run build |
72 | | -``` |
73 | | -- Takes approximately 1-2 seconds |
74 | | -- Uses webpack via @wordpress/scripts |
75 | | -- Generates files in `build/` directory (ignored by git, but required for plugin to function) |
76 | | -- Creates `build/blocks-manifest.php` (automatically generated, do NOT edit manually) |
77 | | -- Creates minified JavaScript, CSS, and asset dependency files in `build/wp-sudo/` |
78 | | -- Build output includes RTL CSS variants automatically |
79 | | - |
80 | | -**For development with hot reload:** |
81 | 33 | ```bash |
82 | | -npm run start |
| 34 | +composer install |
83 | 35 | ``` |
84 | | -- Watches for file changes and rebuilds automatically |
85 | | -- Generates unminified source maps for debugging |
86 | | -- Use Ctrl+C to stop the watch process |
87 | 36 |
|
88 | | -**To clean and rebuild:** |
89 | | -```bash |
90 | | -rm -rf build/ |
91 | | -npm run build |
92 | | -``` |
| 37 | +### Test and Quality Gates |
93 | 38 |
|
94 | | -### Linting and Code Quality |
95 | | - |
96 | | -**JavaScript/JSX Linting:** |
97 | 39 | ```bash |
98 | | -npm run lint:js |
| 40 | +composer test:unit |
| 41 | +composer test:integration |
| 42 | +composer analyse:phpstan |
| 43 | +composer analyse:psalm |
| 44 | +composer lint |
99 | 45 | ``` |
100 | | -- Uses ESLint with WordPress coding standards |
101 | | -- Checks all `.js` files in `src/` |
102 | | -- Must pass with no errors before committing |
103 | | -- Some warnings are acceptable |
104 | 46 |
|
105 | | -**CSS/SCSS Linting:** |
106 | | -```bash |
107 | | -npm run lint:css |
108 | | -``` |
109 | | -- Uses stylelint with WordPress standards |
110 | | -- Checks all `.scss` files in `src/` |
111 | | -- Must pass with no errors before committing |
112 | | - |
113 | | -**Auto-formatting:** |
114 | | -```bash |
115 | | -npm run format |
116 | | -``` |
117 | | -- Uses Prettier to auto-format JavaScript, JSON, CSS/SCSS |
118 | | -- **ALWAYS run this before linting if you get Prettier errors** |
119 | | -- Automatically fixes most lint issues related to formatting |
120 | | -- Safe to run on all files |
| 47 | +### Optional Utilities |
121 | 48 |
|
122 | | -**PHP Linting:** |
123 | 49 | ```bash |
124 | | -./vendor/bin/phpcs wp-sudo.php |
| 50 | +composer test:coverage |
| 51 | +composer sbom |
125 | 52 | ``` |
126 | | -- Uses PHP_CodeSniffer with WordPress Coding Standards |
127 | | -- Available coding standards: WordPress, WordPress-Core, WordPress-Docs, WordPress-Extra |
128 | | -- The main plugin file may have known PHPCS warnings (tabs vs spaces, line length) - these may be acceptable per project style |
129 | | -- Auto-fix many PHP issues with: `./vendor/bin/phpcbf wp-sudo.php` |
130 | | - |
131 | | -**NOTE:** This project uses **tabs for indentation** (not spaces) per WordPress coding standards, as specified in `.editorconfig`. The PHPCS errors about “spaces must be used” are using the wrong standard and can be ignored. |
132 | | - |
133 | | -## Repository Structure |
134 | | - |
135 | | -- `wp-sudo.php` — Plugin entry point, autoloader, lifecycle hooks. |
136 | | -- `includes/` — Core PHP classes (namespace `WP_Sudo`). Key classes: Plugin, Gate, Action_Registry, Challenge, Sudo_Session, Request_Stash, Admin, Admin_Bar, Site_Health, Upgrader. |
137 | | -- `admin/js/` — Vanilla JS for challenge page and admin bar timer. No build step. |
138 | | -- `admin/css/` — Stylesheets for challenge page and admin bar. |
139 | | -- `tests/Unit/` — PHPUnit tests using Brain\Monkey (no WordPress loaded). |
140 | | -- `bridges/` — Drop-in 2FA bridge files for third-party plugins. |
141 | | -- `ROADMAP.md` — Unified roadmap: integration tests, WP 7.0 prep, TDD strategy, core design features, feature backlog, accessibility appendix. |
142 | | -- `CHANGELOG.md` — Full version history. |
143 | | -- `FAQ.md` — All frequently asked questions. |
144 | | -- `docs/` — Documentation suite: |
145 | | - - `security-model.md` — Threat model, boundaries, environmental considerations. |
146 | | - - `developer-reference.md` — Hook signatures, filters, custom rule structure. |
147 | | - - `ai-agentic-guidance.md` — AI and agentic tool integration guidance. |
148 | | - - `two-factor-integration.md` — 2FA plugin integration guide. |
149 | | - - `two-factor-ecosystem.md` — 2FA plugin ecosystem survey. |
150 | | - - `ui-ux-testing-prompts.md` — Structured UI/UX testing prompts. |
151 | | -- `bom.json` — CycloneDX SBOM (regenerate with `composer sbom`). |
152 | 53 |
|
153 | | -## Architecture |
| 54 | +## Important Reality Checks |
154 | 55 |
|
155 | | -**Bootstrap:** `plugins_loaded` → `Plugin::init()` → loads translations, runs upgrader, registers gate, sets up challenge page, initializes admin UI. |
| 56 | +- There is no production JS build pipeline for current plugin runtime assets. |
| 57 | +- Do not introduce or depend on `build/` artifacts unless explicitly requested. |
| 58 | +- Do not assume npm is required for normal PHP/plugin development in this repo. |
| 59 | +- Frontend assets used by the plugin live in `admin/js/` and `admin/css/`. |
156 | 60 |
|
157 | | -**Gate pattern:** Multi-surface interceptor matches incoming requests against the Action Registry (29 rules across 7 categories + 8 multisite rules). Admin requests get the stash-challenge-replay flow. AJAX/REST get error responses. CLI/Cron/XML-RPC follow per-surface policies (Disabled, Limited, Unrestricted). |
| 61 | +## File Map |
158 | 62 |
|
159 | | -**Sessions:** Cryptographic token stored in user meta + httponly cookie. Progressive rate limiting (5 attempts → 5-min lockout). |
| 63 | +- Entry point: `wp-sudo.php` |
| 64 | +- Core classes: `includes/` |
| 65 | +- Optional bridges: `bridges/` |
| 66 | +- MU support: `mu-plugin/` |
| 67 | +- Unit tests: `tests/Unit/` |
| 68 | +- Integration tests: `tests/Integration/` |
| 69 | +- Security + developer docs: `docs/` |
| 70 | +- Roadmap and planning: `.planning/` |
160 | 71 |
|
161 | | -## Coding Standards |
| 72 | +## Before Commit |
162 | 73 |
|
163 | | -- WordPress Coding Standards (WPCS) enforced via PHPCS. |
164 | | -- PHPStan level 6 with `szepeviktor/phpstan-wordpress`. |
165 | | -- Conventional commit messages. |
166 | | -- WCAG 2.1 AA accessibility throughout (ARIA labels, focus management, screen reader announcements). |
167 | | -- No inline `<script>` blocks — all JS is enqueued as external files (CSP-compatible). |
| 74 | +Run and record outcomes: |
168 | 75 |
|
169 | | -## Testing |
| 76 | +1. `composer test:unit` |
| 77 | +2. `composer test:integration` (or document blocker) |
| 78 | +3. `composer analyse:phpstan` |
| 79 | +4. `composer analyse:psalm` |
| 80 | +5. `composer lint` |
170 | 81 |
|
171 | | -Tests use Brain\Monkey to mock WordPress functions/hooks without loading WordPress, plus Mockery for object mocking and Patchwork for redefining `setcookie` and `header`. |
| 82 | +If any command cannot run, report the exact command and blocker. |
172 | 83 |
|
173 | | -PHPUnit strict mode: tests must assert something, produce no output, and not trigger warnings. |
| 84 | +## Documentation Hygiene |
174 | 85 |
|
175 | | -### Plugin Distribution |
176 | | - |
177 | | -**To create a distributable ZIP file:** |
178 | | -```bash |
179 | | -npm run plugin-zip |
180 | | -``` |
181 | | -- Creates `wp-sudo.zip` in the repository root (ignored by git) |
182 | | -- Includes only necessary files: `wp-sudo.php`, `build/` directory contents |
183 | | -- Excludes: `src/`, `node_modules/`, `vendor/`, development files |
184 | | -- Takes approximately 1-2 seconds |
185 | | - |
186 | | -## Project Architecture |
187 | | - |
188 | | -### Directory Structure |
189 | | - |
190 | | -### Build Output Structure |
191 | | - |
192 | | -### Key Files |
193 | | - |
194 | | -## WordPress Coding Guidelines |
195 | | - |
196 | | -### Hook Registration |
197 | | - |
198 | | -**CRITICAL:** Hook registration must ALWAYS come before the callback function definition. |
199 | | - |
200 | | -This ensures that the code is clear and follows WordPress best practices. The hook registration tells WordPress what function to call, so it makes logical sense to define the hook first, then define the function it will call. |
201 | | - |
202 | | -**Correct pattern:** |
203 | | -```php |
204 | | -add_action( ‘init’, ‘my_function’ ); |
205 | | -function my_function() { |
206 | | - // function content here |
207 | | -} |
208 | | -``` |
209 | | - |
210 | | -## Validation Workflow |
211 | | - |
212 | | -**Before committing any code changes, ALWAYS run in this order:** |
213 | | - |
214 | | -1. Format code: `npm run format` |
215 | | -2. Lint JavaScript: `npm run lint:js` |
216 | | -3. Lint CSS: `npm run lint:css` |
217 | | -4. Build: `npm run build` |
218 | | -5. Verify build output exists in `build/wp-sudo/` |
219 | | - |
220 | | -**For PHP changes only:** |
221 | | -1. Format and lint as above (if any JS/CSS was touched) |
222 | | -2. Check PHP: `./vendor/bin/phpcs wp-sudo.php` (warnings acceptable) |
223 | | -3. Build: `npm run build` |
224 | | - |
225 | | -## Common Issues and Solutions |
226 | | - |
227 | | -**Issue:** `npm run build` fails with “Cannot find module” |
228 | | -- **Solution:** Run `npm install` first - dependencies not installed |
229 | | - |
230 | | -**Issue:** Lint errors about Prettier formatting |
231 | | -- **Solution:** Run `npm run format` first, then lint again |
232 | | - |
233 | | -**Issue:** `./vendor/bin/phpcs: No such file or directory` |
234 | | -- **Solution:** Run `composer install —no-interaction` |
235 | | - |
236 | | -**Issue:** Composer hangs asking for GitHub token |
237 | | -- **Solution:** Use `composer install —no-interaction` or let it clone from cache (slower but works) |
238 | | - |
239 | | -**Issue:** Build directory is empty after `npm run build` |
240 | | -- **Solution:** Check for errors in console; ensure `src/wp-sudo/` files exist |
241 | | - |
242 | | -**Issue:** Plugin not working in WordPress after changes |
243 | | -- **Solution:** ALWAYS run `npm run build` after changing any file in `src/` |
244 | | - |
245 | | -## Important Notes |
246 | | - |
247 | | -- Never edit files in `build/` directly - they are auto-generated |
248 | | -- The plugin uses WordPress 6.8+ block registration API with blocks-manifest.php for improved performance |
249 | | -- All source files are in `src/wp-sudo/`, all build outputs go to `build/wp-sudo/` |
250 | | -- This project follows WordPress coding standards, which use TABS for indentation |
251 | | -- Do not generate additional files beyond what is required for the assigned task (e.g., summary or documentation files) unless explicitly requested |
252 | | - |
253 | | -## Trust These Instructions |
254 | | - |
255 | | -These instructions have been thoroughly tested and validated. Only perform additional searches or exploration if: |
256 | | -- The information here is incomplete for your specific task |
257 | | -- You encounter an error not documented in “Common Issues” |
258 | | -- You are adding new functionality not covered by existing patterns |
259 | | - |
260 | | -For routine code changes, trust this documentation and avoid unnecessary exploration. |
261 | | -``` |
| 86 | +- Treat hardcoded counts as perishable. |
| 87 | +- When updating test counts, verify from test output first. |
| 88 | +- When updating project size metrics, use the commands in `AGENTS.md`. |
| 89 | +- Keep release-history entries historical; do not rewrite prior release facts. |
0 commit comments