AI coding agents become much more useful when they can continue working without requiring you to sit in front of the computer.

A refactor might take twenty minutes. A test suite might run much longer. One agent may be implementing a feature while another reviews changes, a third investigates an unrelated bug, and another waits for a decision before proceeding.

Most of this work does not require continuous human attention.

What it does require is coordination, persistence and a clear place to supervise everything.

That changes the role of the development machine.

Instead of being the place where I constantly watch an AI agent work, my MacBook becomes the execution environment. Herdr becomes the persistent control layer around the project, while my phone provides an optional remote interface whenever I am away from the desk.

The basic setup is deliberately small:

iPhone
├── Tailscale
└── Termius
      │
      │ SSH
      ▼
MacBook Air
├── Tailscale
├── macOS Remote Login
└── Herdr
    ├── Coordinator
    ├── Claude Code
    ├── Codex
    ├── Reviewer
    ├── tests
    └── development processes

There is no public SSH endpoint, no VPS, no Docker container and no additional server.

The MacBook runs the development workload. Herdr organizes the active project and its agents. Tailscale provides private connectivity between my devices. Termius gives the iPhone a terminal into the same environment.

The mobile part is useful, but it is only one piece of the idea.

The more interesting part is building a persistent multi-agent development workspace in which several specialized agents can work in parallel with limited supervision.

Why these tools?

Each component solves a different problem.

Tailscale — the private network

Tailscale creates a private network, called a tailnet, between authenticated devices.

Once my iPhone and MacBook are signed into the same tailnet, the Mac receives a stable Tailscale IP address.

This means I do not need to:

  • expose SSH to the public internet,
  • configure router port forwarding,
  • know my home public IP,
  • operate a traditional VPN server.

For this setup, I use normal macOS SSH over the Tailscale network.

Termius — the terminal in my pocket

Termius is the SSH client on the iPhone.

It connects to the MacBook using:

Tailscale IP
+
macOS username
+
SSH authentication

Once connected, I have a normal shell on the Mac.

Termius is not running Claude, Codex or Herdr on the phone. It is only providing an interface to processes actually executing on the MacBook.

The phone therefore acts as a control surface, rather than another development machine.

Herdr — the actual control layer

Herdr is the component that makes this architecture more useful than a collection of ordinary SSH terminals.

It provides a persistent terminal environment where shells, coding agents, test runners, servers and other processes can be grouped into project workspaces.

A simple project might look like this:

Project
│
├── Claude Code
├── Codex
├── test runner
├── development server
└── logs

But the same structure can evolve into something more interesting:

Project
│
├── Coordinator
│
├── Feature Agent
├── Backend Agent
├── Reviewer
├── Integration Agent
│
├── tests
├── application server
└── logs

Instead of treating every coding agent as an isolated chat or terminal process, the project itself becomes the unit of organization.

Herdr also keeps its terminal processes behind a background server.

Closing or detaching the visible interface therefore does not automatically terminate everything running inside the workspace.

That persistence is valuable locally.

It also makes remote supervision practical.

Why Herdr is useful even without the phone

The mobile workflow is convenient, but it is not the primary benefit.

The bigger advantage is that Herdr gives structure to parallel agentic development.

Without a control layer, the environment can quickly become fragmented:

Terminal 1 → Claude
Terminal 2 → Codex
Terminal 3 → tests
Terminal 4 → application server
Terminal 5 → logs
Terminal 6 → second Claude session
Terminal 7 → another repository

Each process may be useful individually, but understanding the state of the overall project becomes increasingly difficult.

Herdr allows those processes to be organized around the work they belong to.

For example:

Workspace: Product

├── Coordinator
│
├── Implementation
│   └── Claude Code
│
├── Review
│   └── Codex
│
├── Verification
│   └── tests
│
├── Runtime
│   └── development server
│
└── Observability
    └── logs

This changes the workflow from operating individual agents to supervising a small development system.

Parallel agents: isolate the work first

Running several agents in parallel can increase throughput considerably, but only when they are not blindly modifying the same working directory.

A good rule is:

For independent tasks that modify code, a strong default is one agent → one Git worktree → one branch.

For example:

Repository
│
├── main
│
├── worktree/api-auth
│   └── Agent A
│
├── worktree/frontend
│   └── Agent B
│
├── worktree/cache-fix
│   └── Agent C
│
└── worktree/review
    └── Reviewer

Git worktrees allow multiple working directories to exist from the same repository while keeping their checked-out branches separate.

Herdr can then provide the shared control surface across those environments.

Conceptually:

                         HERDR
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
        ▼                  ▼                  ▼
   Worktree A         Worktree B         Worktree C
        │                  │                  │
     Agent A            Agent B            Agent C
        │                  │                  │
   API feature          frontend          bug fix

Each worker owns a clearly scoped task.

This is safer and easier to reason about than letting several autonomous coding agents edit the same files simultaneously.

Add a coordinator agent

Once several workers operate in parallel, another problem appears:

Who decides what each agent should work on?

This is where a coordinator or supervisor agent becomes useful.

Instead of implementing features itself, the coordinator maintains the shared plan.

Its responsibilities can include:

Coordinator

├── understand the objective
├── decompose it into tasks
├── determine dependencies
├── assign tasks to workers
├── select appropriate worktrees
├── monitor progress
├── detect blocked workers
├── avoid duplicated work
├── request review
└── decide when integration should begin

The coordinator should generally avoid becoming another worker unless necessary. Its value comes from maintaining the global view of the project.

Herdr can support this pattern through its agent-automation primitives: scripts—or another agent—can start named agents, prompt them, inspect their terminal output and lifecycle state, wait for them to settle, and collect their results. The coordinator role is therefore a workflow you explicitly build on top of Herdr; it is not created automatically merely by putting several agents in the same workspace.

Workers report upward

A useful architecture is to route worker status and results back through the coordinator rather than having workers continuously coordinate among themselves. In practice, this reporting must be implemented explicitly—for example with Herdr agent automation, a shared task file, or an external task/orchestration layer.

For example:

                   Human
                     │
                     ▼
               Coordinator
                     │
       ┌─────────────┼─────────────┐
       │             │             │
       ▼             ▼             ▼
   Backend Agent  UI Agent    Data Agent
       │             │             │
       └─────── status/results ────┘
                     │
                     ▼
               Coordinator

The coordinator maintains:

  • the current objective,
  • outstanding tasks,
  • dependencies,
  • completed work,
  • blocked work,
  • integration status.

This helps prevent a common failure mode in multi-agent systems: several agents independently solving the same problem or making incompatible assumptions.

The workers can stay focused on their assigned context.

The coordinator maintains the project-level context.

Add an independent reviewer

Implementation and evaluation should preferably not be the same role.

After a worker completes a task, a dedicated reviewer can inspect its branch or diff.

For example:

Worker Agent
    │
    │ implementation complete
    ▼
Reviewer Agent
    │
    ├── inspect diff
    ├── check correctness
    ├── inspect edge cases
    ├── evaluate tests
    ├── identify regressions
    └── report findings

The reviewer might receive an instruction such as:

Review the implementation.

Do not modify it yet.

Check:
- correctness
- concurrency
- error handling
- edge cases
- missing tests
- security implications
- unnecessary complexity

Separating generation from evaluation gives the second agent a different objective and helps avoid simply continuing the assumptions of the original implementation.

Use an integration agent for the final step

When several parallel branches are ready, a separate integration role can become useful.

Its job is not primarily to build new features.

Instead it can:

Integration Agent

├── inspect completed branches
├── compare diffs
├── identify overlapping changes
├── merge approved work
├── resolve straightforward conflicts
├── run the combined test suite
├── verify integration behaviour
└── escalate ambiguous conflicts

This produces a cleaner pipeline:

Coordinator
     │
     ├──── Worker A ────┐
     │                  │
     ├──── Worker B ────┤
     │                  │
     └──── Worker C ────┘
                        │
                        ▼
                     Review
                        │
                        ▼
                   Integration
                        │
                        ▼
                       main

The human remains responsible for final judgment where appropriate, but much of the repetitive comparison, testing and integration work can be delegated.

The resulting agentic development workflow

Putting these components together creates a much more structured workflow.

                         HUMAN
                           │
                    define objective
                           │
                           ▼
                    COORDINATOR
                           │
                  decompose + assign
                           │
       ┌───────────────────┼───────────────────┐
       │                   │                   │
       ▼                   ▼                   ▼
    AGENT A             AGENT B             AGENT C
   Worktree A          Worktree B          Worktree C
       │                   │                   │
 implementation        implementation       analysis
       │                   │                   │
       └────────── status / results ───────────┘
                           │
                           ▼
                       REVIEWER
                           │
                           ▼
                      INTEGRATOR
                           │
                    tests + merge
                           │
                           ▼
                          main

Herdr sits around this entire process:

Herdr Workspace
│
├── Coordinator
│
├── Worker A
│   └── worktree A
│
├── Worker B
│   └── worktree B
│
├── Worker C
│   └── worktree C
│
├── Reviewer
│
├── Integrator
│
├── Tests
├── Dev Server
└── Logs

This is where Herdr starts to look less like a terminal utility and more like a lightweight operational layer for an agentic software team.

Scale further with a task board

With two or three workers, the coordinator can often maintain the task plan itself.

As the number of parallel tasks grows, a structured task or Kanban layer becomes useful.

Instead of workers choosing arbitrary work, tasks can move through states such as:

BACKLOG
   ↓
READY
   ↓
CLAIMED
   ↓
WORKING
   ↓
REVIEW
   ↓
INTEGRATION
   ↓
DONE

Workers claim scoped tasks.

The coordinator monitors the overall queue.

The reviewer handles completed work.

The integration agent handles approved changes.

This reduces the risk of agents inventing duplicate work or stepping on tasks that another worker already owns.

The resulting model starts to resemble a small asynchronous engineering organization rather than a collection of chat sessions.

Parallel work instead of sequential prompting

This is fundamentally different from a traditional AI-assisted workflow:

ask agent
↓
wait
↓
review result
↓
ask next question
↓
wait again

With persistent agents and isolated branches:

                Coordinator
                     │
       ┌─────────────┼─────────────┐
       │             │             │
    Feature A     Feature B      Research
       │             │             │
     Agent         Agent          Agent
       │             │             │
       └─────────────┼─────────────┘
                     │
                   Review
                     │
                  Integration

Independent work proceeds simultaneously.

Human attention can move toward decisions and exceptions rather than constantly feeding the next prompt.

Less context switching

There is also a straightforward human benefit.

When everything belonging to a project lives inside one workspace, I no longer have to constantly remember:

Which terminal had Claude?

Which branch is Codex changing?

Where are the tests running?

Which agent owns the API task?

Did somebody already start the frontend work?

Which branch is waiting for review?

Where is the application server?

The project becomes the unit of organization.

That becomes increasingly important as the number of simultaneous agents grows.

Long-running work becomes normal

Some coding-agent tasks are naturally slow:

  • repository-wide refactoring,
  • dependency migrations,
  • large test suites,
  • repeated debugging cycles,
  • codebase analysis,
  • documentation generation,
  • static analysis,
  • build pipelines,
  • local experiments.

Persistent sessions make it easier to treat these as background work.

A worker can receive something like:

Implement the assigned change.

Stay inside your worktree.

Run the relevant tests.

Fix failures clearly caused by your implementation.

Report completion to the coordinator.

Stop if the public API or shared architecture needs to change.

The human does not need to watch every command.

The objective is not unrestricted autonomy.

The objective is to move from continuous supervision toward exception-based supervision.

Human intervention at decision points

A useful development loop becomes:

objective
   ↓
coordinator creates plan
   ↓
workers execute in parallel
   ↓
tests / review / analysis
   ↓
normal work continues autonomously
   ↓
uncertainty or important decision
   ↓
human intervention
   ↓
work continues

The human remains responsible for important engineering decisions.

But there is little value in watching every routine step execute when the surrounding workflow can handle it safely.

Setting up remote access

Once the local Herdr workflow is useful on its own, adding mobile access is straightforward.

1. Install Tailscale on the MacBook

Install the official Tailscale macOS application.

Open it and sign in.

Then enable its CLI integration:

Tailscale
→ Settings
→ CLI Integration
→ Install

Open Terminal and run:

tailscale ip -4

You should receive something similar to:

<tailscale-ip>

This is the private address the iPhone will use.

2. Enable SSH on macOS

Open:

System Settings
→ General
→ Sharing
→ Remote Login

Enable Remote Login.

Allow your own macOS user.

Then check your username:

whoami

For example:

<macOS-username>

You now need:

Mac username:   <macOS-username>
Tailscale IP:   <tailscale-ip>

3. Install Herdr

On the Mac:

brew install herdr

Verify:

herdr --version

Open your project:

cd ~/Projects/my-project

Then:

herdr

4. Install Tailscale on the iPhone

Install Tailscale from the App Store.

Sign in with the same account as on the Mac.

Allow iOS to create the required VPN configuration.

Once connected, both devices belong to the same private tailnet.

5. Configure Termius

Install Termius on the iPhone.

Create a new SSH host using your own connection details in place of the placeholders below:

Name
<connection-label>

Address
<tailscale-ip>

Port
<ssh-port>

Username
<macOS-username>

Example:

Address: <tailscale-ip>
Port: <ssh-port>
Username: <macOS-username>

For an initial personal setup, normal macOS SSH password authentication can be used if it is enabled on the Mac. An Ed25519 SSH key is preferable for long-term use, and access still depends on your Tailscale policy allowing the iPhone to reach the MacBook on its configured SSH port.

Connect.

You should receive a shell similar to:

<macOS-username>@<mac-hostname> ~ %

Taking the control layer mobile

Once Termius reaches the Mac, run:

herdr

The same Herdr environment appears in the phone terminal.

The path is:

iPhone
   │
   │ Tailscale
   ▼
Termius
   │
   │ SSH
   ▼
MacBook Air
   │
   ▼
Herdr
   │
   ├── Coordinator
   ├── Worker A
   ├── Worker B
   ├── Reviewer
   ├── Integrator
   ├── tests
   └── development server

The iPhone is not another copy of the development environment.

It is simply another interface into the same persistent system running on the Mac.

Herdr workspace with grouped agent sessions in the sidebar and a Codex agent reviewing a commit in the terminal.

Persistent sessions are the important part

Herdr's default prefix key is:

Ctrl+B

To detach:

Ctrl+B
q

The client disappears, but the background Herdr server continues running.

That means:

Detach from Herdr
        ↓
agents continue

Close SSH
        ↓
agents continue

Close Termius
        ↓
agents continue

Disconnect the iPhone
        ↓
agents continue

Later:

1. Connect Tailscale
2. Open Termius
3. SSH into the MacBook
4. Run herdr

The existing workspace becomes visible again.

Persistence is not the same as surviving a reboot

There is an important distinction.

Herdr persistence means that the visible client can disappear while its background server and child processes remain alive.

It does not mean that running Unix processes survive:

  • shutting down the Mac,
  • rebooting macOS,
  • stopping the Herdr server,
  • losing power.

The workspace structure and supported agent sessions may be recoverable depending on the relevant integrations, but terminated operating-system processes are still terminated.

Keep the Mac awake

The MacBook is doing the actual work, so it must remain awake.

For temporary long-running sessions:

caffeinate -i

Keep the machine:

connected to power
connected to the network
awake

For a genuinely continuous setup, an always-on Mac mini or Linux workstation is a more natural execution host than a laptop.

The rest of the architecture remains almost identical.

Why mobile supervision becomes useful

The phone is not meant to replace the IDE.

Its purpose is to resolve small interruptions without returning to the workstation.

For example, a coordinator might report:

Worker B is blocked.

The requested implementation requires changing
the public API contract.

Proceed?

Or a reviewer may report:

Implementation passed tests.

I found one possible race condition in the cache layer.

Should I send it back to the worker?

A short decision from the phone may allow another hour of work to continue.

This is much more useful than trying to perform substantial software development on a small screen.

The daily workflow

At the desk:

cd ~/Projects/my-project
herdr

The workspace might contain:

Coordinator
    ↓
┌──────────┬──────────┬──────────┐
│ Worker A │ Worker B │ Worker C │
└──────────┴──────────┴──────────┘
           ↓
        Reviewer
           ↓
       Integrator
           ↓
         Tests

Then detach:

Ctrl+B
q

Later from the iPhone:

Tailscale
    ↓
Termius
    ↓
MacBook
    ↓
Herdr

Check the coordinator.

Inspect blocked workers.

Read review results.

Approve or redirect the next action.

Detach again.

Final architecture

                            HUMAN
                              │
                     objectives / decisions
                              │
                              ▼
                        COORDINATOR
                              │
                task planning / assignment
                              │
          ┌───────────────────┼───────────────────┐
          │                   │                   │
          ▼                   ▼                   ▼
       WORKER A            WORKER B            WORKER C
      Worktree A          Worktree B          Worktree C
          │                   │                   │
          └─────────── results / status ──────────┘
                              │
                              ▼
                           REVIEWER
                              │
                              ▼
                          INTEGRATOR
                              │
                       tests / merge
                              │
                              ▼
                             MAIN

              ───── everything supervised in ─────

                            HERDR
                              ▲
                              │
                         MacBook Air
                              ▲
                              │ SSH
                          Tailscale
                              │
                           Termius
                              │
                            iPhone

The responsibilities remain clean.

The coordinator maintains the global plan.

Workers execute scoped tasks in isolated worktrees.

The reviewer independently evaluates completed work.

The integration agent combines approved changes and verifies the result.

Herdr exposes the entire development environment as one persistent control surface.

The MacBook supplies the repository, tools and compute.

Tailscale and Termius extend that control surface to the phone.

Closing thought

AI coding agents are becoming most useful when they can work in parallel, stay organized, and continue without constant supervision. The real challenge is no longer just getting an agent to write code, but creating a workflow where multiple agents can collaborate safely and predictably. Persistent sessions, clear roles, isolated workspaces, review, and lightweight human oversight make that possible. Remote access is simply an extra layer that lets the same system stay useful wherever you are. The result is a more practical way to develop software with AI: less babysitting, more coordination, and better use of human attention.

References

Documentation checked September 2026.

Herdr

Tailscale

Apple

Termius

Git