diff --git a/.github/CLAUDE_PERMISSIONS.md b/.github/CLAUDE_PERMISSIONS.md deleted file mode 100644 index 0f0416f..0000000 --- a/.github/CLAUDE_PERMISSIONS.md +++ /dev/null @@ -1,212 +0,0 @@ -# Claude Workflow Permissions - -This document explains how to configure user permissions for Claude automation workflows. - -## Current Configuration - -### Issue Implementation Workflow -- **Strategy**: `adminOrPrivileged` - Repository admins OR privileged users -- **Privileged Users**: `bastiaan`, `xtr-dev-team` -- **Access Check**: Validates permissions before any Claude implementation - -### Code Review Workflow -- **Strategy**: `privilegedUsers` - Only users in privileged list -- **Applies to**: Pull request reviews -- **Scope**: PRs created by privileged users only - -## Permission Strategies - -### 1. Privileged Users Only -```javascript -const isAllowed = privilegedUsers.includes(username); -``` -- Most restrictive -- Only specific users can use Claude -- Best for sensitive repositories - -### 2. Admins Only -```javascript -const isAllowed = collaborator.permission === 'admin'; -``` -- Repository administrators only -- Automatic based on GitHub permissions -- Good for small teams - -### 3. Admin OR Privileged (Current) -```javascript -const isAllowed = hasAdminAccess || isPrivilegedUser; -``` -- Repository admins OR users in privileged list -- Flexible access control -- **Currently active strategy** - -### 4. Organization Members with Write Access -```javascript -const isAllowed = isOrgMember && hasWriteAccess; -``` -- Organization members with write/admin permissions -- Good for larger organizations - -### 5. Everyone with Access -```javascript -const isAllowed = hasWriteAccess; -``` -- Any collaborator with write access -- Least restrictive option - -## How to Change Permissions - -### Option A: Edit Privileged Users List -1. Open `.github/workflows/claude-implement-issue.yml` -2. Find the `privilegedUsers` array (line ~32) -3. Add or remove usernames: -```javascript -const privilegedUsers = [ - 'bastiaan', - 'xtr-dev-team', - 'new-user', // Add new users here - 'another-user' -]; -``` - -### Option B: Change Permission Strategy -1. Open `.github/workflows/claude-implement-issue.yml` -2. Find line ~77: `const isAllowed = allowedByAdminOrPrivileged;` -3. Replace with your preferred strategy: -```javascript -// Only privileged users -const isAllowed = allowedByUserList; - -// Only admins -const isAllowed = allowedByAdminAccess; - -// Admin + privileged users (current) -const isAllowed = allowedByAdminOrPrivileged; - -// Organization members with write access -const isAllowed = allowedByOrgAndWrite; -``` - -### Option C: Custom Logic -Add your own permission logic: -```javascript -// Example: Allow specific teams -const allowedTeams = ['core-team', 'senior-devs']; -const userTeams = await github.rest.teams.listForUser({ - org: context.repo.owner, - username: username -}); -const isInAllowedTeam = userTeams.data.some(team => - allowedTeams.includes(team.slug) -); - -const isAllowed = hasAdminAccess || isInAllowedTeam; -``` - -## Code Review Permissions - -The code review workflow uses a simpler approach with GitHub's built-in author associations: - -```yaml -if: | - contains(fromJSON('["bastiaan", "xtr-dev-team"]'), github.event.pull_request.user.login) || - github.event.pull_request.author_association == 'OWNER' || - github.event.pull_request.author_association == 'MEMBER' -``` - -### Author Associations: -- `OWNER` - Repository owner -- `MEMBER` - Organization member -- `COLLABORATOR` - Repository collaborator -- `CONTRIBUTOR` - Has contributed to the repository -- `FIRST_TIME_CONTRIBUTOR` - First-time contributor -- `NONE` - No association - -## Testing Permissions - -### Test Access for a User -1. Create a test issue -2. Have the user comment `@claude implement` -3. Check the workflow logs for permission results - -### Debug Permission Issues -1. Go to **Actions** tab -2. Click on the failed workflow run -3. Expand "Check user permissions" step -4. Review the permission details in logs - -## Error Messages - -### Access Denied -``` -❌ Access Denied: Claude implementation is restricted to privileged users only. - -Your access level: write -Privileged user: No -Organization member: Yes - -Contact a repository administrator for access. -``` - -### Permission Details -The error message shows: -- Current repository permission level -- Whether user is in privileged list -- Organization membership status - -## Security Considerations - -### Best Practices -1. **Start Restrictive**: Begin with privileged users only -2. **Regular Audits**: Review privileged user list regularly -3. **Monitor Usage**: Check workflow logs for unexpected access attempts -4. **Team-based Access**: Consider using GitHub teams for larger organizations - -### Risks -- **Over-permissive**: Too many users can increase costs and misuse -- **Under-permissive**: Blocks legitimate development work -- **Stale Permissions**: Former team members with lingering access - -## Configuration Examples - -### Small Team (2-5 developers) -```javascript -const privilegedUsers = ['owner', 'lead-dev']; -const isAllowed = allowedByAdminOrPrivileged; -``` - -### Medium Team (5-15 developers) -```javascript -const privilegedUsers = ['owner', 'lead-dev', 'senior-dev1', 'senior-dev2']; -const isAllowed = allowedByAdminOrPrivileged; -``` - -### Large Organization -```javascript -// Use organization membership + write access -const isAllowed = allowedByOrgAndWrite; -``` - -### Open Source Project -```javascript -// Only maintainers -const privilegedUsers = ['maintainer1', 'maintainer2']; -const isAllowed = allowedByUserList; -``` - -## Troubleshooting - -### Common Issues -1. **User not in list**: Add username to `privilegedUsers` array -2. **Wrong permission level**: User needs write access minimum -3. **Organization issues**: Verify org membership if using org-based permissions -4. **Case sensitivity**: Usernames are case-sensitive - -### Quick Fixes -- **Add user**: Edit workflow file, add to privileged users -- **Temporary access**: Change strategy to `allowedByAdminAccess` temporarily -- **Emergency access**: Repository admins always have access with `adminOrPrivileged` strategy - ---- - -**Note**: Changes to workflow files require a commit to take effect. Test permissions after any modifications. \ No newline at end of file diff --git a/.github/CLAUDE_PR_ASSISTANT.md b/.github/CLAUDE_PR_ASSISTANT.md new file mode 100644 index 0000000..98dc675 --- /dev/null +++ b/.github/CLAUDE_PR_ASSISTANT.md @@ -0,0 +1,235 @@ +# Claude PR Assistant + +This workflow allows Claude to assist with Pull Requests by implementing improvements, fixes, and changes directly on the PR branch when mentioned in comments. + +## How to Use + +### 1. Comment on Any PR + +Use one of these trigger commands in a comment on any open pull request: + +- `@claude implement` - Implement new features or functionality +- `@claude fix` - Fix bugs or issues in the PR +- `@claude improve` - Improve existing code quality +- `@claude update` - Update code to match requirements +- `@claude refactor` - Refactor code for better structure +- `@claude help` - General assistance with the PR + +### 2. Example Usage + +``` +@claude fix + +Please fix the TypeScript errors in the payments collection and ensure proper typing for the provider data field. +``` + +``` +@claude improve + +Can you optimize the invoice generation logic and add better error handling? +``` + +``` +@claude implement + +Add validation for email addresses in the customer billing information fields. Make sure it follows the existing validation patterns. +``` + +## What Happens + +1. **Permission Check**: Verifies you are `bvdaakster` (only authorized user) +2. **PR Analysis**: Claude analyzes the current PR context and changes +3. **Implementation**: Makes the requested changes directly on the PR branch +4. **Quality Checks**: Runs build, typecheck, and lint +5. **Commit & Push**: Commits changes with descriptive messages +6. **Notification**: Updates the PR with completion status + +## Features + +### ✅ Direct PR Modification +- Works directly on the existing PR branch +- No new branches or PRs created +- Changes appear immediately in the PR + +### ✅ Smart Context Awareness +- Understands the current PR changes +- Analyzes existing code patterns +- Maintains consistency with the codebase + +### ✅ Comprehensive Request Handling +- Code improvements and refactoring +- Bug fixes within the PR +- Adding missing features +- Documentation updates +- Type error fixes +- Performance optimizations +- Test additions + +### ✅ Quality Assurance +- Follows TypeScript conventions +- Uses ESM module structure +- Runs automated quality checks +- Maintains coding standards + +## Command Reference + +| Command | Purpose | Example | +|---------|---------|---------| +| `@claude implement` | Add new functionality | "implement user authentication" | +| `@claude fix` | Fix bugs or errors | "fix the validation logic" | +| `@claude improve` | Enhance existing code | "improve performance of query" | +| `@claude update` | Update to requirements | "update to use new API format" | +| `@claude refactor` | Restructure code | "refactor into smaller functions" | +| `@claude help` | General assistance | "help with error handling" | + +## Examples + +### Bug Fix Request +``` +@claude fix + +There's a TypeScript error in `src/providers/stripe.ts` on line 45. The `amount` property is missing from the payment object. Please fix this and ensure proper typing. +``` + +### Feature Implementation +``` +@claude implement + +Add support for recurring payments in the Stripe provider. Follow the same pattern as the Mollie provider and include proper webhook handling. +``` + +### Code Improvement +``` +@claude improve + +The `validatePayment` function in utils.ts is getting complex. Please refactor it to be more readable and add proper error messages for each validation case. +``` + +### Documentation Update +``` +@claude update + +Update the JSDoc comments in the billing plugin configuration to include examples of how to use the new customer info extractor feature. +``` + +## Response Types + +### Success Response +``` +✅ PR Assistance Complete! + +🔧 Changes Made: +- ✅ Analyzed PR context and requirements +- ✅ Implemented requested improvements/fixes +- ✅ Followed project coding standards +- ✅ Updated the current PR branch + +Changes are ready for review! 🚀 +``` + +### No Changes Response +``` +ℹ️ PR Assistance Complete - No Changes + +Analysis Result: The requested feature is already implemented + +💡 Suggestions: +- Provide more detailed requirements +- Point to specific files or functions +``` + +### Error Response +``` +❌ PR Assistance Failed + +🔄 Try Again: +- Providing more specific instructions +- Breaking down complex requests +``` + +## Best Practices + +### Clear Instructions +- Be specific about what you want changed +- Reference specific files or functions when possible +- Provide context about the desired outcome + +### Examples of Good Requests +``` +@claude fix the TypeScript error in src/collections/payments.ts line 42 where the status field is missing from the Payment interface + +@claude implement email validation in the customer billing form using the same pattern as the phone validation + +@claude refactor the webhook handler in providers/mollie.ts to extract the payment processing logic into separate functions +``` + +### Examples of Unclear Requests +``` +@claude fix everything +@claude make it better +@claude help with this +``` + +## Limitations + +- **User Restriction**: Only `bvdaakster` can use this feature +- **PR Only**: Works on pull request comments, not issue comments +- **Open PRs**: Only works on open pull requests +- **Branch Access**: Requires write access to the PR branch + +## Technical Details + +### Workflow Triggers +- Event: `issue_comment` on pull requests +- Conditions: Comment contains Claude trigger words +- Permissions: User must be `bvdaakster` + +### Quality Checks +Claude automatically runs: +- `pnpm build` - Verify code compiles +- `pnpm typecheck` - Check TypeScript types +- `pnpm lint` - Ensure code style compliance +- `npm run test` - Run test suite (if available) + +### Commit Messages +Automatic commits include: +- Description of the request +- PR number and requester +- Claude attribution +- Proper co-authoring + +### Branch Strategy +- Works directly on the PR's head branch +- No additional branches created +- Changes pushed to existing PR +- Maintains PR history + +## Troubleshooting + +### Common Issues + +1. **Permission Denied** + - Only `bvdaakster` can use Claude PR assistance + - Verify you're commenting as the correct user + +2. **No Changes Made** + - Request might be unclear or already implemented + - Try providing more specific instructions + - Reference specific files or lines + +3. **Workflow Failed** + - Check the Actions tab for detailed logs + - Verify the PR branch is accessible + - Ensure request is actionable + +### Getting Help + +If Claude assistance isn't working: +1. Check the workflow logs in Actions tab +2. Verify your request is specific and actionable +3. Try breaking complex requests into smaller parts +4. Use different command triggers (@claude fix vs @claude implement) + +--- + +**Note**: This feature uses the official Anthropic Claude Code action for reliable, production-ready assistance. All changes should be reviewed before merging. \ No newline at end of file diff --git a/.github/claude-config.json b/.github/claude-config.json index 1297271..7bfe8e7 100644 --- a/.github/claude-config.json +++ b/.github/claude-config.json @@ -10,6 +10,27 @@ "codeReview": { "strategy": "privilegedUsers", "description": "Only bvdaakster can trigger Claude reviews" + }, + "prAssistant": { + "strategy": "privilegedUsers", + "description": "Only bvdaakster can use Claude PR assistance" + } + }, + "workflows": { + "issueImplementation": { + "file": "claude-implement-issue.yml", + "triggers": ["@claude implement", "@claude fix", "@claude create"], + "description": "Creates new branch and PR for issue implementation" + }, + "codeReview": { + "file": "claude-code-review.yml", + "triggers": ["automatic on PR"], + "description": "Automatic code review for PRs from privileged users" + }, + "prAssistant": { + "file": "claude-pr-assistant.yml", + "triggers": ["@claude implement", "@claude fix", "@claude improve", "@claude update", "@claude refactor", "@claude help"], + "description": "Assists with PR improvements directly on the PR branch" } }, "strategies": { diff --git a/.github/workflows/claude-pr-assistant.yml b/.github/workflows/claude-pr-assistant.yml new file mode 100644 index 0000000..b26703d --- /dev/null +++ b/.github/workflows/claude-pr-assistant.yml @@ -0,0 +1,328 @@ +name: Claude PR Assistant + +on: + issue_comment: + types: [created] + +permissions: + contents: write + issues: write + pull-requests: write + id-token: write + +jobs: + claude-pr-assist: + # Only run on PR comments (not issue comments) + if: | + github.event.issue.pull_request && + github.event.issue_comment.issue.state == 'open' && + ( + contains(github.event.comment.body, '@claude implement') || + contains(github.event.comment.body, '@claude fix') || + contains(github.event.comment.body, '@claude improve') || + contains(github.event.comment.body, '@claude update') || + contains(github.event.comment.body, '@claude refactor') || + contains(github.event.comment.body, '@claude help') + ) + runs-on: ubuntu-latest + + steps: + - name: Check user permissions + uses: actions/github-script@v7 + with: + script: | + const username = context.actor; + + // Only allow bvdaakster to use Claude PR assistance + const privilegedUsers = [ + 'bvdaakster' // Only this user can use Claude + ]; + + const isPrivilegedUser = privilegedUsers.includes(username); + + if (!isPrivilegedUser) { + const errorMessage = `❌ **Access Denied**: Claude PR assistance is restricted to privileged users only. + + **User**: ${username} + **Privileged user**: No + + Contact a repository administrator for access.`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: errorMessage + }); + throw new Error('Insufficient permissions for Claude PR assistance'); + } + + console.log(`✅ Access granted to ${username}`); + + - name: Get PR details + id: pr-details + uses: actions/github-script@v7 + with: + script: | + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + + return { + head_ref: pr.head.ref, + head_sha: pr.head.sha, + base_ref: pr.base.ref, + title: pr.title, + body: pr.body, + user: pr.user.login + }; + + - name: Checkout PR branch + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ fromJson(steps.pr-details.outputs.result).head_ref }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + + - name: Install pnpm + run: npm install -g pnpm@10.12.4 + + - name: Add comment with start notification + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `🤖 **Claude PR Assistant Started** + + I'm now working on your request in this pull request: + + 📋 **PR**: #${{ github.event.issue.number }} - ${{ fromJson(steps.pr-details.outputs.result).title }} + 🌿 **Branch**: \`${{ fromJson(steps.pr-details.outputs.result).head_ref }}\` + 💬 **Request**: + \`\`\` + ${{ github.event.comment.body }} + \`\`\` + ⏱️ **Started**: ${new Date().toISOString()} + + I'll analyze the current PR and implement your requested changes. This may take a few minutes... + + You can track the progress in the [Actions tab](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).` + }); + + - name: Assist with Claude + id: assistance + uses: anthropics/claude-code-action@beta + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # Direct prompt with PR context + direct_prompt: | + You are assisting with a GitHub Pull Request. Please help with the following request: + + **Pull Request #${{ github.event.issue.number }}**: ${{ fromJson(steps.pr-details.outputs.result).title }} + + **PR Description**: + ${{ fromJson(steps.pr-details.outputs.result).body }} + + **User Request**: + ${{ github.event.comment.body }} + + **Context**: + - Repository: @xtr-dev/payload-billing (PayloadCMS plugin) + - Branch: ${{ fromJson(steps.pr-details.outputs.result).head_ref }} + - Base branch: ${{ fromJson(steps.pr-details.outputs.result).base_ref }} + - Requested by: @${{ github.event.comment.user.login }} + + **Instructions**: + 1. Analyze the current PR changes and the user's request + 2. Implement the requested improvements, fixes, or changes + 3. Follow existing code patterns and conventions + 4. Ensure TypeScript typing is correct + 5. Use ESM module structure with .js extensions + 6. Run quality checks (build, typecheck, lint) + 7. If the request is unclear, make reasonable assumptions based on context + + **Types of requests to handle**: + - Code improvements and refactoring + - Bug fixes within the PR + - Adding missing features or functionality + - Updating documentation + - Fixing type errors or lint issues + - Performance optimizations + - Adding tests + + Please implement the requested changes directly in the current branch. + + # Allow Claude to run necessary commands + allowed_tools: "Bash(pnpm build),Bash(pnpm typecheck),Bash(pnpm lint),Bash(npm run test)" + + - name: Check for changes + id: changes + run: | + # Check both staged and unstaged changes + if git diff --quiet && git diff --cached --quiet; then + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "No changes were made during assistance" + else + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "Changes detected, preparing commit" + + # Show what changed for debugging + echo "=== Changed files ===" + git diff --name-only + git diff --cached --name-only + echo "====================" + fi + + - name: Commit changes + if: steps.changes.outputs.has_changes == 'true' + run: | + git config --local user.email "action@github.com" + git config --local user.name "Claude PR Assistant" + + git add . + git commit -m "$(cat <<'EOF' + feat: Claude PR assistance - ${{ github.event.comment.user.login }} request + + Implemented requested changes via Claude PR Assistant. + + PR: #${{ github.event.issue.number }} + Request: ${{ github.event.comment.body }} + Requested by: @${{ github.event.comment.user.login }} + + 🤖 Generated with Claude PR Assistant + + Co-Authored-By: Claude + EOF + )" + + git push origin ${{ fromJson(steps.pr-details.outputs.result).head_ref }} + + - name: Update PR with success + if: steps.changes.outputs.has_changes == 'true' + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `✅ **PR Assistance Complete!** + +I've successfully implemented your requested changes: + +💬 **Your Request**: +\`\`\` +${{ github.event.comment.body }} +\`\`\` + +🔧 **Changes Made**: +- ✅ Analyzed PR context and requirements +- ✅ Implemented requested improvements/fixes +- ✅ Followed project coding standards +- ✅ Updated the current PR branch +- ✅ Committed changes with descriptive message + +🌿 **Branch**: \`${{ fromJson(steps.pr-details.outputs.result).head_ref }}\` +⏱️ **Completed**: ${new Date().toISOString()} + +## 🔍 What's Next +The changes have been pushed to this PR branch. You can: +1. **Review** the new changes in the Files Changed tab +2. **Test** the implementation locally +3. **Verify** the changes meet your requirements +4. **Request** additional changes if needed + +## 🛠️ Quality Assurance +The implementation includes: +- TypeScript with proper typing +- ESM module structure with .js extensions +- Following existing code patterns +- Quality checks passed (build/typecheck/lint) + +**Changes are ready for review!** 🚀` + }); + + - name: Update PR with no changes + if: steps.changes.outputs.has_changes == 'false' + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `ℹ️ **PR Assistance Complete - No Changes** + +I analyzed your request but determined that no code changes are needed: + +💬 **Your Request**: +\`\`\` +${{ github.event.comment.body }} +\`\`\` + +## 🔍 Analysis Result +This might be because: +- The requested feature is already implemented +- The issue mentioned is already fixed +- The request requires clarification +- The change is not actionable as code modification + +🌿 **Branch**: \`${{ fromJson(steps.pr-details.outputs.result).head_ref }}\` (unchanged) + +## 💡 Suggestions +If you need specific changes: +1. Provide more detailed requirements +2. Point to specific files or functions +3. Include code examples of desired changes +4. Try a different @claude command + +Feel free to comment again with more specific instructions!` + }); + + - name: Handle assistance failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `❌ **PR Assistance Failed** + +I encountered an error while trying to assist with this PR. + +💬 **Your Request**: +\`\`\` +${{ github.event.comment.body }} +\`\`\` + +## 🔍 Troubleshooting +Please check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. + +Common reasons for failure: +- Request is unclear or too complex +- Technical constraints prevent implementation +- Permission or configuration issues +- Conflicting changes in the PR + +## 🔄 Try Again +You can try again by: +- Providing more specific instructions +- Breaking down complex requests into smaller parts +- Commenting with a different @claude command + +**Available commands**: \`@claude implement\`, \`@claude fix\`, \`@claude improve\`, \`@claude update\`, \`@claude refactor\`, \`@claude help\`` + }); \ No newline at end of file