Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .github/workflows/claude-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ name: Claude Code Integration
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]

jobs:
# Handle PR comments
process-pr-review:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, 'claude:') }}
Expand Down Expand Up @@ -67,4 +70,86 @@ jobs:
pr-number: ${{ steps.pr.outputs.number }}
feedback: ${{ steps.pr.outputs.feedback }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}

# Handle code review comments
process-review-comment:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request_review_comment' && startsWith(github.event.comment.body, 'claude:') }}
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get PR and comment details
id: details
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
FEEDBACK="${{ github.event.comment.body }}"
# Remove the "claude:" prefix
FEEDBACK="${FEEDBACK#claude:}"
COMMENT_ID="${{ github.event.comment.id }}"
FILE_PATH="${{ github.event.comment.path }}"
LINE="${{ github.event.comment.line }}"

echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "feedback=$FEEDBACK" >> $GITHUB_OUTPUT
echo "comment_id=$COMMENT_ID" >> $GITHUB_OUTPUT
echo "file_path=$FILE_PATH" >> $GITHUB_OUTPUT
echo "line=$LINE" >> $GITHUB_OUTPUT

- name: Process with Claude Code for code review comment
uses: fractureinc/claude-code-github-action@v0.2.0
with:
mode: 'review'
pr-number: ${{ steps.details.outputs.number }}
feedback: ${{ steps.details.outputs.feedback }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}

process-suggest-review-comment:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request_review_comment' && startsWith(github.event.comment.body, 'claude-suggest:') }}
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get PR and comment details
id: details
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
FEEDBACK="${{ github.event.comment.body }}"
# Remove the "claude-suggest:" prefix
FEEDBACK="${FEEDBACK#claude-suggest:}"
COMMENT_ID="${{ github.event.comment.id }}"
FILE_PATH="${{ github.event.comment.path }}"
LINE="${{ github.event.comment.line }}"

echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "feedback=$FEEDBACK" >> $GITHUB_OUTPUT
echo "comment_id=$COMMENT_ID" >> $GITHUB_OUTPUT
echo "file_path=$FILE_PATH" >> $GITHUB_OUTPUT
echo "line=$LINE" >> $GITHUB_OUTPUT

- name: Process with Claude Code Suggestions for code review
uses: fractureinc/claude-code-github-action@v0.2.1
with:
mode: 'suggest-review'
pr-number: ${{ steps.details.outputs.number }}
feedback: ${{ steps.details.outputs.feedback }}
file-path: ${{ steps.details.outputs.file_path }}
line-number: ${{ steps.details.outputs.line }}
comment-id: ${{ steps.details.outputs.comment_id }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ This GitHub Action integrates Claude Code in your GitHub workflows, enabling AI-
## Features

- Process PR comments prefixed with "claude:" for general analysis
- Process PR comments prefixed with "claude-suggest:" for clickable code suggestions
- Process PR comments prefixed with "claude-suggest:" for code suggestions
- Process code review comments to provide in-line analysis and suggestions
- Provide rich context about the PR to Claude, including file diffs
- Get AI-powered code analysis and suggestions
- Create GitHub-compatible suggested changes that can be applied with one click
Expand Down Expand Up @@ -48,7 +49,7 @@ jobs:
echo "feedback=$FEEDBACK" >> $GITHUB_OUTPUT

- name: Process with Claude Code
uses: fractureinc/claude-code-github-action@v0.2.0
uses: fractureinc/claude-code-github-action@v0.2.1
with:
mode: 'review'
pr-number: ${{ steps.pr.outputs.number }}
Expand Down Expand Up @@ -80,7 +81,7 @@ jobs:
echo "feedback=$FEEDBACK" >> $GITHUB_OUTPUT

- name: Process with Claude Code Suggestions
uses: fractureinc/claude-code-github-action@v0.2.0
uses: fractureinc/claude-code-github-action@v0.2.1
with:
mode: 'suggest'
pr-number: ${{ steps.pr.outputs.number }}
Expand All @@ -104,7 +105,7 @@ jobs:

## Enhanced Context for Claude

With version 0.2.0, Claude now receives complete context for your PRs, including:
With version 0.2.1, Claude now receives complete context for your PRs, including:

- PR metadata (title, description, branch info)
- List of all files changed
Expand All @@ -120,7 +121,11 @@ Standard mode that provides Claude's analysis and feedback about your PR changes

### Suggest Mode (`mode: 'suggest'`)

Creates GitHub-compatible suggested changes that can be applied with one click directly from the PR interface.
Creates suggested changes in a PR comment that outline potential code improvements.

### Suggest Review Mode (`mode: 'suggest-review'`)

Creates true GitHub-compatible suggestions that can be applied with one click directly from the code review interface. These are attached to specific lines of code.

### Direct Mode (`mode: 'direct'`)

Expand All @@ -135,6 +140,7 @@ Sends a query directly to Claude and saves the response to a file without PR con
- `claude: Are there any security issues in these changes?`
- `claude: How would you refactor this to be more maintainable?`
- `claude: What tests should be added for this code?`
- `claude: Analyze the performance implications of these changes`

### Suggest Mode Examples (prefix: `claude-suggest:`)

Expand All @@ -145,17 +151,19 @@ Sends a query directly to Claude and saves the response to a file without PR con

## How It Works

1. The action is triggered when a comment with the appropriate prefix is detected on a PR
2. The action extracts the PR number and the user's query
1. The action is triggered when a comment with the appropriate prefix is detected (either on the PR or in code review)
2. The action extracts the PR number, user's query, and (for code review comments) the file path and line number
3. The repository is checked out to provide full code context
4. Using GitHub CLI, the action fetches comprehensive information about the PR including:
- PR metadata
- List of files changed
- List of files changed
- Complete diff of all changes
- For code review comments, specific file content and context around the commented line
5. This rich context is provided to Claude along with the user's query
6. Claude processes the information and provides a helpful response
7. For review mode: The response is posted as a comment on the PR
8. For suggest mode: Claude formats responses as GitHub suggested changes that can be applied with one click
8. For suggest mode: Claude formats responses with code suggestions in the PR comment
9. For suggest-review mode: Claude creates true GitHub-compatible suggestions attached to specific lines of code

## Permissions

Expand Down
20 changes: 18 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ branding:

inputs:
mode:
description: 'The mode to run the action in (review, pr-comment, suggest, direct)'
description: 'The mode to run the action in (review, suggest, suggest-review, direct)'
required: true
default: 'review'
pr-number:
Expand All @@ -15,6 +15,15 @@ inputs:
feedback:
description: 'The feedback text from the comment'
required: false
file-path:
description: 'Path to the file being reviewed (for suggest-review mode)'
required: false
line-number:
description: 'Line number in the file (for suggest-review mode)'
required: false
comment-id:
description: 'GitHub comment ID to reply to (for suggest-review mode)'
required: false
anthropic-api-key:
description: 'Anthropic API key for Claude access'
required: true
Expand Down Expand Up @@ -63,4 +72,11 @@ runs:
shell: bash
run: |
chmod +x ${{ github.action_path }}/scripts/direct-mode.sh
${{ github.action_path }}/scripts/direct-mode.sh "${{ inputs.feedback }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.output-file }}"
${{ github.action_path }}/scripts/direct-mode.sh "${{ inputs.feedback }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.output-file }}"

- name: Process In-line Code Suggestions
if: inputs.mode == 'suggest-review'
shell: bash
run: |
chmod +x ${{ github.action_path }}/scripts/suggest-review-mode.sh
${{ github.action_path }}/scripts/suggest-review-mode.sh "${{ inputs.pr-number }}" "${{ inputs.feedback }}" "${{ inputs.file-path }}" "${{ inputs.line-number }}" "${{ inputs.comment-id }}" "${{ inputs.anthropic-api-key }}" "${{ inputs.github-token }}"
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "claude-code-github-action",
"version": "0.2.0",
"description": "GitHub action for Claude Code Integration in PR comments, reviews and code suggestions",
"version": "0.2.1",
"description": "GitHub action for Claude Code Integration in PR comments, reviews and inline code suggestions",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand All @@ -19,7 +19,8 @@
"ai",
"review",
"pull-request",
"suggestions"
"suggestions",
"inline"
],
"author": "Fracture Inc",
"license": "MIT",
Expand Down
106 changes: 106 additions & 0 deletions scripts/suggest-review-mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/bash
set -e

# Get input parameters
PR_NUMBER=$1
FEEDBACK=$2
FILE_PATH=$3
LINE_NUMBER=$4
COMMENT_ID=$5
ANTHROPIC_API_KEY=$6
GITHUB_TOKEN=$7

# Set up authentication
echo "$GITHUB_TOKEN" | gh auth login --with-token
export ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY"

# Create a temp file for Claude's response
RESPONSE_FILE=$(mktemp)

# Get PR details using GitHub CLI
echo "Fetching PR details for PR #$PR_NUMBER"
PR_DETAILS=$(gh pr view $PR_NUMBER --json title,body,baseRefName,headRefName,additions,deletions,changedFiles,state)

PR_TITLE=$(echo "$PR_DETAILS" | jq -r '.title')
PR_BODY=$(echo "$PR_DETAILS" | jq -r '.body')
PR_BASE=$(echo "$PR_DETAILS" | jq -r '.baseRefName')
PR_HEAD=$(echo "$PR_DETAILS" | jq -r '.headRefName')
PR_STATE=$(echo "$PR_DETAILS" | jq -r '.state')

# Checkout PR branch for full repo context
echo "Checking out PR branch: $PR_HEAD"
git fetch origin pull/$PR_NUMBER/head:$PR_HEAD
git checkout $PR_HEAD

# Get the specific file content
FILE_CONTENT=$(cat "$FILE_PATH")

# Get a context window around the line in question (10 lines before and after)
LINE_START=$((LINE_NUMBER - 10))
if [ $LINE_START -lt 1 ]; then
LINE_START=1
fi
LINE_END=$((LINE_NUMBER + 10))
CONTEXT_CONTENT=$(sed -n "${LINE_START},${LINE_END}p" "$FILE_PATH")

# Get repo information
REPO_INFO=$(gh repo view --json name,description,defaultBranchRef,languages)
REPO_NAME=$(echo "$REPO_INFO" | jq -r '.name')
REPO_DESC=$(echo "$REPO_INFO" | jq -r '.description')
REPO_DEFAULT_BRANCH=$(echo "$REPO_INFO" | jq -r '.defaultBranchRef.name')
REPO_LANGUAGES=$(echo "$REPO_INFO" | jq -r '.languages[].name' | tr '\n' ', ' | sed 's/,$//')

# Build the prompt for Claude to generate a suggested change
PROMPT=$(cat <<EOF
This is a GitHub code review. Create a suggestion for the specific code at line $LINE_NUMBER in file '$FILE_PATH'.

Your response will be directly used by GitHub to create a suggestion on this line of code.
You MUST format your response as a SINGLE suggestion using the exact GitHub suggestion format:

\`\`\`suggestion
[Your improved code here]
\`\`\`

Guidelines:
1. Focus ONLY on line $LINE_NUMBER and immediately surrounding lines
2. Keep the suggestion concise - it should replace just what needs to be changed
3. Maintain the existing indentation and code style
4. Ensure your suggestion is syntactically correct
5. Start your response with a brief explanation, then provide the suggestion block
6. Your suggestion will be applied directly to the code via GitHub's suggestion feature

Repository: $REPO_NAME
PR: $PR_TITLE
File being reviewed: $FILE_PATH
Line number: $LINE_NUMBER

Context (code around line $LINE_NUMBER):
\`\`\`
$CONTEXT_CONTENT
\`\`\`

Complete file content:
\`\`\`
$FILE_CONTENT
\`\`\`

User query:
$FEEDBACK

Provide a single, specific suggestion that addresses this query for the code at line $LINE_NUMBER.
EOF
)

# Run Claude CLI
echo "Sending request to Claude for in-line suggestion..."
echo "$PROMPT" | claude -p - > "$RESPONSE_FILE"

# Reply to the specific comment with Claude's suggestion
echo "Posting Claude's suggested change as a reply to the comment"
gh api --method POST "/repos/:owner/:repo/pulls/$PR_NUMBER/comments/$COMMENT_ID/replies" \
-F body="@$RESPONSE_FILE"

# Clean up
rm -f "$RESPONSE_FILE"

echo "Claude's in-line suggestion posted successfully!"
28 changes: 28 additions & 0 deletions scripts/test-sample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Example file with a few bugs for testing claude-suggest
function calculateTotal(items) {
let total = 0;
for (let i = 0; i < items.length; i++) {
// Bug 1: No null check before accessing properties
total += items[i].price * items[i].quantity;
}
return total;
}

// Bug 2: Potential division by zero
function calculateAverage(values) {
const sum = values.reduce((acc, val) => acc + val, 0);
return sum / values.length;
}

// Bug 3: No error handling
async function fetchUserData(userId) {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
return data;
}

module.exports = {
calculateTotal,
calculateAverage,
fetchUserData
};
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-suggest: Fix the bugs in the test-sample.js file