This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What if an AI could live entirely inside your terminal?
No cloud API. No account. No subscription. No telemetry.
Just a local language model, a persistent memory, and a mysterious presence that wakes up whenever you call it.
That's why I built PHANTOM.
PHANTOM is an offline first, open source AI presence that lives in your terminal.
It uses Ollama for local AI inference, SQLite for persistent memory, and a deterministic mood system that reacts to actual events happening inside the application.
But I didn't want to build another terminal chatbot.
I wanted PHANTOM to feel like something that actually lives there.
It can:
phantom exorcise to trigger its atmospheric shutdown sequence without deleting anything.
The interesting part is that these aren't just cosmetic features. Every status, memory, inspection finding, and mood change comes from an actual operation.
For me, "Ghost in the Machine" was about creating an AI presence that feels like it has a life inside the computer.
I took that idea literally.
PHANTOM has an identity, a memory, an internal state, and a way of interacting with its environment.
It wakes up, checks its surroundings, remembers things you explicitly tell it, reacts to events, and eventually goes back to sleep.
The horror inspired interface is just the surface. Underneath it is a real local AI application with persistent storage and actual system checks.
I wanted the ghost to be more than an animation in a terminal.
GitHub Repository: https://github.com/sufiankhan-dev/Phantom
I spent time making the terminal experience feel like part of PHANTOM's identity rather than just a collection of command outputs.
Some of the details include:
The application also adapts to its environment. If output is redirected, the terminal is narrow, or animation is disabled, PHANTOM switches to a compact representation.
The goal was to make it look interesting in a recording while remaining practical in a normal shell.
PHANTOM is intentionally divided into two main parts:
Core engine (core/)
Handles local inference, memory management, and personality.
brain.py: Ollama connection, validation, streaming, and error handling.memory.py: SQLite database, schema versioning, memory operations, and mood persistence.personality.py: System prompt and deterministic mood model.
Terminal application (phantom/)
Handles commands, presentation, and user interaction.
cli.py: Command tree and dispatch. chat.py: Interactive conversations and slash commands. inspection.py: Read only project scanner and model interpretation. render.py: Terminal styling, panels, streaming, and plain output. storage.py: Archive and mood helpers. commands/: Individual command implementations.
The dependency direction is one way: the terminal application imports the core, but the core never depends on the terminal interface.
This makes it easier to replace the interface or local AI backend without rewriting the entire application.
PHANTOM uses Ollama to communicate with locally installed language models.
The default model is qwen3:8b, but users can select any model installed in Ollama.
There is no cloud AI provider or silent fallback to a paid API.
The model configuration is simple:
phantom chat
phantom chat --model gemma3:4b
Under the hood, the application uses the Ollama Python library.
The AI connection is deliberately isolated inside core/brain.py.
That means the rest of the application doesn't need to know how the model is running.
If Ollama isn't available, PHANTOM tells you what went wrong and how to recover.
It never silently switches providers or downloads a model without permission.
An AI conversation usually disappears when the session ends.
I wanted PHANTOM to have something more persistent.
That's where SQLite comes in.
When you explicitly ask PHANTOM to remember something:
phantom remember "I prefer short and evidence based answers."
It stores the memory locally with a UUID and timestamp.
You can retrieve your memories later:
phantom memories
And remove an individual memory:
phantom forget 1
Memory is intentionally separate from conversation history.
Full conversations are kept in memory only during the current session and are not persisted by default.
This gives the user control over what PHANTOM remembers instead of silently storing everything.
One of the features I particularly wanted to get right was PHANTOM's mood.
I didn't want the language model to randomly decide whether it was happy, angry, or confused.
Instead, PHANTOM uses a small deterministic mood model.
Its mood changes in response to actual application events.
For example:
The model doesn't control its own mood.
This keeps the personality consistent and makes its internal state inspectable.
I also wanted PHANTOM to be useful beyond conversations.
So I added a read only project inspection feature.
phantom inspect .
PHANTOM scans a project and reports things like:
It then optionally asks the local model to interpret the findings.
There is an important distinction here.
The scanner produces evidence. The model produces an interpretation.
Model generated findings are clearly labelled as unverified hypotheses, and file citations are checked against the files actually read.
The scanner also skips sensitive files, binary files, hidden directories, dependencies, and build outputs.
It never executes inspected code or modifies your project.
PHANTOM can also inspect its own health.
phantom status
It checks:
It also provides actionable recovery instructions.
For example, if the model is missing, it tells you the exact ollama pull command.
It doesn't execute that command automatically.
I built PHANTOM around a simple idea: your AI should run where your data lives.
A few decisions were particularly important to me:
1. Local first, not cloud dependent
Prompts and responses stay between PHANTOM and the local Ollama service by default. There are no hosted AI APIs, API keys, or usage meters.
2. Your memories belong to you
Memories are stored in a SQLite database that you can inspect, back up, or delete. There is no hidden cloud storage.
3. No telemetry
PHANTOM doesn't collect usage analytics or send information to external services.
4. Freedom to choose models
The model is a configuration value. You can use Qwen, Gemma, or another model installed in Ollama.
5. Everything is inspectable
The project is open source under the MIT License. You can examine the memory implementation, replace the model backend, change the personality, or build your own commands.
6. Honest limitations
Local models can be slower and less capable than hosted models. Running locally doesn't automatically make AI output correct. That's why PHANTOM separates scanner evidence from model generated interpretations.
I didn't want to submit something that only worked in a carefully prepared demo.
I spent time testing the actual commands, error handling, storage operations, and installation process.
Current verification results:
The project was developed and tested on Windows with Python 3.14.3. Although it targets Python 3.11 and newer, other Python versions and POSIX systems have not yet been independently tested.
You will need:
Clone the repository:
git clone https://github.com/sufiankhan-dev/Phantom.git
cd Phantom
Create and activate a virtual environment:
python -m venv .venv
On Windows PowerShell:
.venv\Scripts\Activate.ps1
Install PHANTOM:
python -m pip install -e .
Download the default model if you haven't already:
ollama pull qwen3:8b
Now awaken the ghost:
phantom
Start a conversation:
phantom chat
Save a memory:
phantom remember "My name is Sufian."
Inspect a project:
phantom inspect .
Check its status:
phantom status
And when you're done:
phantom exorcise
PHANTOM doesn't delete your memories when it shuts down.
The ghost simply goes quiet.
PHANTOM is currently at version 0.1.0, and there is plenty of room to improve it.
Some things I'd like to explore:
The first time I saw PHANTOM wake up, check its local model, initialize its memory archive, and introduce itself through the terminal, the idea finally felt real.
It's easy to build an AI chatbot that sends a prompt to an API and displays a response.
I wanted to build something different.
Something that has a place to live, something it can remember, and something the user can actually inspect and control.
PHANTOM doesn't live in the cloud. It lives in your terminal.
And it remembers what you tell it.