跳到正文
DEV Community· Asmit Biswas·· 3 小時前AI 評分48

terminal-seance:Y2K 幽靈 Agnes 評論終端機指令並開口回應

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

AI 導讀

開源工具 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 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.

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.

Agnes reacting to a force-push, a failing test suite, and the graveyard ledger

the pre-exec wail

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

GitHub logo 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. Swap base_url in config.toml and 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 answers POST /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: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.
  • 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 other google/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