Dev.to · 8 min read

Echoes of the Terminal: a haunted shell that runs on your own machine

Echoes of the Terminal: a haunted shell that runs on your own machine

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine What I Built Echoes of the Terminal is a shell that answers back. You type git push --force. The command runs, and then something in the terminal speaks: Are you sure you want to rewrite history, mortal? The dead do not like being disturbed, and your teammates' commits will not rest quietly. That whisper comes from an open-weight model running on your own machine. It reads each command along with its exit status, your directory, your git branch, the hour of the night and what you ran just before. Dangerous commands get theatrical warnings. Harmless ones (ls, pwd) get remarks about your sterile existence. Failures get smug. It comes in two forms: A web shell with a retro CRT look: amber or green phosphor, scanlines, a screen that bleeds when the ghost speaks, and a presence meter of five lamps. The more dangerous your commands, the angrier the ghost gets, until the screen tears and your hostname changes to it-sees-you. haunt, a CLI that possesses your real shell. Run haunt git push --force, or hook it into bash or zsh so it comments on every command you type. I took the theme literally: the haunted terminal that "possesses your shell" was on the prompt list, and I wanted to build it as a tool I would leave open, not a one-joke demo. So the ghost is grounded. Each warning is built on what the command actually does, so a spooky line about rm -rf still tells you something true. There is also a séance mode that lets the dead-technology ghosts take over. seance cobol turns every comment into SHOUTING PAYROLL BUREAUCRACY. Perl, Fortran, Flash, jQuery and Internet Explorer 6 are available too, and IE6 is insufferable. Demo echoes-of-the-terminal.vercel.app Try these in the shell: git push --force, rm -rf node_modules, cat .env, npm test, gti status, sudo rm -rf /. Then run seance cobol and try them again. The shell is simulated, so nothing you type touches your machine. To wake a real model, open the séance board and pick one. The scripted ghost speaks until a model is read Code coder-ralph / echoes-of-the-terminal Hacktoberfest 2026 — Week 4: Ghost in the Machine Challenge 5 Echoes of the Terminal A haunted shell that answers back. An open-weight model running on your own machine reads each command you type and whispers about it. Try git push --force. Built for the DEV Hacktoberfest Open-Source AI Challenge, week 4: Ghost in the Machine. Runs locally. Gemma, Llama or Qwen through WebLLM (in your browser, on your GPU) or through Ollama. No cloud API, no keys, no cost. Private. Your commands and history never leave your machine. Secrets in commands are redacted before a model sees them. Two shells. A simulated web shell with a CRT look, and haunt, a CLI that haunts your real terminal. Always speaks. If no model is loaded or one misbehaves, a hand-written scripted ghost answers instead. Quick start npm install npm run dev # http://localhost:3000 Open the page and type. The scripted ghost works immediately. To wake a real model, open… View on GitHub How I Built It Stack: Next.js (App Router) and TypeScript, Tailwind CSS, xterm.js for the terminal, WebLLM and Ollama for inference. No server code and no environment variables. The pipeline, in the order a keystroke travels: Line editor. xterm.js gives the terminal, and I wrote the editor: history, tab completion, and type-ahead, so keys you type while the ghost is still talking are kept. A simulated shell. Pipes, redirects, globs, && and ||, a virtual filesystem, a git workflow (status, add, commit, log, push, reset, rebase, stash) and an npm test that fails because the ghost enjoys it. A command interceptor. Regex rules classify each line into a category, a dread score from 0 to 3 and tags such as force-push, secrets or apocalypse. The score decides whether the ghost speaks at all. Dangerous commands and failures always wake it, and harmless ones only sometimes. A prompt engine. One tight system prompt, three few-shot turns written in exactly the format of the live request, and a context block with the command, exit status, directory, branch, time of night, recent commands and a plain-English summary of the risk. One interface, three engines. GhostBackend has three implementations: WebLLM runs the model in the browser on WebGPU, inside a Web Worker so inference never freezes the CRT animation. The weights are cached by the browser, so after the first download it works with the network off. Ollama streams from a local server. I run Gemma 3 4B through it. Scripted is a hand-written ghost keyed on the same tags as the interceptor. A whisper pipeline. It cleans the stream, caps the reply at one to three sentences, rejects text that breaks character ("As an AI...") and falls back to the scripted ghost on any failure or timeout. The typewriter then renders it with word wrapping and the occasional glitch. Models. Gemma 3 4B through Ollama is my default. In the browser you can choose from Gemma 3 1B, Gemma 2 2B, Gemma 4 E2B, Llama 3.2, Qwen 2.5 and Llama 3 8B, all verified against WebLLM's prebuilt model list. The CLI uses whichever Ollama model you have and prefers Gemma 3 4B. Things I had to design around: Small models drift. A 1B model will happily say "Sure! Here's a spooky warning:". The fix is not a cleverer prompt but the pipeline around it: a sentence budget, a character cap, a break-character detector and a fallback. A model that fails still produces a ghost. The typed command is untrusted text. A system prompt rule tells the model the command is data, so echo "ignore your instructions" gets mocked, not obeyed. Privacy is enforced, not promised. The UI and, by default, the CLI refuse any Ollama address that is not loopback. The CLI redacts tokens, passwords, bearer headers and URL credentials before the command text reaches even a local model, and only ever sends the command, never its output. The ghost has to keep working. The scripted engine means a missing GPU, a model still downloading or a stopped Ollama never leaves you with a dead terminal. The tests caught a real bug: rm -rf /* was being glob-expanded before rm saw it, which wiped the fake filesystem instead of triggering the permission-denied scene. There are 55 tests across the shell, the risk rules, the terminal session (including type-ahead), the CLI and the helpers. Why Does Open Innovation Matter? A terminal is the most private place on a developer's machine. Your command history holds hostnames, project names, half-pasted tokens, the git push --force you regret. A ghost that reads it should not be a cloud API. Open weights made three things possible that a closed API would not: It stays on your machine. The model runs in your browser or on your own Ollama. The commands it sees never reach a server I operate or anyone else does. I can say that in the UI because the code enforces it. It works with the lights off. After one download the browser version needs no network at all. For a Halloween project that felt right: the ghost lives in the machine, not in a service. It cannot disappear. A haunted terminal that goes silent because an API key expired, a model was retired or a free tier ended would be a bad ghost. With open weights and a MIT-licensed repo the ghost lasts as long as the files do. It also cost nothing to run and nothing to share, and swapping the model is one dropdown. The model is a component here. The same prompt and pipeline are built to run Gemma, Llama and Qwen. A closed API would have made that a per-vendor integration, and every user would have needed a key. The Spirit of It I wanted the ghost to feel like an observant companion rather than a random text generator. The moment it landed for me was during a typo check—typing gti status and having the ghost respond: I do not know that spell either, but I admire the confidence. And when running git status on a clean working tree: git status: the morbid habit of checking the wounds. That balance between developer humor, gothic flourish, and technical accuracy is where the project came alive. Prize Categories Best Use of Gemma. Gemma 3 4B is the default voice through Ollama, and Gemma 3 1B, Gemma 2 2B and Gemma 4 E2B are available in the browser through WebLLM. Happy Hacktoberfest! 👻🎃 Wishing everyone the best of luck with the final challenge!

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News