Restructure CLAUDE.md files and add path-scoped rules for monorepo (#2417)

## Summary

- Restructure CLAUDE.md hierarchy so Claude Code auto-discovers
project-specific instructions
- Delete dead `AGENTS.md` files (referenced non-existent
`.tessl/RULES.md`)
- Rename `django/aiservice/AGENTS.md` → `CLAUDE.md` for auto-discovery
- Create `js/CLAUDE.md` with package commands and gotchas
- Move PR review guidelines to `.claude/rules/pr-review.md` (auto-loaded
rule)
- Move prek workflow to `.claude/skills/fix-prek.md` (on-demand skill)
- Add path-scoped rules for Python and Next.js patterns
- Add domain glossary, service architecture diagram, and per-package
gotchas

## Test plan

- Verify `CLAUDE.md` files exist at root, `django/aiservice/`, and `js/`
- Verify no remaining references to `AGENTS.md` or `.tessl/`
- Verify `.claude/rules/` and `.claude/skills/` files are committed
This commit is contained in:
Kevin Turcios 2026-02-14 17:13:09 -05:00 committed by GitHub
parent e26a8ea486
commit 4c3deeb7b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 244 additions and 148 deletions

View file

@ -0,0 +1,11 @@
---
paths:
- "js/cf-webapp/**"
---
# Next.js Patterns (cf-webapp)
- Default to server components. Only use `"use client"` when the component needs interactivity, state, or browser-only APIs. Push client boundaries as low in the tree as possible.
- Server actions go in files with `"use server"` at the top — never define them inside client components.
- Props passed from server → client components must be JSON-serializable (no functions or class instances).
- Use the `@/*` path alias for imports, not relative paths.
- Prisma queries go in server components. Client components fetch via API or receive data as props.

View file

@ -0,0 +1,22 @@
# PR Review Guidelines
When reviewing PRs, follow these priorities:
## CRITICAL - Always comment:
- Logic errors or bugs that will cause failures
- Security vulnerabilities
- Test method names with typos (won't be discovered by test runner)
- Breaking changes without migration path
## SKIP - Don't comment on:
- Code style or formatting (we have linters for this)
- Suggestions for additional features or refactoring
- "Consider" or "might want to" suggestions
- Performance optimizations without profiling data
- Duplicate concerns (one comment per issue)
## Process:
1. Check if previous comments on same lines are now fixed - resolve those first
2. Limit to 5-7 high-signal comments per review
3. Group related issues into one comment when possible
4. If many issues exist, use a summary comment instead of 20+ inline comments

View file

@ -0,0 +1,11 @@
---
paths:
- "django/**/*.py"
---
# Python Patterns (aiservice)
- Always use `libcst` for code transformation, never `ast` (preserves formatting and comments)
- All endpoints are async — use `async def` and `asyncio.TaskGroup` for concurrency
- Use Pydantic `BaseModel` or `ninja.Schema` for all request/response types
- Use `call_llm()` from `aiservice/llm.py` for all LLM calls — never call OpenAI/Anthropic APIs directly
- Django-Ninja has no built-in exception handling — use `get_object_or_404` and custom error responses explicitly

View file

@ -0,0 +1,11 @@
# Fix Formatting & Linting (prek)
When asked to fix formatting, linting, or pre-commit issues (e.g., "fix prek", "fix formatting", "run pre-k"):
1. Run `uv run prek run --all-files` to auto-fix formatting issues
2. If prek modifies files, stage them with `git add .`
3. Commit with message: `fix: auto-format with prek`
4. Push the changes with `git push`
5. Comment on the PR confirming what was fixed
Do NOT just review the code - actually run prek and push the fixes!

View file

@ -162,7 +162,7 @@ jobs:
2. If found, UPDATE it: `gh api --method PATCH repos/${{ github.repository }}/issues/comments/<ID> -f body="<content>"`
3. If not found, CREATE: `gh pr comment ${{ github.event.pull_request.number }} --body "<content>"`
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/{}`
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 issue view:*),Bash(gh issue list:*),Bash(gh api:*),Bash(cd django/aiservice*),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-5 --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(cd django/aiservice*),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:
@ -220,7 +220,7 @@ jobs:
uses: anthropics/claude-code-action@v1
with:
use_foundry: "true"
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(cd django/aiservice*),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-5 --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(cd django/aiservice*),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:

View file

@ -1,5 +0,0 @@
# Agent Rules <!-- tessl-managed -->
@.tessl/RULES.md follow the [instructions](.tessl/RULES.md)

View file

@ -1,38 +1,44 @@
# Claude Code Instructions
@AGENTS.md
## Monorepo Structure
## PR Review Guidelines
```
codeflash-internal/
├── django/aiservice/ # Python backend — Django-Ninja API for LLM optimization
├── js/
│ ├── cf-api/ # Express API — GitHub webhooks, PR analysis, DB ops
│ ├── cf-webapp/ # Next.js 14 — Dashboard UI
│ ├── common/ # Shared library — Prisma schema, types, integrations
│ └── VSC-Extension/ # VS Code extension — in-editor optimization
├── cli/ # Java/Gradle — sample code-to-optimize for testing
├── deployment/ # Unified Docker container (on-prem) + Azure configs
└── experiments/ # R&D — Jupyter notebooks, analysis scripts
```
When reviewing PRs, follow these priorities:
## Service Architecture
### CRITICAL - Always comment:
- Logic errors or bugs that will cause failures
- Security vulnerabilities
- Test method names with typos (won't be discovered by test runner)
- Breaking changes without migration path
```
VSC-Extension / CLI → cf-api (Express, :3001) → aiservice (Django-Ninja, :8000)
cf-webapp (:3000) reads from the same PostgreSQL DB via Prisma
```
### SKIP - Don't comment on:
- Code style or formatting (we have linters for this)
- Suggestions for additional features or refactoring
- "Consider" or "might want to" suggestions
- Performance optimizations without profiling data
- Duplicate concerns (one comment per issue)
## Shared Tooling
### Process:
1. Check if previous comments on same lines are now fixed - resolve those first
2. Limit to 5-7 high-signal comments per review
3. Group related issues into one comment when possible
4. If many issues exist, use a summary comment instead of 20+ inline comments
- **Python**: Use `uv` for dependency management and script execution. Never use `pip`.
- **JavaScript**: Use `npm` for all JS packages.
- **Pre-commit**: `uv run prek run --all-files` from repo root.
## Formatting & Linting (prek)
## Git Commits
When asked to fix formatting, linting, or pre-commit issues (e.g., "fix prek", "fix formatting", "run pre-k"):
Use conventional commit format: `fix:`, `feat:`, `refactor:`, `docs:`, `test:`, `chore:`
1. Run `uv run prek run --all-files` to auto-fix formatting issues
2. If prek modifies files, stage them with `git add .`
3. Commit with message: `fix: auto-format with prek`
4. Push the changes with `git push`
5. Comment on the PR confirming what was fixed
## Glossary
Do NOT just review the code - actually run prek and push the fixes!
- **Function to Optimize** — target function for optimization
- **Optimization Candidate** — LLM-generated code that may be faster
- **Read-Write Context** — code the LLM can modify
- **Read-Only Context** — code provided as info only (not modified)
- **Tracer** — collects input args for a Python function at runtime
- **Replay Test** — reruns traced inputs to verify behavior
- **Inspired Regression Test** — new tests generated by the LLM from existing tests + function code
- **Comparator** — compares two Python objects for equality

View file

@ -1,114 +0,0 @@
# AGENTS.md
This file provides guidance to AI agents working with code in this repository.
## Project Overview
Django-Ninja backend powering CodeFlash's AI-driven code optimization. Handles LLM interactions, test generation, and optimization workflows.
## Commands
```bash
# Install dependencies (NEVER use pip)
uv sync
uv sync --group dev
# Run development server
uv run uvicorn aiservice.asgi:application --reload
# Run all tests
uv run pytest
# Run a single test file
uv run pytest tests/optimizer/test_optimizer.py
# Run a specific test
uv run pytest tests/optimizer/test_optimizer.py::test_function_name -v
# Type checking
uv run mypy .
uv run ty check
# Linting (auto-fixes enabled)
uv run ruff check .
uv run ruff format .
```
## Architecture
### API Structure
All REST endpoints use Django-Ninja with type-safe Pydantic schemas. APIs are defined in `aiservice/urls.py`:
- `/ai/optimize` - Code optimization (core/languages/python/optimizer/optimizer.py)
- `/ai/testgen` - Test generation (core/languages/python/testgen/testgen.py)
- `/ai/refinement` - Iterative refinement (core/languages/python/optimizer/refinement.py)
- `/ai/rank` - Optimization ranking (core/shared/ranker/ranker.py)
- `/ai/explain` - Code explanations (core/languages/python/explanations/explanations.py)
- `/ai/code_repair` - Code repair (core/languages/python/code_repair/code_repair.py)
- `/ai/adaptive_optimize` - Adaptive optimization (core/languages/python/adaptive_optimizer/adaptive_optimizer.py)
- `/ai/workflow-gen` - GitHub Actions workflow generation (core/shared/workflow_gen/workflow_gen.py)
- `/ai/rewrite_jit` - JIT rewrite (core/languages/python/jit_rewrite/jit_rewrite.py)
- `/ai/optimization_review` - Optimization review (core/languages/python/optimization_review/optimization_review.py)
- `/ai/log_features` - Feature logging (core/log_features/log_features.py)
- `/ai/optimize-line-profiler` - Line profiler optimization (core/languages/python/optimizer/optimizer_line_profiler.py)
### LLM Module (`aiservice/llm.py`)
Unified interface for all LLM calls. Always use this instead of direct API calls:
```python
from aiservice.llm import call_llm, OPTIMIZE_MODEL, LLMResponse
response: LLMResponse = await call_llm(
llm=OPTIMIZE_MODEL,
messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}],
call_type="optimization",
trace_id=trace_id,
)
```
Model assignments are configured at the bottom of `llm.py`. Supports both OpenAI and Anthropic via Azure.
### Prompt Files
LLM prompts are stored as `.md` files alongside their modules:
- `optimizer/system_prompt.md`, `optimizer/user_prompt.md`
- `testgen/execute_system_prompt.md`, `testgen/execute_user_prompt.md`
- `code_repair/CODE_REPAIR_SYSTEM_PROMPT.md`
### Middleware Stack (`aiservice/middleware/`)
- `healthcheck.py` - Health check endpoint
- `auth_middleware.py` - API authentication
- `rate_limit.py` - Rate limiting
- `track_usage_middleware.py` - Usage tracking
### Observability (`aiservice/observability/`)
- `logger.py` - Logging utilities
- `database.py` - Records LLM calls for tracing
- Sentry integration for error tracking (production only)
## Key Patterns
### Use libcst for code manipulation
Always use `libcst` (not `ast`) to preserve formatting when modifying code.
### Use Pydantic for schemas
All request/response models use Pydantic BaseModel or ninja.Schema.
### Async endpoints
Most API endpoints are async. Use `asyncio.TaskGroup` for concurrent operations.
### Context classes
Optimizer and testgen use context classes (`BaseOptimizerContext`, `BaseTestGenContext`) to manage state and prompts.
## Code Style
- **Line length**: 120 characters
- **Python**: 3.12+ syntax
- **Tooling**: Ruff (linting/formatting), mypy (strict mode), ty (type checker)
- **Comments**: Minimal - explain "why", not "what"
- **Docstrings**: Don't add unless explicitly requested
## Git Commits
Use conventional commit format: `fix:`, `feat:`, `refactor:`, `docs:`, `test:`, `chore:`
# Agent Rules <!-- tessl-managed -->
@../../.tessl/RULES.md follow the [instructions](../../.tessl/RULES.md)

View file

@ -0,0 +1,73 @@
# AIService — Claude Code Instructions
## Project Overview
Django-Ninja backend powering CodeFlash's AI-driven code optimization. Handles LLM interactions, test generation, and optimization workflows. Runs under ASGI via uvicorn — all endpoints must be `async def`.
## Commands
```bash
# Install dependencies
uv sync
uv sync --group dev
# Run development server
uv run uvicorn aiservice.asgi:application --reload
# Run all tests
uv run pytest
# Run a single test file
uv run pytest tests/optimizer/test_optimizer.py
# Run a specific test
uv run pytest tests/optimizer/test_optimizer.py::test_function_name -v
# Type checking
uv run mypy .
uv run ty check
# Linting (auto-fixes enabled)
uv run ruff check .
uv run ruff format .
```
## Architecture
All REST endpoints use Django-Ninja with type-safe Pydantic schemas. APIs are defined in `aiservice/urls.py`. Always use `aiservice/llm.py` for LLM calls — never call provider APIs directly.
LLM prompts are stored as `.md` files alongside their modules (e.g., `optimizer/system_prompt.md`).
### Multi-Language Handler System
`core/languages/` has per-language modules (python, js_ts, java) that register handlers via `core/registry`. Each handler implements protocols from `core/protocols/`. Routers in `core/shared/` dispatch to the correct handler based on the `language` field in the request schema.
To add a new language: create a handler in `core/languages/<lang>/`, register it in `__init__.py`, implement the required protocol methods.
## Key Patterns
- **libcst, not ast**: Always use `libcst` to preserve formatting when modifying code.
- **Pydantic schemas**: All request/response models use Pydantic BaseModel or ninja.Schema.
- **Async + TaskGroup**: Most endpoints are async. Use `asyncio.TaskGroup` for concurrent operations.
- **Context classes**: Optimizer and testgen use context classes (`BaseOptimizerContext`, `BaseTestGenContext`) to manage state and prompts.
- **Lazy imports in routers**: Routers use imports inside function bodies to avoid circular dependencies.
## Django-Ninja Gotchas
- No automatic exception handling like DRF — use `get_object_or_404` explicitly.
- Error handling requires custom code (no built-in exception-to-response mapping).
- Auth: `HttpBearer` must come before `django_auth` in auth lists to avoid CSRF errors.
## Testing
- Tests live in `tests/` organized by feature: `optimizer/`, `testgen/`, `integration/`, `validators/`
- Root `conftest.py` for shared fixtures
- Use `@pytest.mark.asyncio` for async endpoint tests
- Helper factories in test files: `create_optimizer_context()`, `create_refiner_context()`
## Code Style
- **Line length**: 120 characters
- **Python**: 3.12+ syntax
- **Comments**: Minimal — explain "why", not "what"
- **Docstrings**: Don't add unless explicitly requested

81
js/CLAUDE.md Normal file
View file

@ -0,0 +1,81 @@
# JS Packages — Claude Code Instructions
## Overview
Four TypeScript packages. All use ESLint + Prettier. Run commands from each package directory.
## Commands
### cf-api (Express API — GitHub webhooks, PR analysis, DB ops)
```bash
npm run dev # Development server
npm run build # Compile TypeScript
npm test # Jest tests
npm run lint # ESLint
npm run type-check # TypeScript check
npm run format # Prettier format
npm run prisma:generate # Generate Prisma client
npm run prisma:migrate # Run DB migrations
```
### cf-webapp (Next.js dashboard UI)
```bash
npm run dev # Next.js dev server
npm run build # Production build
npm test # Vitest tests
npm run lint # ESLint
npm run type-check # TypeScript check
npm run format # Prettier format
```
### common (Shared Prisma schema, types, integrations)
```bash
npm run build # Generate Prisma + compile TypeScript
npm run clean # Remove dist/
npm run format # Prettier format
```
### VSC-Extension (VS Code extension for in-editor optimization)
```bash
npm run dev # Watch mode (esbuild + tsc)
npm run build # Full build (type-check + lint + bundle)
npm run package # Production VSIX build
npm test # VS Code test runner
npm run lint # ESLint
npm run check-types # TypeScript check
npm run format # Prettier format
```
## Key Patterns
- **Prisma schema** lives in `common/` and is shared by `cf-api` and `cf-webapp`
- **TypeScript** is used in all packages. `cf-webapp` and `VSC-Extension` use strict mode.
- **Formatting**: Prettier for all JS/TS code, ESLint for linting
## Inter-Package Dependencies
`common` is published to GitHub Packages as `@codeflash-ai/common`. Both `cf-api` and `cf-webapp` depend on it for Prisma client and shared types. `common` uses **CommonJS** (not ESM) — use `require`-style imports when working with it directly.
## Package-Specific Gotchas
### cf-api
- Webhook routes MUST be registered before body parser (need raw body for signature verification)
- `instrument.ts` must be imported first in entry point (Sentry initialization)
- Tests use dependency injection: `setXxxDependencies()` / `resetXxxDependencies()` per endpoint
### cf-webapp
- Default to server components. Only add `"use client"` for interactivity, state, or browser-only APIs.
- Path alias: `@/*` maps to `./src/*` — use it instead of relative paths
- Tree-sitter WASM files in `public/` are built by `postinstall` — don't delete them
- `@codeflash-ai/common` must be in `transpilePackages` (uses top-level await)
### common
- Prisma schema is in `prisma/schema.prisma`, not `src/`
- Must run `npx prisma generate` before using — this is done automatically in the build script
### VSC-Extension
- **Different prettier config**: 80 width + semicolons (vs 100/no-semi in other packages)
- Uses npm workspaces for local `@codeflash/*` packages (types, shared, sidebar-webview)
- Sidebar is a separate Vite/React app embedded via webview postMessage
- `acquireVsCodeApi()` can only be called once per session — store and reuse the reference
- esbuild excludes `vscode` module from bundle (it's provided by the runtime)