Mert Özen Further With Every Line
Artificial Intelligence Claude Code — #09

Working in Parallel: Worktrees, Desktop, Cloud Sessions and Following Up from Mobile

Mert Özen Nov 15, 2026 9 min 4 views
Working in Parallel: Worktrees, Desktop, Cloud Sessions and Following Up from Mobile

For parallel work in Claude Code, start each session in its own git worktree with claude --worktree; files are separated, but user-secrets, the database and ports are not. Worktree cleanup, .worktreeinclude, shared approvals and hooks, a database per worktree for Bookstore, and Desktop, VS Code and JetBrains, cloud sessions, --teleport, Remote Control and the mobile app.

Version note: This post describes Claude Code 2.1.325 (13 November 2026); worktree behavior, the Desktop app, the IDE extensions, cloud sessions, Remote Control and the mobile app were checked on 15 November 2026 against the Run parallel sessions with worktrees, Desktop application, Use Claude Code in VS Code, JetBrains IDEs, Use Claude Code in the cloud, Remote Control, Claude Code on mobile, Claude Code in Slack and Run agents in parallel pages at code.claude.com/docs. This post is based on the official documentation. The sample PowerShell script was run with PowerShell 7.7, with a stub in place of the claude command.

Guess First

Emre wanted to run two pieces of work at once in Bookstore, the online bookstore used as the shared example across this site's series: an endpoint that exports the order list as CSV, and an update of the Angular dependencies. He opened two terminals and ran claude in the same folder in both. An hour later, the moment the Angular session changed package-lock.json, the other session's npm test broke. The next day he separated the two sessions with claude --worktree; the files no longer collided, but both sessions' migrations were applied to the same BookstoreDb.

What is your guess? Why did the database stay shared when the worktrees separated the files? And does a command you approved with "Yes, and don't ask again" in one worktree session run without asking in the other worktree too? The first answer is in the Bookstore section, the second in the section on what is shared.

Parallel Sessions with Worktrees

A git worktree is a separate working folder that shares the repository history but has its own files and branch; we covered the basics in the twenty-fourth post of the Git & GitHub series. Claude Code reduces this to a single flag:

claude --worktree orders-csv-export
claude --worktree angular-deps
claude --worktree "#1234"

Each command creates a worktree under .claude/worktrees/<name>/ at the repository root and a new branch named worktree-<name>, and starts Claude there; if you give no name, Claude generates one. The third line fetches a pull request's head commit from origin and opens it in .claude/worktrees/pr-1234; the quotes are required because # starts a comment in the shell. An interactive run requires workspace trust: if you haven't run claude in the folder before, run it once and accept the trust dialog first.

When you exit the session, Claude checks the worktree. If there are no changes, an unnamed session's worktree and branch are removed, and a named session asks first. If there are changes, untracked files or new commits, it asks whether to keep or remove it; if you keep it, Claude Code prints the claude --worktree <name> --resume command to come back. claude -p runs have no exit prompt, so their worktrees aren't cleaned up; you remove them yourself with git worktree remove. Following the documentation, we added .claude/worktrees/ to .gitignore; otherwise worktree contents show up as untracked files in the main checkout.

The default base is "fresh": a new worktree branches from the default branch on the remote, usually main. If you want to continue on top of commits you haven't pushed yet, set worktree.baseRef to "head" in your settings; you can't give a branch name, and for a specific branch you create the worktree with git yourself.

What Comes into a Worktree, and What Is Shared?

A worktree is a clean checkout: there are no bin, obj, node_modules or gitignored files. Every worktree needs dotnet restore, npm ci in web/bookstore-web, and npm install --prefix tools/mcp for the MCP packages from the eighth post. If you want a gitignored file copied into every new worktree, you list it in a .worktreeinclude file at the repository root using .gitignore syntax; only files that both match a pattern and are gitignored get copied. Bookstore has a single line:

CLAUDE.local.md

That way the personal notes from the second post come along into every worktree. Watch the habit of adding secrets to this file: if you write .env, every worktree gets one more copy, and each copy has to be protected on its own.

Worktrees share a few things with the main checkout. The repository's .git folder is shared. The answer to the second question is here too: according to the documentation, a Bash approval you give with "Yes, and don't ask again" in a worktree is written to the main checkout's .claude/settings.local.json and applies in every worktree of the repository. The documentation also notes, however, that on Windows and in the other cases where Claude Code doesn't use the repository root, that rule stays with that worktree. The main checkout's untracked .claude/skills, .claude/agents and .claude/commands folders are also read from there when the worktree has no copy of its own.

There is a difference in hooks: when Claude enters a worktree, ${CLAUDE_PROJECT_DIR} stays at the root where the session started, while cwd in the hook input points at the worktree. That is why we wrote the scripts in the seventh post to work from the folder of file_path and from cwd; they look at the right repository in a worktree too. For a session in a worktree, Claude Code also applies isolation checks: it refuses an Edit or Write to a path in the main checkout, commands whose working directory resolves to the main checkout, and Bash commands that redirect git into the main checkout. The documentation also says plainly that these checks don't track commands that write without running git, such as cp or a shell redirect.

Bookstore: Two Worktrees, Two Databases

The answer to the first question is in user-secrets. ConnectionStrings:BookstoreDb is not in the repository; it lives in the user profile, tied to the project's UserSecretsId. Because the worktrees check out the same project, both see the same secret, that is, the same database. In ASP.NET Core's default configuration order, environment variables are read after user-secrets; giving each worktree terminal its own variable is enough. tools/start-worktree.ps1:

# Starts Claude Code in its own worktree with its own database and API port.
# Run it from the repository root, one terminal per worktree:
#   ./tools/start-worktree.ps1 -Name orders-csv-export -ApiPort 5081
param(
    [Parameter(Mandatory = $true)] [string]$Name,
    [int]$ApiPort = 5081,
    [string]$Server = 'localhost'
)

$database = 'BookstoreDb_' + ($Name -replace '[^A-Za-z0-9]', '_')

# Environment variables override user-secrets, so this terminal gets its own database.
$env:ConnectionStrings__BookstoreDb = "Server=$Server;Database=$database;Integrated Security=true;TrustServerCertificate=true"
$env:ASPNETCORE_URLS = "http://localhost:$ApiPort"

Write-Output "worktree: $Name  database: $database  api: $env:ASPNETCORE_URLS"
claude --worktree $Name

The script starts claude with that terminal's environment; the dotnet ef database update, dotnet run and tests that Claude runs through its Bash or PowerShell tool see these variables. With a different name and port in two terminals:

./tools/start-worktree.ps1 -Name orders-csv-export -ApiPort 5081
./tools/start-worktree.ps1 -Name angular-deps -ApiPort 5082

The first line uses the BookstoreDb_orders_csv_export database and port 5081. If you don't use Windows authentication, replace the connection string with your own connection details; don't write a password into the script. On the Angular side give a second port, such as ng serve --port 4201, otherwise the two dev servers want the same port. Because the Playwright server from the eighth post allows http://localhost:4200, you also need to update the port there if you need UI tests in the second worktree.

The isolation: worktree subagents from the sixth post and /batch use the same mechanism; their worktrees are removed automatically when there are no changes, and otherwise by the periodic cleanup once cleanupPeriodDays has passed and no work is left in them.

Desktop and the IDE Extensions

The Code tab in the Claude Desktop app is a graphical interface over the same engine: CLAUDE.md, settings and MCP servers are shared. There are x64 and ARM64 installers for Windows. You can open several sessions in parallel in the sidebar and view two sessions side by side. In a Git repository, if you turn on the Worktree option before starting a session, the session runs in its own worktree; it is off by default. The worktree location and branch prefix change in the settings, and .worktreeinclude applies here too. Desktop worktree sessions have one difference: settings, hooks, skills and .mcp.json are read from the main checkout's root, while CLAUDE.md and .claude/rules/ come from the worktree. For a team that uses WSL, Desktop also has sessions that run inside a WSL 2 distribution.

The VS Code extension is the recommended way: inline diffs, editing a plan before you approve it, passing selected lines with @, and several conversations in separate tabs. The JetBrains plugin opens changes in the IDE's diff view in IDEs such as IntelliJ and WebStorm. The list of supported IDEs in the documentation doesn't name Rider; if someone on the team uses Rider, they should check the JetBrains IDEs page before installing the plugin. General AI assistants in IDEs are in the ninth post of the IDEs series.

Cloud Sessions, Remote Control and Mobile

A cloud session is a Claude Code session that runs on cloud infrastructure instead of your machine: it keeps going even if you close the laptop, and it is available on Pro, Max, Ultra and Team plans, and on Enterprise for certain seat types. You can start one from claude.ai/code, the mobile app, Desktop or the terminal:

claude --cloud "Add a CSV export endpoint for orders in src/Bookstore.Api and its tests"
claude --teleport

--cloud clones the GitHub version of your current branch, not your local checkout; push first if you have local commits. --teleport pulls a cloud session into your terminal: it checks that you are in the right repository, checks out the branch and loads the conversation. Every session runs in a cloud environment; the first environment is the Default environment with Limited network access. Because Bookstore's API tests need SQL Server, the cloud environment's setup script and network settings need separate thought on that front. Cloud sessions count against your plan's usage limits, and there is no separate charge for the VM.

Remote Control does the opposite: the session keeps running on your machine, and claude.ai/code or the mobile app is only a window into it. It starts with claude remote-control in the project folder or /remote-control inside a session; your local file system, MCP servers and settings are used as they are, so your computer has to stay on. It doesn't work with an API key, it needs a claude.ai sign-in, and on Team and Enterprise an administrator has to turn it on. There is no separate Claude Code mobile app; cloud sessions and Remote Control live in the Code tab of the Claude app. A coding task given to @Claude in Slack also starts a cloud session; the documentation says this version answers only Pro, Max and Ultra accounts, and only in workspaces not connected to Claude Tag.

To watch several background sessions from one screen in the terminal there is agent view, opened with claude agents; according to the documentation it is in research preview.

In Production

Parallel sessions and subagents multiply token usage; each one counts against the same plan limit. Limit the amount of parallel work to the number of diffs you can review: if you can't read three large changes that finish at the same time in three worktrees carefully, the parallelism is not a gain.

In cloud sessions the code runs in an isolated VM that Anthropic manages; git credentials are kept outside the sandbox, and a proxy acts for the session with scoped credentials. Network access is limited by default. The documentation notes that even with network access disabled, Claude Code can still reach the Anthropic API and that this may allow data to leave the VM; weigh your company policy with that in mind.

Remote Control means you can send commands to an open session from another device. Don't leave your phone unlocked, and close the session when you are done.

Common Pitfalls

Worktrees that share the same database and port. The files are separate; user-secrets and ports are not. Give each terminal its own variables.

Worktrees that never get cleaned up. -p runs and worktrees you kept stay on disk; check git worktree list now and then.

Two sessions in the same checkout. Two sessions opened without worktrees write to the same files; the documentation also says that opening the same session in two terminals can lead to missing messages in the transcript.

Assuming --cloud takes your local commits. The cloud VM clones the branch on GitHub; work you haven't pushed isn't there.

A Small Experiment

★☆☆ Open a session with claude --worktree deneme, exit without changing anything, and check with git worktree list and git branch whether the worktree and branch were removed.

★★☆ Open two worktrees with start-worktree.ps1, add and apply a migration in one, and confirm that the other's database doesn't have that table.

★★★ Write a PreToolUse hook that, in a worktree session where cwd differs from CLAUDE_PROJECT_DIR and the command is dotnet ef database update, refuses the call when the connection string in the environment doesn't contain the worktree name.

So far a person has always been driving Claude Code. In the tenth post we run Claude Code from scripts and CI with claude -p, set up pull request review in GitHub Actions, and draw the trust boundaries of that automation.