Skip to content

Claude Implementation #1059

Claude Implementation

Claude Implementation #1059

# Claude Implementation Workflow
# THE SINGLE SOURCE OF TRUTH for @claude mentions in issues and PRs
#
# This is the ONLY workflow that responds to @claude mentions.
# Uses the official anthropics/claude-code-base-action@beta to:
# - Implement issues when @claude is mentioned WITH FULL KNOWLEDGE BASE CONTEXT
# - Review PRs when @claude is mentioned
# - Create branches and push changes with proper permissions
#
# Note: Both claude[bot] and github-actions[bot] comments come from this workflow.
# The bot identity depends on the context and step being executed.
#
# KNOWLEDGE INJECTION: This workflow now aggregates and injects the full knowledge base
# into Claude's context, providing the same rich context as local /close-issue commands.
#
# Principle: subtraction-creates-value (removed duplicate workflow)
# Principle: systems-stewardship (single clear workflow to maintain)
# Principle: snowball-method (knowledge persistence and compound improvement)
name: Claude Implementation
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
claude-assistant:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
steps:
- name: Acknowledge request
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
try {
// Add appropriate reaction based on context
let reaction;
if (context.payload.issue && !context.payload.issue.pull_request) {
// 🚀 = Claude is implementing (for issues)
reaction = 'rocket';
} else {
// 👀 = Claude is reviewing (for PRs)
reaction = 'eyes';
}
const reactionResponse = await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: reaction
});
console.log(`✅ Successfully added ${reaction} reaction to comment ${context.payload.comment.id}`);
} catch (error) {
console.error(`❌ Failed to add reaction: ${error.message}`);
console.error(`Comment ID: ${context.payload.comment.id}`);
console.error(`Repository: ${context.repo.owner}/${context.repo.repo}`);
// Don't fail the workflow if reaction fails
// The implementation should still proceed
}
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup environment dependencies
run: |
echo "Setting up environment dependencies..."
source setup.sh # MCP setup already disabled in setup.sh for experiment #1213
- name: Aggregate knowledge base
id: knowledge
run: |
echo "Aggregating knowledge base for Claude..."
KNOWLEDGE=$(.github/scripts/aggregate-knowledge.sh)
# Use EOF delimiter to handle multi-line content
echo "content<<EOF" >> $GITHUB_OUTPUT
echo "$KNOWLEDGE" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Log size for debugging
echo "Knowledge base size: $(echo "$KNOWLEDGE" | wc -c) characters"
- name: Prepare implementation prompt
id: prepare-prompt
run: |
# Determine if this is an issue or PR
IS_ISSUE="${{ github.event.issue && !github.event.issue.pull_request }}"
if [ "$IS_ISSUE" == "true" ]; then
echo "Preparing prompt for issue implementation..."
# Get issue number (safe - just a number)
ISSUE_NUMBER="${{ github.event.issue.number }}"
# Write all values to temp files to avoid bash expansion issues
# Use heredoc for user-controlled content to prevent command injection
cat <<'KNOWLEDGE_EOF' > /tmp/knowledge.txt
${{ steps.knowledge.outputs.content }}
KNOWLEDGE_EOF
echo "$ISSUE_NUMBER" > /tmp/issue_number.txt
# SECURITY: Use heredoc to prevent command injection from issue title
cat <<'ISSUE_TITLE_EOF' > /tmp/issue_title.txt
${{ github.event.issue.title }}
ISSUE_TITLE_EOF
# SECURITY: Use heredoc to prevent command injection from issue body
cat <<'ISSUE_BODY_EOF' > /tmp/issue_body.txt
${{ github.event.issue.body }}
ISSUE_BODY_EOF
echo "${{ github.repository }}" > /tmp/repo.txt
# Load the template (now source of truth is in commands/)
TEMPLATE_FILE="commands/close-issue.md"
# Use awk to safely replace ALL placeholders in a single pass
awk '
/\{\{ KNOWLEDGE_BASE \}\}/ {
while ((getline < "/tmp/knowledge.txt") > 0) print
close("/tmp/knowledge.txt")
next
}
{
# Read replacement values only once
if (!values_read) {
getline issue_num < "/tmp/issue_number.txt"
close("/tmp/issue_number.txt")
getline issue_title < "/tmp/issue_title.txt"
close("/tmp/issue_title.txt")
getline issue_body < "/tmp/issue_body.txt"
close("/tmp/issue_body.txt")
getline repo < "/tmp/repo.txt"
close("/tmp/repo.txt")
values_read = 1
}
# Replace all placeholders in the current line
gsub(/\{\{ ISSUE_NUMBER \}\}/, issue_num)
gsub(/\{\{ ISSUE_TITLE \}\}/, issue_title)
gsub(/\{\{ ISSUE_BODY \}\}/, issue_body)
gsub(/\{\{ REPO \}\}/, repo)
print
}
' "$TEMPLATE_FILE" > /tmp/final_prompt.md
else
echo "Preparing prompt for PR review..."
# For PR reviews, write knowledge to temp file then concatenate
cat <<'KNOWLEDGE_EOF' > /tmp/knowledge.txt
${{ steps.knowledge.outputs.content }}
KNOWLEDGE_EOF
# SECURITY: Use heredoc to prevent command injection from PR comment
cat <<'COMMENT_BODY_EOF' > /tmp/comment_body.txt
${{ github.event.comment.body }}
COMMENT_BODY_EOF
# Build the PR review prompt
{
cat /tmp/knowledge.txt
echo ""
echo "## PR Review Request"
echo ""
echo "The user has requested:"
cat /tmp/comment_body.txt
echo ""
echo "Please review and respond to this pull request comment with the full context of the codebase principles and procedures available above."
} > /tmp/final_prompt.md
fi
# Log final prompt size for debugging
echo "Final prompt size: $(wc -c < /tmp/final_prompt.md) characters"
- uses: anthropics/claude-code-base-action@beta
with:
prompt_file: /tmp/final_prompt.md
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
allowed_tools: "Bash:*,LS,Read,Write,Edit,MultiEdit,Glob,Grep,Task,TodoWrite,WebFetch(domain:*),WebSearch"
timeout_minutes: "30"
model: claude-sonnet-4-5-20250929
claude_env: |
GH_TOKEN=${{ secrets.GITHUB_TOKEN }}