Development Runbook
Common tasks and commands for WP Kernel development.
📖 For release workflow and changesets, see
RELEASING.md
in project root.
For PR flow and sprint process, see Pull Requests.
WordPress Environment
Start WordPress
# Start with seed data (recommended)
pnpm wp:fresh
# Or start without seed
pnpm wp:start
Stop WordPress
pnpm wp:stop
Restart WordPress
pnpm wp:stop && pnpm wp:start
Reset WordPress (Clean Slate)
# Destroy all data and start fresh
pnpm wp:destroy
pnpm wp:fresh
Access WordPress
- Development: http://localhost:8888
- Admin: http://localhost:8888/wp-admin
- Testing: http://localhost:8889
- Credentials:
admin
/password
Seed Data Management
Seed All Fixtures
pnpm wp:seed
Seeds:
- Test users (admin, editor, author, contributor, subscriber)
- Sample applications (pending, approved, rejected)
- Sample jobs (completed, in-progress, failed)
Reset Seed Data
pnpm wp:seed:reset
This deletes existing seed data before re-seeding.
Manual Seeding
# Seed only users
pnpm wp:cli user create editor editor@example.com --role=editor
# Seed custom data
pnpm wp:cli post create --post_type=application --post_title="Test Application"
Building Packages
Watch Mode (Development)
pnpm dev
Watches all packages and rebuilds on file changes.
Production Build
pnpm build
Builds all packages once for production.
Build Specific Package
# Build only kernel package
pnpm --filter @wpkernel/core build
# Build only UI package
pnpm --filter @wpkernel/ui build
Clean Build
# Remove all build artifacts
pnpm clean
# Rebuild from scratch
pnpm build
Running Tests
Unit Tests
# Run once
pnpm test
# Watch mode
pnpm test --watch
# With coverage
pnpm test:coverage
# Specific file
pnpm test packages/core/src/__tests__/index.test.ts
E2E Tests
Important: WordPress must be running first!
# Start WordPress
pnpm wp:start
# Run E2E tests (all browsers)
pnpm e2e
# Chromium only (faster)
pnpm e2e --project=chromium
# Headed mode (see browser)
pnpm e2e --headed
# Debug mode (step through)
pnpm e2e --debug
# Specific test
pnpm e2e packages/e2e-utils/tests/sanity.spec.ts
All Tests
# Run everything (unit + e2e)
pnpm test && pnpm e2e
Linting & Formatting
Check Lint
pnpm lint
Auto-Fix Lint Issues
pnpm lint:fix
Format Code
# Auto-format all files
pnpm format
# Check formatting only
pnpm format:check
Type Checking
Check Types
pnpm typecheck
Generate Types from Schema
# Generate TypeScript types from JSON Schema
pnpm types:generate
(This command will be added when JSON Schema types are implemented)
WP-CLI Commands
Run WP-CLI
# General format
pnpm wp:cli <command>
# Examples:
pnpm wp:cli plugin list
pnpm wp:cli option get siteurl
pnpm wp:cli post list --post_type=page
View WordPress Logs
pnpm wp:logs
Access Database
# Start MySQL shell
pnpm wp:cli db cli
# Export database
pnpm wp:cli db export backup.sql
# Import database
pnpm wp:cli db import backup.sql
Plugin Management
# List plugins
pnpm wp:cli plugin list
# Activate plugin
pnpm wp:cli plugin activate geekist-showcase
# Deactivate plugin
pnpm wp:cli plugin deactivate geekist-showcase
Theme Management
# List themes
pnpm wp:cli theme list
# Activate theme
pnpm wp:cli theme activate twentytwentyfour
User Management
# List users
pnpm wp:cli user list
# Create user
pnpm wp:cli user create newuser newuser@example.com --role=editor
# Update user password
pnpm wp:cli user update admin --user_pass=newpassword
WordPress Playground
Launch Playground
pnpm playground
Launches WordPress in a WebAssembly environment (no Docker required).
Playground Use Cases
- Quick demos
- Testing without Docker
- CI/CD testing (lightweight)
- Sharing prototypes
Versioning
Update CHANGELOG for Sprint
Update CHANGELOG.md files in affected packages:
## 0.x.0 [Unreleased]
### Added
- Sprint 5: Bindings & Interactivity
### Fixed
- Bug fixes
### Changed
- Breaking changes (if any)
Bump types:
- minor (0.x.0) - Feature sprints (default)
- patch (0.x.1) - Alignment/polish sprints
- major (x.0.0) - Breaking changes (rare pre-1.0)
Direct commits to
main
(infra/docs only) do not trigger releases.
Git Workflows
Create Feature Branch
git checkout -b feature/my-feature
Commit Changes
git add .
git commit -m "feat(resources): add custom cache invalidation"
Update from Main
git checkout main
git pull origin main
git checkout feature/my-feature
git merge main
Clean Up Branches
# List local branches
git branch
# Delete merged branches
git branch -d feature/old-feature
# Delete remote branch
git push origin --delete feature/old-feature
Troubleshooting
Port 8888/8889 Already in Use
# Find what's using the port
lsof -i :8888
# Kill the process
kill -9 <PID>
# Or change ports in .wp-env.json
Docker Won't Start
# Restart Docker Desktop
# Then:
pnpm wp:destroy
pnpm wp:fresh
Build Errors
# Clean node_modules
rm -rf node_modules pnpm-lock.yaml
# Reinstall
pnpm install
# Rebuild
pnpm build
Test Failures
# Reset test database
pnpm wp:seed:reset
# Clear test artifacts
rm -rf test-results/
# Run tests again
pnpm test && pnpm e2e
Plugin Not Activating
# Check plugin status
pnpm wp:cli plugin list
# Activate manually
pnpm wp:cli plugin activate geekist-showcase
# Check for errors
pnpm wp:logs
Database Corruption
# Export current data (if needed)
pnpm wp:cli db export backup.sql
# Reset everything
pnpm wp:destroy
pnpm wp:fresh
# Import data (if needed)
pnpm wp:cli db import backup.sql
E2E Tests Hanging
# Kill hung processes
pkill -f playwright
# Restart WordPress
pnpm wp:stop && pnpm wp:start
# Run E2E again
pnpm e2e
Performance Profiling
Build Performance
# Time the build
time pnpm build
Test Performance
# Time unit tests
time pnpm test
# Time E2E tests
time pnpm e2e
WordPress Performance
# Check PHP memory usage
pnpm wp:cli option get WP_MEMORY_LIMIT
# Enable debug mode
pnpm wp:cli config set WP_DEBUG true --raw
pnpm wp:cli config set WP_DEBUG_LOG true --raw
CI/CD
Run CI Locally
# Set CI environment
export CI=true
# Run CI checks
pnpm lint && pnpm build && pnpm test && pnpm e2e
View CI Runs
# Install GitHub CLI
gh auth login
# View recent runs
gh run list --limit 5
# View specific run
gh run view <run-id>
# View logs
gh run view <run-id> --log
Debugging
Debug Unit Tests
# Run specific test
pnpm test -- --testNamePattern="should create thing"
# Debug in VS Code
# Add breakpoint, then F5
Debug E2E Tests
# Run in headed mode
pnpm e2e --headed
# Run in debug mode
pnpm e2e --debug
# Record trace
pnpm e2e --trace on
Debug WordPress
# Enable WordPress debug mode
pnpm wp:cli config set WP_DEBUG true --raw
pnpm wp:cli config set WP_DEBUG_LOG true --raw
pnpm wp:cli config set WP_DEBUG_DISPLAY false --raw
# View debug log
pnpm wp:logs
# Or tail the log
docker exec -it <container-id> tail -f /var/www/html/wp-content/debug.log
Deployment Modes
🚧 Roadmap: Sprints 10-13 • See Modes Guide for complete specification
WP Kernel supports three deployment modes: Dynamic WordPress, Headless, and Static Export. Each mode has specific build and deployment requirements.
Dynamic WordPress (Default)
Standard WordPress deployment with full runtime.
Build:
pnpm build
Deploy:
- Upload plugin/theme to WordPress
- Standard WordPress hosting
- No special configuration needed
Headless WordPress
🚧 Requires:
configure()
API • Sprint 12
WordPress as backend API, external frontend.
Configure API root:
#### Configure Reporter Transport
> **✓ Available**: Sprint 4.5 - Unified Reporting (shipped in v0.1.0)
```typescript
import { configure } from '@wpkernel/core';
configure({
reporter: {
transport: 'console', // or 'hooks', 'all', custom transport
level: 'debug',
},
});
**Build:**
```bash
# WordPress backend
pnpm build
# Frontend app (example: Next.js)
NEXT_PUBLIC_WP_URL=https://cms.example.com npm run build
Deploy:
- WordPress: Standard hosting with REST API enabled
- Frontend: Vercel, Netlify, or custom host
- Configure CORS if needed
CORS Setup (WordPress):
// In theme/plugin
add_action('rest_api_init', function () {
remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
add_filter('rest_pre_serve_request', function ($value) {
header('Access-Control-Allow-Origin: https://your-frontend.com');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, Content-Type, X-WP-Nonce');
return $value;
});
});
Static Export (CDN)
🚧 Requires:
defineKernelConfig()
API, build guards • Sprints 12-13
Pre-rendered HTML for CDN deployment.
Configure for static:
// wpk.config.ts
export default defineKernelConfig({
project: {
supports: {
wp: true,
headless: false,
static: true,
},
},
build: {
staticEnvVar: 'STATIC',
},
});
Build:
# Build with static mode enabled
STATIC=1 pnpm build
# Generate static pages
STATIC=1 node build/generate-static.ts
Verify build:
# Check for forbidden REST calls in front-end bundles
grep -r "apiFetch" dist/public/
# Should return no results
Deploy:
- Upload
dist/
to CDN (Cloudflare, Fastly, AWS CloudFront) - Configure cache headers
- Set up redirects/rewrites
Cloudflare Pages example:
# Install Wrangler CLI
npm install -g wrangler
# Deploy
wrangler pages deploy dist/ \
--project-name=my-site \
--branch=main
Build Verification
Before deployment, verify mode constraints:
# Check bundle sizes
ls -lh dist/*.js
# Verify externals (should not bundle WordPress packages)
grep -r "@wordpress" dist/
# Should be imports, not bundled code
# Check for violations (static mode)
if grep -r "apiFetch\|kernel.fetch" dist/public/ ; then
echo "✗ Static mode violation detected"
exit 1
fi
# Test in target environment
pnpm e2e --config=playwright.static.config.ts
Environment Variables
Set these for different modes:
Dynamic WordPress:
# .env
NODE_ENV=production
WP_ENV=production
Headless:
# .env (frontend)
NEXT_PUBLIC_WP_URL=https://cms.example.com
WP_NONCE=<runtime-nonce>
# .env (WordPress)
ALLOW_ORIGIN=https://app.example.com
Static:
# .env
STATIC=1
WP_API_ROOT=http://localhost:8888 # For build-time fetching
OUTPUT_DIR=dist/static
Common Snippets
Add New Resource
# 1. Create resource definition
touch packages/showcase-plugin/app/resources/MyResource.ts
# 2. Create schema
touch packages/showcase-plugin/contracts/my-resource.schema.json
# 3. Generate types
pnpm types:generate
# 4. Create REST controller
touch packages/showcase-plugin/includes/rest/class-my-resource-controller.php
Add New Action
# 1. Create action directory
mkdir -p packages/showcase-plugin/app/actions/MyResource
# 2. Create action
touch packages/showcase-plugin/app/actions/MyResource/Create.ts
# 3. Write tests
touch packages/showcase-plugin/app/__tests__/actions/MyResource/Create.test.ts
Add New E2E Test
# 1. Create test file
touch packages/e2e-utils/tests/my-feature.spec.ts
# 2. Run the test
pnpm e2e packages/e2e-utils/tests/my-feature.spec.ts
Next Steps
- Coding Standards - Style guide
- Testing - Unit testing guide
- E2E Testing - E2E testing guide
- Pull Requests - PR process
- Modes Guide - Deployment modes deep dive