feat: add Claude PR Assistant workflow for direct PR improvements

- Create new workflow for PR comment-based Claude assistance
- Support multiple commands: implement, fix, improve, update, refactor, help
- Work directly on PR branches without creating new PRs
- Include comprehensive permission checks (bvdaakster only)
- Add detailed documentation and usage examples
- Support quality checks: build, typecheck, lint, test
- Include smart context awareness of PR changes

Features:
- Direct PR branch modification
- Multiple trigger commands for different types of assistance
- Comprehensive error handling and user feedback
- Quality assurance with automated checks
- Detailed commit messages with attribution

Commands:
- @claude implement - Add new functionality
- @claude fix - Fix bugs or errors
- @claude improve - Enhance existing code
- @claude update - Update to requirements
- @claude refactor - Restructure code
- @claude help - General assistance

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-18 21:28:54 +02:00
parent a3108a0f49
commit cabe6eda96
4 changed files with 584 additions and 212 deletions

View File

@@ -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.

235
.github/CLAUDE_PR_ASSISTANT.md vendored Normal file
View File

@@ -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.

View File

@@ -10,6 +10,27 @@
"codeReview": { "codeReview": {
"strategy": "privilegedUsers", "strategy": "privilegedUsers",
"description": "Only bvdaakster can trigger Claude reviews" "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": { "strategies": {

View File

@@ -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 <noreply@anthropic.com>
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\``
});