Skip to content

Commit 026d3b7

Browse files
Merge pull request #2193 from WordPress/add/ai-guidance
Add `AGENTS.md` and AI contribution guidance
2 parents aca663e + 688a21c commit 026d3b7

File tree

3 files changed

+196
-2
lines changed

3 files changed

+196
-2
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ Fixes #
77

88
<!-- Please describe your changes. -->
99

10+
## Use of AI Tools
1011

12+
<!--
13+
You are free to use artificial intelligence (AI) tooling to contribute, but we ask that you disclose what tooling you are using and to what extent a pull request has been authored by AI. Are you using AI just as a code reviewer? Or, for the other extreme, are you using AI to write everything (e.g. "vibe coding")? It is your responsibility to review and take responsibility for what AI generates.
14+
15+
For more, see CONTRIBUTING.md which includes instructions for how to provide instructions to AI agents.
16+
-->
1117

1218
<!--
1319
For maintainers only, please make sure:

AGENTS.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Performance Lab
2+
3+
This is a monorepo for the WordPress Performance Team, containing a collection of standalone performance feature plugins. Refer to the [Performance Lab handbook](https://make.wordpress.org/performance/handbook/performance-lab/) for more details.
4+
5+
## Project Overview
6+
7+
* **Purpose:** To develop and maintain a suite of plugins that improve the performance of WordPress sites. All should be considered potential for future candidates for merging into WordPress core.
8+
* **Technologies:** PHP, JavaScript, CSS, a variety of testing and linting tools.
9+
10+
### Project Structure
11+
12+
* `/bin`: Custom CLI commands and scripts for certain development workflows.
13+
* `/plugins`: The actual WordPress plugins that are developed in this monorepo.
14+
* `/plugins/*`: An individual WordPress plugin folder.
15+
* `/plugins/*/tests`: PHPUnit tests for the specific WordPress plugin.
16+
* `/tools`: Setup and configuration files for various tools, such as linting and testing.
17+
18+
## Building and Running
19+
20+
### Prerequisites
21+
22+
* [Node.js and npm](https://nodejs.org/en/)
23+
* [Docker](https://www.docker.com/)
24+
* [Composer](https://getcomposer.org/)
25+
26+
### Installation
27+
28+
1. Run `npm install` to install the Node.js dependencies.
29+
2. Run `composer install` to install the PHP dependencies.
30+
3. Run `npm run build` to do an initial build of the assets.
31+
32+
### Building
33+
34+
* To build the JavaScript and CSS assets: `npm run build`
35+
* To build all plugins and place into the `build` directory: `npm run build-plugins`
36+
* To build a specific plugin: `npm run build:plugin:<plugin-slug>` (e.g., `npm run build:plugin:performance-lab`)
37+
* To build ZIP files for distribution: `npm run build-plugins:zip`
38+
39+
### Running a Local Environment
40+
41+
This project uses `@wordpress/env` to create a local development environment.
42+
43+
* Check if the environment is already running: `npm run wp-env status`
44+
* Start the environment: `npm run wp-env start`
45+
* Stop the environment: `npm run wp-env stop`
46+
47+
The environment will by default be located at `http://localhost:8888` but this can be overridden by `.wp-env.override.json`.
48+
49+
## Code Style
50+
51+
In general, the [coding standards for WordPress](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/) should be followed:
52+
53+
* [CSS Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/css/)
54+
* [HTML Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/html/)
55+
* [JavaScript Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/)
56+
* [PHP Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/)
57+
58+
Note that for the JavaScript Coding Standards, the code should also be formatted using Prettier, specifically the [wp-prettier](https://www.npmjs.com/package/wp-prettier) fork with the `--paren-spacing` option which inserts extra spaces inside parentheses.
59+
60+
For the HTML Coding Standards, disregard the guidance that void/empty tags should be self-closing, such as `IMG`, `BR`, `LINK`, or `META`. This is only relevant for XML (XHTML), not HTML. So instead of `<br />` this should only use `<br>`, for example.
61+
62+
Additionally, the [inline documentation standards for WordPress](https://developer.wordpress.org/coding-standards/inline-documentation-standards/) should be followed:
63+
64+
* [PHP Documentation Standards](https://developer.wordpress.org/coding-standards/inline-documentation-standards/php/)
65+
* [JavaScript Documentation Standards](https://developer.wordpress.org/coding-standards/inline-documentation-standards/javascript/)
66+
67+
Note that `lint-staged` will be used to automatically run code quality checks with the tooling based on the staged files.
68+
69+
### Indentation
70+
71+
In general, indentation should use tabs. Refer to `.editorconfig` in the project root for specifics.
72+
73+
### Inline Documentation
74+
75+
It is expected for new code introduced to have `@since` tags with the `n.e.x.t` placeholder version. It will get replaced with the actual version at the time of release. Do not add any code review comments to such code.
76+
77+
Every file, function, class, method constant, and global variable must have an associated docblock with a `@since` tag.
78+
79+
### PHP
80+
81+
Follow coding conventions in WordPress core. Namespaces are generally not used, as they are not normally used in WordPress core code. Procedural programming patterns are favored where classes play a supporting role, rather than everything being written in OOP.
82+
83+
Whenever possible, the most specific PHP type hints should be used, when backward compatible with PHP 7.2, the minimum version of PHP supported by WordPress and this repository. When native PHP type cannot be used, PHPStan's [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types) should be used, including not only the basic types but also subtypes like `non-empty-string`, [integer ranges](https://phpstan.org/writing-php-code/phpdoc-types#integer-ranges), [general arrays](https://phpstan.org/writing-php-code/phpdoc-types#general-arrays), and especially [array shapes](https://phpstan.org/writing-php-code/phpdoc-types#array-shapes). The types should comply with PHPStan's level 10. The one exception for using PHP types is whenever a function is used as a filter. Since plugins can supply any value at all when filtering, use the expected type with a union to `mixed`. The first statement in the function in this case must always check the type, and if it is not the expected type, override it to be so.
84+
85+
Never render HTML `SCRIPT` tags directly in HTML. Always use the relevant APIs in WordPress for adding scripts, including `wp_enqueue_script()`, `wp_add_inline_script()`, `wp_localize_script()`, `wp_print_script_tag()`, `wp_print_inline_script_tag()`, `wp_enqueue_script_module()` among others. Favor modules over classic scripts.
86+
87+
Here is an example PHP file with various conventions demonstrated.
88+
89+
```php
90+
/**
91+
* Filtering functions for the Bar plugin.
92+
*
93+
* @since n.e.x.t
94+
* @package Bar
95+
*/
96+
97+
/**
98+
* Filters post title to be upper case.
99+
*
100+
* @since n.e.x.t
101+
*
102+
* @param string|mixed $title Title.
103+
* @param positive-int $post_id Post ID.
104+
* @return string Upper-cased title.
105+
*/
106+
function bar_filter_title_uppercase( $title, int $post_id ): string {
107+
if ( ! is_string( $title ) ) {
108+
$title = '';
109+
}
110+
/**
111+
* Because plugins do bad things.
112+
*
113+
* @var string $title
114+
*/
115+
116+
return strtoupper( $title );
117+
}
118+
add_filter( 'the_title', 'bar_filter_title_uppercase', 10, 2 );
119+
```
120+
121+
### JavaScript
122+
123+
All JavaScript code should be written with JSDoc comments. All function parameters, return values, and other types should use [TypeScript in JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).
124+
125+
JavaScript code should be written using ES modules. This JS code must be runnable as-is without having to go through a build step, so it must be plain JavaScript and not TypeScript. The project _may_ also distribute minified versions of these JS files.
126+
127+
Here's an example JS file:
128+
129+
```js
130+
/**
131+
* Foo module for Optimization Detective
132+
*
133+
* This extension optimizes the foo performance feature.
134+
*
135+
* @since n.e.x.t
136+
*/
137+
138+
export const name = 'Foo';
139+
140+
/**
141+
* @typedef {import("web-vitals").LCPMetric} LCPMetric
142+
* @typedef {import("../optimization-detective/types.ts").InitializeCallback} InitializeCallback
143+
* @typedef {import("../optimization-detective/types.ts").InitializeArgs} InitializeArgs
144+
*/
145+
146+
/**
147+
* Initializes extension.
148+
*
149+
* @since n.e.x.t
150+
*
151+
* @type {InitializeCallback}
152+
* @param {InitializeArgs} args Args.
153+
*/
154+
export async function initialize( { log, onLCP, extendRootData } ) {
155+
onLCP(
156+
( metric ) => {
157+
handleLCPMetric( metric, extendRootData, log );
158+
}
159+
);
160+
}
161+
162+
// ... function definition for handleLCPMetric omitted ...
163+
```
164+
165+
### Static Analysis Commands
166+
167+
* **PHPStan**: `npm run phpstan`
168+
* **TypeScript**: `npm run tsc`
169+
170+
### Linting Commands
171+
172+
* **JavaScript:** `npm run lint-js`
173+
* **PHP:** `npm run lint-php`
174+
175+
### Formatting Commands
176+
177+
* **JavaScript:** `npm run format-js`
178+
* **PHP:** `npm run format-php`
179+
180+
### Testing Commands
181+
182+
* **End-to-end (E2E) tests:** `npm run test-e2e`
183+
* **PHP tests:** `npm run test-php`
184+
* **PHP tests (multisite):** `npm run test-php-multisite`

CONTRIBUTING.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ In general, all code must follow the [WordPress Coding Standards and best practi
99
- **WordPress**: As of Performance Lab v3.3.0, released July 15, 2024, the plugin's minimum WordPress version requirement is 6.5.
1010
- **PHP**: Always match the latest WordPress version. The minimum required version right now is 7.2.
1111

12-
1312
## Guidelines
1413

1514
- As with all WordPress projects, we want to ensure a welcoming environment for everyone. With that in mind, all contributors are expected to follow our [Code of Conduct](https://make.wordpress.org/handbook/community-code-of-conduct/).
16-
1715
- All WordPress projects are [licensed under the GPLv2+](/LICENSE), and all contributions to Gutenberg will be released under the GPLv2+ license. You maintain copyright over any contribution you make, and by submitting a pull request, you are agreeing to release that contribution under the GPLv2+ license.
1816

17+
## Use of AI Tools
18+
19+
You are free to use artificial intelligence (AI) tooling to contribute, but we ask that you disclose what tooling you are using and to what extent a pull request has been authored by AI. Are you using AI just as a code reviewer? Or, for the other extreme, are you using AI to write everything (e.g. "vibe coding")? It is your responsibility to review and take responsibility for what AI generates.
20+
21+
This repo includes an [`AGENTS.md`](./AGENTS.md) file which is a [README for agents](https://agents.md/). This can be used by tools like Cursor, Gemini CLI, GitHub Copilot coding agent, OpenAI Codex, and others. If your AI tool doesn't support `AGENTS.md` directly, you can simply create a symlink to it using the file name your tool is looking for.
22+
1923
## Reporting Security Issues
2024

2125
Please see [SECURITY.md](/SECURITY.md).

0 commit comments

Comments
 (0)