-
Notifications
You must be signed in to change notification settings - Fork 0
Development
This guide covers setting up a local development environment, running the build system, and contributing to Pressocampus.
- PHP 8.3+
- Composer
- MySQL 8.0+ or MariaDB 10.5+
- A local WordPress install (wp-env, LocalWP, DDEV, or similar)
- Node.js (only needed for the release build step that compresses assets)
- WP-CLI
# Clone the repo
git clone https://github.com/RegionallyFamous/pressocampus.git
cd pressocampus
# Install PHP dependencies
composer install
# Verify the build tools are working
make checkpressocampus/
├── pressocampus.php Main plugin file, constants, autoloader
├── uninstall.php Cleanup on plugin deletion
├── includes/
│ ├── class-plugin.php Central singleton, wires everything together
│ ├── class-installer.php Activation, deactivation, DB migrations
│ ├── class-cpt.php Custom post types and taxonomies
│ ├── class-soul.php Soul and Index management
│ ├── class-mcp-endpoint.php MCP JSON-RPC dispatcher + 8 tools
│ ├── class-auth.php OAuth token validation
│ ├── class-oauth-server.php OAuth 2.1 endpoints (league/oauth2-server)
│ ├── class-resource-index.php DB index table, search, dedup
│ ├── class-cache.php Object cache wrapper + rate limiting
│ ├── class-audit-log.php Activity logging
│ ├── class-discovery.php /.well-known endpoints
│ ├── class-settings.php WordPress admin UI
│ ├── class-onboarding.php First-run experience + admin notices
│ └── oauth/
│ ├── class-wp-client-repository.php
│ ├── class-wp-access-token-repository.php
│ ├── class-wp-auth-code-repository.php
│ ├── class-wp-refresh-token-repository.php
│ ├── class-wp-scope-repository.php
│ ├── class-psr7-bridge.php WP → PSR-7 adapter
│ └── class-user-entity.php
├── bin/
│ ├── wp-cli.php WP-CLI command definitions
│ ├── build.sh Distribution zip builder
│ └── install-wp-tests.sh PHPUnit WordPress test suite installer
├── tests/
│ ├── bootstrap.php PHPUnit bootstrap
│ ├── class-testcase.php Custom base class (bypasses WP_UnitTestCase for PHPUnit 12 compat)
│ └── MCPDispatcherTest.php Integration tests
├── languages/ Translation strings
├── .phpcs.xml PHPCS configuration
├── phpstan.neon PHPStan configuration
├── phpstan-baseline.neon PHPStan baseline (pre-existing issues)
├── phpunit.xml PHPUnit configuration
├── Makefile Development task runner
├── composer.json Dependencies and scripts
└── .github/workflows/ci.yml GitHub Actions CI
| Target | Description |
|---|---|
make install |
Install Composer dependencies |
make install-tests |
Set up WordPress test suite (requires DB config) |
make test |
Run PHPUnit tests |
make test-coverage |
Run tests with code coverage report |
make lint |
Check coding standards with PHPCS |
make lint-fix |
Auto-fix coding standards with PHPCBF |
make analyse |
Run PHPStan static analysis |
make check |
Full CI check: lint + analyse + test |
make build |
Build distributable plugin zip |
make clean |
Remove build artifacts |
The same tasks are available via Composer:
composer test # PHPUnit
composer lint # PHPCS
composer lint:fix # PHPCBF
composer analyse # PHPStan
composer check # lint + analyse + test
composer build # build zipThe test suite requires a dedicated MySQL database and a downloaded copy of WordPress core.
# Set up with default local MySQL (no password)
bash bin/install-wp-tests.sh wordpress_test root '' localhost latest
# Set up with a password
bash bin/install-wp-tests.sh wordpress_test root 'mypassword' localhost latest
# Or use the Makefile target (set env vars first)
export DB_NAME=wordpress_test DB_USER=root DB_PASS='' DB_HOST=localhost
make install-tests# Run all tests
make test
# Run with verbose output
vendor/bin/phpunit --testdox
# Run a specific test
vendor/bin/phpunit --filter test_remember_creates_memory
# Run with coverage (requires Xdebug or PCOV)
make test-coverageTests live in tests/MCPDispatcherTest.php and cover:
- MCP
initializehandshake - All 8 MCP tools (success and error cases)
- Rate limiting behavior
- Soul protection (can't be forgotten)
- ETag conflict detection
- Per-user data isolation
Pressocampus follows the WordPress Coding Standards.
# Check
make lint
# Auto-fix
make lint-fixConfiguration is in .phpcs.xml. Notable exceptions from the default WordPress rules:
- Yoda conditions — disabled (PHP 8.3 strict types make this unnecessary)
- Short ternary — allowed (PHP 8.3+)
-
Multiple classes per file — allowed in
class-psr7-bridge.phpand OAuth repositories (by design)
make analyseRunning at level 6 against all plugin PHP files. A phpstan-baseline.neon captures pre-existing issues in the initial build — all new code must be clean.
To regenerate the baseline after fixing issues:
vendor/bin/phpstan analyse --generate-baselineEvery push and pull request runs the full pipeline via GitHub Actions (.github/workflows/ci.yml):
- Lint — PHPCS on PHP 8.3
- Analyse — PHPStan on PHP 8.3
-
Test — PHPUnit matrix:
- PHP 8.3 + WordPress latest
- PHP 8.4 + WordPress latest
- PHP 8.3 + WordPress 6.7
-
Build — creates distributable zip on merge to
main
make buildThis runs bin/build.sh which:
- Runs
composer install --no-dev --optimize-autoloader - Copies only production files (per
.buildignore) - Creates
build/pressocampus-{version}.zip
The version is read from the Version: header in pressocampus.php.
Open a GitHub Issue with:
- WordPress version
- PHP version
- Steps to reproduce
- Expected vs actual behavior
- Relevant error messages or logs
- Fork the repo
- Create a branch:
git checkout -b feature/my-feature - Make your changes
- Ensure
make checkpasses - Open a pull request against
main
Follow Conventional Commits:
feat: add TTL controls to remember tool
fix: prevent duplicate soul creation on concurrent initialize
docs: add troubleshooting section for CORS errors
refactor: extract rate limiter into its own class
test: add coverage for ETag conflict scenario
- Add the tool definition to the
tools_list()method inclass-mcp-endpoint.php - Add the dispatch case in
dispatch_tool() - Implement the handler method following the
tool_remember()pattern - Write tests in
tests/MCPDispatcherTest.php - Document the tool in
docs/mcp-tools-reference.md
Schema changes go in class-installer.php in run_migrations(). Use dbDelta() for table changes. Increment PRESSOCAMPUS_DB_VERSION in pressocampus.php.
Pressocampus uses MySQL advisory locks (GET_LOCK / RELEASE_LOCK) for operations that must not run concurrently across PHP-FPM workers:
| Lock name | Held by | Purpose |
|---|---|---|
pc_soul_{user_id} |
Soul::create() |
Prevents duplicate soul post creation under concurrent initialize requests |
pc_rebuild_{user_id} |
ResourceIndex::rebuild_if_dirty() |
Prevents two workers from rebuilding the memory index simultaneously |
Both locks use timeout=0 (return immediately if already held) rather than blocking. The caller either proceeds or returns a retryable error / skips the rebuild gracefully.
Advisory locks are connection-scoped: if the PHP process dies mid-operation, MySQL releases the lock automatically, so there is no risk of a permanently stuck lock.
Do not use get_transient / set_transient pairs as mutexes — there is a race window between the read and the write. Use GET_LOCK for cross-process critical sections.
The full request/response cycle is logged to the PHP error log when WP_DEBUG is enabled. Set in wp-config.php:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);# Deactivate and reactivate (runs migrations fresh)
wp plugin deactivate pressocampus && wp plugin activate pressocampus
# Flush rewrite rules if endpoints return 404
wp rewrite flushUse curl to simulate the MCP initialize call:
# First, get a token (requires completing OAuth flow)
TOKEN="your-access-token"
# Initialize
curl -X POST https://localhost/brain \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-11-25","clientInfo":{"name":"test","version":"1.0"},"capabilities":{}},"id":1}'Getting started
Reference
Developer