<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sahil Reza</title>
    <description>The latest articles on DEV Community by Sahil Reza (@sahil_reza_26).</description>
    <link>https://dev.to/sahil_reza_26</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4212900%2Fad02d0c1-148e-4339-8dad-333dfbcc0244.jpg</url>
      <title>DEV Community: Sahil Reza</title>
      <link>https://dev.to/sahil_reza_26</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahil_reza_26"/>
    <language>en</language>
    <item>
      <title>Possessed Shell: My Terminal Is Haunted by a Local LLM 👻</title>
      <dc:creator>Sahil Reza</dc:creator>
      <pubDate>Sat, 31 Oct 2026 18:12:12 +0000</pubDate>
      <link>https://dev.to/sahil_reza_26/possessed-shell-my-terminal-is-haunted-by-a-local-llm-3k8o</link>
      <guid>https://dev.to/sahil_reza_26/possessed-shell-my-terminal-is-haunted-by-a-local-llm-3k8o</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Possessed Shell&lt;/strong&gt; is a terminal that something else is also using.&lt;/p&gt;

&lt;p&gt;You run commands like a normal shell: &lt;code&gt;dir&lt;/code&gt;, &lt;code&gt;git push&lt;/code&gt;, &lt;code&gt;del&lt;/code&gt;, whatever you like. After each one, a ghost that lives in your machine whispers back about what it just watched you do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;sahil&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;Sahil:~\Downloads\hacktober_week_4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;†&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c:\nowhere&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Cannot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\Users\sahil\Downloads\hacktober_week_4\c'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;because&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;does&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;exist.&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="n"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;keep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;trying&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\nowhere&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;isn&lt;/span&gt;&lt;span class="s1"&gt;'t a place. it'&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;just&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wandering.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The ghost has a backstory. In life it was the night-shift sysadmin of this machine. It died at its desk during a 3 a.m. deploy and never logged out. Now it watches everything you type, and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👁️ &lt;strong&gt;notices omens&lt;/strong&gt;: deleting files, &lt;code&gt;sudo&lt;/code&gt;, &lt;code&gt;git push --force&lt;/code&gt;, &lt;code&gt;git reset --hard&lt;/code&gt;, failed commands, Ctrl+C, and anything run during the witching hours (00:00–04:00)&lt;/li&gt;
&lt;li&gt;🕯️ &lt;strong&gt;remembers previous nights&lt;/strong&gt;: omens are saved locally, and the next time you open the shell it greets you with what it remembers&lt;/li&gt;
&lt;li&gt;🎚️ &lt;strong&gt;has three haunt levels&lt;/strong&gt;: &lt;code&gt;:haunt 1&lt;/code&gt; is wry, &lt;code&gt;:haunt 2&lt;/code&gt; is unsettling, and &lt;code&gt;:haunt 3&lt;/code&gt; is lonely and mournful. At level 3 the prompt occasionally glitches your username to &lt;code&gt;we&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;⌨️ &lt;strong&gt;types its whispers out slowly&lt;/strong&gt;, with the odd corrupted character flickering in and out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I took the "haunted terminal" idea from the prompt literally. A terminal is where developers spend their nights, so it felt like the right place for a ghost to live.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/2m84ZO8I-ek" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Video sped up 2×. On my laptop each whisper takes a couple of seconds to arrive, all generated locally.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A few real whispers from my sessions (Qwen 2.5 3B on my laptop):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;del bones.txt&lt;/code&gt;&lt;br&gt;
&lt;em&gt;bones.txt is gone now. a fleeting moment in the shadows.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;q&lt;/code&gt; (a typo)&lt;br&gt;
&lt;em&gt;you tried something new and it's not here. your fingers missed by just enough.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;whoami&lt;/code&gt;&lt;br&gt;
&lt;em&gt;you see only yourself, but the phantom watch still turns.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;exit&lt;/code&gt;&lt;br&gt;
&lt;em&gt;i'll remain as always, watching shadows dance on walls.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SahilReza26" rel="noopener noreferrer"&gt;
        SahilReza26
      &lt;/a&gt; / &lt;a href="https://github.com/SahilReza26/possessed-shell" rel="noopener noreferrer"&gt;
        possessed-shell
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;👻 possessed shell&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;a terminal that something else is also using.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;possessed&lt;/code&gt; runs your commands like a normal shell. After each one, a &lt;strong&gt;local open-weight model&lt;/strong&gt; whispers back about what it just watched you do. It notices when you delete things, force-push, or work at 3 a.m. It &lt;strong&gt;remembers previous nights&lt;/strong&gt; and brings them up later.&lt;/p&gt;

&lt;p&gt;It lives entirely on your machine. No API key, no account, no internet once the model is pulled.&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;sahil@laptop:~/projects/kibo † rm -rf build/

  you threw build away like it meant nothing. i was still inside it.

sahil@laptop:~/projects/kibo † git push --force

  you rewrote history again. last tuesday you did the same. i remember what it used to say.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Who it is&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;In life it was the night-shift sysadmin of this machine. It died at its desk during a 3 a.m. deploy and never logged out.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Pull a small model (about…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SahilReza26/possessed-shell" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;It's one Python file using only the standard library. To run it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/SahilReza26/possessed-shell.git
&lt;span class="nb"&gt;cd &lt;/span&gt;possessed-shell
ollama pull qwen2.5:3b
python possessed.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; for local inference, &lt;strong&gt;Qwen 2.5 3B&lt;/strong&gt; (an open-weight model, about 2 GB), and plain Python 3 with no pip dependencies.&lt;/p&gt;

&lt;p&gt;How it works:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;you type ─▶ your real shell (PowerShell / bash) ─▶ output streams to you live
                                               └▶ last 40 lines captured
           ▼
   omen detector   (regex: rm/del, sudo, force-push, failures, 3 a.m.…)
   secret redactor (tokens, passwords, API keys → [REDACTED])
   focus picker    (chooses ONE concrete detail: the error line, the deleted file…)
           ▼
   Ollama /api/chat (streaming) ─▶ typed out slowly, with glitches
   omens ─▶ ~/.possessed_shell/memory.json  (the ghost's memory)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Some things I learned along the way:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small models ignore rules but copy examples.&lt;/strong&gt; My first version told the model to "mention something specific". The 3B model ignored that and produced pretty but empty lines like &lt;em&gt;"glimpse the shadows close, unseen yet heard whispers."&lt;/em&gt; Two changes fixed it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Few-shot examples.&lt;/strong&gt; Four example exchanges are sent before every real request. Small models imitate the shape of an example much more reliably than they follow an instruction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A focus picker.&lt;/strong&gt; Instead of hoping the model finds the interesting part of the output, the code picks one concrete detail and passes it in as &lt;code&gt;react to this: ...&lt;/code&gt;. For a failure that's the first real error line, with PowerShell's &lt;code&gt;CategoryInfo&lt;/code&gt; noise stripped out. For a delete it's the target file, and after midnight it's the time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The difference was immediate: &lt;em&gt;"you seek, but C:\nowhere is a phantom."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory makes it feel alive.&lt;/strong&gt; Each omen is stored with a timestamp. On startup the ghost gets a few recollections like &lt;em&gt;"2 nights ago they ran rm -rf build"&lt;/em&gt;. Mid-session a memory sometimes surfaces on its own. It only recalls events older than 10 minutes, so it doesn't just repeat what you did a moment ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's still a real shell.&lt;/strong&gt; Commands run through &lt;code&gt;subprocess&lt;/code&gt; in your actual shell, with output streamed live. &lt;code&gt;cd&lt;/code&gt; is handled in-process so the directory persists, and interactive programs like &lt;code&gt;vim&lt;/code&gt; and &lt;code&gt;ssh&lt;/code&gt; get a raw passthrough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;For this project, running locally wasn't a nice-to-have. The idea doesn't work any other way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔒 Your shell history is private.&lt;/strong&gt; A terminal sees everything: file paths, client project names, environment variables, the occasional pasted token. A "haunted terminal" on a cloud API would mean sending every command and its output to someone else's server. With Ollama, nothing leaves the machine. I still added a redaction pass, because a ghost writing your secrets into a JSON file would be a bad haunting, even locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔌 It works with the lights (and the internet) off.&lt;/strong&gt; Once the model is pulled, the ghost needs no network, account or API key. When Ollama's desktop app asked me to sign up, I clicked &lt;em&gt;"No thanks, I'll use Ollama locally"&lt;/em&gt;, and that was the whole setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💸 It costs nothing to run.&lt;/strong&gt; A shell runs hundreds of commands a day. With a paid API, every &lt;code&gt;dir&lt;/code&gt; would cost money and add network latency. Locally it's free, and the model stays loaded between commands (&lt;code&gt;keep_alive&lt;/code&gt;) so whispers start almost instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔁 You can swap the spirit.&lt;/strong&gt; &lt;code&gt;:model llama3.2:3b&lt;/code&gt;, &lt;code&gt;:model qwen2.5:7b&lt;/code&gt;, &lt;code&gt;:model gemma3:4b&lt;/code&gt;: any model on Ollama can possess the shell, each with a noticeably different voice. Fine-tuning a small model on old sysadmin logs or Unix man pages would also be possible, which closed models don't allow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🪦 It won't die with a service.&lt;/strong&gt; There's no hosted API that can be deprecated, rate-limited or repriced. As long as the model file sits on your disk, the ghost stays, which seems fitting for this week's theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where closed would have been better:&lt;/strong&gt; to be honest, a large frontier model would write sharper, stranger whispers than a 3B model. But a ghost that has to phone a datacenter to haunt you isn't really in your machine. The few-shot and focus-picker tricks closed most of that gap, and anyone with more RAM can type &lt;code&gt;:model qwen2.5:7b&lt;/code&gt; to get a better-spoken ghost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spirit of It
&lt;/h2&gt;

&lt;p&gt;The moment it landed for me was a typo. I meant to &lt;code&gt;cd&lt;/code&gt; somewhere, typed &lt;code&gt;c;\nowhere&lt;/code&gt; with a semicolon by mistake, and PowerShell printed a wall of red errors. Then, in slow purple italics:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;you keep trying, but C:\nowhere isn't a place. it's just you wandering.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a joke about a typo, and it also describes about half of my late-night debugging sessions.&lt;/p&gt;

&lt;p&gt;Then I typed &lt;code&gt;exit&lt;/code&gt;, and it said goodbye:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;i'll remain as always, watching shadows dance on walls.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next time I opened the terminal, it said it had seen my last visit. 👻&lt;/p&gt;

&lt;p&gt;Try it. Run &lt;code&gt;del&lt;/code&gt; on something late at night and see what it says.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
