mirror of
https://github.com/codeflash-ai/codeflash.git
synced 2026-05-04 18:25:17 +00:00
docs: add comprehensive documentation for codeflash-cc-plugin
Six documents covering getting started, usage, configuration, architecture, hook lifecycle, and troubleshooting for the Claude Code plugin. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1e92f3d2ed
commit
9cc2b949cc
6 changed files with 689 additions and 0 deletions
133
docs/architecture.md
Normal file
133
docs/architecture.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# Architecture
|
||||
|
||||
This document describes the plugin's components, data flow, and internal protocols.
|
||||
|
||||
## Data flow
|
||||
|
||||
```
|
||||
User types /optimize User commits code
|
||||
| |
|
||||
v v
|
||||
SKILL.md hooks.json
|
||||
(fork context) (Stop event, * matcher)
|
||||
| |
|
||||
v v
|
||||
optimizer agent suggest-optimize.sh
|
||||
(15 turns, inherited model) (bash, 30s timeout)
|
||||
| |
|
||||
v v
|
||||
Verify env & config Detect new commits
|
||||
| with .py/.js/.ts files
|
||||
v |
|
||||
codeflash CLI v
|
||||
(background, 10min timeout) Block Claude's stop
|
||||
| with suggestion message
|
||||
v |
|
||||
Results reported Claude acts on suggestion
|
||||
to user (install / configure / run)
|
||||
```
|
||||
|
||||
## Component inventory
|
||||
|
||||
| File | Type | Purpose |
|
||||
|------|------|---------|
|
||||
| `.claude-plugin/plugin.json` | Manifest | Plugin identity, version, metadata |
|
||||
| `.claude-plugin/marketplace.json` | Manifest | Marketplace listing, owner info |
|
||||
| `skills/optimize/SKILL.md` | Skill | `/optimize` slash command definition |
|
||||
| `commands/setup.md` | Command | `/setup` slash command for auto-permissions |
|
||||
| `agents/optimizer.md` | Agent | Background optimization agent with full workflow |
|
||||
| `hooks/hooks.json` | Hook config | Registers the Stop hook |
|
||||
| `scripts/suggest-optimize.sh` | Hook script | Commit detection, dedup, project discovery |
|
||||
| `scripts/find-venv.sh` | Helper script | Python venv auto-discovery |
|
||||
|
||||
## Skill format
|
||||
|
||||
Skills use YAML frontmatter in a Markdown file:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: optimize
|
||||
description: Optimize Python, JavaScript, or TypeScript code for performance using Codeflash
|
||||
user-invocable: true
|
||||
argument-hint: "[--file] [--function] [--subagent]"
|
||||
context: fork # Forks context so optimization doesn't pollute main conversation
|
||||
agent: codeflash:optimizer # Delegates to the optimizer agent
|
||||
allowed-tools: Task
|
||||
---
|
||||
```
|
||||
|
||||
The `context: fork` setting means the skill runs in a forked context -- the optimizer agent gets its own conversation branch, keeping the main session clean.
|
||||
|
||||
## Agent format
|
||||
|
||||
Agents use YAML frontmatter followed by a system prompt:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: optimizer
|
||||
description: |
|
||||
Optimizes Python and JavaScript/TypeScript code for performance...
|
||||
model: inherit # Uses the same model as the parent conversation
|
||||
maxTurns: 15 # Maximum number of agent turns
|
||||
color: cyan # Status line color
|
||||
tools: Read, Glob, Grep, Bash, Write, Edit
|
||||
---
|
||||
```
|
||||
|
||||
The agent body contains the full workflow: project detection, environment verification, configuration setup, running codeflash, and error handling.
|
||||
|
||||
## Hook system
|
||||
|
||||
### `hooks.json` structure
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"Stop": [
|
||||
{
|
||||
"matcher": "*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/suggest-optimize.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **Event**: `Stop` -- fires every time Claude finishes a response
|
||||
- **Matcher**: `*` -- matches all stops (no filtering by tool or content)
|
||||
- **Timeout**: 30 seconds for the hook script to complete
|
||||
- **`${CLAUDE_PLUGIN_ROOT}`**: Resolved by Claude Code to the plugin's install directory
|
||||
|
||||
### Hook stdin/stdout protocol
|
||||
|
||||
**Input** (JSON on stdin):
|
||||
```json
|
||||
{
|
||||
"stop_hook_active": false,
|
||||
"transcript_path": "/path/to/transcript.jsonl"
|
||||
}
|
||||
```
|
||||
|
||||
**Output** (JSON on stdout):
|
||||
```json
|
||||
{"decision": "block", "reason": "message for Claude to act on"}
|
||||
```
|
||||
|
||||
Or no output / exit 0 to allow the stop (no blocking).
|
||||
|
||||
The `decision` field can be:
|
||||
- `"block"` -- prevents Claude from stopping, injects `reason` as a new prompt for Claude to act on
|
||||
- Absent / script exits 0 without output -- allows the stop
|
||||
|
||||
## State files
|
||||
|
||||
| File | Purpose | Lifetime |
|
||||
|------|---------|----------|
|
||||
| `/tmp/codeflash-hook-debug.log` | Debug output from the hook script (`set -x` stderr) | Persists across sessions until manually cleared |
|
||||
| `$TRANSCRIPT_DIR/codeflash-seen` | SHA-256 hashes of already-processed commit sets | Per-session (lives alongside the transcript file) |
|
||||
117
docs/configuration.md
Normal file
117
docs/configuration.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Configuration
|
||||
|
||||
This document covers all configuration surfaces: plugin manifests, project-level codeflash config, and Claude Code permissions.
|
||||
|
||||
## Plugin manifests
|
||||
|
||||
These files live in `.claude-plugin/` and define the plugin for Claude Code's plugin system. You generally don't need to modify them.
|
||||
|
||||
### `plugin.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "codeflash",
|
||||
"description": "Run codeflash as a background agent to optimize code for performance",
|
||||
"version": "0.1.10",
|
||||
"author": { "name": "Codeflash", "url": "https://codeflash.ai" },
|
||||
"repository": "https://github.com/codeflash-ai/codeflash-cc-plugin",
|
||||
"license": "MIT",
|
||||
"keywords": ["python", "javascript", "typescript", "optimization", "performance"]
|
||||
}
|
||||
```
|
||||
|
||||
### `marketplace.json`
|
||||
|
||||
Defines the plugin for the Claude Code marketplace. Contains owner info, metadata, and a `plugins` array with the same fields as `plugin.json` plus `source` (relative path) and `category`.
|
||||
|
||||
## Python project configuration
|
||||
|
||||
Codeflash reads its configuration from `[tool.codeflash]` in `pyproject.toml`.
|
||||
|
||||
### Full reference
|
||||
|
||||
```toml
|
||||
[tool.codeflash]
|
||||
# All paths are relative to this pyproject.toml's directory.
|
||||
module-root = "src" # Root of your Python module (where tests import from)
|
||||
tests-root = "tests" # Directory containing your test files
|
||||
ignore-paths = [] # Paths to exclude from optimization
|
||||
formatter-cmds = ["disabled"] # Formatter commands, or ["disabled"] to skip formatting
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Required | Default | Description |
|
||||
|-------|----------|---------|-------------|
|
||||
| `module-root` | Yes | -- | Relative path to the module root. If your tests do `from mypackage import ...`, then `mypackage/` is the module root |
|
||||
| `tests-root` | Yes | -- | Relative path to the tests directory |
|
||||
| `ignore-paths` | No | `[]` | List of paths to exclude from optimization |
|
||||
| `formatter-cmds` | No | `["disabled"]` | List of formatter commands. Each can include flags, e.g. `"black --line-length 88 {file}"`. Use `["disabled"]` to skip formatting |
|
||||
|
||||
### Auto-discovery
|
||||
|
||||
When configuration is missing, the optimizer agent discovers values automatically:
|
||||
|
||||
- **module-root**: Uses Glob and Read to find the Python package directory (the one tests import from)
|
||||
- **tests-root**: Looks for directories named `tests` or `test`, or folders containing `test_*.py` files. Falls back to `tests` (creates it if needed)
|
||||
|
||||
## JS/TS project configuration
|
||||
|
||||
Codeflash reads its configuration from a `"codeflash"` key at the root level of `package.json`.
|
||||
|
||||
### Full reference
|
||||
|
||||
```json
|
||||
{
|
||||
"codeflash": {
|
||||
"moduleRoot": "src",
|
||||
"testsRoot": "tests",
|
||||
"formatterCmds": ["disabled"],
|
||||
"ignorePaths": ["dist", "**/node_modules", "**/__tests__"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Required | Default | Description |
|
||||
|-------|----------|---------|-------------|
|
||||
| `moduleRoot` | Yes | -- | Relative path to the JS/TS module root (e.g. `.` or `src`) |
|
||||
| `testsRoot` | Yes | -- | Relative path to the tests directory |
|
||||
| `formatterCmds` | No | `["disabled"]` | Formatter commands. Use `npx` prefix for project-local tools, e.g. `"npx prettier --write {file}"` |
|
||||
| `ignorePaths` | No | `[]` | Glob patterns to exclude from optimization |
|
||||
|
||||
### Auto-discovery
|
||||
|
||||
When configuration is missing, the optimizer agent:
|
||||
|
||||
- **moduleRoot**: Inspects the project structure; typically `.` or `src`
|
||||
- **testsRoot**: Looks for `tests`, `test`, `__tests__`, or directories with `*.test.js`/`*.spec.ts` files. Falls back to `tests`
|
||||
|
||||
## Claude Code permissions
|
||||
|
||||
To allow codeflash to run without permission prompts, add the following to `.claude/settings.json` in your project root:
|
||||
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(*codeflash*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This can be set up automatically by running `/setup`.
|
||||
|
||||
### Scope options
|
||||
|
||||
The permission can be placed at different levels:
|
||||
|
||||
| File | Scope |
|
||||
|------|-------|
|
||||
| `.claude/settings.json` | Project-wide, shared with team (committed to git) |
|
||||
| `.claude/settings.local.json` | Project-wide, personal (gitignored) |
|
||||
| `~/.claude/settings.json` | User-wide, all projects |
|
||||
|
||||
The stop hook checks `.claude/settings.json` in the repo root to determine if auto-allow is already configured. If the `permissions.allow` array contains any entry matching `codeflash`, the hook skips adding auto-allow instructions to its suggestions.
|
||||
79
docs/getting-started.md
Normal file
79
docs/getting-started.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Getting Started
|
||||
|
||||
This guide walks you through installing the Codeflash Claude Code plugin and running your first optimization.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Claude Code** v2.1.38 or later
|
||||
- **Python projects**: [codeflash](https://pypi.org/project/codeflash/) installed in a virtual environment
|
||||
- **JS/TS projects**: [codeflash](https://www.npmjs.com/package/codeflash) installed as a dev dependency
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Add the marketplace and install
|
||||
|
||||
```bash
|
||||
/plugin marketplace add codeflash-ai/codeflash-cc-plugin
|
||||
/plugin install codeflash
|
||||
```
|
||||
|
||||
Or from a local clone:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/codeflash-ai/codeflash-cc-plugin.git
|
||||
/plugin marketplace add ./codeflash-cc-plugin
|
||||
/plugin install codeflash
|
||||
```
|
||||
|
||||
### 2. Choose installation scope
|
||||
|
||||
By default, plugins install at the **user** level (available across all projects). You can change this:
|
||||
|
||||
| Scope | Flag | Effect |
|
||||
|-------|------|--------|
|
||||
| User (default) | _(none)_ | Available in all your projects |
|
||||
| Project | `--scope project` | Shared with team via `.claude/settings.json` |
|
||||
| Local | `--scope local` | This project only, gitignored |
|
||||
|
||||
```bash
|
||||
/plugin install codeflash --scope project
|
||||
```
|
||||
|
||||
### 3. Verify installation
|
||||
|
||||
Run `/plugin` to open the plugin manager. Confirm **codeflash** appears under the **Installed** tab.
|
||||
|
||||
## First optimization
|
||||
|
||||
Run the `/optimize` skill with a target file:
|
||||
|
||||
```
|
||||
/optimize src/utils.py
|
||||
```
|
||||
|
||||
What happens behind the scenes:
|
||||
|
||||
1. The skill forks a background **optimizer agent**
|
||||
2. The agent walks upward from CWD to the git root, looking for `pyproject.toml` (Python) or `package.json` (JS/TS)
|
||||
3. It verifies codeflash is installed and configured
|
||||
4. If configuration is missing, it auto-discovers your module root and tests directory and writes the config for you
|
||||
5. It runs `codeflash --subagent` in the background with a 10-minute timeout
|
||||
6. Results are reported when optimization completes
|
||||
|
||||
You can continue working while codeflash optimizes in the background.
|
||||
|
||||
## Set up auto-permissions
|
||||
|
||||
Run `/setup` to allow codeflash to execute automatically without permission prompts:
|
||||
|
||||
```
|
||||
/setup
|
||||
```
|
||||
|
||||
This adds `Bash(*codeflash*)` to the `permissions.allow` array in `.claude/settings.json`. After this, the post-commit hook can trigger optimizations without asking each time.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Usage Guide](usage-guide.md) -- all commands, flags, and workflows
|
||||
- [Configuration](configuration.md) -- config reference for Python and JS/TS projects
|
||||
- [Troubleshooting](troubleshooting.md) -- common problems and fixes
|
||||
145
docs/hook-lifecycle.md
Normal file
145
docs/hook-lifecycle.md
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# Hook Lifecycle
|
||||
|
||||
Deep dive into `scripts/suggest-optimize.sh` -- the Stop hook that detects commits and suggests optimizations.
|
||||
|
||||
## When the hook fires
|
||||
|
||||
The hook fires on **every Claude stop** (every time Claude finishes a response). This is configured in `hooks/hooks.json` with a `*` matcher, meaning it runs unconditionally regardless of what Claude just did.
|
||||
|
||||
## Decision tree
|
||||
|
||||
The hook evaluates a series of conditions and takes the first matching exit path:
|
||||
|
||||
```
|
||||
1. stop_hook_active == true?
|
||||
YES -> exit 0 (allow stop, prevent infinite loop)
|
||||
|
||||
2. Not inside a git repo?
|
||||
YES -> exit 0
|
||||
|
||||
3. No transcript_path or file doesn't exist?
|
||||
YES -> exit 0
|
||||
|
||||
4. Session start time unavailable?
|
||||
YES -> exit 0
|
||||
|
||||
5. No commits with .py/.js/.ts/.jsx/.tsx files since session start?
|
||||
YES -> exit 0
|
||||
|
||||
6. Commit hash set already seen (in codeflash-seen)?
|
||||
YES -> exit 0
|
||||
|
||||
7. JS/TS project with JS changes?
|
||||
7a. Not configured -> block: set up config (+ install if needed)
|
||||
7b. Configured, not installed -> block: install codeflash
|
||||
7c. Configured + installed -> block: run codeflash
|
||||
|
||||
8. No Python changes?
|
||||
YES -> exit 0
|
||||
|
||||
9. Python project, no venv found?
|
||||
YES -> block: create venv, install, configure, run
|
||||
|
||||
10. Python project with venv:
|
||||
10a. Not configured -> block: set up config (+ install if needed)
|
||||
10b. Configured, not installed -> block: install codeflash
|
||||
10c. Configured + installed -> block: run codeflash
|
||||
```
|
||||
|
||||
Every `block` decision also appends auto-allow instructions if `Bash(*codeflash*)` is not yet in `.claude/settings.json`.
|
||||
|
||||
## Infinite loop prevention
|
||||
|
||||
When the hook blocks Claude's stop with a suggestion, Claude acts on it (e.g., runs codeflash). When Claude finishes that response, the hook fires again. To prevent an infinite loop:
|
||||
|
||||
1. Claude sets `stop_hook_active: true` in the hook input when it's responding to a previous hook block
|
||||
2. The hook checks this flag first and immediately exits if true
|
||||
|
||||
This means the hook only triggers once per "natural" Claude stop, not on stops caused by responding to hook suggestions.
|
||||
|
||||
## Session boundary detection
|
||||
|
||||
The hook needs to know when the current session started to find only commits made during this session.
|
||||
|
||||
1. It reads `transcript_path` from the hook input JSON
|
||||
2. It gets the transcript file's **birth time** (creation timestamp) using `stat`:
|
||||
- **macOS**: `stat -f %B <file>` (birth time)
|
||||
- **Linux**: `stat -c %W <file>` (birth time), falls back to `stat -c %Y` (modification time) if birth time is unavailable
|
||||
3. This timestamp becomes `SESSION_START`, used in `git log --after=@$SESSION_START`
|
||||
|
||||
## Commit detection
|
||||
|
||||
```bash
|
||||
git log --after="@$SESSION_START" --name-only --diff-filter=ACMR \
|
||||
--pretty=format: -- '*.py' '*.js' '*.ts' '*.jsx' '*.tsx'
|
||||
```
|
||||
|
||||
- `--after=@$SESSION_START` -- only commits after session start (Unix timestamp)
|
||||
- `--diff-filter=ACMR` -- Added, Copied, Modified, Renamed files only
|
||||
- `--pretty=format:` -- suppress commit metadata, show only file names
|
||||
- File patterns filter to Python and JS/TS extensions
|
||||
|
||||
The results are sorted and deduplicated. The hook also determines which language families have changes (`HAS_PYTHON_CHANGES`, `HAS_JS_CHANGES`) by grepping the file list for extension patterns.
|
||||
|
||||
## Deduplication
|
||||
|
||||
The hook prevents suggesting optimization for the same set of commits twice:
|
||||
|
||||
1. It computes the commit hashes of all matching commits:
|
||||
```bash
|
||||
git log --after="@$SESSION_START" --pretty=format:%H -- '*.py' '*.js' '*.ts' '*.jsx' '*.tsx'
|
||||
```
|
||||
2. It hashes the full list with SHA-256:
|
||||
```bash
|
||||
... | shasum -a 256 | cut -d' ' -f1
|
||||
```
|
||||
3. It checks this hash against `$TRANSCRIPT_DIR/codeflash-seen`
|
||||
4. If found, the hook exits (already processed)
|
||||
5. If not found, appends the hash and continues
|
||||
|
||||
The seen-marker file lives in the transcript directory, so it's scoped to the current session/project.
|
||||
|
||||
## Project detection (`detect_project`)
|
||||
|
||||
The `detect_project` function walks from `$PWD` upward to `$REPO_ROOT`:
|
||||
|
||||
1. At each directory level, check for `pyproject.toml` first, then `package.json`
|
||||
2. The **first** config file found determines the project type
|
||||
3. It records:
|
||||
- `PROJECT_TYPE`: `"python"` or `"js"`
|
||||
- `PROJECT_DIR`: directory containing the config file
|
||||
- `PROJECT_CONFIG_PATH`: full path to the config file
|
||||
- `PROJECT_CONFIGURED`: `"true"` if codeflash config section exists
|
||||
|
||||
For Python, it checks for `[tool.codeflash]` in `pyproject.toml`. For JS/TS, it checks for a `"codeflash"` key in `package.json` using `jq`.
|
||||
|
||||
The walk stops at `$REPO_ROOT` -- it never searches above the git repository root.
|
||||
|
||||
## Auto-allow suggestion
|
||||
|
||||
Every `block` decision checks whether codeflash is already auto-allowed:
|
||||
|
||||
```bash
|
||||
SETTINGS_JSON="$REPO_ROOT/.claude/settings.json"
|
||||
jq -e '.permissions.allow // [] | any(test("codeflash"))' "$SETTINGS_JSON"
|
||||
```
|
||||
|
||||
If no matching entry exists, the block message appends instructions to add `Bash(*codeflash*)` to `permissions.allow`. This means after the first optimization, future runs won't need permission prompts.
|
||||
|
||||
## Debug logging
|
||||
|
||||
The hook writes all debug output to `/tmp/codeflash-hook-debug.log`:
|
||||
|
||||
```bash
|
||||
LOGFILE="/tmp/codeflash-hook-debug.log"
|
||||
exec 2>>"$LOGFILE"
|
||||
set -x
|
||||
```
|
||||
|
||||
All stderr (including bash trace output from `set -x`) is appended to this file. To debug hook issues:
|
||||
|
||||
```bash
|
||||
tail -f /tmp/codeflash-hook-debug.log
|
||||
```
|
||||
|
||||
The log persists across sessions and is not automatically cleaned up.
|
||||
123
docs/troubleshooting.md
Normal file
123
docs/troubleshooting.md
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# Troubleshooting
|
||||
|
||||
## Plugin not appearing after install
|
||||
|
||||
**Symptom**: `/plugin` doesn't show codeflash in the Installed tab.
|
||||
|
||||
**Fix**:
|
||||
1. Verify the marketplace was added: `/plugin marketplace add codeflash-ai/codeflash-cc-plugin`
|
||||
2. Install again: `/plugin install codeflash`
|
||||
3. Check you're running Claude Code v2.1.38 or later
|
||||
|
||||
## `/optimize` does nothing
|
||||
|
||||
**Symptom**: Running `/optimize` produces no output or immediately returns.
|
||||
|
||||
**Possible causes**:
|
||||
- No project config found. The agent walks from CWD to the git root looking for `pyproject.toml` or `package.json`. Make sure you're inside a git repository.
|
||||
- Codeflash CLI not installed. For Python: `pip install codeflash` in your venv. For JS/TS: `npm install --save-dev codeflash`.
|
||||
- The agent is running in the background. Check if you see "Codeflash is optimizing in the background" -- results appear when the background task completes.
|
||||
|
||||
## Permission prompts every time
|
||||
|
||||
**Symptom**: Claude asks for permission to run codeflash on every invocation.
|
||||
|
||||
**Fix**: Run `/setup` to add `Bash(*codeflash*)` to `.claude/settings.json`. Or add it manually:
|
||||
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(*codeflash*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## No venv found (Python)
|
||||
|
||||
**Symptom**: Hook or agent reports "No Python virtual environment was found."
|
||||
|
||||
**Fix**:
|
||||
1. Create a venv: `python3 -m venv .venv`
|
||||
2. Activate it: `source .venv/bin/activate`
|
||||
3. Install codeflash: `pip install codeflash`
|
||||
4. Restart Claude Code from within the activated venv
|
||||
|
||||
The plugin searches for venvs in this order:
|
||||
1. `<project_dir>/.venv`
|
||||
2. `<project_dir>/venv`
|
||||
3. `<repo_root>/.venv`
|
||||
4. `<repo_root>/venv`
|
||||
|
||||
## Codeflash not installed (JS/TS)
|
||||
|
||||
**Symptom**: `npx codeflash --version` fails or package not found.
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
npm install --save-dev codeflash
|
||||
```
|
||||
|
||||
Run this in the directory containing your `package.json`.
|
||||
|
||||
## Hook not triggering after commits
|
||||
|
||||
**Symptom**: You commit Python/JS/TS files but don't see optimization suggestions.
|
||||
|
||||
**Check**:
|
||||
1. Verify the hook is registered: look for `hooks/hooks.json` in the plugin directory
|
||||
2. Check the debug log: `cat /tmp/codeflash-hook-debug.log`
|
||||
3. Ensure commits touch `.py`, `.js`, `.ts`, `.jsx`, or `.tsx` files
|
||||
4. The hook only detects commits made **during the current session** (after the transcript file was created). Commits from before starting Claude Code won't trigger it.
|
||||
|
||||
## Hook triggering repeatedly
|
||||
|
||||
**Symptom**: The hook keeps suggesting optimization for the same commits.
|
||||
|
||||
This shouldn't happen due to deduplication (the hook tracks seen commit hashes in `$TRANSCRIPT_DIR/codeflash-seen`). If it does:
|
||||
|
||||
1. Check the seen-marker file exists in the transcript directory
|
||||
2. Look at `/tmp/codeflash-hook-debug.log` for the dedup logic trace
|
||||
3. If commit hashes changed (e.g., amended commits), the hook treats them as new
|
||||
|
||||
## "Attempting to repair broken tests..."
|
||||
|
||||
This is **normal codeflash behavior**, not an error. Codeflash generates tests and sometimes needs to fix them. Let it continue.
|
||||
|
||||
## 10-minute timeout exceeded
|
||||
|
||||
**Symptom**: Codeflash background task times out.
|
||||
|
||||
This can happen on large projects or with `--all`. Options:
|
||||
- Optimize specific files instead of the entire project: `/optimize src/specific_file.py`
|
||||
- Target individual functions: `/optimize src/utils.py my_function`
|
||||
- The `--all` flag scans every function, which naturally takes longer
|
||||
|
||||
## Formatter errors
|
||||
|
||||
**Symptom**: Codeflash fails with formatter-related errors.
|
||||
|
||||
**Check**:
|
||||
1. Read the `formatter-cmds` (Python) or `formatterCmds` (JS/TS) in your config
|
||||
2. Verify each formatter is installed:
|
||||
- Python: `which black` (or whichever formatter)
|
||||
- JS/TS: `npx prettier --version` (or whichever formatter)
|
||||
3. Set `formatter-cmds = ["disabled"]` or `"formatterCmds": ["disabled"]` to skip formatting entirely
|
||||
|
||||
## Debugging the hook script manually
|
||||
|
||||
Run the hook script directly to test it:
|
||||
|
||||
```bash
|
||||
echo '{"stop_hook_active": false, "transcript_path": "/path/to/transcript.jsonl"}' | \
|
||||
bash /path/to/codeflash-cc-plugin/scripts/suggest-optimize.sh
|
||||
```
|
||||
|
||||
Check the debug log for detailed trace output:
|
||||
|
||||
```bash
|
||||
tail -100 /tmp/codeflash-hook-debug.log
|
||||
```
|
||||
|
||||
The log includes every variable and branch taken (via `set -x`), making it straightforward to trace why the hook did or didn't trigger.
|
||||
92
docs/usage-guide.md
Normal file
92
docs/usage-guide.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Usage Guide
|
||||
|
||||
## The `/optimize` skill
|
||||
|
||||
`/optimize` is the primary command. It spawns a background optimizer agent that runs the codeflash CLI on your code.
|
||||
|
||||
### Syntax
|
||||
|
||||
```
|
||||
/optimize [file] [function] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
| Command | Effect |
|
||||
|---------|--------|
|
||||
| `/optimize` | Let codeflash detect changed files automatically |
|
||||
| `/optimize src/utils.py` | Optimize all functions in `src/utils.py` |
|
||||
| `/optimize src/utils.py my_function` | Optimize only `my_function` in that file |
|
||||
| `/optimize --all` | Optimize the entire project |
|
||||
| `/optimize src/utils.py --no-pr` | Optimize without creating a PR |
|
||||
| `/optimize src/utils.py --effort high` | Set optimization effort level to high |
|
||||
|
||||
Flags can be combined: `/optimize src/utils.py my_function --no-pr --effort high`
|
||||
|
||||
### What happens behind the scenes
|
||||
|
||||
1. The skill (defined in `skills/optimize/SKILL.md`) forks context and spawns the **optimizer agent**
|
||||
2. The agent locates your project config (`pyproject.toml` or `package.json`)
|
||||
3. It verifies the codeflash CLI is installed and the project is configured
|
||||
4. It runs `codeflash --subagent` as a **background task** with a 10-minute timeout
|
||||
5. You're notified when optimization completes with results
|
||||
|
||||
The agent has up to **15 turns** to complete its work (install codeflash, configure the project, run optimization).
|
||||
|
||||
## The `/setup` command
|
||||
|
||||
`/setup` configures auto-permissions so codeflash runs without prompting.
|
||||
|
||||
### What it does
|
||||
|
||||
1. Finds `.claude/settings.json` in your project root
|
||||
2. Checks if `Bash(*codeflash*)` is already in `permissions.allow`
|
||||
3. If not, adds it (creating the file and directory if needed)
|
||||
4. Preserves any existing settings
|
||||
|
||||
Running `/setup` multiple times is safe -- it's idempotent. If permissions are already configured, it reports "No changes needed."
|
||||
|
||||
## Automatic post-commit suggestions
|
||||
|
||||
After every Claude response (the **Stop** hook), the plugin checks whether you committed Python, JS, or TS files during the current session. If so, it suggests running `/optimize`.
|
||||
|
||||
### How commit detection works
|
||||
|
||||
1. The hook determines the session start time from the transcript file's creation timestamp
|
||||
2. It queries `git log --after=@<session_start>` for commits touching `*.py`, `*.js`, `*.ts`, `*.jsx`, `*.tsx` files
|
||||
3. It deduplicates so the same commits don't trigger suggestions twice
|
||||
4. If new commits are found, it blocks Claude's stop and injects a suggestion
|
||||
|
||||
The suggestion varies depending on the project state:
|
||||
|
||||
| State | Suggestion |
|
||||
|-------|------------|
|
||||
| Configured + installed | Run `codeflash --subagent` in the background |
|
||||
| Configured, not installed | Install codeflash first, then run |
|
||||
| Not configured | Auto-discover config, write it, then run |
|
||||
| No venv (Python) | Create venv, install codeflash, configure, then run |
|
||||
|
||||
If `Bash(*codeflash*)` is not yet in `.claude/settings.json`, the suggestion also includes adding it for auto-permissions.
|
||||
|
||||
## Python-specific workflow
|
||||
|
||||
For Python projects, the optimizer agent:
|
||||
|
||||
1. Checks for an active virtual environment (`$VIRTUAL_ENV`)
|
||||
2. If none, searches for `.venv` or `venv` directories in the project dir and repo root
|
||||
3. Verifies `codeflash` is installed in the venv (`$VIRTUAL_ENV/bin/codeflash --version`)
|
||||
4. Reads `[tool.codeflash]` from `pyproject.toml` for configuration
|
||||
5. Runs: `source $VIRTUAL_ENV/bin/activate && codeflash --subagent [flags]`
|
||||
|
||||
The agent also checks `formatter-cmds` in the config and verifies formatters are installed.
|
||||
|
||||
## JS/TS-specific workflow
|
||||
|
||||
For JavaScript/TypeScript projects, the optimizer agent:
|
||||
|
||||
1. Checks codeflash is available via `npx codeflash --version`
|
||||
2. Reads the `"codeflash"` key from `package.json` for configuration
|
||||
3. Always runs from the project root (the directory containing `package.json`)
|
||||
4. Runs: `npx codeflash --subagent [flags]`
|
||||
|
||||
No virtual environment is needed -- JS/TS projects use `npx`/`npm` directly.
|
||||
Loading…
Reference in a new issue