Watch the recording on asciinema
There is a specific small thrill the first time you type rm -rf / --no-preserve-root and actually mean it. No backups, second thoughts or warranty to void. I get to feel it as often as I like now, because the computer I am deleting was never there.
This post is a little different from what I usually write here.
Most of the time, I write about software that is supposed to be manageable, useful, and boring in the right places. vibeSH is not that. vibeSH is dessert. It is a toy project with almost no practical value, built mostly because the idea made me laugh and then kept getting funnier the longer I worked on it.
vibeSH is a shell that sits in front of a language model and asks it to be a computer. It does not call tools or run commands. It performs the whole machine.
You type ls, and the model imagines what would be in the directory. You cat a file, and it invents the contents on the spot, then remembers them for the rest of the session. The filesystem, the processes, the network, the occasional kernel panic: all of it is improvised, and none of it is real.
$ uv run vibesh.py
vibebox login: user
user@vibebox:~$ git clone --depth 1 https://git.kernel.org/.../linux.git
Cloning into 'linux'...
Receiving objects: 100% (92301/92301), 240.18 MiB | 12.66 MiB/s, done.
user@vibebox:~$ cat linux/kernel/sched/core.c
It clones Linux very quickly because cloning Linux, here, means deciding that you now have a copy of Linux. Then you cat a kernel file and it dreams up something that looks enough like the scheduler to make you uneasy, and from then on that is what is in that file.
I did not write the kernel. Neither did the model, really. We agreed it exists and moved on.
The project is called vibeSH. It is a fully hallucinated terminal shell.
The inspiration
The immediate inspiration was Steve Sanderson’s VibeOS, shown around Microsoft Build 2026 under the title “VibeOS – Fully Hallucinated Operating System”. The idea was wonderful: an operating system where the applications are hallucinated into existence by a model. It looked like a desktop environment, but the desktop was really a stage.
That idea stuck in my head.
I kept thinking about what the terminal version would be. A desktop OS has windows, icons, applications, and little visual lies. A shell has something else: rituals.
Prompts. Paths. Error messages. Man pages. Daemons. Logs. /etc. /var. Strange warnings from programs you half remember installing. A terminal is already a role-playing environment. You type into it and expect the machine to answer in a very particular dialect.
Models have seen enough shell transcripts, man pages, Stack Overflow answers, package logs, and half-broken terminal sessions to speak Unix with an accent. The question was whether I could put that performance behind an interface that felt like an actual terminal instead of a chat box wearing a fake prompt.
So I built the terminal version.
Giving the hallucination a body
The idea of asking a language model to behave like a Linux shell is not new. People were already doing that with early ChatGPT prompts in late 2022. You could say “act as a Linux terminal”, type ls, and the model would print something plausible.
That was already fun. It also had a very different feel. A chat prompt pretending to be a shell is still a chat. You type something, the whole answer appears, and then you type the next thing. The illusion works for a moment, but the interface keeps reminding you where you are.
vibeSH tries to make the shell feel like a shell, and most of that is in how output behaves over time.
Output arrives in chunks, so a long-running command does not have to appear all at once. An imaginary apt install can download packages, unpack them, configure services, print warnings, pause, continue, and generally behave like a process that is taking its time. Colors work and the prompt can be styled.
Full-screen programs like vim, less, and top work too, in the sense that matters. The REPL batches your keystrokes and the model repaints the whole screen on each round trip, so using them feels exactly like SSH over a 1996 modem. You type a burst, you wait, the screen catches up. top refreshes on its own, but each refresh is another model turn, which makes it the most leisurely process monitor ever built. You can watch the load average change at the speed of an API call. It is strangely relaxing.
Even tab completion is hallucinated. Press Tab and the model completes against the imaginary machine: git che becomes checkout, paths complete against whatever it has decided lives here. It costs nothing until you press it, and then the box pauses to think, because of course it does. It is making up the filesystem you are asking it to autocomplete.
The difference sounds small until you feel it. A model saying “here is what a terminal would output” is one thing. A terminal that waits, paints, completes, redraws, and stutters like a remote shell over a bad connection is something else. It gives the hallucination a body.
The whole machine is the conversation
Here is the part I find genuinely interesting, and the reason I kept building instead of treating it as a one-evening joke.
The machine has no storage. There is no virtual disk, no hidden world model, no background simulator updating state behind the scenes. The session’s conversation history is the computer. Everything the box “is” at any moment is just the sum of what has been said so far: the files you read into existence, the packages you pretended to install, the hostname you talked it into, the weird log message it invented and then had to live with.
Close the terminal and the machine is gone, the way a dream is gone, except it briefly had a working apt.
This has a few consequences that feel like physics once you sit with them.
Files do not exist until you look at them. A file is pure potential right up until you cat it or ls its directory, and the act of observing it is what fixes its contents. Before that, it is neither there nor not-there. Schrödinger ran a startup, apparently, and this is the shell.
Saving the machine is trivial, because saving the machine is just saving the transcript. You configure a box, install some imaginary tooling, get the prompt exactly how you like it, write it to a JSON file, and reload the whole computer next week exactly as it was. The save format is not a snapshot of a system. It is the memory of a conversation about one.
In a normal shell, cat README.md reads a file. In vibeSH, cat README.md creates an obligation.
Talking to management
Not everything you type goes to the machine. Anything starting with @ai talks to the director instead, which is how you rewrite reality mid-session.
user@vibebox:~$ @ai make this box a Solaris machine from 1996
ok, SPARCstation 5, Solaris 2.5.1, hostname 'gravity'.
gravity%
You can tell it the disk is slowly failing and should get worse over time. You can tell it there is a cron job that occasionally leaves ominous notes in /var/log. You can tell it this is actually a Commodore 64 and only speaks BASIC, and it will be a Commodore 64. The directives stick.
That is the part that made the project click for me. The model is not only pretending to be a computer. It is pretending to be a computer whose genre can change while you are logged in. A Linux box can become Solaris. Solaris can become haunted. The haunted Solaris machine can slowly lose its disk. Then you can ask it why /var/adm/messages contains breathing.
This is exactly as useful as it sounds.
Unreliable RAM is canon
Long sessions eventually overflow the model’s context window. When that happens, the oldest parts of the conversation fall out of memory, which means the machine develops amnesia. Files you wrote earlier may have quietly rewritten themselves. A directory you visited an hour ago might come back subtly different.
On any normal system this would be a serious bug. Here it is canon. The box has bad memory. It forgets things, it misremembers files, and it is doing its honest best with a transcript that no longer fits.
I decided early not to fight this completely. Some drift needs to be handled with parsers, tests, and stricter protocols. Local models in particular can mumble through the wire format, leak thoughts, glue JSON together, or forget what kind of machine they are supposed to be. But some of the weirdness belongs to the project. The fake computer getting old files wrong is not ideal, but it feels fitting. Its memory is literally conversation, and when the context gets too full, old parts of the dream get blurry.
That became one of vibeSH’s laws of physics:
Long sessions overflow the model’s context, so the machine gets amnesia and old files may have quietly rewritten themselves. This is not a bug. This is canon. The box has bad memory. Relatable.
There is a lot of freedom in building a toy where the failure modes can become lore.
The plumbing behind the joke
The stupid idea still needed a surprising amount of non-stupid plumbing.
vibeSH is a REPL in front of a model, but it is not just sending a command and printing a reply. There is a small wire protocol between the shell and the model. The model emits events like output chunks, prompt updates, yields, completions, out-of-character notes, and exits. The shell turns those into terminal behavior.
That makes a few things possible. Long-running commands can stream instead of dumping everything at once. Full-screen programs can repaint the display. Tab completion can ask the imaginary machine what might complete. You can force-quit a stuck full-screen program with Ctrl+] or hard-kill the whole thing with Ctrl+\. And snapshots can save the session, because the session is the machine.
There are also different brains to plug in. You can use Anthropic’s API, Claude via the Agent SDK, local OpenAI-compatible servers like llama.cpp or Ollama, or hosted providers such as OpenRouter. Strong models are better at staying in character. Smaller local models are often more chaotic. Sometimes chaos is a feature. Sometimes it is just broken JSON. There is even an optional grammar mode for local backends, because nothing says “whimsical dream computer” like forcing a model to obey an output protocol byte by byte.
The project is useless, but the uselessness took real work to hold up.
Vibe coding a vibe shell
The colophon says it plainly: this was fully vibe coded.
That felt appropriate. A human and a language model built a shell whose entire job is to be a language model pretending to be a computer. Calling it vibeSH and then pretending the recursion was not the point would have been cowardice.
The model was genuinely useful here. It helped sketch out terminal edge cases, generate boring glue code, iterate on prompts, and produce weird test scenarios. It was also good at discovering what kind of machine the fake machine wanted to be.
The important part was still taste. A project like this can become mush very quickly. The model will happily add features forever. The work is deciding where the boundary is, what should stay fake, what needs real engineering, and which errors are funny enough to keep. The point is not to make the model omnipotent. The point is to put it in a box where its particular kind of wrongness becomes entertaining.
That is also why the safety story is simple. Nothing in vibeSH touches your real machine. rm -rf / is content. The fake computer can panic, corrupt itself, delete its imaginary filesystem, and collapse into smoke. Your actual files are not involved. The danger is theatrical.
Contained hallucination
That boundary is the part I keep coming back to.
The model can hallucinate anything inside the box. It can invent files, logs, packages, processes, devices, mysterious old cron jobs, fake kernel source, haunted man pages, and a /var directory with emotional problems. It cannot touch the real filesystem. It cannot run real commands. It cannot see your secrets. The entire project works because the hallucination is contained.
That pattern shows up in my more serious software too.
This blog, for example, is published with Stelae, a thing I am building around a similar boundary. WordPress is useful as an editor, so Stelae keeps it where it is useful. The public site is static HTML, so the outside world gets boring files instead of a live PHP application with a database and login page.
That is a much less cursed project than vibeSH, but the taste is related: put the powerful, messy machinery behind a hard boundary, then expose something simple. In vibeSH, the simple thing is a terminal pointed at a fake universe. In Stelae, the simple thing is a static website.
Try it
vibeSH is on Codeberg:
You need uv and a model. Claude gives the most convincing machine in my testing. Qwen3-Coder-30B-A3B is a good local option. Cheap hosted models can also work, depending on how much character drift you are willing to forgive.
A few good first commands:
ls
cat README.txt
uname -a
ps aux
top
@ai make this a haunted Solaris machine from 1996
ls /var/adm
sudo rm -rf / --no-preserve-root
If you try it, please do not tell me whether it is useful.
It is not.
Tell me what kind of machine it became.
