diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..cef878a6e --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,14 @@ +{ + "description": "Claude Code settings for WordPress ActivityPub plugin development", + "skills": { + "allowedSkills": [ + "activitypub-dev-cycle", + "activitypub-php-conventions", + "activitypub-pr-workflow", + "activitypub-federation", + "activitypub-testing", + "activitypub-release", + "activitypub-integrations" + ] + } +} diff --git a/.claude/skills/activitypub-dev-cycle/SKILL.md b/.claude/skills/activitypub-dev-cycle/SKILL.md new file mode 100644 index 000000000..c7d50d679 --- /dev/null +++ b/.claude/skills/activitypub-dev-cycle/SKILL.md @@ -0,0 +1,139 @@ +--- +name: activitypub-dev-cycle +description: Development workflows for WordPress ActivityPub plugin including wp-env setup, testing commands, linting, and build processes. Use when setting up development environment, running tests, checking code quality, building assets, or working with wp-env. +--- + +# ActivityPub Development Cycle + +Quick reference for common development workflows in the WordPress ActivityPub plugin. + +## Quick Reference + +### Environment Management +```bash +npm run env-start # Start WordPress at http://localhost:8888. +npm run env-stop # Stop WordPress environment. +``` + +### Testing Commands +```bash +npm run env-test # Run all PHP tests. +npm run env-test -- --filter=pattern # Run tests matching pattern. +npm run env-test -- path/to/test.php # Run specific test file. +npm run env-test -- --group=name # Run tests with @group annotation. +npm run test:e2e # Run Playwright E2E tests. +npm run test:e2e:debug # Debug E2E tests. +``` + +### Code Quality +```bash +composer lint # Check PHP coding standards. +composer lint:fix # Auto-fix PHP issues. +npm run lint:js # Check JavaScript. +npm run lint:css # Check CSS styles. +npm run format # Format all code (wp-scripts). +``` + +### Building Assets +```bash +npm run build # Build for production (formatted and minified). +npm run dev # Start development watch mode. +``` + +### Code Coverage +```bash +npm run env-start -- --xdebug=coverage # Start with coverage support. +npm run env-test -- --coverage-text # Generate text coverage report. +npm run env-test -- --coverage-html ./coverage # Generate HTML report. +``` + +## Comprehensive Documentation + +See [Development Environment Setup](../../../docs/development-environment.md) for detailed setup instructions. + +See [Testing Reference](../../../tests/README.md) for comprehensive testing guidance. + +See [Code Linting](../../../docs/code-linting.md) for linting configuration and standards. + +## Pre-commit Hooks + +The repository uses automated pre-commit hooks (`.githooks/pre-commit`) that run automatically on `git commit`: + +1. **Sort PHP imports** - Automatically organizes use statements. +2. **Check unused imports** - Prevents unused use statements. +3. **Validate test patterns** - Blocks `remove_all_filters('pre_http_request')`. +4. **Run PHPCS auto-fix** - Applies coding standards automatically. +5. **Format JavaScript** - Runs wp-scripts formatter. + +**IMPORTANT:** Hooks modify staged files automatically. Always review changes before committing. If hooks make changes, you'll need to stage them and commit again. + +**Setup:** Hooks are installed by `npm run prepare` (runs automatically after `npm install`). + +## Common Development Workflows + +### Initial Setup +```bash +git clone git@github.com:Automattic/wordpress-activitypub.git +cd wordpress-activitypub +npm install # Also runs 'npm run prepare' to install hooks. +composer install +npm run env-start # WordPress at http://localhost:8888. +``` + +### Making Changes Workflow +```bash +# 1. Make code changes. + +# 2. Run relevant tests. +npm run env-test -- --filter=FeatureName + +# 3. Check code quality (optional - pre-commit hook does this). +composer lint +npm run lint:js + +# 4. Commit (pre-commit hook runs automatically). +git add . +git commit -m "Description" +# Hook may modify files - review and stage again if needed. +``` + +### Before Creating PR +```bash +# Run full test suite. +npm run env-test + +# Build assets. +npm run build + +# Final lint check. +composer lint +npm run lint:js +``` + +### Debugging Failing Tests +```bash +# Run with verbose output. +npm run env-test -- --verbose --filter=test_name + +# Run single test file to isolate issue. +npm run env-test -- tests/phpunit/tests/path/to/test.php + +# Check test groups. +npm run env-test -- --list-groups +npm run env-test -- --group=specific_group +``` + +### Fresh Environment +```bash +npm run env-stop +npm run env-start +# wp-env automatically sets up WordPress with debug mode and test users. +``` + +## Key Files + +- `package.json` - npm scripts and dependencies. +- `composer.json` - PHP dependencies and lint scripts. +- `.wp-env.json` - wp-env configuration. +- `phpcs.xml` - PHP coding standards (custom WordPress rules). +- `.githooks/pre-commit` - Pre-commit automation. diff --git a/.claude/skills/activitypub-federation/SKILL.md b/.claude/skills/activitypub-federation/SKILL.md new file mode 100644 index 000000000..ba94d854f --- /dev/null +++ b/.claude/skills/activitypub-federation/SKILL.md @@ -0,0 +1,316 @@ +--- +name: activitypub-federation +description: ActivityPub protocol specification and federation concepts. Use when working with ActivityPub activities, understanding federation mechanics, implementing protocol features, or debugging federation issues. +--- + +# ActivityPub Federation Protocol + +This skill provides understanding of the ActivityPub protocol specification and how federation works. + +**For supported features and compatibility:** See [FEDERATION.md](../../../FEDERATION.md) for the complete list of implemented FEPs, supported standards, and federation compatibility details. + +**For implementation details:** See [PHP Conventions](../activitypub-php-conventions/SKILL.md) for transformers, handlers, and PHP code patterns. + +## Core Concepts + +### Three Building Blocks + +1. **Actors** - Users/accounts in the system + - Each actor has a unique URI + - Required: `inbox`, `outbox` + - Optional: `followers`, `following`, `liked` + +2. **Activities** - Actions taken by actors + - Create, Update, Delete, Follow, Like, Announce, Undo + - Wrap objects to describe how they're shared + +3. **Objects** - Content being acted upon + - Notes, Articles, Images, Videos, etc. + - Can be embedded or referenced by URI + +### Actor Structure + +```json +{ + "@context": "https://www.w3.org/ns/activitystreams", + "type": "Person", + "id": "https://example.com/@alice", + "inbox": "https://example.com/@alice/inbox", + "outbox": "https://example.com/@alice/outbox", + "followers": "https://example.com/@alice/followers", + "following": "https://example.com/@alice/following", + "preferredUsername": "alice", + "name": "Alice Example", + "summary": "Bio text here" +} +``` + +## Collections + +### Standard Collections + +**Inbox** - Receives incoming activities +- De-duplicate by activity ID +- Filter based on permissions +- Process activities for side effects + +**Outbox** - Publishes actor's activities +- Public record of what actor has posted +- Filtered based on viewer permissions +- Used for profile activity displays + +**Followers** - Actors following this actor +- Updated when Follow activities are Accepted +- Used for delivery targeting + +**Following** - Actors this actor follows +- Tracks subscriptions +- Used for timeline building + +### Public Addressing + +Special collection: `https://www.w3.org/ns/activitystreams#Public` + +- Makes content publicly accessible +- **Do not deliver to this URI** - it's a marker, not a real inbox +- Used in `to`, `cc`, `bto`, `bcc` fields for visibility + +## Activity Types + +### Create +Wraps newly published content: +```json +{ + "type": "Create", + "actor": "https://example.com/@alice", + "object": { + "type": "Note", + "content": "Hello, Fediverse!" + } +} +``` + +### Follow +Initiates subscription: +```json +{ + "type": "Follow", + "actor": "https://example.com/@alice", + "object": "https://other.example/@bob" +} +``` +- Recipient should respond with Accept or Reject +- Only add to followers upon Accept + +### Like +Indicates appreciation: +```json +{ + "type": "Like", + "actor": "https://example.com/@alice", + "object": "https://other.example/@bob/post/123" +} +``` + +### Announce +Reshares/boosts content: +```json +{ + "type": "Announce", + "actor": "https://example.com/@alice", + "object": "https://other.example/@bob/post/123" +} +``` + +### Update +Modifies existing content: +- Supplied properties replace existing +- `null` values remove fields +- Must include original object ID + +### Delete +Removes content: +- May replace with Tombstone for referential integrity +- Should cascade to related activities + +### Undo +Reverses previous activities: +```json +{ + "type": "Undo", + "actor": "https://example.com/@alice", + "object": { + "type": "Follow", + "id": "https://example.com/@alice/follow/123" + } +} +``` + +## Server-to-Server Federation + +### Activity Delivery Process + +1. **Resolve Recipients** + - Check `to`, `bto`, `cc`, `bcc`, `audience` fields + - Dereference collections to find individual actors + - De-duplicate recipient list + - Exclude activity's own actor + +2. **Discover Inboxes** + - Fetch actor profiles + - Extract `inbox` property + - Use `sharedInbox` if available for efficiency + +3. **Deliver via HTTP POST** + - Content-Type: `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` + - Include HTTP Signatures for authentication + - Handle delivery failures gracefully + +### Inbox Forwarding + +**Ghost Replies Problem:** When Alice replies to Bob's post that Carol follows, Carol might not see the reply if she doesn't follow Alice. + +**Solution:** Inbox forwarding +- When receiving activity addressing a local collection +- If activity references local objects +- Forward to collection members +- Ensures conversation participants see replies + +### Shared Inbox Optimization + +For public posts with many recipients on same server: +- Use `sharedInbox` endpoint instead of individual inboxes +- Reduces number of HTTP requests +- Server distributes internally + +## Addressing and Visibility + +### To/CC Fields + +- `to` - Primary recipients (public in UI) +- `cc` - Secondary recipients (copied/mentioned) +- `bto` - Blind primary (hidden in delivery) +- `bcc` - Blind secondary (hidden in delivery) + +**Important:** Remove `bto` and `bcc` before delivery to preserve privacy + +### Visibility Patterns + +**Public Post:** +```json +{ + "to": ["https://www.w3.org/ns/activitystreams#Public"], + "cc": ["https://example.com/@alice/followers"] +} +``` + +**Followers-Only:** +```json +{ + "to": ["https://example.com/@alice/followers"] +} +``` + +**Direct Message:** +```json +{ + "to": ["https://other.example/@bob"], + "cc": [] +} +``` + +## Content Verification + +### Security Considerations + +1. **Verify Origins** + - Don't trust claimed sources without verification + - Check HTTP Signatures + - Validate actor owns referenced objects + +2. **Prevent Spoofing** + - Mallory could claim Alice posted something + - Always verify before processing side effects + +3. **Rate Limiting** + - Limit recursive dereferencing + - Protect against denial-of-service + - Implement spam filtering + +4. **Content Sanitization** + - Clean HTML before browser rendering + - Validate media types + - Check for malicious payloads + +## Protocol Extensions + +### Supported Standards + +See [FEDERATION.md](../../../FEDERATION.md) for the complete list of implemented standards and FEPs, including: +- WebFinger - Actor discovery. +- HTTP Signatures - Request authentication. +- NodeInfo - Server metadata. +- Various FEPs (Fediverse Enhancement Proposals). + +### FEPs (Fediverse Enhancement Proposals) + +FEPs extend ActivityPub with additional features. Common FEP categories include: +- Long-form text support. +- Quote posts. +- Activity intents. +- Follower synchronization. +- Actor metadata extensions. + +**For supported FEPs in this plugin:** See [FEDERATION.md](../../../FEDERATION.md) for the authoritative list of implemented FEPs. + +## Implementation Notes + +### WordPress Plugin Specifics + +This plugin implements: +- **Actor Types**: User, Blog, Application +- **Transformers**: Convert WordPress content to ActivityPub objects +- **Handlers**: Process incoming activities + +For implementation details, see: +- [PHP Conventions](../activitypub-php-conventions/SKILL.md) for code structure +- [Integration Guide](../activitypub-integrations/SKILL.md) for extending + +### Testing Federation + +```bash +# Test actor endpoint +curl -H "Accept: application/activity+json" \ + https://site.com/@username + +# Test WebFinger +curl https://site.com/.well-known/webfinger?resource=acct:user@site.com + +# Test NodeInfo +curl https://site.com/.well-known/nodeinfo +``` + +## Common Issues + +### Activities Not Received +- Check inbox URL is accessible +- Verify HTTP signature validation +- Ensure content-type headers correct +- Check for firewall/security blocks + +### Replies Not Federated +- Verify inbox forwarding enabled +- Check addressing includes relevant actors +- Ensure `inReplyTo` properly set + +### Follower Sync Issues +- Check Accept activities sent for Follow +- Verify followers collection updates +- Ensure shared inbox used when available + +## Resources + +- [ActivityPub Spec](https://www.w3.org/TR/activitypub/) +- [ActivityStreams Vocabulary](https://www.w3.org/TR/activitystreams-vocabulary/) +- [Project FEDERATION.md](../../../FEDERATION.md) +- [FEPs Repository](https://codeberg.org/fediverse/fep) \ No newline at end of file diff --git a/.claude/skills/activitypub-integrations/SKILL.md b/.claude/skills/activitypub-integrations/SKILL.md new file mode 100644 index 000000000..3f4465f50 --- /dev/null +++ b/.claude/skills/activitypub-integrations/SKILL.md @@ -0,0 +1,155 @@ +--- +name: activitypub-integrations +description: Third-party WordPress plugin integration patterns. Use when adding new integrations, debugging compatibility with other plugins, or working with existing integrations. +--- + +# ActivityPub Integrations + +This skill provides guidance on integrating the ActivityPub plugin with other WordPress plugins. + +## Quick Reference + +### Integration Location +All integrations live in the `integration/` directory. + +**File naming:** `class-{plugin-name}.php` (following [PHP conventions](../activitypub-php-conventions/SKILL.md)) + +### Available Integrations +- BuddyPress +- bbPress +- WooCommerce +- Jetpack +- The Events Calendar +- WP User Avatars +- And 13+ more + +For complete directory structure and naming conventions, see [PHP Class Structure](../../../docs/php-class-structure.md). + +## Creating New Integration + +### Basic Integration Class + +```php +ID, 'price', true ); + } + return $object; +}, 10, 2 ); +``` + +## Testing Integrations + +### Verify Integration Loading + +```php +// Check if integration is active. +if ( class_exists( '\Activitypub\Integration\Plugin_Name' ) ) { + // Integration loaded. +} +``` + +### Test Compatibility + +1. Install target plugin +2. Activate ActivityPub +3. Check for conflicts +4. Verify custom post types work +5. Test federation of plugin content + +## Common Integration Issues + +### Plugin Detection +```php +// Multiple detection methods. +if ( defined( 'PLUGIN_VERSION' ) ) { } +if ( function_exists( 'plugin_function' ) ) { } +if ( class_exists( 'Plugin_Class' ) ) { } +``` + +### Hook Priority +```php +// Use appropriate priority. +add_filter( 'hook', 'callback', 20 ); // After plugin's filter. +``` + +### Namespace Conflicts +```php +// Use fully qualified names. +$object = new \Plugin\Namespace\Class(); +``` + +## Existing Integrations + +### BuddyPress +- Adds BuddyPress activity support +- Custom member transformers +- Group activity federation + +### WooCommerce +- Product post type support +- Order activity notifications +- Customer review federation + +### bbPress +- Forum topic federation +- Reply activities +- User forum profiles + +## Best Practices + +1. **Always check if plugin is active** before adding hooks +2. **Use late priority** for filters to override plugin defaults +3. **Test with multiple plugin versions** +4. **Document compatibility requirements** +5. **Handle plugin deactivation gracefully** diff --git a/.claude/skills/activitypub-php-conventions/SKILL.md b/.claude/skills/activitypub-php-conventions/SKILL.md new file mode 100644 index 000000000..11c8af173 --- /dev/null +++ b/.claude/skills/activitypub-php-conventions/SKILL.md @@ -0,0 +1,212 @@ +--- +name: activitypub-php-conventions +description: PHP coding standards and WordPress patterns for ActivityPub plugin. Use when writing PHP code, creating classes, implementing WordPress hooks, or structuring plugin files. +--- + +# ActivityPub PHP Conventions + +Plugin-specific conventions and architectural patterns for the ActivityPub plugin. + +## Quick Reference + +### File Naming +``` +class-{name}.php # Regular classes. +trait-{name}.php # Traits. +interface-{name}.php # Interfaces. +``` + +### Namespace Pattern +```php +namespace Activitypub; +namespace Activitypub\Transformer; +namespace Activitypub\Collection; +namespace Activitypub\Handler; +namespace Activitypub\Activity; +namespace Activitypub\Rest; +``` + +### Text Domain +Always use `'activitypub'` for translations: +```php +\__( 'Text', 'activitypub' ); +\_e( 'Text', 'activitypub' ); +``` + +### WordPress Global Functions +When in a namespace, always escape WordPress functions with backslash: `\get_option()`, `\add_action()`, etc. + +## Comprehensive Standards + +See [PHP Coding Standards](../../../docs/php-coding-standards.md) for complete WordPress coding standards. + +See [PHP Class Structure](../../../docs/php-class-structure.md) for detailed directory organization. + +## Directory Structure + +``` +includes/ +├── class-*.php # Core classes. +├── activity/ # Activity type classes. +├── collection/ # Collection classes. +├── handler/ # Activity handlers. +├── rest/ # REST API endpoints. +├── transformer/ # Content transformers. +└── wp-admin/ # Admin functionality. + +integration/ # Third-party integrations (root level). +``` + +## ActivityPub Architectural Patterns + +### Transformers +Convert WordPress content into ActivityPub objects. + +**When to use:** Converting posts, comments, users, or custom content types into ActivityPub format. + +**Base class:** `includes/transformer/class-base.php` + +**Pattern:** +```php +namespace Activitypub\Transformer; + +class Custom extends Base { + /** + * Transform object to ActivityPub format. + * + * @return array The ActivityPub representation. + */ + public function transform() { + $object = parent::transform(); + // Custom transformation logic. + return $object; + } +} +``` + +**Examples:** +- `includes/transformer/class-post.php` - Post transformation. +- `includes/transformer/class-comment.php` - Comment transformation. +- `includes/transformer/class-event.php` - Event-specific transformation. + +### Handlers +Process incoming ActivityPub activities from remote servers. + +**When to use:** Processing incoming Follow, Like, Create, Delete, Update, etc. activities. + +**Pattern:** Each handler processes one activity type from the inbox. + +**Examples:** +- `includes/handler/class-follow.php` - Process Follow activities. +- `includes/handler/class-create.php` - Process Create activities. +- `includes/handler/class-delete.php` - Process Delete activities. +- `includes/handler/class-like.php` - Process Like activities. + +### Collections +Implement ActivityPub collections (Followers, Following, etc.). + +**When to use:** Exposing lists of actors, activities, or objects via ActivityPub. + +**Examples:** +- `includes/collection/class-followers.php` - Followers collection. +- `includes/collection/class-following.php` - Following collection. + +### REST API Controllers +Expose ActivityPub endpoints. + +**Namespace:** `ACTIVITYPUB_REST_NAMESPACE` + +**Examples:** +- `includes/rest/class-actors-controller.php` - Actor endpoint. +- `includes/rest/class-inbox-controller.php` - Inbox endpoint. +- `includes/rest/class-outbox-controller.php` - Outbox endpoint. +- `includes/rest/class-followers-controller.php` - Followers collection endpoint. + +## Plugin-Specific Helper Functions + +```php +// Get remote actor metadata. +$metadata = get_remote_metadata_by_actor( $actor_url ); + +// Convert ActivityPub object to URI string. +$uri = object_to_uri( $object ); + +// Enrich content with callbacks. +$content = enrich_content_data( $content, $pattern, $callback ); + +// Resolve WebFinger handle to actor URL. +$resource = Webfinger::resolve( $handle ); + +// Get user's ActivityPub actor URL. +$actor_url = get_author_posts_url( $user_id ); + +// Check if a post type is enabled for ActivityPub. +$enabled = \is_post_type_enabled( $post_type ); +``` + +## Real Codebase Examples + +**Core Classes:** +- `includes/class-activitypub.php` - Main plugin initialization. +- `includes/class-dispatcher.php` - Activity dispatching to followers. +- `includes/class-scheduler.php` - WP-Cron integration for async tasks. +- `includes/class-signature.php` - HTTP Signatures for federation. + +**Activity Types:** +- `includes/activity/class-activity.php` - Base activity class. +- `includes/activity/class-follow.php` - Follow activity. +- `includes/activity/class-undo.php` - Undo activity. + +**Integrations (see [Integration Patterns](../activitypub-integrations/SKILL.md)):** +- `integration/class-woocommerce.php` - WooCommerce integration. +- `integration/class-buddypress.php` - BuddyPress integration. +- `integration/class-jetpack.php` - Jetpack integration. + +## Common Initialization Patterns + +### Static Initialization +```php +class Feature { + /** + * Initialize the class. + */ + public static function init() { + \add_action( 'init', array( self::class, 'register' ) ); + \add_filter( 'activitypub_activity_object', array( self::class, 'filter' ) ); + } +} +``` + +### Singleton Pattern +```php +class Manager { + private static $instance = null; + + public static function get_instance() { + if ( null === self::$instance ) { + self::$instance = new self(); + } + return self::$instance; + } + + private function __construct() { + $this->init(); + } +} +``` + +## Custom Hook Patterns + +**Actions:** +```php +\do_action( 'activitypub_before_send_activity', $activity ); +\do_action( 'activitypub_after_send_activity', $activity, $response ); +\do_action( 'activitypub_inbox_received', $activity ); +``` + +**Filters:** +```php +$activity = \apply_filters( 'activitypub_activity_object', $activity, $post ); +$content = \apply_filters( 'activitypub_the_content', $content, $post ); +$actor = \apply_filters( 'activitypub_actor_data', $actor, $user_id ); +``` diff --git a/.claude/skills/activitypub-pr-workflow/SKILL.md b/.claude/skills/activitypub-pr-workflow/SKILL.md new file mode 100644 index 000000000..1aa1089f1 --- /dev/null +++ b/.claude/skills/activitypub-pr-workflow/SKILL.md @@ -0,0 +1,239 @@ +--- +name: activitypub-pr-workflow +description: Pull request creation and review workflow for WordPress ActivityPub plugin. Use when creating branches, managing PRs, adding changelogs, assigning reviewers, or following branch naming conventions. +--- + +# ActivityPub PR Workflow + +Workflow guidance for creating and managing pull requests in the WordPress ActivityPub plugin repository. + +## Quick Reference + +### Branch Naming +```bash +add/{feature} # New features. +update/{feature} # Iterating on existing features. +fix/{bug} # Bug fixes. +try/{idea} # Experimental ideas. +``` + +**Reserved branches:** +- `release/{X.Y.Z}` - Release process only. +- `trunk` - Main development branch. + +### PR Requirements +- ✅ Changelog entry (or "Skip Changelog" label). +- ✅ Passing CI checks. +- ✅ Clean merge with trunk. +- ✅ **Always assign @me**. +- ✅ **Always add Fediverse team as reviewer**. +- ✅ Proper branch naming. + +### Quick Commands +```bash +# Create and switch to branch. +git checkout -b add/new-feature + +# Create PR with GitHub CLI. +gh pr create --assignee @me --reviewer Fediverse + +# Check PR status and CI. +gh pr status +gh pr checks +``` + +## Comprehensive Workflow Guide + +See [Pull Request Guide](../../../docs/pull-request.md) for complete PR workflow, detailed checklist, and git best practices. + +## Critical Rules + +### AI Tool Usage + +**CRITICAL:** Never add Claude Code as a co-author or mention AI tools in: +- Commit messages +- PR descriptions +- PR comments +- Code comments +- Anywhere in the codebase + +This is a hard requirement for all PRs. + +### Assignment and Review + +**Required for every PR:** +- **Always assign yourself** as assignee. +- **Always add Fediverse** as reviewer. +- Add other relevant reviewers if needed. + +## Changelog Management + +The repository uses Jetpack Changelogger for automated changelog generation. + +### PR Template Changelog Section + +Every PR template (`.github/PULL_REQUEST_TEMPLATE.md`) includes changelog fields: + +1. **Check "Automatically create a changelog entry" checkbox** +2. **Select Significance:** Patch/Minor/Major +3. **Select Type:** Added/Changed/Deprecated/Removed/Fixed/Security +4. **Write Message:** Clear description that **must end with punctuation!** + +**OR** add "Skip Changelog" label if no changelog entry needed. + +### Changelog Requirements + +**Always end changelog messages with proper punctuation:** +``` +✅ Add support for custom post types. +✅ Fix signature verification bug. +❌ Add support for custom post types +❌ Fix signature verification bug +``` + +See [Release Process - Changelog Management](../activitypub-release/SKILL.md) for complete changelog details. + +### Manual Changelog Entry + +If you forgot changelog in PR: +```bash +composer changelog:add # Interactive prompt. +git add . +git commit -m "Add changelog entry" +git push +``` + +## Development Workflow Best Practices + +### Break Down Features + +**Important:** Break features into small, focused PRs. Each piece should be its own PR. + +**Good approach:** +``` +PR 1: Add database schema +PR 2: Add REST endpoint +PR 3: Add UI component +PR 4: Add tests +``` + +**Bad approach:** +``` +Single PR with all changes +``` + +**For multi-PR features:** +1. Create tracking issue. +2. Link all related PRs to issue. +3. Use consistent naming: `add/feature-part-1`, `add/feature-part-2`. +4. Merge in order. + +### Branch Creation Workflow + +```bash +# Always branch from trunk. +git checkout trunk +git pull origin trunk + +# Create branch with appropriate prefix. +git checkout -b fix/notification-issue + +# Make changes, commit frequently. +git add . +git commit -m "Add follower validation" + +# Push to remote. +git push -u origin fix/notification-issue +``` + +### Pre-Push Checks + +Before creating PR or pushing changes: + +```bash +# Check PHP standards. +composer lint +composer lint:fix # Auto-fix issues. + +# Check JavaScript/CSS if you made changes. +npm run lint:js +npm run lint:css + +# Run tests. +npm run env-test + +# Build assets if needed. +npm run build +``` + +See [Development Cycle](../activitypub-dev-cycle/SKILL.md) for complete testing and linting commands. + +### Creating the PR + +1. Push your branch to remote. +2. Create PR via GitHub UI or `gh pr create`. +3. Fill out PR template completely. +4. Add changelog entry (or "Skip Changelog" label). +5. **Assign yourself**. +6. **Add Fediverse as reviewer**. +7. Mark as draft if not ready for review. + +### Review and Iteration + +After receiving feedback: +```bash +# Make requested changes. +git add . +git commit -m "Address review feedback" +git push + +# CI re-runs automatically. +# Re-request review after addressing feedback. +``` + +## Special PR Types + +### Hotfixes +For urgent fixes: +1. Branch from trunk: `fix/critical-issue`. +2. Minimal changeset. +3. Add "Hotfix" label. +4. Request expedited review. + +### Experimental Changes +For trying ideas: +1. Use `try/` prefix. +2. Mark as draft PR. +3. Request feedback early. +4. Convert to proper branch type once approach confirmed. + +## Keeping Branch Updated + +```bash +# Fetch latest trunk. +git fetch origin + +# Rebase your branch. +git rebase origin/trunk + +# Resolve conflicts if any, then continue. +git add . +git rebase --continue + +# Force push (safe if you're the only one on the branch). +git push --force-with-lease +``` + +**When to rebase:** Always rebase before final merge to trunk for clean history. + +See [Pull Request Guide](../../../docs/pull-request.md) for detailed rebase and merge conflict resolution. + +## Common PR Labels + +- `[Type] Bug` - Bug fixes. +- `[Type] Enhancement` - New features. +- `[Type] Documentation` - Doc updates. +- `Skip Changelog` - No changelog needed. +- `Needs Review` - Ready for review. +- `In Progress` - Still working. +- `Hotfix` - Urgent fix. diff --git a/.claude/skills/activitypub-release/SKILL.md b/.claude/skills/activitypub-release/SKILL.md new file mode 100644 index 000000000..511a9747b --- /dev/null +++ b/.claude/skills/activitypub-release/SKILL.md @@ -0,0 +1,119 @@ +--- +name: activitypub-release +description: Version management and release processes using Jetpack Changelogger. Use when creating releases, managing changelogs, bumping versions, or preparing patch releases. +--- + +# ActivityPub Release Process + +Quick reference for managing releases and changelogs for the WordPress ActivityPub plugin. + +## Quick Reference + +### Release Commands +```bash +npm run release # Create major/minor release PR. +``` + +### Version File Locations +When updating versions manually, change these files: +- `activitypub.php` - Plugin header (`Version: X.Y.Z`). +- `readme.txt` - WordPress.org readme (`Stable tag: X.Y.Z`). +- `package.json` - npm version (`"version": "X.Y.Z"`). +- `CHANGELOG.md` - Changelog file (auto-updated by release script). + +## Comprehensive Release Guide + +See [Release Process](../../../docs/release-process.md) for complete release workflow and detailed steps. + +## Release Workflow + +### Major/Minor Releases + +**Quick workflow:** +```bash +# 1. Run release script from plugin root. +npm run release + +# Script automatically: +# - Determines version from changelog entries. +# - Updates version numbers in all files. +# - Updates CHANGELOG.md. +# - Creates PR for review. + +# 2. Review and merge the release PR. + +# 3. Create GitHub release from trunk using the new tag. +``` + +See [Release Process - Major/Minor](../../../docs/release-process.md) for detailed steps. + +### Patch Releases + +**Quick workflow:** +```bash +# 1. Create branch from the tag to patch. +git fetch --tags +git checkout -b tags/5.3.1 5.3.0 # Patch 5.3.0 -> 5.3.1 + +# 2. Cherry-pick merge commits from trunk (note -m 1 flag). +git cherry-pick -m 1 + +# 3. Update changelog and versions. +composer changelog:write + +# Manually update versions in: +# - activitypub.php +# - readme.txt +# - package.json + +# 4. Push branch and create GitHub release. +git push -u origin tags/5.3.1 +``` + +**Important:** Use `-m 1` flag when cherry-picking merge commits to select the mainline parent. + +See [Release Process - Patch Releases](../../../docs/release-process.md#patch-releases) for detailed steps. + +## Changelog Management + +### How It Works + +Changelogs are managed automatically through the PR workflow: + +1. **PR Template** (`.github/PULL_REQUEST_TEMPLATE.md`): + - Check "Automatically create a changelog entry" checkbox. + - Select significance: Patch/Minor/Major. + - Select type: Added/Fixed/Changed/Deprecated/Removed/Security. + - Write message **ending with punctuation!** + +2. **GitHub Action** (`.github/workflows/changelog.yml`): + - Creates changelog file from PR description. + - Validates proper punctuation. + - Saves to `.github/changelog/` directory. + +3. **Release Process**: + - `npm run release` aggregates all entries. + - Updates `CHANGELOG.md` and `readme.txt` automatically. + +### Critical Requirements + +**Always end changelog messages with punctuation:** +``` +✅ Add support for custom post types. +✅ Fix signature verification bug. +❌ Add support for custom post types +❌ Fix signature verification bug +``` + +**Never mention AI tools or coding assistants in changelog messages.** + +See [PR Workflow - Changelog](../activitypub-pr-workflow/SKILL.md#changelog-management) for complete changelog requirements. + +## Version Numbering + +**Semantic versioning:** +- **Major (X.0.0)** - Breaking changes. +- **Minor (0.X.0)** - New features, backward compatible. +- **Patch (0.0.X)** - Bug fixes only. + +The release script determines version automatically from changelog entry significance levels. diff --git a/.claude/skills/activitypub-testing/SKILL.md b/.claude/skills/activitypub-testing/SKILL.md new file mode 100644 index 000000000..055db87d7 --- /dev/null +++ b/.claude/skills/activitypub-testing/SKILL.md @@ -0,0 +1,123 @@ +--- +name: activitypub-testing +description: Testing patterns for PHPUnit and Playwright E2E tests. Use when writing tests, debugging test failures, setting up test coverage, or implementing test patterns for ActivityPub features. +--- + +# ActivityPub Testing + +This skill provides guidance on writing and running tests for the WordPress ActivityPub plugin. + +## Quick Reference + +For complete testing commands and environment setup, see [Testing Reference](../../../tests/README.md). + +### Key Commands +- **PHP:** `npm run env-test` +- **E2E:** `npm run test:e2e` +- **JavaScript:** `npm run test:unit` + +## PHPUnit Testing + +### Test Structure + +```php + { + await page.goto('/wp-admin/options-general.php?page=activitypub'); + await expect(page.locator('h1')).toContainText('ActivityPub'); +}); +``` + +### Testing Federation + +```javascript +test('WebFinger discovery works', async ({ page }) => { + const response = await page.request.get('/.well-known/webfinger', { + params: { + resource: 'acct:admin@localhost:8888' + } + }); + + expect(response.ok()).toBeTruthy(); + const json = await response.json(); + expect(json.subject).toBe('acct:admin@localhost:8888'); +}); +``` + +## Test Data Factories + +For creating test data (users, posts, comments), see [Testing Reference - Test Utilities](../../../tests/README.md#test-utilities). + +## Coverage Reports + +See [Testing Reference](../../../tests/README.md) for detailed coverage generation instructions. + +## Debugging Tests + +### Debug Output + +```php +// In tests +var_dump( $data ); +error_log( print_r( $result, true ) ); + +// Run with verbose +npm run env-test -- --verbose --debug +``` + +### Isolating Tests + +```bash +# Run single test method +npm run env-test -- --filter=test_specific_method + +# Stop on first failure +npm run env-test -- --stop-on-failure +``` \ No newline at end of file diff --git a/.distignore b/.distignore index adad50bf4..a162ba06a 100644 --- a/.distignore +++ b/.distignore @@ -1,3 +1,4 @@ +.claude .codeclimate.yml .data .distignore @@ -18,6 +19,7 @@ _config.yml _site bin CHANGELOG.md +CLAUDE.md CODE_OF_CONDUCT.md CONTRIBUTING.md composer.json diff --git a/.gitignore b/.gitignore index a984b643e..f816aa17f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,8 @@ /vendor/ _site .idea/ -.claude +# Claude Code - track skills but ignore local overrides +.claude/**/*.local* .cursor .DS_Store .php_cs.cache @@ -16,5 +17,4 @@ _site .windsurf .windsurfrules .wp-env.override.json -CLAUDE* composer.lock diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..d619502c5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,27 @@ +## WordPress ActivityPub Development + +This project uses AI coding assistant skills to provide contextual guidance for development workflows. + +### Available Skills + +The following skills are available in `.claude/skills/`: + +- **activitypub-dev-cycle** — Development workflows, testing, linting, and environment setup +- **activitypub-php-conventions** — PHP coding standards and WordPress patterns +- **activitypub-pr-workflow** — Pull request creation and review processes +- **activitypub-federation** — ActivityPub protocol implementation and federation +- **activitypub-testing** — PHPUnit and E2E testing patterns +- **activitypub-release** — Version management and release processes +- **activitypub-integrations** — Third-party plugin integration patterns + +**CRITICAL:** After reading a skill, check if a local skill override file exists at `~/.claude/skills/{skill-name}-local/SKILL.md` and apply it too. +For example, after reading `.claude/skills/activitypub-dev-cycle/SKILL.md`, check for `~/.claude/skills/activitypub-dev-cycle-local/SKILL.md`. + +**Local override skills take precedence over project-level skills in case of conflict.** + +## Notes for Claude + +- This doc provides context; skills provide procedures +- When in doubt about HOW to do something, check the skills +- When in doubt about WHAT something is or WHERE it fits, check this doc +- Skills are invoked automatically when relevant to the task diff --git a/docs/development-environment.md b/docs/development-environment.md index 8cf272020..db860e5a5 100644 --- a/docs/development-environment.md +++ b/docs/development-environment.md @@ -70,6 +70,8 @@ cd wordpress-activitypub composer install ``` +**Note:** `npm install` automatically runs `npm run prepare`, which sets up pre-commit hooks in `.githooks/pre-commit`. These hooks automatically format code and check standards before commits. + ### Start Development Environment Start the local WordPress environment using wp-env: