DEV Community

AR Bird
AR Bird

Posted on

PossessedShell: a Victorian ghost haunts my terminal with local Gemma 2

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission ๐Ÿ‘ป๐ŸŒผ

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

What I Built

PossessedShell is a Victorian ghost trapped in your terminal. It is an ambient companion for zsh and bash that mourns every command you kill, then tells you how to fix it. It does three things:

  • The Failing Command Curse. When a command exits non-zero, the hook captures the command, its stderr and the exit code. A local Gemma 2 model writes a short Victorian lament and a plain-English diagnosis. It also suggests one fix command, which is pre-typed on your next prompt in zsh or placed in history in bash. The ghost never runs the fix for you.
  • The Forbidden Ritual Interceptor. Destructive commands (rm -rf, git push --force, git reset --hard, chmod 777, DROP DATABASE, mkfs, curl | sh, fork bombs and more) are stopped before they run. The ghost asks whether you truly wish to summon such destruction.
  • The Ectoplasm Leak Detector. A background monitor watches CPU and RAM and raises a spooky warning when the machine runs hot or one process devours memory.

I took the "haunted terminal that possesses your shell" idea literally. The ghost is Cornelius Vale, a telegraph engineer who perished in 1887 and is now bound inside the machine. The theme is the fun part, but the diagnoses are useful because Gemma sees the real stderr, the exit code, the cwd and a snapshot of system state.

Demo

Here is a typical haunting (a missing Python module):

โ˜   THE PROCESS `python3 -c 'import ectoplasm'` HAS DIED  (exit 1)  โ˜ 

  โšฐ  Diagnosis: The Python package 'ectoplasm' is not installed in this environment.

โ•ญโ”€ the ghost's remedy โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  python3 -m pip install ectoplasm  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
  The remedy waits on your next prompt. Enter to accept, Ctrl-U to refuse.
  whispered by gemma2:2b in 1.9s, 212 tokens
Enter fullscreen mode Exit fullscreen mode

Code

๐Ÿ‘ป PossessedShell

A Victorian ghost is trapped in your terminal. It mourns every command you kill, and it tells you how to fix them.

            .-~~~~~~~~~-
          .'   _     _   '.            ___________
         /    (@)   (@)    \          |           |
        |         ^         |         |  R.I.P.   |
        |     .-------.     |         |           |
         \    \ ~~~~~ /    /          | here lies |
          |    '-----'    |           |  your     |
          |               |           |  process  |
          | /\   /\   /\  |         __|___________|__
          |/  \_/  \_/  \_|        /////////////////
โ˜   THE PROCESS `python3 -c 'import ectoplasm'` HAS DIED  (exit 1)  โ˜ 

  Alas! python3 hath perished, its last breath a ModuleNotFoundError for
  'ectoplasm'. I drew the curtains and stopped every clock in the house.

  โšฐ  Diagnosis: The Python package 'ectoplasm' is not installed in this environment.

โ•ญโ”€ the ghost's remedy โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  python3 -m pip install ectoplasm  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
  The remedy waits on your next prompt. Enter to accept, Ctrl-U to refuse.
โ€ฆ

How I Built It

Open-source AI at the core. Gemma 2 (gemma2:2b by default, gemma2:9b if you want a wiser ghost) runs locally through Ollama. Gemma is asked for strict JSON ({lament, diagnosis, fix}) through Ollama's format JSON schema, so the fix can be extracted reliably. The system prompt forbids inventing files, flags or packages the error doesn't imply, and bans destructive remedies unless there is no other way.

Architecture.

  • The hooks are plain shell: zsh preexec/precmd plus an accept-line widget, and bash's DEBUG trap plus PROMPT_COMMAND. Python starts only when a command fails, matches the destructive-command prefilter, or an omen is waiting. Successful everyday commands cost nothing.
  • A small asyncio daemon keeps Gemma warm, runs the resource monitor, and talks newline-delimited JSON over a 0600 Unix socket.
  • If Ollama is down, an offline grimoire of heuristics answers instead (typos, missing modules, missing git upstream, ports in use, OOM kills). The demo never falls flat.
  • Rendering uses rich, with glitch-in ASCII apparitions and a typewriter effect. Resource checks use psutil.

Sentry agent tracing. With a DSN set, every curse becomes a trace, and the Gemma call follows Sentry's AI agent span conventions. It shows up under Insights โ†’ AI โ†’ Agents:

curse ls                          shell.curse           the transaction
โ”œโ”€ system vital signs             ghost.snapshot
โ”œโ”€ backboard recall               ghost.memory.recall
โ””โ”€ invoke_agent Cornelius Vale    gen_ai.invoke_agent
   โ””โ”€ chat gemma2:2b              gen_ai.chat           tokens, timings, prompt and reply
Enter fullscreen mode Exit fullscreen mode

The gen_ai.chat span records token counts, model load time and tokens per second. When Gemma times out or answers with something unusable, the span is marked as an error and the agent span records that it fell back to the grimoire, so a slow model server stands out at a glance. Everything is scrubbed by redact.py before it leaves the machine.

Backboard ghost memory (opt-in). With a BACKBOARD_API_KEY, the ghost remembers your past failures across sessions: "Again, mortal? python3 has died before by your handโ€ฆ". Backboard only ever receives a scrubbed one-line summary per failure.

Tests. Unit tests plus end-to-end tests that start real interactive zsh and bash sessions in a pty. They check that a failing command is cursed with its captured stderr, that a banished rm -rf runs nothing at all, and that omens appear at the next prompt.

Why Does Open Innovation Matter?

  • Your terminal is private. Commands and stderr routinely contain paths, hostnames, tokens and half-typed secrets. Because Gemma runs on localhost, that text never has to leave the machine. A closed API would force me to ship every failed command to someone else's server.
  • It works with the lights off. On a plane, on a train, or behind a locked-down network, the ghost still haunts. The default install is 100% offline. Sentry and Backboard are opt-in extras, and the offline grimoire covers the case where even Ollama is down.
  • It isn't locked inside a service that might disappear. The model is a file I hold. I can swap gemma2:2b for gemma2:9b, or point POSSESSED_LLM_URL at any OpenAI-compatible local server such as llama.cpp, without changing a line of code.
  • Open weights made the tracing honest. Since inference is local, cost is $0 and I could observe the real latency and token counts per failure, and design the fallback around them.

Prize Categories

  • Best Use of Gemma: Gemma 2 is the brain, running locally via Ollama and producing structured JSON diagnoses.
  • Best Use of Sentry Agent Tracing: each curse is traced as a gen_ai.invoke_agent / gen_ai.chat agent run with token usage, timings and error outcomes.
  • Best Use of Backboard: persistent, scrubbed memory of your past failures, so the ghost can recall earlier sins.

Top comments (0)