Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2f07699
remove php-wasm from Studio
bcotrim Dec 17, 2025
76ebd94
remove php-wasm and wp-playground code from Studio
bcotrim Dec 18, 2025
9444ed3
move PHP-WASM packages to devDependencies
bcotrim Dec 18, 2025
49d15d5
remove unnecessary PHP-WASM ignore patterns from forge config
bcotrim Dec 18, 2025
07bc3c9
remove PHP-WASM references from Jest config
bcotrim Dec 18, 2025
68552af
update documentation for PHP-WASM removal
bcotrim Dec 18, 2025
f00dea0
merge trunk, keep PHP-WASM removal
bcotrim Dec 18, 2025
92ffd24
remove outdated playground-cli-workflow design doc
bcotrim Dec 18, 2025
e21e57a
trigger ci e2e
bcotrim Dec 18, 2025
270ab29
merge dev/studio-cli-i2, keep PHP-WASM removal
bcotrim Jan 7, 2026
faf7407
replace unzipper with yauzl for zip extraction
bcotrim Jan 7, 2026
fa9ce7b
fix lint and unit tests
bcotrim Jan 7, 2026
ae79eee
Consolidate studio site set-* commands into single command (#2355)
bcotrim Jan 7, 2026
47dce34
Studio CLI: Add support for xdebug beta flag (#2316)
bcotrim Jan 8, 2026
141f102
CLI: Update `studio-cli.bat` so we can read from stdin (#2304)
fredrikekelund Jan 8, 2026
43f08cf
Merge remote-tracking branch 'origin/dev/studio-cli-i2' into stu-960-…
bcotrim Jan 15, 2026
eb23db8
Fix lint issues after merge with dev/studio-cli-i2
bcotrim Jan 15, 2026
cfaa5d8
Fix DEFAULT_WORDPRESS_VERSION reference in edit-site-details
bcotrim Jan 15, 2026
f2ea007
fix unit tests
bcotrim Jan 15, 2026
d9d3db6
Merge trunk into stu-960-remove-php-wasm-from-studio
bcotrim Jan 16, 2026
3629839
pr feedback
bcotrim Jan 16, 2026
78015d0
`--studio-no-path` to appease TS
fredrikekelund Jan 16, 2026
7111f6a
Merge branch 'trunk' into stu-960-remove-php-wasm-from-studio
bcotrim Jan 16, 2026
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
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ vendor/*
/fastlane/report.xml
/fastlane/README.md

# Include the vendored copy of wp-now in our repo
!vendor/wp-now

# CLI npm artifacts
cli/vendor/

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Blueprint } from '@wp-playground/blueprints';
import { RunCLIArgs } from '@wp-playground/cli';
import type { RunCLIArgs } from '@wp-playground/cli';
import type { Blueprint } from 'common/types/blueprint';

/**
* Sanitizes a Blueprint step to remove sensitive data while keeping useful debugging info.
Expand Down
2 changes: 1 addition & 1 deletion cli/wordpress-server-child.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import {
OverlayFilesystem,
InMemoryFilesystem,
} from '@wp-playground/storage';
import { sanitizeRunCLIArgs } from 'common/lib/cli-args-sanitizer';
import { isWordPressDirectory } from 'common/lib/fs-utils';
import { getMuPlugins } from 'common/lib/mu-plugins';
import { formatPlaygroundCliMessage } from 'common/lib/playground-cli-messages';
import { sequential } from 'common/lib/sequential';
import { isWordPressDevVersion } from 'common/lib/wordpress-version-utils';
import { z } from 'zod';
import { sanitizeRunCLIArgs } from 'cli/lib/cli-args-sanitizer';
import { getSqliteCommandPath, getWpCliPharPath } from 'cli/lib/server-files';
import {
ServerConfig,
Expand Down
5 changes: 3 additions & 2 deletions common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RecommendedPHPVersion } from '@wp-playground/common';
import { RecommendedPHPVersion } from './types/php-versions';

// Time constants
export const HOUR_MS = 1000 * 60 * 60;
Expand Down Expand Up @@ -27,7 +27,8 @@ export const PLAYGROUND_CLI_ACTIVITY_CHECK_INTERVAL = 5 * 1000; // Check for ina
// Custom domains
export const DEFAULT_CUSTOM_DOMAIN_SUFFIX = '.wp.local';

// WordPress Playground constants
// WordPress constants
export const MINIMUM_WORDPRESS_VERSION = '6.2.1' as const; // https://wordpress.github.io/wordpress-playground/blueprints/examples/#load-an-older-wordpress-version
export const DEFAULT_WORDPRESS_VERSION = 'latest' as const;
export const DEFAULT_PHP_VERSION: typeof RecommendedPHPVersion = RecommendedPHPVersion;
export const SQLITE_FILENAME = 'sqlite-database-integration' as const;
66 changes: 66 additions & 0 deletions common/lib/extract-zip.ts
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use this function in scripts/download-node-binary.mjs, too?

In the future, we might consider also targeting src/lib/import-export/import/handlers/backup-handler-zip.ts, but that's for another PR.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import path from 'path';
import { promisify } from 'util';
import fs from 'fs-extra';
import yauzl from 'yauzl';

const openZip = promisify< string, yauzl.Options, yauzl.ZipFile >( yauzl.open );

export async function extractZip( zipPath: string, destinationFolder: string ): Promise< void > {
const zipFile = await openZip( zipPath, { lazyEntries: true } );
const openReadStream = promisify( zipFile.openReadStream.bind( zipFile ) );
const resolvedDestination = path.resolve( destinationFolder );

return new Promise( ( resolve, reject ) => {
zipFile.on( 'entry', async ( entry: yauzl.Entry ) => {
if ( entry.fileName.endsWith( '/' ) ) {
zipFile.readEntry();
return;
}

const normalizedPath = path.normalize( entry.fileName );
const fullPath = path.join( resolvedDestination, normalizedPath );

if ( ! fullPath.startsWith( resolvedDestination + path.sep ) ) {
console.warn( `Skipping invalid path: ${ entry.fileName }` );
zipFile.readEntry();
return;
}

try {
await fs.ensureDir( path.dirname( fullPath ) );

const readStream = await openReadStream( entry );
const writeStream = fs.createWriteStream( fullPath );

function onError( error: Error ) {
if ( ! readStream.destroyed ) {
readStream.destroy();
}
if ( ! writeStream.destroyed ) {
writeStream.destroy();
}
reject( error );
}

readStream.once( 'error', onError );
writeStream.once( 'error', onError );

writeStream.once( 'finish', () => {
zipFile.readEntry();
} );

readStream.pipe( writeStream );
} catch ( error ) {
reject( error );
}
} );

zipFile.on( 'end', () => {
resolve();
} );

zipFile.on( 'error', reject );

zipFile.readEntry();
} );
}
1 change: 1 addition & 0 deletions common/types/blueprint.ts
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't we import these directly from @wp-playground/blueprints?

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { Blueprint, BlueprintV1Declaration, StepDefinition } from '@wp-playground/blueprints';
29 changes: 29 additions & 0 deletions common/types/php-versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Local type definitions for PHP versions.
* These replace imports from @php-wasm/universal to avoid bundling PHP-WASM in the desktop app.
*
* Note: Keep these values in sync with @php-wasm/universal if the upstream package changes.
*/

export const SupportedPHPVersions = [
'8.4',
'8.3',
'8.2',
'8.1',
'8.0',
'7.4',
'7.3',
'7.2',
] as const;

export const LatestSupportedPHPVersion = '8.4' as const;

export const SupportedPHPVersionsList: string[] = [ ...SupportedPHPVersions ];

export type SupportedPHPVersion = ( typeof SupportedPHPVersions )[ number ];

/**
* The recommended PHP version for new sites.
* This replaces RecommendedPHPVersion from @wp-playground/common.
*/
export const RecommendedPHPVersion: SupportedPHPVersion = '8.3';
57 changes: 22 additions & 35 deletions docs/ai-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ See the site management commands (create, list, start, etc) in `cli/commands/sit

## WordPress Studio - Architecture Overview

WordPress Studio is a desktop application for creating, managing, and testing WordPress sites locally. It's built as an Electron desktop application with a React renderer, powered by WordPress Playground and PHP WASM.
WordPress Studio is a desktop application for creating, managing, and testing WordPress sites locally. It's built as an Electron desktop application with a React renderer. The CLI component uses WordPress Playground (PHP WASM) to run WordPress sites.

## High-Level Architecture

Expand All @@ -162,7 +162,6 @@ WordPress Studio is a desktop application for creating, managing, and testing Wo
├─────────────────────────────────────────────────────┤
│ • IPC Handler Layer (ipc-handlers.ts) │
│ • Site Server Management (site-server.ts) │
│ • WordPress Provider Abstraction │
│ • Storage & User Data Management │
│ • OAuth / Authentication │
│ • Sync Operations (WordPress.com / Pressable) │
Expand All @@ -175,11 +174,11 @@ WordPress Studio is a desktop application for creating, managing, and testing Wo
└────────────────┬─┘ └───────────────┘
┌──────────────────────▼──────────────────────┐
WORDPRESS PROVIDERS
STUDIO CLI
├──────────────────────────────────────────────┤
│ • Playground-CLI Provider (with Blueprints) │
│ • WP-Now Provider (fallback)
│ • PHP WASM Runtime
│ • WordPress Playground (@wp-playground/cli) │
│ • PHP WASM Runtime (@php-wasm/*)
│ • Blueprint Support
│ • Server Process Management │
└─────────────────────────────────────────────┘
```
Expand All @@ -198,12 +197,10 @@ WordPress Studio is a desktop application for creating, managing, and testing Wo
- **`storage/`** - User data persistence and app state storage
- **`stores/`** - Redux RTK stores (centralized state management)
- **`lib/`** - Utility libraries and business logic
- `wordpress-provider/` - Abstraction layer for WordPress runtime (Playground vs WP-Now)
- `import-export/` - Site backup/restore functionality
- `sync/` - WordPress.com sync operations
- `certificate-manager.ts` - HTTPS certificate generation for custom domains
- `proxy-server.ts` - Local HTTP proxy for custom domain routing
- `wp-cli-process.ts` - WP-CLI command execution wrapper
- **`components/`** - React UI components
- `root.tsx` - Root component with all context providers
- `app.tsx` - Main app layout
Expand Down Expand Up @@ -266,15 +263,11 @@ window.ipcApi.installStudioCli() // Install the CLI
window.ipcApi.uninstallStudioCli() // Uninstall the CLI
```

### 3. WordPress Provider Pattern (Strategy Pattern)
Two implementations for running WordPress:
- **PlaygroundCliProvider**: Uses `@wp-playground/cli` with Blueprint support (feature-gated)
- **WpNowProvider**: Fallback provider with core functionality

Both implement the `WordPressProvider` interface with methods:
- `startServer()` - Start a WordPress site
- `setupWordPressSite()` - Initialize WordPress installation
- `createServerProcess()` - Create server child process
### 3. CLI Server Process
The desktop app delegates WordPress operations to the CLI:
- **CliServerProcess** (`src/modules/cli/lib/cli-server-process.ts`): Spawns CLI as child process
- **Site operations**: Start/stop servers, run WP-CLI commands
- **Blueprint support**: Passed to CLI for site initialization

### 4. Redux Store Architecture (RTK)
```typescript
Expand All @@ -284,7 +277,6 @@ Both implement the `WordPressProvider` interface with methods:
- connectedSites: Connected WordPress.com sites
- snapshot: Site snapshots/backups
- onboarding: First-run experience state
- provider constants: WordPress/PHP versions
- RTK Query APIs for data fetching:
- wpcomApi: WordPress.com API calls
- installedAppsApi: System apps detection, CLI installation status
Expand Down Expand Up @@ -338,11 +330,12 @@ Redux State Update / Re-render

### Main Process
- **Electron 38** - Desktop framework
- **express** - Lightweight HTTP server for sites

### CLI (runs WordPress sites)
- **@wp-playground/cli** - WordPress Playground CLI
- **@php-wasm/node** - PHP runtime in Node.js
- **@php-wasm/universal** - Universal PHP WASM
- **@wp-playground/blueprints** - Blueprint compilation
- **@wp-playground/cli** - Playground CLI integration
- **express** - Lightweight HTTP server for sites

### Development
- **electron-vite** - Electron build orchestration
Expand Down Expand Up @@ -410,19 +403,13 @@ Storage is protected by file locking (`lockAppdata()` / `unlockAppdata()`).
- Renderer uses `<I18nProvider>` context
- CLI translates via `loadTranslations()` in CLI bootstrap

## WordPress Playground Integration

### Blueprints
- Complex site configurations declaratively defined
- Compiled to runtime executable by `@wp-playground/blueprints`
- Feature detection/filtering: `filterUnsupportedBlueprintFeatures()` in `src/lib/blueprint-features.ts`
- Passed to server startup for automatic setup
## WordPress Playground Integration (CLI)

### PHP WASM Runtime
- `@php-wasm/node` provides PHP runtime in Node.js
- Runs in child processes via `WorkerThreads`
- WP-CLI integration: `WpCliProcess` class wraps CLI commands
- Server process: Handles PHP execution and WordPress HTTP requests
The CLI component uses WordPress Playground to run WordPress sites:
- **@wp-playground/cli**: Runs WordPress in Node.js using PHP WASM
- **Blueprints**: Declarative site configurations passed to CLI for setup
- **Feature filtering**: `filterUnsupportedBlueprintFeatures()` removes unsupported steps
- The desktop app spawns the CLI as a child process via `CliServerProcess`

## Sync & WordPress.com Integration

Expand Down Expand Up @@ -474,12 +461,12 @@ Local component state used for temporary UI interactions.

- **Code Splitting**: Vendor and Sentry chunks extracted separately
- **CSS Code Split**: Separate CSS files for better caching
- **WASM Bundling**: WASM files included as external assets
- **CLI Separation**: PHP WASM (~1GB) only in CLI, not in desktop app bundle
- **Port Finder**: Efficient port availability checking with caching
- **Snapshot System**: Browser-like snapshots for fast site restoration

---

Last Updated: 2025-11-10
Last Updated: 2025-12-18
Repository: https://github.com/Automattic/studio
License: GPLv2 or later
Loading