{"slug": "my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back", "title": "My terminal is haunted — a Y2K ghost reviews my commands (and she talks back)", "summary": "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.", "body_md": "*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)*\n\n**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.\n\nI 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:\n\n`rm -rf`, `git push --force`, `DROP TABLE`, `curl | sh`) — she `hello` or `tell me a joke` at the prompt and she answers in character\nIt 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.\n\nThe 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.\n\n**Live séance:** REPLACE-ME-WITH-YOUR-RENDER-URL\n\n*(free tier: the first visitor wakes the service after ~15 idle minutes — the ghost politely whispers until she's warm, then goes live)*\n\nTry, in order: `pytest tests/ -q` → `git push --force origin main` → `hello` → `tell me a joke` → `seance journal` → `seance demo`.\n\nNo key needed to try it — and if the service is asleep, run `seance demo` locally for the same scripted séance, fully offline.\n\n```\n _____   _____   ____    __  __   ___   _   _      _      _            _____   _____      _      _   _    ____   _____\n|_   _| | ____| |  _ \\  |  \\/  | |_ _| | \\ | |    / \\    | |          / ___|  | ____|    / \\    | \\ | |  / ___| | ____|\n  | |   |  _|   | |_) | | |\\/| |  | |  |  \\| |   / _ \\   | |          \\___ \\  |  _|     / _ \\   |  \\| | | |     |  _|\n  | |   | |___  |  _ <  | |  | |  | |  | |\\  |  / ___ \\  | |___        ___) | | |___   / ___ \\  | |\\  | | |___  | |___\n  |_|   |_____| |_| \\_\\ |_|  |_| |___| |_| \\_| /_/   \\_\\ |_____|      |____/  |_____| /_/   \\_\\ |_| \\_|  \\____| |_____|\n```\n\n**A haunted CLI companion.** Agnes — a Victorian programmer's…\n\nMIT-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.\n\n**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.\n\n**The architecture:**\n\n```\nflowchart TD\n    subgraph SHELL[\"interactive bash / zsh\"]\n        A[\"DEBUG trap / preexec<br>fires BEFORE the command\"] -->|\"cheap local regex\"| B[\"seance guard<br>instant pre-exec wail, no API call\"]\n        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\"]\n    end\n    D --> E{\"tier decision<br>all local\"}\n    E -->|\"dangerous / failed / long / chat\"| G\n    E -->|\"boring success\"| F{\"throttle:<br>at least 4 commands<br>since the last remark<br>at most 1 in 5\"}\n    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\"]\n    F -->|\"dice say no\"| H[\"stays silent\"]\n    G -->|\"reply\"| I[\"one marigold line from Agnes\"]\n    G -->|\"timeout / 429 / no key / offline\"| J[\"random line from the bundled whispers list\"]\n    I --> K[(\"~/.config/terminal-seance/journal.log\")]\n    J --> K\n    H --> K\n    K --> L[\"seance journal — the graveyard ledger\"]\n    K --> M[\"seance summon № — re-run a row\"]\n```\n\nDesign laws, all enforced by tests (114 of them):\n\n`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.\nThis 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.\n\nThe moment it landed: I made the fake test suite fail on purpose so Agnes would have something to mourn, and she said:\n\n*\"Three failures, cariño. I have died for fewer — though mine was production.\"*\n\nI 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.\n\nAgnes 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.\n\nSay `hello` to her sometime. She answers.\n\n`google/gemma-*` variant or a local Gemma via llama.cpp/Ollama", "url": "https://wpnews.pro/news/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back", "canonical_source": "https://dev.to/asmittzzz/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back-2iib", "published_at": "2026-10-30 19:06:58+00:00", "updated_at": "2026-10-30 19:21:04.769026+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "developer-tools", "ai-products"], "entities": ["terminal-seance", "Agnes", "Google", "Gemma 3 27B", "OpenRouter", "Hacktoberfest", "Render"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back", "markdown": "https://wpnews.pro/news/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back.md", "text": "https://wpnews.pro/news/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back.txt", "jsonld": "https://wpnews.pro/news/my-terminal-is-haunted-a-y2k-ghost-reviews-my-commands-and-she-talks-back.jsonld"}}