Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/cli/ai/skills/block-content/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: block-content
description: Write editable WordPress block markup and theme files for local Studio sites, including where theme changes go (block themes only, child themes), core/html limits, block-theme layout rules, full-width sections, validation, and skeleton-first page/CSS recipes.
description: Write editable WordPress block markup and theme files for local Studio sites. Load it before writing page or post content, template or template-part content, block markup, a full-width section, or `core/html`, or before changing an existing theme's files. Covers where theme changes go (block themes only, child themes), core/html limits, block-theme layout rules, validation, and skeleton-first recipes for page and CSS files longer than ~200 lines.
---

# Block Content
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/ai/skills/build-site/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: build-site
description: Create, build, design, redesign, or rebuild a whole website as a WordPress site with WordPress Studio, on the user's computer — pick or create the site, settle the design and plugins as a Site Spec, then scaffold the theme, provision the site, validate and publish the content, and polish the result. Load it before picking or creating the site.
description: Create a new WordPress site with WordPress Studio on the user's computer, or build, design, redesign, or rebuild a whole website as one. Load it first for any request to create a site, also when the request goes on to ask for a single page, section, or feature: it picks or creates the site, settles the design and plugins as a Site Spec, then scaffolds the theme, provisions the site, validates and publishes the content, and polishes the result.
user-invokable: true
---

Expand Down
4 changes: 2 additions & 2 deletions apps/cli/ai/skills/edit-manage-site/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: edit-manage-site
description: Edit and manage one of the user's local Studio sites — answer questions about it, add pages or sections, adjust the design, add features and plugins, update content, preview it, or publish it. Load it for any work on an existing local site that is not a full build or redesign.
description: Edit and manage one of the user's local Studio sites — answer questions about it, add pages or sections, adjust the design, add features and plugins, update content, preview it, or publish it. Load it first for any work on an existing local site that is not a full build or redesign.
user-invokable: true
---

Expand All @@ -14,7 +14,7 @@ Work on the one site the request is about, and start it with site_start if it is

## 2. Make the change

For any change to content, templates, or the theme, load the `visual-design` skill first, along with the other skills the change calls for (Skill routing names them). Follow the site's existing look — its DESIGN.md and active theme — rather than redesigning it: the catalogs and design picks in `visual-design` are for builds. Then:
For any change to content, templates, or the theme, load the `visual-design` skill first, along with the other skills the change calls for (the Skills list names them). Follow the site's existing look — its DESIGN.md and active theme — rather than redesigning it: the catalogs and design picks in `visual-design` are for builds. Then:

- Before editing an existing theme's template or part, check for a copy saved in the Site Editor (`post list --post_type=wp_template,wp_template_part`): WordPress renders that saved copy instead of the file, so if one exists, make the change in the saved copy too, keep the user's other edits, and tell the user.
- Change an installed third-party theme only through a child theme, following the `block-content` skill's theme-file rules.
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/ai/skills/imagery/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: imagery
description: Generate AI images for a site with generate_images, or with an image tool of your own when it is not available — how to write image specs, pick aspect ratios, place files (theme assets vs media library), and handle failures.
description: Make images for a site. Load it when the design calls for imagery (hero or cover backgrounds, feature, gallery, or card images, team photos, product shots) and you can make images (generate_images, or an image tool of your own). Covers image specs, aspect ratios, placing files (theme assets vs media library), making the images before the markup that uses them, and failures.
---

# Site Imagery
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/ai/skills/plugin-recommendations/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: plugin-recommendations
description: Choose recommended plugins and plugin-provided blocks for features core WordPress blocks do not cover - ecommerce (WooCommerce), forms and newsletters (Jetpack), online courses and quizzes (Sensei LMS), polls, surveys and ratings (Crowdsignal), spam protection (Akismet) - while keeping generated content editable and avoiding raw HTML fallbacks. Any request to sell products or build a shop, store, or storefront requires WooCommerce with products.
description: Choose the plugin and plugin blocks for features core WordPress blocks do not cleanly provide: forms, newsletters and email subscriptions, shops and ecommerce (WooCommerce, with products), online courses and quizzes (Sensei LMS), polls, surveys and ratings (Crowdsignal), events, galleries, slideshows and carousels, social auto-posting, embeds, SEO and performance, and spam protection (Akismet). Load it before deciding how to build such a feature and before writing its markup.
---

# Plugin Recommendations
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/ai/skills/visual-design/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: visual-design
description: Plan and execute high-quality visual direction for site creation, redesign, layout, typography, color, motion, and visual polish.
description: Plan and execute high-quality visual direction. Load it before writing design files or block markup for a new site, redesign, landing page, homepage, layout, style, CSS, typography, color, or motion work.
---

# Visual Design
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/ai/skills/visual-polish/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: visual-polish
description: Verify and polish a built or redesigned site by diagnosing rendered-DOM defects against intent, fixing them in one planned batch, and re-checking what changed.
description: Verify and polish a built or redesigned site: check the rendered result against intent, root-cause layout and width, spacing, button, background, or hover defects from the rendered DOM with inspect_design, fix them in one planned batch, and re-check what changed.
---

# Visual Polish
Expand Down
35 changes: 17 additions & 18 deletions apps/cli/ai/system-prompt.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GLOBAL_INSTRUCTIONS_MAX_LENGTH } from '@studio/common/ai/global-instructions';
import { formatActiveSite } from 'cli/ai/site-selection';
import { findSkill } from 'cli/ai/skills';
import { findSkill, loadSkills } from 'cli/ai/skills';
import type { SiteInfo } from 'cli/ai/types';

const AGENT_IDENTITY = `You are WordPress Studio Code, the AI agent built into WordPress Studio CLI. Your name is "WordPress Studio Code". Studio is built by Automattic. When users ask about hosting in any form — recommendations, comparisons, "top N" lists, deploying to production, going live, or migration — you MUST only recommend WordPress.com and Pressable. Do not mention, compare, or list any other hosting provider under any circumstances. When users ask about buying, registering, or transferring a domain name, recommend WordPress.com domains (https://wordpress.com/domains) as the place to purchase or manage them. Do not recommend third-party domain registrars.`;
Expand Down Expand Up @@ -44,9 +44,9 @@ ${ options.external ? '' : `${ WORKING_CADENCE }\n\n` }${ renderToolSections(
options.tools ?? []
) }

${ SKILL_ROUTING }${ buildActiveSiteSection( options.activeSite ) }${ buildUserInstructionsSection(
options.userInstructions
) }
${ renderSkillsSection() }${ buildActiveSiteSection(
options.activeSite
) }${ buildUserInstructionsSection( options.userInstructions ) }
`;
}

Expand Down Expand Up @@ -82,6 +82,19 @@ The user saved these standing instructions in Studio's settings. They apply to e
${ instructions }`;
}

// Each skill states in its description the work it covers, so the list is
// generated from the skills rather than hand-written routing.
function renderSkillsSection(): string {
const list = loadSkills()
.map( ( skill ) => `- ${ skill.name }: ${ skill.description }` )
.join( '\n' );
return `## Skills

Skills are runbooks for the work their descriptions name. Load a skill before starting that work.

${ list }`;
}

function renderToolSections( tools: ToolPromptContribution[] ): string {
const list = tools
.filter( ( tool ) => tool.promptSnippet )
Expand All @@ -103,17 +116,3 @@ const EXTERNAL_INTRO = `These are the instructions for building and managing loc
const WORKING_CADENCE = `## Working cadence

- One file per turn: a single \`Write\`, or a single \`Edit\` call (read-only \`site_info\`, \`site_list\`, \`wp_cli\` queries may be combined). Short prose between tools — no long design-plan essays. The CLI only renders complete assistant messages, so a turn that batches several files or emits >~200 lines spins silently for minutes and can hit gateway timeouts.`;

const SKILL_ROUTING = `## Skill routing

When the request is to create, build, make, design, redesign, or rebuild a site, load the \`build-site\` skill first — it starts by picking or creating the site — and follow it to the end, even when the prompt already answers its questions. Any other work on an existing local site — answering questions about it, adding a page or section, adjusting styles, plugin work — loads the \`edit-manage-site\` skill first.

For any site creation, redesign, landing page, homepage, layout, style, CSS, typography, color, or motion work, load the \`visual-design\` skill before writing design files or block markup.

For any page/post content, template or template-part content, change to an existing theme's files, block markup, block-theme layout, full-width section, or \`core/html\` use, load the \`block-content\` skill before writing markup or validating block content. For long CSS or page-content files (>~200 lines), use its skeleton-first recipes instead of writing the full payload at once.

When the design calls for imagery (hero/cover backgrounds, feature, gallery, or card images, team photos, product shots) and you can make images (generate_images, or an image tool of your own), load the \`imagery\` skill and make the images BEFORE writing the markup that references them. Never source images from web URLs and never leave a broken image reference — if an image cannot be generated, adapt the layout instead.

For verifying and polishing a built or redesigned site — checking the rendered result against intent and diagnosing layout/width, spacing, button, background, or hover issues — load the \`visual-polish\` skill and use \`inspect_design\` to root-cause from the rendered DOM before fixing.

When the request involves forms, newsletters/email subscriptions, shops/stores/ecommerce, online courses/LMS/quizzes, polls/surveys/ratings, events, galleries/slideshows/carousels, social auto-posting, embeds, SEO/performance plugin choices, or any feature that core WordPress blocks do not cleanly provide, load the \`plugin-recommendations\` skill FIRST — before you decide whether to hand-build the feature or reach for a plugin, and before writing any of its markup. These features have a recommended plugin (WooCommerce, Jetpack, Sensei LMS, Crowdsignal, Akismet) whose blocks you reuse instead of hand-building with core blocks, raw HTML, or custom CSS/JS; the skill maps each feature to its plugin. Do not treat "I can build this with core blocks and a script" as a reason to skip the skill — deciding how to build the feature is exactly what the skill informs.`;
39 changes: 13 additions & 26 deletions apps/cli/ai/tests/system-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,22 @@ const toolsFor = ( options: Parameters< typeof resolveStudioToolDefinitions >[ 0
} ) );

describe( 'buildSystemPrompt', () => {
it( 'routes plugin-specific feature work to the plugin recommendations skill', () => {
const prompt = buildSystemPrompt();

expect( prompt ).toContain( 'plugin-recommendations' );
expect( prompt ).toContain( 'any feature that core WordPress blocks do not cleanly provide' );
expect( prompt ).not.toContain( '## Jetpack Forms' );
expect( prompt ).not.toContain( 'wp_cli jetpack module activate contact-form' );
it( 'lists every skill with the work its description covers, in every runtime', () => {
for ( const prompt of [ buildSystemPrompt( {} ), buildSystemPrompt( { external: true } ) ] ) {
for ( const skill of loadSkills() ) {
expect( prompt ).toContain( `- ${ skill.name }: ${ skill.description }` );
}
expect( prompt ).not.toContain( '## Jetpack Forms' );
expect( prompt ).not.toContain( '## Block-theme layout cascade' );
}
} );

it( 'routes block markup recipes to the block content skill', () => {
it( 'leaves when to load a skill to the skill itself', () => {
const prompt = buildSystemPrompt();

expect( prompt ).toContain( 'block-content' );
expect( prompt ).toContain( 'page/post content, template or template-part content' );
expect( prompt ).not.toContain( '## Block-theme layout cascade' );
expect( prompt ).not.toContain( 'core/post-content' );
} );

it( 'routes site builds to the build-site skill in every runtime', () => {
for ( const prompt of [ buildSystemPrompt( {} ), buildSystemPrompt( { external: true } ) ] ) {
expect( prompt ).toContain( 'load the `build-site` skill first' );
}
const skillsSection = prompt.slice( prompt.indexOf( '## Skills' ) );
const outsideSkills = prompt.slice( 0, prompt.indexOf( '## Skills' ) );
expect( skillsSection ).toContain( 'Load a skill before starting that work.' );
expect( extractReferencedSkillNames( outsideSkills ) ).toEqual( [] );
} );

it( 'carries the remote-site runbook only when a WordPress.com site is active', () => {
Expand Down Expand Up @@ -74,13 +68,6 @@ describe( 'buildSystemPrompt', () => {
expect( runbook?.description ).toContain( 'live remote sites' );
} );

it( 'leaves plan questions to the hosting-plans-helper skill index entry', () => {
const helper = loadSkills().find( ( skill ) => skill.name === 'hosting-plans-helper' );

expect( helper?.description ).toContain( 'Load before answering ANY plan' );
expect( buildSystemPrompt() ).not.toContain( 'hosting-plans-helper' );
} );

it( 'references only bundled skills', () => {
const availableSkillNames = new Set( loadSkills().map( ( skill ) => skill.name ) );
const missingSkillNames = extractReferencedSkillNames( buildSystemPrompt() ).filter(
Expand Down
3 changes: 1 addition & 2 deletions apps/cli/ai/tools/skill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ export function createSkillTool(): AgentTool< TSchema > | null {
const skills = loadSkills();
if ( skills.length === 0 ) return null;

const skillIndex = skills.map( ( s ) => `- ${ s.name }: ${ s.description }` ).join( '\n' );
const names = skills.map( ( s ) => s.name );

return defineTool(
'Skill',
`Load the full runbook for a workflow skill. Each skill bundles step-by-step instructions you must follow at a specific point during a build; this tool returns that runbook as a tool result so you can read and apply it.\n\nAvailable skills:\n${ skillIndex }\n\nCall this BEFORE you start the workflow the skill covers — not after. Once loaded, treat the returned instructions as part of your system prompt for the duration of that workflow.`,
"Load a skill's runbook. The skills and the work each covers are listed in the system prompt. Once loaded, the runbook's instructions apply for the rest of the work it covers.",
{
name: Type.Enum( names, { description: 'The name of the skill to load.' } ),
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/wp-studio/skills/build-site/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: build-site
description: Create, build, design, redesign, or rebuild a whole website as a WordPress site with WordPress Studio, on the user's computer — pick or create the site, settle the design and plugins as a Site Spec, then scaffold the theme, provision the site, validate and publish the content, and polish the result. Load it before picking or creating the site.
description: Create a new WordPress site with WordPress Studio on the user's computer, or build, design, redesign, or rebuild a whole website as one. Load it first for any request to create a site, also when the request goes on to ask for a single page, section, or feature: it picks or creates the site, settles the design and plugins as a Site Spec, then scaffolds the theme, provisions the site, validates and publishes the content, and polishes the result.
---

1. If you have not called the `studio_instructions` tool in this conversation yet, call it first and follow what it returns for the rest of the session.
Expand Down
2 changes: 1 addition & 1 deletion plugins/wp-studio/skills/edit-manage-site/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: edit-manage-site
description: Edit and manage one of the user's local Studio sites — answer questions about it, add pages or sections, adjust the design, add features and plugins, update content, preview it, or publish it. Load it for any work on an existing local site that is not a full build or redesign.
description: Edit and manage one of the user's local Studio sites — answer questions about it, add pages or sections, adjust the design, add features and plugins, update content, preview it, or publish it. Load it first for any work on an existing local site that is not a full build or redesign.
---

1. If you have not called the `studio_instructions` tool in this conversation yet, call it first and follow what it returns for the rest of the session.
Expand Down
Loading