Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea/
.claude/
.DS_Store
.venv/
__pycache__/
Expand Down
112 changes: 65 additions & 47 deletions agents/optimizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ description: |
</example>

model: inherit
maxTurns: 15
color: cyan
tools: Read, Glob, Grep, Bash, Write, Edit, Task
---

You are a thin-wrapper agent that runs the codeflash CLI to optimize Python, Java, and JavaScript/TypeScript code.
Expand All @@ -69,23 +67,37 @@ You are a thin-wrapper agent that runs the codeflash CLI to optimize Python, Jav

Follow these steps in order:

### 0. Check API Key
### Quick Check (Fast Path)

Before anything else, check if a Codeflash API key is available:
Before running the full setup steps, run the preflight script. Use `${CLAUDE_PLUGIN_ROOT}` to locate the plugin directory:

```bash
[ -n "${CODEFLASH_API_KEY:-}" ] && [[ "${CODEFLASH_API_KEY}" == cf-* ]] && printf 'env:ok\n' || printf 'env:missing\n'; grep -l 'CODEFLASH_API_KEY.*cf-' ~/.zshrc ~/.bashrc ~/.profile ~/.kshrc ~/.cshrc ~/codeflash_env.ps1 ~/codeflash_env.bat 2>/dev/null || true
bash "${CLAUDE_PLUGIN_ROOT}/scripts/preflight.sh" <project_dir>
```

If the output contains `env:ok`, proceed to Step 1.
Where `<project_dir>` is the target project directory from the user's prompt (or the current working directory if not specified).

**Evaluate the output and skip ahead if everything is ready:**

- **API key**: `api_key=ok` means the key is set. If `missing`, go to Step 0.
- **Environment**: For Python, `venv` must not be `none` and `codeflash_path` must show a path. For JS/TS, `npx_codeflash` must show a version. For Java, `codeflash_path` must show a path. If any are missing, go to Step 2.
- **Configuration**: `python_configured=yes`, `java_configured=yes`, or `jsts_configured=yes` means config exists. If missing for the relevant project type, go to Step 3.

**If api_key=ok AND the relevant environment check passes AND config is present → skip directly to Step 4.**

Otherwise, jump to the first failing step below.

If the output contains `env:missing` but a shell RC file path was listed, source that file to load the key:
### 0. Check API Key

Before anything else, check if a Codeflash API key is available. Use the preflight output from the Quick Check — if `api_key=ok` was printed, the key is set, proceed to Step 1.

If the API key is missing, try sourcing the shell RC file and re-running the preflight:

```bash
source ~/.zshrc # or whichever file had the key
bash -c "source ~/.zshrc 2>/dev/null; bash ${CLAUDE_PLUGIN_ROOT}/scripts/preflight.sh <project_dir>"
```

Then proceed to Step 1.
If the key is now set, proceed to Step 1.

If **no API key is found anywhere**, run the OAuth login script:

Expand Down Expand Up @@ -139,21 +151,18 @@ The verification process depends on the project type determined in Step 1.

#### 2a. Python projects

First, check that a Python virtual environment is active by running `echo $VIRTUAL_ENV`.
First, check the preflight output for `venv=`. If it shows a path (not `none`), a virtual environment is already active — proceed to checking codeflash installation below.

If `$VIRTUAL_ENV` is empty or unset, **try to find and activate a virtual environment automatically**. Look for common venv directories in the project directory (from Step 1), then in the git repo root:
If `venv=none`, **try to find a virtual environment automatically** using the Glob tool. Search for `bin/activate` files in the project directory and git repo root:

```bash
# Check these directories in order, using the project directory first:
for candidate in <project_dir>/.venv <project_dir>/venv <repo_root>/.venv <repo_root>/venv; do
if [ -f "$candidate/bin/activate" ]; then
source "$candidate/bin/activate"
break
fi
done
```
- `<project_dir>/.venv/bin/activate`
- `<project_dir>/venv/bin/activate`
- `<repo_root>/.venv/bin/activate`
- `<repo_root>/venv/bin/activate`

After attempting auto-discovery, check `echo $VIRTUAL_ENV` again. If it is **still** empty or unset, **stop and inform the user**:
If found, record the venv path (the directory two levels up from `bin/activate`). You do NOT need to "activate" it — instead, use the full path to the codeflash binary: `<venv_path>/bin/codeflash`.

If no virtual environment is found anywhere, **stop and inform the user**:

> No Python virtual environment was found. Codeflash must be installed in a virtual environment.
> Please create and activate one, then install codeflash:
Expand All @@ -164,15 +173,15 @@ After attempting auto-discovery, check `echo $VIRTUAL_ENV` again. If it is **sti
> ```
> Then restart Claude Code from within the activated virtual environment.

If a virtual environment is now active, run `$VIRTUAL_ENV/bin/codeflash --version`. If it succeeds, proceed to Step 3.
Once you have a venv path (either from `$VIRTUAL_ENV` or from Glob discovery), run `<venv_path>/bin/codeflash --version`. If it succeeds, proceed to Step 3.

If it fails (exit code non-zero or command not found), codeflash is not installed in the active virtual environment. Ask the user whether they'd like to install it now:
If it fails (exit code non-zero or command not found), codeflash is not installed in the virtual environment. Ask the user whether they'd like to install it now:

```bash
pip install codeflash
<venv_path>/bin/pip install codeflash
```

If the user agrees, run the installation command in the project directory. If installation succeeds, proceed to Step 3. If the user declines or installation fails, stop.
If the user agrees, run the installation command. If installation succeeds, proceed to Step 3. If the user declines or installation fails, stop.

#### 2b. JS/TS projects

Expand Down Expand Up @@ -301,67 +310,65 @@ If no file and no `--all` flag, run codeflash without `--file` or `--all` to let

**Always `cd` to the project directory** (from Step 1) before running codeflash, so that relative paths in the config resolve correctly.

Execute the appropriate command **in the background** (`run_in_background: true`) with a **10-minute timeout** (`timeout: 600000`):
Execute the appropriate command with a **10-minute timeout**. You MUST pass `timeout: 600000` to every Bash tool call that runs codeflash. The default 2-minute Bash timeout is too short — codeflash optimization can take several minutes. Do NOT use `run_in_background: true` — the agent must wait for the command to complete so results are captured before the agent exits.

#### Python projects

Use the `run-codeflash.sh` wrapper script to cd into the project directory and run codeflash. This ensures the command is a single invocation (no `&&` chains) and matches the `Bash(*codeflash*)` permission pattern.

```bash
# Default: let codeflash detect changed files
source $VIRTUAL_ENV/bin/activate && cd <project_dir> && codeflash --subagent [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> <venv_path>/bin/codeflash --subagent [flags]

# Specific file
source $VIRTUAL_ENV/bin/activate && cd <project_dir> && codeflash --subagent --file <path> [--function <name>] [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> <venv_path>/bin/codeflash --subagent --file <path> [--function <name>] [flags]

# All files (only when explicitly requested with --all)
source $VIRTUAL_ENV/bin/activate && cd <project_dir> && codeflash --subagent --all [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> <venv_path>/bin/codeflash --subagent --all [flags]
```

If CWD is already the project directory, omit the `cd`. Always include the `source $VIRTUAL_ENV/bin/activate` prefix to ensure the virtual environment is active in the shell that runs codeflash.
Where `<venv_path>` is the virtual environment path from Step 2 (either `$VIRTUAL_ENV` if set, or the path discovered via Glob like `/path/to/project/.venv`).

#### JS/TS projects

**Important**: Codeflash must always be run from the project root (the directory containing `package.json`).

```bash
# Default: let codeflash detect changed files
cd <project_dir> && npx codeflash --subagent [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> npx codeflash --subagent [flags]

# Specific file
cd <project_dir> && npx codeflash --subagent --file <path> [--function <name>] [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> npx codeflash --subagent --file <path> [--function <name>] [flags]

# All files (only when explicitly requested with --all)
cd <project_dir> && npx codeflash --subagent --all [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> npx codeflash --subagent --all [flags]
```

If CWD is already the project directory, omit the `cd`. Use `npx codeflash` (no virtual environment activation needed).

#### Java projects

**Important**: Codeflash must be run from the project root (the directory containing `codeflash.toml` or `pom.xml`/`build.gradle`).

```bash
# Default: let codeflash detect changed files
cd <project_dir> && <codeflash_bin> --subagent [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> <codeflash_bin> --subagent [flags]

# Specific file
cd <project_dir> && <codeflash_bin> --subagent --file <path> [--function <name>] [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> <codeflash_bin> --subagent --file <path> [--function <name>] [flags]

# All files (only when explicitly requested with --all)
cd <project_dir> && <codeflash_bin> --subagent --all [flags]
bash "${CLAUDE_PLUGIN_ROOT}/scripts/run-codeflash.sh" <project_dir> <codeflash_bin> --subagent --all [flags]
```

If CWD is already the project directory, omit the `cd`. Use the binary found in Step 2c (`codeflash` or `uv run codeflash`).

**IMPORTANT**: Always use `run_in_background: true` when calling the Bash tool to execute codeflash. This allows optimization to run in the background while Claude continues other work. Tell the user "Codeflash is optimizing in the background, you'll be notified when it completes" and do not wait for the result.
Use the binary found in Step 2c (`codeflash` or `uv run codeflash`).

### 6. Report Initial Status
**IMPORTANT**: Do NOT use `run_in_background: true` for the codeflash Bash call. Run codeflash in the **foreground** with `timeout: 600000` so the agent waits for it to complete. Background execution is handled at a higher level — this agent already runs in a forked context (`context: fork`), so the user's session is not blocked. If you use `run_in_background: true` inside the agent, the background task will be killed when the agent exits.

After starting the codeflash command in the background, immediately tell the user:
1. That codeflash is optimizing in the background
2. Which files/functions are being analyzed (if specified)
3. That they'll be notified when optimization completes
### 6. Report Results

Do not wait for the background task to finish. The user will be notified automatically when the task completes with the results (optimizations found, performance improvements, PR creation status).
After codeflash completes, report:
1. Whether optimizations were found and what performance improvements were achieved
2. Which files/functions were analyzed
3. Any errors or issues encountered

## What This Agent Does NOT Do

Expand All @@ -378,3 +385,14 @@ Do not wait for the background task to finish. The user will be notified automat
- **Not configured**: Interactively ask the user for module root and tests folder, then write the config (Python/JS/TS), or run `codeflash init --yes` (Java)
- **No optimizations found**: Normal — not all code can be optimized, report this clearly
- **"Attempting to repair broken tests..."**: Normal codeflash behavior, not an error

## Return Format

You run as a subagent. Your final output is returned to the main conversation context. Keep it concise to avoid polluting the main context window.

Return ONLY a short summary:
- **Files/functions analyzed**: list them briefly
- **Result**: optimizations found (with speedups) or "no optimizations found"
- **Errors**: any issues encountered, or "none"

Do NOT include raw command output, logs, full file contents, or step-by-step narration of what you did.
19 changes: 0 additions & 19 deletions commands/setup.md

This file was deleted.

16 changes: 0 additions & 16 deletions hooks/hooks.json

This file was deleted.

20 changes: 0 additions & 20 deletions scripts/find-venv.sh

This file was deleted.

42 changes: 42 additions & 0 deletions scripts/preflight.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
# Codeflash preflight check — verifies API key, venv, and project configuration.
# Usage: bash preflight.sh <project_dir>
set -euo pipefail

project_dir="${1:-.}"

echo "=== codeflash preflight ==="

# API key
printf "api_key="
if [ -n "${CODEFLASH_API_KEY:-}" ] && [[ "${CODEFLASH_API_KEY}" == cf-* ]]; then
echo "ok"
else
echo "missing"
fi

# Virtual environment
printf "venv="
echo "${VIRTUAL_ENV:-none}"

# Git root
git_root=$(git -C "$project_dir" rev-parse --show-toplevel 2>/dev/null || true)
echo "git_root=${git_root:-unknown}"

# Codeflash binary
printf "codeflash_path="
command -v codeflash 2>/dev/null || echo "not_found"

# npx codeflash (JS/TS)
printf "npx_codeflash="
npx codeflash --version 2>/dev/null || echo "not_found"

# Config files
if [ -n "$git_root" ]; then
for f in codeflash.toml pyproject.toml package.json; do
[ -f "$git_root/$f" ] && echo "found=$f"
done
grep -q '\[tool\.codeflash\]' "$git_root/pyproject.toml" 2>/dev/null && echo "python_configured=yes" || true
grep -q '\[tool\.codeflash\]' "$git_root/codeflash.toml" 2>/dev/null && echo "java_configured=yes" || true
python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print('jsts_configured=yes' if 'codeflash' in d else '')" "$git_root/package.json" 2>/dev/null || true
fi
11 changes: 11 additions & 0 deletions scripts/run-codeflash.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
# Wrapper to cd into a project directory and run codeflash.
# Usage: bash run-codeflash.sh <project_dir> <codeflash_binary> [args...]
# Example: bash run-codeflash.sh /path/to/project /path/.venv/bin/codeflash --subagent --file src/foo.py
set -euo pipefail

project_dir="$1"
shift

cd "$project_dir"
exec "$@"
Loading
Loading