<?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: Ratish jain</title>
    <description>The latest articles on DEV Community by Ratish jain (@ratishjain12).</description>
    <link>https://dev.to/ratishjain12</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%2F1196246%2Fe1f4bfe6-6942-4507-8234-b7366b5e6bd0.jpeg</url>
      <title>DEV Community: Ratish jain</title>
      <link>https://dev.to/ratishjain12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ratishjain12"/>
    <language>en</language>
    <item>
      <title>I built a CLI that learns from your past bugs — here's how the scoring works</title>
      <dc:creator>Ratish jain</dc:creator>
      <pubDate>Tue, 16 Jun 2026 10:38:44 +0000</pubDate>
      <link>https://dev.to/ratishjain12/i-built-a-cli-that-learns-from-your-past-bugs-heres-how-the-scoring-works-1g3i</link>
      <guid>https://dev.to/ratishjain12/i-built-a-cli-that-learns-from-your-past-bugs-heres-how-the-scoring-works-1g3i</guid>
      <description>&lt;p&gt;The problem with AI-assisted debugging isn't Claude. It's the 10 minutes &lt;em&gt;before&lt;/em&gt; you even open Claude — manually hunting through 300 files to figure out which 5 are actually relevant.&lt;/p&gt;

&lt;p&gt;My debugging loop used to look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Error fires in production&lt;/li&gt;
&lt;li&gt;Open the repo — 300 files staring back at me&lt;/li&gt;
&lt;li&gt;Spend 10 minutes manually figuring out which 5 files are actually relevant&lt;/li&gt;
&lt;li&gt;Copy those files into Claude&lt;/li&gt;
&lt;li&gt;Claude gives a great answer&lt;/li&gt;
&lt;li&gt;Repeat tomorrow with a different error&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step 3 was the bottleneck. Not the AI — the archaeology before the AI.&lt;/p&gt;

&lt;p&gt;So I built &lt;code&gt;dug&lt;/code&gt; — a CLI that does that context-gathering step automatically, and gets better at it every time you fix a bug.&lt;/p&gt;




&lt;h2&gt;
  
  
  What dug actually does
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dug init          &lt;span class="c"&gt;# indexes your codebase once&lt;/span&gt;
dug &lt;span class="s2"&gt;"your error"&lt;/span&gt;  &lt;span class="c"&gt;# generates a Claude Code prompt with ranked file context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That second command outputs something like this — on the dug codebase itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;dug "language detection returning wrong languages includes python in typescript project"

&lt;span class="gu"&gt;## Bug Report&lt;/span&gt;

&lt;span class="gs"&gt;**Error:**&lt;/span&gt; language detection returning wrong languages includes python in typescript project

&lt;span class="gs"&gt;**Files to investigate (ranked by relevance):**&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; src/dug/__main__.py  (modified in relevant recent commit, semantic match 3.36/5)
&lt;span class="p"&gt;  -&lt;/span&gt; src/dug/graph.py     (semantic match 2.00/5)
&lt;span class="p"&gt;  -&lt;/span&gt; src/dug/chunker.py   (semantic match 1.51/5)

&lt;span class="gs"&gt;**Recent commits touching these files:**&lt;/span&gt;
  0560e92: "fix: language detection now respects ignore_paths"  (0d ago)

&lt;span class="gs"&gt;**Suggested starting point:**&lt;/span&gt;
  Begin at src/dug/__main__.py.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;__main__.py&lt;/code&gt; is exactly where the bug lived — in a function called &lt;code&gt;_detect_languages()&lt;/code&gt;. The tool found it from a plain English description with no file names, no line numbers, no stack trace.&lt;/p&gt;

&lt;p&gt;Here's how.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three-layer scoring system
&lt;/h2&gt;

&lt;p&gt;dug doesn't just grep. It combines three independent signals into a single relevance score for every file in your repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1 — Structural scoring
&lt;/h3&gt;

&lt;p&gt;During &lt;code&gt;dug init&lt;/code&gt;, dug builds a directed graph of your codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FILE nodes   →  SYMBOL nodes (functions, classes)
FILE nodes   →  FILE nodes (imports)
COMMIT nodes →  FILE nodes (recently changed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At query time, dug extracts signals from your error text — file names mentioned, symbol names, error type — and walks this graph:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Points&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File directly mentioned in error&lt;/td&gt;
&lt;td&gt;+10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File imports the mentioned file&lt;/td&gt;
&lt;td&gt;+8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File modified in a commit matching the error&lt;/td&gt;
&lt;td&gt;+8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File modified in any recent commit&lt;/td&gt;
&lt;td&gt;+2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This alone gets you far. A &lt;code&gt;NullPointerException in UserService&lt;/code&gt; will score &lt;code&gt;UserService.java&lt;/code&gt; highly just from the graph — no ML required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2 — Semantic scoring
&lt;/h3&gt;

&lt;p&gt;Structural scoring fails when the error text doesn't match file names. "checkout is failing with a null value" won't grep-match anything useful.&lt;/p&gt;

&lt;p&gt;During &lt;code&gt;dug init&lt;/code&gt;, every function body gets embedded using &lt;a href="https://github.com/qdrant/fastembed" rel="noopener noreferrer"&gt;fastembed&lt;/a&gt; (ONNX-based, no PyTorch, runs fully local) and stored in &lt;a href="https://lancedb.github.io/lancedb/" rel="noopener noreferrer"&gt;LanceDB&lt;/a&gt;. At query time, the error text gets embedded with the same model and a cosine similarity search finds the most semantically related functions.&lt;/p&gt;

&lt;p&gt;The model is &lt;code&gt;sentence-transformers/all-MiniLM-L6-v2&lt;/code&gt; — 384 dimensions, fast on CPU. Semantic hits add up to +5 points based on similarity score.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3 — History boost
&lt;/h3&gt;

&lt;p&gt;This is the part that makes dug different from every other code search tool.&lt;/p&gt;

&lt;p&gt;After you fix a bug, you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dug solved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It shows what it suggested and asks which files actually had the fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Last query: "language detection returning wrong languages"
Suggested files were:
  - src/dug/__main__.py
  - src/dug/graph.py

Which files actually contained the bug? (comma-separated paths)
&amp;gt; src/dug/__main__.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gets saved to &lt;code&gt;.dug/history.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bug_input"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"language detection returning wrong languages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"None"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resolved_files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src/dug/__main__.py"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"solve_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"last_solved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-06-16T10:23:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next time a similar error comes in, &lt;code&gt;find_similar_past_bugs()&lt;/code&gt; scores it against every entry in history:&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;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_similarity&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;
      &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;signal_overlap&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.25&lt;/span&gt;    &lt;span class="c1"&gt;# shared files/symbols between queries
&lt;/span&gt;      &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;error_type_match&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;   &lt;span class="c1"&gt;# exact error class gives a bonus
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Text similarity uses a blend of character-level SequenceMatcher and word-level Jaccard with CamelCase/snake_case splitting — so &lt;code&gt;NullPointerException&lt;/code&gt; and &lt;code&gt;null pointer in config&lt;/code&gt; score as similar even without shared substrings.&lt;/p&gt;

&lt;p&gt;Files from matching past bugs get up to &lt;strong&gt;+6 points&lt;/strong&gt;, scaled by similarity:&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;boost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;6.0&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="n"&gt;similarity_score&lt;/span&gt;
&lt;span class="c1"&gt;# 0.9 similar → +5.4 points
# 0.5 similar → +3.0 points
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On top of that, there's an error pattern boost — if &lt;code&gt;UserService.java&lt;/code&gt; appeared in 8 of 10 past &lt;code&gt;NullPointerException&lt;/code&gt; fixes, it gets an extra +0–3 points from that pattern alone, independent of text similarity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "learning" is the right word
&lt;/h2&gt;

&lt;p&gt;Fresh install, dug is good. After 20 bugs marked solved, dug is better for your specific codebase. After 100 bugs, it knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ImportError&lt;/code&gt; almost always means &lt;code&gt;__main__.py&lt;/code&gt; in this project&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TypeError undefined&lt;/code&gt; almost always means &lt;code&gt;api/client.ts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The auth bug that keeps coming back always starts in &lt;code&gt;src/auth/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not ML training in the PyTorch sense. It's weighted frequency built from your team's actual debugging history. Stateless tools like grep can't do this — they have no memory. dug does.&lt;/p&gt;




&lt;h2&gt;
  
  
  Zero LLM calls
&lt;/h2&gt;

&lt;p&gt;The entire pipeline — graph traversal, vector search, history lookup, scoring, prompt assembly — runs locally. No API key. No network requests. No latency.&lt;/p&gt;

&lt;p&gt;The LLM call happens &lt;em&gt;after&lt;/em&gt;, when you paste the output into Claude Code. dug's job is purely context assembly.&lt;/p&gt;

&lt;p&gt;This means it works offline, costs nothing to run, and produces deterministic output you can inspect and debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS&lt;/span&gt;
brew tap ratishjain12/dug
brew trust ratishjain12/dug
brew &lt;span class="nb"&gt;install &lt;/span&gt;dug-cli

&lt;span class="c"&gt;# Python users&lt;/span&gt;
pipx &lt;span class="nb"&gt;install &lt;/span&gt;dug-cli

&lt;span class="c"&gt;# Linux / macOS one-liner&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/ratishjain12/dug/main/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supports Python, TypeScript, JavaScript, Java.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/ratishjain12/dug" rel="noopener noreferrer"&gt;github.com/ratishjain12/dug&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sentry / error tracker integration&lt;/strong&gt; — &lt;code&gt;dug sentry &amp;lt;issue-url&amp;gt;&lt;/code&gt; fetches the stack trace directly. Eliminates copy-paste entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP server&lt;/strong&gt; — expose dug as an MCP tool so Claude Code can call it mid-session directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Call graph edges&lt;/strong&gt; — use jedi to add SYMBOL→SYMBOL edges for Python. Callers of the broken function get scored too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VSCode extension&lt;/strong&gt; — highlight error text, right-click, "Generate dug prompt."&lt;/p&gt;




&lt;p&gt;If you try it, run &lt;code&gt;dug solved&lt;/code&gt; after your first fix — that's what starts the learning loop. The first few times it's just bookkeeping. By week two it's noticeably better at predicting where your bugs live.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions about the architecture or scoring? Happy to go deeper in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devtools</category>
      <category>opensource</category>
      <category>claude</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
