Content Guidelines: Add AI-powered generate/improve UI via Jetpack#47959
Content Guidelines: Add AI-powered generate/improve UI via Jetpack#47959aagam-shah wants to merge 87 commits intotrunkfrom
Conversation
Adds a wpcom proxy endpoint that forwards guideline generation requests to the wpcom AI suggest-guidelines API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…es proxy - Accept and forward optional filters param to wpcom endpoint - Extensible structure for adding new filter types Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Jetpack plugin: The Jetpack plugin has different release cadences depending on the platform:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
Code Coverage SummaryCoverage changed in 1 file.
2 files are newly checked for coverage.
Full summary · PHP report · JS report If appropriate, add one of these labels to override the failing coverage check:
Covered by non-unit tests
|
|
Thanks for getting this started @aagam-shah. Here are a few comments based on what I see right now: 1. Badges 2. Suggestions The suggestions are presented in what appears like a disabled field: The container should look and behave like a regular input (but have a green border). We need to match the height of the input (and visa versa) to prevent layout shift. We also can accept a suggestion if someone clicks on the suggestion to start editing it. When the section is open, we don't need to show the suggestion badge any longer since the input + buttons communicate the suggestion. This is what I had in the design:
3. Banner behaviour The main banner dismisses if you generate a suggestion from within a section. The causes the layout to shift and feels jarring. The banner should only dismiss if the user dismisses it or the main call to action is used to generate guidelines for all the sections. 4. Block suggestions I'm not seeing any block suggestions being added. Are you planning on adding those separately? We should have suggestions for the block section as well as the blocks themselves.
|
dfbee81 to
3c42428
Compare
|
Thanks for the detailed feedback @fditrapani! Here's where we're at on each point: 1. Badges 2. Suggestions 3. Banner behaviour 4. Block suggestions |
|
Thanks for the updates @aagam-shah!
Sounds good to me if this is the badge we're already using. I understand we're updating components but hopefully this will get updates along with the others when that happens.
Thanks for the updates. This is looking better. We still have some shifting happening if the text area isn't the default size: Screen.Recording.2026-04-08.at.12.51.15.PM.mov
Nice! looking better here too. I noticed a bug where the banner unexpectedly goes away if you accept a suggestion. Screen.Recording.2026-04-08.at.12.53.02.PM.movJetpack logoI got some feedback from Devin that the logo should be reversed instead of the regular colour. (p1775665181650579/1775564866.152469-slack-C08NFD7RA58) Can we update the logo to look like this:
|
0b4325a to
e03390e
Compare
|
Thanks @fditrapani! Here's an update on the latest changes: 1. Suggestions UX — Updated:
2. Banner behaviour — Fixed:
3. Block suggestions — Still planned as a follow-up. 4. Upgrade notice — Added a persistent warning Notice (instead of snackbar) with a "View plans" button when AI is unavailable. Matches the standard WordPress notice pattern. |
Injects an AI-powered "Generate with Jetpack" button next to each "Save guidelines" button on the Content Guidelines settings page. Uses DOM injection via MutationObserver to find accordion forms and render React buttons that call the suggest-guidelines API endpoint. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pass AI availability, connection status, and upgrade URL from PHP to JS - Show contextual snackbar with action link when AI is unavailable: - Not connected: "Connect" action linking to Jetpack dashboard - Connected but no AI: "Upgrade" action linking to checkout - wpcom vs self-hosted sites get appropriate upgrade URLs - Disconnect MutationObserver once all buttons are injected - Inline buttons next to Save guidelines in a flex row Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Content Guidelines page is registered with slug 'guidelines-wp-admin', not 'content-guidelines-wp-admin'. Without this fix the script never enqueues. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split monolithic 146-line JS file into: - constants.js (store name, sections, API path) - lib/api.js (suggest-guidelines API wrapper) - lib/inject.js (DOM injection + MutationObserver) - components/generate-button.jsx (per-section button) Entry point is now a thin import + init. Button label changes to "Improve with Jetpack" when content exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New SuggestAllButton component generates all 4 guideline sections at once. Injected into the .admin-ui-page__header via DOM injection. Label adapts: "Generate guidelines" when empty, "Improve guidelines" when content exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows a Jetpack-branded card above the guideline list when all sections are empty, encouraging users to generate their first set of guidelines. Hides automatically when content exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Target .admin-ui-page__header-actions instead of .admin-ui-page__header so the button renders in the header row next to the title, not below the subtitle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Option B design only has the top-level "Generate/Improve guidelines" button and the empty state banner. Per-section buttons are not part of the design. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add wp.data store (jetpack/content-guidelines-ai) for shared suggestion state across injected React roots - Show "Suggestion" badge in accordion headers when a suggestion exists - Show loading spinner in accordion headers while generating - Show suggestion preview with Accept/Dismiss inside expanded accordions - Accept writes to core/content-guidelines store, Dismiss discards - Header button now writes to suggestion store instead of directly to the guideline store Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add per-section "Improve/Generate guidelines" tertiary button in each accordion's button row (triggers single-section AI generation) - When suggestion exists: hide Gutenberg's DataForm + Save/Clear via CSS class toggle, show suggestion textarea + Accept/Dismiss instead - Add Jetpack icon SVG to the header "Improve guidelines" button - Add per-section loading state to the store so each accordion shows its own spinner independently - Update suggestion badge to use per-section loading Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review fixes: - Extract shared availability check to lib/availability.js - Centralize config in constants.js - MutationObserver disconnects once all injections complete - Remove unused store actions/selectors - Add useEffect cleanup for DOM class manipulation - Use Jetpack CSS custom properties for colors Banner upgrade: - Rich dark gradient background with green orb decorations - Matches exploration-b prototype design - Shows when all guidelines empty, hides automatically - No localStorage persistence — purely data-driven Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the global Suggest All button fires with sections collapsed, textarea.offsetHeight is 0. Fall back to computing height from the rows attribute so the diff view matches the textarea size. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace custom PHP config and availability.js with the standard useAiFeature() and useAICheckout() hooks from jetpack-ai-client. Plan detection and checkout URLs are now fully client-side. HACK: requireUpgrade forced to true in UpgradeNotice for testing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6217069 to
fd5e3b8
Compare
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…es-plugin-extensibility # Conflicts: # pnpm-lock.yaml
- jetpack_ai_guidelines_generate: section/block generate or improve - jetpack_ai_guidelines_generate_all: global suggest all - jetpack_ai_guidelines_accept: accept a suggestion - jetpack_ai_guidelines_dismiss: dismiss a suggestion - jetpack_ai_upgrade_button: reuses existing event with placement=content-guidelines Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use hasFeature from useAiFeature() instead of requireUpgrade to block free-tier users entirely. Free tier (hasFeature: false) sees the upgrade notice and disabled buttons. Paid plans (AI Assistant or Complete) get full access. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds Jetpack AI-powered guideline generation/improvement UX to Gutenberg’s Content Guidelines admin screen, including section-level and block-level suggestions with word-diff review, plus a Jetpack REST proxy endpoint to request suggestions from wpcom.
Changes:
- Add a new admin-only Jetpack bundle that injects React UI into the Content Guidelines screen (buttons, banners, loading states, diff/accept/dismiss flows, Tracks events).
- Add a
/wpcom/v2/jetpack-ai/suggest-guidelinesREST API proxy endpoint to forward guideline suggestion requests upstream. - Add shared styling/tokens and a small client-side data store to coordinate loading + suggestions UI state.
Reviewed changes
Copilot reviewed 23 out of 24 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| projects/plugins/jetpack/package.json | Adds the diff dependency for word-level diffs. |
| projects/plugins/jetpack/load-jetpack.php | Loads the new Content Guidelines AI bootstrap on admin requests. |
| projects/plugins/jetpack/changelog/add-content-guidelines-plugin-extensibility | Changelog entry for the new AI guideline suggestions UI. |
| projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-agent-guidelines-ai.php | New wpcom/v2 proxy endpoint for suggest-guidelines requests. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/style.scss | Styles for injected UI (banner, shimmer, diff highlighting, modal tweaks). |
| projects/plugins/jetpack/_inc/content-guidelines-ai/store.js | Redux store for loading state, suggestions, and banner dismissal persistence. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/lib/tracks.js | Tracks helpers for content-guidelines AI events and shared AI events. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/lib/inject.js | MutationObserver-driven DOM injection of React roots into Gutenberg UI. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/lib/dom.js | DOM helpers for writing into React-controlled textareas and accepting block suggestions. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/lib/api.js | Client wrapper translating internal slugs to the REST API categories format. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/hooks/use-generate-all.js | Hook to generate/improve all section guidelines at once. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/constants.js | Constants for store names, valid sections, and REST path. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/upgrade-notice.jsx | Upgrade notice shown when AI feature isn’t available. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/suggestion-badge.jsx | Badge/spinner shown in accordion headers for per-section state. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/suggestion-actions.jsx | Section diff + accept/dismiss controls and form class toggling. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/suggest-all-button.jsx | Header “Generate/Improve guidelines” button logic/visibility. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/section-generate-button.jsx | Per-section generate/improve button and request logic. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/empty-state-banner.jsx | Empty-state Jetpack banner with “Get started” CTA and dismiss. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/diff-view.jsx | Shared word-diff renderer with click/keyboard-to-accept behavior. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/block-suggestion-buttons.jsx | Block modal action row: generate vs accept/dismiss. |
| projects/plugins/jetpack/_inc/content-guidelines-ai/components/block-suggestion-actions.jsx | Block modal diff view + modal class toggling + stale cleanup. |
| projects/plugins/jetpack/_inc/content-guidelines-ai.php | Admin enqueue + Automattician gating logic for the feature bundle. |
| projects/plugins/jetpack/_inc/content-guidelines-ai.js | Bundle entrypoint: store registration, styles, and injection startup. |
| pnpm-lock.yaml | Locks the new diff@8.0.4 dependency. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prevents bundle crash in Safari private mode or when storage is disabled. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| function jetpack_content_guidelines_ai_is_automattician() { | ||
| // Allow access via query parameter. | ||
| // phpcs:ignore WordPress.Security.NonceVerification.Recommended | ||
| if ( isset( $_GET['enable_ai_generation'] ) && 'true' === $_GET['enable_ai_generation'] ) { |
There was a problem hiding this comment.
We should remove this because we're already checking for proxy.
There was a problem hiding this comment.
I added this so that we can use JN sites for easy testing and debugging. Fine to remove this before merging it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>









Summary
Adds AI-powered guideline generation to the WordPress Content Guidelines admin page via Jetpack. Supports both section-level (site, copy, images, additional) and block-level (per-block) guidelines with word-level diffs for review.
What it does
Section-level AI
Block-level AI
Plan gating
useAiFeature()hook from@automattic/jetpack-ai-client— checkshasFeatureto gate to Jetpack AI / Complete plans only (no free tier access)useAICheckout()provides checkout URL for upgrade CTA!hasFeatureAutomattician gate
wpcom_is_proxied_request()+is_automattician()Visitor::is_automattician_feature_flags_only()?enable_ai_generation=truequery param bypass for testingShared components
lib/dom.js$cg-green,$cg-green-light,$cg-diff-added,$cg-diff-removedTracking (Tracks events)
jetpack_ai_guidelines_generate— section/block generate or improve (type,slug,action)jetpack_ai_guidelines_generate_all— global suggest all (action)jetpack_ai_guidelines_accept— accept a suggestion (type,slug)jetpack_ai_guidelines_dismiss— dismiss a suggestion (type,slug)jetpack_ai_upgrade_button— reuses existing event withplacement: "content-guidelines"API proxy
wpcom/v2/jetpack-ai/suggest-guidelinescategoriesobject through to wpcom (sections as top-level keys, blocks undercategories.blocks)Architecture
Uses DOM injection — Jetpack enqueues a standalone JS+CSS bundle on
settings_page_guidelines-wp-admin, uses MutationObserver to inject React components into Gutenberg's Content Guidelines page, and shares state viawp.datastores (jetpack/content-guidelines-aifor suggestions,wordpress-com/plansfor plan detection).Related
Testing instructions
pnpm jetpack build plugins/jetpackSection-level:
4. Verify empty state banner with "Get started" button
5. Click "Get started" — shimmer on textareas, spinners in headers
6. After generation: diff view with Accept / Dismiss
7. Accept — content moves to textarea. Dismiss — suggestion removed.
8. Navigate to history and back — injections re-appear
Block-level:
9. Open Blocks section, click Edit on a block
10. Click "Improve guidelines" in modal — shimmer on textarea
11. Diff appears, Accept/Dismiss below. Click-to-accept on diff works.
Plan gating:
12. On a site without Jetpack AI plan: upgrade notice shown, buttons disabled
13. On a site with Jetpack AI/Complete: full access
Does this pull request change what data or activity we track or use?
Yes. This PR adds Tracks events for guideline generation, acceptance, dismissal, and upgrade clicks (see Tracking section above). It also calls the Jetpack AI suggest-guidelines endpoint when users explicitly click generate/improve buttons.