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

> Source: <https://dev.to/asmittzzz/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back-2iib>
> Published: 2026-10-30 19:06:58+00:00

*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine](https://dev.to/challenges/hacktoberfest-week4-2026-10-26)*

**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
