DEV Community

Om Senjalia
Om Senjalia

Posted on

We built RepoBuddy at Hacktoberfest Hack Day: Graphify + Gemma 4 tell you where to start in any repo

Every Hacktoberfest the hard part isn't writing the pull request. It's opening a repo you've never seen and figuring out where anything lives. At Hacktoberfest Hack Day Vadodara × NavraCommunity, our team (Omkumar Vaghela, Soham Kanakhara and I) built RepoBuddy to make that first hour shorter.

Try it: https://repobuddy.pages.dev/ · Code (MIT): https://github.com/omsenjalia/repobuddy

What it does

Paste a GitHub repo URL and ask "Where do I start?" RepoBuddy maps the repo into a code knowledge graph with Graphify, then has Gemma 4 answer from that graph. Because the model only sees the graph, its answers name real files and symbols instead of guessing.

How it works

  1. Clone. The FastAPI server shallow-clones the repo (git clone --depth 1).
  2. Map. graphify extract . --code-only builds graph.json with tree-sitter (no API cost), and graphify cluster-only adds a GRAPH_REPORT.md and an interactive graph.html.
  3. Ask. For each question, graphify query "<question>" returns just the relevant subgraph. That subgraph plus the report go to Gemma 4 with one rule: answer only from the graph and always name file paths.

Here's the core of /ask, trimmed:

try:
    subgraph = await run("graphify", "query", body.question, cwd=target)
except CommandError as e:
    if e.code != 4:  # 4 means no node matched (broad questions); answer from the report alone.
        raise HTTPException(500, str(e))
    subgraph = "No nodes matched this question."

prompt = f"""You are RepoBuddy, helping a first-time open-source contributor.
Answer using ONLY the code knowledge graph below. Always name real file paths.
If the graph doesn't contain the answer, say so.
<graph_report>{report[:30000]}</graph_report>
<relevant_subgraph>{subgraph[:30000]}</relevant_subgraph>
Question: {body.question}"""
Enter fullscreen mode Exit fullscreen mode

Two details that saved us during the day:

  • Concurrent maps share one build. Two people pasting the same repo used to race git clone, so we keep one asyncio.Task per repo and asyncio.shield it for every caller.
  • Model fallback. Gemma 4 runs on Ollama Cloud (gemma4:31b) by default. If you opt into the Gemini API instead and it fails, RepoBuddy falls back to Ollama, and when both fail the error names both causes, so a missing key is obvious.

Architecture

  • Website: a static Next.js site on Cloudflare Pages.
  • API: FastAPI on Render, because cloning and running graphify needs git and real processes.
  • Beta "cloud" mode: Pages Functions query Graphify Cloud's hosted MCP directly, so the whole thing runs on Cloudflare (for repos indexed in the admin's Graphify workspace).

What we'd do differently

Render's free disk is wiped on restart, so a mapped repo can disappear between questions. Right now the client just re-maps and retries. Caching graph.json somewhere persistent would make that instant.

Further reading

Built with help from Claude Code. Feedback and PRs welcome!

Top comments (0)