Skip to content
Open
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
60 changes: 60 additions & 0 deletions apps/cli/ai/slash-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,73 @@ export const AI_CHAT_LOGOUT_COMMAND = '/logout';
export const AI_CHAT_MODEL_COMMAND = '/model';
export const AI_CHAT_PROVIDER_COMMAND = '/provider';
export const AI_CHAT_EXIT_COMMAND = '/exit';
export const AI_CHAT_CLASSIC_TO_BLOCKS_COMMAND = '/classic-to-blocks';

export const AI_CHAT_SLASH_COMMANDS: SlashCommandDef[] = [
{ name: 'browser', description: 'Open the active site in the browser' },
{ name: 'api-key', description: 'Set or update the Anthropic API key' },
{ name: 'classic-to-blocks', description: 'Convert the active classic theme to a block theme' },
{ name: 'login', description: 'Log in to WordPress.com' },
{ name: 'logout', description: 'Log out of WordPress.com' },
{ name: 'model', description: 'Switch the AI model' },
{ name: 'provider', description: 'Switch the AI provider' },
{ name: 'exit', description: 'Exit the chat' },
];

export const CLASSIC_TO_BLOCKS_PROMPT = `Convert the active site's current classic PHP theme into a fully functional WordPress block theme. Follow these steps precisely:

## Step 1: Capture the current design

Before making ANY changes, capture visual reference of the classic theme:
1. Use site_info to get the site URL.
2. Use take_screenshot on the site's homepage (desktop and mobile).
3. Take screenshots of other key pages if they exist (check with wp_cli: \`post list --post_type=page --post_status=publish --fields=ID,post_title,post_name\`).
4. Save these screenshots mentally as the "target" — the block theme MUST look identical.

## Step 2: Analyze the classic theme

Read and understand the entire classic theme structure:
1. List all theme files with Glob (*.php, *.css, *.js in the theme directory).
2. Read every PHP template file: index.php, header.php, footer.php, sidebar.php, single.php, page.php, archive.php, functions.php, and any custom templates.
3. Read style.css fully — every CSS rule matters.
4. Read any JS files.
5. Identify: the header structure, navigation menus, footer structure, sidebars/widgets, custom post type templates, template hierarchy usage, enqueued styles/scripts, custom functions, theme supports, and customizer settings.

## Step 3: Create the block theme

Create a NEW block theme (do not modify the classic theme in place). Name it with "-blocks" appended (e.g., "flavor-blocks" for "flavor"):

### Required files:
- **style.css**: Theme header + ALL the original CSS rules, adapted for block markup. Selectors may need updating since block themes use different markup (e.g., \`.wp-block-navigation\` instead of custom menu markup).
- **theme.json**: Define colors, typography, spacing, and layout settings matching the classic theme's design. Use the original fonts, colors, and sizes.
- **functions.php**: Enqueue styles, register block patterns, add theme supports. Keep any custom functionality from the original.
- **templates/index.html**: Main template using blocks.
- **templates/page.html**: Page template.
- **templates/single.html**: Single post template.
- **templates/archive.html**: Archive/category template.
- **templates/404.html**: 404 page.
- **templates/front-page.html**: If the original has a custom front page.
- **parts/header.html**: Header template part — must match the original header exactly (logo, navigation, any top bars).
- **parts/footer.html**: Footer template part — must match the original footer exactly.

### Conversion rules:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you find this useful? I wonder if the LLM is capable of figuring these by itself?

- PHP template tags → block equivalents: \`the_title()\` → \`core/post-title\`, \`the_content()\` → \`core/post-content\`, \`the_excerpt()\` → \`core/post-excerpt\`, \`wp_nav_menu()\` → \`core/navigation\`, \`get_header()\`/\`get_footer()\` → template parts, \`the_post_thumbnail()\` → \`core/post-featured-image\`, \`get_search_form()\` → \`core/search\`, \`dynamic_sidebar()\` → relevant blocks, loops → \`core/query\` + \`core/post-template\`.
- Custom PHP logic → block patterns or custom blocks where necessary.
- Preserve ALL visual styling — every color, font, spacing, border, shadow, hover effect.
- Preserve responsive behavior.

## Step 4: Activate and validate

1. Activate the new block theme: \`wp_cli theme activate <new-theme-slug>\`.
2. Use take_screenshot on every page you captured in Step 1.
3. Compare side by side with the original screenshots. Fix ANY visual differences:
- Header layout and navigation
- Typography (fonts, sizes, weights, line heights)
- Colors (backgrounds, text, links, accents)
- Spacing (margins, padding)
- Footer layout
- Responsive behavior (check mobile too)
4. Run validate_blocks on all template files to ensure block validity.
5. Iterate until the block theme is visually indistinguishable from the classic theme.

IMPORTANT: The goal is VISUAL PARITY. The block theme must look exactly like the classic theme. Do not "improve" or "modernize" the design — reproduce it faithfully.`;
12 changes: 12 additions & 0 deletions apps/cli/commands/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import { AI_PROVIDERS, type AiProviderId } from 'cli/ai/providers';
import {
AI_CHAT_API_KEY_COMMAND,
AI_CHAT_BROWSER_COMMAND,
AI_CHAT_CLASSIC_TO_BLOCKS_COMMAND,
AI_CHAT_EXIT_COMMAND,
AI_CHAT_LOGIN_COMMAND,
AI_CHAT_LOGOUT_COMMAND,
AI_CHAT_MODEL_COMMAND,
AI_CHAT_PROVIDER_COMMAND,
CLASSIC_TO_BLOCKS_PROMPT,
} from 'cli/ai/slash-commands';
import { AiChatUI } from 'cli/ai/ui';
import { runCommand as runLoginCommand } from 'cli/commands/auth/login';
Expand Down Expand Up @@ -211,6 +213,16 @@ export async function runCommand(): Promise< void > {
continue;
}

if ( trimmedPrompt === AI_CHAT_CLASSIC_TO_BLOCKS_COMMAND ) {
if ( ! ui.activeSite ) {
ui.showInfo( 'No site selected. Use ↓ to select a site with a classic theme first.' );
continue;
}
ui.addUserMessage( '/classic-to-blocks' );
await runAgentTurn( CLASSIC_TO_BLOCKS_PROMPT );
continue;
}

if ( trimmedPrompt === AI_CHAT_LOGIN_COMMAND ) {
ui.stop();
await runLoginCommand();
Expand Down
Loading