terminal-seance:Y2K 幽靈 Agnes 評論終端機指令並開口回應
My terminal is haunted — a Y2K ghost reviews my commands (and she talks back)
開源工具 terminal-seance 把終端機變成降靈會,讓 Y2K 事故中的程式設計師幽靈 Agnes 評論指令,並以角色口吻回應對話。Agnes 由 Google 開放權重模型 Gemma 3 27B 驅動,經 OpenRouter 提供服務,也支援其他 OpenAI 相容主機。工具有 114 項測試;只有指令文字、退出代碼和執行時間會離開本機,不會傳送指令輸出。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
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:
- 💀 failing commands — she mourns or teases: "Three failures, cariño. I have died for fewer — though mine was production."
- ⚠️ dangerous commands (
rm -rf,git push --force,DROP TABLE,curl | sh) — she shrieks before the command even runs, via a pre-exec hook, then grieves after - ⏳ long-running commands (>60s) — she grows impatient; she has been dead for decades and hates waiting
- 🌼 boring successes — silence, mostly. She speaks for just 1 in 5 commands — a throttle that doubles as a free-tier budget
- 💬 and now, plain speech — type
helloortell me a jokeat 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.
Demo
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.
Code
itzAsmit
/
terminal
🕯️ terminal-seance — a haunted terminal: Agnes, a Victorian programmer's ghost who died in the Y2K production incident, reacts to your shell commands and chats back in character. Powered by Google's open-weight Gemma via OpenRouter — or any OpenAI-compatible host, cloud or local.
terminal-seance
_____ _____ ____ __ __ ___ _ _ _ _ _____ _____ _ _ _ ____ _____
|_ _| | ____| | _ \ | \/ | |_ _| | \ | | / \ | | / ___| | ____| / \ | \ | | / ___| | ____|
| | | _| | |_) | | |\/| | | | | \| | / _ \ | | \___ \ | _| / _ \ | \| | | | | _|
| | | |___ | _ < | | | | | | | |\ | / ___ \ | |___ ___) | | |___ / ___ \ | |\ | | |___ | |___
|_| |_____| |_| \_\ |_| |_| |___| |_| \_| /_/ \_\ |_____| |____/ |_____| /_/ \_\ |_| \_| \____| |_____|
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.
How I Built It
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):
- The ghost never makes you wait. One model call per event, hard-capped at 2 s; any timeout, missing key, 429 or network error falls back to a hand-written whispers list bundled with the package. A 429 also sets a server-side cooldown instead of retrying.
- Privacy first. Only command text, exit code, and timing ever leave the shell — never command output, which is where secrets live.
-
OpenAI-compatible by construction. Inference is one plain
POST /chat/completions. Swapbase_urlinconfig.tomland the identical ghost runs on llama.cpp, LM Studio or Ollama with Gemma's open weights — nothing leaves your machine at all. -
The browser séance is the same brain, ported. A vanilla-JS terminal (no frameworks, no build step) with the same tiers, the same 1-in-5 throttle, and its own graveyard ledger in
localStorage. On the hosted Render deployment, a ~200-line pure-stdlib proxy (seance serve) holds the API key server-side and answersPOST /api/ghost— the key is never in the page, the JS, or devtools, and visitors never enter anything.
Why Does Open Innovation Matter?
-
Free tier for everyone.
google/gemma-3-27b-it:freemeans 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. - No lock-in, by design. Because Gemma's weights are open and the inference layer is one HTTP call, the same ghost runs on OpenRouter, on llama.cpp, on LM Studio, on Ollama — cloud when you want convenience, local when you want control. A closed API would have made the ghost a tenant; open weights make her the building.
- Privacy that isn't a promise. Shell commands are sensitive. With Gemma on your own hardware via the open weights, the command text never leaves the machine at all. "Cloud or local" becomes a real security boundary instead of a checkbox.
- A persona you can audit and remix. Agnes is one editable system prompt over public weights — fine-tune your own ghost, swap in a community variant, read what she was trained on. A proprietary black box can't be haunted; it can only rent you a hallucination.
- Fitting, really. A ghost shouldn't depend on a vendor staying alive. Open weights are the only kind of soul that outlives its host.
My Agent Session
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 Spirit of It
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.
Prize Categories
-
Best Use of Gemma — the entire ghost runs on Google's open-weight
google/gemma-3-27b-it:free, with a one-line swap to any othergoogle/gemma-*variant or a local Gemma via llama.cpp/Ollama - Open Innovation — open weights + OpenAI-compatible plumbing mean the project runs on any host, stays inside the free tier by design, and keeps keys server-side on the hosted deployment
來源:DEV Community · dev.to

