Claude Implementation #1059
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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) | |
| } | |
| ' "$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 }} |