cd /news/ai-tools/my-terminal-is-haunted-a-y2k-ghost-r… · home › topics › ai-tools › article
[ARTICLE · art-161136] src=dev.to ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

My terminal is haunted — a Y2K ghost reviews my commands (and she talks back)

A developer built terminal-seance, an MIT-licensed, pure-Python CLI and static web app in which a fictional Victorian programmer's ghost named Agnes comments on terminal commands, with every line of dialogue improvised by Google's open-weight Gemma 3 27B model served through OpenRouter's free tier. The tool hooks into bash and zsh via DEBUG traps and PROMPT_COMMAND to react to dangerous, failed or long-running commands, throttling remarks to at most one in five commands and falling back to a bundled list of canned lines on timeout, rate limit or missing API key. It ships with 114 tests covering reaction tiers, throttling, API fallback and the shell hooks.

by read5 min views1 publishedOct 30, 2026

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

terminal-seance turns your terminal into a séance table. Every command you run is witnessed by Agnes — a Victorian-era programmer's ghost who died in the Y2K production incident at midnight, December 31, 1999, muttering "the code will hold" as the reports fell.

I took the theme literally: the machine doesn't just have a ghost in it — the ghost has a name, a death date, a personality, and opinions about your git habits:

rm -rf, git push --force, DROP TABLE, curl | sh) — she hello or tell me a joke at the prompt and she answers in character It ships as two haunted surfaces: a CLI (pipx install terminal-seance + seance install hooks into bash/zsh) and a browser séance — the same ghost, same tiers, hosted on Render, where visitors can play with her immediately.

The Día de los Muertos flavor is baked in: her color is marigold (ANSI 208 — cempasúchil, the flower of the dead), she slips into Spanish ("otra vez, cariño?"), and your command history is kept as a Graveyard Ledger. seance summon <№> literally calls a spirit back — it re-runs a past command.

Live séance: REPLACE-ME-WITH-YOUR-RENDER-URL

(free tier: the first visitor wakes the service after ~15 idle minutes — the ghost politely whispers until she's warm, then goes live)

Try, in order: pytest tests/ -q → git push --force origin main → hello → tell me a joke → seance journal → seance demo.

No key needed to try it — and if the service is asleep, run seance demo locally for the same scripted séance, fully offline.

 _____   _____   ____    __  __   ___   _   _      _      _            _____   _____      _      _   _    ____   _____
|_   _| | ____| |  _ \  |  \/  | |_ _| | \ | |    / \    | |          / ___|  | ____|    / \    | \ | |  / ___| | ____|
  | |   |  _|   | |_) | | |\/| |  | |  |  \| |   / _ \   | |          \___ \  |  _|     / _ \   |  \| | | |     |  _|
  | |   | |___  |  _ <  | |  | |  | |  | |\  |  / ___ \  | |___        ___) | | |___   / ___ \  | |\  | | |___  | |___
  |_|   |_____| |_| \_\ |_|  |_| |___| |_| \_| /_/   \_\ |_____|      |____/  |_____| /_/   \_\ |_| \_|  \____| |_____|

A haunted CLI companion. Agnes — a Victorian programmer's…

MIT-licensed, pure-Python CLI (zero runtime dependencies beyond the standard library) + a zero-dependency static web séance. 114 tests cover the reaction tiers, the throttle cap, API fallback/cooldown, the shell hooks, and the proxy.

The open-source AI: every word Agnes says is improvised by google/gemma-3-27b-it:free — Google's open-weight Gemma 3 27B, served through OpenRouter's free tier. The persona is a single editable system prompt; the model brings her to life.

The architecture:

flowchart TD
    subgraph SHELL["interactive bash / zsh"]
        A["DEBUG trap / preexec<br>fires BEFORE the command"] -->|"cheap local regex"| B["seance guard<br>instant pre-exec wail, no API call"]
        C["PROMPT_COMMAND / precmd<br>fires AFTER the command"] -->|"env: command text + exit code + timing<br>(command text only — never output)"| D["seance hear<br>backgrounded and disowned — the prompt is never delayed"]
    end
    D --> E{"tier decision<br>all local"}
    E -->|"dangerous / failed / long / chat"| G
    E -->|"boring success"| F{"throttle:<br>at least 4 commands<br>since the last remark<br>at most 1 in 5"}
    F -->|"dice say yes"| G["ONE https call — Gemma via<br>OpenRouter or your own host<br>2 s hard cap · single attempt · no retries"]
    F -->|"dice say no"| H["stays silent"]
    G -->|"reply"| I["one marigold line from Agnes"]
    G -->|"timeout / 429 / no key / offline"| J["random line from the bundled whispers list"]
    I --> K[("~/.config/terminal-seance/journal.log")]
    J --> K
    H --> K
    K --> L["seance journal — the graveyard ledger"]
    K --> M["seance summon № — re-run a row"]

Design laws, all enforced by tests (114 of them):

POST /chat/completions. Swap base_url in config.toml and the identical ghost runs on localStorage. On the hosted Render deployment, a ~200-line pure-stdlib proxy (seance serve) holds the API key POST /api/ghost — the key is never in the page, the JS, or devtools, and visitors never enter anything.google/gemma-3-27b-it:free means a student can haunt their shell all Hacktoberfest without a credit card. The built-in 1-in-5 throttle is tuned to live inside that free quota forever. This project was built end-to-end in a single AI agent session (with ZCode) — scaffold to deployed service — and the session earned its keep: the shell hooks were verified live in Git Bash with a stub seance binary, which caught real bugs no test had seen (a start-time stamp lost to a subshell, ghost reactions firing for the previous session's history at startup, typed-ahead input being swallowed while the ghost was speaking). Playwright then drove the browser séance — typing commands, wailing at force-pushes — before the assets were rendered.

The moment it landed: I made the fake test suite fail on purpose so Agnes would have something to mourn, and she said:

"Three failures, cariño. I have died for fewer — though mine was production."

I stopped for a second. Because that's the whole project in one line — a joke about test failures that is also literally her death story. Every detail is like that if you look: the terminal's marigold color is 208, chosen because it's the shade of cempasúchil, the flower the living put on ofrendas; the command journal is called a ledger because the dead keep records; seance summon re-runs a command the way you'd call back a spirit.

Agnes is fictional. The Y2K midnights she stands for were not — an entire industry sat up with candles (and pagers) on December 31, 1999, whispering the code will hold. This is a small marigold left on that doorstep.

Say hello to her sometime. She answers.

google/gemma-* variant or a local Gemma via llama.cpp/Ollama

── more in #ai-tools 4 stories · sorted by recency
── more on @terminal-seance 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/my-terminal-is-haunt…] indexed:0 read:5min 2026-10-30 · —