Inspiration
Sooner or later, someone points at your code and asks "why is this here?" or "what happens if the list is empty?" It might be an examiner in a project viva, a TA at a demo, a reviewer on a pull request, or an interviewer saying "walk me through your project."
AI coding agents changed what happens next. The code works, but more and more often the person who shipped it can't explain it. Re-reading your code the night before doesn't tell you what you can't explain, and a friend quizzing you doesn't know your code. As a software engineering student whose projects end with exactly that kind of questioning, I wanted a way to find the gaps before an examiner does.
What it does
CodeViva is a mock viva on your own code:
- Load your project. Drag in files, paste a snippet, or try the bundled sample (a C bank-token queue, a classic data-structures assignment).
- Questions are anchored to exact lines. Each question names a file and line range, and those lines light up in the code panel. The examiner asks what a real one would: edge cases, design choices, memory handling, complexity.
- Answer by typing or speaking, or press "I don't know — teach me".
- Every answer is marked Solid / Partial / Gap with feedback and a model answer. A shallow answer gets one pointed follow-up on the same lines, like an examiner pushing back.
- The report gives an ownership score out of 100 and an ownership heatmap: your code, coloured by how well you defended each examined region, plus three concrete things to revise. You can click a gap to jump to its lines, or copy the whole report as Markdown.
The examiner can be a Friendly TA or a Strict external. It speaks English by default, and non-native English speakers can choose to be examined in their own language (10 languages), so they're judged on understanding rather than fluency. With no API key, it runs a clearly labelled, scripted demo mode (the mode shown in the video).
How I built it
I built it with an AI coding agent (Claude) following the Devpost Learn Skill Pack, and the planning documents are in the repo:
scope.md: the kernel (line-anchored questions + adaptive follow-ups + heatmap), the target user, and a tight proof-of-concept boundary.prd.md: the full journey, every behaviour with acceptance criteria, and the empty, error and first-use states.spec.md: the architecture, data flow and failure modes.checklist.md: five end-to-end slices, each verified and committed separately, plus a log of every plan revision.
Stack: Node.js + Express server, vanilla HTML/CSS/JS front end (no framework, no build step), Google Gemini API (or any OpenAI-compatible API), and the browser's Web Speech API for voice answers.
The design decision I'm most happy with is that the model's output is never trusted blindly:
- The code is sent with a line number in front of every line, and the model must reply in a fixed JSON shape (
file,startLine,endLine,question). clampRangesnaps any wrong file name or out-of-range line back onto real code before it reaches the screen.- The score decides the verdict, so the stamp, the heatmap and the total can never disagree.
- The ownership score is computed by the server, not guessed by the AI: the average over questions, where a question counts the better of the original answer and its follow-up. Recovering under questioning is rewarded, like in a real viva.
- All model text is inserted with
textContent, neverinnerHTML.
There are 29 automated tests (Node's built-in test runner). They cover a fake model that returns deliberately messy JSON and line 400 of a 30-line file, the Gemini client against a mocked API, and a full viva through the HTTP API. Headless-browser walkthroughs cover desktop and phone width.
Challenges
- The browser caught bugs the unit tests didn't. At phone width, the highlight scrolled to the wrong lines because the offset was measured from the wrong element. In demo grading, the answer "150" was being counted as saying "0" (short keywords now match whole words only).
- Models change under you. The Gemini 2.5 models were shut down on Oct 16, 2026, so the default had to be a current model, made configurable, with readable errors for "model not found", bad keys and rate limits.
- Scope. It was tempting to add GitHub import, accounts and history. The Skill Pack's "now / later / cut" discipline kept the build to the one loop that proves the idea.
- Audience. My first version was framed around my own university course. I reframed it for everyone who has to explain code out loud.
What I learned
- Planning before building (scope, then PRD, then spec, then small verified slices) made the agent's work predictable and kept the build reviewable.
- For any AI feature: write down what the model must return, then write the check that rejects or repairs anything else, before building the screen that displays it.
What's next
Load a GitHub repo by URL; a spoken examiner (text-to-speech) for a fully spoken mock viva; an "explain this commit" mode for the lines an AI agent just changed; and a teacher mode that generates a viva for a student's submission.
Built With
- claude
- css3
- express.js
- gemini
- html5
- javascript
- node.js
- web-speech-api
Log in or sign up for Devpost to join the conversation.