Skip to content

Commit c56b008

Browse files
authored
Merge branch 'main' into fix/test-file-pattern-matching-parent-dirs
2 parents a765b6d + 3e4a2a8 commit c56b008

51 files changed

Lines changed: 3901 additions & 774 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/rules/architecture.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Architecture
2+
3+
```
4+
codeflash/
5+
├── main.py # CLI entry point
6+
├── cli_cmds/ # Command handling, console output (Rich)
7+
├── discovery/ # Find optimizable functions
8+
├── context/ # Extract code dependencies and imports
9+
├── optimization/ # Generate optimized code via AI
10+
│ ├── optimizer.py # Main optimization orchestration
11+
│ └── function_optimizer.py # Per-function optimization logic
12+
├── verification/ # Run deterministic tests (pytest plugin)
13+
├── benchmarking/ # Performance measurement
14+
├── github/ # PR creation
15+
├── api/ # AI service communication
16+
├── code_utils/ # Code parsing, git utilities
17+
├── models/ # Pydantic models and types
18+
├── languages/ # Multi-language support (Python, JavaScript/TypeScript)
19+
├── setup/ # Config schema, auto-detection, first-run experience
20+
├── picklepatch/ # Serialization/deserialization utilities
21+
├── tracing/ # Function call tracing
22+
├── tracer.py # Root-level tracer entry point for profiling
23+
├── lsp/ # IDE integration (Language Server Protocol)
24+
├── telemetry/ # Sentry, PostHog
25+
├── either.py # Functional Result type for error handling
26+
├── result/ # Result types and handling
27+
└── version.py # Version information
28+
```

.claude/rules/code-style.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Code Style
2+
3+
- **Line length**: 120 characters
4+
- **Python**: 3.9+ syntax
5+
- **Tooling**: Ruff for linting/formatting, mypy strict mode, prek for pre-commit checks
6+
- **Comments**: Minimal - only explain "why", not "what"
7+
- **Docstrings**: Do not add unless explicitly requested
8+
- **Naming**: NEVER use leading underscores (`_function_name`) - Python has no true private functions, use public names
9+
- **Paths**: Always use absolute paths, handle encoding explicitly (UTF-8)

.claude/rules/git.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Git Commits & Pull Requests
2+
3+
- Use conventional commit format: `fix:`, `feat:`, `refactor:`, `docs:`, `test:`, `chore:`
4+
- Keep commits atomic - one logical change per commit
5+
- Commit message body should be concise (1-2 sentences max)
6+
- PR titles should also use conventional format

.claude/rules/source-code.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
paths:
3+
- "codeflash/**/*.py"
4+
---
5+
6+
# Source Code Rules
7+
8+
- Use `libcst` for code modification/transformation to preserve formatting. `ast` is acceptable for read-only analysis and parsing.
9+
- NEVER use leading underscores for function names (e.g., `_helper`). Python has no true private functions. Always use public names.
10+
- Any new feature or bug fix that can be tested automatically must have test cases.
11+
- If changes affect existing test expectations, update the tests accordingly. Tests must always pass after changes.

.claude/rules/testing.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
paths:
3+
- "tests/**"
4+
- "codeflash/**/*test*.py"
5+
---
6+
7+
# Testing Conventions
8+
9+
- Code context extraction and replacement tests must always assert for full string equality, no substring matching.
10+
- Use pytest's `tmp_path` fixture for temp directories (it's a `Path` object).
11+
- Write temp files inside `tmp_path`, never use `NamedTemporaryFile` (causes Windows file contention).
12+
- Always call `.resolve()` on Path objects to ensure absolute paths and resolve symlinks.
13+
- Use `.as_posix()` when converting resolved paths to strings (normalizes to forward slashes).
14+
- Any new feature or bug fix that can be tested automatically must have test cases.
15+
- If changes affect existing test expectations, update the tests accordingly. Tests must always pass after changes.

.github/workflows/claude-code-review.yml

Lines changed: 0 additions & 59 deletions
This file was deleted.

.github/workflows/claude.yml

Lines changed: 203 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: Claude Code
22

33
on:
4+
pull_request:
5+
types: [opened, synchronize, ready_for_review, reopened]
46
issue_comment:
57
types: [created]
68
pull_request_review_comment:
@@ -11,19 +13,205 @@ on:
1113
types: [submitted]
1214

1315
jobs:
14-
claude:
16+
# Automatic PR review (can fix linting issues and push)
17+
# Blocked for fork PRs to prevent malicious code execution
18+
pr-review:
1519
if: |
16-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17-
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18-
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19-
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
github.event_name == 'pull_request' &&
21+
github.actor != 'claude[bot]' &&
22+
github.event.pull_request.head.repo.full_name == github.repository
2023
runs-on: ubuntu-latest
2124
permissions:
2225
contents: write
2326
pull-requests: write
2427
issues: read
2528
id-token: write
26-
actions: read # Required for Claude to read CI results on PRs
29+
actions: read
30+
steps:
31+
- name: Checkout repository
32+
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 0
35+
ref: ${{ github.event.pull_request.head.ref }}
36+
37+
- name: Install uv
38+
uses: astral-sh/setup-uv@v6
39+
40+
- name: Install dependencies
41+
run: |
42+
uv venv --seed
43+
uv sync
44+
45+
- name: Run Claude Code
46+
id: claude
47+
uses: anthropics/claude-code-action@v1
48+
with:
49+
use_foundry: "true"
50+
use_sticky_comment: true
51+
allowed_bots: "claude[bot]"
52+
prompt: |
53+
REPO: ${{ github.repository }}
54+
PR NUMBER: ${{ github.event.pull_request.number }}
55+
EVENT: ${{ github.event.action }}
56+
57+
## STEP 1: Run prek and mypy checks, fix issues
58+
59+
First, run these checks on files changed in this PR:
60+
1. `uv run prek run --from-ref origin/main` - linting/formatting issues
61+
2. `uv run mypy <changed_files>` - type checking issues
62+
63+
If there are prek issues:
64+
- For SAFE auto-fixable issues (formatting, import sorting, trailing whitespace, etc.), run `uv run prek run --from-ref origin/main` again to auto-fix them
65+
- For issues that prek cannot auto-fix, do NOT attempt to fix them manually — report them as remaining issues in your summary
66+
67+
If there are mypy issues:
68+
- Fix type annotation issues (missing return types, Optional/None unions, import errors for type hints, incorrect types)
69+
- Do NOT add `type: ignore` comments - always fix the root cause
70+
71+
After fixing issues:
72+
- Stage the fixed files with `git add`
73+
- Commit with message "style: auto-fix linting issues" or "fix: resolve mypy type errors" as appropriate
74+
- Push the changes with `git push`
75+
76+
IMPORTANT - Verification after fixing:
77+
- After committing fixes, run `uv run prek run --from-ref origin/main` ONE MORE TIME to verify all issues are resolved
78+
- If errors remain, either fix them or report them honestly as unfixed in your summary
79+
- NEVER claim issues are fixed without verifying. If you cannot fix an issue, say so
80+
81+
Do NOT attempt to fix:
82+
- Type errors that require logic changes or refactoring
83+
- Complex generic type issues
84+
- Anything that could change runtime behavior
85+
86+
## STEP 2: Review the PR
87+
88+
${{ github.event.action == 'synchronize' && 'This is a RE-REVIEW after new commits. First, get the list of changed files in this latest push using `gh pr diff`. Review ONLY the changed files. Check ALL existing review comments and resolve ones that are now fixed.' || 'This is the INITIAL REVIEW.' }}
89+
90+
Review this PR focusing ONLY on:
91+
1. Critical bugs or logic errors
92+
2. Security vulnerabilities
93+
3. Breaking API changes
94+
4. Test failures (methods with typos that wont run)
95+
96+
IMPORTANT:
97+
- First check existing review comments using `gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments`. For each existing comment, check if the issue still exists in the current code.
98+
- If an issue is fixed, use `gh api --method PATCH repos/${{ github.repository }}/pulls/comments/COMMENT_ID -f body="✅ Fixed in latest commit"` to resolve it.
99+
- Only create NEW inline comments for HIGH-PRIORITY issues found in changed files.
100+
- Limit to 5-7 NEW comments maximum per review.
101+
- Use CLAUDE.md for project-specific guidance.
102+
- Use `mcp__github_inline_comment__create_inline_comment` sparingly for critical code issues only.
103+
104+
## STEP 3: Coverage analysis
105+
106+
Analyze test coverage for changed files:
107+
108+
1. Get the list of Python files changed in this PR (excluding tests):
109+
`git diff --name-only origin/main...HEAD -- '*.py' | grep -v test`
110+
111+
2. Run tests with coverage on the PR branch:
112+
`uv run coverage run -m pytest tests/ -q --tb=no`
113+
`uv run coverage json -o coverage-pr.json`
114+
115+
3. Get coverage for changed files only:
116+
`uv run coverage report --include="<changed_files_comma_separated>"`
117+
118+
4. Compare with main branch coverage:
119+
- Checkout main: `git checkout origin/main`
120+
- Run coverage: `uv run coverage run -m pytest tests/ -q --tb=no && uv run coverage json -o coverage-main.json`
121+
- Checkout back: `git checkout -`
122+
123+
5. Analyze the diff to identify:
124+
- NEW FILES: Files that don't exist on main (require good test coverage)
125+
- MODIFIED FILES: Files with changes (changes must be covered by tests)
126+
127+
6. Report in PR comment with a markdown table:
128+
- Coverage % for each changed file (PR vs main)
129+
- Overall coverage change
130+
- For NEW files: Flag if coverage is below 75%
131+
- For MODIFIED files: Flag if the changed lines are not covered by tests
132+
- Flag if overall coverage decreased
133+
134+
Coverage requirements:
135+
- New implementations/files: Must have ≥75% test coverage
136+
- Modified code: Changed lines should be exercised by existing or new tests
137+
- No coverage regressions: Overall coverage should not decrease
138+
139+
## STEP 4: Post ONE consolidated summary comment
140+
141+
CRITICAL: You must post exactly ONE summary comment containing ALL results (pre-commit, review, coverage).
142+
DO NOT post multiple separate comments. Use this format:
143+
144+
```
145+
## PR Review Summary
146+
147+
### Prek Checks
148+
[status and any fixes made]
149+
150+
### Code Review
151+
[critical issues found, if any]
152+
153+
### Test Coverage
154+
[coverage table and analysis]
155+
156+
---
157+
*Last updated: <timestamp>*
158+
```
159+
160+
To ensure only ONE comment exists:
161+
1. Find existing claude[bot] comment: `gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments --jq '.[] | select(.user.login == "claude[bot]") | .id' | head -1`
162+
2. If found, UPDATE it: `gh api --method PATCH repos/${{ github.repository }}/issues/comments/<ID> -f body="<content>"`
163+
3. If not found, CREATE: `gh pr comment ${{ github.event.pull_request.number }} --body "<content>"`
164+
4. Delete any OTHER claude[bot] comments to clean up duplicates: `gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments --jq '.[] | select(.user.login == "claude[bot]") | .id' | tail -n +2 | xargs -I {} gh api --method DELETE repos/${{ github.repository }}/issues/comments/{}`
165+
166+
## STEP 5: Merge pending codeflash optimization PRs
167+
168+
Check for open optimization PRs from codeflash and merge if CI passes:
169+
170+
1. List open PRs from codeflash bot:
171+
`gh pr list --author "codeflash-ai[bot]" --state open --json number,title,headRefName`
172+
173+
2. For each optimization PR:
174+
- Check if CI is passing: `gh pr checks <number>`
175+
- If all checks pass, merge it: `gh pr merge <number> --squash --delete-branch`
176+
claude_args: '--model claude-opus-4-6 --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*),Bash(gh pr checks:*),Bash(gh pr merge:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh api:*),Bash(uv run prek *),Bash(uv run mypy *),Bash(uv run coverage *),Bash(uv run pytest *),Bash(git status*),Bash(git add *),Bash(git commit *),Bash(git push*),Bash(git diff *),Bash(git checkout *),Read,Glob,Grep,Edit"'
177+
additional_permissions: |
178+
actions: read
179+
env:
180+
ANTHROPIC_FOUNDRY_API_KEY: ${{ secrets.AZURE_ANTHROPIC_API_KEY }}
181+
ANTHROPIC_FOUNDRY_BASE_URL: ${{ secrets.AZURE_ANTHROPIC_ENDPOINT }}
182+
183+
# @claude mentions (can edit and push) - restricted to maintainers only
184+
claude-mention:
185+
if: |
186+
(
187+
github.event_name == 'issue_comment' &&
188+
contains(github.event.comment.body, '@claude') &&
189+
(github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')
190+
) ||
191+
(
192+
github.event_name == 'pull_request_review_comment' &&
193+
contains(github.event.comment.body, '@claude') &&
194+
(github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') &&
195+
github.event.pull_request.head.repo.full_name == github.repository
196+
) ||
197+
(
198+
github.event_name == 'pull_request_review' &&
199+
contains(github.event.review.body, '@claude') &&
200+
(github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'COLLABORATOR') &&
201+
github.event.pull_request.head.repo.full_name == github.repository
202+
) ||
203+
(
204+
github.event_name == 'issues' &&
205+
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
206+
(github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR')
207+
)
208+
runs-on: ubuntu-latest
209+
permissions:
210+
contents: write
211+
pull-requests: write
212+
issues: read
213+
id-token: write
214+
actions: read
27215
steps:
28216
- name: Get PR head ref
29217
id: pr-ref
@@ -44,15 +232,22 @@ jobs:
44232
fetch-depth: 0
45233
ref: ${{ steps.pr-ref.outputs.ref }}
46234

235+
- name: Install uv
236+
uses: astral-sh/setup-uv@v6
237+
238+
- name: Install dependencies
239+
run: |
240+
uv venv --seed
241+
uv sync
242+
47243
- name: Run Claude Code
48244
id: claude
49245
uses: anthropics/claude-code-action@v1
50246
with:
51247
use_foundry: "true"
52-
claude_args: '--allowedTools "Read,Edit,Write,Glob,Grep,Bash(git status*),Bash(git diff*),Bash(git add *),Bash(git commit *),Bash(git push*),Bash(git log*),Bash(uv run pre-commit *),Bash(uv run ruff *),Bash(uv run pytest *),Bash(uv run mypy *),Bash(uv run coverage *),Bash(gh pr comment*),Bash(gh pr view*),Bash(gh pr diff*)"'
248+
claude_args: '--model claude-opus-4-6 --allowedTools "Read,Edit,Write,Glob,Grep,Bash(git status*),Bash(git diff*),Bash(git add *),Bash(git commit *),Bash(git push*),Bash(git log*),Bash(git merge*),Bash(git fetch*),Bash(git checkout*),Bash(git branch*),Bash(uv run prek *),Bash(prek *),Bash(uv run ruff *),Bash(uv run pytest *),Bash(uv run mypy *),Bash(uv run coverage *),Bash(gh pr comment*),Bash(gh pr view*),Bash(gh pr diff*),Bash(gh pr merge*),Bash(gh pr close*)"'
53249
additional_permissions: |
54250
actions: read
55251
env:
56252
ANTHROPIC_FOUNDRY_API_KEY: ${{ secrets.AZURE_ANTHROPIC_API_KEY }}
57253
ANTHROPIC_FOUNDRY_BASE_URL: ${{ secrets.AZURE_ANTHROPIC_ENDPOINT }}
58-

0 commit comments

Comments
 (0)