Skip to content

Feat/search console verification#37

Merged
Sidhant0707 merged 34 commits into
mainfrom
feat/search-console-verification
Jun 7, 2026
Merged

Feat/search console verification#37
Sidhant0707 merged 34 commits into
mainfrom
feat/search-console-verification

Conversation

@Sidhant0707

Copy link
Copy Markdown
Owner

No description provided.

- 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.
- 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)
Copilot AI review requested due to automatic review settings June 7, 2026 06:13
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
codeautopsy Ready Ready Preview, Comment Jun 7, 2026 6:14am

@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown

🧠 Architecture Analyzed by CodeAutopsy

Latest commit scanned: 714cfb3

View Architecture Graph

@Sidhant0707 Sidhant0707 merged commit 39086d7 into main Jun 7, 2026
4 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces SEO/search-console verification assets (Google verification meta, sitemap/robots generation) while significantly expanding the analysis pipeline with new graph metrics (betweenness centrality), CFG-based findings, stronger file filtering, and multiple performance/caching improvements across the API and UI.

Changes:

  • Add sitemap/robots + Google Search Console verification metadata, and wire next-sitemap into postbuild.
  • Expand repo analysis output with betweenness centrality + CFG findings/summary, plus graph quality metadata and improved file selection.
  • Add caching behaviors for analyses/AI responses and optimize ReactFlow visualizers to reduce expensive re-renders.

Reviewed changes

Copilot reviewed 28 out of 31 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
public/sitemap.xml Adds sitemap index for search engines.
public/sitemap-0.xml Adds first sitemap URL set for site pages.
public/robots.txt Adds crawler directives and sitemap reference.
package.json Adds next-sitemap postbuild + new deps/devDeps (incl. Puppeteer).
package-lock.json Locks dependency updates for new/updated packages.
next-sitemap.config.js Adds next-sitemap configuration for sitemap/robots generation.
lib/types/analyze.ts Extends analysis types with betweenness + CFG fields.
lib/pipeline/ast-pipeline.ts Adds filtering, graph quality, betweenness + CFG analysis, and depth-based file selection.
lib/gemini.ts Switches OpenAI-compatible endpoint/key and caps file context sent to the model.
lib/file-filter.ts Introduces repo-type detection + stricter file/graph-node gating + graph quality assessment.
lib/dependency-graph.ts Adds depth-based traversal (getFilesByDepth) for selecting important files.
lib/debug/groq-debug.ts Updates model selection for debug analysis calls.
lib/cfg-builder.ts Adds Babel-based CFG-oriented static findings extraction for JS/TS.
lib/analysis-cache.ts Adds a Supabase-backed cache utility layer (staleness + invalidation).
lib/algorithms/betweenness.ts Adds Brandes betweenness centrality + severity mapping utilities.
lib/algorithms/tests/betweenness.test.ts Adds unit tests for betweenness algorithm + severity mapping.
lib/tests/file-filter.test.ts Adds tests for new file-filter skip rules.
lib/tests/dependency-graph-depth.test.ts Adds tests for new depth-based file selection.
lib/tests/cfg-builder.test.ts Adds tests for CFG findings and summarization.
generate-og.js Adds OG image generator script using Puppeteer.
components/DirectoryTreeVisualizer.tsx Avoids recreating ReactFlow nodeTypes on each render.
components/ArchitectureMap.tsx Adds betweenness overlays + memoization/perf refactors for ReactFlow graph rendering.
components/analyze/VisualizerPanel.tsx Plumbs betweenness scores into graph view and adds a legend hint.
app/layout.tsx Adds Google verification + JSON-LD structured data in the root layout.
app/api/v1/analyze/route.ts Bumps analysis version to match updated pipeline output.
app/api/generate-test/route.ts Updates model selection for test generation.
app/api/analyze/route.ts Bumps analysis version and adjusts caching/insert behavior (incl. user scoping).
app/api/analyze-pr/route.ts Updates model selection for PR analysis.
app/api/ai/route.ts Adds AI-response cache read + background writeback to analyses.
app/analyze/page.tsx Passes betweenness scores into the visualizer panel.
Files not reviewed (1)
  • generate-og.js: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread next-sitemap.config.js
Comment on lines +1 to +25
/** @type {import('next-sitemap').IConfig} */
const config = {
siteUrl: 'https://codeautopsy-lyart.vercel.app',
generateRobotsTxt: true,
exclude: [
'/api/*',
'/auth/*',
'/dashboard',
'/dashboard/*',
'/profile',
'/history',
'/analyze',
'/pr-scan',
'/view/*',
'/actions/*',
],
robotsTxtOptions: {
policies: [
{ userAgent: '*', allow: '/' },
{ userAgent: '*', disallow: ['/api/', '/auth/', '/dashboard/', '/profile/', '/history/', '/analyze/', '/pr-scan/', '/view/'] },
],
},
};

export default config;
Comment thread app/api/ai/route.ts
Comment on lines +139 to +149
try {
const { error } = await supabase
.from("analyses")
.update({ ai_response: fullResponse })
.eq("repo_url", repoUrl)
.eq("user_id", user.id)
.order("created_at", { ascending: false })
.limit(1);

if (error) console.error("[ai] Cache store failed:", error.message);
else console.log("[ai] AI response cached for future calls");
Comment thread app/api/analyze/route.ts
Comment on lines 219 to +223
.select("result_json")
.eq("repo_url", repoUrl)
.eq("commit_sha", commitSha)
.eq("analysis_version", ANALYSIS_VERSION)
.eq("user_id", userId ?? "")
Comment thread lib/analysis-cache.ts
Comment on lines +31 to +55
export async function getLatestCommitSha(
owner: string,
repo: string,
githubToken: string,
): Promise<string | null> {
try {
const res = await fetch(
`https://api.github.com/repos/${owner}/${repo}/commits/HEAD`,
{
headers: {
Authorization: `Bearer ${githubToken}`,
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
},
next: { revalidate: 60 }, // Next.js fetch cache: 1 min
},
);

if (!res.ok) return null;
const data = await res.json();
return typeof data?.sha === "string" ? data.sha : null;
} catch {
return null;
}
}
Comment thread lib/analysis-cache.ts
Comment on lines +86 to +95
const { data: row } = await supabase
.from("analyses")
.select("commit_sha, created_at")
.eq("repo_url", repoUrl)
.eq("analysis_version", ANALYSIS_VERSION)
.eq("user_id", userId ?? "")
.gte("created_at", staleCutoff)
.order("created_at", { ascending: false })
.limit(1)
.maybeSingle();
Comment thread lib/analysis-cache.ts
Comment on lines +5 to +24
// Cache key: analyses table row keyed on (repo_url, commit_sha, analysis_version, user_id).
// This table already exists in your Supabase schema (confirmed from screenshot).
// The pipeline already reads from it via the checkCache callback in runAstPipeline.
// This module adds the three missing pieces:
// 1. getLatestCommitSha — fetches the HEAD sha from GitHub API.
// 2. isCacheStale — compares stored commit_sha vs live HEAD.
// 3. invalidateUserCache — hard-deletes rows for a (repo_url, user_id) pair.
// 4. forceReanalyze — used by /api/reanalyze route to bust cache.
//
// TTL is enforced via a Postgres partial index or a where-clause filter on
// created_at. No cron needed — stale rows are just ignored on read, and
// the nightly Supabase pg_cron cleanup (if configured) handles GC.

import { SupabaseClient } from "@supabase/supabase-js";

const CACHE_TTL_HOURS = 24;
const ANALYSIS_VERSION = 14; // keep in sync with app/api/analyze/route.ts

// ── GitHub HEAD sha ────────────────────────────────────────────────────────A

Comment on lines +612 to +613
const fanInValues = Object.values(fanIn);
const maxFanIn = fanInValues.length > 0 ? Math.max(...fanInValues) : 0;
Comment thread package.json
"husky": "^9.1.7",
"lint-staged": "^17.0.5",
"prettier": "^3.8.3",
"puppeteer": "^25.1.0",
Comment thread public/robots.txt
Comment on lines +1 to +20
# *
User-agent: *
Allow: /

# *
User-agent: *
Disallow: /api/
Disallow: /auth/
Disallow: /dashboard/
Disallow: /profile/
Disallow: /history/
Disallow: /analyze/
Disallow: /pr-scan/
Disallow: /view/

# Host
Host: https://codeautopsy-lyart.vercel.app

# Sitemaps
Sitemap: https://codeautopsy-lyart.vercel.app/sitemap.xml
Comment thread generate-og.js
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}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants