Feat/seo improvements#36
Merged
Merged
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
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR expands the app’s SEO surface (sitemaps/robots/structured data/OG image) while also significantly enhancing the repository analysis pipeline and UI (new graph metrics, CFG findings, caching behavior, and rendering performance optimizations).
Changes:
- Add SEO assets and generation hooks (sitemap + robots + JSON-LD + OG image generation script).
- Enhance analysis pipeline outputs (betweenness centrality, CFG findings/summary, depth-based file selection, improved file filtering, graph quality metadata).
- Add/adjust caching behaviors (analysis row insertion behavior, AI response caching) and optimize graph UI rendering.
Reviewed changes
Copilot reviewed 6 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| public/sitemap.xml | Adds sitemap index entry. |
| public/sitemap-0.xml | Adds initial URL sitemap entries with lastmod/changefreq/priority. |
| public/robots.txt | Adds robots rules + sitemap pointer. |
| next-sitemap.config.js | Adds next-sitemap configuration (currently exported as ESM). |
| package.json | Adds postbuild sitemap generation and new deps/devDeps. |
| package-lock.json | Locks new dependencies and transitive changes. |
| lib/types/analyze.ts | Extends RepoData with new analysis outputs (betweenness/CFG). |
| lib/pipeline/ast-pipeline.ts | Expands pipeline: filtering, depth selection, betweenness, CFG, graph quality metadata, caching-related tweaks. |
| lib/gemini.ts | Switches upstream LLM endpoint/key and caps context files. |
| lib/file-filter.ts | Introduces stricter file filtering + repo type detection + graph quality assessment. |
| lib/dependency-graph.ts | Minor cleanup + adds getFilesByDepth helper. |
| lib/debug/groq-debug.ts | Changes model used for debug analysis. |
| lib/cfg-builder.ts | Adds CFG static analysis module for JS/TS. |
| lib/analysis-cache.ts | Adds semantic cache utilities and GitHub SHA staleness checking. |
| lib/algorithms/betweenness.ts | Adds betweenness centrality algorithm + severity helpers. |
| lib/algorithms/tests/betweenness.test.ts | Adds unit tests for betweenness implementation. |
| lib/tests/file-filter.test.ts | Adds tests for new filtering rules. |
| lib/tests/dependency-graph-depth.test.ts | Adds tests for depth-based file selection. |
| lib/tests/cfg-builder.test.ts | Adds tests for CFG builder and summaries. |
| generate-og.js | Adds Puppeteer-based OG image generation script. |
| components/DirectoryTreeVisualizer.tsx | ReactFlow perf improvement (stable nodeTypes) and small styling tweaks. |
| components/ArchitectureMap.tsx | Adds betweenness visualization and multiple performance optimizations/memoization changes. |
| components/analyze/VisualizerPanel.tsx | Passes betweenness scores through + adds a small legend chip. |
| app/layout.tsx | Adds JSON-LD structured data and refines metadata formatting. |
| app/api/v1/analyze/route.ts | Bumps analysis version. |
| app/api/generate-test/route.ts | Changes model used for test generation. |
| app/api/analyze/route.ts | Bumps version + changes caching/insert logic + adds user-scoped cache filter. |
| app/api/analyze-pr/route.ts | Changes model used for PR analysis. |
| app/api/ai/route.ts | Adds AI response caching (stream tee + DB update). |
| app/analyze/page.tsx | Wires betweenness scores into the visualizer. |
Files not reviewed (1)
- generate-og.js: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }, | ||
| }; | ||
|
|
||
| export default config; |
Comment on lines
+1
to
+16
| import puppeteer from "puppeteer"; | ||
| import path from "path"; | ||
| import { fileURLToPath } from "url"; | ||
|
|
||
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
|
|
||
| const html = `<!DOCTYPE html><html><head><meta charset="UTF-8" /><style>* { margin: 0; padding: 0; box-sizing: border-box; } body { width: 1200px; height: 630px; overflow: hidden; background: #0e0e0e; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } .root { width: 1200px; height: 630px; background: #0e0e0e; display: flex; flex-direction: column; justify-content: center; padding: 56px 80px; position: relative; overflow: hidden; } .grid { position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,0.022) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.022) 1px, transparent 1px); background-size: 64px 64px; -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 50%, black 40%, transparent 100%); pointer-events: none; } .top { display: flex; flex-direction: column; position: relative; z-index: 1; } .logo-row { display: flex; align-items: center; gap: 10px; margin-bottom: 44px; } .logo-mark { font-size: 18px; color: #e2e8f0; font-weight: 600; letter-spacing: -0.3px; } .logo-mark span { color: #334155; } .logo-sep { width: 1px; height: 16px; background: #1e293b; margin: 0 4px; } .logo-url { font-size: 13px; color: #334155; font-family: monospace; letter-spacing: 0.02em; } .eyebrow { font-size: 12px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: #334155; margin-bottom: 20px; } .headline { font-size: 76px; font-weight: 700; line-height: 1.04; letter-spacing: -3px; margin-bottom: 24px; } .headline .l1 { display: block; color: #f1f5f9; } .headline .l2 { display: block; color: #1e293b; } .sub { font-size: 17px; color: #475569; font-weight: 400; line-height: 1.5; max-width: 780px; letter-spacing: -0.2px; } .bottom { display: flex; align-items: flex-end; justify-content: space-between; position: relative; z-index: 1; } .tags { display: flex; gap: 8px; } .tag { font-size: 12px; font-weight: 500; color: #334155; border: 1px solid #1e293b; border-radius: 4px; padding: 5px 12px; letter-spacing: 0.03em; font-family: monospace; } .stats { display: flex; align-items: center; gap: 28px; } .stat { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; } .stat-val { font-size: 22px; font-weight: 700; color: #e2e8f0; letter-spacing: -0.5px; line-height: 1; } .stat-label { font-size: 11px; color: #334155; text-transform: uppercase; letter-spacing: 0.12em; font-weight: 500; } .stat-sep { width: 1px; height: 32px; background: #1e293b; }</style></head><body><div class="root"><div class="grid"></div><div class="top"><div class="logo-row"><span class="logo-mark">Code<span>Autopsy</span></span><div class="logo-sep"></div><span class="logo-url">codeautopsy-lyart.vercel.app</span></div><div class="eyebrow">AI Code Intelligence</div><div class="headline"><span class="l1">Understand any codebase</span><span class="l2">before it understands you.</span></div><div class="sub">Architecture maps · Dependency graphs · Fragile points · Execution flows</div></div><div class="bottom"><div class="tags"><div class="tag">dependency-graph</div><div class="tag">fragile-points</div><div class="tag">bridge-detection</div><div class="tag">cfg-analysis</div></div><div class="stats"><div class="stat"><span class="stat-val">75+</span><span class="stat-label">GitHub Stars</span></div><div class="stat-sep"></div><div class="stat"><span class="stat-val">1,300+</span><span class="stat-label">Clones</span></div><div class="stat-sep"></div><div class="stat"><span class="stat-val">Free</span><span class="stat-label">To Use</span></div></div></div></div></body></html>`; | ||
|
|
||
| const browser = await puppeteer.launch({ headless: true }); | ||
| const page = await browser.newPage(); | ||
| await page.setViewport({ width: 1200, height: 630, deviceScaleFactor: 2 }); | ||
| await page.setContent(html, { waitUntil: "networkidle0" }); | ||
| const outputPath = path.join(__dirname, "public", "og-image.png"); | ||
| await page.screenshot({ path: outputPath, clip: { x: 0, y: 0, width: 1200, height: 630 } }); | ||
| await browser.close(); | ||
| console.log(`OG image generated → ${outputPath}`); |
Comment on lines
5
to
12
| "scripts": { | ||
| "dev": "next dev", | ||
| "build": "next build", | ||
| "start": "next start", | ||
| "lint": "eslint", | ||
| "prepare": "husky" | ||
| "prepare": "husky", | ||
| "postbuild": "next-sitemap" | ||
| }, |
Comment on lines
+10
to
12
| "prepare": "husky", | ||
| "postbuild": "next-sitemap" | ||
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.