This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
I built Haunted Git Blame, a local-first Git history seance that turns the recent history of a software repository into a spooky, traceable case file.
The idea began with a simple question: if a codebase could remember everything that happened inside it, what kind of ghost story would it tell?
A repository already contains the ingredients of a haunting. There are abandoned branches, unfinished features, repeated fixes, sudden bursts of activity, long silences, and commit messages written by people who may have moved on to other projects. Haunted Git Blame reads those traces and gives them an atmosphere without pretending that the software can literally know a developer's intentions.
The user pastes the path to a local Git repository. The app reads up to 18 recent commits and collects bounded metadata:
- Commit hashes
- Short commit hashes
- Author names
- Commit dates
- Commit subjects
- Files changed
- Insertions and deletions
That evidence becomes a visual report. The interface shows a recovered transmission, a mood, cited commit hashes, and a chronological commit timeline. The generated narrative is always tied back to real commits so the experience stays playful without becoming completely ungrounded.
The project interprets Ghost in the Machine in two ways:
- The repository is treated like a haunted archive. Its commits are the footprints left behind by people and decisions that are no longer visible in the present code.
- The AI itself is deliberately kept local and replaceable. The “ghost” does not need to live on a remote server. It can run on the builder's own machine, even when the internet is unavailable.
The visual design follows that idea. Haunted Git Blame looks like a damaged local archive rather than a conventional dashboard: dark paper, ember-red signals, scanlines, faint noise, warning stamps, old terminal typography, and a timeline that makes every commit feel like a recovered mark.
Demo
Local demo: Run the project locally and open:
The project is intentionally designed as a local application because privacy is part of the demo. To run it:
npm install
npm run build
npm start
Then paste the path to a local Git repository with at least one commit.
For an Ollama-backed demo, configure an installed local model before starting the server:
$env:OLLAMA_MODEL = "tinyllama:latest"
$env:OLLAMA_URL = "http://127.0.0.1:11434/api/generate"
npm start
The application has also been tested in fallback mode with Ollama unavailable or configured with a model that is not installed. In that case, the interface remains functional and produces a built-in local archive narration instead of an empty result.
Code
Repository: [https://github.com/HarshDev-07/Git-Haunted-Blame]
The project is structured as a small Node.js and TypeScript application with a plain browser client:
src/
ai.ts Ollama adapter, response normalization, and offline archive voices
git.ts Safe Git inspection and commit parsing
server.ts Local HTTP server and API route
types.ts Shared response types
public/
index.html Accessible application structure
app.css Offline-safe haunted archive visual system
app.js Browser interaction and report rendering
README.md Setup, privacy, troubleshooting, and challenge documentation
The main implementation is intentionally readable. There is no large framework hiding the important behavior and no hosted service required to understand the full request path.
The project uses:
- Node.js
- TypeScript
- Native Node HTTP APIs
- Native
fetchfor the Ollama request - The installed Git command-line tool for repository inspection
- Ollama-compatible local inference
- Vanilla HTML, CSS, and JavaScript for the interface
The server invokes Git with argument arrays rather than interpolating a user-provided path into a shell command. The project does not clone, fetch, push, commit, or modify the repository.
The repository response is also privacy-conscious. The server uses the absolute path locally to inspect the requested repository, but the browser-facing API returns only the repository folder name. The complete local path is not returned to the client.
The Ollama endpoint is restricted to local loopback addresses such as localhost, 127.0.0.1, and ::1. Remote endpoints and embedded credentials are rejected before commit metadata is sent.
How I Built It
Haunted Git Blame is built around local Ollama inference. Ollama provides a local HTTP endpoint that can run open-weight models on the user's own machine. The exact model is configurable, so the app is not tied to one provider or one model family.
The default configuration expects:
http://127.0.0.1:11434/api/generate
The user can choose an installed model through the OLLAMA_MODEL environment variable. During development, I verified the application with an installed tinyllama:latest model. A different local model can be used without changing the browser interface or Git adapter.
The flow is deliberately bounded:
- The user selects a local repository by entering its path.
- The server validates the directory and checks that Git can inspect it.
- Git returns a maximum of 18 recent commits.
- The server extracts metadata and short statistics rather than reading the entire source tree.
- That structured commit evidence is placed into a carefully scoped prompt.
- Ollama is asked to return JSON containing a title, message, mood, and evidence hashes.
- The app validates the response and keeps only evidence that matches real commits.
- The browser renders the result as a recovered transmission and timeline.
The prompt instructs the model to stay within the supplied evidence. It asks for exact commit hashes and tells the model not to invent people, files, or events. The application still treats model output as interpretation rather than fact, which is why the cited hashes remain visible in the interface.
The AI adapter also handles the reality of local inference. A local model may be unavailable, may not be installed, may take too long, or may return malformed JSON. These conditions should not destroy the whole application. Instead, the adapter falls back to the built-in archive cabinet.
The offline cabinet contains several deterministic voices chosen from repository signals:
- The first and final breath for a repository with one commit.
- The silent maintainer for a repository whose latest commit is more than a year old.
- The repeated footsteps when one author accounts for a long sequence of commits.
- The unfinished room when the recent history contains substantial code churn.
- The repository remembers for a quieter mixed history.
This means the project has two useful modes:
- Ollama mode: a local open-weight model creates the atmospheric interpretation.
- Local archive mode: built-in text produces an offline, deterministic experience without AI inference.
The second mode is not just a backup for a broken demo. It is an important part of the product design. A local-first tool should remain useful when the model is missing, the laptop is offline, or the user does not have enough hardware to run a larger model.
The browser interface uses no external fonts, images, stylesheets, or JavaScript services. The haunted visual language is made with local CSS: scanlines, noise, archival borders, ember colors, signal bars, subtle flicker, and a responsive timeline. This keeps the presentation available when the internet is switched off as well.
Why Does Open Innovation Matter?
Open innovation matters because the material Haunted Git Blame examines can be sensitive by default.
A Git history may reveal:
- Internal project names
- Unreleased product ideas
- Security-related fixes
- Customer or organization terminology
- Names of contributors
- Work that was never intended to be public
- The timing and structure of a team's development process
A closed hosted AI API would make it easy to send that information away simply to produce a fun narrative. That would be the wrong tradeoff for this project. The spooky effect is not worth giving up control of a private codebase.
Running an open-weight model locally makes a different design possible. The repository stays on the user's machine. The model endpoint is inspectable. The prompt is visible. The model can be changed. The user can run the app with the network disconnected. There is no account requirement, API key, per-request charge, or dependency on a remote provider remaining available.
Open innovation also changes the creative process. Because the model is replaceable, Haunted Git Blame can evolve in several directions:
- A smaller model can be selected for an older laptop.
- A stronger model can be selected for richer writing.
- A model can be fine-tuned or prompted for a particular historical tone.
- The prompt can be changed to emulate an archivist, detective, séance host, or systems historian.
- The Git evidence boundary can be audited and changed by the project owner.
- The app can remain useful even if no model is installed.
A closed API might have made the first prototype quicker, but it would have hidden the most important question: where does the repository history go? With local inference, the privacy decision is part of the architecture instead of a footnote in a privacy policy.
The open approach also improves durability. A hosted service can change pricing, remove a model, change its terms, or disappear. An open local setup gives the project a better chance of remaining understandable and runnable. The model is one component, not the owner of the application.
There is a second kind of open innovation in the project: the fallback behavior. The application does not pretend that AI is the only source of value. The Git history itself is useful. The deterministic archive voices make that visible and keep the experience available without a model. This makes the project more honest and more resilient.
The Spirit of It
The part that stayed with me was the idea that a repository can be full of evidence but empty of explanation.
A commit named file-upload may be the beginning of a product, the last surviving fragment of an experiment, or simply the only door left open in an abandoned project. Git records what changed, when it changed, and who made the change. It does not record what the developer hoped would happen next.
That gap is where the haunting lives.
Haunted Git Blame does not claim to resurrect the people behind a repository. It gives the traces a voice while keeping the original evidence visible. The report can be dramatic, but the hashes remain real. The story is allowed to be eerie because the timeline keeps it accountable.
The offline cabinet is part of that spirit too. If the model cannot answer, the repository does not become silent. A one-commit project can still receive The first and final breath. A long-quiet project can still receive The silent maintainer. Those messages are small, but they make the absence itself part of the story.
The result is a tool that treats old code with a little ceremony. Not every abandoned repository needs to be revived as a product. Sometimes it only needs someone to notice that it was there.
Prize Categories
Primary category: Github-Copilot
Top comments (0)