Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
04a87cf
fix: add Jest 30 support, fix time limit, and fix async function looping
mohammedahmed18 Feb 3, 2026
4c61d08
Merge branch 'main' into fix/js-jest30-loop-runner
mohammedahmed18 Feb 3, 2026
a3764f1
Merge branch 'main' of github.com:codeflash-ai/codeflash into fix/js-…
mohammedahmed18 Feb 3, 2026
4157534
fix: use getter functions for env var constants in capture.js
mohammedahmed18 Feb 3, 2026
017bde1
refactor: improve code quality and documentation in loop-runner and c…
mohammedahmed18 Feb 3, 2026
71b38d5
fix: Parse timing markers from console output for JavaScript benchmar…
mohammedahmed18 Feb 3, 2026
7273f27
chore: trigger CI workflows
mohammedahmed18 Feb 3, 2026
b83e516
fix: use lazy % formatting for logger.debug to pass ruff G004
mohammedahmed18 Feb 3, 2026
0592d92
Merge branch 'main' into fix/js-jest30-loop-runner
mohammedahmed18 Feb 4, 2026
b4d0b0f
fix: support monorepo hoisted dependencies in JS requirements check
mohammedahmed18 Feb 4, 2026
3b56d24
debug: add extensive Jest execution logging for troubleshooting
mohammedahmed18 Feb 4, 2026
9cd5d5a
fix: calculate correct import paths for JavaScript tests in temp dire…
mohammedahmed18 Feb 4, 2026
0a8d120
fix: preserve ./ prefix in JS import paths and fix TestType enum
mohammedahmed18 Feb 4, 2026
6febd69
debug: add extensive performance test debugging
mohammedahmed18 Feb 4, 2026
6c74adc
fix: disable custom loop-runner to enable basic performance testing
mohammedahmed18 Feb 4, 2026
202bdc4
Merge branch 'main' into fix/js-jest30-loop-runner
mohammedahmed18 Feb 4, 2026
bab3bd4
style: auto-fix linting issues
github-actions[bot] Feb 4, 2026
535c640
fix: resolve all linting issues from ruff and mypy
mohammedahmed18 Feb 4, 2026
d0b859a
Optimize PrComment.to_json
codeflash-ai[bot] Feb 4, 2026
c151b6c
Merge pull request #1383 from codeflash-ai/codeflash/optimize-pr1318-…
claude[bot] Feb 4, 2026
ae31ca7
Fix JavaScript test generation and benchmarking
mohammedahmed18 Feb 5, 2026
9bb05f6
style: auto-fix linting issues
github-actions[bot] Feb 5, 2026
8fcb8cc
cleanup
mohammedahmed18 Feb 5, 2026
67ea0c9
Merge branch 'fix/js-jest30-loop-runner' of github.com:codeflash-ai/c…
mohammedahmed18 Feb 5, 2026
a6b9364
fix: include same-class helper methods inside class wrapper for TypeS…
mohammedahmed18 Feb 6, 2026
f800ae3
Merge branch 'main' into fix/js-jest30-loop-runner
mohammedahmed18 Feb 6, 2026
b65711d
fix: resolve merge conflict in function_optimizer.py
github-actions[bot] Feb 6, 2026
4545b8c
fix: add export keywords to remaining JavaScript/TypeScript tests
mohammedahmed18 Feb 6, 2026
183d800
fix: detect CommonJS exports (module.exports) for function discovery
mohammedahmed18 Feb 6, 2026
6c23255
version upgrade for cf package
mohammedahmed18 Feb 6, 2026
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
4 changes: 2 additions & 2 deletions code_to_optimize/js/code_to_optimize_js/bubble_sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @param {number[]} arr - The array to sort
* @returns {number[]} - The sorted array
*/
function bubbleSort(arr) {
export function bubbleSort(arr) {
const result = arr.slice();
const n = result.length;

Expand All @@ -29,7 +29,7 @@ function bubbleSort(arr) {
* @param {number[]} arr - The array to sort
* @returns {number[]} - The sorted array in descending order
*/
function bubbleSortDescending(arr) {
export function bubbleSortDescending(arr) {
const n = arr.length;
const result = [...arr];

Expand Down
6 changes: 3 additions & 3 deletions code_to_optimize/js/code_to_optimize_js/calculator.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const { sumArray, average, findMax, findMin } = require('./math_helpers');
* @param numbers - Array of numbers to analyze
* @returns Object containing sum, average, min, max, and range
*/
function calculateStats(numbers) {
export function calculateStats(numbers) {
if (numbers.length === 0) {
return {
sum: 0,
Expand Down Expand Up @@ -42,7 +42,7 @@ function calculateStats(numbers) {
* @param numbers - Array of numbers to normalize
* @returns Normalized array
*/
function normalizeArray(numbers) {
export function normalizeArray(numbers) {
if (numbers.length === 0) return [];

const min = findMin(numbers);
Expand All @@ -62,7 +62,7 @@ function normalizeArray(numbers) {
* @param weights - Array of weights (same length as values)
* @returns The weighted average
*/
function weightedAverage(values, weights) {
export function weightedAverage(values, weights) {
if (values.length === 0 || values.length !== weights.length) {
return 0;
}
Expand Down
8 changes: 4 additions & 4 deletions code_to_optimize/js/code_to_optimize_js/fibonacci.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @param {number} n - The index of the Fibonacci number to calculate
* @returns {number} - The nth Fibonacci number
*/
function fibonacci(n) {
export function fibonacci(n) {
if (n <= 1) {
return n;
}
Expand All @@ -20,7 +20,7 @@ function fibonacci(n) {
* @param {number} num - The number to check
* @returns {boolean} - True if num is a Fibonacci number
*/
function isFibonacci(num) {
export function isFibonacci(num) {
// A number is Fibonacci if one of (5*n*n + 4) or (5*n*n - 4) is a perfect square
const check1 = 5 * num * num + 4;
const check2 = 5 * num * num - 4;
Expand All @@ -33,7 +33,7 @@ function isFibonacci(num) {
* @param {number} n - The number to check
* @returns {boolean} - True if n is a perfect square
*/
function isPerfectSquare(n) {
export function isPerfectSquare(n) {
const sqrt = Math.sqrt(n);
return sqrt === Math.floor(sqrt);
}
Expand All @@ -43,7 +43,7 @@ function isPerfectSquare(n) {
* @param {number} n - The number of Fibonacci numbers to generate
* @returns {number[]} - Array of Fibonacci numbers
*/
function fibonacciSequence(n) {
export function fibonacciSequence(n) {
const result = [];
for (let i = 0; i < n; i++) {
result.push(fibonacci(i));
Expand Down
8 changes: 4 additions & 4 deletions code_to_optimize/js/code_to_optimize_js/math_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @param numbers - Array of numbers to sum
* @returns The sum of all numbers
*/
function sumArray(numbers) {
export function sumArray(numbers) {
// Intentionally inefficient - using reduce with spread operator
let result = 0;
for (let i = 0; i < numbers.length; i++) {
Expand All @@ -22,7 +22,7 @@ function sumArray(numbers) {
* @param numbers - Array of numbers
* @returns The average value
*/
function average(numbers) {
export function average(numbers) {
if (numbers.length === 0) return 0;
return sumArray(numbers) / numbers.length;
}
Expand All @@ -32,7 +32,7 @@ function average(numbers) {
* @param numbers - Array of numbers
* @returns The maximum value
*/
function findMax(numbers) {
export function findMax(numbers) {
if (numbers.length === 0) return -Infinity;

// Intentionally inefficient - sorting instead of linear scan
Expand All @@ -45,7 +45,7 @@ function findMax(numbers) {
* @param numbers - Array of numbers
* @returns The minimum value
*/
function findMin(numbers) {
export function findMin(numbers) {
if (numbers.length === 0) return Infinity;

// Intentionally inefficient - sorting instead of linear scan
Expand Down
10 changes: 5 additions & 5 deletions code_to_optimize/js/code_to_optimize_js/string_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @param {string} str - The string to reverse
* @returns {string} - The reversed string
*/
function reverseString(str) {
export function reverseString(str) {
// Intentionally inefficient O(n²) implementation for testing
let result = '';
for (let i = str.length - 1; i >= 0; i--) {
Expand All @@ -27,7 +27,7 @@ function reverseString(str) {
* @param {string} str - The string to check
* @returns {boolean} - True if str is a palindrome
*/
function isPalindrome(str) {
export function isPalindrome(str) {
const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, '');
return cleaned === reverseString(cleaned);
}
Expand All @@ -38,7 +38,7 @@ function isPalindrome(str) {
* @param {string} sub - The substring to count
* @returns {number} - Number of occurrences
*/
function countOccurrences(str, sub) {
export function countOccurrences(str, sub) {
let count = 0;
let pos = 0;

Expand All @@ -57,7 +57,7 @@ function countOccurrences(str, sub) {
* @param {string[]} strs - Array of strings
* @returns {string} - The longest common prefix
*/
function longestCommonPrefix(strs) {
export function longestCommonPrefix(strs) {
if (strs.length === 0) return '';
if (strs.length === 1) return strs[0];

Expand All @@ -78,7 +78,7 @@ function longestCommonPrefix(strs) {
* @param {string} str - The string to convert
* @returns {string} - The title-cased string
*/
function toTitleCase(str) {
export function toTitleCase(str) {
return str
.toLowerCase()
.split(' ')
Expand Down
8 changes: 4 additions & 4 deletions code_to_optimize/js/code_to_optimize_js_cjs/fibonacci.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @param {number} n - The index of the Fibonacci number to calculate
* @returns {number} The nth Fibonacci number
*/
function fibonacci(n) {
export function fibonacci(n) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: export keyword in CommonJS module causes syntax error

This file is a CommonJS module (uses module.exports at the bottom, and the parent package.json lacks "type": "module"). Adding the export keyword creates invalid JavaScript — Node.js will throw SyntaxError: Unexpected token 'export'.

The same issue exists in:

  • code_to_optimize/js/code_to_optimize_js_cjs/fibonacci_class.js
  • tests/test_languages/fixtures/js_cjs/math_utils.js
  • tests/test_languages/fixtures/js_cjs/calculator.js
  • tests/test_languages/fixtures/js_cjs/helpers/format.js

The CommonJS export detection added in treesitter_utils.py (_is_name_in_commonjs_exports) should handle discovering these functions without needing the export keyword. Remove export from all CJS files.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export keyword invalid in CommonJS module

This file is in a CommonJS project (no "type": "module" in package.json, no babel/transpiler). The export keyword is ESM syntax and will cause SyntaxError: Unexpected token 'export' when Node.js loads this file.

Either:

  • Remove export keywords (functions are already exported via module.exports at bottom)
  • Or convert the project to ESM

Same issue affects: fibonacci_class.js, tests/test_languages/fixtures/js_cjs/math_utils.js, calculator.js, helpers/format.js

if (n <= 1) {
return n;
}
Expand All @@ -21,7 +21,7 @@ function fibonacci(n) {
* @param {number} num - The number to check
* @returns {boolean} True if num is a Fibonacci number
*/
function isFibonacci(num) {
export function isFibonacci(num) {
// A number is Fibonacci if one of (5*n*n + 4) or (5*n*n - 4) is a perfect square
const check1 = 5 * num * num + 4;
const check2 = 5 * num * num - 4;
Expand All @@ -33,7 +33,7 @@ function isFibonacci(num) {
* @param {number} n - The number to check
* @returns {boolean} True if n is a perfect square
*/
function isPerfectSquare(n) {
export function isPerfectSquare(n) {
const sqrt = Math.sqrt(n);
return sqrt === Math.floor(sqrt);
}
Expand All @@ -43,7 +43,7 @@ function isPerfectSquare(n) {
* @param {number} n - The number of Fibonacci numbers to generate
* @returns {number[]} Array of Fibonacci numbers
*/
function fibonacciSequence(n) {
export function fibonacciSequence(n) {
const result = [];
for (let i = 0; i < n; i++) {
result.push(fibonacci(i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Intentionally inefficient for optimization testing.
*/

class FibonacciCalculator {
export class FibonacciCalculator {
constructor() {
// No initialization needed
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 23 additions & 18 deletions codeflash/code_utils/time_utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
from __future__ import annotations

import datetime as dt
import re

import humanize


def humanize_runtime(time_in_ns: int) -> str:
runtime_human: str = str(time_in_ns)
Expand All @@ -14,22 +9,32 @@ def humanize_runtime(time_in_ns: int) -> str:

if time_in_ns / 1000 >= 1:
time_micro = float(time_in_ns) / 1000
runtime_human = humanize.precisedelta(dt.timedelta(microseconds=time_micro), minimum_unit="microseconds")

units = re.split(r",|\s", runtime_human)[1]

if units in {"microseconds", "microsecond"}:
# Direct unit determination and formatting without external library
if time_micro < 1000:
runtime_human = f"{time_micro:.3g}"
elif units in {"milliseconds", "millisecond"}:
runtime_human = "%.3g" % (time_micro / 1000)
elif units in {"seconds", "second"}:
runtime_human = "%.3g" % (time_micro / (1000**2))
elif units in {"minutes", "minute"}:
runtime_human = "%.3g" % (time_micro / (60 * 1000**2))
elif units in {"hour", "hours"}: # hours
runtime_human = "%.3g" % (time_micro / (3600 * 1000**2))
units = "microseconds" if time_micro >= 2 else "microsecond"
elif time_micro < 1000000:
time_milli = time_micro / 1000
runtime_human = f"{time_milli:.3g}"
units = "milliseconds" if time_milli >= 2 else "millisecond"
elif time_micro < 60000000:
time_sec = time_micro / 1000000
runtime_human = f"{time_sec:.3g}"
units = "seconds" if time_sec >= 2 else "second"
elif time_micro < 3600000000:
time_min = time_micro / 60000000
runtime_human = f"{time_min:.3g}"
units = "minutes" if time_min >= 2 else "minute"
elif time_micro < 86400000000:
time_hour = time_micro / 3600000000
runtime_human = f"{time_hour:.3g}"
units = "hours" if time_hour >= 2 else "hour"
else: # days
runtime_human = "%.3g" % (time_micro / (24 * 3600 * 1000**2))
time_day = time_micro / 86400000000
runtime_human = f"{time_day:.3g}"
units = "days" if time_day >= 2 else "day"

runtime_human_parts = str(runtime_human).split(".")
if len(runtime_human_parts[0]) == 1:
if runtime_human_parts[0] == "1" and len(runtime_human_parts) > 1:
Expand Down
8 changes: 4 additions & 4 deletions codeflash/github/PrComment.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ class PrComment:

def to_json(self) -> dict[str, Union[str, int, dict[str, dict[str, int]], list[BenchmarkDetail], None]]:
report_table: dict[str, dict[str, int]] = {}
for test_type, result in self.winning_behavior_test_results.get_test_pass_fail_report_by_type().items():
for test_type, test_result in self.winning_behavior_test_results.get_test_pass_fail_report_by_type().items():
name = test_type.to_name()
if name:
report_table[name] = result
report_table[name] = test_result

result: dict[str, Union[str, int, dict[str, dict[str, int]], list[BenchmarkDetail], None]] = {
"optimization_explanation": self.optimization_explanation,
Expand All @@ -45,8 +45,8 @@ def to_json(self) -> dict[str, Union[str, int, dict[str, dict[str, int]], list[B
}

if self.original_async_throughput is not None and self.best_async_throughput is not None:
result["original_async_throughput"] = str(self.original_async_throughput)
result["best_async_throughput"] = str(self.best_async_throughput)
result["original_async_throughput"] = self.original_async_throughput
result["best_async_throughput"] = self.best_async_throughput
Comment on lines +48 to +49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential breaking API change: throughput fields changed from str to int

Previously these were serialized as str(self.original_async_throughput) and str(self.best_async_throughput). Now they're passed as raw int values. This JSON is sent to the CodeFlash API server (via cfapi.py where pr_comment.to_json() is called). If the server expects string values for these fields, this will cause a type mismatch or API error.

Verify the server-side API accepts int for these fields before merging.


return result

Expand Down
Loading
Loading