Skip to content

Commit a9ff297

Browse files
merge: resolve conflict with main after PR #2019 merge
Take -cp first ordering from #2019, remove --app-args and mvn exec:java, keep #2018's additions (Maven/Gradle test suites, multi-module, trace-only). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 parents e0a9ca7 + 1f69837 commit a9ff297

17 files changed

Lines changed: 193 additions & 43 deletions

File tree

codeflash/code_utils/code_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from codeflash.cli_cmds.console import logger, paneled_text
1919
from codeflash.code_utils.config_parser import find_pyproject_toml, get_all_closest_config_files
20-
from codeflash.lsp.helpers import is_LSP_enabled
20+
from codeflash.lsp.helpers import is_LSP_enabled, is_subagent_mode
2121

2222
_INVALID_CHARS_NT = {"<", ">", ":", '"', "|", "?", "*"}
2323

@@ -471,6 +471,11 @@ def exit_with_message(message: str, *, error_on_exit: bool = False) -> None:
471471
if is_LSP_enabled():
472472
logger.error(message)
473473
return
474+
if is_subagent_mode():
475+
from xml.sax.saxutils import escape
476+
477+
sys.stdout.write(f"<codeflash-error>{escape(message)}</codeflash-error>\n")
478+
sys.exit(1 if error_on_exit else 0)
474479
paneled_text(message, panel_args={"style": "red"})
475480

476481
sys.exit(1 if error_on_exit else 0)

codeflash/languages/java/gradle_strategy.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
'spotbugsMain', 'spotbugsTest',
4646
'pmdMain', 'pmdTest',
4747
'rat', 'japicmp',
48-
'jarHell', 'thirdPartyAudit'
48+
'jarHell', 'thirdPartyAudit',
49+
'spotlessCheck', 'spotlessApply', 'spotlessJava', 'spotlessKotlin', 'spotlessScala'
4950
]
5051
}.configureEach {
5152
enabled = false

codeflash/languages/java/maven_strategy.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
"-Denforcer.skip=true",
4444
"-Djapicmp.skip=true",
4545
"-Derrorprone.skip=true",
46+
"-Dspotless.check.skip=true",
47+
"-Dspotless.apply.skip=true",
4648
"-Dmaven.compiler.failOnWarning=false",
4749
"-Dmaven.compiler.showWarnings=false",
4850
]

codeflash/languages/javascript/support.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,10 @@ def get_module_path(self, source_file: Path, project_root: Path, tests_root: Pat
22682268
source_without_ext = source_file_abs.with_suffix("")
22692269

22702270
# Use os.path.relpath to compute relative path from tests_root to source file
2271-
rel_path = os.path.relpath(str(source_without_ext), str(tests_root_abs))
2271+
# Replace backslashes with forward slashes — JavaScript import/require paths
2272+
# must use forward slashes. Backslashes are escape chars in JS strings
2273+
# (e.g. \t → tab, \n → newline) and would break imports on Windows.
2274+
rel_path = os.path.relpath(str(source_without_ext), str(tests_root_abs)).replace("\\", "/")
22722275

22732276
# For ESM, add .js extension (TypeScript convention)
22742277
# TypeScript requires imports to reference the OUTPUT file extension (.js),

codeflash/languages/javascript/test_runner.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,9 @@ def _create_runtime_jest_config(base_config_path: Path | None, project_root: Pat
369369

370370
runtime_config_path = config_dir / f"jest.codeflash.runtime.config{config_ext}"
371371

372-
test_dirs_js = ", ".join(f"'{d}'" for d in sorted(test_dirs))
372+
# Normalize to forward slashes — backslashes in JS strings are escape chars
373+
# (e.g. \t → tab, \n → newline) and would corrupt paths on Windows.
374+
test_dirs_js = ", ".join(f"'{d.replace(chr(92), '/')}'" for d in sorted(test_dirs))
373375

374376
# In monorepos, add the root node_modules to moduleDirectories so Jest
375377
# can resolve workspace packages that are hoisted to the monorepo root.
@@ -382,6 +384,8 @@ def _create_runtime_jest_config(base_config_path: Path | None, project_root: Pat
382384
else:
383385
module_dirs_line_no_base = ""
384386

387+
project_root_posix = project_root.as_posix()
388+
385389
# TypeScript configs (.ts) cannot be required from CommonJS modules
386390
# because Node.js cannot parse TypeScript syntax in require().
387391
# When the base config is TypeScript, we create a standalone config
@@ -403,7 +407,7 @@ def _create_runtime_jest_config(base_config_path: Path | None, project_root: Pat
403407
else:
404408
config_content = f"""// Auto-generated by codeflash - runtime config with test roots
405409
module.exports = {{
406-
roots: ['{project_root}', {test_dirs_js}],
410+
roots: ['{project_root_posix}', {test_dirs_js}],
407411
testMatch: ['**/*.test.ts', '**/*.test.js', '**/*.test.tsx', '**/*.test.jsx'],
408412
{module_dirs_line_no_base}}};
409413
"""

codeflash/telemetry/posthog_cf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from codeflash.api.cfapi import get_user_id
99
from codeflash.cli_cmds.console import logger
10+
from codeflash.lsp.helpers import is_subagent_mode
1011
from codeflash.version import __version__
1112

1213
_posthog = None
@@ -36,7 +37,7 @@ def ph(event: str, properties: dict[str, Any] | None = None) -> None:
3637
return
3738

3839
properties = properties or {}
39-
properties.update({"cli_version": __version__})
40+
properties.update({"cli_version": __version__, "subagent": is_subagent_mode()})
4041

4142
user_id = get_user_id()
4243

codeflash/verification/coverage_utils.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,17 @@ def load_from_jest_json(
5454
return CoverageData.create_empty(source_code_path, function_name, code_context)
5555

5656
# Find the file entry in coverage data
57-
# Jest uses absolute paths as keys
57+
# Jest/Vitest always writes coverage keys with forward slashes (POSIX paths),
58+
# so we normalize our paths to POSIX for comparison — critical on Windows
59+
# where Path.resolve() and str(Path) produce backslash paths.
5860
file_coverage = None
59-
source_path_str = str(source_code_path.resolve())
61+
source_path_posix = source_code_path.resolve().as_posix()
62+
source_relative_posix = source_code_path.as_posix()
6063

6164
for file_path, file_data in coverage_data.items():
6265
# Match exact path or path ending with full relative path from src/
6366
# Avoid matching files with same name in different directories (e.g., db/utils.ts vs utils/utils.ts)
64-
if file_path == source_path_str or file_path.endswith(str(source_code_path)):
67+
if file_path == source_path_posix or file_path.endswith(source_relative_posix):
6568
file_coverage = file_data
6669
break
6770

docs/codeflash-concepts/how-codeflash-works.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ title: "How Codeflash Works"
33
description: "Understand Codeflash's generate-and-verify approach to code optimization and correctness verification"
44
icon: "gear"
55
sidebarTitle: "How It Works"
6-
keywords: ["architecture", "verification", "correctness", "testing", "optimization", "LLM", "benchmarking", "javascript", "typescript", "python"]
6+
keywords: ["architecture", "verification", "correctness", "testing", "optimization", "LLM", "benchmarking", "javascript", "typescript", "python", "java"]
77
---
88
# How Codeflash Works
99

1010
Codeflash follows a "generate and verify" approach to optimize code. It uses LLMs to generate optimizations, then it rigorously verifies if those optimizations are indeed
1111
faster and if they have the same behavior. The basic unit of optimization is a function—Codeflash tries to speed up the function, and tries to ensure that it still behaves the same way. This way if you merge the optimized code, it simply runs faster without breaking any functionality.
1212

13-
Codeflash supports **Python**, **JavaScript**, and **TypeScript** projects.
13+
Codeflash supports **Python**, **JavaScript**, **TypeScript**, and **Java** projects.
1414

1515
## Analysis of your code
1616

1717
Codeflash scans your codebase to identify all available functions. It locates existing unit tests in your projects and maps which functions they test. When optimizing a function, Codeflash runs these discovered tests to verify nothing has broken.
1818

19-
For Python, code analysis uses `libcst` and `jedi`. For JavaScript/TypeScript, it uses `tree-sitter` for AST parsing.
19+
For Python, code analysis uses `libcst` and `jedi`. For JavaScript/TypeScript and Java, it uses `tree-sitter` for AST parsing.
2020

2121
#### What kind of functions can Codeflash optimize?
2222

@@ -25,7 +25,7 @@ Codeflash supports optimizing async functions in all supported languages.
2525

2626
#### Test Discovery
2727

28-
Codeflash discovers tests that directly call the target function in their test body. For Python, it finds pytest and unittest tests. For JavaScript/TypeScript, it finds Jest and Vitest test files.
28+
Codeflash discovers tests that directly call the target function in their test body. For Python, it finds pytest and unittest tests. For JavaScript/TypeScript, it finds Jest and Vitest test files. For Java, it finds JUnit 5, JUnit 4, and TestNG test classes.
2929

3030
To discover tests that indirectly call the function, you can use the Codeflash Tracer. The Tracer analyzes your test suite and identifies all tests that eventually call a function.
3131

@@ -54,12 +54,12 @@ We recommend manually reviewing the optimized code since there might be importan
5454

5555
Codeflash generates two types of tests:
5656

57-
- **LLM Generated tests** - Codeflash uses LLMs to create several regression test cases that cover typical function usage, edge cases, and large-scale inputs to verify both correctness and performance. This works for Python, JavaScript, and TypeScript.
57+
- **LLM Generated tests** - Codeflash uses LLMs to create several regression test cases that cover typical function usage, edge cases, and large-scale inputs to verify both correctness and performance. This works for Python, JavaScript, TypeScript, and Java.
5858
- **Concolic coverage tests** - Codeflash uses state-of-the-art concolic testing with an SMT Solver (a theorem prover) to explore execution paths and generate function arguments. This aims to maximize code coverage for the function being optimized. Currently, this feature only supports Python (pytest).
5959

6060
## Code Execution
6161

62-
Codeflash runs tests for the target function on your machine. For Python, it uses pytest or unittest. For JavaScript/TypeScript, it uses Jest or Vitest. Running on your machine ensures access to your environment and dependencies, and provides accurate performance measurements since runtime varies by system.
62+
Codeflash runs tests for the target function on your machine. For Python, it uses pytest or unittest. For JavaScript/TypeScript, it uses Jest or Vitest. For Java, it uses Maven Surefire or Gradle's test task. Running on your machine ensures access to your environment and dependencies, and provides accurate performance measurements since runtime varies by system.
6363

6464
#### Performance benchmarking
6565

docs/getting-started/java-installation.mdx

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,72 @@ uv tool install codeflash
4747
```
4848

4949
</Step>
50-
<Step title="Initialize your project">
50+
<Step title="Authenticate with Codeflash">
51+
52+
Codeflash uses cloud-hosted AI models. You need to authenticate before running any commands.
53+
54+
**Option A: Browser login (recommended)**
55+
56+
```bash
57+
codeflash auth login
58+
```
59+
60+
This opens your browser to sign in with your GitHub account. Your API key is saved automatically to your shell profile.
61+
62+
If you're on a remote server without a browser, a URL will be displayed that you can open on any device.
63+
64+
**Option B: API key**
65+
66+
1. Visit the [Codeflash Web App](https://app.codeflash.ai/) and sign up with your GitHub account (free tier available)
67+
2. Navigate to the [API Key](https://app.codeflash.ai/app/apikeys) page to generate your key
68+
3. Set it as an environment variable:
69+
70+
```bash
71+
export CODEFLASH_API_KEY="your-api-key-here"
72+
```
73+
74+
Add this to your shell profile (`~/.bashrc`, `~/.zshrc`) so it persists across sessions.
75+
76+
<Info>
77+
If you skip this step, `codeflash init` will prompt you to authenticate interactively.
78+
</Info>
79+
80+
</Step>
81+
<Step title="Initialize your project (recommended)">
5182

5283
Navigate to your Java project root (where `pom.xml` or `build.gradle` is) and run:
5384

5485
```bash
5586
codeflash init
5687
```
5788

58-
This will:
59-
- Detect your build tool (Maven/Gradle)
60-
- Find your source and test directories
61-
- Write Codeflash configuration to your `pom.xml` properties (Maven) or `gradle.properties` (Gradle)
89+
The init command will:
90+
1. **Auto-detect your project** — find your build tool, source root (e.g., `src/main/java`), test root (e.g., `src/test/java`), and test framework
91+
2. **Confirm settings** — show the detected values and ask if you want to change anything
92+
3. **Configure formatter** — let you set up a code formatter (e.g., Spotless, google-java-format)
93+
4. **Install GitHub App** — offer to set up the [Codeflash GitHub App](https://github.com/apps/codeflash-ai/installations/select_target) for automatic PR creation (see next step)
94+
5. **Install GitHub Actions** — offer to add a CI workflow for automated optimization on PRs
95+
96+
Only non-default settings are written to your `pom.xml` properties (Maven) or `gradle.properties` (Gradle). For standard layouts, no config changes are needed.
97+
98+
<Info>
99+
**Can I skip init?** Yes. For standard Maven/Gradle projects, Codeflash auto-detects your project structure from `pom.xml` or `build.gradle` at runtime. If you're already authenticated and your project uses a standard layout (`src/main/java`, `src/test/java`), you can skip straight to optimizing.
100+
101+
Init is recommended because it also sets up the GitHub App and Actions workflow, and lets you override paths for non-standard project layouts (e.g., multi-module projects where source is under `client/src/`).
102+
</Info>
103+
104+
</Step>
105+
<Step title="Install the Codeflash GitHub App (recommended)">
106+
107+
To have Codeflash create pull requests with optimizations automatically, install the GitHub App:
108+
109+
[Install Codeflash GitHub App](https://github.com/apps/codeflash-ai/installations/select_target)
110+
111+
Select the repositories you want Codeflash to optimize. This allows the codeflash-ai bot to open PRs with optimization suggestions in your repository.
112+
113+
<Info>
114+
If you prefer to try Codeflash locally first, you can skip this step and use the `--no-pr` flag to apply optimizations directly to your local files (see next step).
115+
</Info>
62116

63117
</Step>
64118
<Step title="Run your first optimization">
@@ -69,6 +123,12 @@ Optimize a specific function:
69123
codeflash --file src/main/java/com/example/Utils.java --function myMethod
70124
```
71125

126+
If you installed the GitHub App, Codeflash will create a pull request with the optimization. If you haven't installed the app yet, or prefer to review changes locally first, add `--no-pr`:
127+
128+
```bash
129+
codeflash --file src/main/java/com/example/Utils.java --function myMethod --no-pr
130+
```
131+
72132
Or optimize all functions in your project:
73133

74134
```bash
@@ -80,7 +140,7 @@ Codeflash will:
80140
2. Generate tests and optimization candidates using AI
81141
3. Verify correctness by running tests (JUnit 5, JUnit 4, or TestNG)
82142
4. Benchmark performance improvements
83-
5. Create a pull request with the optimization (if the GitHub App is installed)
143+
5. Create a pull request with the optimization (or apply locally with `--no-pr`)
84144

85145
For advanced workflow tracing (profiling a running Java program), see [Trace & Optimize](/optimizing-with-codeflash/trace-and-optimize).
86146

docs/optimizing-with-codeflash/codeflash-all.mdx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Optimize Your Entire Codebase"
33
description: "Automatically optimize all codepaths in your project with Codeflash's comprehensive analysis"
44
icon: "database"
55
sidebarTitle: "Optimize Entire Codebase"
6-
keywords: ["codebase optimization", "all functions", "batch optimization", "github app", "checkpoint", "recovery", "javascript", "typescript", "python"]
6+
keywords: ["codebase optimization", "all functions", "batch optimization", "github app", "checkpoint", "recovery", "javascript", "typescript", "python", "java"]
77
---
88

99
# Optimize your entire codebase
@@ -45,6 +45,11 @@ codeflash --all path/to/dir
4545
codeflash optimize --trace-only --vitest ; codeflash --all
4646
```
4747
</Tab>
48+
<Tab title="Java">
49+
```bash
50+
codeflash optimize --timeout 60 java -cp target/classes com.example.Main ; codeflash --all
51+
```
52+
</Tab>
4853
</Tabs>
4954

5055
This runs your test suite, traces all the code covered by your tests, ensuring higher correctness guarantees

0 commit comments

Comments
 (0)