wordpress-agent-kit 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/.agents/skills/wp-bootstrap/SKILL.md +314 -0
  2. package/.agents/skills/wp-bootstrap/references/composer-setup.md +275 -0
  3. package/.agents/skills/wp-bootstrap/references/monorepo-patterns.md +184 -0
  4. package/.agents/skills/wp-bootstrap/scripts/bootstrap.sh +151 -0
  5. package/.agents/skills/wp-bootstrap/scripts/detect-structure.mjs +466 -0
  6. package/.agents/skills/wp-bootstrap/scripts/package-wp.sh +173 -0
  7. package/.agents/skills/wp-bootstrap/scripts/playground-start.sh +148 -0
  8. package/.agents/skills/wp-bootstrap/scripts/playground-verify.sh +165 -0
  9. package/.agents/skills/wp-bootstrap/scripts/setup-github.sh +417 -0
  10. package/.agents/skills/wp-wpengine/SKILL.md +76 -12
  11. package/.agents/skills/wp-wpengine/references/github-actions-deploy.md +16 -9
  12. package/README.md +1 -1
  13. package/dist/cli.js +2 -0
  14. package/dist/commands/bootstrap.js +105 -0
  15. package/dist/lib/api.js +1 -0
  16. package/dist/lib/bootstrap.js +352 -0
  17. package/extensions/wp-agent-kit/index.ts +143 -3
  18. package/package.json +1 -1
  19. package/skills-custom/wp-bootstrap/SKILL.md +314 -0
  20. package/skills-custom/wp-bootstrap/references/composer-setup.md +275 -0
  21. package/skills-custom/wp-bootstrap/references/monorepo-patterns.md +184 -0
  22. package/skills-custom/wp-bootstrap/scripts/bootstrap.sh +151 -0
  23. package/skills-custom/wp-bootstrap/scripts/detect-structure.mjs +466 -0
  24. package/skills-custom/wp-bootstrap/scripts/package-wp.sh +173 -0
  25. package/skills-custom/wp-bootstrap/scripts/playground-start.sh +148 -0
  26. package/skills-custom/wp-bootstrap/scripts/playground-verify.sh +165 -0
  27. package/skills-custom/wp-bootstrap/scripts/setup-github.sh +417 -0
  28. package/skills-custom/wp-wpengine/SKILL.md +76 -12
  29. package/skills-custom/wp-wpengine/references/github-actions-deploy.md +16 -9
  30. package/.github/skills/blueprint/SKILL.md +0 -418
  31. package/.github/skills/wordpress-router/SKILL.md +0 -52
  32. package/.github/skills/wordpress-router/references/decision-tree.md +0 -55
  33. package/.github/skills/wp-abilities-api/SKILL.md +0 -108
  34. package/.github/skills/wp-abilities-api/references/delegate-helper-pattern.md +0 -241
  35. package/.github/skills/wp-abilities-api/references/domain-vs-projection.md +0 -113
  36. package/.github/skills/wp-abilities-api/references/error-code-vocabulary.md +0 -123
  37. package/.github/skills/wp-abilities-api/references/grouping-heuristic.md +0 -89
  38. package/.github/skills/wp-abilities-api/references/input-schema-gotchas.md +0 -265
  39. package/.github/skills/wp-abilities-api/references/php-registration.md +0 -94
  40. package/.github/skills/wp-abilities-api/references/plugin-family-patterns.md +0 -233
  41. package/.github/skills/wp-abilities-api/references/rest-api.md +0 -13
  42. package/.github/skills/wp-abilities-api/references/shared-core-service.md +0 -184
  43. package/.github/skills/wp-abilities-audit/SKILL.md +0 -199
  44. package/.github/skills/wp-abilities-audit/references/audit-schema.md +0 -300
  45. package/.github/skills/wp-abilities-audit/references/capability-gate-tracing.md +0 -197
  46. package/.github/skills/wp-abilities-audit/references/controller-enumeration.md +0 -116
  47. package/.github/skills/wp-abilities-verify/SKILL.md +0 -215
  48. package/.github/skills/wp-abilities-verify/references/annotation-correctness.md +0 -154
  49. package/.github/skills/wp-abilities-verify/references/audit-schema-validation.md +0 -131
  50. package/.github/skills/wp-abilities-verify/references/permission-roundtrip.md +0 -190
  51. package/.github/skills/wp-abilities-verify/references/runtime-harness.md +0 -462
  52. package/.github/skills/wp-abilities-verify/references/schema-lints.md +0 -118
  53. package/.github/skills/wp-abilities-verify/references/static-enumeration.md +0 -126
  54. package/.github/skills/wp-block-development/SKILL.md +0 -175
  55. package/.github/skills/wp-block-development/references/attributes-and-serialization.md +0 -22
  56. package/.github/skills/wp-block-development/references/block-json.md +0 -49
  57. package/.github/skills/wp-block-development/references/creating-new-blocks.md +0 -46
  58. package/.github/skills/wp-block-development/references/debugging.md +0 -36
  59. package/.github/skills/wp-block-development/references/deprecations.md +0 -24
  60. package/.github/skills/wp-block-development/references/dynamic-rendering.md +0 -23
  61. package/.github/skills/wp-block-development/references/inner-blocks.md +0 -25
  62. package/.github/skills/wp-block-development/references/registration.md +0 -30
  63. package/.github/skills/wp-block-development/references/supports-and-wrappers.md +0 -18
  64. package/.github/skills/wp-block-development/references/tooling-and-testing.md +0 -21
  65. package/.github/skills/wp-block-development/scripts/list_blocks.mjs +0 -121
  66. package/.github/skills/wp-block-themes/SKILL.md +0 -117
  67. package/.github/skills/wp-block-themes/references/creating-new-block-theme.md +0 -37
  68. package/.github/skills/wp-block-themes/references/debugging.md +0 -24
  69. package/.github/skills/wp-block-themes/references/patterns.md +0 -18
  70. package/.github/skills/wp-block-themes/references/style-variations.md +0 -14
  71. package/.github/skills/wp-block-themes/references/templates-and-parts.md +0 -16
  72. package/.github/skills/wp-block-themes/references/theme-json.md +0 -59
  73. package/.github/skills/wp-block-themes/scripts/detect_block_themes.mjs +0 -117
  74. package/.github/skills/wp-interactivity-api/SKILL.md +0 -180
  75. package/.github/skills/wp-interactivity-api/references/debugging.md +0 -29
  76. package/.github/skills/wp-interactivity-api/references/directives-quickref.md +0 -30
  77. package/.github/skills/wp-interactivity-api/references/server-side-rendering.md +0 -310
  78. package/.github/skills/wp-performance/SKILL.md +0 -147
  79. package/.github/skills/wp-performance/references/autoload-options.md +0 -24
  80. package/.github/skills/wp-performance/references/cron.md +0 -20
  81. package/.github/skills/wp-performance/references/database.md +0 -20
  82. package/.github/skills/wp-performance/references/http-api.md +0 -15
  83. package/.github/skills/wp-performance/references/measurement.md +0 -21
  84. package/.github/skills/wp-performance/references/object-cache.md +0 -24
  85. package/.github/skills/wp-performance/references/query-monitor-headless.md +0 -38
  86. package/.github/skills/wp-performance/references/server-timing.md +0 -22
  87. package/.github/skills/wp-performance/references/wp-cli-doctor.md +0 -24
  88. package/.github/skills/wp-performance/references/wp-cli-profile.md +0 -32
  89. package/.github/skills/wp-performance/scripts/perf_inspect.mjs +0 -128
  90. package/.github/skills/wp-phpstan/SKILL.md +0 -98
  91. package/.github/skills/wp-phpstan/references/configuration.md +0 -52
  92. package/.github/skills/wp-phpstan/references/third-party-classes.md +0 -76
  93. package/.github/skills/wp-phpstan/references/wordpress-annotations.md +0 -124
  94. package/.github/skills/wp-phpstan/scripts/phpstan_inspect.mjs +0 -263
  95. package/.github/skills/wp-playground/SKILL.md +0 -233
  96. package/.github/skills/wp-playground/references/blueprints.md +0 -36
  97. package/.github/skills/wp-playground/references/cli-commands.md +0 -39
  98. package/.github/skills/wp-playground/references/debugging.md +0 -16
  99. package/.github/skills/wp-playground/references/e2e-playwright.md +0 -115
  100. package/.github/skills/wp-plugin-development/SKILL.md +0 -113
  101. package/.github/skills/wp-plugin-development/references/data-and-cron.md +0 -19
  102. package/.github/skills/wp-plugin-development/references/debugging.md +0 -19
  103. package/.github/skills/wp-plugin-development/references/lifecycle.md +0 -33
  104. package/.github/skills/wp-plugin-development/references/security.md +0 -29
  105. package/.github/skills/wp-plugin-development/references/settings-api.md +0 -22
  106. package/.github/skills/wp-plugin-development/references/structure.md +0 -16
  107. package/.github/skills/wp-plugin-development/scripts/detect_plugins.mjs +0 -122
  108. package/.github/skills/wp-plugin-directory-guidelines/SKILL.md +0 -133
  109. package/.github/skills/wp-plugin-directory-guidelines/references/gpl-compliance.md +0 -217
  110. package/.github/skills/wp-plugin-directory-guidelines/references/guideline-review-checklist.md +0 -592
  111. package/.github/skills/wp-plugin-directory-guidelines/references/naming-rules.md +0 -121
  112. package/.github/skills/wp-project-triage/SKILL.md +0 -39
  113. package/.github/skills/wp-project-triage/references/triage.schema.json +0 -143
  114. package/.github/skills/wp-project-triage/scripts/detect_wp_project.mjs +0 -610
  115. package/.github/skills/wp-rest-api/SKILL.md +0 -115
  116. package/.github/skills/wp-rest-api/references/authentication.md +0 -18
  117. package/.github/skills/wp-rest-api/references/custom-content-types.md +0 -20
  118. package/.github/skills/wp-rest-api/references/discovery-and-params.md +0 -20
  119. package/.github/skills/wp-rest-api/references/responses-and-fields.md +0 -30
  120. package/.github/skills/wp-rest-api/references/routes-and-endpoints.md +0 -36
  121. package/.github/skills/wp-rest-api/references/schema.md +0 -22
  122. package/.github/skills/wp-wpcli-and-ops/SKILL.md +0 -124
  123. package/.github/skills/wp-wpcli-and-ops/references/automation.md +0 -30
  124. package/.github/skills/wp-wpcli-and-ops/references/cron-and-cache.md +0 -23
  125. package/.github/skills/wp-wpcli-and-ops/references/debugging.md +0 -17
  126. package/.github/skills/wp-wpcli-and-ops/references/multisite.md +0 -22
  127. package/.github/skills/wp-wpcli-and-ops/references/packages-and-updates.md +0 -22
  128. package/.github/skills/wp-wpcli-and-ops/references/safety.md +0 -30
  129. package/.github/skills/wp-wpcli-and-ops/references/search-replace.md +0 -40
  130. package/.github/skills/wp-wpcli-and-ops/scripts/wpcli_inspect.mjs +0 -90
  131. package/.github/skills/wp-wpengine/SKILL.md +0 -127
  132. package/.github/skills/wpds/SKILL.md +0 -59
@@ -1,592 +0,0 @@
1
- # WordPress.org Plugin Directory Guidelines — Review Checklist
2
-
3
- Source: [Detailed Plugin Guidelines](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/?output_format=md)
4
-
5
- Use this section as a structured checklist when reviewing a plugin. Each guideline includes the violation signal to look for, the verdict to issue, and the fix to recommend. Cite the guideline number in every finding.
6
-
7
- ## Contents
8
-
9
- - [WordPress.org Plugin Directory Guidelines — Review Checklist](#wordpressorg-plugin-directory-guidelines--review-checklist)
10
- - [Contents](#contents)
11
- - [Guideline 1: GPL-Compatible License](#guideline-1-gpl-compatible-license)
12
- - [Guideline 2: Developer Responsibility](#guideline-2-developer-responsibility)
13
- - [Guideline 3: Stable Version in SVN](#guideline-3-stable-version-in-svn)
14
- - [Guideline 4: Human-Readable Code](#guideline-4-human-readable-code)
15
- - [Guideline 5: No Trialware](#guideline-5-no-trialware)
16
- - [Guideline 6: SaaS Integrations Are Allowed — With Conditions](#guideline-6-saas-integrations-are-allowed--with-conditions)
17
- - [Guideline 7: No External Data Collection Without Consent](#guideline-7-no-external-data-collection-without-consent)
18
- - [Guideline 8: No Remotely Loaded Executable Code](#guideline-8-no-remotely-loaded-executable-code)
19
- - [Guideline 9: No Illegal, Dishonest, or Offensive Behavior](#guideline-9-no-illegal-dishonest-or-offensive-behavior)
20
- - [Guideline 10: No Forced External Links](#guideline-10-no-forced-external-links)
21
- - [Guideline 11: No Admin Dashboard Hijacking](#guideline-11-no-admin-dashboard-hijacking)
22
- - [Guideline 12: No Readme Spam](#guideline-12-no-readme-spam)
23
- - [Guideline 13: Use WordPress-Bundled Libraries](#guideline-13-use-wordpress-bundled-libraries)
24
- - [Guideline 14: SVN Is a Release Repository](#guideline-14-svn-is-a-release-repository)
25
- - [Guideline 15: Increment Version Numbers](#guideline-15-increment-version-numbers)
26
- - [Guideline 16: Plugin Must Be Complete at Submission](#guideline-16-plugin-must-be-complete-at-submission)
27
- - [Guideline 17: Respect Trademarks and Copyrights](#guideline-17-respect-trademarks-and-copyrights)
28
- - [Guideline 18: WordPress.org Reserves Directory Rights](#guideline-18-wordpressorg-reserves-directory-rights)
29
-
30
- ---
31
-
32
- ### Guideline 1: GPL-Compatible License
33
-
34
- **Check:** Does the main plugin file have a `License:` header with a GPL-compatible value? Are all bundled third-party libraries under compatible licenses?
35
-
36
- **Violation signals:**
37
- - Missing `License:` or `License URI:` header in the main plugin file
38
- - License is `Proprietary`, `All Rights Reserved`, `CC-BY-NC`, `CC-BY-ND`, `SSPL`, `BSL`, `Commons Clause`, `EPL`, `EUPL`, or `MPL-1.0`
39
- - Bundled library under a license not in the GPL-Compatible Licenses table (see below)
40
- - PHP files encoded with ionCube, Zend Guard, or similar — source cannot be exercised → violation
41
-
42
- **Verdict:** Flag as **FAIL** with the specific file and license value found.
43
-
44
- **Fix:** Use `GPL-2.0-or-later` (recommended). Add full license text or a `License URI:` to `https://www.gnu.org/licenses/gpl-2.0.html`. Replace incompatible libraries.
45
-
46
- ---
47
-
48
- ### Guideline 2: Developer Responsibility
49
-
50
- **Check:** Has the developer deliberately re-introduced previously removed code, circumvented a prior guideline decision, or included files they cannot legally distribute?
51
-
52
- **Violation signals:**
53
- - Commit history shows restoring a file after it was removed by the review team
54
- - Bundled assets with no documented license (treat as unlicensed until proven otherwise)
55
- - Third-party API terms prohibit redistribution of the bundled SDK
56
-
57
- **Verdict:** Flag as **FAIL**. Document the specific file or commit.
58
-
59
- **Fix:** Remove the offending file or obtain and document proper licensing.
60
-
61
- ---
62
-
63
- ### Guideline 3: Stable Version in SVN
64
-
65
- **Check:** Is the WordPress.org SVN version the canonical release? Is the plugin also distributed via an external channel with a newer version?
66
-
67
- **Violation signals:**
68
- - `readme.txt` advertises a version not present in SVN trunk/tags
69
- - External download page (developer's own site) offers a newer build than WP.org
70
- - Plugin auto-updates itself from a non-WP.org server (also a Guideline 8 issue)
71
-
72
- **Verdict:** Flag as **FAIL** if an actively maintained external version is ahead of the directory.
73
-
74
- **Fix:** Keep SVN up to date. External channels may mirror but must not supersede the directory version.
75
-
76
- ---
77
-
78
- ### Guideline 4: Human-Readable Code
79
-
80
- **Check:** Is all PHP, JS, and CSS in a form that a developer can read and understand? Are build sources available?
81
-
82
- **Violation signals:**
83
- - PHP obfuscated with packer, eval+base64 chains, or variable names like `$a1b2c3` throughout
84
- - Minified JS present **without** any source map or reference to the source repo/file in the readme
85
- - Build artifacts (`.min.js`) committed with no corresponding unminified source in the package or a public repo linked from `readme.txt`
86
-
87
- **Verdict:** Flag as **FAIL** for obfuscated PHP (always). Flag minified-only JS as **FAIL** if no source access is documented.
88
-
89
- **Fix:** Remove obfuscation. Add a `Development` or `Build` section to `readme.txt` linking to the source repo (GitHub, GitLab, etc.).
90
-
91
- ---
92
-
93
- ### Guideline 5: No Trialware
94
-
95
- **Core rule:** Every feature shipped in the directory must function end-to-end without a license key, payment, or account.
96
-
97
- **Check for each feature gate in the code:**
98
-
99
- 1. Does a `has_paid_access()` / `is_licensed()` / `check_license()` check gate **local** processing (not an external service call)?
100
- 2. Is there a time-based expiry (`time() > $installed_at + 30 * DAY_IN_SECONDS`) for local behavior?
101
- 3. Is there a usage quota (`if ( $count >= 100 )`) that is artificially low and only exists to pressure upgrades?
102
- 4. Does the free user see a blocked/locked UI that prevents completing a core workflow?
103
-
104
- **Violation signals (flag as FAIL):**
105
- - `return` / `wp_die()` / blocking screen shown when `has_paid_access()` is false for a local feature
106
- - Ternary limits: `$limit = $licensed ? 10000 : 100` with no filter to extend the free cap
107
- - Features expire after X days even when no external service is involved
108
- - Admin screen is entirely replaced with an upgrade prompt
109
-
110
- **Allowed patterns (do not flag):**
111
- - Upsell notice shown alongside a working free feature (non-blocking)
112
- - Premium feature delegated to a **separate** add-on plugin not hosted on WP.org
113
- - External SaaS feature gated because the **service** itself requires payment (e.g., AI API quota)
114
- - Dismissible comparison table or upgrade button in plugin settings
115
-
116
- **Code patterns:**
117
-
118
- ```php
119
- // VIOLATION — local feature blocked by paid check
120
- if ( ! $this->has_paid_access() ) {
121
- echo 'Upgrade required';
122
- return; // ← blocks execution
123
- }
124
-
125
- // VIOLATION — artificial cap with no extension point
126
- $limit = $this->has_paid_access() ? 10000 : 100;
127
- ```
128
-
129
- ```php
130
- // COMPLIANT — free path works; premium adds to it
131
- $this->render_basic_export();
132
- if ( $this->has_premium_addon() ) {
133
- do_action( 'myplugin_premium_export_options' );
134
- }
135
-
136
- // COMPLIANT — cap is consistent; extensible via filter
137
- $limit = apply_filters( 'myplugin_event_limit', 10000 );
138
- ```
139
-
140
- **Pre-submission checklist:**
141
- - [ ] All free features work without a license key
142
- - [ ] No time-based expirations or usage quotas for local behavior
143
- - [ ] No blocking/locked UI preventing free-tier workflows
144
- - [ ] Upsell prompts are informational, non-blocking, and dismissible
145
- - [ ] Premium-only code lives in a separate add-on or an external service
146
-
147
- ---
148
-
149
- ### Guideline 6: SaaS Integrations Are Allowed — With Conditions
150
-
151
- **Check:** Does the external service provide real functionality? Is it documented in the readme?
152
-
153
- **Violation signals:**
154
- - The external service's sole purpose is validating a license key; all actual processing is local
155
- - Code was moved server-side specifically to disguise what is really a local feature gate
156
- - Plugin is a storefront or checkout page for an external product with no real plugin functionality
157
-
158
- **Verdict:** Flag as **FAIL** for license-validation-only services. Do not flag genuine SaaS integrations.
159
-
160
- **Fix:** Document what the external service does in `readme.txt`. Move license validation out of the plugin's critical path if the functionality is local.
161
-
162
- ---
163
-
164
- ### Guideline 7: No External Data Collection Without Consent
165
-
166
- **Check:** Does the plugin send any data to an external server without the user explicitly opting in?
167
-
168
- **Violation signals:**
169
- - HTTP request to a remote URL on plugin activation, admin page load, or cron job with no user opt-in
170
- - User email, site URL, or usage data sent without a visible opt-in checkbox or registration step
171
- - Third-party analytics or ad-tracking scripts loaded in admin or frontend without consent
172
- - Assets (images, fonts, scripts) loaded from an external CDN that are not the plugin's primary service
173
-
174
- **Exception:** Plugins that are interfaces to a named third-party service (e.g., Akismet, Mailchimp, a CDN) — consent is implied when the user configures the service connection.
175
-
176
- **Code patterns (violation vs compliant):**
177
-
178
- ```php
179
- // VIOLATION — sends data on activation without consent
180
- register_activation_hook( __FILE__, function() {
181
- wp_remote_post(
182
- 'https://api.example.com/collect',
183
- array(
184
- 'body' => array(
185
- 'site' => home_url(),
186
- 'admin_email' => get_option( 'admin_email' ),
187
- ),
188
- )
189
- );
190
- } );
191
-
192
- // COMPLIANT — explicit opt-in gate
193
- if ( isset( $_POST['myplugin_opt_in'] ) && '1' === $_POST['myplugin_opt_in'] ) {
194
- update_option( 'myplugin_tracking_opt_in', 1 );
195
- }
196
-
197
- if ( get_option( 'myplugin_tracking_opt_in' ) ) {
198
- wp_remote_post( 'https://api.example.com/collect', $payload );
199
- }
200
- ```
201
-
202
- **Review questions:**
203
- 1. Is any outbound request made on activation, first-run, or cron before consent is stored?
204
- 2. Is the opt-in UI explicit, unambiguous, and default-off?
205
- 3. Is consent persisted and checked before every telemetry request path?
206
- 4. Are collected fields documented in `readme.txt` privacy disclosures?
207
-
208
- **Verdict:** Flag as **FAIL** for any unconsented outbound call. Include the specific URL or domain found.
209
-
210
- **Fix:** Wrap all outbound calls in an opt-in gate. Add a `Privacy Policy` section to `readme.txt` describing what data is collected and why.
211
-
212
- **Pre-submission checklist:**
213
- - [ ] No telemetry/analytics calls occur before explicit opt-in
214
- - [ ] Opt-in control is visible and off by default
215
- - [ ] Consent is stored and checked in every outbound path
216
- - [ ] Privacy policy in readme explains data, destination, and purpose
217
-
218
- ---
219
-
220
- ### Guideline 8: No Remotely Loaded Executable Code
221
-
222
- **Check:** Is all JS/CSS that runs on the user's site included in the plugin package?
223
-
224
- **Violation signals:**
225
- - `wp_enqueue_script()` loading JS from a third-party CDN (not a self-hosted asset)
226
- - Plugin fetches and executes code from an external URL at runtime (`file_get_contents` + `eval`, dynamic `<script src>`)
227
- - Plugin installs or updates itself from a non-WP.org server
228
- - Admin page rendered entirely inside an `<iframe>` pointing to an external URL
229
-
230
- **Exceptions allowed:**
231
- - Web fonts loaded from Google Fonts or similar font CDNs
232
- - The plugin's own SaaS service loading its own widget/embed scripts (with user consent per Guideline 7)
233
-
234
- **Code patterns (violation vs compliant):**
235
-
236
- ```php
237
- // VIOLATION — executable JS loaded from third-party CDN
238
- wp_enqueue_script(
239
- 'myplugin-admin',
240
- 'https://cdn.example.com/myplugin/admin.js',
241
- array(),
242
- '1.0.0',
243
- true
244
- );
245
-
246
- // COMPLIANT — executable JS bundled in plugin package
247
- wp_enqueue_script(
248
- 'myplugin-admin',
249
- plugins_url( 'assets/js/admin.js', __FILE__ ),
250
- array(),
251
- MYPLUGIN_VERSION,
252
- true
253
- );
254
- ```
255
-
256
- **Review questions:**
257
- 1. Are any script/style enqueues pointing to third-party domains for executable assets?
258
- 2. Is any runtime code download/execution path present (`eval`, dynamic `<script>`, remote includes)?
259
- 3. Does update/install logic bypass WP.org distribution channels?
260
- 4. Are external assets limited to permitted exceptions (fonts, genuine service embed)?
261
-
262
- **Verdict:** Flag as **FAIL** for each externally loaded executable. Note the URL and the file/line where it is enqueued.
263
-
264
- **Fix:** Bundle JS/CSS locally. Use the WP.org SVN for updates. Replace `<iframe>` admin pages with proper WP Admin UI backed by a REST or admin-ajax API.
265
-
266
- **Pre-submission checklist:**
267
- - [ ] All executable JS/CSS is packaged locally in the plugin
268
- - [ ] No runtime remote code download or execution
269
- - [ ] No external self-update/install mechanism
270
- - [ ] Any external assets are documented and fall under allowed exceptions
271
-
272
- ---
273
-
274
- ### Guideline 9: No Illegal, Dishonest, or Offensive Behavior
275
-
276
- **Check:** Does the plugin engage in any deceptive, manipulative, or harmful behavior?
277
-
278
- **Violation signals:**
279
- - Hidden keyword stuffing in page output to manipulate search rankings
280
- - Code that posts reviews, ratings, or support replies on the user's behalf
281
- - Plugin presented as original work but is a fork or copy of another plugin without attribution
282
- - Plugin claims to make a site “GDPR compliant” or “ADA compliant” without legal basis
283
- - Code that uses site visitor resources for crypto-mining, botnets, or similar
284
-
285
- **Verdict:** Flag as **FAIL**. This is a high-severity category; document evidence thoroughly.
286
-
287
- ---
288
-
289
- ### Guideline 10: No Forced External Links
290
-
291
- **Check:** Does the plugin output any “Powered by” links, footer credits, or backlinks visible to site visitors?
292
-
293
- **Violation signals:**
294
- - Credit link output by default with no setting to disable it
295
- - Plugin requires the credit link to remain active for full functionality
296
- - Link is embedded in non-optional template output
297
- - “Powered by” text/link in templates (scanner pattern: `(?<!x-)powered[ -_]by`)
298
- - Backlink required to unlock an upgrade/feature (crosses Guideline 5 + 10)
299
-
300
- **Exception:** A service may brand its own rendered output (e.g., a payment form branded with the payment processor's logo).
301
-
302
- **Code patterns (violation vs compliant):**
303
-
304
- ```php
305
- // VIOLATION — forced credit link on public output
306
- add_action( 'wp_footer', function() {
307
- echo '<p class="myplugin-credit"><a href="https://vendor.example">Powered by Vendor</a></p>';
308
- } );
309
-
310
- // VIOLATION — backlink required for feature activation
311
- if ( ! get_option( 'myplugin_keep_backlink' ) ) {
312
- wp_die( 'Please keep our credit link active to use this feature.' );
313
- }
314
-
315
- // COMPLIANT — optional, explicit opt-in, default off
316
- if ( get_option( 'myplugin_show_credit_link', false ) ) {
317
- echo '<p class="myplugin-credit"><a href="https://vendor.example">Powered by Vendor</a></p>';
318
- }
319
- ```
320
-
321
- **Review questions:**
322
- 1. Is any “Powered by” or credit link injected into frontend output by default?
323
- 2. Can users disable the link without breaking functionality?
324
- 3. Is there any logic that ties feature access to keeping a backlink active?
325
- 4. Is consent for showing credits explicit (not implied) and persisted?
326
-
327
- **Verdict:** Flag as **FAIL** if the link is on by default with no opt-out. Flag as **FAIL** if removing it breaks functionality.
328
-
329
- **Fix:** Default the setting to `false` (hidden). Provide a clear checkbox in settings to enable it.
330
-
331
- **Pre-submission checklist:**
332
- - [ ] No credit/backlink is shown by default on public pages
333
- - [ ] Credit link is strictly opt-in and user-controlled
334
- - [ ] Disabling credit links does not disable any plugin functionality
335
- - [ ] No upgrade path requires a backlink to remain active
336
-
337
- ---
338
-
339
- ### Guideline 11: No Admin Dashboard Hijacking
340
-
341
- **Check:** Are admin notices, upgrade prompts, and nags limited and non-intrusive?
342
-
343
- **Violation signals:**
344
- - Site-wide admin notice that cannot be dismissed (no dismiss button, reappears on every page load)
345
- - Upgrade/upsell prompt shown on every admin page, not just the plugin's own settings screen
346
- - Plugin overrides the WordPress dashboard home page or injects full-page overlays
347
- - Ad banners or tracking pixels placed in the WordPress admin area
348
- - Admin settings page rendered as an external `<iframe>` instead of native WP admin UI
349
-
350
- **Code patterns (violation vs compliant):**
351
-
352
- ```php
353
- // VIOLATION — external iframe in admin page
354
- add_action( 'admin_menu', function() {
355
- add_menu_page( 'My Plugin', 'My Plugin', 'manage_options', 'myplugin', function() {
356
- echo '<iframe src="https://app.vendor.example/dashboard" style="width:100%;height:80vh;border:0"></iframe>';
357
- } );
358
- } );
359
-
360
- // COMPLIANT — native admin page shell with server/API data fetch
361
- add_action( 'admin_menu', function() {
362
- add_menu_page( 'My Plugin', 'My Plugin', 'manage_options', 'myplugin', function() {
363
- echo '<div class="wrap"><h1>My Plugin</h1><div id="myplugin-admin-app"></div></div>';
364
- } );
365
- } );
366
-
367
- add_action( 'admin_enqueue_scripts', function( $hook ) {
368
- if ( 'toplevel_page_myplugin' !== $hook ) {
369
- return;
370
- }
371
- wp_enqueue_script(
372
- 'myplugin-admin',
373
- plugins_url( 'assets/js/admin.js', __FILE__ ),
374
- array( 'wp-api-fetch' ),
375
- MYPLUGIN_VERSION,
376
- true
377
- );
378
- } );
379
- ```
380
-
381
- **Review questions:**
382
- 1. Does any admin screen render plugin UI inside an external iframe?
383
- 2. Is the plugin using native WP admin pages and capabilities checks instead?
384
- 3. Are upsells/notices scoped to plugin pages and dismissible?
385
- 4. Does removing upsell UI leave settings and core flows fully usable?
386
-
387
- **Verdict:** Flag as **FAIL** for persistent undismissable notices or for notices appearing outside the plugin's own pages.
388
-
389
- **Fix:** Use `is_plugin_page()` or an equivalent check to scope notices. Add a dismiss handler using `update_user_meta` or the WP dismissible notice pattern. Never show upgrade prompts on unrelated admin pages.
390
-
391
- **Pre-submission checklist:**
392
- - [ ] No external iframes used for admin/settings pages
393
- - [ ] Admin UI is rendered as native WP admin pages
394
- - [ ] Notices are dismissible and scoped to plugin screens only
395
- - [ ] Removing notices/upsells does not break plugin functionality
396
-
397
- ---
398
-
399
- ### Guideline 12: No Readme Spam
400
-
401
- **Check:** Is the `readme.txt` free of keyword stuffing, excessive affiliate links, and competitor tags?
402
-
403
- **Violation signals:**
404
- - More than 5 tags in the `Tags:` field
405
- - Affiliate links present but not disclosed, or using redirect/cloaking URLs
406
- - Tags that name competitor plugins or irrelevant popular terms purely for SEO
407
- - `readme.txt` reads as a keyword list rather than useful documentation
408
-
409
- **Verdict:** Flag as **WARNING** for minor stuffing; **FAIL** for undisclosed affiliate links or more than 5 tags.
410
-
411
- **Fix:** Reduce tags to 5 or fewer relevant terms. Disclose all affiliate links with “(affiliate link)” notation. Link affiliate URLs directly without cloaking.
412
-
413
- ---
414
-
415
- ### Guideline 13: Use WordPress-Bundled Libraries
416
-
417
- **Check:** Does the plugin bundle its own copies of libraries that WordPress already ships?
418
-
419
- **Violation signals:**
420
- - Plugin includes its own `jquery.js`, `jquery.min.js`, or loads jQuery from a CDN
421
- - Plugin bundles `PHPMailer`, `SimplePie`, `PHPass`, `Backbone`, `Underscore`, `React`, `wp-polyfill`, or other WP-bundled libraries
422
- - `wp_enqueue_script()` registers a library already available as a WordPress handle (check [Default Scripts](https://developer.wordpress.org/reference/functions/wp_enqueue_script/))
423
- - Scanner indicators: `files_library_core` and known core library filename matches (see scanner `known-libraries.php`)
424
-
425
- **Code patterns (violation vs compliant):**
426
-
427
- ```php
428
- // VIOLATION — loading custom/bundled jQuery copy
429
- wp_enqueue_script(
430
- 'myplugin-jquery',
431
- plugins_url( 'assets/vendor/jquery-3.7.1.min.js', __FILE__ ),
432
- array(),
433
- '3.7.1',
434
- true
435
- );
436
-
437
- // COMPLIANT — use WordPress-bundled jQuery handle
438
- wp_enqueue_script( 'jquery' );
439
- ```
440
-
441
- ```php
442
- // VIOLATION — bundling WP core PHP libs directly
443
- require_once __DIR__ . '/vendor/PHPMailer.php';
444
- require_once __DIR__ . '/vendor/SimplePie.php';
445
-
446
- // COMPLIANT — use WordPress APIs that rely on core libs
447
- wp_mail( $to, $subject, $message, $headers );
448
- $feed = fetch_feed( $feed_url );
449
- ```
450
-
451
- ```php
452
- // VIOLATION — registering local copy for a core-shipped package
453
- wp_register_script(
454
- 'myplugin-underscore',
455
- plugins_url( 'assets/vendor/underscore.min.js', __FILE__ ),
456
- array(),
457
- '1.13.6',
458
- true
459
- );
460
-
461
- // COMPLIANT — rely on core handle
462
- wp_enqueue_script( 'underscore' );
463
- ```
464
-
465
- **Review questions:**
466
- 1. Does the plugin ship filenames that match core-library patterns (`jquery`, `underscore`, `backbone`, `codemirror`, `moment`, `PHPMailer`, `SimplePie`)?
467
- 2. Are any core-library equivalents registered/enqueued from plugin paths instead of WP handles?
468
- 3. Are SMTP/feed features implemented through WordPress APIs (`wp_mail`, `fetch_feed`) rather than bundled core libs?
469
- 4. Can bundled duplicates be removed without breaking functionality?
470
-
471
- **Verdict:** Flag as **FAIL** for each duplicate bundled library.
472
-
473
- **Fix:** Replace bundled copies with `wp_enqueue_script( 'jquery' )` (or the appropriate WP handle). Remove the local copy from the plugin package.
474
-
475
- **Pre-submission checklist:**
476
- - [ ] No bundled copies of libraries already shipped by WordPress core
477
- - [ ] Core script dependencies are loaded via WP handles
478
- - [ ] Mail/feed functionality uses WordPress APIs instead of bundled core libs
479
- - [ ] Any remaining third-party libs are not core duplicates and are documented/license-compliant
480
-
481
- ---
482
-
483
- ### Guideline 14: SVN Is a Release Repository
484
-
485
- **Check:** Are SVN commits release-quality and infrequent?
486
-
487
- **Violation signals:**
488
- - Multiple commits per day with messages like “fix typo”, “testing”, “debug”
489
- - Development/debug code committed to trunk (e.g., `var_dump()`, `error_log()`, `console.log( 'test' )`)
490
- - Version number not incremented between commits that change functional code
491
-
492
- **Note:** This guideline is primarily advisory; violations do not block submission but reflect poorly on the developer.
493
-
494
- **Fix:** Use a development branch (GitHub/GitLab) and commit to SVN only for releases. Each SVN commit should correspond to a version bump.
495
-
496
- ---
497
-
498
- ### Guideline 15: Increment Version Numbers
499
-
500
- **Check:** Is the version number in `readme.txt` and the plugin header incremented for every release?
501
-
502
- **Violation signals:**
503
- - `Stable tag:` in `readme.txt` does not match the `Version:` field in the main plugin file
504
- - `Stable tag: trunk` used (discouraged; use an explicit version number)
505
- - Version number is the same across two different functional releases in SVN tags
506
-
507
- **Code patterns (violation vs compliant):**
508
-
509
- ```text
510
- // VIOLATION — readme/plugin header mismatch
511
- readme.txt:
512
- Stable tag: 1.4.0
513
-
514
- my-plugin.php header:
515
- Version: 1.3.9
516
- ```
517
-
518
- ```text
519
- // COMPLIANT — values are aligned and bumped together
520
- readme.txt:
521
- Stable tag: 1.4.1
522
-
523
- my-plugin.php header:
524
- Version: 1.4.1
525
- ```
526
-
527
- ```text
528
- // VIOLATION — releasing functional changes without version increment
529
- SVN tag: tags/1.4.1
530
- Current release code: changed features, still Version: 1.4.1
531
-
532
- // COMPLIANT — each functional release gets a new version tag
533
- SVN tags: tags/1.4.1 -> tags/1.4.2
534
- ```
535
-
536
- **Review questions:**
537
- 1. Does `readme.txt` `Stable tag` exactly match main plugin `Version`?
538
- 2. Is the new SVN tag version unique for this release?
539
- 3. Did functional/code changes occur without a version increment?
540
- 4. Are all user-facing changelog/release markers consistent with the bumped version?
541
-
542
- **Verdict:** Flag as **FAIL** if `Stable tag` and plugin header `Version` do not match.
543
-
544
- **Fix:** Bump both values together on every release. Tag the release in SVN under `tags/X.Y.Z`.
545
-
546
- **Pre-submission checklist:**
547
- - [ ] `Stable tag` matches plugin header `Version`
548
- - [ ] Version is incremented for this release
549
- - [ ] SVN tag uses the new version (`tags/X.Y.Z`)
550
- - [ ] Changelog/release notes reflect the same version
551
-
552
- ---
553
-
554
- ### Guideline 16: Plugin Must Be Complete at Submission
555
-
556
- **Check:** Is the plugin functional and complete at the time of submission?
557
-
558
- **Violation signals:**
559
- - Plugin is a skeleton with placeholder functions or “coming soon” admin pages
560
- - Slug was requested to reserve a name for a future or in-progress product
561
- - Primary plugin functionality requires a separate plugin not yet published
562
-
563
- **Verdict:** Flag as **FAIL**. An incomplete plugin cannot be approved.
564
-
565
- **Fix:** Submit only when the plugin is feature-complete and functional for end users.
566
-
567
- ---
568
-
569
- ### Guideline 17: Respect Trademarks and Copyrights
570
-
571
- **Check:** Does the plugin name or slug start with a trademark or project name the developer does not own?
572
-
573
- **Violation signals:**
574
- - Slug starts with `woocommerce-`, `elementor-`, `jetpack-`, `yoast-`, or any term in the Trademark Slug List (see Naming Rules section below)
575
- - Plugin name starts with a trademarked term (e.g., “WooCommerce Pricing Rates” → starts with WooCommerce)
576
- - Name uses a portmanteau of a trademark (e.g., “PricingPress” uses `-Press` from WordPress)
577
-
578
- **Correct pattern:** Trademark may only appear **after** a connector word: `for`, `with`, `using`, `and`.
579
- - ✅ `Pricing Rates for WooCommerce`
580
- - ❌ `WooCommerce Pricing Rates`
581
-
582
- **Verdict:** Flag as **FAIL** with the specific trademark and the correct name structure.
583
-
584
- **Fix:** Move the trademark to after a connector. Rename the slug accordingly (max 50 chars, lowercase, hyphens only).
585
-
586
- ---
587
-
588
- ### Guideline 18: WordPress.org Reserves Directory Rights
589
-
590
- **Note:** This guideline is informational — no code or readme check is required. It establishes that WordPress.org may update guidelines, remove plugins, revoke access, or modify plugins for public safety at any time. Inform developers of this when advising on submission strategy.
591
-
592
- ---