Release/v1.1 dsa engine#33
Conversation
- Implement circular dependency detection on adjacency list - Add percentile-based file complexity heatmap to graph nodes - Introduce orphan file detection for dead code identification - Update node state interfaces and UI legends
…nents - Extract state management, LLM streaming, and graph traversal into custom hooks - Modularize UI into dedicated layout components (Visualizer, Doctor, Risk Radar) - Isolate static configurations and types into constants.ts - Strip page.tsx down to act strictly as a layout orchestrator
- Extract changed files from existing PR analysis route - Add 'pr-blast' highlight mode to React Flow ArchitectureMap - Implement automatic tab switching and state lifting for seamless UX
…ive dashboard - **Algorithms**: Shipped zero-latency, pure math static analysis features including Articulation Points (Bridge Detection), Dead Code Reachability (BFS), Dependency PageRank, and Robert C. Martin's Instability Matrix (Ca/Ce coupling). - **Architecture Insights UI**: Built the new `ArchInsightsPanel` and `InfoTooltip` to visualize critical single-points-of-failure, unreachable code chunks, and codebase stability metrics directly over the React Flow canvas. - **Pipeline Integration**: Upgraded `ast-pipeline.ts` and `analyze.ts` types to support the new graph theory outputs without triggering external API calls. - **Command Center Dashboard**: Extracted flat dashboard list into a client-side `DashboardGrid` component. Added interactive grouping by repository, analysis count badges, and chronological sorting with formatted timestamps.
…hangedFiles comment
- Add checkout API route (/api/checkout) - Add webhook handler (/api/webhooks/lemonsqueezy) - Update usage.ts to support pro tier (100/day limit) - Update analyze route to use ratelimitPro for pro users - Update chat route to bypass limit for pro users - Update analyze-pr route to bypass limit for pro users - Add ratelimitPro to ratelimit.ts - Supabase profiles table created with plan_tier column
- Add handleUpgrade function calling /api/checkout - Update tier names: Student→Intern, Architect→Specialist, Surgical→Chief Surgeon - Specialist tier now live with ₹99/mo and amber styling - Add loading state and login redirect for unauthenticated users - Remove Coming Soon badge from Specialist tier
- Free tier: context 20k -> 6k chars, max_tokens 1024 -> 512 - Pro tier: context 14k chars, max_tokens 1024, deepseek-r1 model - Reduces token usage by ~70% for free tier chat
Amber color tokens felt out of place against the dark technical aesthetic. Replaced all amber instances in RiskDashboard with the existing slate/white/transparent vocabulary used throughout the component. - Pro banner: amber border/bg → white/5 glass surface - Upgrade button: amber fills → slate-300/white hover - Locked Auto-Patch button: amber tint → desaturated slate-500 - FileCode icon: amber-400 → slate-300 with white hover - Traffic light middle dot: amber-500 → slate-500
Amber color tokens felt out of place against the dark technical aesthetic. Replaced all amber instances in RiskDashboard with the existing slate/white/transparent vocabulary used throughout the component. - Pro banner: amber border/bg → white/5 glass surface - Upgrade button: amber fills → slate-300/white hover - Locked Auto-Patch button: amber tint → desaturated slate-500 - FileCode icon: amber-400 → slate-300 with white hover - Traffic light middle dot: amber-500 → slate-500
- fix: dynamic analysis_version query instead of hardcoded v3 - fix: separate visited sets for upstream/downstream BFS traversal - fix: node ID collision in mermaid sanitizer (path-aware) - fix: opacity replaced with stroke-width in mermaid styles - fix: JSON.parse wrapped in try/catch in cache and groq-debug - fix: requiresRuntimeCheck narrowed to specific runtime patterns - fix: at async removed from framework noise filter in stack-parser - fix: findMatchingFile disambiguates same-name files by path score - perf: parallel file fetching via Promise.allSettled - perf: reverse graph memoized via WeakMap - perf: BFS queue uses head pointer instead of array.shift() - refactor: rename gemini-debug to groq-debug with backward alias - refactor: confidence removed from AI prompt, heuristics only - remove: dead code generateErrorGraph and extractAllCrashNodes - add: cache invalidation via invalidateRepoCache() - add: server-side rate limiting with 429 response
The React Flow node/edge renderer — wherever node styles and badges are applied The right analysis panel — wherever CIRCULAR DEPS / ORPHANS / NERVE CENTER are rendered The Risk Radar tab — its current state
…d as prop - Add computePageRank() helper using damped iteration (20 passes, 0.85 factor) - Normalize scores to 0-100 range for consistent tier thresholds - Add computedPageRankScores useMemo that falls back to internal computation - Replace all pageRankScores references with computedPageRankScores - Nerve Center panel now works out of the box without parent wiring
- Logged-in users now get a fresh DB row on every analysis (cached or not) so the dashboard always reflects the latest activity with correct timestamp - RAG storage still skipped for cached results to avoid redundant processing - Anon users retain original behavior (insert only on fresh analyses) Fixes: dashboard showing stale May 29 dates after re-analyzing existing repos
- Switch all routes from llama-3.3-70b-versatile to llama-3.1-8b-instant (5x higher token limit: 100K -> 500K TPD, same free tier) - Cache AI response in analyses.ai_response column after first run so repeat analysis of same repo costs 0 tokens - Tee live stream to store response without breaking streaming UX - Cap fileContents to top 20 files in gemini.ts to prevent token blowout on large repos (was sending all files unbounded)
…ty, and cfg builder
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Release v1.1 of the DSA engine: adds new graph algorithms (betweenness centrality), a control-flow-graph static analyzer, repo-type detection and graph-quality assessment, a depth-based file selector, a semantic analysis cache, several performance/perf-correctness fixes in ArchitectureMap, and switches the streaming LLM from Groq Llama-3.3-70B to Cerebras gpt-oss-120b (with smaller fallback models for non-streaming endpoints).
Changes:
- New analysis modules:
lib/algorithms/betweenness.ts,lib/cfg-builder.ts,lib/file-filter.ts,lib/analysis-cache.ts, plusgetFilesByDepthinlib/dependency-graph.ts, all wired intorunAstPipelineand surfaced throughPipelineResult/RepoData. - Pipeline hardening: PageRank uses
reduceinstead of spread to avoid call-stack blowups, source nodes are preserved when all targets are config files, local uploads now run language detection, andMAX_FILES_TO_FETCHis raised to 60. - UI:
ArchitectureMapmemoizes nodes/sidebar, splits layout vs. score memos, renders betweenness severity rings/badges, andVisualizerPanel/app/analyze/page.tsxforward the newbetweennessScoresprop; analysis-version bumped to 14 and analyze caching gains auser_idfilter and per-user insert path.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json / package-lock.json | Bump openai to ^6.40.0; add @babel/parser & @babel/types as devDeps for the new CFG builder. |
| lib/types/analyze.ts | Add betweennessScores, cfgFindings, cfgSummary to RepoData. |
| lib/pipeline/ast-pipeline.ts | Integrate file-filter, betweenness, CFG batch, depth-based selection, graph-quality metadata; misc cleanups and commented bug fixes. |
| lib/dependency-graph.ts | Add getFilesByDepth BFS selector and tidy whitespace. |
| lib/file-filter.ts (new) | Multi-layer skip / graph-node / repo-type / graph-quality filters. |
| lib/cfg-builder.ts (new) | Babel-based detector for unreachable code, missing error handling, infinite loops. |
| lib/algorithms/betweenness.ts (new) | Brandes' betweenness centrality with severity mapping & colors. |
| lib/analysis-cache.ts (new) | Helpers for HEAD-SHA fetch, staleness check, and cache invalidation. |
| lib/gemini.ts | Switch streaming model/provider to Cerebras gpt-oss-120b; cap file context to 20. |
| lib/debug/groq-debug.ts | Downgrade debug model to llama-3.1-8b-instant. |
| components/ArchitectureMap.tsx | Memoize node/sidebar, split layout/score memos, render betweenness ring/badge. |
| components/DirectoryTreeVisualizer.tsx | Move nodeTypes to module scope; minor cleanups. |
| components/analyze/VisualizerPanel.tsx | Pass betweennessScores through; show legend chip. |
| app/analyze/page.tsx | Forward betweennessScores to the visualizer. |
| app/api/analyze/route.ts | Bump ANALYSIS_VERSION, scope cache by user_id, split logged-in vs. anonymous insert/RAG paths. |
| app/api/v1/analyze/route.ts | Bump ANALYSIS_VERSION to 14. |
| app/api/ai/route.ts | Add per-user ai_response cache with tee'd stream write-back. |
| app/api/analyze-pr/route.ts, app/api/generate-test/route.ts | Switch to llama-3.1-8b-instant. |
| lib/tests/*.test.ts, lib/algorithms/tests/betweenness.test.ts | Tests for file-filter, depth selector, CFG builder, and betweenness. |
Comments suppressed due to low confidence (1)
app/api/analyze/route.ts:223
- For anonymous requests
userIdisundefined, so this becomes.eq("user_id", ""). If theuser_idcolumn isuuid, Postgres will reject the empty string and the cache query will return an error (logged as a warning and treated as a miss), so anonymous users will never get a cache hit. Additionally, even if the column accepts empty strings, anonymous rows are inserted withuser_id: null(line 281), which.eq("user_id", "")will never match. Use.is("user_id", null)whenuserIdis absent.
.eq("user_id", userId ?? "")
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .select("commit_sha, created_at") | ||
| .eq("repo_url", repoUrl) | ||
| .eq("analysis_version", ANALYSIS_VERSION) | ||
| .eq("user_id", userId ?? "") |
| for (const stmt of body.body) { | ||
| if (stmt.type === "TryStatement") { | ||
| hasTryCatch = true; | ||
| } | ||
| if (JSON.stringify(stmt).includes('"type":"AwaitExpression"')) { | ||
| hasAwait = true; | ||
| } | ||
| } |
| const eligible = fileContents.filter((f) => { | ||
| const ext = "." + f.path.split(".").pop(); | ||
| return analysableExtensions.has(ext); | ||
| }); |
| const baseGroq = new OpenAI({ | ||
| apiKey: process.env.GROQ_API_KEY!, | ||
| baseURL: "https://api.groq.com/openai/v1", | ||
| apiKey: process.env.CEREBRAS_API_KEY!, | ||
| baseURL: "https://api.cerebras.ai/v1", | ||
| }); |
| // NOTE: NON_JS_REPO removed — all languages are now supported. | ||
| // Sparse graphs show folder structure + metrics instead of failing. |
| const betweennessResult = computeBetweenness(dependencyGraph, true); | ||
| const betweennessScores: Record<string, number> = Object.fromEntries( | ||
| betweennessResult.scores, | ||
| ); |
No description provided.