<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hannah Redmond</title>
    <description>The latest articles on DEV Community by Hannah Redmond (@hannah_redmond_94d6a9f987).</description>
    <link>https://dev.to/hannah_redmond_94d6a9f987</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1863761%2Feee99e8b-aaef-4a97-83d4-d19f1c19e100.jpg</url>
      <title>DEV Community: Hannah Redmond</title>
      <link>https://dev.to/hannah_redmond_94d6a9f987</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hannah_redmond_94d6a9f987"/>
    <language>en</language>
    <item>
      <title>Why I Stopped Trusting PR Line Counts (And Built a Complexity Scorer)</title>
      <dc:creator>Hannah Redmond</dc:creator>
      <pubDate>Tue, 30 Jun 2026 12:00:35 +0000</pubDate>
      <link>https://dev.to/hannah_redmond_94d6a9f987/why-i-stopped-trusting-pr-line-counts-and-built-a-complexity-scorer-p5k</link>
      <guid>https://dev.to/hannah_redmond_94d6a9f987/why-i-stopped-trusting-pr-line-counts-and-built-a-complexity-scorer-p5k</guid>
      <description>&lt;h1&gt;
  
  
  Why I Stopped Trusting PR Line Counts (And Built a Complexity Scorer)
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;A 200-file refactor and a 10-line bugfix look identical in GitHub's pull request list. That's a problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A while back, my team shipped a nasty regression. The root cause? A massive refactor PR had been sitting in the queue for three days, buried between tiny bugfixes and dependency updates. Nobody spotted it. Everyone assumed "it's just another PR."&lt;/p&gt;

&lt;p&gt;But it wasn't. It was &lt;strong&gt;2,847 lines across 56 files&lt;/strong&gt;, touching core business logic, authentication flows, and the database layer. In GitHub's UI, it looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chore: upgrade to Node 22 LTS                    +2,847 −198
fix: token expiry not refreshing on 401             +45 −12
docs: update README                                  +8 −2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three lines. Equal visual weight. One of them is a landmine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Flat PR Lists Don't Scale
&lt;/h2&gt;

&lt;p&gt;GitHub shows you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;Author&lt;/li&gt;
&lt;li&gt;Labels&lt;/li&gt;
&lt;li&gt;Line count&lt;/li&gt;
&lt;li&gt;Last updated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's useful for small teams. But when you're tracking 50+ open PRs across multiple repos, you need to know &lt;strong&gt;which ones are dangerous&lt;/strong&gt; and &lt;strong&gt;which ones need your eyes right now&lt;/strong&gt;. Line count is a terrible proxy for risk. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A 500-line change to &lt;code&gt;package-lock.json&lt;/code&gt; is trivial.&lt;/strong&gt; It's generated, mechanical, and safe to approve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A 50-line change to your auth middleware is terrifying.&lt;/strong&gt; It's small, surgical, and high-stakes.&lt;/p&gt;

&lt;p&gt;Yet in the PR list, the lockfile change looks "bigger." Your brain learns to ignore large numbers, so the genuinely risky PRs get lost in the noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Wanted
&lt;/h2&gt;

&lt;p&gt;I wanted a dashboard that could:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Score every PR for complexity&lt;/strong&gt; — not by raw lines, but by &lt;em&gt;what actually changed&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show me only PRs that need my review&lt;/strong&gt; — filter out my own PRs, drafts, and things I've already reviewed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surface blockers instantly&lt;/strong&gt; — build failures, merge conflicts, changes requested, all in one view&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work across repos&lt;/strong&gt; — one view for everything my team owns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surface failing CI/CD&lt;/strong&gt; — see which workflows are failing across branches without leaving the dashboard&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I built &lt;a href="https://review-radar.pages.dev?src=1" rel="noopener noreferrer"&gt;ReviewRadar&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Complexity Score: How It Works
&lt;/h2&gt;

&lt;p&gt;The core idea is simple: &lt;strong&gt;weight every changed file by its type, then combine churn, file count, and rewrite intensity into a single 0-100 score.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: File Relevance
&lt;/h3&gt;

&lt;p&gt;Not all files are equal. A generated lockfile shouldn't count the same as your auth service.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File type&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source code &amp;amp; tests&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.ts&lt;/code&gt;, &lt;code&gt;.tsx&lt;/code&gt;, &lt;code&gt;.py&lt;/code&gt;, &lt;code&gt;.go&lt;/code&gt;, &lt;code&gt;.rs&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Config &amp;amp; infra&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.yml&lt;/code&gt;, &lt;code&gt;.json&lt;/code&gt;, &lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;.tf&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;0.1&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.md&lt;/code&gt;, &lt;code&gt;.rst&lt;/code&gt;, &lt;code&gt;.txt&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generated / binary&lt;/td&gt;
&lt;td&gt;0.0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;node_modules/&lt;/code&gt;, &lt;code&gt;.lock&lt;/code&gt;, images, &lt;code&gt;.min.js&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This means a PR that changes &lt;code&gt;package-lock.json&lt;/code&gt; + 3 source files gets scored almost entirely on those 3 source files. The 500-line lockfile contributes virtually nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Weighted Churn
&lt;/h3&gt;

&lt;p&gt;For each relevant file, compute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;churn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;additions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deletions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per-file churn is capped at 500 lines to prevent a single enormous file from dominating the score.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: File Spread
&lt;/h3&gt;

&lt;p&gt;More files = more context to hold in your head = more complexity. We add a logarithmic file-count factor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;spread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;relevantFiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means going from 5 → 15 files matters more than going from 50 → 60.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Rewrite Intensity
&lt;/h3&gt;

&lt;p&gt;A PR that deletes 1,000 lines and adds 1,000 lines is a rewrite, not a refactor. We measure this with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;intensity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;totalChurn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;churnRatio&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;churnRatio&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;churnRatio = totalChurn / (1 + |netChange|)&lt;/code&gt;. High ratio = high rewrite intensity = higher complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Final Formula
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;weightedChurn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;5.5&lt;/span&gt;
      &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;relevantFiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
      &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="n"&gt;intensity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is a 0-100 score with clear colour bands:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Colour&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt; 15&lt;/td&gt;
&lt;td&gt;🟢 Green&lt;/td&gt;
&lt;td&gt;Trivial — safe to approve quickly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15-29&lt;/td&gt;
&lt;td&gt;🟢 Green&lt;/td&gt;
&lt;td&gt;Small — quick review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30-49&lt;/td&gt;
&lt;td&gt;🔵 Cyan&lt;/td&gt;
&lt;td&gt;Medium — standard review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50-69&lt;/td&gt;
&lt;td&gt;🟠 Amber&lt;/td&gt;
&lt;td&gt;Large — careful review needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70-89&lt;/td&gt;
&lt;td&gt;🔴 Red&lt;/td&gt;
&lt;td&gt;Complex — significant risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90+&lt;/td&gt;
&lt;td&gt;🔴 Red&lt;/td&gt;
&lt;td&gt;Very complex — break it up&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Real World Calibration
&lt;/h2&gt;

&lt;p&gt;I tested this against real PRs from my team's repos:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PR&lt;/th&gt;
&lt;th&gt;Files&lt;/th&gt;
&lt;th&gt;Lines&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Label&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bugfix: null check&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;+45 / −12&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;18&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature: webhook listener&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;+124 / −18&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dark mode toggle&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;+312 / −84&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node upgrade refactor&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;+2,847 / −198&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;73&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monorepo migration&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;+6,200 / −1,800&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very Complex&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The scores spread nicely across the 0-100 range without clustering at the top. A 300-file PR scores ~94. A typical 10-file, 3,000-line PR scores ~55-60. The scoring feels right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero Backend Philosophy (With a Server-Side Twist)
&lt;/h2&gt;

&lt;p&gt;One of my non-negotiables: &lt;strong&gt;I didn't want to run infrastructure&lt;/strong&gt; — no databases, no long-running servers, no ops burden.&lt;/p&gt;

&lt;p&gt;ReviewRadar is a Next.js app that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static-exported to Cloudflare Pages — zero server costs&lt;/li&gt;
&lt;li&gt;Uses a Cloudflare Worker to proxy all GitHub API calls&lt;/li&gt;
&lt;li&gt;Your token is encrypted with AES-GCM and stored in an &lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt;, &lt;code&gt;SameSite=Strict&lt;/code&gt; cookie — &lt;strong&gt;never in &lt;code&gt;localStorage&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;never visible to client-side JavaScript&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The Worker validates every request against a strict path allowlist — unapproved endpoints are rejected with a 403 before they reach GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ No signup required (OAuth or PAT)&lt;/li&gt;
&lt;li&gt;✅ Your token is encrypted at rest — even a compromised browser can't steal it&lt;/li&gt;
&lt;li&gt;✅ No infrastructure to manage&lt;/li&gt;
&lt;li&gt;✅ Deployed to Cloudflare Pages — global edge network, zero cold starts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; When you sign in, your token is sent once to the Worker (&lt;code&gt;POST /api/session&lt;/code&gt;). The Worker encrypts it and returns the ciphertext as an &lt;code&gt;HttpOnly&lt;/code&gt; cookie. Every subsequent API call goes through the Worker (&lt;code&gt;/api/github/*&lt;/code&gt;), which decrypts the cookie, attaches the token, and proxies the request. The raw token never touches the browser's network tab — you can verify this in DevTools yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's In the Dashboard
&lt;/h2&gt;

&lt;p&gt;Beyond complexity scoring, ReviewRadar gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Customisable table&lt;/strong&gt; — drag, drop, and show/hide any column (size, complexity, files, approvals, build status, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Needs Attention" filter&lt;/strong&gt; — instantly shows only PRs that are not yours, not drafts, not yet reviewed by you, and have no approvals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocked filter&lt;/strong&gt; — aggregates build failures, merge conflicts, and changes requested across all repos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow dashboard&lt;/strong&gt; — see your main branch's latest run plus all failing feature branches. Expand any card to inspect individual jobs and quality gates (check runs). Inline summaries show what broke without clicking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status reports&lt;/strong&gt; — visual breakdowns by author, label, status, and complexity spread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep PR drawer&lt;/strong&gt; — slide out any PR for full details, reviews, comments, and a complete complexity breakdown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-refresh&lt;/strong&gt; — optional background refresh with browser notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multilingual&lt;/strong&gt; — English, French, Polish, and Vietnamese&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;It's free, open source, and takes 30 seconds to set up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;a href="https://github.com/settings/tokens/new" rel="noopener noreferrer"&gt;GitHub Personal Access Token&lt;/a&gt; with &lt;code&gt;repo&lt;/code&gt; scope&lt;/li&gt;
&lt;li&gt;Paste it into &lt;a href="https://review-radar.pages.dev?src=2" rel="noopener noreferrer"&gt;ReviewRadar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add your repos and go&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or just explore the code: &lt;a href="https://github.com/0xC0DEM4M4N/review-radar" rel="noopener noreferrer"&gt;https://github.com/0xC0DEM4M4N/review-radar&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Love Feedback On
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Does the complexity scoring feel right for your repos?&lt;/li&gt;
&lt;li&gt;What file types should have different weights?&lt;/li&gt;
&lt;li&gt;Would you use this with GitLab, Bitbucket, or Azure DevOps?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a comment or open an issue. I'd love to hear what you think.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Next.js 16, React, TypeScript, Zustand, and Chart.js. Deployed on Cloudflare Pages.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>developer</category>
      <category>github</category>
      <category>complexity</category>
      <category>codereview</category>
    </item>
  </channel>
</rss>
