Commit graph

6441 commits

Author SHA1 Message Date
claude[bot]
8d5b81edc3 style: auto-fix linting issues
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 11:33:48 +00:00
codeflash-ai[bot]
220457e546
Optimize validate_trace_id
The hot path replaced `uuid.UUID(trace_id, version=4)` — which constructs a full UUID object and validates via parsing — with direct string checks: length, hyphen positions, version digit, variant digit, and a frozenset lookup for hex characters. Line profiler shows the original spent 71.6% of runtime in `uuid.UUID()` alone; the optimized code eliminates that entirely, bringing per-call cost from ~9.5 µs to ~1.6 µs. The suffix check was also micro-optimized from `in ["EXP0", "EXP1"]` (list construction + membership) to two direct string equality tests.
2026-04-10 11:32:23 +00:00
Kevin Turcios
7fb684b7fb ci: retrigger checks after auto-format commit 2026-04-10 06:16:50 -05:00
claude[bot]
624551978a style: auto-fix ruff formatting issues 2026-04-10 11:13:04 +00:00
Kevin Turcios
e2731745fb perf: fix Sentry-reported errors and speed bottlenecks across all services
UUID validation (1,459 errors/month):
- Add normalize_trace_id() to handle EXP0/EXP1 experiment suffixes
- Add validate_trace_id checks to optimization_review, testgen review/repair
- Fix bare UUID() call in log_event.py that caused 960 errors/month
- Return 400 instead of 500 for invalid trace_id in log_features

CodeValidationError (1,068 errors/month):
- Add repair_preamble() to fix broken LLM-generated test preambles
- 9 new tests covering preamble repair and end-to-end validation

create-pr speed (11.8s → ~6s):
- Parallelize auth lookups with Promise.all
- Parallelize post-PR-creation DB updates and GitHub API calls

apikeys LCP (5,084ms → ~2s):
- Single server-side getDashboardInitData() replaces 5 sequential client fetches
- PrivacyModeContext, ViewModeContext, Sidebar accept initial data props

optimization-prs speed (7.2s → ~3s):
- Replace LEFT JOIN COUNT on huge JSONB table with EXISTS semi-join
- Add composite indexes on optimization_events for org and user queries
- Add sizes="32px" to avatar images to prevent layout warnings
2026-04-10 06:08:00 -05:00
Kevin Turcios
3c9beac4b5 perf: fix dashboard CLS, onboarding LCP, and bundle size from Sentry traces
- Fix dashboard CLS (2.1→~0) by adding OptimizationPRsTable skeleton and
  min-height to match actual page layout order
- Reduce onboarding intro animation from 2400ms to 1200ms to cut LCP
- Add optimizePackageImports for 12 heavy packages (lucide-react, date-fns,
  chart.js, motion, Radix UI) to reduce bundle size
- Fix trace page CLS (0.46→~0) with flex-shrink-0 on header sections
- Wrap PostHogPageView in Suspense to restore static rendering
- Defer Intercom/Crisp scripts to lazyOnload strategy (~200KB deferred)
- Add font display swap, reduce JetBrains Mono to 2 weights
- Connect JetBrains Mono to Tailwind font-mono utility
- Add Webflow landing page performance audit document
2026-04-10 06:06:38 -05:00
Kevin Turcios
0ebc109a88
fix: resolve npm audit vulnerabilities in cf-webapp (#2592)
## Summary
- Run `npm audit fix` to resolve 12 of 14 vulnerabilities
- Fixed: axios (critical), brace-expansion, defu, effect/prisma,
minimatch, picomatch, qs, rollup, vite, yaml
- Remaining 2 moderate (`dompurify` via `monaco-editor`) have no
upstream fix yet

## Test plan
- [ ] Verify cf-webapp builds successfully
- [ ] Verify no regressions in dev server
2026-04-10 04:25:01 -05:00
Kevin Turcios
60ba2d44ac
fix: upgrade Next.js to 16.2.3 and fix theme/roadmap issues (#2591)
## Summary
- Upgrade Next.js from 16.1.6 to 16.2.3
- Add `suppressHydrationWarning` to `<html>` tag to fix `next-themes`
hydration mismatch
- Remove unnecessary `isClient` guard in `ThemeProvider` that caused
script tag warning
- Redirect unauthenticated `/roadmap` visitors to `/login` instead of
`/`

## Test plan
- [ ] Verify `/roadmap` redirects to `/login` when not logged in
- [ ] Verify `/roadmap` loads correctly when logged in as team member
- [ ] Verify no hydration warnings in browser console
- [ ] Verify dark/light theme switching still works
2026-04-10 03:51:28 -05:00
Kevin Turcios
e8561b9485
feat: add internal team-only roadmap page (#2590)
## Summary

- Adds `/roadmap` page with visual flowchart showing codeflash-python
and codeflash-agent planned work
- Gated behind `isTeamMemberCheck` (same auth pattern as
`/observability`)
- Sidebar link visible only to team members
- Status tracking with distinct visual treatments: compact left-accent
for shipped, hero cards with glow for in-progress, dashed wireframe for
planned

## Test plan

- [ ] Visit `/roadmap` as a team member — page renders with status cards
- [ ] Visit `/roadmap` as a non-team member — redirects to `/`
- [ ] Sidebar shows roadmap link only for team members
- [ ] Build passes (`npm run build`)
- [ ] All tests pass (`npm test` — 39/39)
2026-04-09 15:54:43 -05:00
Hesham Mohamed
b43e9ba648
fix: remove console.log that leaks API key in token exchange endpoint (#2589)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:48:14 +02:00
Kevin Turcios
a2dae4b60c
ci: fix deploy path filter, Claude Code paths, disable PyPI (#2588)
## CI Waste Cleanup

### Changes

1. **Deploy AI Service path filter** — narrowed `.github/workflows/**`
to `.github/workflows/deploy_aiservice_to_azure.yml`
- Previously, editing *any* workflow file triggered an AI service deploy
- The other deploy workflows (CFAPI, CF-WEB-APP) are already scoped
correctly

2. **Claude Code paths-ignore** — added `paths-ignore` for
`.github/workflows/**`, `*.md`, `docs/**`
- Currently fires on every PR regardless of files changed (85% failure
rate)
- The `codeflash` repo's Claude Code workflow already has these filters

3. **Publish to PyPI** — disabled via API
   - Had `if: false` hardcoded with a TODO comment
   - Was creating a skipped run on every push to main (pure noise)

### Context

Part of the Codeflash org CI audit. See also:
- codeflash-ai/codeflash#2025 (E2E path filters)
- codeflash-ai/codeflash#2026 (claude-code-action pin)
2026-04-09 02:37:58 -05:00
Kevin Turcios
0bef49265a
ci: pin claude-code-action to v1.0.89 (fix Bedrock auth) (#2587)
## Summary
- Pin `anthropics/claude-code-action` from `@v1` to `@v1.0.89` in both
`claude.yml` and `duplicate-code-detector.yml`

## Why
v1.0.90 (released Apr 8) broke Bedrock OIDC auth. Every Claude Code and
Duplicate Code Detector run has been failing with:

```
403 Authorization header requires 'Credential' parameter.
Authorization header requires 'Signature' parameter.
```

**Upstream issue:** anthropics/claude-code-action#1196

v1.0.89 was the last working version (confirmed: all runs succeeded on
Apr 7, all failed starting Apr 8).

## Test plan
- [ ] Merge and verify Claude Code workflow passes on next PR
- [ ] Verify Duplicate Code Detector passes on next PR
- [ ] Unpin to `@v1` once anthropics/claude-code-action#1196 is resolved
2026-04-09 02:16:09 -05:00
Hesham Mohamed
c02a4e6b5d
fix: stop dashboard and review-optimizations infinite refetch loops (#2584)
Summary
                                                                  
- Replace server action calls with API Route Handlers in
OptimizationPRsTable and OptimizationsTable to break the Next.js RSC
refresh cycle that caused continuous endpoint polling
- Create /api/optimization-prs and /api/optimization-events route
handlers that read auth from session cookies
- Remove accountPayload prop threading from both table components and
their parent pages
- Add key-based remount on OptimizationsTable to ensure data refreshes
correctly on org switch
Root Cause
Next.js server actions always trigger an RSC page refresh (GET) after
completion. When a client component calls a server action inside a
useEffect, it creates an infinite loop: server action POST → RSC refresh
→ component
re-renders → effect fires again → repeat. This was happening in both
OptimizationPRsTable (dashboard) and OptimizationsTable
(review-optimizations).
Solution
   
Regular fetch() calls to Route Handlers do not trigger RSC refreshes,
breaking the loop entirely. Auth is handled server-side in the route
handlers by reading the session cookie — same mechanism as
getAccountContext().

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Codeflash Bot <bot@codeflash.ai>
Co-authored-by: Kevin Turcios <106575910+KRRT7@users.noreply.github.com>
2026-04-08 23:26:35 -05:00
Aseem Saxena
22317c04a4
Merge pull request #2586 from codeflash-ai/fix/tracer-webapp-after-optimziation
Fix: Trace page in web app
2026-04-08 16:25:25 -07:00
Codeflash Bot
7bdb95e000 fix trace page in web app 2026-04-09 01:21:50 +02:00
Hesham Mohamed
f4412246e5
FIx(auth): enhance OAuth handling and improve code structure (#2585)
---
  Summary

- Fixes OAuth authentication flow reliability by preventing duplicate
auth
checks caused by React Strict Mode / Suspense remounts using a useRef
guard
- Extracts useSearchParams() values into stable string primitives
outside the
effect, removing searchParams from the dependency array to avoid
unnecessary
  re-runs
- Adds /codeflash/auth/oauth to the proxy ignore paths so OAuth token
exchange
   requests are not intercepted by the auth middleware
  - Adds debug logging for the API key returned during token exchange
  - Adds codeflash configuration block to the root package.json

  Test plan

- Verify CLI OAuth login flow completes successfully end-to-end (auth
page →
  GitHub → redirect → token exchange)
- Confirm the auth page does not trigger duplicate API calls in React
Strict
  Mode (check network tab)
  - Verify VSCode extension OAuth login still works
- Confirm /codeflash/auth/oauth/token endpoint is reachable and not
blocked by
   proxy middleware

  ---
  Want me to push the branch and create the PR?

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 22:40:42 +02:00
Kevin Turcios
996c82ac4c
feat: add internal /report page for optimization results (#2576)
## Summary
- Adds `/report` page showing results of the 20-PR webapp optimization
sprint
- Team-member only access (guarded in `proxy.ts` + server component
`isTeamMember()` check)
- Full-width layout (no sidebar), matching `/roadmap` and
`/observability` patterns
- Dual-view toggle: Executive Summary / Engineering Details
- chart.js charts with datalabels matching the original Plotly Dash
report
- Full light/dark theme support via Tailwind `dark:` variants

## Files
- **New**: `src/app/report/page.tsx`,
`src/components/report/report-charts.tsx`,
`src/components/report/report-toggle.tsx`
- **Modified**: `proxy.ts` (added `/report` + `/roadmap` to team-member
guard), `conditional-layout.tsx` (hide sidebar for `/report`)
- **Dep**: `chartjs-plugin-datalabels` for bar/pie chart value labels

## Test plan
- [ ] Visit `/report` as a CF team member — page renders with all
sections
- [ ] Toggle between Executive Summary and Engineering Details
- [ ] Charts display with value labels and correct colors
- [ ] Visit `/report` as a non-team-member — redirected to `/`
- [ ] Light and dark mode both render correctly
2026-04-04 23:55:12 -05:00
Kevin Turcios
c8c4608d1d
fix: add chartjs-plugin-datalabels to dependencies (#2579)
## Summary
- Adds `chartjs-plugin-datalabels` to `package.json` — was installed
locally but missing, causing CI build failure for both `/report` and
`/membench` chart components

## Test plan
- [ ] CI build passes
- [ ] `/report` and `/membench` deploy successfully to staging
2026-04-04 23:46:38 -05:00
Kevin Turcios
475ecf37c8
feat: add /membench page for Unstructured memory benchmark (#2577)
## Summary
- Ports the Unstructured Core Product memory benchmark Dash app into
cf-webapp as `/membench`
- Green accent theme, exec/eng dual view, 4 charts (peak memory,
allocators, headroom, max alloc)
- Access restricted to Codeflash team + `@unstructured.io` emails via
`isMembenchAllowed()` domain check

## Changes
- `src/app/membench/page.tsx` — Server component with all benchmark data
hardcoded
- `src/components/membench/membench-charts.tsx` — 4 chart.js charts with
datalabels
- `src/components/membench/membench-toggle.tsx` — Green-accent exec/eng
view toggle
- `src/lib/team-members.ts` — Added `isMembenchAllowed()` (CF team OR
`@unstructured.io`)
- `src/app/utils/auth.ts` — Added `canAccessMembench()` server-side
helper
- `src/proxy.ts` — Added `/membench` route guard
- `src/components/conditional-layout.tsx` — Added `/membench` to
full-width layout

## Test plan
- [ ] `npm run build` passes
- [ ] `/membench` renders for CF team member
- [ ] `/membench` renders for `@unstructured.io` user
- [ ] Non-authorized user redirected to `/`
- [ ] Exec/eng toggle switches views
- [ ] Charts render with hover tooltips
- [ ] Light and dark mode both look correct
2026-04-04 23:33:00 -05:00
Kevin Turcios
c8a66b5ec6
fix: stop dashboard sidebar infinite refetch loop (#2564)
## Summary
- Fix infinite refetch loop in the dashboard sidebar that fires hundreds
of POST+GET requests per second
- The `subscriptionFetchRef` was reset in `finally()`, allowing
re-entrancy: fetch → `setSubscription` → re-render → ref is `false` →
fetch again → infinite loop
- Move the ref reset to the effect cleanup function so it only resets
when `mode` actually changes

## Note: Auth0 favicon 404
The Auth0 login page at `codeflash-ai.us.auth0.com` returns a 404 for
`/favicon.ico`. This is configured in **Auth0 Dashboard > Branding >
Universal Login**, not in application code. Upload the Codeflash favicon
there to resolve.

## Test plan
- [ ] Navigate to dashboard, open Network tab — confirm no repeated
POST/GET polling
- [ ] Switch between personal/org mode — confirm subscription data still
loads correctly
- [ ] Verify sidebar subscription usage display still renders
2026-04-04 12:46:56 -05:00
Kevin Turcios
f6a7d9b29d
chore: add cf-webapp quality gates CI workflow (#2563)
## Summary
- Adds GitHub Actions workflow that runs on PRs touching
`js/cf-webapp/**`
- Runs type-check (`tsc --noEmit`), tests (`vitest run`), and build
(`next build`)
- Posts a PR comment with results table and collapsible route size
details
- Fails the check if any gate fails

## Evidence
- Proof doc: `js/cf-webapp/proof/20-quality-gates.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/20-quality-gates.sh` — 10/10
checks pass
- [ ] Workflow triggers on a PR touching cf-webapp files
- [ ] PR comment appears with quality report
2026-04-04 11:43:02 -05:00
Kevin Turcios
0c37015650
chore: remove unused dependencies and replace react-papaparse with papaparse (#2562)
## Summary
- Removes `@azure/msal-node` (unused — Auth0 is the auth provider)
- Removes `github-markdown-css` (not imported anywhere)
- Replaces `react-papaparse` with `papaparse` (only core parser needed,
not React wrapper)
- Adds `@types/papaparse` for TypeScript types

## Evidence
- No imports of removed packages exist in source
- Proof doc: `js/cf-webapp/proof/18-remove-unused-deps.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/18-remove-unused-deps.sh` —
7/7 checks pass
- [ ] `npm run build` succeeds
- [ ] CSV parsing functionality still works
2026-04-04 11:42:18 -05:00
Kevin Turcios
87db8f6026
perf: parallelize LLM call detail and errors queries (#2561)
## Summary
- Runs `llm_calls.findUnique` and `optimization_errors.findMany` in
parallel via `Promise.all`
- Both queries use `params.id` directly — no data dependency between
them
- Page load time reduced from sum to max of both queries

## Evidence
- Proof doc: `js/cf-webapp/proof/17-parallel-llm-call-detail.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/17-parallel-llm-call-detail.sh` — 5/5
checks pass
- [ ] LLM call detail page renders correctly with error list
2026-04-04 11:41:16 -05:00
Kevin Turcios
94b9de946e
perf: deduplicate trace page Prisma query with React cache() (#2560)
## Summary
- Wraps `optimization_features.findUnique` in `React.cache()` so
`generateMetadata()` and the page component share one DB hit
- Eliminates redundant query — before: 2 identical queries per page
load, after: 1
- Replaces inline type annotation with `Awaited<ReturnType<...>>` for
DRY types

## Evidence
- Proof doc: `js/cf-webapp/proof/16-react-cache-dedup.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/16-react-cache-dedup.sh` —
5/5 checks pass
- [ ] Trace detail page renders correctly with metadata title
2026-04-04 11:41:05 -05:00
Kevin Turcios
c7df7bf27c
perf: parallelize event + features queries in getOptimizationEventById (#2559)
## Summary
- Runs `optimization_events.findFirst` and
`optimization_features.findUnique` in parallel via `Promise.all`
- The features query only needs `trace_id` (a parameter), not the event
result, making the queries independent
- Wall-clock time goes from sum of both queries to max of either

## Evidence
- Proof doc: `js/cf-webapp/proof/15-parallel-optimization-event.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/15-parallel-optimization-event.sh` — 6/6
checks pass
- [ ] Optimization review page loads correctly with review quality data
2026-04-04 11:40:10 -05:00
Kevin Turcios
dc684b9a28
perf: use PostHog singleton and replace shutdown() with flush() (#2558)
## Summary
- Converts `PostHogClient()` to singleton pattern — reuses one `PostHog`
instance instead of creating new ones per call
- Replaces `shutdown()` with `flush()` across 5 files (6 call sites) —
flush sends events without destroying the shared client

## Evidence
- Before: each call to `PostHogClient()` creates new HTTP connection +
event queue
- After: single instance reused across all server components/actions in
the same process
- Proof doc: `js/cf-webapp/proof/14-posthog-singleton.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/14-posthog-singleton.sh` —
9/9 checks pass
- [ ] PostHog events still appear in PostHog dashboard after deployment
2026-04-04 11:37:05 -05:00
Kevin Turcios
67ec032429
perf: dynamic-import LineProfilerView to defer prism-react-renderer (#2557)
## Summary
- Replaces static import of `LineProfilerView` with `next/dynamic` +
`ssr: false`
- Defers loading of `prism-react-renderer` (~100KB+) until user
navigates to profiler tab
- Adds `<Skeleton>` loading fallback for smooth UX

## Evidence
- Proof doc: `js/cf-webapp/proof/13-dynamic-import-line-profiler.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/13-dynamic-import-line-profiler.sh` — 7/7
checks pass
- [ ] `npm run build` succeeds
- [ ] Profiler page loads and renders LineProfilerView correctly
2026-04-04 11:36:59 -05:00
Kevin Turcios
fbedf0c1ee
perf: migrate framer-motion to motion/react for smaller bundle (#2556)
## Summary
- Replaces `framer-motion` with `motion` (the official tree-shakeable
successor)
- Updates import in onboarding page from `"framer-motion"` to
`"motion/react"`
- Enables better tree-shaking: only `AnimatePresence` + `motion`
component are imported

## Evidence
- `motion` uses ESM-first exports with `sideEffects: false`
- Same API, officially recommended migration path
- Proof doc: `js/cf-webapp/proof/12-framer-motion-migration.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/12-framer-motion-migration.sh` — 6/6
checks pass
- [ ] `npm run build` in cf-webapp succeeds
- [ ] Onboarding page animations work correctly
2026-04-04 11:36:54 -05:00
Kevin Turcios
eed0646f32
fix: use @sentry/nextjs instead of @sentry/node in repository action (#2555)
## Summary

Replace `@sentry/node` import with `@sentry/nextjs` in the repository
action. `@sentry/nextjs` already re-exports all server-side APIs, so
importing `@sentry/node` separately pulls in a duplicate SDK.

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/11-sentry-nextjs-consistency.sh
```

3 checks: no @sentry/node in app/, repository action uses
@sentry/nextjs, all app/ Sentry imports consistent.
2026-04-04 11:36:48 -05:00
Kevin Turcios
6ebff6f079
perf: lazy-load Sentry Replay integration to reduce initial bundle ~600KB (#2554)
## Summary

- Move `replayIntegration` from eager initialization to
`lazyLoadIntegration()`
- Removes ~300KB per copy (two copies were shipped) from the critical
path
- Replay still activates after page is interactive via
`Sentry.addIntegration`

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/10-lazy-sentry-replay.sh
```

6 checks: lazyLoadIntegration used, empty init integrations,
addIntegration for deferred loading, maskAllText/blockAllMedia
preserved.

## Test Plan

- [ ] Run reproducer (6/6 pass)
- [ ] Verify Sentry Replay still works after page load
2026-04-04 11:36:41 -05:00
Kevin Turcios
278aab2b11
test: add test coverage for server actions and withTiming (#2553)
## Summary

- Add 90 unit tests across 4 test files covering server action timing,
members, repository, and review-optimizations
- Add Vitest configuration with `@/` path alias matching Next.js
tsconfig
- Add global mock setup for Prisma, Sentry (nextjs + node), and
analytics

## Test Files

| File | Tests |
|------|-------|
| `server-action-timing.test.ts` | 24 (timing, slow detection, error
handling, Sentry spans) |
| `members/action.test.ts` | 14 (access control, member mapping, error
handling) |
| `repositories/action.test.ts` | 20 (parallel fetch, auth, is_active,
analytics) |
| `review-optimizations/action.test.ts` | 32 (both code paths, N+1 fix,
raw SQL, pagination, search, filter) |

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/09-test-coverage.sh
```

## Test Plan

- [ ] Run reproducer (11/11 pass)
- [ ] Run `npm test` to execute all tests
2026-04-04 11:35:19 -05:00
Kevin Turcios
566424e97f
feat: add server action timing and expand PostHog analytics (#2552)
## Summary

- Add `withTiming()` wrapper for server actions with Sentry span
reporting and slow action warnings (>1s)
- Add centralized `captureEvent()` helper for PostHog tracking
- Add 5 new PostHog tracking events: optimization_reviewed,
repository_connected, api_key_created, member_invited,
billing_page_viewed
- Instrument 4 server actions with `withTiming()`:
getOrganizationMembers, getRepositoryById,
getRepositoriesWithStagingEvents, getAllOptimizationEvents

## Proof of Correctness

See
[`js/cf-webapp/proof/08-server-action-timing.md`](js/cf-webapp/proof/08-server-action-timing.md)

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/08-server-action-timing.sh
```

21 checks verify: withTiming utility, 4 instrumented actions,
captureEvent helper, 5 tracking functions, and all tracking calls wired
into action files.

## Test Plan

- [ ] Run reproducer: `bash
proof/reproducers/08-server-action-timing.sh` (21/21 pass)
- [ ] Verify server actions still work correctly
- [ ] Check Sentry for `server.action` spans after deployment
2026-04-04 11:34:53 -05:00
Kevin Turcios
e0d76d4338
feat: add observability stack (OTel, Sentry tuning, Prisma logging, bundle-analyzer) (#2547)
## Summary

- Add OpenTelemetry distributed tracing with Sentry bridge
(`instrumentation.ts`) — dynamic imports so OTel is only loaded when
active
- Reduce Sentry `tracesSampleRate` from 100% to 10% in production
(server + client), cutting event volume ~90%
- Add `skipOpenTelemetrySetup` to prevent duplicate OTel SDK
initialization
- Add `browserTracingIntegration` with long animation frame detection
for Web Vitals
- Add Prisma slow query logging (>500ms) and error forwarding to Sentry
- Add `@next/bundle-analyzer` for on-demand CI bundle tracking
(`ANALYZE=true npm run build`)
- Fix Edge-incompatible OTel exports (`SentryContextManager`,
`validateOpenTelemetrySetup`)

## Proof of Correctness

See
[`js/cf-webapp/proof/07-observability-stack.md`](js/cf-webapp/proof/07-observability-stack.md)
for detailed analysis.

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/07-observability-stack.sh
```

The reproducer verifies (24 checks):
1. OTel SDK configured with Sentry bridge (NodeSDK, SentrySpanProcessor,
SentryPropagator, PrismaInstrumentation)
2. Dynamic imports (4 packages only loaded when tracing active)
3. Noisy instrumentations disabled (fs, dns, net)
4. Sentry 10% production sampling (server + client)
5. `skipOpenTelemetrySetup: true` prevents duplicate OTel
6. Prisma slow query logging + Sentry error forwarding
7. `@next/bundle-analyzer` wired into next.config.mjs
8. All 5 required packages in package.json
9. `browserTracingIntegration` with long animation frame detection

## New Dependencies

| Package | Purpose |
|---------|---------|
| `@opentelemetry/sdk-node` | OTel Node.js SDK |
| `@opentelemetry/auto-instrumentations-node` | Auto-instrumentation for
HTTP, Express, etc. |
| `@prisma/instrumentation` | Prisma query spans |
| `@sentry/opentelemetry` | OTel → Sentry bridge |
| `@next/bundle-analyzer` (dev) | Interactive bundle treemap |

## Test Plan

- [ ] Run reproducer: `bash proof/reproducers/07-observability-stack.sh`
(24/24 pass)
- [ ] Verify `npm run build` succeeds
- [ ] Verify `npm run analyze` generates bundle treemap
- [ ] Confirm no Edge runtime build errors
(SentryContextManager/validateOpenTelemetrySetup removed)
2026-04-04 11:27:10 -05:00
Kevin Turcios
d9faaf4722
perf: parallelize data fetches on repository detail page (#2546)
## Summary

- Parallelize `getRepositoryById` server action: repo fetch + auth check
now run via `Promise.all` instead of sequentially
- Parallelize 6 independent stats queries on the repository detail page
via `Promise.all`: optimization counts, time series data, PR event data,
and leaderboard
- Reduces repository detail page server-side latency from ~350ms (7
sequential round-trips) to ~100ms (2 parallel batches)

## Proof of Correctness

See
[`js/cf-webapp/proof/06-parallel-repo-page.md`](js/cf-webapp/proof/06-parallel-repo-page.md)
for detailed analysis.

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/06-parallel-repo-page.sh
```

The reproducer verifies:
1. `getRepositoryById` uses `Promise.all` for repo + auth
2. At least 5 of 6 stats queries are inside `Promise.all`
3. No sequential `await` patterns remain for stats queries
4. All stats queries are independent (take only `repositoryId`)

## Why This Is Real

1. **All 6 stats queries are independent** — each takes only
`repositoryId` and returns different data
2. **Repo fetch and auth check are independent** — `findFirst` needs
`repoId`, `getRepositoriesForAccountCached` needs `payload`
3. **Latency reduction is significant** — 6 sequential DB round-trips
become 1 parallel batch

## Test Plan

- [ ] Run reproducer script: `bash
proof/reproducers/06-parallel-repo-page.sh`
- [ ] Verify repository detail page loads correctly
- [ ] Confirm all stats widgets render with correct data
2026-04-04 11:26:58 -05:00
Kevin Turcios
025ed0a980
proof: parallelize members page fetches (8a039c52) (#2545)
## Proof of Correctness — Commit 5/22

**Optimization:** Run `getCurrentUserRole` and `getOrganizationMembers`
concurrently via `Promise.all` instead of sequentially.

**Claim:** Saves one round-trip latency. Total latency: `role_time +
members_time` → `max(role_time, members_time)`.

### Evidence

Both calls take `(userId, orgId)` and are independent — neither uses the
other's result. The sequential pattern was unnecessary.

### Reproducer

```bash
cd js/cf-webapp
bash proof/reproducers/05-parallel-members-page.sh
```

Verifies: both calls inside `Promise.all`, no sequential awaits remain,
no cross-dependency.

### Files
- `js/cf-webapp/proof/05-parallel-members-page.md` — proof
- `js/cf-webapp/proof/reproducers/05-parallel-members-page.sh` —
reproducer
2026-04-04 11:26:53 -05:00
Kevin Turcios
385692b3c3
proof: N+1 query elimination in getAllOptimizationEvents (25013adb) (#2544)
## Proof of Correctness — Commit 4/22

**Optimization:** Eliminate N+1 query pattern in
`getAllOptimizationEvents` — the server action powering the
review-optimizations page.

**Claim:** For a page of 10 events: 12–22 queries → 2–3 queries.

### Evidence

Two code paths, both had N+1 patterns:

**Raw SQL path (before → after):**
- Before: events query + count query + N per-event
`repositories.findUnique` = 12 queries
- After: single JOIN query (includes `r.full_name`, `r.name`, `r.id`) +
count query, run in parallel via `Promise.all` = 2 queries

**Prisma path (before → after):**
- Before: events query + N per-event `optimization_features.findUnique`
+ count query = 12 queries
- After: events + count in `Promise.all`, then 1 batch `findMany({
where: { trace_id: { in: traceIds } } })` with `Map` lookup = 3 queries

Also includes the `r.name` fix (originally 5c94f329) since it modifies
the same JOIN query.

### Reproducer

```bash
cd js/cf-webapp
bash proof/reproducers/04-n-plus-one-benchmark.sh
```

Static analysis that:
1. Confirms no `findUnique` inside `map()` loops remains (the N+1
pattern)
2. Verifies batch `findMany` with `IN` filter on trace_ids
3. Verifies `Promise.all` parallelizes events + count
4. Verifies raw SQL JOIN includes repository fields
5. Prints before/after query count comparison

### Files
- `js/cf-webapp/proof/04-n-plus-one-fix.md` — detailed proof
- `js/cf-webapp/proof/reproducers/04-n-plus-one-benchmark.sh` —
reproducer

### Reference
- Source commits: 25013adb + 5c94f329 from PR #2536
2026-04-04 11:26:47 -05:00
Kevin Turcios
fad39c934d
proof: PrismaClient singleton consolidation (16c5887a) (#2543)
## Proof of Correctness — Commit 3/22

**Optimization:** Replace 5 separate `new PrismaClient()` instances with
a shared singleton at `@/lib/prisma`.

**Claim:** Eliminates 5 independent connection pools → 1 shared pool
with `connection_limit=10`, `pool_timeout=20`. Prevents connection pool
exhaustion under concurrent requests.

### Evidence

Each `new PrismaClient()` creates its own query engine and PostgreSQL
connection pool (default 5 connections). With 5 instances, the app could
hold 25 connections simultaneously — a real risk against PostgreSQL's
hard limit (typically 100, often lower on Azure).

Files that had their own `new PrismaClient()`:
- `src/app/(dashboard)/apikeys/page.tsx`
- `src/app/(dashboard)/apikeys/tokenfuncs.ts`
- `src/app/api/traces/[trace_id]/save-modified-code/route.ts`
- `src/app/trace/[trace_id]/page.tsx`
- `src/lib/modified-code-utils.ts`

The singleton pattern is [Prisma's official recommendation for
Next.js](https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/nextjs-prisma-client-dev-practices).

### Reproducer

```bash
cd js/cf-webapp
bash proof/reproducers/03-prisma-singleton.sh
```

Verifies:
1. No `new PrismaClient()` outside `src/lib/prisma.ts`
2. All 5 affected files import from `@/lib/prisma`
3. Singleton has connection pooling + globalThis caching
4. TypeScript compiles cleanly

### Files
- `js/cf-webapp/proof/03-prisma-singleton.md` — detailed proof
- `js/cf-webapp/proof/reproducers/03-prisma-singleton.sh` — reproducer

### Reference
- Source commit: 16c5887a from PR #2536
2026-04-04 11:26:33 -05:00
Kevin Turcios
b4d89c5cd3
proof: named diff import + Sentry import fix (36bd47b4) (#2540)
## Proof of Correctness — Commit 2/22

**Optimization:** Replace `import * as Diff` with named `import {
createPatch }` for tree-shaking, and `@sentry/browser` →
`@sentry/nextjs` to eliminate duplicate SDK bundle.

### Evidence

1. **`import *` prevents tree-shaking** — webpack/turbopack must include
all 15+ exports from the `diff` package. Named import allows dead code
elimination of unused functions (`diffChars`, `diffWords`, `diffLines`,
`structuredPatch`, etc.).

2. **`@sentry/browser` duplicates `@sentry/nextjs` core** — the app
already uses `@sentry/nextjs` everywhere. Having one file import
`@sentry/browser` pulls in a second copy of Sentry's core code.

### Reproducer

```bash
cd js/cf-webapp
bash proof/reproducers/02-named-diff-sentry-import.sh
```

Verifies via grep that:
- No `import * as Diff` remains
- No `@sentry/browser` imports remain  
- Only `createPatch` is used from the `diff` package
- All Sentry imports use `@sentry/nextjs`

For bundle size measurement, run with `MEASURE=1`:
```bash
MEASURE=1 bash proof/reproducers/02-named-diff-sentry-import.sh
```

### Files
- `js/cf-webapp/proof/02-named-diff-sentry-import.md` — detailed proof
- `js/cf-webapp/proof/reproducers/02-named-diff-sentry-import.sh` —
reproducer

### Reference
- Source commit: 36bd47b4 from PR #2536
2026-04-04 11:26:18 -05:00
Kevin Turcios
06d824d70e
proof: PrismLight switch benchmark (e249a1cf) (#2539)
## Proof of Correctness — Commit 1/22

**Optimization:** Replace full `react-syntax-highlighter/Prism` build
(300 language grammars via `refractor/all`) with PrismLight registering
only 11 used languages.

**Claim:** Client JS bundle 5,990 KB → 3,146 KB (−47.5%, −2,844 KB)

### Evidence

The default Prism import resolves to `refractor/all.js` — a barrel file
that eagerly imports grammar definitions for 300+ languages (each 3–10
KB). The app only uses 11: python, javascript, typescript, java, json,
css, html, bash, jsx, tsx, markup.

PrismLight uses `refractor/core` and requires explicit
`registerLanguage()` calls, eliminating ~289 unused grammars from the
bundle.

### Reproducer

```bash
cd js/cf-webapp
bash proof/reproducers/01-prismlight-benchmark.sh
```

This runs two real `next build` passes (baseline on main, then with only
the PrismLight diff applied) and prints the route tables side-by-side
for comparison.

### Files
- `js/cf-webapp/proof/01-prismlight-switch.md` — detailed proof document
- `js/cf-webapp/proof/reproducers/01-prismlight-benchmark.sh` —
reproducible benchmark

### Reference
- Source commit: e249a1cf from PR #2536
- [react-syntax-highlighter light build
docs](https://github.com/react-syntax-highlighter/react-syntax-highlighter#light-build)
2026-04-04 11:14:09 -05:00
mohammed ahmed
d10868e05e
Fix: Strip .js extensions from all test outputs in JS/TS testgen (#2551)
## Problem
Generated tests imported TypeScript files with `.js` extensions, causing
"Cannot find module" errors. The AI service was only stripping
extensions from `generated_test_source` but NOT from
`instrumented_behavior_tests` and `instrumented_perf_tests` (which the
CLI actually uses).

## Root Cause
**File:** `core/languages/js_ts/testgen.py:608`

Only `generated_test_source` received `strip_js_extensions()` call. The
CLI uses `instrumented_behavior_tests` from the response, which still
had incorrect `.js` extensions on TypeScript imports.

## Impact
- Affected **15 out of 20 test runs (~75% failure rate)**
- **Severity: HIGH** - systematic bug blocking all TypeScript projects
- **Error:** `Cannot find module '../../google.js'` when source is
`google.ts`

## Fix
Apply `strip_js_extensions()` to all three test output variants:
- `generated_test_source` (already done)
- `instrumented_behavior_tests`  **NEW**
- `instrumented_perf_tests`  **NEW**

## Testing
 All 32 existing JavaScript testgen tests pass
 Added regression test for extension stripping  
 Verified with `--rerun` on trace
`03899729-131e-4ff6-8149-c132bd888089`
 No "Cannot find module *.js" errors after fix

## References
**Trace IDs exhibiting this bug:**
- `03899729-131e-4ff6-8149-c132bd888089`
- `19446b34-cd22-4a38-b304-22c16ba86747`
- (and 13 others - see `/workspace/logs`)

**Related:** AI Service Reference doc section 10.1 issue #2

---------

Co-authored-by: mohammed ahmed <mohammedahmed18@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2026-04-04 16:30:41 +05:30
Aseem Saxena
c54904daf9
Merge pull request #2548 from codeflash-ai/fix/llm-close-errors
Fix: Handle LLM client close() errors gracefully
2026-04-03 14:37:35 -07:00
claude[bot]
681e8187ca fix: resolve mypy type errors in test file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 19:21:57 +00:00
claude[bot]
2135849f27 style: auto-fix linting issues
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 19:20:57 +00:00
mohammed ahmed
4c4b497d2a Fix: Handle LLM client close() errors gracefully
**Issue**: The `/ai/optimization_review` endpoint was returning 500 errors
when trying to close LLM clients during event loop changes.

**Root Cause**: In `aiservice/llm.py` lines 96-99, the `close()` calls on
OpenAI and Anthropic clients were not wrapped in exception handlers. When
the httpx transport was already closed or in a bad state (e.g., event loop
closure, connection already closed), the exception would propagate and cause
the entire request to fail with a 500 error.

**Fix**: Wrapped both `openai_client.close()` and `anthropic_client.close()`
in try-except blocks that catch and log exceptions at DEBUG level. This
prevents transport errors from crashing requests while still attempting to
clean up resources properly.

**Impact**: Fixes 500 errors on `/ai/optimization_review` and other endpoints
that use the LLM client when event loops change or clients are in bad states.

**Testing**: Added `test_llm_client_close.py` with 2 test cases that verify:
1. Transport errors during close() are handled gracefully
2. Event loop closed errors are handled gracefully

**Traces**: 312d7392, 5bbdf214, a1325051
2026-04-03 19:19:19 +00:00
mohammed ahmed
b814e1e7e6
Merge pull request #2535 from codeflash-ai/fix/llm-client-event-loop-closure
fix: close old LLM clients when event loop changes
2026-04-03 19:00:36 +02:00
mohammed ahmed
b2debb96b7
Merge branch 'main' into fix/llm-client-event-loop-closure 2026-04-03 15:31:36 +02:00
Sarthak Agarwal
9bf81e7418
aiservice logs add and misc fix to track the errors (#2530)
# Pull Request Checklist

## Description
- [ ] **Description of PR**: Clear and concise description of what this
PR accomplishes
- [ ] **Breaking Changes**: Document any breaking changes (if
applicable)
- [ ] **Related Issues**: Link to any related issues or tickets

## Testing
- [ ] **Test cases Attached**: All relevant test cases have been
added/updated
- [ ] **Manual Testing**: Manual testing completed for the changes

## Monitoring & Debugging
- [ ] **Logging in place**: Appropriate logging has been added for
debugging user issues
- [ ] **Sentry will be able to catch errors**: Error handling ensures
Sentry can capture and report errors
- [ ] **Avoid Dev based/Prisma logging**: No development-only or
Prisma-specific logging in production code

## Configuration
- [ ] **Env variables newly added**: Any new environment variables are
documented in .env.example file or mentioned in description
---

## Additional Notes
<!-- Add any additional context, screenshots, or notes for reviewers
here -->

Co-authored-by: ali <mohammed18200118@gmail.com>
2026-04-03 16:50:45 +05:30
claude[bot]
35519b6e84 fix: resolve mypy type errors in test_llm_client.py 2026-04-03 07:25:08 +00:00
claude[bot]
20b0b01994 style: auto-fix linting issues
- ruff-format: reformat test file
- fix ty type error: cast mock clients to MagicMock for assert_called_once

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 07:23:09 +00:00
Codeflash Bot
322d8736c9 fix: close old LLM clients when event loop changes
This fixes a critical bug where old AsyncAzureOpenAI and AsyncAnthropicBedrock
clients were not being closed when the event loop changed, causing:

1. Connection pool exhaustion → "couldn't get a connection after 30.00 sec"
2. RuntimeError: Event loop is closed during httpx client cleanup

Root cause:
In LLMClient.call(), when the event loop changed, new clients were created
but old clients were not properly closed, leading to connection leaks.

Fix:
- Added await client.close() for both openai_client and anthropic_client
  before creating new instances
- Added comprehensive unit tests to verify proper cleanup

Impact:
- Resolves ~150+ test generation failures (500 errors)
- Fixes event loop closure errors in aiservice logs

Trace IDs affected: 04500fbd-88e0-44e4-8d20-32f6a0dc06cc (and many others)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 07:20:37 +00:00