## Problem
Codeflash was generating import statements without file extensions for
TypeScript and ESM projects, causing ERR_MODULE_NOT_FOUND errors when
Node.js tried to resolve the modules.
Example error from trace 08d0e99e-10e6-4ad2-981d-b907e3c068ea:
```
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
'/workspace/target/packages/microservices/server/server-factory'
imported from .../test_create__unit_test_0.test.ts
```
The generated test had:
```typescript
import ServerFactory from '../../server/server-factory'
```
But Node.js ESM requires explicit file extensions.
## Root Cause
The get_module_path method in JavaScriptSupport was unconditionally
removing file extensions with .with_suffix(""), regardless of whether
the project used ESM or CommonJS module system.
## Solution
Modified get_module_path to:
1. Detect the module system using detect_module_system()
2. For ESM or TypeScript files: add .js extension (TypeScript convention)
3. For CommonJS: keep no extension (backward compatible)
TypeScript convention is to use .js extension in imports even when the
source file is .ts, as imports reference the compiled output.
## Testing
- Added two new test cases in TestGetModulePath class
- All 73 existing JavaScript support tests pass
- All 28 module system tests pass
- Lint and type checks pass
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
--no-pr is a top-level codeflash flag, not an optimize subcommand flag.
Placing it after optimize caused it to be passed to the JVM as an
unrecognized option.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Walk up parent directories when looking for mvnw wrapper, fixing
multi-module projects where mvnw is in the root but optimizer runs
from a submodule
- Respect user's --no-pr flag in Java tracer path instead of hardcoding
no_pr=True, allowing PR creation from tracer-based optimizations
- Add --no-pr to e2e tracer test script
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
**Problem:**
When functions are defined as property getters/setters (e.g., inside
Object.defineProperty with `get: function getrouter() {...}`), they were
being discovered as optimizable functions. This caused test generation
to fail because:
1. Tests tried to call the getter function directly (e.g., `obj.getrouter()`)
2. But getters are not accessible by function name - only via property access
3. This resulted in "TypeError: Cannot read properties of undefined (reading 'bind')"
**Root Cause:**
The tree-sitter function discovery in `treesitter.py` was finding all
function_expression nodes, including those used as property getters/setters.
These are not standalone functions and cannot be called directly.
**Solution:**
Added a check in `_walk_tree_for_functions` to exclude function_expression
nodes that are:
- Inside a `pair` node (key-value pair in object literal)
- Where the key is "get" or "set" (property accessor pattern)
**Affected Trace IDs (from logs):**
- 11b5475c-91d9-43b1-a317-33b7f4811c52 (init.getrouter)
- 78d8f1de-541a-4208-85c7-77194c70ec72 (createETagGenerator.generateETag)
- And others with similar patterns
**Testing:**
- Added comprehensive test suite in test_property_getter_exclusion.py
- Verified fix on actual Express.js application.js (getrouter no longer discovered)
- All existing JavaScript function discovery tests pass
- Linting (prek) passes
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
setup_test_config now returns bool so the optimizer aborts when JS
requirements (Node, npm, test framework) are missing instead of
silently continuing. Adds SetupError dataclass, fixes warning log to
print messages, and updates tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follow-up to #1909 — the npm package now installs into a dedicated venv
instead of using uv tool, but these references were missed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
wrap_target_calls_with_treesitter() operated line-by-line but tree-sitter
byte offsets span multiple lines. Multi-line calls like:
func(arg1,
arg2);
only had the first line replaced, leaving orphaned continuation lines
that caused compilation errors (80% of Spring AI functions skipped).
Rewrote to operate on the full body text with pre-computed character
offsets, processing calls back-to-front — same approach as
_add_timing_instrumentation which never had this bug.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zero-config Java support (auto-detection from build files, codeflash.toml
elimination) is handled separately in cf-java-zero-config-strategy. This
commit strips those changes, keeping only bug fixes:
- JFR parser, ReplayHelper, instrumentation, replay tests
- Multi-module test root resolution
- JUnit 4/5 test framework detection
- add_help=False for optimize subparser
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add JaCoCo runtime and CLI dependencies to Gradle build. Split Maven validation
skip properties into true/false groups so failOnViolation flags are set to false
instead of true. Add Gradle wrapper and integration tests for Java auto-config.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AI-generated tests sometimes place `import X from 'Y'` inside jest.mock()
callbacks, describe() blocks, or other function bodies. This is invalid
JavaScript syntax (import must be top-level). Add a post-processing step
that converts indented import statements to equivalent require() calls.
Affects ~79/1026 Strapi log files showing "import/export cannot be used
outside of module code" SWC syntax errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In monorepo setups (e.g., Strapi), workspace packages are hoisted to the
root node_modules. When Jest runs from a subpackage, it can't resolve
these packages because its default moduleDirectories only includes the
local node_modules. This adds the monorepo root's node_modules to
moduleDirectories in the runtime Jest config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shorthand method definitions inside object literals (e.g., `{ encrypt(data) {} }`)
were being discovered as optimizable functions. Since bare method syntax is only
valid inside class bodies or object literals, extracting them as standalone code
produced syntactically invalid JavaScript, failing context extraction.
Now skip method_definition nodes whose parent is an `object` node, matching
the existing skip for arrow functions in `pair` nodes.
Trace IDs: 04f07244, 01ac202f, 024a3d42, 04da127a (~274 affected logs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TypeScriptSupport.validate_syntax() always used the TYPESCRIPT parser,
which cannot parse JSX syntax. TSX files (.tsx) containing JSX were
incorrectly rejected as syntactically invalid, blocking optimization
of React components.
Added optional file_path parameter to validate_syntax across all
language support classes. When provided, the correct parser is selected
based on file extension (e.g., TSX parser for .tsx files).
Trace IDs: 00c25f79, 02697f98, fdfc6a8d (113 affected logs total)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
format_generated_code was called without the language parameter in
process_review(), defaulting to "python". This created temp files with
.py extension when formatting JS/TS code, causing prettier to fail.
Trace IDs: 11e9745d, 1578f081, 7e8abab2 (73 affected logs total)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds `codeflash auth login` CLI subcommand that performs the full OAuth
PKCE flow, prints the authentication URL, and saves the API key.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Java detection in parse_config_file() short-circuited before the existing
depth-comparison logic, so a parent pom.xml would override a closer
package.json or pyproject.toml. Now all config sources are detected first
and the closest one to CWD wins.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace xml.etree.ElementTree with text-based regex manipulation in
_write_maven_properties() and _remove_java_build_config(). ElementTree
destroys XML comments, mangles namespace declarations (ns0: prefixes),
and reformats whitespace. The new approach reads/writes pom.xml as plain
text, only touching codeflash.* property lines.
Also extracts duplicated key_map to shared _MAVEN_KEY_MAP constant and
aligns remove priority to check pom.xml first (matching write order).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dedup candidates in CandidateProcessor when each batch arrives (initial,
line profiler, repair, refinement, adaptive) instead of only catching
duplicates one-by-one during the benchmark loop.
Changes:
- Add dedup_candidates() to CandidateProcessor with persistent
seen_normalized set that tracks queued candidates across batches
- Simplify handle_duplicate_candidate/register_new_candidate to accept
original_flat_code string instead of full CodeOptimizationContext
- 14 unit tests covering all dedup paths
- Set jdk.ExecutionSample#period=1ms (default was 10ms) so JFR captures
samples from shorter-running programs
- Workload.main now runs 1000 rounds with larger inputs so JFR can
capture method-level CPU samples (repeatString with O(n²) concat
dominates ~75% of samples)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use print(flush=True) instead of logging.info for subprocess output so
CI logs show progress in real-time instead of buffering until completion.
Also set PYTHONUNBUFFERED=1 for the subprocess.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use Path comparisons instead of forward-slash substring matching
- Avoid parse_args() in test (reads stdin on Windows) — use Namespace directly
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Trigger on any codeflash/** or tests/** changes (not just java subset)
- Validate replay test files are discovered per-function
- Already validates: replay test generation, global discovery count,
optimization success, and minimum speedup percentage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The behavior instrumentation was producing malformed output for compact
@Test lines (annotation + method signature on same line, common in
replay tests). The method signature collection loop would skip past the
opening brace and consume subsequent methods' content.
Fix: detect when the @Test annotation line already contains { and treat
it as both annotation and method signature, avoiding the separate
signature search that was over-consuming lines.
Reverted the instrumentation skip for replay tests — they now get
properly instrumented for both behavior capture and performance timing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 new tests covering:
- JFR class name normalization (/ to . conversion)
- Package-based sample filtering
- Addressable time calculation from JFR samples
- Method ranking order and format
- Graceful timeout (SIGTERM before SIGKILL)
- Multi-module project root detection (Path not str)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
10 new tests covering:
- JUnit 5 replay test generation (imports, class visibility)
- JUnit 4 replay test generation (imports, public methods, @AfterClass)
- Overloaded method handling (no duplicate test method names)
- Instrumentation skip for replay tests (behavior + perf mode)
- Regular tests still get instrumented normally
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Java projects no longer need a standalone config file. Codeflash reads
config from pom.xml <properties> or gradle.properties, and auto-detects
source/test roots from build tool conventions.
Changes:
- Add parse_java_project_config() to read codeflash.* properties from
pom.xml and gradle.properties
- Add multi-module Maven scanning: parses each module's pom.xml for
<sourceDirectory> and <testSourceDirectory>, picks module with most
Java files as source root, identifies test modules by name
- Route Java projects through build-file detection in config_parser.py
before falling back to pyproject.toml
- Detect Java language from pom.xml/build.gradle presence (no config needed)
- Fix project_root for multi-module projects (was resolving to sub-module)
- Fix JFR parser / separators (JVM uses com/example, normalized to com.example)
- Fix graceful timeout (SIGTERM before SIGKILL for JFR dump + shutdown hooks)
- Remove isRecording() check from TracingTransformer (was preventing class
instrumentation for classes loaded during serialization)
- Delete all codeflash.toml files from fixtures and code_to_optimize
- Add 33 config detection tests
- Update docs for zero-config Java setup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
get_git_diff now uses all registered extensions instead of filtering
by current language, so update tests to reflect the new behavior.
Co-authored-by: Sarthak Agarwal <undefined@users.noreply.github.com>
Git doesn't track empty directories, so src/test/java must be created
before process_pyproject_config validates tests-root exists.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use `uv run -m codeflash.main` instead of direct file path
- Remove redundant --no-pr (already hardcoded in _run_java_tracer)
- Clean up leftover replay tests between retry attempts
- Add error logging for subprocess output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The conftest.py autouse fixture already resets _current_language before/after
each test, making per-test try/finally cleanup unnecessary.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
test_parse_line_profile_results_non_python_java_json set Language.JAVA
but never reset it, causing test_java_diff_ignored_when_language_is_python
to fail when tests ran in this order.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
- Fix bug: skip attrs classes with init=False (no __init__ to patch)
- Deduplicate attrs namespace/name sets into shared constants
- Fix _get_attrs_config to resolve import aliases properly
- Add test for init=False case with exact expected output
Instead of skipping attrs classes entirely (previous approach), emit a
module-level patch block immediately after the class definition:
_codeflash_orig_ClassName_init = ClassName.__init__
def _codeflash_patched_ClassName_init(self, *args, **kwargs):
return _codeflash_orig_ClassName_init(self, *args, **kwargs)
ClassName.__init__ = codeflash_capture(...)(_codeflash_patched_ClassName_init)
This sidesteps the __class__ cell TypeError that attrs(slots=True) triggers
when a synthetic super().__init__() body is injected into the original class,
because the patched wrapper is a plain module-level function with no __class__
cell.
Changes:
- InitDecorator.__init__: add _attrs_classes_to_patch dict
- visit_ClassDef: for attrs classes, record (name -> decorator) instead of
returning immediately; set inserted_decorator=True
- visit_Module: splice patch block statements after each attrs ClassDef
- _build_attrs_patch_block: new helper that builds the 3-statement AST block
- Tests: rename *_no_init_skipped -> *_patched_via_module_wrapper and update
expected strings to assert the exact generated patch block
Co-Authored-By: Oz <oz-agent@warp.dev>
- instrument_codeflash_capture: detect @attrs.define / @attr.s / etc. in the
'no explicit __init__' branch and return early, same as dataclass/NamedTuple.
Prevents a TypeError caused by attrs(slots=True) creating a new class whose
__class__ cell no longer matches the injected super().__init__ wrapper.
- code_context_extractor: add _get_attrs_config() helper; update
_collect_synthetic_constructor_type_names, _build_synthetic_init_stub, and
_extract_synthetic_init_parameters to handle attrs field conventions
(factory= keyword, init=False, kw_only).
- tests: add 3 exact-output tests for instrumentation skip behaviour and
3 exact-output tests for attrs stub generation.
Co-Authored-By: Oz <oz-agent@warp.dev>
When codeflash runs with --subagent (e.g., via the Claude Code plugin),
exit_with_message() now outputs <codeflash-error> XML to stdout instead
of Rich panel text. This lets the calling agent parse errors
programmatically rather than receiving unstructured text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
get_git_diff() hardcoded `.py` as the only valid file extension, causing
the auto-detect flow (no --file flag) to return 0 functions for Java,
JavaScript, and TypeScript projects. This broke the Claude Code plugin
integration where the hook runs `codeflash --subagent` without --file.
Now uses current_language_support().file_extensions to filter by the
active language's extensions dynamically.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers setup_test_config symlinking node_modules from original repo
to worktree, including edge cases (no worktree, missing node_modules,
already existing node_modules).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The function was removed in the dead code cleanup but the test file still
imported it and had a TestCreatePyprojectToml class, causing ImportError.
Co-authored-by: Kevin Turcios <undefined@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runtime annotations in PR descriptions were broken in two ways:
1. add_runtime_comments() ignored class/method prefixes in keys, causing
annotations from unrelated test classes to leak across files and sum
incorrectly at the same line number. Now filters by class names found
in each test source file.
2. Test functions were removed before annotations were added, shifting
line numbers so annotations landed on wrong lines. Swapped ordering
so annotations are applied first, then function removal carries them
along correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build test_count_cache once before ranking instead of calling
existing_unit_test_count O(2N) times. Guard for None function_to_tests
and add debug logging when effort is escalated from medium to high.
Parse each file once instead of up to 16 times by:
- Making remove_unused_definitions_by_function_names accept/return cst.Module
- Making parse_code_and_prune_cst and add_needed_imports_from_module accept cst.Module
- Threading the parsed Module through process_file_context
- Adding extract_all_contexts_from_files that processes all 4 context types
(READ_WRITABLE, READ_ONLY, HASHING, TESTGEN) in a single per-file pass
review_generated_tests and repair_generated_tests called add_language_metadata
without language_version, sending python_version=None to the API which rejects
with "Python version is required". Now falls back to current_language_support().
- Add existing_unit_test_count() with parametrized test deduplication
- Stable-sort ranked functions so tested ones come first
- Enable reference graph resolver (was disabled) for non-CI runs
- Add per-function logging with ref count and test count
- Auto-upgrade top N functions to high effort when user hasn't set --effort
- Add CallGraph model with traversal (BFS, topological sort, subgraph)
- Add get_call_graph() to DependencyResolver protocol and ReferenceGraph
- Refactor get_callees() to delegate through get_call_graph()
CF-1660
Cover all detection paths: Java (pom.xml, build.gradle, build.gradle.kts),
TypeScript, JavaScript, Python, empty directory fallback, and priority
resolution when multiple build system markers coexist.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When optimized JS/TS code introduces new global declarations (const, Set, etc.),
add_global_declarations inserts them into the original source, shifting the target
function's line numbers. The stale starting_line from function_to_optimize then
causes _replace_function_body to fail with "Could not find function X at line Y".
This affected ~666 function replacements in the Strapi optimization run, including
bytesToHumanReadable, isSelectable, getFileIconComponent, and many others.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update TestJestRootsConfiguration to match the new runtime config
approach: verify no --roots/config when tests are inside the project
root, and verify runtime config creation when tests are outside it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added functions to install the Codeflash runtime and manage its dependency in the Maven POM file.
- Implemented JaCoCo plugin addition and configuration for test coverage.
- Enhanced XML parsing for POM files to support both namespaced and non-namespaced formats.
- Updated test cases to reflect changes in dependency management and plugin configuration.
- Removed obsolete runtime jar finding logic and consolidated module detection for both Maven and Gradle projects.
- Improved input validation for test run commands.
- Updated tests in `test_java_multimodule_deps_install.py` to utilize `MavenStrategy` for installing multi-module dependencies.
- Changed function calls from `ensure_multi_module_deps_installed` to `MavenStrategy.install_multi_module_deps`.
- Added a fixture for `MavenStrategy` to streamline test setup.
- Modified assertions and mock setups to align with the new strategy implementation.
- Refactored tests in `test_java_test_filter_validation.py` to replace `_run_maven_tests` with `MavenStrategy.run_tests_via_build_tool`.
- Adjusted test cases to ensure proper handling of empty and valid test filters.
- Updated mock setups for Maven executable and command execution to reflect changes in the strategy.
Node.js subprocess pipe behavior causes the test to hang on Windows
(returncode=1 but stdout reader thread blocks beyond 10s timeout).
Co-authored-by: Aseem Saxena <aseembits93@users.noreply.github.com>
_expr_name now recurses into ast.Attribute to produce the full dotted
path (e.g. "dataclasses.dataclass", "typing.NamedTuple"). Callers use
.endswith() so both bare and module-qualified forms are matched. Adds
test for typing.NamedTuple base class.
NamedTuples have a synthesized __init__ that cannot be overwritten.
The instrumentation was missing a skip check (like the existing one
for dataclasses), causing "Cannot overwrite NamedTuple attribute
__init__" errors that crashed the test subprocess and produced 0%
coverage.
Also removes duplicate docstring in make_ai_service_request.
- Extract CODEFLASH_RUNTIME_VERSION and CODEFLASH_RUNTIME_JAR_NAME constants
in build_tools.py, replacing 15+ hardcoded "1.0.0" references across
test_runner.py, comparator.py, and line_profiler.py
- Cache _ensure_codeflash_runtime() results so it runs once per optimization
instead of 3 times (behavioral, benchmarking, line profiling phases)
- Add backup_pom/restore_pom/restore_all_pom_backups to build_tools.py so
pom.xml modifications (codeflash-runtime dependency, JaCoCo plugin) are
always reverted after optimization completes, even on crashes
- Call restore_all_pom_backups() in function_optimizer.py's finally block
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dataclass __init__ is auto-generated at class creation time and not
present in the AST. The instrumentor was injecting a synthetic __init__
with super().__init__(*args, **kwargs) which calls object.__init__()
and fails because dataclass fields are passed as kwargs.
Now only skips when the class is a @dataclass AND has no explicit
__init__. Dataclasses with custom __init__ are still instrumented.
Replace substring assertions (e.g. `"// 2.89ms ->" in lines[7]`) with
exact full-output comparisons for better regression detection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The base class had duplicate _get_java_sources_root and _fix_java_test_paths
methods that were overridden by JavaFunctionOptimizer. The base class also
had an is_java() block in generate_and_instrument_tests that used undefined
variables (used_behavior_paths, is_java). Removed all dead code since
JavaFunctionOptimizer.fixup_generated_tests handles this properly.
Also updated JavaFunctionOptimizer._fix_java_test_paths to accept
display_source parameter and use whole-word rename for collision handling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Windows backslashes in paths embedded into JavaScript strings are
interpreted as escape sequences by Node.js, corrupting the module path.
Use .as_posix() to emit forward slashes which Node accepts on all platforms.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
Initialize conn to None before try blocks and guard finally with
if conn is not None to prevent NameError if sqlite3.connect() raises.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
Inner-class methods are intentionally skipped by Java discovery
(PR #1726) since instrumentation is name-only and not class-aware.
Update test to expect False from replacement.
Take omni-main-java's fix for E2E test runner path resolution —
uses os.path.relpath from __file__ instead of hardcoded relative path.
Also adds codeflash.toml detection for Java projects.
- Update test_inject_profiling_used_frameworks, test_async_run_and_parse,
test_pickle_patcher to use new inject_profiling_into_existing_test API
(test_string param removed)
- Add parse_line_profile_results function to parse_line_profile_test_output
module (imported by main's PythonFunctionOptimizer and test_instrument_tests)
Merges the omni-main-java branch which synced main into omni-java,
including JavaFunctionOptimizer, removal of is_java()/is_python() guards,
protocol dispatch for parse_test_xml, and deletion of concolic_testing.py.
Fix 10 failing tests: remove wrong assertions expecting import statements
inside extracted class code, use substring matching for UserDict class
signature, and rewrite click-dependent tests as project-local equivalents.
Add tests for resolve_instance_class_name, enhanced extract_init_stub_from_class,
and enrich_testgen_context instance resolution.
- Use instrumented class name in _cf_mod/_cf_cls markers to disambiguate
existing vs generated tests sharing the same original class name
- Encode line number in invocation IDs (L{line}_{counter}) for deterministic
call-site identification in inline runtime comments
- Rewrite add_runtime_comments() to annotate each call line with inline
performance data instead of a summary block at top
- Strip assertions before instrumenting so both modes share the same base source
- Update test expected strings for new marker format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts ed2594bf which added --pool=forks to Vitest commands and
changed capture.js to use process.stdout.write and Vitest worker API.
These changes broke JS E2E tests (CJS, ESM, TS class) by altering
how all JS tests run, not just Vitest benchmarking.
The AI backend generates vitest/jest-style imports for Mocha projects.
Our sanitize_mocha_imports() stripped ESM `import { ... } from 'vitest'`,
but process_generated_test_strings() runs BEFORE postprocessing and calls
ensure_module_system_compatibility() which converts these to CJS requires.
Result: `const { ... } = require('vitest')` survived sanitization.
Added regexes for the CJS variants of vitest and @jest/globals requires.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: Vitest performance tests reported "20.0 seconds over 1 loop"
(JUnit XML wall-clock fallback) instead of actual per-function nanosecond
timing. This was a chain of two issues:
1. **stdout interception**: Vitest's default `threads` pool intercepts
process.stdout.write() and console.log(), preventing timing markers
from flowing to the parent process. Fixed by adding `--pool=forks`
to all Vitest commands and config files. The `forks` pool uses child
processes where stdout flows directly to the parent.
2. **test name detection**: Even after markers flowed through (43,000+
found in stdout), the parser couldn't match them to JUnit XML
testcases because all markers had "unknown" as the test name. This
happened because Vitest doesn't inject `beforeEach` as a global
(unlike Jest), so capture.js's Jest-style hook to set
`currentTestName` never fired.
Fixed by adding Vitest-specific test name detection in capture.js:
- Primary: `expect.getState().currentTestName` (full describe path)
- Fallback: `__vitest_worker__.current.fullTestName`
- Defense-in-depth: parser fallback matches "unknown" markers to
the first testcase when no name match is found
Result: cheerio's `isHtml` went from "20.0s / 1 loop" to
"902μs / 20,853 loops" with proper speedup analysis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three related fixes for Mocha test generation in CommonJS projects:
1. inject_test_globals() now accepts module_system param — emits
`require('node:assert/strict')` for CJS instead of ESM import syntax
2. ensure_module_system_compatibility() now converts ESM→CJS even when
the source has mixed imports (was skipping when both ESM and CJS were
detected, leaving the ESM import from inject_test_globals unconverted)
3. New sanitize_mocha_imports() strips vitest/jest/@jest/globals imports
that the AI sometimes generates for Mocha projects — Mocha provides
describe/it/before*/after* as globals
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ship a zero-dependency jest-reporter.js inside the codeflash runtime package
instead of requiring the external jest-junit npm package. This ensures the
reporter is always available when codeflash is installed, fixing Jest-based
projects (Strapi, Moleculer) that failed because jest-junit wasn't installed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nested functions are now skipped by FunctionVisitor, and
discover_functions no longer swallows parse/IO errors — callers
handle them. Update test expectations accordingly.
When testsRoot overlaps moduleRoot (common in JS/TS monorepos like Ghost
where both point to "src"), the directory-based filter incorrectly
excluded ALL source files. Switch to filename/directory pattern matching
(*.test.*, *.spec.*, __tests__/) when roots overlap, preserving the
existing directory-based filter for standard layouts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow init_js_project(), should_modify_package_json_config(), and
collect_js_setup_info() to run without interactive prompts when
skip_confirm=True. Uses auto-detected defaults instead of prompting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add NotImplementedError guard in all 3 test dispatchers (behavioral,
benchmarking, line-profile) for frameworks other than jest and vitest.
Previously, mocha and other frameworks silently fell through to Jest,
causing confusing failures. Now users get a clear error message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve `module.exports = varName` where varName is an object literal
containing methods. For patterns like `const utils = { match() {} };
module.exports = utils;`, the individual methods are now recognized as
exported. This fixes function discovery for CJS libraries like Moleculer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Post-process find_functions() to mark functions as exported when they appear
in named export clauses like `export { joinBy }`. This fixes discovery for
TypeScript codebases (e.g., Strapi) that define const arrow functions and
export them via a separate export statement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
parse_code_and_prune_cst now returns cst.Module instead of str.
add_needed_imports_from_module accepts cst.Module | str, skipping re-parse
when a Module is passed. This eliminates the string round-trip that caused
comments to migrate from statement leading_lines to Module.header,
resulting in comments appearing above imports instead of at their
original position.
Cache inspect.getmembers() results per module so repeated loop
iterations skip the expensive rescan. Add tests for get_runtime_from_stdout,
should_stop, _set_nodeid, _get_total_time, _timed_out, logreport, and
setup/teardown hooks.