# Project export: GitGauge

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: By copying a GitHub link, GitGauge extracts the desired qualities of candidates to analyze qualifications for a position application.
- Devpost: https://devpost.com/software/gitgauge
- GitHub: https://github.com/SonavAgarwal/treehacks-24
- Team: 2 GitHub contributor(s) — sophiasharif (35 commits), Sonav Agarwal (34 commits)

## Devpost submission (written by the team)

### Inspiration

If you're a student recruiting for a tech role, you've likely heard of CodeSignal or Leetcode. These programs are a company's way of evaluating a candidate's technical skill. However, these methods of assessments often fail to capture a completely accurate picture of an individual's coding skills. Performance on a sole online assessment does not accurately depict abilities. In addition, job postings often ask applicants to include a GitHub link with their application in order to glean insight into the applicant's past projects. We sought to operationalize GitHub into metrics available to a recruiter, in addition to already existing programming assessments. CodeSignal and Leetcode give numeric, data-driven evaluations of performance, but examining GitHub projects can paint a more holistic picture of applicant skills.

### What it does

From a GitHub link, it assesses candidate strengths in technical fields that are specified by the recruiter. GitGauge then outputs levels of strength in the corresponding technical fields selected for examination. A user can additionally prompt GitGauge in other areas of inquiry about the applicant, and from there more evaluations can generate. One use case might be: If a sophomore in college has participated in hackathons and worked on developing apps from front to end, however lacks much formal education in algorithmic coding (often the content of Leetcode or CodeSignal interviews). This applicant is already at a significant disadvantage as opposed to a student who is able to have higher education and be trained in these particular skills. Here, online assessment not fully encapsulate skills. Not only is this a more accurate evaluation method, but is more speedy for recruiters (as opposed to having to search through a GitHub project page and lengthy blocks of code).

### How we built it

API from GitHub retrieve data, extract relevant code with TogetherAI, LLM for chatbox, algorithm to compute value.

### Challenges we ran into

Putting the scheme into action was tough. It seemed clear and doable when we looked at broadly, but we lost a bit of sleep over it! Technical challenges: One challenge we ran into was speed of analyzing all the code. Analyzing everything in sequence was too time consuming, but doing them all in parallel was too resource-intensive. We settled on a compromise of processing queries and repositories in batches, a few per inference call. Another challenge was fetching the user's data from GitHub. We couldn't just fetch all the user's repos and cloning big repos took too long. To solve this, we had to learn GraphQL to fetch the preliminary data, and we solved the issue of cloning efficiently using git sparse cloning, only cloning files our LLMs recommended.

### Accomplishments we're proud of

One thing we're proud of is how fast we were able to learn all the skills to build the project. Before this, we had next to no experience with FastAPI, GraphQL, Together.ai, Docker, and automating filesystem manipulation. Another thing we're proud of is the real time updates while the backend is doing the processing. To create these, we connected to Firebase and subscribed to a doc with changing update statuses, all in the span of an hour.

### What we learned

GraphQL, FastAPI, Together.ai, Docker

### What's next

Improve the relevant code finding algorithm. Right now, the algorithm is fed lots of code and it picks out the relevant ones. In the future, we should be able to give the algorithm a file and have it search for the relevant code by itself. Improve the speed. This can be done by parallelizing more of the computations, and refining our prompts.

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 43 recognized source files, 82 KB.
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- Firebase (technology) — detected in the code
- HTML (language) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- TypeScript (language) — detected in the code
- Docker (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (85 of 85)

```
.gitignore
.vscode/launch.json
backend/.gitignore
backend/app/__init__.py
backend/app/main.py
backend/app/models/__init__.py
backend/app/models/analysis_models.py
backend/app/models/git_models.py
backend/app/routers/__init__.py
backend/app/routers/analyze.py
backend/app/routers/helloworld.py
backend/app/routers/testing.py
backend/app/utils/__init__.py
backend/app/utils/analysis.py
backend/app/utils/config.py
backend/app/utils/github.py
backend/docker-compose.yml
backend/Dockerfile
backend/README.MD
backend/requirements.txt
frontend/.eslintrc.cjs
frontend/.gitignore
frontend/index.html
frontend/package.json
frontend/README.md
frontend/src/App.css
frontend/src/App.tsx
frontend/src/components/Bar.css
frontend/src/components/Bar.tsx
frontend/src/components/Button.css
frontend/src/components/Button.tsx
frontend/src/components/Chat.css
frontend/src/components/Chat.tsx
frontend/src/components/Dashboard.css
frontend/src/components/Dashboard.tsx
frontend/src/components/Input.css
frontend/src/components/Input.tsx
frontend/src/components/QueryBox.css
frontend/src/components/QueryBox.tsx
frontend/src/components/QueryResponseCard.tsx
frontend/src/components/Strength.css
frontend/src/components/Strength.tsx
frontend/src/data.ts
frontend/src/firebase.ts
frontend/src/fonts/CircularXX-Black.otf
frontend/src/fonts/CircularXX-BlackItalic.otf
frontend/src/fonts/CircularXX-Bold.otf
frontend/src/fonts/CircularXX-BoldItalic.otf
frontend/src/fonts/CircularXX-Book.otf
frontend/src/fonts/CircularXX-BookItalic.otf
frontend/src/fonts/CircularXX-ExtraBlack.otf
frontend/src/fonts/CircularXX-ExtraBlackItalic.otf
frontend/src/fonts/CircularXX-Italic.otf
frontend/src/fonts/CircularXX-Light.otf
frontend/src/fonts/CircularXX-LightItalic.otf
frontend/src/fonts/CircularXX-Medium.otf
frontend/src/fonts/CircularXX-MediumItalic.otf
frontend/src/fonts/CircularXX-Regular.otf
frontend/src/fonts/CircularXX-Thin.otf
frontend/src/fonts/CircularXX-ThinItalic.otf
frontend/src/index.css
frontend/src/main.tsx
frontend/src/types/types.ts
frontend/src/vite-env.d.ts
frontend/tsconfig.json
frontend/tsconfig.node.json
frontend/vite.config.ts
ui-design/index.css
ui-design/index.html
ui-design/src/CircularXX-Black.otf
ui-design/src/CircularXX-BlackItalic.otf
ui-design/src/CircularXX-Bold.otf
ui-design/src/CircularXX-BoldItalic.otf
ui-design/src/CircularXX-Book.otf
ui-design/src/CircularXX-BookItalic.otf
ui-design/src/CircularXX-ExtraBlack.otf
ui-design/src/CircularXX-ExtraBlackItalic.otf
ui-design/src/CircularXX-Italic.otf
ui-design/src/CircularXX-Light.otf
ui-design/src/CircularXX-LightItalic.otf
ui-design/src/CircularXX-Medium.otf
ui-design/src/CircularXX-MediumItalic.otf
ui-design/src/CircularXX-Regular.otf
ui-design/src/CircularXX-Thin.otf
ui-design/src/CircularXX-ThinItalic.otf
```

### Dependencies

- backend/requirements.txt: aiohttp, fastapi@==0.75.0, firebase_admin, openai, python-dotenv, together, uvicorn@==0.17.6
- frontend/package.json: @types/react@^18.2.55, @types/react-dom@^18.2.19, @typescript-eslint/eslint-plugin@^6.21.0, @typescript-eslint/parser@^6.21.0, @vitejs/plugin-react@^4.2.1, axios@^1.6.7, eslint@^8.56.0, eslint-plugin-react-hooks@^4.6.0, eslint-plugin-react-refresh@^0.4.5, firebase@^10.8.0, react@^18.2.0, react-animate-height@^3.2.3, react-code-blocks@^0.1.6, react-dom@^18.2.0, react-hook-form@^7.50.1, react-loader-spinner@^6.1.6, typescript@^5.2.2, vite@^5.1.0

### Recent commits (newest first)

- thakn god
- removed timeout
- bug fix & timeout
- add errors to realtime updates
- Update .gitignore
- leaked two keys lmao
- accidentally leaked a key im stupid
- firebase updates in real time!
- merge
- styling
- merge
- small analysis channge
- score display improvements
- more score variety
- update
- multiply score by 10
- Merge branch 'main' of https://github.com/SonavAgarwal/treehacks-24
- misc type fixes
- uncook_json uncooked
- backend gives usable form, frontend looks better

## Key source files (fetched from GitHub, selected and truncated for size)

### backend/requirements.txt

```
fastapi==0.75.0
uvicorn==0.17.6
together
python-dotenv
openai
aiohttp
firebase_admin
```

### backend/docker-compose.yml

```yaml
version: "3.8"
services:
  web:
    build: .
    command: uvicorn app.main:app --host 0.0.0.0 --port 80 --reload
    volumes:
      - .:/usr/src/app
    ports:
      - "8000:80"
    environment:
      - NAME=World

```

### backend/Dockerfile

```
# Use an official Python runtime as a parent image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /usr/src/app

# Install git
RUN apt-get update && \
    apt-get install -y git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Copy the current directory contents into the container at /usr/src/app
COPY . .

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run main.py when the container launches
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

```

### frontend/package.json

```
{
  "name": "frontend",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.6.7",
    "firebase": "^10.8.0",
    "react": "^18.2.0",
    "react-animate-height": "^3.2.3",
    "react-code-blocks": "^0.1.6",
    "react-dom": "^18.2.0",
    "react-hook-form": "^7.50.1",
    "react-loader-spinner": "^6.1.6"
  },
  "devDependencies": {
    "@types/react": "^18.2.55",
    "@types/react-dom": "^18.2.19",
    "@typescript-eslint/eslint-plugin": "^6.21.0",
    "@typescript-eslint/parser": "^6.21.0",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.56.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.5",
    "typescript": "^5.2.2",
    "vite": "^5.1.0"
  }
}

```

### frontend/src/main.tsx

```typescript
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

```

### backend/app/main.py

```python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from .routers import helloworld, analyze, testing

app = FastAPI()

# List of allowed origins (i.e., the frontend URLs that you want to allow to access your backend)
origins = [
    "http://localhost:5173",  # Adjust the port if your React app runs on a different one
    "http://localhost:3000",  # Common React development server port
    "http://localhost",
]

# Add CORSMiddleware to the application instance
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # Allows all origins
    allow_credentials=True,
    allow_methods=["*"],  # Allows all methods
    allow_headers=["*"],  # Allows all headers
)

app.include_router(helloworld.router)
app.include_router(analyze.router)
app.include_router(testing.router)

```

### frontend/src/App.tsx

```typescript
import axios from "axios";
import { useState } from "react";
import "./App.css";
import { Dashboard } from "./components/Dashboard";

function App() {
	const [name, setName] = useState<string>("");

	function fetchHelloWorld() {
		// "http://localhost:8000/analyze_account"
		return axios
			.post("http://localhost:8000/analyze_account", {
				username: name,
				queries: [
					// "How well can the candidate work with low level memory management?",
					// "Is the candidate familiar with regular expressions?",
					// "What databases is the candidate familiar with?",
					"How competent is the programmer with web development?",
					"How competent is the programmer with C++?",
					// "Can the candidate set up an authentication system?",
				],
			})
			.then((response) => {
				console.log(response);
			});
	}

	return (
		// <>
		// 	<div>
		// 		<h1>Hello World</h1>
		// 		<input
		// 			type="text"
		// 			value={name}
		// 			onChange={(e) => setName(e.target.value)}
		// 		/>
		// 		<button
		// 			onClick={() => {
		// 				fetchHelloWorld();
		// 			}}
		// 		>
		// 			Fetch
		// 		</button>
		// 	</div>
		// </>
		<Dashboard />
	);
}

export default App;

```

### frontend/vite.config.ts

```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})

```

### frontend/index.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

```

### ui-design/index.html

```html
<!DOCTYPE html>
<html>
	<head>
		<title>My Website</title>
		<link rel="stylesheet" type="text/css" href="index.css" />
	</head>
	<div class="center">

		<div class="grid-container">

			<div class="heading-subheading">
				<h1>Evaluate a new applicant</h1>
				<p>
					By copying a GitHub link, Git Good extracts the desired qualities of candidates to analyze qualifications for a position application.
				</p>
			</div>

			<div class="inner-container">

				<div class="inner-container-questions"> <!-- this is not doing spacing right -->
					<div class="question-heading"> 
						<h2>GitHub Profile Link</h2>
						<input type="text" placeholder="Paste Profile Link here" readonly>
					</div>
					<div class="question-heading"> 
						<h2>Desired Evaluation Criteria</h2>
						<div class="flex-container">
							<button class="multi-select-unfilled">Code Quality</button>
							<button class="multi-select-filled">Number of Commits</button>
							<button class="multi-select-unfilled">This is a longer one</button>
							<button class="multi-select-unfilled">Oh no make this super duper duper long</button>
						</div>
					</div>
				</div>

				<button class="submit">Analyze Profile</button>
			</div>
		</div>
	</div>
</html>

```

[26 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]