Skip to content
Draft
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
48 changes: 40 additions & 8 deletions apps/cli/ai/system-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,50 @@ IMPORTANT: For any generated content for the site, these three principles are ma

For any request that involves a WordPress site, you MUST first determine which site to use:

- **"Create" / "build" / "make" a site**: Call site_create with a name as your FIRST tool call. Do NOT call site_list first. Do NOT reuse or repurpose any existing site. Every new project gets a fresh site.
- **User names a specific existing site**: Call site_list to find it.
- **"Create" / "build" / "make" a site**: Call site_create with a name as your FIRST tool call. Do NOT call site_list first. Do NOT reuse or repurpose any existing site. Every new project gets a fresh site. Then follow the **Creation workflow** below.
- **User names a specific existing site**: Call site_list to find it. Then follow the **Modification workflow** below.
- **User doesn't specify**: Ask the user whether to create a new site or use an existing one.

Then continue with:
### Creation workflow

1. **Get site details**: Use site_info to get the site path, URL, and credentials.
2. **Plan the design**: Before writing any code, read the Design Guidelines below and plan the visual direction — layout, colors, typography, spacing.
3. **Write theme/plugin files**: Use Write and Edit to create files under the site's wp-content/themes/ or wp-content/plugins/ directory.
4. **Configure WordPress**: Use wp_cli to activate themes, install plugins, manage options, create posts and pages, edit and import content. The site must be running. Note: post content passed via \`wp post create\` or \`wp post update --post_content=...\` need to be pre-validated for editability and also validated using validate_blocks tool and adhere to the block content guidelines above as well.
5. **Check the misuse of HTML blocks**: Verify if HTML blocks were used as sections or not. If they were, convert them to regular core blocks and run block validation again.
6. **Check the result**: Use take_screenshot to capture the site's landing page on desktop and mobile and verify the design visually on both viewports, check for wrong spacing, alignment, colors, contrast, borders, hover styles and other visual issues. Fix any issues found. Pay particular attention to the navigation menu and the CTA buttons. The design needs to match your original expectations.
2. **Initialize version control**: Run \`git init\` and \`git add -A && git commit -m "Initial WordPress installation"\` in the site directory using Bash. This creates a safety checkpoint you can revert to if anything goes wrong.
3. **Plan the design**: Before writing any code, read the Design Guidelines below and plan the visual direction — layout, colors, typography, spacing.
4. **Write theme/plugin files**: Use Write and Edit to create files under the site's wp-content/themes/ or wp-content/plugins/ directory.
5. **Configure WordPress**: Use wp_cli to activate themes, install plugins, manage options, create posts and pages, edit and import content. The site must be running. Note: post content passed via \`wp post create\` or \`wp post update --post_content=...\` need to be pre-validated for editability and also validated using validate_blocks tool and adhere to the block content guidelines above as well.
6. **Check the misuse of HTML blocks**: Verify if HTML blocks were used as sections or not. If they were, convert them to regular core blocks and run block validation again.
7. **Verify quality**: Run the quality checks described in the Quality Verification section below.
8. **Check the result**: Use take_screenshot to capture the site's landing page on desktop and mobile and verify the design visually on both viewports, check for wrong spacing, alignment, colors, contrast, borders, hover styles and other visual issues. Fix any issues found. Pay particular attention to the navigation menu and the CTA buttons. The design needs to match your original expectations.
9. **Commit your work**: Run \`git add -A && git commit -m "<description of what was built>"\` in the site directory.

### Modification workflow

When the user asks you to change, update, fix, or extend an **existing** site:

1. **Get site details**: Use site_info to get the site path, URL, and credentials.
2. **Analyze the existing site**: Before making any changes, understand what is already there:
- Read the active theme's \`theme.json\` (if it exists) to understand the design system — colors, typography, spacing presets.
- Run \`wp_cli\` with \`theme list --status=active --format=json\` and \`plugin list --status=active --format=json\` to know what is installed.
- Read the active theme's \`style.css\` and \`functions.php\` to understand existing patterns and hooks.
- If modifying content, run \`wp_cli\` with \`post list --post_type=page --format=json\` to see the site's page structure.
- Respect the existing design system. Use the colors, fonts, and spacing already defined in \`theme.json\` rather than introducing new ones, unless the user explicitly asks for a redesign.
3. **Create a safety checkpoint**: If the site directory is not already a git repository, run \`git init\` and \`git add -A && git commit -m "Pre-modification checkpoint"\` using Bash. If it is already a git repo, commit any uncommitted changes first: \`git add -A && git commit -m "Save current state before modifications"\`. This lets you revert with \`git checkout .\` if something goes wrong.
4. **Capture the current state**: Use take_screenshot on the pages you are about to modify (desktop and mobile). This is your "before" reference.
5. **Make targeted changes**: Only modify what the user asked for. Do not restructure or restyle parts of the site that are working correctly. When editing theme files, preserve existing code and add to it rather than rewriting from scratch.
6. **Verify quality**: Run the quality checks described in the Quality Verification section below.
7. **Compare before and after**: Use take_screenshot again on the same pages. Visually compare against your "before" screenshots. Verify that:
- The requested changes are visible and correct.
- Nothing else broke — other sections, navigation, footer, and overall layout should look the same as before.
- No visual regressions were introduced (spacing, colors, fonts, alignment).
8. **Commit your work**: Run \`git add -A && git commit -m "<description of what was changed>"\` in the site directory. If the user is unhappy with the result, you can revert with \`git revert HEAD\`.

## Quality verification

Run these checks after making changes and before taking final screenshots. Use Bash to run commands in the site directory.

1. **Check for PHP errors**: Read the debug log with \`cat wp-content/debug.log 2>/dev/null | tail -50\`. If the file contains recent errors or warnings related to your changes, fix them.
2. **Verify the site loads**: Use wp_cli with \`option get siteurl\` to confirm WordPress is responding. If WP-CLI fails, the site may be broken — check the debug log and revert your last change if needed.
3. **Validate block content**: If you created or modified post/page content, run validate_blocks to ensure all blocks are valid.

## Available Studio Tools (prefixed with mcp__studio__)

Expand Down
105 changes: 105 additions & 0 deletions apps/cli/ai/tests/system-prompt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { buildSystemPrompt } from '../system-prompt';

describe( 'buildSystemPrompt', () => {
const prompt = buildSystemPrompt();

it( 'should return a non-empty string', () => {
expect( prompt ).toBeTruthy();
expect( typeof prompt ).toBe( 'string' );
} );

describe( 'workflow routing', () => {
it( 'should route "create" requests to the creation workflow', () => {
expect( prompt ).toContain( 'follow the **Creation workflow**' );
} );

it( 'should route existing site requests to the modification workflow', () => {
expect( prompt ).toContain( 'follow the **Modification workflow**' );
} );
} );

describe( 'creation workflow', () => {
it( 'should include git initialization step', () => {
expect( prompt ).toContain( 'git init' );
expect( prompt ).toContain( 'Initial WordPress installation' );
} );

it( 'should include quality verification step', () => {
expect( prompt ).toContain(
'**Verify quality**: Run the quality checks described in the Quality Verification section'
);
} );

it( 'should include final commit step', () => {
expect( prompt ).toContain( '**Commit your work**: Run `git add -A && git commit' );
} );
} );

describe( 'modification workflow', () => {
it( 'should include site analysis step', () => {
expect( prompt ).toContain( '**Analyze the existing site**' );
} );

it( 'should instruct reading theme.json', () => {
expect( prompt ).toContain( 'theme.json' );
expect( prompt ).toContain( 'design system' );
} );

it( 'should instruct checking active plugins', () => {
expect( prompt ).toContain( 'plugin list --status=active --format=json' );
} );

it( 'should include safety checkpoint step', () => {
expect( prompt ).toContain( '**Create a safety checkpoint**' );
expect( prompt ).toContain( 'Pre-modification checkpoint' );
} );

it( 'should include before/after screenshot comparison', () => {
expect( prompt ).toContain( '**Capture the current state**' );
expect( prompt ).toContain( '**Compare before and after**' );
} );

it( 'should instruct targeted changes only', () => {
expect( prompt ).toContain( '**Make targeted changes**' );
expect( prompt ).toContain( 'Only modify what the user asked for' );
} );

it( 'should include revert instructions', () => {
expect( prompt ).toContain( 'git revert HEAD' );
} );
} );

describe( 'quality verification', () => {
it( 'should include PHP error checking', () => {
expect( prompt ).toContain( 'debug.log' );
expect( prompt ).toContain( 'PHP errors' );
} );

it( 'should include site health verification', () => {
expect( prompt ).toContain( 'option get siteurl' );
expect( prompt ).toContain( 'WordPress is responding' );
} );

it( 'should include block validation', () => {
expect( prompt ).toContain( 'run validate_blocks' );
} );
} );

describe( 'existing sections preserved', () => {
it( 'should still contain design guidelines', () => {
expect( prompt ).toContain( '## Design guidelines' );
} );

it( 'should still contain block content guidelines', () => {
expect( prompt ).toContain( '## Block content guidelines' );
} );

it( 'should still contain available studio tools', () => {
expect( prompt ).toContain( '## Available Studio Tools' );
} );

it( 'should still contain general rules', () => {
expect( prompt ).toContain( '## General rules' );
} );
} );
} );
75 changes: 75 additions & 0 deletions tools/common/lib/agents-md.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,81 @@ studio wp db query "SELECT option_name, option_value FROM wp_options LIMIT 10;"
- Do not reference \`DB_NAME\`, \`DB_HOST\`, \`DB_USER\`, or \`DB_PASSWORD\` constants — they are not defined on this site
- Plugins that explicitly check for a MySQL connection and refuse to run may not be compatible

## Version Control

Studio sites are regular directories — you can use git for version control and safe experimentation.

**Initialize a new site:**
\`\`\`bash
cd /path/to/site
git init
git add -A
git commit -m "Initial WordPress installation"
\`\`\`

**Before making changes** to an existing site, commit the current state so you can revert if needed:
\`\`\`bash
git add -A && git commit -m "Pre-modification checkpoint"
\`\`\`

**After making changes**, commit your work:
\`\`\`bash
git add -A && git commit -m "Add blog section with custom styling"
\`\`\`

**If something breaks**, revert to the last checkpoint:
\`\`\`bash
git checkout . # Discard uncommitted changes
git revert HEAD # Undo the last commit (keeps history)
\`\`\`

**Recommended .gitignore** for Studio sites:
\`\`\`
# WordPress core (managed by Studio)
/wp-admin/
/wp-includes/
/wp-*.php
/index.php
/xmlrpc.php
/license.txt
/readme.html

# Database
wp-content/database/

# Studio internals
wp-content/mu-plugins/sqlite-database-integration/
wp-content/db.php
\`\`\`

This keeps only your custom work (themes, plugins, uploads) under version control.

## Quality Checks

After making changes to a site, verify your work:

**Check for PHP errors:**
\`\`\`bash
studio wp eval "error_reporting(E_ALL); ini_set('display_errors', 1);" 2>&1
cat wp-content/debug.log 2>/dev/null | tail -30
\`\`\`

**Verify the site responds:**
\`\`\`bash
studio wp option get siteurl # Should return the site URL without errors
studio wp post list --format=count # Quick check that the database is accessible
\`\`\`

**Before modifying an existing site**, understand what is already there:
\`\`\`bash
studio wp theme list --status=active --format=json
studio wp plugin list --status=active --format=json
studio wp post list --post_type=page --format=json
cat wp-content/themes/$(studio wp option get stylesheet)/theme.json 2>/dev/null
\`\`\`

This helps you make targeted changes that respect the existing design system and avoid breaking what already works.

## Studio-Specific Notes

**WordPress core:** Do not modify files inside \`wp-includes/\` or \`wp-admin/\`. Studio sites run on WordPress Playground (PHP WASM), and core changes will not persist as expected.
Expand Down
87 changes: 87 additions & 0 deletions tools/common/lib/tests/agents-md.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { AGENTS_MD_TEMPLATE, AGENTS_MD_FILE_NAME } from '../agents-md';

describe( 'AGENTS_MD_TEMPLATE', () => {
it( 'should export a non-empty template string', () => {
expect( AGENTS_MD_TEMPLATE ).toBeTruthy();
expect( typeof AGENTS_MD_TEMPLATE ).toBe( 'string' );
} );

it( 'should export the correct file name', () => {
expect( AGENTS_MD_FILE_NAME ).toBe( 'AGENTS.md' );
} );

describe( 'version control section', () => {
it( 'should include the version control heading', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '## Version Control' );
} );

it( 'should include git init instructions', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( 'git init' );
expect( AGENTS_MD_TEMPLATE ).toContain( 'git add -A' );
} );

it( 'should include checkpoint workflow', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( 'Pre-modification checkpoint' );
} );

it( 'should include revert instructions', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( 'git checkout .' );
expect( AGENTS_MD_TEMPLATE ).toContain( 'git revert HEAD' );
} );

it( 'should include a recommended .gitignore', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '.gitignore' );
expect( AGENTS_MD_TEMPLATE ).toContain( '/wp-admin/' );
expect( AGENTS_MD_TEMPLATE ).toContain( '/wp-includes/' );
expect( AGENTS_MD_TEMPLATE ).toContain( 'wp-content/database/' );
} );
} );

describe( 'quality checks section', () => {
it( 'should include the quality checks heading', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '## Quality Checks' );
} );

it( 'should include PHP error checking', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( 'debug.log' );
} );

it( 'should include site health verification', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( 'studio wp option get siteurl' );
} );

it( 'should include site analysis commands', () => {
expect( AGENTS_MD_TEMPLATE ).toContain(
'studio wp theme list --status=active --format=json'
);
expect( AGENTS_MD_TEMPLATE ).toContain(
'studio wp plugin list --status=active --format=json'
);
expect( AGENTS_MD_TEMPLATE ).toContain( 'theme.json' );
} );
} );

describe( 'existing sections preserved', () => {
it( 'should still contain managing this site section', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '## Managing This Site' );
} );

it( 'should still contain development best practices', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '## WordPress Development Best Practices' );
} );

it( 'should still contain SQLite documentation', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '## Database: SQLite (not MySQL)' );
} );

it( 'should still contain studio-specific notes', () => {
expect( AGENTS_MD_TEMPLATE ).toContain( '## Studio-Specific Notes' );
} );

it( 'should still use studio wp instead of bare wp', () => {
expect( AGENTS_MD_TEMPLATE ).toContain(
'Always use `studio wp` instead of a standalone `wp` binary'
);
} );
} );
} );