<?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: Arnab Lahiri</title>
    <description>The latest articles on DEV Community by Arnab Lahiri (@sampi007able).</description>
    <link>https://dev.to/sampi007able</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%2F1319148%2F8decdf9d-d8a8-493e-93f3-4e8083237233.jpeg</url>
      <title>DEV Community: Arnab Lahiri</title>
      <link>https://dev.to/sampi007able</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sampi007able"/>
    <language>en</language>
    <item>
      <title>I Built RepoPilot: An AI-Powered Tool to Understand Codebases and Generate Tests</title>
      <dc:creator>Arnab Lahiri</dc:creator>
      <pubDate>Sun, 18 Oct 2026 21:40:28 +0000</pubDate>
      <link>https://dev.to/sampi007able/i-built-repopilot-an-ai-powered-tool-to-understand-codebases-and-generate-tests-286g</link>
      <guid>https://dev.to/sampi007able/i-built-repopilot-an-ai-powered-tool-to-understand-codebases-and-generate-tests-286g</guid>
      <description>&lt;p&gt;&lt;em&gt;How a side project evolved into a developer tool combining AST parsing, dependency graphs, repository-aware AI, and automated test generation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As developers, we've all been there.&lt;/p&gt;

&lt;p&gt;You open an unfamiliar repository. There are hundreds of files, deeply nested dependencies, unfamiliar abstractions, and barely any documentation.&lt;/p&gt;

&lt;p&gt;Before you can fix a bug or introduce a feature, you need to answer a few questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where does the actual business logic live?&lt;/li&gt;
&lt;li&gt;How are different modules connected?&lt;/li&gt;
&lt;li&gt;Which functions depend on this particular service?&lt;/li&gt;
&lt;li&gt;How can I generate meaningful tests without spending hours understanding every implementation detail?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI coding assistants have made parts of this easier. But I wanted to experiment with something more structured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if an AI assistant could first understand a repository's architecture and dependencies, then use that context to answer questions and generate tests?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's how &lt;strong&gt;RepoPilot&lt;/strong&gt; started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing RepoPilot
&lt;/h2&gt;

&lt;p&gt;RepoPilot is an AI-powered developer tool designed to help engineers explore unfamiliar codebases, understand their structure, and generate context-aware tests.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try RepoPilot:&lt;/strong&gt; &lt;a href="https://repopilotapp.com" rel="noopener noreferrer"&gt;https://repopilotapp.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of manually copying files into an AI chatbot, you can connect a repository and let RepoPilot build the context required for codebase-aware interactions.&lt;/p&gt;

&lt;p&gt;Here's what the current version offers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Repository integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Connect GitHub, GitLab, or Bitbucket repositories, including private repositories through supported OAuth integrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Codebase indexing and dependency analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RepoPilot analyzes the repository's source code, extracts structural information, and builds relationships between files and code entities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AI-powered codebase chat&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ask questions about your repository and receive answers informed by the indexed codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Context-aware unit and integration test generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select source files and generate tests based on their implementation and related dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Scenario-based test generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Describe a business scenario in natural language and let RepoPilot generate relevant test cases using repository context.&lt;/p&gt;

&lt;p&gt;The goal isn't to replace an engineer's judgment. It's to reduce the repetitive work required to understand a codebase and establish a useful testing foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Engineering Challenge: Context Is Everything
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges with AI-assisted development is context.&lt;/p&gt;

&lt;p&gt;Large repositories cannot simply be passed into an LLM prompt in their entirety.&lt;/p&gt;

&lt;p&gt;Even when a repository fits within a model's context window, providing every file is often inefficient.&lt;/p&gt;

&lt;p&gt;It increases token consumption, introduces irrelevant information, and makes it harder to focus on the specific implementation being discussed.&lt;/p&gt;

&lt;p&gt;I wanted RepoPilot to retrieve relevant code based on its actual structural relationships.&lt;/p&gt;

&lt;p&gt;That led me toward a combination of &lt;strong&gt;AST parsing, dependency graphs, and targeted context building&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Understanding Source Code with AST Parsing
&lt;/h2&gt;

&lt;p&gt;RepoPilot's indexing pipeline uses TypeScript's compiler ecosystem to analyze JavaScript and TypeScript source files, Python AST for Python source files &amp;amp; Comment-aware source scan for Java.&lt;/p&gt;

&lt;p&gt;Rather than treating code as plain text, the parser extracts structural information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imports and exports&lt;/li&gt;
&lt;li&gt;Functions and classes&lt;/li&gt;
&lt;li&gt;Method signatures&lt;/li&gt;
&lt;li&gt;Source-file relationships&lt;/li&gt;
&lt;li&gt;Relevant source-code segments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This provides a structured representation of the repository.&lt;/p&gt;

&lt;p&gt;For example, consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PaymentService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./payment.service&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paymentService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;paymentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A text-based search might identify the imported class name.&lt;/p&gt;

&lt;p&gt;An AST-based approach gives us a more reliable way to identify the import relationship and the structure of the function containing it.&lt;/p&gt;

&lt;p&gt;That information becomes valuable when deciding which related files should be included in an AI request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Building a Repository Dependency Graph
&lt;/h2&gt;

&lt;p&gt;After parsing, RepoPilot constructs a knowledge graph representing relationships within the codebase.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;checkout.ts
    |
    | imports
    v
payment.service.ts
    |
    | imports
    v
payment.gateway.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if someone requests tests for &lt;code&gt;checkout.ts&lt;/code&gt;, we don't necessarily need to provide the entire repository.&lt;/p&gt;

&lt;p&gt;We can start with the selected file and traverse relevant dependencies.&lt;/p&gt;

&lt;p&gt;This allows the context-building layer to collect the implementation details most likely to matter.&lt;/p&gt;

&lt;p&gt;The graph also creates a foundation for future capabilities such as impact analysis and architectural exploration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Building Context for the LLM
&lt;/h2&gt;

&lt;p&gt;This was one of the more interesting architectural decisions.&lt;/p&gt;

&lt;p&gt;I separated the code-analysis pipeline from the AI-generation pipeline.&lt;/p&gt;

&lt;p&gt;At a high level, the flow looks 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;Git Repository
      |
      v
Repository Parser
      |
      v
Dependency Graph
      |
      v
Context Builder
      |
      v
Prompt Builder
      |
      v
LLM Provider
      |
      v
Generated Tests / AI Responses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The context builder is responsible for identifying and collecting relevant code.&lt;/p&gt;

&lt;p&gt;The prompt builder then transforms that information into task-specific instructions.&lt;/p&gt;

&lt;p&gt;For example, generating unit tests requires a different prompt structure from answering an architectural question.&lt;/p&gt;

&lt;p&gt;Keeping these responsibilities separate makes the system easier to extend, debug, and maintain.&lt;/p&gt;

&lt;p&gt;It also allows the AI provider to evolve independently of the repository-analysis pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Generating Tests from Real Code Context
&lt;/h2&gt;

&lt;p&gt;One of RepoPilot's primary use cases is test generation.&lt;/p&gt;

&lt;p&gt;Consider a function that validates an order, checks inventory, and processes payment.&lt;/p&gt;

&lt;p&gt;A useful test suite should consider more than the happy path.&lt;/p&gt;

&lt;p&gt;It might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Valid orders&lt;/li&gt;
&lt;li&gt;Invalid input&lt;/li&gt;
&lt;li&gt;Insufficient inventory&lt;/li&gt;
&lt;li&gt;Payment failures&lt;/li&gt;
&lt;li&gt;Dependency exceptions&lt;/li&gt;
&lt;li&gt;Boundary conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By supplying the relevant implementation and dependency context, RepoPilot aims to produce more meaningful test suggestions than a generic prompt containing only a function name.&lt;/p&gt;

&lt;p&gt;The generated tests still require developer review and execution. AI-generated tests are not automatically proof of correctness.&lt;/p&gt;

&lt;p&gt;But they can significantly reduce the effort required to create an initial testing baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Scenario-Based Test Generation
&lt;/h2&gt;

&lt;p&gt;I also wanted developers to describe tests in the language of business requirements.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generate tests for a checkout flow where payment succeeds but inventory reservation fails.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;RepoPilot uses the scenario and available repository context to generate relevant test code.&lt;/p&gt;

&lt;p&gt;This is particularly useful when developers know the behavior they want to validate but haven't yet identified every implementation detail.&lt;/p&gt;

&lt;p&gt;It also helps connect business-level requirements with actual source-code behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technology Stack
&lt;/h2&gt;

&lt;p&gt;Here's a simplified view of the technologies behind RepoPilot:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vue 3, TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Python, FastAPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code analysis&lt;/td&gt;
&lt;td&gt;TypeScript Compiler API / ts-morph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repository intelligence&lt;/td&gt;
&lt;td&gt;Dependency graph and context builder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI integration&lt;/td&gt;
&lt;td&gt;Provider abstraction for LLM services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;Auth0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source integrations&lt;/td&gt;
&lt;td&gt;GitHub, GitLab, Bitbucket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background processing&lt;/td&gt;
&lt;td&gt;Asynchronous jobs and workers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One of my main goals was to keep the architecture modular.&lt;/p&gt;

&lt;p&gt;I didn't want the repository parser, context builder, and LLM integration to become one large service that would be difficult to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Building RepoPilot
&lt;/h2&gt;

&lt;p&gt;A few lessons stood out during development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Better context matters as much as better prompts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prompt engineering is useful, but identifying the correct source files and relationships is equally important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Deterministic code analysis and generative AI complement each other.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AST parsing provides structural information. LLMs help interpret that information and generate useful outputs.&lt;/p&gt;

&lt;p&gt;Neither approach needs to replace the other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AI-generated tests require validation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generated code can contain incorrect assumptions, incomplete mocks, or invalid assertions.&lt;/p&gt;

&lt;p&gt;Human review and execution remain essential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Security becomes more complicated with private repositories.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repository credentials must be handled carefully, with scoped access, secure storage, and protection against accidental exposure in logs or prompts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Building a product is different from building a prototype.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authentication, quotas, failure handling, deployment, observability, and user onboarding quickly become just as important as the AI functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;RepoPilot is still evolving.&lt;/p&gt;

&lt;p&gt;Some areas I'm interested in exploring further include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better semantic retrieval for large repositories&lt;/li&gt;
&lt;li&gt;More advanced dependency and impact analysis&lt;/li&gt;
&lt;li&gt;Test quality evaluation&lt;/li&gt;
&lt;li&gt;Improved support for different languages and frameworks&lt;/li&gt;
&lt;li&gt;More intelligent, repository-aware development workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm deliberately keeping production preview execution out of the initial public release while I validate the security, infrastructure, and operational requirements.&lt;/p&gt;

&lt;p&gt;For now, the focus is on repository intelligence and AI-assisted testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'd Love Feedback from Other
&lt;/h2&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
