Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>RepoQA</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { font-family: sans-serif; background: #0d1117; color: #e6edf3; height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; } | |
| .container { width: 100%; max-width: 720px; padding: 24px; display: flex; flex-direction: column; gap: 16px; } | |
| h1 { font-size: 20px; font-weight: 600; color: #58a6ff; } | |
| .repo-bar { display: flex; gap: 8px; } | |
| input { flex: 1; padding: 10px 14px; border-radius: 8px; border: 1px solid #30363d; background: #161b22; color: #e6edf3; font-size: 14px; outline: none; } | |
| input:focus { border-color: #58a6ff; } | |
| button { padding: 10px 18px; border-radius: 8px; border: none; background: #238636; color: white; font-size: 14px; cursor: pointer; } | |
| button:hover { background: #2ea043; } | |
| button:disabled { background: #21262d; color: #484f58; cursor: not-allowed; } | |
| .chat-box { background: #161b22; border: 1px solid #30363d; border-radius: 10px; height: 420px; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; } | |
| .msg { max-width: 85%; padding: 10px 14px; border-radius: 8px; font-size: 14px; line-height: 1.6; white-space: pre-wrap; } | |
| .msg.user { align-self: flex-end; background: #1f6feb; color: white; } | |
| .msg.bot { align-self: flex-start; background: #21262d; color: #e6edf3; } | |
| .msg.system { align-self: center; color: #8b949e; font-size: 13px; font-style: italic; } | |
| .input-bar { display: flex; gap: 8px; } | |
| #status { font-size: 13px; color: #8b949e; min-height: 18px; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>RepoQA — Chat with any GitHub Repo</h1> | |
| <div class="repo-bar"> | |
| <input id="repoUrl" placeholder="https://github.com/user/repo" /> | |
| <button id="loadBtn" onclick="loadRepo()">Load Repo</button> | |
| </div> | |
| <div id="status"></div> | |
| <div class="chat-box" id="chatBox"> | |
| <div class="msg system">Load a repo to start chatting. Type /end to reset.</div> | |
| </div> | |
| <div class="input-bar"> | |
| <input id="questionInput" placeholder="Ask something about the repo..." onkeydown="if(event.key==='Enter') sendMessage()" disabled /> | |
| <button id="askBtn" onclick="sendMessage()" disabled>Send</button> | |
| </div> | |
| </div> | |
| <script> | |
| let repoName = null; | |
| function setStatus(msg) { | |
| document.getElementById("status").textContent = msg; | |
| } | |
| function addMessage(text, type) { | |
| const box = document.getElementById("chatBox"); | |
| const div = document.createElement("div"); | |
| div.className = "msg " + type; | |
| div.textContent = text; | |
| box.appendChild(div); | |
| box.scrollTop = box.scrollHeight; | |
| } | |
| async function loadRepo() { | |
| const url = document.getElementById("repoUrl").value.trim(); | |
| if (!url) return; | |
| const btn = document.getElementById("loadBtn"); | |
| btn.disabled = true; | |
| setStatus("Loading repo... this may take a minute."); | |
| try { | |
| const res = await fetch("/load_repo", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ repo_url: url }) | |
| }); | |
| const data = await res.json(); | |
| if (res.ok) { | |
| repoName = data.repo; | |
| setStatus("Repo loaded: " + repoName); | |
| addMessage("Repo loaded successfully. Ask me anything about it.", "system"); | |
| document.getElementById("questionInput").disabled = false; | |
| document.getElementById("askBtn").disabled = false; | |
| } else { | |
| setStatus("Error: " + (data.detail || "Failed to load repo")); | |
| } | |
| } catch (e) { | |
| setStatus("Error: " + e.message); | |
| } | |
| btn.disabled = false; | |
| } | |
| async function sendMessage() { | |
| const input = document.getElementById("questionInput"); | |
| const question = input.value.trim(); | |
| if (!question || !repoName) return; | |
| if (question === "/end") { | |
| repoName = null; | |
| input.value = ""; | |
| input.disabled = true; | |
| document.getElementById("askBtn").disabled = true; | |
| document.getElementById("repoUrl").value = ""; | |
| document.getElementById("chatBox").innerHTML = '<div class="msg system">Session ended. Load a new repo to start again.</div>'; | |
| setStatus(""); | |
| return; | |
| } | |
| addMessage(question, "user"); | |
| input.value = ""; | |
| input.disabled = true; | |
| document.getElementById("askBtn").disabled = true; | |
| setStatus("Thinking..."); | |
| try { | |
| const res = await fetch("/ask", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ repo_name: repoName, question: question }) | |
| }); | |
| const data = await res.json(); | |
| if (res.ok) { | |
| addMessage(data.answer, "bot"); | |
| setStatus(""); | |
| } else { | |
| addMessage("Error: " + (data.detail || "Something went wrong"), "system"); | |
| setStatus(""); | |
| } | |
| } catch (e) { | |
| addMessage("Error: " + e.message, "system"); | |
| setStatus(""); | |
| } | |
| input.disabled = false; | |
| document.getElementById("askBtn").disabled = false; | |
| input.focus(); | |
| } | |
| </script> | |
| </body> | |
| </html> |