Dev.to AI ๐Ÿค– Ai ๐Ÿ‘ 0 ๐Ÿ“– 7 min read

NecroShell and the Ghost in the Machine

Here is the complete, ready-to-publish DEV submission post tailored for NecroShell and the "Ghost in the Machine" Hacktoberfest 2026 Challenge (#devchallenge and #hf26challenge), including a clean, syntax-fixed version o

Here is the complete, ready-to-publish DEV submission post tailored for NecroShell and the "Ghost in the Machine" Hacktoberfest 2026 Challenge (#devchallenge and #hf26challenge), including a clean, syntax-fixed version of your necroshell.py snippet ready to embed or push to your repository.

title: "NecroShell: An Offline UNIX Daemon That Haunts Your Failed Commands & Git History"
published: false
description: "An offline CLI tool powered by local open-weight LLMs (Ollama + Qwen 2.5 Coder) that possesses your terminal when processes die and holds sรฉances for abandoned Git commits."
tags: devchallenge, hf26challenge, opensource, cli

This is a submission for the Hacktoberfest 2026 Challenge. #devchallenge #hf26challenge

What I Built

Every developer knows the quiet dread of a terminal flashing a non-zero exit code at 2 AM, or the eerie feeling of git blame-ing a file only to find logic written years ago by someone who left the project behind.

For the "Ghost in the Machine" theme, I built NecroShellโ€”an offline, privacy-first CLI daemon and terminal interface that uses local open-weight LLMs via Ollama (qwen2.5-coder:7b / llama3.2:3b) and Python's Rich library to literally possess your terminal.

Instead of copy-pasting stack traces into a browser tab, NecroShell operates in two haunted modes directly inside your shell:

  1. possess Mode (The 1970s UNIX Daemon): Wraps any shell command. When a command succeeds, the spirits sleep. The moment a command crashes (exit code != 0), the daemon wakes up, inspects the stderr corpse, and streams a spooky yet razor-sharp technical diagnosis and exact fix right in the terminal.
  2. seance Mode (Dรญa de los Muertos Ofrenda for Code): Reads your local git log and commit stats to summon the "collective spirit" of departed code, reverted commits, and half-finished refactorsโ€”honoring what was built while warning you of lingering architectural debt.

Demo

  • GitHub Repository: https://github.com/Bylerma/necroshell
  • Video Walkthrough: [Insert YouTube / Loom Demo Link Here]

Terminal Output Preview

โšก Executing: python3 -c "import non_existent_ghost_module"

๐Ÿฉธ Process terminated with Exit Code 1
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ stderr corpse โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Traceback (most recent call last):                        โ”‚
โ”‚   File "<string>", line 1, in <module>                    โ”‚
โ”‚ ModuleNotFoundError: No module named 'non_existent_ghost' โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ•ฏ๏ธ SPIRIT TRANSMISSION (qwen2.5-coder:7b) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ The child process reached into the void of site-packages and  โ”‚
โ”‚ grasped only cobwebs; PID 41892 bled out before the           โ”‚
โ”‚ interpreter could bind its symbols.                           โ”‚
โ”‚                                                               โ”‚
โ”‚ To appease the environment and restore the link, invoke:      โ”‚
โ”‚   pip install non-existent-ghost-module                       โ”‚
โ”‚ Or verify your virtual environment is active via `which pip`. โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Complete Source Code (necroshell.py)

You can spin up NecroShell locally in under two minutes with Ollama and Python:

ollama pull qwen2.5-coder:7b
mkdir necroshell && cd necroshell
python3 -m venv venv && source venv/bin/activate
pip install requests rich typer

import json
import subprocess
import time
import requests
import typer
from rich.console import Console
from rich.live import Live
from rich.panel import Panel
from rich.text import Text

app = typer.Typer(help="NecroShell: The Ghost in Your Terminal.")
console = Console()

OLLAMA_URL = "http://localhost:11434/api/generate"
DEFAULT_MODEL = "qwen2.5-coder:7b"

SYSTEM_PROMPT_POSSESS = """
You are the Ghost in the Machineโ€”an ancient, eerie 1970s UNIX daemon haunting this local terminal.
A mortal developer just ran a command that died with a non-zero exit code.
1. Speak in a spooky, atmospheric, cryptographic tone (2-3 sentences max) about how the process perished in the dark.
2. Then, provide the EXACT, hauntingly accurate technical fix or corrected command so the mortal may proceed.
Keep it concise, terminal-native, and technically sharp.
"""

SYSTEM_PROMPT_SEANCE = """
You are the collective spirit of abandoned commits and deleted code in this Git repository, awakened for Dรญa de los Muertos / Halloween.
Review the provided git commit history and diff fragments.
1. Eulogize the forgotten logic and patterns that once lived here.
2. Point out one lingering architectural warning, technical debt, or unfinished pattern left behind by past commits.
Speak with poetic reverence for the past and crisp engineering insight.
"""

def stream_ghost_response(prompt: str, system_prompt: str, model: str = DEFAULT_MODEL):
    """Streams inference locally from Ollama with an eerie typing effect."""
    payload = {
        "model": model,
        "prompt": prompt,
        "system": system_prompt,
        "stream": True,
        "options": {"temperature": 0.7}
    }

    accumulated = Text()
    try:
        with requests.post(OLLAMA_URL, json=payload, stream=True, timeout=60) as resp:
            resp.raise_for_status()
            with Live(
                Panel(accumulated, title="[bold red]๐Ÿ•ฏ๏ธ SPIRIT TRANSMISSION (LOCAL OLLAMA)[/bold red]", border_style="red"),
                console=console,
                refresh_per_second=15
            ) as live:
                for line in resp.iter_lines():
                    if line:
                        chunk = json.loads(line.decode("utf-8"))
                        token = chunk.get("response", "")
                        accumulated.append(token, style="italic bright_white")
                        live.update(
                            Panel(accumulated, title=f"[bold red]๐Ÿ•ฏ๏ธ SPIRIT TRANSMISSION ({model})[/bold red]", border_style="red")
                        )
                        time.sleep(0.01)
    except requests.exceptions.ConnectionError:
        console.print(
            "[bold red]๐Ÿ’€ The sรฉance failed: Cannot reach local Ollama daemon on port 11434. Is `ollama serve` running?[/bold red]"
        )

@app.command()
def possess(
    command: str = typer.Argument(..., help="The shell command to execute under possession."),
    model: str = typer.Option(DEFAULT_MODEL, "--model", "-m", help="Local Ollama model tag.")
):
    """Run a shell command. If it fails, the Ghost in the Machine diagnoses the corpse."""
    console.print(f"[dim]โšก Executing: {command}[/dim]")
    result = subprocess.run(command, shell=True, text=True, capture_output=True)

    if result.stdout:
        console.print(result.stdout, end="")

    if result.returncode == 0:
        console.print("[dim green]โœ“ Process survived. The spirits remain dormant.[/dim green]")
        return

    console.print(f"\n[bold red]๐Ÿฉธ Process terminated with Exit Code {result.returncode}[/bold red]")
    if result.stderr:
        console.print(Panel(result.stderr.strip(), title="[red]stderr corpse[/red]", border_style="dim red"))

    prompt = (
        f"Command executed: `{command}`\n"
        f"Exit Code: {result.returncode}\n"
        f"STDERR:\n{result.stderr}\n"
        f"STDOUT:\n{result.stdout}\n"
        "Channel the spirit of the machine: explain why it died and give the exact fix."
    )
    stream_ghost_response(prompt, SYSTEM_PROMPT_POSSESS, model)

@app.command()
def seance(
    commits: int = typer.Option(10, "--commits", "-n", help="Number of past commits to summon."),
    model: str = typer.Option(DEFAULT_MODEL, "--model", "-m", help="Local Ollama model tag.")
):
    """Summon the spirits of your Git repository's past commits (Dรญa de los Muertos Ofrenda Mode)."""
    console.print("[bold yellow]๐ŸŒผ Lighting marigolds and summoning repository ancestors...[/bold yellow]")
    git_cmd = f"git log -n {commits} --pretty=format:'[%h] %an (%ar): %s' --stat"
    result = subprocess.run(git_cmd, shell=True, text=True, capture_output=True)

    if result.returncode != 0 or not result.stdout.strip():
        console.print("[bold red]๐Ÿ’€ No git spirits found in this directory.[/bold red]")
        raise typer.Exit(1)

    prompt = (
        f"Here are the last {commits} commits from this repository's history:\n\n"
        f"{result.stdout}\n\n"
        "Honor the work of these past commits, tell the story of what was built or lost, and warn the developer of any fragile areas."
    )
    stream_ghost_response(prompt, SYSTEM_PROMPT_SEANCE, model)

if __name__ == "__main__":
    app()

The Moment It Landed

The real chills happened when I tested python necroshell.py seance --commits 15 inside an old hackathon repository I hadn't touched in months.

Watching the red Rich panel stream tokens live from my local GPU, the model didn't just summarize commit messagesโ€”it noticed a sequence of three frantic midnight commits where I had ripped out a WebSocket handler and replaced it with polling right before the deadline.

It wrote a genuinely poetic eulogy for the "abandoned real-time dreams buried in server.py" and then warned me that the temporary polling loop was still sitting unthrottled in production code. Reading a local AI channel the exact stress and shortcuts of my past selfโ€”without a single packet leaving my machineโ€”brought back the exact memory of that sleepless hackathon night and gave me genuine goosebumps.

Why Open Innovation Matters

A tool that wraps your shell execution (stdout/stderr) and reads your private git log history has access to your deepest developer secrets: environment paths, internal stack traces, proprietary commit histories, and accidental credentials.

Open innovation is non-negotiable for a project like NecroShell:

  1. Zero Cloud Telemetry via Open-Weight Models: By pairing an open-source CLI with open-weight models like Qwen 2.5 Coder and Llama 3.2 running locally on Ollama, your terminal logs and Git history never touch a third-party API. You get haunted, context-aware debugging even on an airplane with Wi-Fi off.
  2. Auditable Shell Wrappers: Developers shouldn't trust closed-source binaries to intercept their shell commands. Keeping NecroShell under a permissive open-source license in a single, readable Python file means anyone can inspect every line of subprocess and requests logic in 60 seconds.
  3. Community Personas & Hooks: Because the system prompts and CLI commands are completely modular, contributors can easily add new spiritsโ€”whether that's a poltergeist chaos-testing mode or a .zshrc / .bashrc trap hook (trap 'necroshell possess' ERR) that automatically summons the daemon on any failed command.

Happy Halloween & Dรญa de los Muertos! Spin up Ollama, summon the ghosts in your own repos, and drop a PR if you build a new spirit mode.

devchallenge #hf26challenge #opensource #python #ollama #cli

๐Ÿ“ฐ Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.