Unleashing Code Health: Our New AI-Powered Refactor Pipeline is Live!
We've just launched our cutting-edge AI-powered Refactor Pipeline, designed to proactively identify and suggest code improvements across your repositories. Dive into how we built it, the challenges we overcame (including a critical SSE stability fix!), and what's next for smarter code maintenance.
The journey of building robust software isn't just about shipping new features; it's about continuously improving the underlying codebase. Today, we're thrilled to announce a significant leap forward in that mission: the release of our new AI-powered Refactor Pipeline!
This isn't just another linter. Our Refactor Pipeline proactively scans your repositories, leveraging the power of Large Language Models (LLMs) to detect refactoring opportunities and generate actionable improvements. And while we were busy building this exciting new capability, we also took the opportunity to ship crucial stability fixes, making our real-time event streaming even more robust.
Let's pull back the curtain on this development session and explore what went into making this happen.
The Vision: Proactive Code Health
Our goal was clear: empower developers to maintain healthier codebases with less manual effort. Imagine a tool that doesn't just tell you what's broken, but what could be better, and even how to fix it. That's the promise of the Refactor Pipeline. It shifts the paradigm from reactive bug fixing to proactive code maintenance, helping teams tackle technical debt before it becomes a burden.
Building the Brain: The Refactor Pipeline Core
Bringing this vision to life required a comprehensive approach, from data modeling to intelligent generation.
Laying the Foundation: Data and Types
First, we needed a way to track refactoring efforts. We introduced new Prisma models: RefactorRun to represent a scan session and RefactorItem for each identified opportunity. These models are meticulously linked to users, tenants, and repositories, ensuring proper context and access control.
To give structure to the LLM's output and our UI, we defined a rich set of TypeScript types (src/types/refactor.ts). This includes:
RefactorPhase: To track the pipeline's progress (scan, detect, improve).RefactorCategory: Six distinct types, fromduplicate-codeanddead-codetoslow-codeandslow-query, ensuring comprehensive analysis.RefactorDifficultyandRefactorImpact: Crucial for prioritizing and tailoring improvement suggestions.
Intelligent Opportunity Detection
The heart of the pipeline lies in src/server/services/refactor/opportunity-detector.ts. Here, LLMs perform batch detection across the six defined categories. The process involves:
- Scanning: Analyzing repository code for patterns indicative of refactoring needs.
- Categorization: Assigning each finding to its relevant
RefactorCategory. - Deduplication: Ensuring we present unique, meaningful opportunities.
- Prioritization: Sorting detected items by a combination of
ImpactandDifficultyso developers can focus on the most valuable changes first.
Smart Improvement Generation
Once an opportunity is detected, the next step is to provide actionable guidance. Our src/server/services/refactor/improvement-generator.ts is designed to adapt its output based on the detected RefactorDifficulty:
- Easy: Generates a direct
patch(unified diff) that can often be applied with minimal review. - Medium: Provides a detailed
promptor step-by-step guide, ideal for more complex changes requiring developer input. - Hard: Offers a high-level
suggestionor architectural recommendation, prompting deeper discussion and planning.
This system also supports iteration and regeneration, allowing developers to refine suggestions as needed.
Orchestration and API
The entire process is orchestrated by src/server/services/refactor/pipeline.ts, an AsyncGenerator that mirrors the pattern of our existing auto-fix pipeline (scan → detect → improve). We then exposed its functionality through a robust tRPC router (src/server/trpc/routers/refactor.ts), offering seven distinct procedures for managing refactor runs, from listing and starting to regenerating and skipping items.
Bringing it to Life: The User Experience
A powerful backend needs an intuitive frontend. We built a suite of components and pages to make the Refactor Pipeline a seamless part of the developer workflow:
- Real-time Progress:
src/app/api/v1/events/refactor/[id]/route.tsprovides an SSE (Server-Sent Events) streaming endpoint, delivering live updates on scan progress, detection, and improvement generation. - Insightful Dashboards:
src/components/refactor/run-stats.tsx: Offers at-a-glance statistics on opportunities, improvements, difficulty breakdown, and completion rates.src/components/refactor/run-progress.tsx: Visualizes the pipeline's currentRefactorPhase.src/components/refactor/opportunity-card.tsx: An expandable card that intelligently displays patches, prompts, or suggestions based on the item's difficulty.
- Dedicated Pages:
src/app/(dashboard)/dashboard/refactor/page.tsx: Lists all refactor runs, with a "New Scan" dialog and automatic redirection to the detail page upon starting a scan.src/app/(dashboard)/dashboard/refactor/[id]/page.tsx: The run detail page, featuring the SSE stream, and filters for category and difficulty to help developers navigate findings.
- Seamless Integration: We added a "Refactor" link with a
Scissorsicon to the main sidebar and a dedicated "Refactor" tab to project detail pages, making the feature easily discoverable within the existing UI.
Under the Hood: Enhancing Stability and Robustness
Building new features often illuminates areas for improvement in existing systems. This session was no exception, leading to critical fixes that enhance the overall platform stability:
The Critical SSE Stream Fix: "Controller is already closed"
One of the most significant challenges we encountered was a persistent "Invalid state: Controller is already closed" error in our SSE streams, particularly during AutoFix runs. This would happen when a user navigated away from a page while the server was still processing and attempting to send events – for example, during the PR creation phase of an AutoFix run. The client-side stream would close, but the server, unaware, would try to write to a defunct connection, leading to a crash.
Our Solution: We implemented safeEnqueue and safeClose wrappers around our SSE stream controllers. These wrappers gracefully catch Controller is already closed errors, preventing crashes while allowing the underlying pipeline logic to continue uninterrupted. The stream might break for the user, but the server-side process remains stable.
This fix was initially applied to both AutoFix and the new Refactor SSE endpoints, but it's a pattern we're immediately extending to all our SSE endpoints (workflows, code-analysis, discussions, dashboard) to ensure consistent robustness across the platform.
AutoFix UI and Redirect Improvements
We also took the opportunity to refine the AutoFix experience:
- The AutoFix sidebar now correctly queries for active
autoFixRuns, ensuring real-time status updates are reflected with aWrenchicon. - Starting a new AutoFix run now correctly redirects the user to the detail page, maintaining a smooth workflow.
Tackling Tooling Nuances
Like any development journey, there were a few minor bumps:
- Next.js Turbopack: We ran into
error: unknown option '--turbopack'when attempting to usenpx next dev --turbopack. It seems Next.js 14.2.35 doesn't fully support this flag yet, so we reverted to standardnpm run devor our./scripts/dev-start.shscript. - ESLint & Suspense: We noted pre-existing ESLint configuration issues and a
useSearchParams()Suspense boundary problem in an older page. These were acknowledged and will be addressed in upcoming sessions. For now,npx next build --no-lintallowed us to move forward.
What's Next?
With the Refactor Pipeline now live, our immediate next steps include:
- End-to-end testing: Rigorous validation of a full refactor scan, ensuring SSE streaming works flawlessly.
- SSE Hardening: Applying the
safeEnqueue/safeClosepattern to all remaining SSE endpoints for maximum stability. - Security: Implementing Row Level Security (RLS) policies for
refactor_runsandrefactor_itemsinprisma/rls.sql. - Quality of Life: Addressing the pre-existing ESLint config and
useSearchParams()Suspense boundary issues. - Enhanced Customization: Considering a model selection dropdown for the refactor scan dialog, allowing users to choose their preferred LLM.
We're incredibly excited about the potential of the AI-powered Refactor Pipeline to transform how teams approach code health. It's a significant step towards a future where maintaining a clean, efficient, and robust codebase is more automated and intelligent than ever before.
Stay tuned for more updates, and happy refactoring!