Sitemap
Alexander Nykolaiszyn

Alexander Nykolaiszyn

Running Multiple Claude Agents From Windows Without Losing Your Mind

6 min readOct 26, 2026

--

It wasn’t a skill gap, and a git worktree isn’t enough isolation

For a year I ran Claude Code from PowerShell and blamed myself when it felt hit-and-miss. Commands that flowed on my homelab Linux boxes stuttered on my desktop. Agents stepped on each other’s files. Multiplexing meant a pile of terminal tabs I could not tell apart.

The diagnosis took ten minutes once I stopped assuming the problem was me. The agent tooling, the docs, the examples, the plugins, and most of the people writing about this workflow are on macOS or Linux. Windows is not unsupported; it is the second-class path, and the friction shows up in a hundred small ways rather than one big error.

So I moved the whole workflow into WSL2 and treated Windows as the thing that boots the GPU drivers and runs Outlook. This is the setup, the daily pattern that came out of it, the mistakes I made on the way, and one warning for analytics engineers who think a git worktree is enough isolation.

The stack

Five pieces, in the order they went in. Each one earns its place by removing one specific kind of friction.

1. WSL2 with Ubuntu, repos in ~/code. Not on a Windows share, not on /mnt/c. Cross-filesystem I/O is where WSL gets slow, and agents do a lot of small file reads. Moving the repos off the share was the single biggest speed-up. Docker Desktop integrates with the WSL distro, so docker works inside Ubuntu without a second install.

2. SSH config and keys. One ~/.ssh/config with a named entry per machine (proxmox, docker-nas), so an agent can run ssh docker-nas 'docker ps' without me pasting IPs into prompts. Each client machine gets its own key; the laptop does not get a copy of the desktop’s.

3. tmux. One session per project, one window per agent. tmux attach -t awesomeproject and I am back where I left off, agents still running, even after closing the terminal.

4. Git worktrees. git worktree add ../smf-issue-42 -b issue-42 gives each agent its own checkout of the same repo, and I can diff their branches side by side.

5. GitHub CLI (gh). Issues are the handoff. gh issue view 42, gh pr create, gh pr checks all work from inside the agent's shell, so the agent reads its own task and files its own PR without a browser.

That is the whole thing. Nothing custom sits in the loop: no plugins, no wrappers, nothing that will break on the next release. The only code I wrote is two idempotent setup scripts (setup-windows.ps1, setup-ubuntu.sh) so the laptop could get the same environment in one run, with the homelab reached over Tailscale instead of the LAN.

The daily pattern

The tools matter less than the three rules they enforce.

Session per project. Every repo I am actively working on has a tmux session named after it. Switching projects is tmux switch -t projectA, not finding the right window in a stack of twenty.

Worktree per task. An agent never works on main and never shares a working tree with another agent. The branch name is the issue number. When the PR merges, git worktree remove and the directory is gone. This is what makes running three agents in parallel boring instead of terrifying.

GitHub issue as the handoff. I write the task once, as an issue with acceptance criteria. The agent reads it with gh issue view, works in its worktree, opens the PR with Closes #42 in the body, and I review the diff. No prompt copy-paste, no context lost between my head and the agent's. The issue is the contract; the PR is the receipt.

Get Alexander Nykolaiszyn’s stories in your inbox

Join Medium for free to get updates from this writer.

A typical evening: open the project session, gh issue list --label ready, start one agent per issue in its own window and worktree, let them run, review PRs as checks go green. Two hours of wall-clock time covers three or four small issues that used to take a weekend of sequential work.

Gotchas I hit so you don’t have to

  • PowerShell execution policy blocks your profile. The first $PROFILE script you add will silently fail to load. Set-ExecutionPolicy -Scope CurrentUser RemoteSigned once, then it works.
  • claude isn't on PATH inside WSL. The installer puts it in ~/.local/bin, which Ubuntu does not add to PATH until the directory exists at login. Add it to .bashrc or log out and back in.
  • Docker Desktop’s WSL integration is off by default for any distro that isn’t your default one. Enable it in Docker Desktop settings, then sudo usermod -aG docker $USER and start a new shell. Until both happen, docker ps fails with a permissions error that looks like Docker is not installed.
  • Key-only SSH hosts and the chicken-and-egg problem. My Docker VM refuses password logins, so ssh-copy-id cannot bootstrap a new key. The way around it on Proxmox is qm guest exec through the guest agent to append the public key from the host side.
  • Claude Code’s full-screen mode fights tmux. The alternate-screen rendering scrolls badly inside a tmux pane. /tui default in the session, or CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 in the environment, and it behaves like a normal terminal program again.
  • Typos cost more in a prompt. mdkir, hellow-world. The agent will happily create the misspelled thing. Slow down on the commands you type to the agent; the agent is fast enough for both of you.

The analytics-engineering twist

If you write software, the pattern above is complete. If you write dbt, it is not, and I have not seen anyone say so plainly.

A git worktree isolates code. It does not isolate the warehouse. Two agents on two branches of the same dbt project both run dbt run against the same target schema, and the second one overwrites the first one's tables. Your worktrees are clean; your dev schema is a crime scene. The PR diffs look fine while the models are built from each other’s half-finished intermediate tables.

The fix is a dev schema per task, not per developer. In profiles.yml, derive the schema from the branch or the worktree name so each agent builds into dev_issue_42, dev_issue_43, and so on (connection fields omitted for brevity):

dev:
target: dev
outputs:
dev:
type: snowflake
schema: "dev_{{ env_var('DBT_TASK_SCHEMA') }}"

Set DBT_TASK_SCHEMA in each tmux window when you start the agent. Derive it rather than typing it: export DBT_TASK_SCHEMA=$(basename $PWD | sed s/-/_/g) run inside the worktree turns smf-issue-42 into dev_smf_issue_42 with no hand-typed schema names. Drop the schema when the worktree goes. If your warehouse supports zero-copy clones (Snowflake does), clone the source schema per task too, so an agent’s test data does not drift under the other agents.

The broader point: software engineers got cheap isolation from git twenty years ago. Analytics engineers have to build the equivalent for the warehouse themselves, and multi-agent work is the first thing that makes the gap hurt. Expect this to become standard practice; today it is not.

Where this leaves me

Windows is still my desktop. It runs the GPU, the games, the Office apps, and the family’s parental controls. But every line of agent work now happens in Ubuntu, in a named session, in a disposable worktree, against a disposable schema, with a GitHub issue as the only thing I have to write by hand.

If you are on Windows and the agent workflow feels harder than the videos make it look, it probably is. Spend one evening on WSL2, tmux, and worktrees before you spend another weekend fighting PowerShell. And if you are an analytics engineer, add the per-task schema before you add the second agent.

The commands I actually use, on one page.

Press enter or click to view image in full size

About the author

Alexander Nykolaiszyn is a senior analytics and BI leader with fifteen years in enterprise data, and the writer behind Pivot Tables & Plot Twist, where he covers analytics engineering, governed metrics for AI agents, and the dbt Semantic Layer. He runs the workflow in this article most evenings from a home-lab.

Connect on LinkedIn: https://www.linkedin.com/in/alexnyk/

If this saved you a weekend, buy me a coffee: https://buymeacoffee.com/alexnyk

--

--