diff --git a/.claude/rules/architecture.md b/.claude/rules/architecture.md new file mode 100644 index 000000000..cc53dac0f --- /dev/null +++ b/.claude/rules/architecture.md @@ -0,0 +1,28 @@ +# Architecture + +``` +codeflash/ +├── main.py # CLI entry point +├── cli_cmds/ # Command handling, console output (Rich) +├── discovery/ # Find optimizable functions +├── context/ # Extract code dependencies and imports +├── optimization/ # Generate optimized code via AI +│ ├── optimizer.py # Main optimization orchestration +│ └── function_optimizer.py # Per-function optimization logic +├── verification/ # Run deterministic tests (pytest plugin) +├── benchmarking/ # Performance measurement +├── github/ # PR creation +├── api/ # AI service communication +├── code_utils/ # Code parsing, git utilities +├── models/ # Pydantic models and types +├── languages/ # Multi-language support (Python, JavaScript/TypeScript) +├── setup/ # Config schema, auto-detection, first-run experience +├── picklepatch/ # Serialization/deserialization utilities +├── tracing/ # Function call tracing +├── tracer.py # Root-level tracer entry point for profiling +├── lsp/ # IDE integration (Language Server Protocol) +├── telemetry/ # Sentry, PostHog +├── either.py # Functional Result type for error handling +├── result/ # Result types and handling +└── version.py # Version information +``` diff --git a/.claude/rules/code-style.md b/.claude/rules/code-style.md new file mode 100644 index 000000000..fcad0f253 --- /dev/null +++ b/.claude/rules/code-style.md @@ -0,0 +1,9 @@ +# Code Style + +- **Line length**: 120 characters +- **Python**: 3.9+ syntax +- **Tooling**: Ruff for linting/formatting, mypy strict mode, prek for pre-commit checks +- **Comments**: Minimal - only explain "why", not "what" +- **Docstrings**: Do not add unless explicitly requested +- **Naming**: NEVER use leading underscores (`_function_name`) - Python has no true private functions, use public names +- **Paths**: Always use absolute paths, handle encoding explicitly (UTF-8) diff --git a/.claude/rules/git.md b/.claude/rules/git.md new file mode 100644 index 000000000..058e8ca80 --- /dev/null +++ b/.claude/rules/git.md @@ -0,0 +1,6 @@ +# Git Commits & Pull Requests + +- Use conventional commit format: `fix:`, `feat:`, `refactor:`, `docs:`, `test:`, `chore:` +- Keep commits atomic - one logical change per commit +- Commit message body should be concise (1-2 sentences max) +- PR titles should also use conventional format diff --git a/.claude/rules/source-code.md b/.claude/rules/source-code.md new file mode 100644 index 000000000..27c939642 --- /dev/null +++ b/.claude/rules/source-code.md @@ -0,0 +1,11 @@ +--- +paths: + - "codeflash/**/*.py" +--- + +# Source Code Rules + +- Use `libcst` for code modification/transformation to preserve formatting. `ast` is acceptable for read-only analysis and parsing. +- NEVER use leading underscores for function names (e.g., `_helper`). Python has no true private functions. Always use public names. +- Any new feature or bug fix that can be tested automatically must have test cases. +- If changes affect existing test expectations, update the tests accordingly. Tests must always pass after changes. diff --git a/.claude/rules/testing.md b/.claude/rules/testing.md new file mode 100644 index 000000000..809a4ea91 --- /dev/null +++ b/.claude/rules/testing.md @@ -0,0 +1,15 @@ +--- +paths: + - "tests/**" + - "codeflash/**/*test*.py" +--- + +# Testing Conventions + +- Code context extraction and replacement tests must always assert for full string equality, no substring matching. +- Use pytest's `tmp_path` fixture for temp directories (it's a `Path` object). +- Write temp files inside `tmp_path`, never use `NamedTemporaryFile` (causes Windows file contention). +- Always call `.resolve()` on Path objects to ensure absolute paths and resolve symlinks. +- Use `.as_posix()` when converting resolved paths to strings (normalizes to forward slashes). +- Any new feature or bug fix that can be tested automatically must have test cases. +- If changes affect existing test expectations, update the tests accordingly. Tests must always pass after changes. diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 2c249bad7..5c89e6ea7 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -62,6 +62,7 @@ jobs: If there are prek issues: - 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 + - For issues that prek cannot auto-fix, do NOT attempt to fix them manually — report them as remaining issues in your summary If there are mypy issues: - Fix type annotation issues (missing return types, Optional/None unions, import errors for type hints, incorrect types) @@ -72,6 +73,11 @@ jobs: - Commit with message "style: auto-fix linting issues" or "fix: resolve mypy type errors" as appropriate - Push the changes with `git push` + IMPORTANT - Verification after fixing: + - After committing fixes, run `uv run prek run --from-ref origin/main` ONE MORE TIME to verify all issues are resolved + - If errors remain, either fix them or report them honestly as unfixed in your summary + - NEVER claim issues are fixed without verifying. If you cannot fix an issue, say so + Do NOT attempt to fix: - Type errors that require logic changes or refactoring - Complex generic type issues @@ -167,7 +173,7 @@ jobs: 2. For each optimization PR: - Check if CI is passing: `gh pr checks ` - If all checks pass, merge it: `gh pr merge --squash --delete-branch` - 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"' + 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"' additional_permissions: | actions: read env: @@ -239,7 +245,7 @@ jobs: uses: anthropics/claude-code-action@v1 with: use_foundry: "true" - 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(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*)"' + 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*)"' additional_permissions: | actions: read env: diff --git a/.gitignore b/.gitignore index 99219de86..b80ab3816 100644 --- a/.gitignore +++ b/.gitignore @@ -258,6 +258,10 @@ WARP.MD .mcp.json .tessl/ tessl.json + +# Claude Code - track shared rules, ignore local config +.claude/* +!.claude/rules/ **/node_modules/** **/dist-nuitka/** **/.npmrc diff --git a/CLAUDE.md b/CLAUDE.md index 94ca7e6e0..fdc1b943b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,55 +33,6 @@ uv run codeflash init # Initialize in a project uv run codeflash --all # Optimize entire codebase ``` -## Architecture - -``` -codeflash/ -├── main.py # CLI entry point -├── cli_cmds/ # Command handling, console output (Rich) -├── discovery/ # Find optimizable functions -├── context/ # Extract code dependencies and imports -├── optimization/ # Generate optimized code via AI -│ ├── optimizer.py # Main optimization orchestration -│ └── function_optimizer.py # Per-function optimization logic -├── verification/ # Run deterministic tests (pytest plugin) -├── benchmarking/ # Performance measurement -├── github/ # PR creation -├── api/ # AI service communication -├── code_utils/ # Code parsing, git utilities -├── models/ # Pydantic models and types -├── tracing/ # Function call tracing -├── lsp/ # IDE integration (Language Server Protocol) -├── telemetry/ # Sentry, PostHog -├── either.py # Functional Result type for error handling -└── result/ # Result types and handling -``` - -### Key Rules to follow - -- Use libcst, not ast - For Python, always use `libcst` for code parsing/modification to preserve formatting. -- Code context extraction and replacement tests must always assert for full string equality, no substring matching. -- Any new feature or bug fix that can be tested automatically must have test cases. -- If changes affect existing test expectations, update the tests accordingly. Tests must always pass after changes. -- NEVER use leading underscores for function names (e.g., `_helper`). Python has no true private functions. Always use public names. - -## Code Style - -- **Line length**: 120 characters -- **Python**: 3.9+ syntax -- **Tooling**: Ruff for linting/formatting, mypy strict mode, prek for pre-commit checks -- **Comments**: Minimal - only explain "why", not "what" -- **Docstrings**: Do not add unless explicitly requested -- **Naming**: NEVER use leading underscores (`_function_name`) - Python has no true private functions, use public names -- **Paths**: Always use absolute paths, handle encoding explicitly (UTF-8) - -## Git Commits & Pull Requests - -- Use conventional commit format: `fix:`, `feat:`, `refactor:`, `docs:`, `test:`, `chore:` -- Keep commits atomic - one logical change per commit -- Commit message body should be concise (1-2 sentences max) -- PR titles should also use conventional format - # Agent Rules