Skip to content

Commit 202bdc4

Browse files
Merge branch 'main' into fix/js-jest30-loop-runner
Resolved conflicts by: 1. Accepting origin/main's refactored verify_requirements() in support.py - Uses centralized find_node_modules_with_package() from init_javascript.py - Cleaner monorepo dependency detection 2. Accepting origin/main's refactored Jest parsing in parse_test_output.py - Jest-specific parsing moved to new codeflash/languages/javascript/parse.py - parse_test_xml() now routes to _parse_jest_test_xml() for JavaScript 3. Fixed TestType.GENERATED_PERFORMANCE bug in new parse.py - Changed to TestType.GENERATED_REGRESSION (performance tests are regression tests) - This was part of the original fixes in this branch The merge preserves all the infrastructure fixes from this branch while adopting the cleaner code organization from main. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2 parents 6c74adc + 6fc2c17 commit 202bdc4

9 files changed

Lines changed: 775 additions & 430 deletions

File tree

.github/workflows/claude.yml

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,28 @@ jobs:
5454
PR NUMBER: ${{ github.event.pull_request.number }}
5555
EVENT: ${{ github.event.action }}
5656
57-
## STEP 1: Run pre-commit checks and fix issues
57+
## STEP 1: Run prek and mypy checks, fix issues
5858
59-
First, run `uv run prek run --from-ref origin/main` to check for linting/formatting issues on files changed in this PR.
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
6062
61-
If there are any issues:
63+
If there are prek issues:
6264
- 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+
66+
If there are mypy issues:
67+
- Fix type annotation issues (missing return types, Optional/None unions, import errors for type hints, incorrect types)
68+
- Do NOT add `type: ignore` comments - always fix the root cause
69+
70+
After fixing issues:
6371
- Stage the fixed files with `git add`
64-
- Commit with message "style: auto-fix linting issues"
72+
- Commit with message "style: auto-fix linting issues" or "fix: resolve mypy type errors" as appropriate
6573
- Push the changes with `git push`
6674
6775
Do NOT attempt to fix:
68-
- Type errors that require logic changes
69-
- Complex refactoring suggestions
70-
- Anything that could change behavior
76+
- Type errors that require logic changes or refactoring
77+
- Complex generic type issues
78+
- Anything that could change runtime behavior
7179
7280
## STEP 2: Review the PR
7381
@@ -85,7 +93,6 @@ jobs:
8593
- Only create NEW inline comments for HIGH-PRIORITY issues found in changed files.
8694
- Limit to 5-7 NEW comments maximum per review.
8795
- Use CLAUDE.md for project-specific guidance.
88-
- Use `gh pr comment` for summary-level feedback.
8996
- Use `mcp__github_inline_comment__create_inline_comment` sparingly for critical code issues only.
9097
9198
## STEP 3: Coverage analysis
@@ -122,7 +129,45 @@ jobs:
122129
- New implementations/files: Must have ≥75% test coverage
123130
- Modified code: Changed lines should be exercised by existing or new tests
124131
- No coverage regressions: Overall coverage should not decrease
125-
claude_args: '--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 issue view:*),Bash(gh issue list:*),Bash(gh api:*),Bash(uv run prek *),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"'
132+
133+
## STEP 4: Post ONE consolidated summary comment
134+
135+
CRITICAL: You must post exactly ONE summary comment containing ALL results (pre-commit, review, coverage).
136+
DO NOT post multiple separate comments. Use this format:
137+
138+
```
139+
## PR Review Summary
140+
141+
### Prek Checks
142+
[status and any fixes made]
143+
144+
### Code Review
145+
[critical issues found, if any]
146+
147+
### Test Coverage
148+
[coverage table and analysis]
149+
150+
---
151+
*Last updated: <timestamp>*
152+
```
153+
154+
To ensure only ONE comment exists:
155+
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`
156+
2. If found, UPDATE it: `gh api --method PATCH repos/${{ github.repository }}/issues/comments/<ID> -f body="<content>"`
157+
3. If not found, CREATE: `gh pr comment ${{ github.event.pull_request.number }} --body "<content>"`
158+
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/{}`
159+
160+
## STEP 5: Merge pending codeflash optimization PRs
161+
162+
Check for open optimization PRs from codeflash and merge if CI passes:
163+
164+
1. List open PRs from codeflash bot:
165+
`gh pr list --author "codeflash-ai[bot]" --state open --json number,title,headRefName`
166+
167+
2. For each optimization PR:
168+
- Check if CI is passing: `gh pr checks <number>`
169+
- If all checks pass, merge it: `gh pr merge <number> --squash --delete-branch`
170+
claude_args: '--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"'
126171
additional_permissions: |
127172
actions: read
128173
env:

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ uv run mypy codeflash/ # Type check
2424
uv run ruff check codeflash/ # Lint
2525
uv run ruff format codeflash/ # Format
2626

27-
# Pre-commit (run before committing)
28-
uv run pre-commit run --all-files
27+
# Linting (run before committing)
28+
uv run prek run --from-ref origin/main
2929

3030
# Running the CLI
3131
uv run codeflash --help
@@ -69,7 +69,7 @@ codeflash/
6969

7070
- **Line length**: 120 characters
7171
- **Python**: 3.9+ syntax
72-
- **Tooling**: Ruff for linting/formatting, mypy strict mode, pre-commit hooks
72+
- **Tooling**: Ruff for linting/formatting, mypy strict mode, prek for pre-commit checks
7373
- **Comments**: Minimal - only explain "why", not "what"
7474
- **Docstrings**: Do not add unless explicitly requested
7575
- **Naming**: NEVER use leading underscores (`_function_name`) - Python has no true private functions, use public names

codeflash/cli_cmds/init_javascript.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,32 @@ def determine_js_package_manager(project_root: Path) -> JsPackageManager:
146146
return JsPackageManager.UNKNOWN
147147

148148

149+
def find_node_modules_with_package(project_root: Path, package_name: str) -> Path | None:
150+
"""Find node_modules directory containing a specific package.
151+
152+
Searches from project_root up to filesystem root for node_modules containing
153+
the specified package. This supports monorepo setups where dependencies are
154+
hoisted to the workspace root.
155+
156+
Args:
157+
project_root: Starting directory for the search.
158+
package_name: Name of the package to look for (e.g., "jest", "vitest").
159+
160+
Returns:
161+
Path to the node_modules directory containing the package, or None if not found.
162+
163+
"""
164+
current_dir = project_root.resolve()
165+
while current_dir != current_dir.parent:
166+
node_modules = current_dir / "node_modules"
167+
if node_modules.exists():
168+
package_path = node_modules / package_name
169+
if package_path.exists():
170+
return node_modules
171+
current_dir = current_dir.parent
172+
return None
173+
174+
149175
def get_package_install_command(project_root: Path, package: str, dev: bool = True) -> list[str]:
150176
"""Get the correct install command for the project's package manager.
151177

0 commit comments

Comments
 (0)