mirror of
https://github.com/codeflash-ai/codeflash.git
synced 2026-05-04 18:25:17 +00:00
chore: rebuild .claude config from scratch
Delete all existing .claude/ tracked files and recreate from scratch, adapting patterns from codeflash-agent. Hooks (6, up from 1): - bash-guard: blocks grep/find/cat in Bash, redirects to dedicated tools - require-read + track-read: enforces Read-before-Write/Edit - post-compact: injects git state + project conventions into compaction - post-edit-lint: runs prek on edited Python files (kept) - status-line: shows user, area, branch, dirty state Rules (10, up from 8): - New: sessions, debugging, github (from codeflash-agent) - Rewrote: code-style (absorbed source-code), git (added sizing/hygiene) - Removed: source-code (folded into code-style) Settings: permissions allowlist, attribution, includeCoAuthoredBy, full hook wiring, status line, enableAllProjectMcpServers. .gitignore: whitelist .claude/skills/ for tracking.
This commit is contained in:
parent
bb3a447191
commit
e4b1fb854b
20 changed files with 384 additions and 62 deletions
41
.claude/hooks/bash-guard.sh
Executable file
41
.claude/hooks/bash-guard.sh
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env bash
|
||||
# PreToolUse hook: Block Bash calls that should use dedicated tools.
|
||||
# Exit 0 = allow, Exit 2 = block (message on stderr).
|
||||
|
||||
INPUT=$(cat 2>/dev/null || true)
|
||||
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null || true)
|
||||
|
||||
[ -z "$COMMAND" ] && exit 0
|
||||
|
||||
# Strip leading env vars (FOO=bar cmd ...) and whitespace to get the actual command
|
||||
STRIPPED=$(echo "$COMMAND" | sed 's/^[[:space:]]*\([A-Za-z_][A-Za-z0-9_]*=[^[:space:]]*[[:space:]]*\)*//')
|
||||
FIRST_CMD=$(echo "$STRIPPED" | awk '{print $1}')
|
||||
|
||||
case "$FIRST_CMD" in
|
||||
grep|egrep|fgrep|rg)
|
||||
echo "BLOCKED: Use the Grep tool instead of \`$FIRST_CMD\`. It provides better output and permissions handling." >&2
|
||||
exit 2
|
||||
;;
|
||||
find)
|
||||
echo "BLOCKED: Use the Glob tool instead of \`find\`. Glob is faster and returns results sorted by modification time." >&2
|
||||
exit 2
|
||||
;;
|
||||
cat|head|tail)
|
||||
echo "BLOCKED: Use the Read tool instead of \`$FIRST_CMD\`. Read provides line numbers and supports images/PDFs." >&2
|
||||
exit 2
|
||||
;;
|
||||
sed)
|
||||
if echo "$COMMAND" | grep -qE '(^|[[:space:]])sed[[:space:]]+-i'; then
|
||||
echo "BLOCKED: Use the Edit tool instead of \`sed -i\`. Edit tracks changes properly." >&2
|
||||
exit 2
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# echo with file redirection (echo "..." > file)
|
||||
if echo "$STRIPPED" | grep -qE '^echo\b.*[[:space:]]>'; then
|
||||
echo "BLOCKED: Use the Write tool instead of \`echo >\`. Write provides proper file creation." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
exit 0
|
||||
49
.claude/hooks/post-compact.sh
Executable file
49
.claude/hooks/post-compact.sh
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env bash
|
||||
# PreCompact hook: Inject state preservation guidance before context compaction.
|
||||
|
||||
cd "$CLAUDE_PROJECT_DIR" 2>/dev/null || exit 0
|
||||
|
||||
STATE=""
|
||||
|
||||
BRANCH=$(git branch --show-current 2>/dev/null)
|
||||
[ -n "$BRANCH" ] && STATE="${STATE}Branch: ${BRANCH}\n"
|
||||
|
||||
DIRTY=$(git status --porcelain 2>/dev/null)
|
||||
if [ -n "$DIRTY" ]; then
|
||||
COUNT=$(echo "$DIRTY" | wc -l | tr -d ' ')
|
||||
STATE="${STATE}Uncommitted files (${COUNT}):\n${DIRTY}\n"
|
||||
fi
|
||||
|
||||
UPSTREAM=$(git rev-parse --abbrev-ref '@{upstream}' 2>/dev/null)
|
||||
if [ -n "$UPSTREAM" ]; then
|
||||
AHEAD=$(git rev-list --count "${UPSTREAM}..HEAD" 2>/dev/null)
|
||||
[ "$AHEAD" -gt 0 ] 2>/dev/null && STATE="${STATE}Unpushed commits: ${AHEAD}\n"
|
||||
fi
|
||||
|
||||
RECENT=$(git log --oneline -5 2>/dev/null)
|
||||
[ -n "$RECENT" ] && STATE="${STATE}Recent commits:\n${RECENT}\n"
|
||||
|
||||
LATEST_HANDOFF=$(ls -t "$CLAUDE_PROJECT_DIR/.claude/handoffs/"*.md 2>/dev/null | head -1)
|
||||
if [ -n "$LATEST_HANDOFF" ] && [ -f "$LATEST_HANDOFF" ]; then
|
||||
HANDOFF_CONTENT=$(head -40 "$LATEST_HANDOFF" 2>/dev/null)
|
||||
[ -n "$HANDOFF_CONTENT" ] && STATE="${STATE}\nHandoff context:\n${HANDOFF_CONTENT}\n"
|
||||
fi
|
||||
|
||||
STATE="${STATE}\nProject conventions to preserve:\n"
|
||||
STATE="${STATE}- Python 3.9+, uv for all tooling, ruff + mypy via prek\n"
|
||||
STATE="${STATE}- Verification: uv run prek (single command for lint/format/types)\n"
|
||||
STATE="${STATE}- Pre-push: uv run prek run --from-ref origin/<base>\n"
|
||||
STATE="${STATE}- Conventional commits: fix:, feat:, refactor:, test:, chore:\n"
|
||||
STATE="${STATE}- Result type: Success(value) / Failure(error), check with is_successful()\n"
|
||||
STATE="${STATE}- Language singleton: set_current_language() / current_language()\n"
|
||||
STATE="${STATE}- libcst for code transforms, ast for read-only analysis\n"
|
||||
|
||||
[ -z "$STATE" ] && exit 0
|
||||
|
||||
cat <<EOF
|
||||
{
|
||||
"systemMessage": "PRESERVE the following session state through compaction:\n$(echo -e "$STATE" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')"
|
||||
}
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
# Everyone is on macOS so this should be fine, we don't account for Windows
|
||||
set -euo pipefail
|
||||
|
||||
input=$(cat)
|
||||
|
|
@ -10,6 +9,5 @@ if [[ -z "$file_path" || ! -f "$file_path" ]]; then
|
|||
fi
|
||||
|
||||
if [[ "$file_path" == *.py ]]; then
|
||||
# First run auto-fixes formatting; second run catches real lint errors
|
||||
uv run prek --files "$file_path" 2>/dev/null || uv run prek --files "$file_path"
|
||||
fi
|
||||
|
|
|
|||
25
.claude/hooks/require-read.sh
Executable file
25
.claude/hooks/require-read.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
# PreToolUse hook: Block Write/Edit on existing files that haven't been Read first.
|
||||
# Exit 0 = allow, Exit 2 = block (message on stderr).
|
||||
|
||||
INPUT=$(cat 2>/dev/null || true)
|
||||
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)
|
||||
|
||||
[ -z "$FILE_PATH" ] && exit 0
|
||||
|
||||
# New files don't need prior reads
|
||||
[ ! -f "$FILE_PATH" ] && exit 0
|
||||
|
||||
TRACKER="$CLAUDE_PROJECT_DIR/.claude/.read-tracker"
|
||||
|
||||
if [ ! -f "$TRACKER" ]; then
|
||||
echo "BLOCKED: Read \`$(basename "$FILE_PATH")\` first before modifying it." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if grep -qxF "$FILE_PATH" "$TRACKER"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "BLOCKED: Read \`$(basename "$FILE_PATH")\` first before modifying it." >&2
|
||||
exit 2
|
||||
50
.claude/hooks/status-line.sh
Executable file
50
.claude/hooks/status-line.sh
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env bash
|
||||
# Status line: derive context from git state.
|
||||
|
||||
input=$(cat)
|
||||
project_dir=$(echo "$input" | jq -r '.workspace.project_dir')
|
||||
|
||||
user=$(whoami)
|
||||
branch=$(git -C "$project_dir" branch --show-current 2>/dev/null)
|
||||
|
||||
changed=$(git -C "$project_dir" diff --name-only HEAD 2>/dev/null)
|
||||
[ -z "$changed" ] && changed=$(git -C "$project_dir" diff --name-only 2>/dev/null)
|
||||
[ -z "$changed" ] && changed=$(git -C "$project_dir" diff --name-only --cached 2>/dev/null)
|
||||
|
||||
if [ -n "$changed" ]; then
|
||||
area=$(echo "$changed" | sed 's|/.*||' | sort | uniq -c | sort -rn | head -1 | awk '{print $2}')
|
||||
else
|
||||
area=""
|
||||
fi
|
||||
|
||||
context=""
|
||||
case "$area" in
|
||||
codeflash)
|
||||
subsystem=$(echo "$changed" | grep '^codeflash/' | sed 's|^codeflash/||; s|/.*||' | sort | uniq -c | sort -rn | head -1 | awk '{print $2}')
|
||||
[ -n "$subsystem" ] && context="editing $subsystem" ;;
|
||||
tests)
|
||||
target=$(echo "$changed" | grep '^tests/' | sed 's|^tests/||; s|/.*||' | sort -u | head -1)
|
||||
[ -n "$target" ] && context="testing $target" ;;
|
||||
.claude)
|
||||
context="configuring claude" ;;
|
||||
esac
|
||||
|
||||
if [ -z "$context" ] && [ -n "$branch" ]; then
|
||||
case "$branch" in
|
||||
feat/*|cf-*) context="building: ${branch#feat/}" ;;
|
||||
fix/*) context="fixing: ${branch#fix/}" ;;
|
||||
refactor/*) context="refactoring: ${branch#refactor/}" ;;
|
||||
test/*) context="testing: ${branch#test/}" ;;
|
||||
chore/*) context="chore: ${branch#chore/}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
dirty=""
|
||||
if [ -n "$(git -C "$project_dir" status --porcelain 2>/dev/null)" ]; then
|
||||
dirty=" *"
|
||||
fi
|
||||
|
||||
status="$user | codeflash"
|
||||
[ -n "$context" ] && status="$status | $context"
|
||||
[ -n "$branch" ] && status="$status | $branch$dirty"
|
||||
echo "$status"
|
||||
10
.claude/hooks/track-read.sh
Executable file
10
.claude/hooks/track-read.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
# PostToolUse hook: Track Read calls for the require-read guard.
|
||||
|
||||
INPUT=$(cat 2>/dev/null || true)
|
||||
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)
|
||||
|
||||
[ -z "$FILE_PATH" ] && exit 0
|
||||
|
||||
echo "$FILE_PATH" >> "$CLAUDE_PROJECT_DIR/.claude/.read-tracker"
|
||||
exit 0
|
||||
|
|
@ -4,10 +4,11 @@
|
|||
- **Python**: 3.9+ syntax
|
||||
- **Package management**: Always use `uv`, never `pip`
|
||||
- **Tooling**: Ruff for linting/formatting, mypy strict mode, prek for pre-commit checks
|
||||
- **Comments**: Minimal - only explain "why", not "what"
|
||||
- **Docstrings**: Do not add docstrings to new or changed code unless the user explicitly asks for them — not even one-liners. The codebase intentionally keeps functions self-documenting through clear naming and type annotations
|
||||
- **Types**: Match the type annotation style of surrounding code — the codebase uses annotations, so add them in new code
|
||||
- **Naming**: NEVER use leading underscores (`_function_name`) - Python has no true private functions, use public names
|
||||
- **Comments**: Minimal — only explain "why", not "what"
|
||||
- **Docstrings**: Do not add docstrings unless the user explicitly asks
|
||||
- **Types**: Match the type annotation style of surrounding code
|
||||
- **Naming**: No leading underscores (`_function_name`) — Python has no true private functions
|
||||
- **Paths**: Always use absolute paths
|
||||
- **Encoding**: Always pass `encoding="utf-8"` to `open()`, `read_text()`, `write_text()`, etc. in new or changed code — Windows defaults to `cp1252` which breaks on non-ASCII content. Don't flag pre-existing code that lacks it unless you're already modifying that line.
|
||||
- **Verification**: Use `uv run prek` to verify code — it handles ruff, ty, mypy in one pass. Don't run `ruff`, `mypy`, or `python -c "import ..."` separately; `prek` is the single verification command
|
||||
- **Encoding**: Always pass `encoding="utf-8"` to `open()`, `read_text()`, `write_text()` in new or changed code
|
||||
- **Verification**: Use `uv run prek` — it handles ruff, ty, mypy in one pass. Don't run them separately
|
||||
- **Code transforms**: Use `libcst` for code modification/transformation. `ast` is acceptable for read-only analysis
|
||||
|
|
|
|||
19
.claude/rules/debugging.md
Normal file
19
.claude/rules/debugging.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Debugging
|
||||
|
||||
## Root cause first
|
||||
|
||||
When encountering a bug, investigate the root cause. Don't patch symptoms. If you're about to add a try/except, a fallback default, or a defensive check — ask whether the real fix is upstream.
|
||||
|
||||
## Isolated testing
|
||||
|
||||
Prefer running individual test functions over full suites. Only run the full suite when explicitly asked or before pushing.
|
||||
|
||||
- Single function: `uv run pytest tests/test_foo.py::TestBar::test_baz -v`
|
||||
- Single module: `uv run pytest tests/test_foo.py -v`
|
||||
- Full suite: only when asked, or before `git push`
|
||||
|
||||
When debugging a specific endpoint or integration, test it directly instead of running the entire pipeline end-to-end.
|
||||
|
||||
## Subprocess failures
|
||||
|
||||
When a subprocess fails, always log stdout and stderr. "Exit code 1" with no output is useless.
|
||||
|
|
@ -1,19 +1,35 @@
|
|||
# Git Commits & Pull Requests
|
||||
# Git
|
||||
|
||||
## Commits
|
||||
|
||||
- Never commit, amend, or push without explicit permission
|
||||
- Don't commit intermediate states — wait until the full implementation is complete, reviewed, and explicitly approved before committing. If the user corrects direction mid-implementation, incorporate the correction before any commit
|
||||
- Always create a new branch from `main` before starting any new work — never commit directly to `main` or reuse an existing feature branch for unrelated changes
|
||||
- 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)
|
||||
- Merge for simple syncs, rebase when branches have diverged significantly
|
||||
- When committing to an external/third-party repo, follow that repo's own conventions for versioning, changelog, and CI
|
||||
- Pre-commit: Run `uv run prek` before committing — fix any issues before creating the commit
|
||||
- Pre-push: Run `uv run prek run --from-ref origin/<base>` to check all changed files against the PR base — this matches CI behavior and catches issues that per-commit prek misses. To detect the base branch: `gh pr view --json baseRefName -q .baseRefName 2>/dev/null || echo main`
|
||||
- Don't commit intermediate states — wait until the full implementation is complete and approved
|
||||
- Always create a new branch from `main` — never commit directly to `main`
|
||||
- Conventional format: `fix:`, `feat:`, `refactor:`, `docs:`, `test:`, `chore:`
|
||||
- First line: imperative verb + what changed, under 72 characters
|
||||
- Body for *why*, not *what* — the diff shows what changed
|
||||
- One purpose per commit: a bug fix, a new function, a refactor — not all three
|
||||
- A commit that adds a function also adds its tests and exports — that's one logical change
|
||||
|
||||
## Sizing
|
||||
|
||||
- Too small: renaming a variable in one commit, updating its references in another
|
||||
- Right size: adding a function with its tests, `__init__` export, and usage update
|
||||
- Too large: implementing an entire subsystem in one commit
|
||||
|
||||
## Pre-commit / Pre-push
|
||||
|
||||
- Pre-commit: Run `uv run prek` before committing
|
||||
- Pre-push: Run `uv run prek run --from-ref origin/<base>` to check all changed files against the PR base
|
||||
|
||||
## Pull Requests
|
||||
- PR titles should use conventional format
|
||||
- Keep the PR body short and straight to the point
|
||||
|
||||
- PR titles use conventional format
|
||||
- Keep the PR body short and to the point
|
||||
- If related to a Linear issue, include `CF-#` in the body
|
||||
- Branch naming: `cf-#-title` (lowercase, hyphenated), no other prefixes/suffixes
|
||||
- Branch naming: `cf-#-title` (lowercase, hyphenated)
|
||||
|
||||
## Branch Hygiene
|
||||
|
||||
- Delete feature branches locally after merging (`git branch -d <branch>`)
|
||||
- Use `/clean_gone` to prune local branches whose remote tracking branch has been deleted
|
||||
|
|
|
|||
5
.claude/rules/github.md
Normal file
5
.claude/rules/github.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# GitHub Interactions
|
||||
|
||||
ALWAYS use MCP GitHub tools (`mcp__github__*`) for GitHub operations. Check for a matching MCP tool first — only fall back to `gh` via Bash when no MCP tool exists for the operation.
|
||||
|
||||
This also applies to other MCP-connected services (Linear, Granola). MCP first, CLI second.
|
||||
|
|
@ -6,8 +6,8 @@ paths:
|
|||
# Language Support Patterns
|
||||
|
||||
- Current language is a module-level singleton in `languages/current.py` — use `set_current_language()` / `current_language()`, never pass language as a parameter through call chains
|
||||
- Use `get_language_support(identifier)` from `languages/registry.py` to get a `LanguageSupport` instance — never import language classes directly
|
||||
- New language support classes must use the `@register_language` decorator to register with the extension and language registries
|
||||
- `languages/__init__.py` uses `__getattr__` for lazy imports to avoid circular dependencies — follow this pattern when adding new exports
|
||||
- Prefer `LanguageSupport` protocol dispatch over `is_python()`/`is_javascript()` guards — remaining guards are being migrated to protocol methods
|
||||
- Use `get_language_support(identifier)` from `languages/registry.py` — never import language classes directly
|
||||
- New language support classes must use the `@register_language` decorator
|
||||
- `languages/__init__.py` uses `__getattr__` for lazy imports to avoid circular dependencies
|
||||
- Prefer `LanguageSupport` protocol dispatch over `is_python()`/`is_javascript()` guards
|
||||
- `is_javascript()` returns `True` for both JavaScript and TypeScript (still used in ~15 call sites pending migration)
|
||||
|
|
|
|||
27
.claude/rules/sessions.md
Normal file
27
.claude/rules/sessions.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Session Discipline
|
||||
|
||||
## Scope
|
||||
|
||||
One task per session. Don't mix implementation with communication drafting, transcript search, or strategic planning.
|
||||
|
||||
## Duration
|
||||
|
||||
Cap sessions at 2-3 hours. Use `/handoff` at natural breakpoints rather than letting auto-compaction degrade context.
|
||||
|
||||
- After 1 compaction: consider wrapping up the current task and handing off
|
||||
- After 3 compactions: stop, and tell the user to start a fresh session
|
||||
- Never continue past 5 compactions — context is too degraded
|
||||
|
||||
## Context preservation
|
||||
|
||||
When compacting, preserve: modified files list, current branch, test commands used, key decisions made. Use subagents for exploration to keep main context clean.
|
||||
|
||||
## No polling
|
||||
|
||||
Never poll background tasks. No `wc -l`, no `tail -f`, no `sleep` loops. Use `run_in_background` and wait for the completion notification.
|
||||
|
||||
## File read budget
|
||||
|
||||
If you've read the same file 3+ times in a session, either:
|
||||
- The session is too long and compaction destroyed your context — write a handoff
|
||||
- You're not retaining key information — write it down in your response before it compacts away
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
paths:
|
||||
- "codeflash/**/*.py"
|
||||
---
|
||||
|
||||
# Source Code Rules
|
||||
|
||||
- Use `libcst` for code modification/transformation to preserve formatting. `ast` is acceptable for read-only analysis and parsing.
|
||||
|
|
@ -4,13 +4,14 @@ paths:
|
|||
- "codeflash/**/*test*.py"
|
||||
---
|
||||
|
||||
# Testing Conventions
|
||||
# Testing
|
||||
|
||||
- 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 — do not use `tempfile.mkdtemp()`, `tempfile.TemporaryDirectory()`, or `NamedTemporaryFile`. Some existing tests still use `tempfile` but new tests must use `tmp_path`.
|
||||
- Always call `.resolve()` on Path objects before passing them to functions under test — this ensures absolute paths and resolves symlinks. Example: `source_file = (tmp_path / "example.py").resolve()`
|
||||
- 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.
|
||||
- The pytest plugin patches `time`, `random`, `uuid`, and `datetime` for deterministic test execution — never assume real randomness or real time in verification tests.
|
||||
- `conftest.py` uses an autouse fixture that calls `reset_current_language()` — tests always start with Python as the default language.
|
||||
- Full string equality for context extraction/replacement tests — no substring matching
|
||||
- Use pytest's `tmp_path` fixture — not `tempfile.mkdtemp()` or `NamedTemporaryFile`
|
||||
- Always call `.resolve()` on Path objects before passing to functions under test
|
||||
- Use `.as_posix()` when converting resolved paths to strings
|
||||
- New features and bug fixes must have test cases
|
||||
- The pytest plugin patches `time`, `random`, `uuid`, `datetime` for deterministic execution
|
||||
- `conftest.py` autouse fixture calls `reset_current_language()` — tests start with Python as default
|
||||
- Prefer running individual tests over full suites: `uv run pytest tests/test_foo.py::TestBar::test_baz -v`
|
||||
- Only run the full suite when explicitly asked or before pushing
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
# Workflow
|
||||
|
||||
## Code Changes
|
||||
- Before making any changes, outline your approach in 3-5 numbered steps. Include which repo/branch you'll work in, what commands you'll run, and what success looks like. Wait for approval before starting
|
||||
|
||||
Before making any changes, outline your approach in 3-5 numbered steps. Include which branch you'll work on, what commands you'll run, and what success looks like. Wait for approval before starting.
|
||||
|
||||
## Response Style
|
||||
- When listing items (PRs, functions, optimization targets), always provide the complete list ordered by priority on the first attempt. Do not give partial lists
|
||||
|
||||
When listing items (PRs, functions, optimization targets), provide the complete list ordered by priority on the first attempt. No partial lists.
|
||||
|
||||
## Commands
|
||||
- When running long-running commands (benchmarks, profiling, optimizers like codeflash), always run them in the foreground. Do not use background processes
|
||||
|
||||
Long-running commands (benchmarks, profiling, optimizers) always run in the foreground. Do not use background processes.
|
||||
|
||||
## Debugging
|
||||
- When claiming something is a pre-existing issue (e.g., test failures on main), verify by checking out main and running the tests before making that claim
|
||||
|
||||
When claiming something is a pre-existing issue (e.g., test failures on main), verify by checking out main and running the tests before making that claim.
|
||||
|
|
|
|||
|
|
@ -1,16 +1,96 @@
|
|||
{
|
||||
"attribution": {
|
||||
"commit": "",
|
||||
"pr": ""
|
||||
},
|
||||
"includeCoAuthoredBy": false,
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git status*)",
|
||||
"Bash(git diff*)",
|
||||
"Bash(git log*)",
|
||||
"Bash(git branch*)",
|
||||
"Bash(git show*)",
|
||||
"Bash(git fetch*)",
|
||||
"Bash(git checkout*)",
|
||||
"Bash(uv run*)",
|
||||
"Bash(uv sync*)",
|
||||
"Bash(uv pip*)",
|
||||
"Bash(prek*)",
|
||||
"Bash(make*)",
|
||||
"Bash(gh *)"
|
||||
]
|
||||
},
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/bash-guard.sh",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/require-read.sh",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Edit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/require-read.sh",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Read",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/track-read.sh",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": ".claude/hooks/post-edit-lint.sh",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/post-edit-lint.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreCompact": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/post-compact.sh",
|
||||
"timeout": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusLine": {
|
||||
"type": "command",
|
||||
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/status-line.sh"
|
||||
},
|
||||
"enableAllProjectMcpServers": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ uv run mypy --non-interactive --config-file pyproject.toml <changed_files>
|
|||
```
|
||||
|
||||
- Fix type annotation issues: missing return types, incorrect types, Optional/None unions, import errors for type hints
|
||||
- Do NOT add `# type: ignore` comments — always fix the root cause
|
||||
- Do NOT add `# type: ignore` comments -- always fix the root cause
|
||||
- Do NOT fix type errors that require logic changes, complex generic type rework, or anything that could change runtime behavior
|
||||
- Files in `mypy_allowlist.txt` are checked in CI — ensure they remain error-free
|
||||
- Files in `mypy_allowlist.txt` are checked in CI -- ensure they remain error-free
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@ When prek (pre-commit) checks fail:
|
|||
1. Run `uv run prek run` to see failures (local, checks staged files)
|
||||
2. In CI, the equivalent is `uv run prek run --from-ref origin/main`
|
||||
3. prek runs ruff format, ruff check, and mypy on changed files
|
||||
4. Fix issues in order: formatting → lint → type errors
|
||||
4. Fix issues in order: formatting -> lint -> type errors
|
||||
5. Re-run `uv run prek run` to verify all checks pass
|
||||
|
|
|
|||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -266,11 +266,12 @@ WARP.MD
|
|||
.tessl/
|
||||
tessl.json
|
||||
|
||||
# Claude Code - track shared rules, ignore local config
|
||||
# Claude Code - track shared config, ignore local state
|
||||
.claude/*
|
||||
!.claude/rules/
|
||||
!.claude/settings.json
|
||||
!.claude/hooks/
|
||||
!.claude/skills/
|
||||
!.claude/settings.json
|
||||
**/node_modules/**
|
||||
**/dist-nuitka/**
|
||||
**/.npmrc
|
||||
|
|
|
|||
21
CLAUDE.md
21
CLAUDE.md
|
|
@ -7,19 +7,22 @@ CodeFlash is an AI-powered code optimizer that automatically improves performanc
|
|||
## Optimization Pipeline
|
||||
|
||||
```
|
||||
Discovery → Ranking → Context Extraction → Test Gen + Optimization → Baseline → Candidate Evaluation → PR
|
||||
Discovery -> Ranking -> Context Extraction -> Test Gen + Optimization -> Baseline -> Candidate Evaluation -> PR
|
||||
```
|
||||
|
||||
See `.claude/rules/architecture.md` for directory mapping and entry points.
|
||||
|
||||
# Instructions
|
||||
- **Bug fix workflow** — follow these steps in order, do not skip ahead:
|
||||
1. Read the relevant code to understand the bug
|
||||
2. Write a test that reproduces the bug (run it to confirm it fails)
|
||||
3. Spawn subagents (using the Agent tool) to attempt the fix — each subagent should apply a fix and run the test to prove it passes
|
||||
4. Review the subagent results, pick the best fix, and apply it
|
||||
5. Never jump straight to writing a fix yourself — always go through steps 1-4
|
||||
- Everything that can be tested should have tests.
|
||||
## Bug Fix Workflow
|
||||
|
||||
Follow these steps in order, do not skip ahead:
|
||||
|
||||
1. Read the relevant code to understand the bug
|
||||
2. Write a test that reproduces the bug (run it to confirm it fails)
|
||||
3. Spawn subagents (using the Agent tool) to attempt the fix — each subagent should apply a fix and run the test to prove it passes
|
||||
4. Review the subagent results, pick the best fix, and apply it
|
||||
5. Never jump straight to writing a fix yourself — always go through steps 1-4
|
||||
|
||||
Everything that can be tested should have tests.
|
||||
|
||||
<!-- Section below is auto-generated by `tessl install` - do not edit manually -->
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue