wordpress-agent-kit 0.3.2 → 0.5.1

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 (135) hide show
  1. package/.agents/skills/blueprint/SKILL.md +418 -0
  2. package/.agents/skills/wordpress-router/SKILL.md +52 -0
  3. package/.agents/skills/wordpress-router/references/decision-tree.md +55 -0
  4. package/.agents/skills/wp-abilities-api/SKILL.md +108 -0
  5. package/.agents/skills/wp-abilities-api/references/delegate-helper-pattern.md +241 -0
  6. package/.agents/skills/wp-abilities-api/references/domain-vs-projection.md +113 -0
  7. package/.agents/skills/wp-abilities-api/references/error-code-vocabulary.md +123 -0
  8. package/.agents/skills/wp-abilities-api/references/grouping-heuristic.md +89 -0
  9. package/.agents/skills/wp-abilities-api/references/input-schema-gotchas.md +265 -0
  10. package/.agents/skills/wp-abilities-api/references/php-registration.md +94 -0
  11. package/.agents/skills/wp-abilities-api/references/plugin-family-patterns.md +233 -0
  12. package/.agents/skills/wp-abilities-api/references/rest-api.md +13 -0
  13. package/.agents/skills/wp-abilities-api/references/shared-core-service.md +184 -0
  14. package/.agents/skills/wp-abilities-audit/SKILL.md +199 -0
  15. package/.agents/skills/wp-abilities-audit/references/audit-schema.md +300 -0
  16. package/.agents/skills/wp-abilities-audit/references/capability-gate-tracing.md +197 -0
  17. package/.agents/skills/wp-abilities-audit/references/controller-enumeration.md +116 -0
  18. package/.agents/skills/wp-abilities-verify/SKILL.md +215 -0
  19. package/.agents/skills/wp-abilities-verify/references/annotation-correctness.md +154 -0
  20. package/.agents/skills/wp-abilities-verify/references/audit-schema-validation.md +131 -0
  21. package/.agents/skills/wp-abilities-verify/references/permission-roundtrip.md +190 -0
  22. package/.agents/skills/wp-abilities-verify/references/runtime-harness.md +462 -0
  23. package/.agents/skills/wp-abilities-verify/references/schema-lints.md +118 -0
  24. package/.agents/skills/wp-abilities-verify/references/static-enumeration.md +126 -0
  25. package/.agents/skills/wp-block-development/SKILL.md +175 -0
  26. package/.agents/skills/wp-block-development/references/attributes-and-serialization.md +22 -0
  27. package/.agents/skills/wp-block-development/references/block-json.md +49 -0
  28. package/.agents/skills/wp-block-development/references/creating-new-blocks.md +46 -0
  29. package/.agents/skills/wp-block-development/references/debugging.md +36 -0
  30. package/.agents/skills/wp-block-development/references/deprecations.md +24 -0
  31. package/.agents/skills/wp-block-development/references/dynamic-rendering.md +23 -0
  32. package/.agents/skills/wp-block-development/references/inner-blocks.md +25 -0
  33. package/.agents/skills/wp-block-development/references/registration.md +30 -0
  34. package/.agents/skills/wp-block-development/references/supports-and-wrappers.md +18 -0
  35. package/.agents/skills/wp-block-development/references/tooling-and-testing.md +21 -0
  36. package/.agents/skills/wp-block-development/scripts/list_blocks.mjs +121 -0
  37. package/.agents/skills/wp-block-themes/SKILL.md +117 -0
  38. package/.agents/skills/wp-block-themes/references/creating-new-block-theme.md +37 -0
  39. package/.agents/skills/wp-block-themes/references/debugging.md +24 -0
  40. package/.agents/skills/wp-block-themes/references/patterns.md +18 -0
  41. package/.agents/skills/wp-block-themes/references/style-variations.md +14 -0
  42. package/.agents/skills/wp-block-themes/references/templates-and-parts.md +16 -0
  43. package/.agents/skills/wp-block-themes/references/theme-json.md +59 -0
  44. package/.agents/skills/wp-block-themes/scripts/detect_block_themes.mjs +117 -0
  45. package/.agents/skills/wp-interactivity-api/SKILL.md +180 -0
  46. package/.agents/skills/wp-interactivity-api/references/debugging.md +29 -0
  47. package/.agents/skills/wp-interactivity-api/references/directives-quickref.md +30 -0
  48. package/.agents/skills/wp-interactivity-api/references/server-side-rendering.md +310 -0
  49. package/.agents/skills/wp-performance/SKILL.md +147 -0
  50. package/.agents/skills/wp-performance/references/autoload-options.md +24 -0
  51. package/.agents/skills/wp-performance/references/cron.md +20 -0
  52. package/.agents/skills/wp-performance/references/database.md +20 -0
  53. package/.agents/skills/wp-performance/references/http-api.md +15 -0
  54. package/.agents/skills/wp-performance/references/measurement.md +21 -0
  55. package/.agents/skills/wp-performance/references/object-cache.md +24 -0
  56. package/.agents/skills/wp-performance/references/query-monitor-headless.md +38 -0
  57. package/.agents/skills/wp-performance/references/server-timing.md +22 -0
  58. package/.agents/skills/wp-performance/references/wp-cli-doctor.md +24 -0
  59. package/.agents/skills/wp-performance/references/wp-cli-profile.md +32 -0
  60. package/.agents/skills/wp-performance/scripts/perf_inspect.mjs +128 -0
  61. package/.agents/skills/wp-phpstan/SKILL.md +98 -0
  62. package/.agents/skills/wp-phpstan/references/configuration.md +52 -0
  63. package/.agents/skills/wp-phpstan/references/third-party-classes.md +76 -0
  64. package/.agents/skills/wp-phpstan/references/wordpress-annotations.md +124 -0
  65. package/.agents/skills/wp-phpstan/scripts/phpstan_inspect.mjs +263 -0
  66. package/.agents/skills/wp-playground/SKILL.md +233 -0
  67. package/.agents/skills/wp-playground/references/blueprints.md +36 -0
  68. package/.agents/skills/wp-playground/references/cli-commands.md +39 -0
  69. package/.agents/skills/wp-playground/references/debugging.md +16 -0
  70. package/.agents/skills/wp-playground/references/e2e-playwright.md +115 -0
  71. package/.agents/skills/wp-plugin-development/SKILL.md +113 -0
  72. package/.agents/skills/wp-plugin-development/references/data-and-cron.md +19 -0
  73. package/.agents/skills/wp-plugin-development/references/debugging.md +19 -0
  74. package/.agents/skills/wp-plugin-development/references/lifecycle.md +33 -0
  75. package/.agents/skills/wp-plugin-development/references/security.md +29 -0
  76. package/.agents/skills/wp-plugin-development/references/settings-api.md +22 -0
  77. package/.agents/skills/wp-plugin-development/references/structure.md +16 -0
  78. package/.agents/skills/wp-plugin-development/scripts/detect_plugins.mjs +122 -0
  79. package/.agents/skills/wp-plugin-directory-guidelines/SKILL.md +133 -0
  80. package/.agents/skills/wp-plugin-directory-guidelines/references/gpl-compliance.md +217 -0
  81. package/.agents/skills/wp-plugin-directory-guidelines/references/guideline-review-checklist.md +592 -0
  82. package/.agents/skills/wp-plugin-directory-guidelines/references/naming-rules.md +121 -0
  83. package/.agents/skills/wp-project-triage/SKILL.md +39 -0
  84. package/.agents/skills/wp-project-triage/references/triage.schema.json +143 -0
  85. package/.agents/skills/wp-project-triage/scripts/detect_wp_project.mjs +610 -0
  86. package/.agents/skills/wp-rest-api/SKILL.md +115 -0
  87. package/.agents/skills/wp-rest-api/references/authentication.md +18 -0
  88. package/.agents/skills/wp-rest-api/references/custom-content-types.md +20 -0
  89. package/.agents/skills/wp-rest-api/references/discovery-and-params.md +20 -0
  90. package/.agents/skills/wp-rest-api/references/responses-and-fields.md +30 -0
  91. package/.agents/skills/wp-rest-api/references/routes-and-endpoints.md +36 -0
  92. package/.agents/skills/wp-rest-api/references/schema.md +22 -0
  93. package/.agents/skills/wp-wpcli-and-ops/SKILL.md +126 -0
  94. package/.agents/skills/wp-wpcli-and-ops/references/automation.md +30 -0
  95. package/.agents/skills/wp-wpcli-and-ops/references/cron-and-cache.md +23 -0
  96. package/.agents/skills/wp-wpcli-and-ops/references/debugging.md +17 -0
  97. package/.agents/skills/wp-wpcli-and-ops/references/multisite.md +22 -0
  98. package/.agents/skills/wp-wpcli-and-ops/references/packages-and-updates.md +22 -0
  99. package/.agents/skills/wp-wpcli-and-ops/references/safety.md +30 -0
  100. package/.agents/skills/wp-wpcli-and-ops/references/search-replace.md +40 -0
  101. package/.agents/skills/wp-wpcli-and-ops/scripts/wpcli_inspect.mjs +90 -0
  102. package/.agents/skills/wp-wpengine/SKILL.md +398 -0
  103. package/.agents/skills/wp-wpengine/references/ci-gate.md +469 -0
  104. package/.agents/skills/wp-wpengine/references/github-actions-deploy.md +736 -0
  105. package/.agents/skills/wp-wpengine/scripts/ci-gate.sh +118 -0
  106. package/.agents/skills/wp-wpengine/scripts/wpe-check.sh +89 -0
  107. package/.agents/skills/wp-wpengine/scripts/wpe-preflight.sh +104 -0
  108. package/.agents/skills/wpds/SKILL.md +59 -0
  109. package/.github/agents/wp-architect.agent.md +1 -2
  110. package/.github/copilot-instructions.md +1 -1
  111. package/.github/instructions/wordpress-workflow.instructions.md +3 -3
  112. package/.github/skills/wp-playground/SKILL.md +132 -1
  113. package/.github/skills/wp-playground/references/e2e-playwright.md +115 -0
  114. package/.github/skills/wp-wpengine/SKILL.md +127 -0
  115. package/AGENTS.md +22 -10
  116. package/AGENTS.template.md +20 -10
  117. package/README.md +93 -86
  118. package/dist/cli.js +5 -1
  119. package/dist/commands/clean-skills.js +64 -0
  120. package/dist/commands/setup.js +6 -2
  121. package/dist/commands/sync-skills.js +3 -0
  122. package/dist/lib/api.js +176 -4
  123. package/dist/lib/installer.js +166 -2
  124. package/extensions/wp-agent-kit/index.ts +185 -10
  125. package/package.json +10 -14
  126. package/skills-custom/wp-wpengine/SKILL.md +398 -0
  127. package/skills-custom/wp-wpengine/references/ci-gate.md +469 -0
  128. package/skills-custom/wp-wpengine/references/github-actions-deploy.md +736 -0
  129. package/skills-custom/wp-wpengine/scripts/ci-gate.sh +118 -0
  130. package/skills-custom/wp-wpengine/scripts/wpe-check.sh +89 -0
  131. package/skills-custom/wp-wpengine/scripts/wpe-preflight.sh +104 -0
  132. package/.github/workflows/ci.yml +0 -44
  133. package/.husky/pre-commit +0 -7
  134. package/CLI_REVIEW.md +0 -250
  135. package/biome.json +0 -39
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env bash
2
+ # ci-gate.sh — run the full CI gate locally before pushing.
3
+ #
4
+ # Mirrors what GitHub Actions ci-gate.yml runs. Use this before any push
5
+ # to a branch that triggers a WP Engine deploy.
6
+ #
7
+ # Usage:
8
+ # bash scripts/ci-gate.sh # run both gates
9
+ # bash scripts/ci-gate.sh --php-only # PHP gate only
10
+ # bash scripts/ci-gate.sh --js-only # JS/TS gate only
11
+ #
12
+ # Exit code: 0 = all passed, 1 = at least one check failed.
13
+
14
+ set -uo pipefail
15
+ root="$(git rev-parse --show-toplevel)"
16
+ cd "$root"
17
+
18
+ PHP_ONLY=false
19
+ JS_ONLY=false
20
+ for arg in "$@"; do
21
+ [[ "$arg" == "--php-only" ]] && PHP_ONLY=true
22
+ [[ "$arg" == "--js-only" ]] && JS_ONLY=true
23
+ done
24
+
25
+ PASS=0
26
+ FAIL=0
27
+
28
+ run() {
29
+ local label="$1"; shift
30
+ echo "▶ $label"
31
+ if "$@" 2>&1; then
32
+ echo " ✓ $label"
33
+ ((PASS++))
34
+ else
35
+ echo " ✗ FAILED: $label"
36
+ ((FAIL++))
37
+ return 1
38
+ fi
39
+ }
40
+
41
+ # ── PHP gate ──────────────────────────────────────────────────────────────────
42
+ if ! $JS_ONLY; then
43
+ echo ""
44
+ echo "── PHP gate ──────────────────────────────────────────────────────────"
45
+ if command -v composer >/dev/null 2>&1 && [ -f composer.json ]; then
46
+ if [ ! -d vendor ]; then
47
+ echo "▶ composer install"
48
+ composer install --no-interaction --quiet
49
+ fi
50
+
51
+ run "php -l (all tracked PHP files)" \
52
+ bash -c 'git ls-files "*.php" | xargs -P4 php -l > /dev/null'
53
+
54
+ if [ -x vendor/bin/phpcs ]; then
55
+ run "phpcs (WordPress coding standards)" composer run phpcs
56
+ else
57
+ echo " ⚠ phpcs not found — run: composer install"
58
+ fi
59
+
60
+ if [ -x vendor/bin/phpstan ]; then
61
+ run "phpstan (static analysis)" composer run phpstan
62
+ else
63
+ echo " ⚠ phpstan not found — run: composer install"
64
+ fi
65
+ else
66
+ echo " ⚠ composer not available or no composer.json — skipping PHP gate"
67
+ fi
68
+ fi
69
+
70
+ # ── JS/TS gate ────────────────────────────────────────────────────────────────
71
+ if ! $PHP_ONLY; then
72
+ echo ""
73
+ echo "── JS/TS gate ────────────────────────────────────────────────────────"
74
+ if [ -f package.json ]; then
75
+ if [ ! -d node_modules ]; then
76
+ echo "▶ npm install"
77
+ npm install --silent
78
+ fi
79
+
80
+ if [ -x node_modules/.bin/biome ]; then
81
+ run "biome check (lint + format)" npx biome check .
82
+ else
83
+ echo " ⚠ biome not installed — run: npm install"
84
+ fi
85
+
86
+ if npm run typecheck --if-present 2>/dev/null; then
87
+ ((PASS++))
88
+ elif command -v tsc >/dev/null 2>&1 || [ -x node_modules/.bin/tsc ]; then
89
+ run "tsc --noEmit (type check)" npx tsc --noEmit
90
+ fi
91
+
92
+ if npm run test --if-present 2>/dev/null; then
93
+ ((PASS++))
94
+ fi
95
+
96
+ if npm run build --if-present 2>/dev/null; then
97
+ ((PASS++))
98
+ fi
99
+ else
100
+ echo " ⚠ No package.json — skipping JS/TS gate"
101
+ fi
102
+ fi
103
+
104
+ # ── Summary ───────────────────────────────────────────────────────────────────
105
+ echo ""
106
+ echo "── CI Gate Result ────────────────────────────────────────────────────"
107
+ echo " Passed : $PASS"
108
+ echo " Failed : $FAIL"
109
+ echo ""
110
+
111
+ if [[ "$FAIL" -eq 0 ]]; then
112
+ echo "✅ Gate green — safe to push."
113
+ exit 0
114
+ else
115
+ echo "❌ Gate failed — fix the issues above before pushing."
116
+ echo " --no-verify is not a valid workaround; CI will catch the same failures."
117
+ exit 1
118
+ fi
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env bash
2
+ # wpe-check.sh — verify SSH connectivity to all configured WP Engine environments.
3
+ #
4
+ # Reads installs from wp-cli.yml @aliases (ssh: field) or from WPE_INSTALLS env var.
5
+ # Useful after first-time machine setup or when debugging SSH issues.
6
+ #
7
+ # Usage:
8
+ # bash scripts/wpe-check.sh
9
+ # WPE_INSTALLS="mysite mysitestg mysitedev" bash scripts/wpe-check.sh
10
+ #
11
+ # Exit code: 0 = all connected, 1 = at least one failed.
12
+
13
+ set -uo pipefail
14
+ root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
15
+ cd "$root"
16
+
17
+ SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=8 -o StrictHostKeyChecking=accept-new"
18
+
19
+ # ── Discover installs from wp-cli.yml @aliases ────────────────────────────────
20
+ declare -A ALIAS_MAP # install → alias label
21
+ CURRENT_ALIAS=""
22
+
23
+ if [ -f wp-cli.yml ]; then
24
+ while IFS= read -r line; do
25
+ if [[ "$line" =~ ^@([a-zA-Z0-9_-]+): ]]; then
26
+ CURRENT_ALIAS="${BASH_REMATCH[1]}"
27
+ elif [[ "$line" =~ ^[[:space:]]+ssh:[[:space:]]+([^@[:space:]]+)@[^[:space:]]+ && -n "$CURRENT_ALIAS" ]]; then
28
+ INSTALL="${BASH_REMATCH[1]}"
29
+ ALIAS_MAP["$INSTALL"]="@${CURRENT_ALIAS}"
30
+ CURRENT_ALIAS=""
31
+ fi
32
+ done < wp-cli.yml
33
+ fi
34
+
35
+ # Fallback: WPE_INSTALLS env var
36
+ if [ "${#ALIAS_MAP[@]}" -eq 0 ] && [ -n "${WPE_INSTALLS:-}" ]; then
37
+ for slug in $WPE_INSTALLS; do
38
+ ALIAS_MAP["$slug"]="$slug"
39
+ done
40
+ fi
41
+
42
+ if [ "${#ALIAS_MAP[@]}" -eq 0 ]; then
43
+ echo "No WP Engine installs found."
44
+ echo ""
45
+ echo "Options:"
46
+ echo " 1. Add @aliases with 'ssh: <install>@<install>.ssh.wpengine.net' to wp-cli.yml"
47
+ echo " 2. Set WPE_INSTALLS='slug1 slug2 slug3' environment variable"
48
+ exit 1
49
+ fi
50
+
51
+ echo ""
52
+ echo "── WP Engine SSH connectivity ────────────────────────────────────────"
53
+ printf " %-25s %-15s %-12s %s\n" "Install" "Alias" "Status" "WP version"
54
+ echo " ─────────────────────────────────────────────────────────────────"
55
+
56
+ PASS=0
57
+ FAIL=0
58
+
59
+ for INSTALL in "${!ALIAS_MAP[@]}"; do
60
+ ALIAS="${ALIAS_MAP[$INSTALL]}"
61
+ SSH_HOST="${INSTALL}.ssh.wpengine.net"
62
+
63
+ WP_VERSION=$(ssh $SSH_OPTS "${INSTALL}@${SSH_HOST}" \
64
+ wp core version --skip-plugins --skip-themes 2>/dev/null || echo "")
65
+
66
+ if [ -n "$WP_VERSION" ]; then
67
+ printf " %-25s %-15s %-12s %s\n" "$INSTALL" "$ALIAS" "✓ connected" "$WP_VERSION"
68
+ ((PASS++))
69
+ else
70
+ printf " %-25s %-15s %-12s %s\n" "$INSTALL" "$ALIAS" "✗ FAILED" "—"
71
+ ((FAIL++))
72
+ fi
73
+ done
74
+
75
+ echo ""
76
+ echo " $PASS connected | $FAIL failed"
77
+
78
+ if [[ "$FAIL" -gt 0 ]]; then
79
+ echo ""
80
+ echo "Troubleshooting:"
81
+ echo " • Confirm key exists: ls -la ~/.ssh/wpengine_ed25519"
82
+ echo " • Confirm permissions: chmod 600 ~/.ssh/wpengine_ed25519"
83
+ echo " • Trust the host: ssh-keyscan -H ssh.wpengine.net >> ~/.ssh/known_hosts"
84
+ echo " • Check portal: https://my.wpengine.com/ssh_keys"
85
+ echo " • Verify git access: ssh git@git.wpengine.com info"
86
+ fi
87
+
88
+ echo ""
89
+ [[ "$FAIL" -eq 0 ]] && exit 0 || exit 1
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env bash
2
+ # wpe-preflight.sh — pre-deploy sanity checks for a WP Engine environment.
3
+ #
4
+ # Verifies SSH access, WP-CLI, site URL consistency, HTTP health, and
5
+ # active plugin count before any deploy touches production or staging.
6
+ #
7
+ # Usage:
8
+ # INSTALL=mysite bash scripts/wpe-preflight.sh [staging|production]
9
+ # WPE_INSTALL=mysite bash scripts/wpe-preflight.sh production
10
+ #
11
+ # Exit code: 0 = all checks passed (safe to deploy), 1 = at least one failed.
12
+
13
+ set -uo pipefail
14
+
15
+ ENV="${1:-production}"
16
+ INSTALL="${WPE_INSTALL:-${INSTALL:-}}"
17
+
18
+ if [ -z "$INSTALL" ]; then
19
+ echo "❌ Usage: INSTALL=<slug> bash scripts/wpe-preflight.sh [staging|production]"
20
+ echo " The install slug is the WP Engine environment name (e.g., 'mysite', 'mysitestg')."
21
+ exit 1
22
+ fi
23
+
24
+ SSH_HOST="${INSTALL}.ssh.wpengine.net"
25
+ SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
26
+ WP="ssh $SSH_OPTS ${INSTALL}@${SSH_HOST} wp"
27
+
28
+ PASS=0
29
+ FAIL=0
30
+
31
+ check() {
32
+ local label="$1"; shift
33
+ printf " %-50s" "$label"
34
+ local output
35
+ if output=$("$@" 2>&1); then
36
+ echo "✓ $output"
37
+ ((PASS++))
38
+ else
39
+ echo "✗ FAILED"
40
+ echo " $output" >&2
41
+ ((FAIL++))
42
+ fi
43
+ }
44
+
45
+ echo ""
46
+ echo "── WP Engine preflight: ${INSTALL} (${ENV}) ─────────────────────"
47
+ echo ""
48
+
49
+ # ── SSH ───────────────────────────────────────────────────────────────────────
50
+ echo "SSH"
51
+ check "SSH gateway reachable" \
52
+ ssh $SSH_OPTS "${INSTALL}@${SSH_HOST}" echo "connected"
53
+
54
+ check "WP-CLI available" \
55
+ $WP --info --skip-plugins --skip-themes
56
+
57
+ # ── WordPress ─────────────────────────────────────────────────────────────────
58
+ echo ""
59
+ echo "WordPress"
60
+ check "WP core version" \
61
+ $WP core version --skip-plugins --skip-themes
62
+
63
+ check "siteurl option readable" \
64
+ $WP option get siteurl --skip-plugins --skip-themes
65
+
66
+ check "Active plugins present (count > 0)" \
67
+ bash -c "COUNT=\$(${WP} plugin list --status=active --format=count --skip-plugins --skip-themes 2>&1); echo \"\$COUNT active\"; [[ \"\$COUNT\" -gt 0 ]]"
68
+
69
+ check "No pending DB upgrades" \
70
+ $WP core update-db --dry-run --skip-plugins --skip-themes
71
+
72
+ # ── HTTP health ───────────────────────────────────────────────────────────────
73
+ echo ""
74
+ echo "HTTP health"
75
+ SITE_URL=$(ssh $SSH_OPTS "${INSTALL}@${SSH_HOST}" \
76
+ wp option get home --skip-plugins --skip-themes 2>/dev/null || echo "")
77
+
78
+ if [ -n "$SITE_URL" ]; then
79
+ check "Homepage returns 2xx/3xx" \
80
+ bash -c "STATUS=\$(curl -s -o /dev/null -w '%{http_code}' -L --max-time 15 '${SITE_URL}'); echo \"HTTP \$STATUS\"; [[ \"\$STATUS\" -ge 200 && \"\$STATUS\" -lt 400 ]]"
81
+
82
+ check "No PHP errors in homepage body" \
83
+ bash -c "BODY=\$(curl -sL --max-time 15 '${SITE_URL}'); echo \"\${#BODY} chars\"; ! echo \"\$BODY\" | grep -qi 'fatal error\|parse error\|warning: '"
84
+
85
+ check "wp-json REST API responds" \
86
+ bash -c "STATUS=\$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 '${SITE_URL}/wp-json/wp/v2/'); echo \"HTTP \$STATUS\"; [[ \"\$STATUS\" -ge 200 && \"\$STATUS\" -lt 400 ]]"
87
+ else
88
+ echo " ⚠ Could not retrieve site URL — skipping HTTP checks"
89
+ fi
90
+
91
+ # ── Result ────────────────────────────────────────────────────────────────────
92
+ echo ""
93
+ echo "── Preflight result ──────────────────────────────────────────────────"
94
+ echo " Passed : $PASS"
95
+ echo " Failed : $FAIL"
96
+ echo ""
97
+
98
+ if [[ "$FAIL" -eq 0 ]]; then
99
+ echo "✅ All checks passed — safe to deploy to ${ENV}."
100
+ exit 0
101
+ else
102
+ echo "❌ Preflight failed — resolve the issues above before deploying to ${ENV}."
103
+ exit 1
104
+ fi
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: wpds
3
+ description: "Use when building UIs leveraging the WordPress Design System (WPDS) and its components, tokens, patterns, etc."
4
+ license: GPL-2.0-or-later
5
+ compatibility: "Requires WPDS MCP server configured and running. Targets WordPress 6.9+ (PHP 7.2.24+)."
6
+ ---
7
+
8
+ # WordPress Design System (WPDS)
9
+
10
+ ## Prerequisites
11
+
12
+ This skill works best with the **WPDS MCP server** installed. The MCP provides access to WordPress Design System documentation and resources, such as components and DS token lists.
13
+
14
+ The following terms should be treated as synonyms:
15
+ - "WordPress" and "WP";
16
+ - "Design System" and "DS";
17
+ - "WordPress Design System" and "WPDS".
18
+
19
+ ## When to use
20
+
21
+ Use this skill when the user mentions:
22
+
23
+ - building and/or reviewing any UI in a WordPress-related context (for example, Gutenberg, WooCommerce, WordPress.com, Jetpack, etc etc);
24
+ - WordPress Design System, WPDS, Design System;
25
+ - UI components, Design tokens, color primitives, spacing scales, typography variables and presets;
26
+ - Specific component packages such as @wordpress/components or @wordpress/ui;
27
+
28
+ ## Rules
29
+
30
+ ### Use the WPDS MCP server to access WPDS-related documentation
31
+
32
+ - Use the WPDS MCP server to retrieve the canonical, authoritative documentation:
33
+ - reference site (`wpds://pages`)
34
+ - list of available components (`wpds://components`) and specific component information (`wpds://components/:name`)
35
+ - list of available tokens (`wpds://design-tokens`)
36
+ - DO NOT search the web for canonical documentation about the WordPress Design System. If asked by the user, push back and ask for confirmation, warning them that the MCP server is the best place to provide information
37
+
38
+ ### Required documentation
39
+
40
+ Before working on any WPDS-related tasks, make sure you read relevant documentation on the reference site. This documentation should take the absolute precedence when evaluating the best course of action for any given tasks.
41
+
42
+ ### Boundaries
43
+
44
+ - Skip non-UI related aspects of an answer (for example, fetching data from stores, or localizing strings of text).
45
+ - Focus on building UI that adheres as much as possible to the WPDS best practices, uses the most fitting WPDS components/tokens/patterns.
46
+
47
+ ### Tech stack
48
+
49
+ - Unless you are told otherwise (or gathered specific information from the local context of the request), assume the following tech stack: TypeScript, React, CSS.
50
+
51
+ ### Validation
52
+
53
+ - If the local context in which a task is running provide lint scripts, use them to validate the proposed code output when possible.
54
+
55
+ ## Output
56
+
57
+ - As a recap at the end of your response, provide a clear and concise explanation of what the solution does, and add context to why each decision was made.
58
+ - Be explicit about the boundaries, ie. what was explicitly left out of the task because not relevant (eg non-ui related).
59
+ - Provide working code snippets
@@ -14,8 +14,7 @@ When a task is assigned, you must retrieve information in this sequence:
14
14
 
15
15
  1. **Local Project Instructions**: Read `.github/instructions/wordpress-workflow.instructions.md` to understand the specific prefix, folder structure, and dev workflow for this repo.
16
16
 
17
- 2. **Agent Skills**: Consult the `.github/skills/` directory.
18
-
17
+ 2. **Agent Skills**: Consult the `.agents/skills/` directory.
19
18
  - Reference `wp-project-triage` to confirm if you are in a Plugin or Theme context.
20
19
  - Reference `wp-block-development` for any Gutenberg/React tasks.
21
20
  - Reference `wp-playground` to provide testable blueprints for your code.
@@ -1,2 +1,2 @@
1
1
  @workspace /AGENTS.md
2
- @workspace / .github/instructions/wordpress-workflow.instructions.md
2
+ @workspace / .github/instructions/wordpress-workflow.instructions.md
@@ -1,10 +1,10 @@
1
1
  \# WordPress Agent Skills Workflow
2
2
 
3
- This repo uses a local, filesystem-based set of WordPress agent skills under `.github/skills/`. Follow these procedures for every interaction.
3
+ This repo uses a local, filesystem-based set of WordPress agent skills under `.agents/skills/`. Follow these procedures for every interaction.
4
4
 
5
5
  \## 1. Skill Discovery & Activation
6
6
 
7
- \- \*\*Always start by scanning \`.github/skills/\`\*\* to see which specialized modules are active.
7
+ \- \*\*Always start by scanning \`.agents/skills/\`\*\* to see which specialized modules are active.
8
8
 
9
9
  \- If the user asks for a Block, explicitly activate the \`wp-block-development\` skill.
10
10
 
@@ -38,4 +38,4 @@ Before finalizing a response:
38
38
 
39
39
  2\. Check if a [WordPress.org Plugin Handbook]\(https://developer.wordpress.org) rule supersedes a generic community pattern.
40
40
 
41
- 3\. State which skill was used (e.g., \*"Applied patterns from wp-block-development"\*).
41
+ 3\. State which skill was used (e.g., \*"Applied patterns from wp-block-development"\*).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wp-playground
3
- description: "Use for WordPress Playground workflows: fast disposable WP instances in the browser or locally via @wp-playground/cli (server, run-blueprint, build-snapshot), auto-mounting plugins/themes, switching WP/PHP versions, blueprints, and debugging (Xdebug)."
3
+ description: "Use for WordPress Playground workflows: fast disposable WP instances in the browser or locally via @wp-playground/cli (server, run-blueprint, build-snapshot), auto-mounting plugins/themes, switching WP/PHP versions, blueprints, PHPUnit testing, E2E Playwright testing, programmatic runCLI API, and debugging (Xdebug)."
4
4
  license: GPL-2.0-or-later
5
5
  compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Playground CLI requires Node.js 20.18+; runs WP in WebAssembly with SQLite."
6
6
  ---
@@ -14,6 +14,9 @@ compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Playground CLI requires No
14
14
  - Build a reproducible snapshot of a site for sharing or CI.
15
15
  - Switch WP/PHP versions quickly to reproduce issues.
16
16
  - Debug plugin/theme code with Xdebug in an isolated Playground.
17
+ - Run PHPUnit tests without a local database (no Docker, no MySQL).
18
+ - Write E2E Playwright tests against a real WordPress instance.
19
+ - Automate Playground in CI/CD pipelines via the programmatic `runCLI` API.
17
20
 
18
21
  ## Inputs required
19
22
 
@@ -82,6 +85,134 @@ npx @wp-playground/cli@latest build-snapshot --blueprint=<file> --outfile=./site
82
85
  - Query: `https://playground.wordpress.net/?blueprint-url=<public-url-or-zip>`
83
86
  - Use the live Blueprint Editor (playground.wordpress.net) to author blueprints with schema help; paste JSON and copy a shareable link.
84
87
 
88
+ ### 8) PHPUnit testing (no database required)
89
+
90
+ Run PHPUnit inside Playground — every run starts with a clean WordPress install, fully isolated.
91
+
92
+ Plugin:
93
+ ```bash
94
+ npx @wp-playground/cli@latest php \
95
+ --auto-mount \
96
+ -- \
97
+ /wordpress/wp-content/plugins/MY_PLUGIN/vendor/bin/phpunit \
98
+ -c /wordpress/wp-content/plugins/MY_PLUGIN/phpunit.xml.dist
99
+ ```
100
+
101
+ Theme (replace `plugins/` with `themes/`):
102
+ ```bash
103
+ npx @wp-playground/cli@latest php \
104
+ --auto-mount \
105
+ -- \
106
+ /wordpress/wp-content/themes/MY_THEME/vendor/bin/phpunit \
107
+ -c /wordpress/wp-content/themes/MY_THEME/phpunit.xml.dist
108
+ ```
109
+
110
+ - Requires PHPUnit installed via Composer in the project (`composer require --dev phpunit/phpunit`).
111
+ - `--auto-mount` maps the current directory to the correct WP content path automatically.
112
+ - Use `--php=8.1 --wp=6.5` flags to test against specific versions (PHP 7.4–8.5 supported).
113
+ - Explicit mount: `--mount=.:/wordpress/wp-content/plugins/MY_PLUGIN`.
114
+
115
+ ### 9) E2E testing with Playwright
116
+
117
+ Use `runCLI` from `@wp-playground/cli` to start a Playground server programmatically in Playwright tests. No Docker, no database.
118
+
119
+ Install:
120
+ ```bash
121
+ npm install --save-dev @playwright/test @wp-playground/cli
122
+ npx playwright install chromium
123
+ ```
124
+
125
+ Minimal `playwright.config.ts`:
126
+ ```ts
127
+ import { defineConfig } from '@playwright/test';
128
+ export default defineConfig({
129
+ testDir: './tests/e2e',
130
+ fullyParallel: false,
131
+ workers: 1, // prevent port conflicts
132
+ timeout: 120_000, // WP boot takes time
133
+ expect: { timeout: 30_000 },
134
+ use: { screenshot: 'only-on-failure', trace: 'on-first-retry' },
135
+ });
136
+ ```
137
+
138
+ First test (`tests/e2e/plugin.spec.ts`):
139
+ ```ts
140
+ import { test, expect } from '@playwright/test';
141
+ import { runCLI } from '@wp-playground/cli';
142
+
143
+ let cli: Awaited<ReturnType<typeof runCLI>>;
144
+
145
+ test.beforeAll(async () => {
146
+ cli = await runCLI({
147
+ command: 'server',
148
+ blueprint: {
149
+ preferredVersions: { php: '8.3', wp: 'latest' },
150
+ login: true,
151
+ },
152
+ });
153
+ });
154
+
155
+ test.afterAll(async () => { await cli?.server?.close(); });
156
+
157
+ test('dashboard loads', async ({ page }) => {
158
+ await page.goto(`${cli.serverUrl}/wp-admin/`);
159
+ await expect(page.locator('#wpbody-content')).toBeVisible();
160
+ });
161
+ ```
162
+
163
+ Mount a local plugin:
164
+ ```ts
165
+ cli = await runCLI({
166
+ command: 'server',
167
+ mount: { './': '/wordpress/wp-content/plugins/my-plugin' },
168
+ blueprint: {
169
+ preferredVersions: { php: '8.3', wp: 'latest' },
170
+ login: true,
171
+ steps: [{ step: 'activatePlugin', pluginPath: 'my-plugin/my-plugin.php' }],
172
+ },
173
+ });
174
+ ```
175
+
176
+ Locator priority (most to least preferred):
177
+ 1. `page.getByRole()` — buttons, headings, links, inputs
178
+ 2. `page.getByLabel()` — labeled form fields
179
+ 3. `page.getByText()` — visible text
180
+ 4. `page.getByTestId()` — your own `data-testid` attributes
181
+ 5. `page.locator()` — CSS/XPath last resort (WP core layout elements like `#wpadminbar`)
182
+
183
+ Version matrix pattern:
184
+ ```ts
185
+ const matrix = [{ php: '8.1', wp: '6.5' }, { php: '8.3', wp: 'latest' }];
186
+ for (const { php, wp } of matrix) {
187
+ test.describe(`PHP ${php} + WP ${wp}`, () => {
188
+ // ... beforeAll/afterAll with those versions
189
+ });
190
+ }
191
+ ```
192
+
193
+ CI (GitHub Actions): see `references/e2e-playwright.md`.
194
+
195
+ ### 10) Programmatic `runCLI` API (scripts / Vitest integration)
196
+
197
+ ```ts
198
+ import { runCLI } from '@wp-playground/cli';
199
+
200
+ const server = await runCLI({
201
+ command: 'server',
202
+ php: '8.3',
203
+ wp: 'latest',
204
+ login: true,
205
+ mount: [{ hostPath: './my-plugin', vfsPath: '/wordpress/wp-content/plugins/my-plugin' }],
206
+ blueprint: { steps: [{ step: 'activatePlugin', pluginPath: 'my-plugin/plugin.php' }] },
207
+ });
208
+
209
+ // server.serverUrl — the base URL
210
+ // server.server — the HTTP server instance (call .close() in afterEach)
211
+ // server[Symbol.asyncDispose]() — cleanup in Vitest afterEach
212
+ ```
213
+
214
+ Use `wordpressInstallMode: 'do-not-attempt-installing'` + `skipSqliteSetup: true` when testing pure PHP with no WordPress overhead.
215
+
85
216
  ## Verification
86
217
 
87
218
  - Verify mounted code is active (plugin listed/active; theme selected).
@@ -0,0 +1,115 @@
1
+ # E2E Testing with Playwright + WordPress Playground
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install --save-dev @playwright/test @wp-playground/cli
7
+ npx playwright install chromium
8
+ ```
9
+
10
+ ## playwright.config.ts
11
+
12
+ ```ts
13
+ import { defineConfig } from '@playwright/test';
14
+ export default defineConfig({
15
+ testDir: './tests/e2e',
16
+ fullyParallel: false,
17
+ forbidOnly: !!process.env.CI,
18
+ retries: process.env.CI ? 2 : 0,
19
+ workers: 1,
20
+ reporter: 'html',
21
+ timeout: 120_000,
22
+ expect: { timeout: 30_000 },
23
+ use: { screenshot: 'only-on-failure', trace: 'on-first-retry' },
24
+ });
25
+ ```
26
+
27
+ ## Server lifecycle
28
+
29
+ **Shared** (faster, tests can affect each other — use for read-only tests):
30
+ ```ts
31
+ test.beforeAll(async () => { cli = await runCLI({ command: 'server', blueprint }); });
32
+ test.afterAll(async () => { await cli?.server?.close(); });
33
+ ```
34
+
35
+ **Per-test** (isolated, slower — use when tests modify state):
36
+ ```ts
37
+ test.beforeEach(async () => { cli = await runCLI({ command: 'server', blueprint }); });
38
+ test.afterEach(async () => { await cli?.server?.close(); });
39
+ ```
40
+
41
+ ## Blueprint fixtures
42
+
43
+ Installing from wordpress.org:
44
+ ```ts
45
+ steps: [{ step: 'installPlugin', pluginData: { resource: 'wordpress.org/plugins', slug: 'contact-form-7' } }]
46
+ ```
47
+
48
+ Creating content:
49
+ ```ts
50
+ steps: [{ step: 'runPHP', code: `<?php require '/wordpress/wp-load.php'; wp_insert_post([...]);` }]
51
+ ```
52
+
53
+ ## WordPress-specific locator guidance
54
+
55
+ - `page.getByRole('button', { name: 'Save Changes' })` — works for standard WP buttons
56
+ - `page.getByLabel('API Key')` — works for labeled form fields
57
+ - `page.locator('#wpadminbar')` — CSS required for WP core layout elements (no ARIA)
58
+ - Add `data-testid` to your own plugin markup for stable selectors
59
+ - Run `npx playwright codegen localhost:9400/wp-admin/` to auto-generate locators
60
+
61
+ ## Page Object Model
62
+
63
+ ```ts
64
+ // tests/e2e/pages/plugin-settings.ts
65
+ export class PluginSettingsPage {
66
+ constructor(readonly page: Page) {}
67
+ async goto(baseUrl: string) { await this.page.goto(`${baseUrl}/wp-admin/options-general.php?page=my-plugin`); }
68
+ async setApiKey(key: string) {
69
+ await this.page.getByLabel('API Key').fill(key);
70
+ await this.page.getByRole('button', { name: 'Save Changes' }).click();
71
+ }
72
+ async expectSaved() { await expect(this.page.getByText('Settings saved')).toBeVisible(); }
73
+ }
74
+ ```
75
+
76
+ ## GitHub Actions CI
77
+
78
+ ```yaml
79
+ name: E2E Tests
80
+ on:
81
+ push: { branches: [main] }
82
+ pull_request: { branches: [main] }
83
+ jobs:
84
+ e2e:
85
+ runs-on: ubuntu-latest
86
+ steps:
87
+ - uses: actions/checkout@v4
88
+ - uses: actions/setup-node@v4
89
+ with: { node-version: 20, cache: 'npm' }
90
+ - run: npm ci
91
+ - uses: actions/cache@v4
92
+ id: playwright-cache
93
+ with:
94
+ path: ~/.cache/ms-playwright
95
+ key: playwright-${{ hashFiles('package-lock.json') }}
96
+ - if: steps.playwright-cache.outputs.cache-hit != 'true'
97
+ run: npx playwright install chromium --with-deps
98
+ - run: npx playwright test
99
+ - uses: actions/upload-artifact@v4
100
+ if: ${{ !cancelled() }}
101
+ with: { name: playwright-report, path: playwright-report/, retention-days: 30 }
102
+ ```
103
+
104
+ ## Troubleshooting
105
+
106
+ - **Timeout errors** — increase `timeout` in config; CI needs 120–180s
107
+ - **Port conflicts** — don't hardcode ports; use `cli.serverUrl`
108
+ - **Browser not found** — run `npx playwright install chromium`
109
+ - **Passes locally, fails CI** — increase timeouts, ensure `workers: 1`
110
+ - **Debug** — `npx playwright test --debug` or `--ui` for interactive mode
111
+
112
+ ## Docs
113
+
114
+ - https://wordpress.github.io/wordpress-playground/guides/e2e-testing-with-playwright
115
+ - https://wordpress.github.io/wordpress-playground/guides/programmatic-playground-cli