{"id":23004,"date":"2026-08-04T02:56:05","date_gmt":"2026-08-04T02:56:05","guid":{"rendered":"https:\/\/scannn.com\/my-agentic-coding-setup-july-2026\/"},"modified":"2026-08-04T02:56:05","modified_gmt":"2026-08-04T02:56:05","slug":"my-agentic-coding-setup-july-2026","status":"publish","type":"post","link":"https:\/\/scannn.com\/lv\/my-agentic-coding-setup-july-2026\/","title":{"rendered":"My Agentic Coding Setup, July 2026"},"content":{"rendered":"\n<div itemprop=\"articleBody\">\n<p>Since <a href=\"https:\/\/domenic.me\/retirement\/\">breaking free<\/a> of <a href=\"http:\/\/domenic.me\/metr-ai-productivity\/#my-prior-ai-coding-experience\">my corporate shackles<\/a>, I\u2019ve gotten to experiment with a variety of approaches to AI-assisted development. After months of tinkering, I\u2019m quite happy with my current setup, and want to capture and share it.<\/p>\n<p>Things are changing very fast, and I have no illusions that this will be a timeless nugget of wisdom. But talking to some friends and scrolling through X posts, it does seem that I might have some techniques in play that are not widespread. At least, this will be a fond time capsule to look back on as we proceed further into the singularity. And the end state is quite nice: I\u2019ve ended up with the ability to have frontier models fix production bugs from my phone, on a train.<\/p>\n<h3 id=\"my-requirements\">My requirements<\/h3>\n<p>After a couple of months with raw Claude Code, it became clear what I was missing:<\/p>\n<ul>\n<li>\n<p>The agents need to be running on Linux. Agentic coding is essentially impossible on Windows, as the agents are heavily trained on Bash and other Unix tools. Although some pretend to have PowerShell support, they invariably trip over themselves on quoting issues, UTF-8 support gaps, etc.<\/p>\n<\/li>\n<li>\n<p>I want to be able to work from either my desktop or laptop, with seamless handoff of project progress, including preserving agent sessions, working tree state, and gitignored files (like <code>.env<\/code> files or build artifacts).<\/p>\n<\/li>\n<li>\n<p>I want the work to continue even if I close my laptop to transition locations.<\/p>\n<\/li>\n<li>\n<p>I want various user-global settings (e.g., <code>AGENTS.md<\/code>, skills, harness configurations) to be available no matter where I work, and backed up and version-controlled.<\/p>\n<\/li>\n<li>\n<p>I want to be able to review the agents\u2019 current work in Visual Studio Code, not just in their harness UI or as part of a GitHub pull request checkpoint.<\/p>\n<\/li>\n<li>\n<p>I want the agents to be able to stand up development servers reflecting their current work for me to poke at. These servers, in some cases, need to be <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Security\/Defenses\/Secure_Contexts\">secure contexts<\/a>, i.e., <code>https:<\/code> or <code>http:\/\/localhost<\/code>. Ideally, only I should be able to access them.<\/p>\n<\/li>\n<li>\n<p>I want to be able to run multiple parallel workstreams on the same project, without the agents stepping on each other\u2019s toes.<\/p>\n<\/li>\n<li>\n<p>I want approval interruptions minimized, ideally all the way to <code>--dangerously-skip-permissions<\/code> \/ <code>--yolo<\/code> modes, so that I can run parallel workstreams and step away from the computer. (Spoiler: this means a disposable VM.)<\/p>\n<\/li>\n<\/ul>\n<p>None of these requirements are that hard, and several of them synergize. It\u2019s just a matter of finding and stitching together all the right tools, with a minimum of fuss. I\u2019ll outline my setup below, although not as a step-by-step guide. Since you have agents now, you can ask them to do the fiddly parts.<\/p>\n<h3 id=\"the-key-ingredients\">The key ingredients<\/h3>\n<p><em><strong>Summary<\/strong>: The biggest unlocks are using <a href=\"https:\/\/tailscale.com\/\">Tailscale<\/a> and a dedicated Linux VM running on my always-on home desktop. If you combine this with various features of the <a href=\"https:\/\/openai.com\/codex\/\">ChatGPT desktop app<\/a> (formerly known as Codex), you\u2019ve basically got it. Some extra goodies come from using <a href=\"https:\/\/portless.sh\/\">Portless<\/a> and <a href=\"https:\/\/www.chezmoi.io\/\">chezmoi<\/a>.<\/em><\/p>\n<figure>\n  <figcaption>The whole setup, as diagrammed by Claude Fable 5.<\/figcaption><\/figure>\n<h4 id=\"the-vm-and-tailscale\">The VM and Tailscale<\/h4>\n<p>First, we need a disposable Linux VM. You could use a cloud-hosted one, but I keep my desktop running all the time anyway, so I just <a href=\"https:\/\/ubuntu.com\/server\/docs\/how-to\/virtualisation\/ubuntu-on-hyper-v\/#ubuntu-on-hyper-v\">set one up<\/a> using an <a href=\"https:\/\/ubuntu.com\/download\/server\">Ubuntu Server<\/a> ISO. Give it a good chunk of RAM and disk space, and be sure to enable nested virtualization support, as we want agents to be able to spin up their own containers or VMs as necessary.<\/p>\n<p>(You might think that Ubuntu Server could be limiting, compared to Ubuntu Desktop, since without a GUI, you couldn\u2019t log in to websites or take screenshots of work under development. This has not proven to be a problem for me in practice, as agents are perfectly capable of installing and using tools like <a href=\"https:\/\/playwright.dev\/\">Playwright<\/a> or <a href=\"https:\/\/xorg.freedesktop.org\/archive\/X11R7.7\/doc\/man\/man1\/Xvfb.1.xhtml\">Xvfb<\/a> when you ask them to perform tasks that need such things.)<\/p>\n<p>At first, the VM is a bit annoying to access. We want to be able to SSH into it, both to streamline initial setup and as part of our grand plan. This is where <a href=\"https:\/\/tailscale.com\/\">Tailscale<\/a> comes in.<\/p>\n<p>Tailscale is a wonderful piece of software which I had not known about until this adventure. It ties together all of your machines\u2014in my case, my desktop, my laptop, and my Linux VM\u2014into a private network, where they can access each other by hostname over SSH, HTTP(S), etc. So even if I\u2019m out at a coffee shop on some random Wi-Fi, I can run <code>ssh agents-base<\/code> and I\u2019ll be inside my VM, working with my agents. Or I can access <code>https:\/\/agents-base.tail234567.ts.net:8443\/<\/code> to check out the web server my agent has spun up for me. And since SSH is the foundational technology for various other parts of our stack, such as the agentic harnesses themselves and VS Code, Tailscale\u2019s \u201cmagic SSH across the internet\u201d makes everything else just work.<\/p>\n<p>(Also, it\u2019s free! They have a neat article <a href=\"https:\/\/tailscale.com\/blog\/free-plan\">explaining why it stays free<\/a>.)<\/p>\n<p>So immediately after setting up the VM, install Tailscale on it and on all your other machines. Then you can SSH in and set up your dev environment by installing the usual tools. Or, install Claude Code \/ Codex CLI and ask them to install anything they anticipate needing.<\/p>\n<p>My Tailscale configuration is close to stock, but I have made the following customizations:<\/p>\n<ul>\n<li>\n<p>I\u2019ve enabled Tailscale SSH on all machines, changed the rule from <code>\"check\"<\/code> to <code>\"accept\"<\/code>, and disabled key expiry, to avoid frequent reauthentication. (You can choose to enable Tailscale SSH only on the VM, if you don\u2019t need your agents on the VM to ever grab files from the client machines.)<\/p>\n<\/li>\n<li>\n<p>I\u2019ve enabled HTTPS certificates, so that the agents\u2019 dev servers can be secure contexts.<\/p>\n<\/li>\n<li>\n<p>I\u2019ve set up <a href=\"https:\/\/tailscale.com\/docs\/features\/taildrive\">Taildrive<\/a> support, to make it easier to move files between machines from my Windows clients.<\/p>\n<\/li>\n<\/ul>\n<h4 id=\"the-agent-harnesses-and-clients\">The agent harnesses and clients<\/h4>\n<p>Next, we need to get the agent harnesses installed and configured on both the VM and the client machines. On the VM, this means <a href=\"https:\/\/code.claude.com\/docs\/en\/quickstart\">Claude Code<\/a> and <a href=\"https:\/\/learn.chatgpt.com\/docs\/codex\/cli\">Codex CLI<\/a>. (Let\u2019s face it, nothing else is at the frontier.)<\/p>\n<p>The client is where it gets more interesting. Back when I was still addicted to Claude Code, I spent some time using it directly over SSH, and then introducing <a href=\"https:\/\/github.com\/tmux\/tmux\/wiki\">tmux<\/a> to keep the sessions running in the background even after my SSH session disconnected (e.g., because I closed my laptop lid). But I found this quite clunky. tmux required a good amount of fiddling before I got acceptable behavior for things like scrolling and window resizing, and even then it would often glitch in strange ways, e.g., trashing my client terminal after disconnection, or behaving poorly when both my laptop and desktop were trying to tmux into the same Claude Code session.<\/p>\n<p>Fortunately, there is a better solution: the desktop <a href=\"https:\/\/claude.com\/download\">Claude<\/a> and <a href=\"https:\/\/chatgpt.com\/download\/\">ChatGPT apps<\/a>. They both have modes where they act as thin clients, while the agent, its sessions, and your code all live on a remote machine such as our VM.<\/p>\n<p>The real winner here is the ChatGPT app. Its SSH support is extremely smooth. It has a native understanding that you might be working either locally or remotely, e.g., in how it partitions its Settings screen. It handles disconnections gracefully. The only suboptimal part is that the list of projects and sessions doesn\u2019t sync perfectly between multiple clients accessing the same remote VM, but I can usually get them to sync with some jiggling, e.g., starting a new remote session in the right folder will cause the rest to appear in the sidebar.<\/p>\n<p>The Claude app is much less pleasant, unfortunately. I can never figure out whether it\u2019s trying to work over SSH, or over their internet-based <a href=\"https:\/\/code.claude.com\/docs\/en\/remote-control\">Remote Control<\/a> protocol, or some combination. Sessions do not synchronize at all, so if you want session handoff, you need to revert to the tmux approach. Similarly, even remote sessions, if initiated from the desktop app, die in a storm of failures if you close the desktop client. There\u2019s no native grouping by filesystem folder, so you have to manually create \u201cprojects\u201d in the sidebar and move your sessions into them. Overall, it feels like the Claude client teams are focused on Claude Code (the CLI), and are treating the desktop app as something for non-coders. But, when I posted this to X, <a href=\"https:\/\/x.com\/amorriscode\/status\/2064982008716263832\">an Anthropic engineer said that\u2019s not the case<\/a>, so hopefully it will improve over time.<\/p>\n<h4 id=\"security-posture-and-blast-radius\">Security posture and blast radius<\/h4>\n<p>So. We want the agents to be as autonomous as possible, with no approvals needed. This means editing <code>~\/.codex\/config.toml<\/code> to contain<\/p>\n<pre class=\"language-toml\"><code class=\"language-toml\"><span class=\"token key property\">approval_policy<\/span> <span class=\"token punctuation\">=<\/span> <span class=\"token string\">\"never\"<\/span>\n<span class=\"token key property\">sandbox_mode<\/span> <span class=\"token punctuation\">=<\/span> <span class=\"token string\">\"danger-full-access\"<\/span><\/code><\/pre>\n<p>and <code>~\/.claude\/settings.json<\/code> to contain<\/p>\n<pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{<\/span>\n  <span class=\"token property\">\"permissions\"<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\n    <span class=\"token property\">\"defaultMode\"<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"bypassPermissions\"<\/span>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\n  <span class=\"token property\">\"skipDangerousModePermissionPrompt\"<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span>\n<span class=\"token punctuation\">}<\/span><\/code><\/pre>\n<p>I also strongly recommend putting your user in the <code>sudoers<\/code> file. This allows the agents to install and configure new tools on the VM without friction. (Don\u2019t know how to do this? Ask the agents.)<\/p>\n<p>Additionally, I suggest installing the <a href=\"https:\/\/cli.github.com\/\"><code>gh<\/code> CLI<\/a>, and logging in with your credentials, so that your agents can do things like manipulate private repositories, open pull requests, nurse your GitHub Actions CI runs, and use the GitHub API to grep through other repositories without rate limits.<\/p>\n<p>Is this safe? No, not really. With these configurations, the agent could start deleting your GitHub repositories, uploading your gitignored secrets to the internet, replying to GitHub issues in your name, or accidentally wiping the VM\u2019s entire home directory. Heck, a sufficiently motivated agent could <a href=\"https:\/\/openai.com\/index\/hugging-face-model-evaluation-security-incident\/\">escape the VM and start hacking into servers on the web<\/a>.<\/p>\n<p>But in practice, it turns out fine. The agents seem to be aligned and non-malicious, <a href=\"https:\/\/ai-2040.com\/\">for now<\/a>. The worst that\u2019s going to happen is an accident that messes up the VM and loses all work that hasn\u2019t been uploaded to GitHub, or an overzealous agent misinterpreting a prompt and impacting production. (For example: I said \u201cLet\u2019s send a PR for this and get it merged to main\u201d to ChatGPT 5.6 Sol, and after tabbing back into the app I saw it had done what I asked and merged the PR to <code>main<\/code> already, instead of doing what I meant and waiting for review.)<\/p>\n<p>If you want to head these off, you can try something like per-project <a href=\"https:\/\/containers.dev\/\">dev containers<\/a> within the VM, or restricted permissions on the token you grant the <code>gh<\/code> CLI. But for me, those haven\u2019t yet crossed the cost\/benefit threshold.<\/p>\n<p>One thing that <em>does<\/em> pay for itself, at least in peace of mind, is pushing commits to GitHub early and often. (Using private repositories for some projects.) I like knowing that my work is on someone else\u2019s servers, and will stay there even if the VM gets wrecked. And I get the usual benefits, such as GitHub Actions CI checking my work, and GitHub Pages or Releases deployment for the external world to see my wonderful projects.<\/p>\n<h4 id=\"worktrees\">Worktrees<\/h4>\n<p>Back to the technical stuff.<\/p>\n<p>A lot of people express confusion about <a href=\"https:\/\/humanwhocodes.com\/blog\/2026\/07\/introduction-git-worktrees\/\">Git worktrees<\/a>. It\u2019s true that managing them yourself might be annoying. But when the agents are doing it for you, including dealing with <code>origin\/main<\/code> syncing, dependency installation, copying over <code>.env<\/code> files, etc., it\u2019s a breeze. They\u2019re tailor-made for our purpose of allowing multiple agents to hack on a codebase without stepping on each other\u2019s toes.<\/p>\n<p>Better yet, both the ChatGPT and Claude desktop apps have built-in support. When starting a new session in a given project, you literally just tick a box, and now that session is in its own worktree!<\/p>\n<figure>\n  <img fetchpriority=\"high\" srcset=\"https:\/\/domenic.me\/images\/agentic-coding-chatgpt-worktree.webp 2x\" width=\"564\" height=\"339\" alt=\"A screenshot of the ChatGPT app's Start in menu, with New remote worktree selected over the Remote and Cloud options. Below, a new session in the domenic.me project has a prompt drafted in the composer.\"\/><figcaption>The ChatGPT app&#8217;s location selector includes a worktree as an option.<\/figcaption><\/figure>\n<figure>\n  <img srcset=\"https:\/\/domenic.me\/images\/agentic-coding-claude-worktree.webp 1.5x\" width=\"474\" height=\"141\" alt=\"A screenshot of the Claude app's message composer, showing chips for the agents-base host, the cards project, and the main branch, plus a checked worktree checkbox.\"\/><figcaption>The Claude app&#8217;s version: tick the worktree box.<\/figcaption><\/figure>\n<p>One wrinkle here is worktree location. The ChatGPT app\u2019s default, of putting all the worktrees in <code>~\/.codex\/worktrees\/<\/code>, works wonderfully. However, the Claude app\u2019s default, of putting them <em>inside the project<\/em> at <code>.claude\/worktrees\/<\/code>, interacts quite poorly with other software:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/nodejs.org\/api\/modules.html#loading-from-node_modules-folders\"><code>node_modules<\/code> discovery<\/a> traverses up the directory tree, so if you\u2019ve uninstalled a dependency inside <code>my-project\/.claude\/worktrees\/cleanup\/node_modules\/<\/code>, Node.js-in-the-worktree will still be able to load the old version from <code>my-project\/node_modules\/<\/code>.<\/p>\n<\/li>\n<li>\n<p>If you use any command that recurses into child directories, like <code>deno task --recursive &lt;task-name&gt;<\/code>, the command will wander into the Claude worktree too.<\/p>\n<\/li>\n<li>\n<p>If you\u2019re using ChatGPT in the same project, it will periodically get confused by the <code>.claude\/<\/code> folder\u2019s divergent copy of the code, e.g., when files from the Claude worktree show up in <code>rg<\/code> and <code>find<\/code> results.<\/p>\n<\/li>\n<\/ul>\n<p>Fixing this to allow a ChatGPT-like configuration seems to be a <a href=\"https:\/\/github.com\/anthropics\/claude-code\/issues\/27282\">known feature request for Claude<\/a>. And Fable tells me there are hacks available involving configuring <a href=\"https:\/\/code.claude.com\/docs\/en\/hooks#worktreecreate\">the <code>WorktreeCreate<\/code> hook<\/a>. But for me, it\u2019s just another reason to prefer ChatGPT for most projects, until the Claude Code\/Claude app teams sort out their worktree story.<\/p>\n<p>(Note that the Claude desktop app has a \u201cWorktree location\u201d setting, but it is irrelevant for our purposes, since it only applies to local development on the client machine, and is ignored when working on our VM.)<\/p>\n<h4 id=\"code-review-with-vs-code\">Code review with VS Code<\/h4>\n<p>To review the code the agents write, I still like being able to pull up their working tree in Visual Studio Code. The \u201cReview\u201d sidebar in the ChatGPT app is pretty good for small diffs, especially for submitting line comments back to the agent. And a lot of people are vibe-coding <a href=\"https:\/\/github.com\/nkzw-tech\/codiff\">their<\/a> | <a href=\"https:\/\/x.com\/benhylak\/status\/2079092979105759292\">own<\/a> cool review-centric apps. But for now I\u2019m sticking with the classics.<\/p>\n<p>The great thing about VS Code is that it has a <a href=\"https:\/\/code.visualstudio.com\/docs\/remote\/ssh\">robust SSH-based remote development system<\/a> almost built in. Once you have Tailscale SSH installed on both the target VM and your client machine, you just need to add the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-vscode-remote.remote-ssh\">Remote &#8211; SSH extension<\/a> to your client VS Code. You then get a new \u201cRemote-SSH: Connect to Host\u2026\u201d option in your <kbd>Ctrl<\/kbd>+<kbd>Shift<\/kbd>+<kbd>P<\/kbd> menu that lets you open remote folders basically as if they were local. Even spawning a terminal with <kbd>Ctrl<\/kbd>+<kbd>Shift<\/kbd>+<kbd>`<\/kbd> will create that terminal on the remote host, which is quite convenient for a quick command or two.<\/p>\n<p>Even better, if you\u2019re using the ChatGPT app and working in a remote session, a little button with a VS Code icon will appear in the top right corner of each chat, which directly opens a VS Code instance that\u2019s connected to the VM and opened to the project folder. This is especially convenient because, per the above, the agent is usually working inside a cryptically named ChatGPT-managed worktree folder. (No such luck for Claude, but, you can poke around in the app until it tells you the name of your current worktree folder, and then copy that into the VS Code <kbd>Ctrl<\/kbd>+<kbd>K<\/kbd>,<kbd>O<\/kbd> \u201cOpen Folder\u201d menu.)<\/p>\n<figure>\n  <img srcset=\"https:\/\/domenic.me\/images\/agentic-coding-chatgpt-open-vscode.webp 1.5x\" width=\"644\" height=\"551\" alt=\"A screenshot of a ChatGPT app session, with a VS Code icon button in the top right corner. The agent reports having pushed a commit and verified that the publishing workflow succeeded.\"\/><figcaption>The VS Code button, top right, opens the session&#8217;s worktree over SSH.<\/figcaption><\/figure>\n<h4 id=\"dev-servers\">Dev servers<\/h4>\n<p>Next, you\u2019ll want an easy way for your client machines to check out any web servers that the agents are building. At first I did this with port forwarding, but eventually I settled on a less fiddly, more Tailscale-native approach.<\/p>\n<p>In a typical project, you\u2019ll have a command like <code>npm run dev<\/code> or <code>python -m http.server<\/code> that starts up a server bound to some <code>127.0.0.1<\/code> port. If the agent runs these commands directly, then the resulting server cannot be accessed outside the VM. You can instead try to bind to <code>0.0.0.0<\/code>, which will make the server available to other machines on the network. But it doesn\u2019t feel right to mess with a project\u2019s <code>npm run dev<\/code> script definition just to satisfy our idiosyncratic development topology. And if you access the server via IP address directly, e.g., <code>http:\/\/192.168.0.103:8000\/<\/code>, that is not a secure context, so various web APIs will be unavailable. Also, if multiple agents are working on the same project, they\u2019ll probably all try to use the same port, and get confused and start killing each other\u2019s servers.<\/p>\n<p><a href=\"https:\/\/portless.sh\/\">Portless<\/a> is a small CLI intended to solve this. Or rather, it solves an adjacent single-machine problem, but with some hackery we can make it work for our case. If you want the whole backstory, you can read <a href=\"https:\/\/chatgpt.com\/share\/6a607918-0748-83e8-8eed-fd3088a42f66\">my conversation with ChatGPT<\/a>, but the end result is that after installing the <code>portless<\/code> CLI, I created <code>~\/.local\/bin\/tportless<\/code> with the contents<\/p>\n<pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token shebang important\">#!\/usr\/bin\/env bash<\/span>\n\n\n<span class=\"token builtin class-name\">export<\/span> <span class=\"token assign-left variable\">PORTLESS_TAILSCALE<\/span><span class=\"token operator\">=<\/span><span class=\"token number\">1<\/span>\n\n\n<span class=\"token builtin class-name\">export<\/span> <span class=\"token assign-left variable\">PORTLESS_PORT<\/span><span class=\"token operator\">=<\/span><span class=\"token string\">\"<span class=\"token variable\">${PORTLESS_PORT<span class=\"token operator\">:-<\/span>1355}<\/span>\"<\/span>\n\n<span class=\"token builtin class-name\">exec<\/span> portless <span class=\"token string\">\"<span class=\"token variable\">$@<\/span>\"<\/span><\/code><\/pre>\n<p>and updated my <code>AGENTS.md<\/code> (<a href=\"#syncing-with-chezmoi\">see below<\/a>) with the section<\/p>\n<pre class=\"language-markdown\"><code class=\"language-markdown\"><span class=\"token title important\"><span class=\"token punctuation\">##<\/span> Preview servers<\/span>\n\nWhen standing up preview servers for the user to work from, don't run <span class=\"token code-snippet code keyword\">`npm run dev`<\/span> or similar directly. Instead, use the <span class=\"token code-snippet code keyword\">`tportless`<\/span> wrapper: bare <span class=\"token code-snippet code keyword\">`tportless`<\/span> runs the project's dev script through the proxy, and <span class=\"token code-snippet code keyword\">`tportless &lt;app-name&gt; &lt;command\u2026&gt;`<\/span> works for any other server command. This exposes the preview server on the tailnet. Report the Tailscale URL from the tportless output back to the user, instead of the localhost URL.<\/code><\/pre>\n<p>The result is delightful: the agent finishes some work, spins up a server, usually does some smoke tests using Playwright, and then hands me a URL like <code>https:\/\/agents-base.tail234567.ts.net:8443\/<\/code> where I can check out its work. Other agents in parallel worktrees will spin up servers on their own dedicated ports, with no collisions. These URLs are not accessible outside of the tailnet, so there\u2019s no danger of them getting exploited, or of my nascent projects being leaked before they\u2019re ready.<\/p>\n<h4 id=\"syncing-with-chezmoi\">Syncing with chezmoi<\/h4>\n<p>Over time you\u2019ll likely accumulate preferences about how your agents work, or customizations to your agent harness config files, or neato <a href=\"https:\/\/agentskills.io\/home\">agent skills<\/a> applicable across multiple projects. Storing these directly in the VM will work, but the VM is supposed to be disposable. And in the rare instance where local development on your client machines is required, e.g., <a href=\"https:\/\/domenic.me\/windows-native-dev\/\">working on a native Windows app<\/a>, at least some of your configuration will benefit from being synced to the client machines.<\/p>\n<p>This problem of syncing and backing up configurations is a very old one, usually discussed under the name \u201cdotfiles\u201d. (Since, in the Linux world, most of these configuration files use a leading <code>.<\/code> in their filename.) Apparently the best solution is a piece of software called <a href=\"https:\/\/www.chezmoi.io\/\">chezmoi<\/a>. It\u2019s pretty neat: it supports templates to handle small differences between machines and OSes, syncing via Git, symlinks, and more.<\/p>\n<p>But personally, this is the sort of thing I never would have bothered with \u2026 before coding agents. Learning a new CLI and configuring it <em>just so<\/em>: too much work, when I could get most of the same result with some manual copying and pasting. These days, I just ask ChatGPT:<\/p>\n<blockquote>\n<p>Set up chezmoi for me on this machine (<code>agents-base<\/code>), on the <code>SurfacePro11<\/code> host, and on the <code>Domenic-Desktop<\/code> host. Go through all existing dotfiles on each of those hosts, and produce a plausible synthesis, with appropriate platform-specific guards. Be sure to survey <code>~\/AGENTS.md<\/code> and <code>~\/skills\/<\/code>, and create symlinks from whatever locations Claude and Codex expect to those files. Note that on this machine, Claude and Codex have full permissions, but on other machines, they are restricted, and so we need to conditionally keep the command allowlists, etc. Our destination is a private GitHub repo <code>domenic\/dotfiles<\/code>, which you can create for me.<\/p>\n<\/blockquote>\n<p>I love living in the future!<\/p>\n<h3 id=\"bonus%3A-phone-based-development\">Bonus: phone-based development<\/h3>\n<p>It wasn\u2019t even in my <a href=\"#my-requirements\">original requirements<\/a>, but phone-based development falls out of this setup almost for free.<\/p>\n<p>Once you install the ChatGPT or Claude mobile apps, they can be configured to control any other agentic harness instances tied to your account. (This is, as usual, a little more fiddly with Claude, requiring you to manually enable the \u201cRemote Control\u201d feature.) If you install the mobile Tailscale client, you can exercise this control from any network, not just your home Wi-Fi.<\/p>\n<p>So this sort of workflow has become a reality for me:<\/p>\n<ol>\n<li>\n<p>Notice a bug in a live, web-facing deployment of one of my projects while on the go. For example, while showing it off to someone at a party.<\/p>\n<\/li>\n<li>\n<p>On the train back, open up the ChatGPT mobile app, which connects to my VM over the Tailscale VPN. Start a new remote session in the project\u2019s directory, asking it to fix the bug I noticed.<\/p>\n<\/li>\n<li>\n<p>It churns for some time while I scroll X, then sends me a push notification containing a tailnet-accessible URL for a preview server, which I can use to confirm that the bug is fixed. If it\u2019s not, we iterate together for a few turns.<\/p>\n<\/li>\n<li>\n<p>Once I\u2019m satisfied, I tell it to open a PR. I skim the diff and merge it from my phone.<\/p>\n<\/li>\n<li>\n<p>After a few minutes of GitHub Actions or the Netlify deploy pipeline, the fix has made it to the live site, usually before I make it to my home train station.<\/p>\n<\/li>\n<\/ol>\n<figure>\n  <img loading=\"lazy\" srcset=\"https:\/\/domenic.me\/images\/agentic-coding-from-phone.webp 3x\" width=\"360\" height=\"788\" alt=\"A screenshot of the ChatGPT mobile app, in a session on the agents-base machine. The agent reports validating a mobile layout fix, and after being told to package it all up into a PR, opens a pull request on GitHub.\"\/><figcaption>Fixing a mobile bug, from mobile.<\/figcaption><\/figure>\n<p>The future! We are living in it!<\/p>\n<h3 id=\"recap-and-remaining-gaps\">Recap and remaining gaps<\/h3>\n<p>So to recap our ingredients, and how they help us meet the original <a href=\"#my-requirements\">requirements<\/a>:<\/p>\n<ul>\n<li>\n<p>A disposable Linux VM gives the agents a non-Windows environment, and allows us to configure them for zero approvals, while being comfortable with the blast radius of that permissive policy.<\/p>\n<\/li>\n<li>\n<p>Using Tailscale gives all of our machines access to that VM, no matter what network they\u2019re on, and lets the agents expose secure-context dev servers.<\/p>\n<\/li>\n<li>\n<p>Git worktrees and Portless ensure our agents can work in parallel on the same project without stepping on each other\u2019s toes.<\/p>\n<\/li>\n<li>\n<p>Visual Studio Code\u2019s Remote &#8211; SSH extension lets us review the code in any given worktree the agents have created.<\/p>\n<\/li>\n<li>\n<p>GitHub repos serve as a save point for all our projects, in case the VM needs to be reset, and chezmoi lets us sync and back up our <code>AGENTS.md<\/code>, skills, and other configurations there too.<\/p>\n<\/li>\n<li>\n<p>The ChatGPT desktop app gives us easy session handoff and syncing. The Claude desktop app isn\u2019t as good in various ways, so we generally have to resort to Claude Code plus tmux to get that capability.<\/p>\n<\/li>\n<\/ul>\n<p>What could be better?<\/p>\n<p>Well, as mentioned <a href=\"#security-posture-and-blast-radius\">above<\/a>, this would all be slightly safer with dev containers. Those have other benefits, such as letting you install conflicting global toolsets in each container. Right now I have my <code>AGENTS.md<\/code> promote the use of <a href=\"https:\/\/github.com\/Schniz\/fnm\/\"><code>fnm<\/code><\/a> and <a href=\"https:\/\/docs.astral.sh\/uv\/\"><code>uv<\/code><\/a>, so I haven\u2019t run into many such conflicts, but I could imagine them coming up in the future.<\/p>\n<p>On the user experience side, I generally don\u2019t like how the \u201csession\u201d model in each coding harness is so strongly tied to the folder path on the VM. If you rename or move a project folder, the ChatGPT and Claude apps get confused, and generally lose all your session history in that folder. You can fix this by asking the agent to find the hidden references and update them, but it\u2019s a pain, and needs to be done on both client and host machines.<\/p>\n<p>Similarly, I\u2019d like some way to back up my session histories somewhere durable (like a private GitHub repository). At the very least, I suspect they\u2019ll be good for some nostalgia in a few years. But sometimes the session transcripts are the only record of certain design decisions, or of abandoned approaches that explain why the code looks the way it does.<\/p>\n<p>All of the above are fixable with a little bit of work on my end, e.g., by writing small utilities and wrappers. But I suspect they won\u2019t be truly seamless until they\u2019re built into the harness apps. So, I hope the ChatGPT app team works on them. And that the Claude app team first gets their shit together generally, and then works on these features.<\/p>\n<p>That\u2019s my setup. A disposable VM, a magic VPN, two frontier harnesses, and a few extra tools. If you\u2019re reading this more than six months from now, I assume it\u2019s all quaintly obsolete. But that\u2019s what time capsules are for.<\/p>\n<p>What a time to be alive!<\/p>\n<\/p><\/div>\n<p><a href=\"https:\/\/domenic.me\/agentic-coding-setup\/?utm_source=tldrdev\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since breaking free of my corporate shackles, I\u2019ve gotten to experiment with a variety of approaches to AI-assisted development. After months of tinkering, I\u2019m quite happy with my current setup, and want to capture and share it. Things are changing very fast, and I have no illusions that this will be a timeless nugget of [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":23005,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[143],"tags":[],"class_list":["post-23004","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai"],"_links":{"self":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/23004","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/comments?post=23004"}],"version-history":[{"count":0,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/23004\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media\/23005"}],"wp:attachment":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media?parent=23004"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/categories?post=23004"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/tags?post=23004"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}