-
Notifications
You must be signed in to change notification settings - Fork 2
195 lines (168 loc) · 7.7 KB
/
Copy pathclaude-implementation.yml
File metadata and controls
195 lines (168 loc) · 7.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# 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 }}