Backseat coding with a ghost driver
How Shelley and I write code together
Hi! This is my first Substack post in years. Some subscribers probably forgot who I am and why they subscribed to this mailing list. If that’s the case for you, go ahead and unsubscribe. Or if you want more updates than are likely to appear here, I post more frequently (but more randomly) to my Bluesky account.
Two and a half years ago, I did some experiments writing code with ChatGPT’s Code Interpreter, which seemed very promising, but not yet practical. Since then, I’ve been reading lots of articles about AI, but not doing much with AI-assisted coding myself. (I’m retired and have other interests, so it doesn’t really matter if I’m left behind.)
After seeing a post about someone vibe-coding a personal shopping list app in the grocery store, it seemed about time to try it again.
It turns out that writing code is a lot of fun if you don’t have to do the work! I doubt I will ever go back to writing code myself. It did take a few days of experimenting before I decided on a good setup. I’ll describe it in more detail, in case it helps someone.
A $HOME in the cloud
A lot of people run Claude Code on their laptop. I have a very nice laptop, so I tried it, but it doesn’t suit me. I’d rather chat in a browser tab than in a terminal window. I like to close the lid on my laptop when doing other things, but when the laptop goes to sleep, that will pause any coding agent that’s running locally. I’m also a bit wary of coding agents making mistakes or being subverted, so I don’t want to give it direct access to my laptop or the local network. The best coding agents require an Internet connection anyway, so you don’t lose much by running it in the cloud.
I’m using exe.dev, which is what you get if you start with a regular hosting service for Linux VM’s and add some nice extras that make vibe-coding easy. When you create a new VM, the service automatically sets up a coding agent called Shelley.1 You can chat with Shelley in a browser tab. I keep that tab pinned in my browser so I can chat with it whenever I like.
Shelley’s UI is bare-bones but has everything you really need; it should be familiar to anyone who has used the ChatGPT website.
Although I can easily log in using ssh to run Unix commands, you could in theory do without it entirely and ask Shelley to do everything for you. (Shelley is an AI replacement for a shell - get it?)
At the time I’m writing, exe.dev is brand new; they haven’t even implemented billing yet. “Free for now” is certainly a nice way to get started, but I’m pretty sure that I’ll start paying for a subscription when they set that up.
You can create as many VM’s as you like. They will all share the same quotas, based on your subscription plan. After a few experiments, I settled on using a single VM for development, with a directory for each project, much like I would in my home directory on my laptop. There’s a risk that the coding agent will delete all my project directories, but it doesn’t seem too likely. Since I regularly push code to Github, it should be possible to recover.2
Setting up the VM: Shelley can help
Shelley and I need a way to push code to Github from the VM. We are using a personal access token that’s locked down to just the repositories that I want to give Shelley access to. After generating a token on GitHub’s website, giving the VM access was easy: I just pasted the access token into Shelley’s window and asked it to install it. It knows which config files to edit. (I did take a peek at them myself using ssh.)
For viewing files in the project directory, I use VS Code. It has an extension to access a remote folder via ssh. This is a comfy coding environment. I could edit any project files I like, but in practice I’m just using it to read code and look at diffs.
I’m writing a Chrome extension, so I often need to copy files to my laptop for manual testing. I set up a one-way sync using Syncthing that copies files from the release directory in the VM to a local directory.3 The Syncthing software isn’t as simple as it could be, but it’s free and does the job. I asked Shelley to set up Syncthing on the VM4 and asked Shelley for directions on how to set up the other end on my laptop.
Setting up our project
I’ve been using Deno a lot recently so I decided to stick with that. Shelley handles it fine. We have a build script to compile the source for my Chrome extension from Typescript to JavaScript, and Shelley could write any other scripts we need the same way.
Shelley can also use a browser. It has access to commands for starting a headless instance of Chrome on any web page, taking a screenshot (which will be displayed in Shelley’s chat transcript), running an arbitrary JavaScript expression on the web page, and reading the console log. It turns out that’s enough to drive the browser. Sadly for me, there’s no way to load a Chrome extension, but Shelley and I hacked up a way to load a content script into an arbitrary web page. That means I can ask Shelley to reproduce bugs by doing “manual” testing on a URL that I give it.
What coding is like now
If you’re using open source software and you encounter a bug, you could create a Github issue explaining what the bug is and how to reproduce it. Maybe someone else will fix it in a few weeks or months or maybe never.
When I’m using my Chrome extension and I notice something that could be improved, I switch to the Shelley tab and write a bug report. Shelley will try to reproduce the bug, then go on to try to fix it. Sometimes that works the first time. Otherwise, it might ask questions. I will make a few suggestions on what to try or nag it to write more tests.
This reminds me a bit of pair programming. Back in the days when Extreme Programming was new, I worked at a job where we pair-programmed all the time. One person was typing and the other was watching and making suggestions, but we’d switch off frequently so that the person who’s not “driving” has to keep paying attention and not space out.
Those days are gone. Now I have a full-time driver. I’m in the back seat, giving directions when asked, or perhaps browsing the Internet if the driver doesn’t need any help. I do look in now and then to make sure we’re going in the right direction. I have opinions about how code should be written, so I take a look now and then and ask Shelley to do refactorings. I thought “hey, property tests would be a good idea” so I asked it to use my experimental property test framework that nobody ever uses. Now it has a user. It’s a ghost, so not a real user,5 but I’m happy with that.
For now, I’m fine with just having one driver. There are people who are running multiple coding agents at once for more productivity, but since I’m a hobby programmer now, I see no reason to spin more plates. If I did want to do more at once, I would use a “shared nothing” architecture by putting coding agents on disjoint products.
It currently runs Claude Opus 4.5 by default, which is very good. Others are available, but I’m happy with the default.
A coding agent could in theory clobber any Github repos you give it access to as well, but you would still have the code if you cloned it somewhere.
Since it’s syncing executable code, that’s a possible way for a coding agent or someone controlling it to hack into my laptop. I’m going to live with that risk. I’m guarding against accidents, not malice.
I asked Shelley to configure Syncthing by editing its config file and to shut down its UI, since I don’t want to leave that port open. Why have a UI when you can ask a bot for edits?


