Inspiration

Developers regularly inherit unfamiliar repositories, review changes in code they did not write, and debug failed pipelines with limited context. Before making even a small change, they may need to search through dozens of files, trace imports manually, identify entry points, and determine which parts of the system depend on one another.

We built ctrl-why to make that process faster and less intimidating. Our goal was to create a developer tool that answers three practical questions:

  • What does this repository do?
  • What could break if this code changes?
  • Why did the build or test pipeline fail?

Instead of focusing on generating more code, our project focuses on helping developers understand the code they already have.

What It Does

A developer submits a public GitHub repository URL. The application safely downloads the repository into temporary storage (workspace), analyzes its supported source files, and creates a structured representation of the codebase.

The resulting dashboard provides:

  • A repository file explorer
  • A structural repository overview
  • An interactive dependency and function-call graph
  • Repository questions answered with supporting file and line references
  • Git diff impact analysis
  • Risk and security warnings for proposed changes
  • Suggested files and tests to review
  • CI/CD failure explanations grounded in pipeline logs and repository code

The application currently supports Python, JavaScript, TypeScript, and TSX repositories.

How We Built It

The frontend uses Next.js, TypeScript, Tailwind-compatible styling, and React Flow. It is organized into four main workspaces:

  • Explore for architecture and dependencies
  • Ask for repository questions
  • Review Change for Git diff analysis
  • Debug CI for pipeline failure investigation

The backend uses Python and FastAPI. Repositories are downloaded into temporary, isolated workspaces with limits on download size, expanded size, file count, and individual source-file size. Repository code is never executed.

We use Tree-sitter to parse supported languages and extract:

  • Files and languages
  • Functions, methods, classes, interfaces, and type aliases
  • Imports
  • Internal function calls
  • Symbol locations
  • Source code chunks

This information is stored in an in-memory, graph-friendly index. Files, symbols, and external modules become graph nodes, while containment, import, and call relationships become graph edges.

Repository questions use retrieval rather than sending the entire repository at once to prevent latency. Relevant code chunks are selected from a local vector index and supplied as bounded context. Answers include the filenames and line ranges supporting their claims.

The change and review workflow parses a pasted unified Git diff, maps changed lines to indexed symbols, and traverses dependency relationships to find affected files. It also generates a risk score, finds suspicious added-line patterns, and recommends tests.

The CI/CD workflow extracts errors, failed commands, and file references from pasted logs. It classifies the failure, retrieves related repository code, and presents log evidence separately from source code evidence.

The Role Codex Played

Codex worked as a development partner throughout the project rather than as a one-time code generator. We divided the project into small phases and reviewed each phase before continuing.

Codex helped us:

  • Design boundaries between ingestion, parsing, indexing, retrieval, and presentation
  • Trace defects across the frontend and backend
  • Improve the dependency graph after early versions were difficult to read
  • Add tests for repository ingestion, parsing, indexing, chat, diff analysis, and CI analysis

Codex also influenced several decisions. For example, we chose temporary workspaces and an in memory index for the MVP instead of introducing PostgreSQL and Neo4j immediately. We prioritized bounded retrieval over sending entire repositories to a model. We also separated deterministic analysis from generated explanations so that dependency tracing, evidence collection, and basic CI classification continue to work without an external provider.

Our workflow generally looked like this:

  • Agree on one development phase
  • Inspect the current codebase and teammate changes
  • Discuss the architecture and files involved
  • Implement only that phase
  • Run backend tests, TypeScript checks, and a production build
  • Review, commit, and push before continuing

Codex Usage Evidence

Evidence is present within the project repository README.md.

Challenges We Faced

Building a Useful Dependency Graph

Extracting imports was relatively straightforward, but displaying them clearly was not. Early graph versions became crowded and showed counts such as “4 imports” without explaining which relationships those counts represented.

We redesigned the visualization around different levels of detail. The architecture view groups related files into components, while the file and call views expose more specific relationships. Selecting an edge now reveals the underlying imports or calls, including source files and line numbers.

Resolving Relationships Across Languages

Python and TypeScript use different import conventions, extensions, and module-resolution rules. We needed separate resolution logic while maintaining a shared internal graph format. We intentionally kept resolution conservative: uncertain relationships are labeled with lower confidence instead of being presented as facts.

Balancing Scope and Demo Quality

Our original proposal included persistent graph databases, automatic GitHub pull-request reviews, direct CI integrations, bug investigation, patch generation, and an editor extension. Implementing everything would have weakened the core demo.

We focused on the smallest complete workflow: connect a repository, understand its architecture, ask grounded questions, inspect a diff, and investigate a failed pipeline. The architecture remains modular so the omitted integrations can be added later.

What We Learned

We learned that repository understanding is not one problem but instead a combination of parsing, relationship resolution, retrieval, visualization, and careful communication of uncertainty.

We also learned that a useful developer tool needs evidence, not just confident explanations. Showing a filename, line range, graph relationship, or matching log entry makes the output easier to verify and more valuable during code review.

From a product perspective, we learned to prioritize vertical slices. A smaller feature that works from the repository URL through the final dashboard is more compelling than several disconnected prototypes.

Finally, we learned how valuable an incremental Codex workflow can be. Treating Codex as a collaborative engineering partner while reviewing changes, running tests, and making scope decisions ourselves helped us move quickly without losing control of the architecture.

What’s Next

Future improvements could include:

  • Direct GitHub pull-request and GitHub Actions integration
  • Persistent repository indexes
  • Deeper API, database, and external-service detection
  • Dead-code and vulnerability analysis
  • Stack-trace and bug-report investigation
  • Human-approved patch generation
  • Team authentication and saved projects
  • A VS Code extension

The long-term vision is a tool that gives every developer the context of a senior engineer who already understands the repository.

Built With

Share this project:

Updates