dev

July 27, 2026 · View on GitHub

Parallel development environment manager using git worktrees.

Overview

The dev command helps you work on multiple features simultaneously by creating isolated git worktrees. Each dev environment is a separate working directory with its own branch, allowing you to:

  • Switch between features without stashing changes
  • Run multiple AI coding agents in parallel
  • Keep your main branch clean while experimenting

Like git-worktree-runner (gtr) but with many more QoL features.

Quick Start

# Create a new dev environment (auto-generates a random branch name like "clever-fox")
agent-cli dev new

# Create a new dev environment with AI-generated branch name from the prompt
agent-cli dev new --branch-name-mode ai --prompt "Refactor auth flow"

# Create a dev environment with a specific branch name
agent-cli dev new my-feature

# Create a dev environment and open in editor + start AI agent
agent-cli dev new my-feature -e --start-agent

# Create a dev environment and launch the agent in a detached repo-scoped tmux session
agent-cli dev new my-feature --start-agent -m tmux

# Launch into a specific tmux session instead of the default repo-scoped one
agent-cli dev new my-feature --agent codex --tmux-session review-batch --prompt-file task.md

# List all dev environments
agent-cli dev list

# Remove a dev environment
agent-cli dev rm my-feature

Subcommands

dev new

Create a new parallel development environment.

agent-cli dev new [BRANCH] [OPTIONS]

Arguments:

ArgumentDescription
BRANCHBranch name (auto-generated if not provided)

Options:

Options

OptionDefaultDescription
--from, -f-Git ref (branch/tag/commit) to branch from. Defaults to origin/main or origin/master
--editor, -efalseOpen the worktree in an editor. Uses --with-editor, config default, or auto-detects
--start-agentfalseStart an AI coding agent in a new terminal tab without providing an initial prompt. Uses config default or auto-detects.
--agent-Which AI agent to start: claude, codex, gemini, aider, copilot, cn (Continue), opencode, cursor-agent, or auto. Implies starting the agent
--with-editor-Which editor to open: cursor, vscode, zed, nvim, vim, emacs, sublime, idea, pycharm, etc.
--setup/--no-setuptrueRun project setup after creation: npm/pnpm/yarn install, poetry/uv sync, cargo build, etc. Auto-detects project type
--copy-env/--no-copy-envtrueCopy env and local agent instruction files from main repo to worktree
--fetch/--no-fetchtrueRun 'git fetch' before creating the worktree to ensure refs are up-to-date
--branch-name-moderandomHow to auto-name branches when BRANCH is omitted: random (default), auto (AI only when --prompt/--prompt-file is set), or ai (always try AI first)
--branch-name-agent-Headless agent for AI branch naming: claude, codex, or gemini. If omitted, uses --agent when supported, otherwise tries available agents in that order
--branch-name-timeout20.0Timeout in seconds for AI branch naming command
--direnv/--no-direnv-Generate .envrc based on project type and run 'direnv allow'. Auto-enabled if direnv is installed
--agent-args-Extra CLI args for the agent. Can be repeated. Example: --agent-args='--dangerously-skip-permissions'
--prompt, -p-Initial task for the AI agent. Saved to a unique file in .claude/ to avoid conflicts. Implies starting the agent. Example: --prompt='Fix the login bug'
--prompt-file, -P-Read the agent prompt from a file. Useful for long prompts to avoid shell quoting. Implies starting the agent
--multiplexer, -m-Launch the agent in a specific multiplexer. Currently supported: tmux, zellij (zellij requires >= 0.44.0). When started outside the multiplexer, creates or reuses a detached session and reports the tab/pane handle
--tmux-session-Reuse or create a specific tmux session for the agent. Implies --multiplexer tmux
--zellij-session-Reuse or create a specific zellij session for the agent. Implies --multiplexer zellij
--hooks/--no-hookstrueRun built-in agent preparation (like Codex auto-trust) and configured pre-launch hooks before starting the agent
--verbose, -vfalseStream output from setup commands instead of hiding it

Examples:

# Create dev environment from a specific commit
agent-cli dev new hotfix --from v1.2.3

# Create an interactive dev environment with Cursor and Claude
agent-cli dev new feature --with-editor cursor --agent claude

# Quick interactive dev environment with defaults from config
agent-cli dev new -e --start-agent

# Create dev environment with an initial prompt for the agent
agent-cli dev new fix-bug --prompt "Fix the login validation bug in auth.py"

# Use --prompt-file for long prompts (avoids shell quoting issues)
agent-cli dev new refactor --prompt-file task.md

# Launch the default agent interactively in tmux
agent-cli dev new feature --start-agent -m tmux

# Launch a specific agent in tmux with an initial task
agent-cli dev new feature --agent codex -m tmux --prompt-file task.md

# Override the default repo-scoped tmux session
agent-cli dev new feature --agent codex --tmux-session review-batch --prompt-file task.md

For automated or headless use, pass --prompt or --prompt-file so the agent starts working immediately. --start-agent is mainly useful when a human plans to attach and drive the session interactively. --tmux-session implies -m tmux and overrides the default repo-scoped tmux session name.

dev list

List all dev environments (worktrees) for the current repository.

agent-cli dev list [OPTIONS]

Options

OptionDefaultDescription
--jsonfalseOutput as JSON. Fields: name, path, branch, is_main, is_detached, is_locked, is_prunable

dev status

Show status of all dev environments with git status information.

agent-cli dev status [OPTIONS]

Options:

Options

OptionDefaultDescription
--stale-days, -s7Mark worktrees as stale if inactive for N+ days (default: 7)
--jsonfalseOutput as JSON with fields: name, branch, modified, staged, untracked, ahead, behind, last_commit_timestamp, is_stale

Output columns:

ColumnDescription
NameWorktree directory name
BranchGit branch name
ChangesFile changes: M modified, S staged, ? untracked
↑/↓Commits ahead (+) / behind (-) upstream
Last CommitRelative time since last commit

Examples:

# Show status of all worktrees
agent-cli dev status

# Highlight worktrees inactive for 14+ days
agent-cli dev status --stale-days 14

Example output:

                          Dev Environment Status
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Name        ┃ Branch          ┃ Changes ┃ ↑/↓ ┃ Last Commit    ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━╇━━━━━━━━━━━━━━━━┩
│ main        │ main            │      3M │  —  │ 24 minutes ago │
│ my-feature  │ feat/my-feature │   clean │  —  │ 9 days ago ⚠️   │
└─────────────┴─────────────────┴─────────┴─────┴────────────────┘

2 worktrees · 1 with uncommitted changes · 1 stale (>7 days)

Legend:

  • M = Modified files (not staged)
  • S = Staged files
  • ? = Untracked files
  • +N = N commits ahead of upstream
  • -N = N commits behind upstream
  • ⚠️ = Stale worktree (inactive for longer than --stale-days)

dev rm

Remove a dev environment (worktree).

agent-cli dev rm NAME [OPTIONS]

Options

OptionDefaultDescription
--force, -ffalseForce removal even if worktree has uncommitted changes
--delete-branch, -dfalseAlso delete the git branch (not just the worktree)
--yes, -yfalseSkip confirmation prompt

When a worktree was launched in tmux through agent-cli, dev rm also cleans up any tagged tmux windows for that worktree. If git removal succeeds but tmux cleanup is partial, the command warns and still removes the worktree.

dev path

Print the path to a dev environment (for shell integration).

agent-cli dev path NAME

Example:

# Navigate to a dev environment
cd "$(agent-cli dev path my-feature)"

dev editor

Open a dev environment in an editor.

agent-cli dev editor NAME [--editor/-e EDITOR]

Options

OptionDefaultDescription
--editor, -e-Override auto-detection. Options: cursor, vscode, zed, nvim, vim, emacs, sublime, idea, pycharm, etc.

dev agent

Start an AI coding agent in a dev environment.

agent-cli dev agent NAME [--agent/-a AGENT] [--agent-args ARGS] [--prompt/-p PROMPT] [--multiplexer/-m tmux] [--tmux-session SESSION]

Options:

Options

OptionDefaultDescription
--agent, -a-Which agent: claude, codex, gemini, aider, copilot, cn, opencode, cursor-agent. Auto-detects if omitted
--agent-args-Extra CLI args for the agent. Example: --agent-args='--dangerously-skip-permissions'
--prompt, -p-Initial task for the agent. Saved to a unique file in .claude/ to avoid conflicts. Example: --prompt='Add unit tests for auth'
--prompt-file, -P-Read the agent prompt from a file instead of command line
--multiplexer, -m-Launch the agent in a specific multiplexer instead of the current terminal. Currently supported: tmux, zellij (zellij requires >= 0.44.0)
--tmux-session-Reuse or create a specific tmux session for the agent. Implies --multiplexer tmux
--zellij-session-Reuse or create a specific zellij session for the agent. Implies --multiplexer zellij
--hooks/--no-hookstrueRun built-in agent preparation (like Codex auto-trust) and configured pre-launch hooks before starting the agent

Examples:

# Start Claude in an existing worktree with a prompt
agent-cli dev agent my-feature --prompt "Continue implementing the user settings page"

# Start aider with a specific task
agent-cli dev agent my-feature -a aider --prompt "Add unit tests for the auth module"

# Start an agent in a detached tmux session and get its pane handle
agent-cli dev agent my-feature -a codex -m tmux --prompt-file continue-task.md

# Reuse or create a specific tmux session for a shared review batch
agent-cli dev agent my-feature -a codex --tmux-session review-batch --prompt-file continue-task.md

For automated use, prefer --prompt-file or --prompt. Without either, the agent starts interactively and may wait for input. --tmux-session implies -m tmux, and tmux session names cannot contain . or :.

dev run

Run a command in a dev environment.

agent-cli dev run NAME COMMAND...

Example:

# Run tests in the my-feature worktree
agent-cli dev run my-feature npm test

# Run multiple commands
agent-cli dev run my-feature bash -c "npm install && npm test"

dev clean

Clean up stale worktrees and empty directories.

agent-cli dev clean [OPTIONS]

Options

OptionDefaultDescription
--mergedfalseAlso remove worktrees whose GitHub PRs are merged (requires gh CLI and auth)
--no-commitsfalseAlso remove worktrees with 0 commits ahead of default branch (abandoned branches)
--dry-run, -nfalsePreview what would be removed without actually removing
--yes, -yfalseSkip confirmation prompts
--force, -ffalseForce removal of worktrees with modified or untracked files

Examples:

# Prune stale worktrees and remove empty directories
agent-cli dev clean

# Also remove worktrees whose PRs have been merged
agent-cli dev clean --merged

# Remove worktrees with no commits (abandoned or manually merged branches)
agent-cli dev clean --no-commits

# Preview what would be cleaned
agent-cli dev clean --merged --dry-run

Like dev rm, dev clean also removes tagged tmux windows for worktrees it deletes and warns if tmux cleanup is only partial.

dev doctor

Check system requirements and available integrations.

agent-cli dev doctor [OPTIONS]

Options

OptionDefaultDescription
--jsonfalseOutput as JSON with git, editors, agents, terminals status

Shows available editors, AI agents, and terminals with their detection status.

dev install-skill

Install Claude Code skill for parallel agent orchestration.

agent-cli dev install-skill [OPTIONS]

Installs a skill that teaches Claude Code how to use agent-cli dev to spawn parallel AI coding agents in isolated git worktrees. The skill is installed to .claude/skills/agent-cli-dev/ in the current repository.

Options:

Options

OptionDefaultDescription
--force, -ffalseOverwrite existing skill files if already installed

Example:

# Install the skill in your project
agent-cli dev install-skill

# Force reinstall if files already exist
agent-cli dev install-skill --force

Once installed, Claude Code can automatically use the skill when you ask to work on multiple features or parallelize development tasks.

Alternative: Plugin Marketplace

You can also install the skill globally via the Claude Code plugin marketplace:

claude plugin marketplace add basnijholt/agent-cli
claude plugin install agent-cli-dev@agent-cli

This installs the skill globally so it's available in all projects without needing to run dev install-skill in each one.

Discovery Commands

dev agents

List available AI coding agents.

agent-cli dev agents [OPTIONS]

Options

OptionDefaultDescription
--jsonfalseOutput as JSON with name, command, is_available, is_current, install_url

dev editors

List available editors.

agent-cli dev editors [OPTIONS]

Options

OptionDefaultDescription
--jsonfalseOutput as JSON with name, command, is_available, is_current, install_url

dev terminals

List available terminal multiplexers.

agent-cli dev terminals [OPTIONS]

Options

OptionDefaultDescription
--jsonfalseOutput as JSON with name, is_available, is_current

Supported Integrations

AI Coding Agents

AgentCommandDetectionPrompt Support
Claude CodeclaudeCLAUDECODE=1 env varclaude "prompt"
OpenAI CodexcodexParent process detectioncodex "prompt"
Google Gemini CLIgeminiParent process detectiongemini -i "prompt"
AideraiderParent process detectionaider --message "prompt"
GitHub Copilot CLIcopilotParent process detectioncopilot --prompt "prompt"
Continue DevcnParent process detection
OpenCodeopencodeOPENCODE=1 env var
Cursor Agentcursor-agentCURSOR_AGENT env var

Editors

EditorCommandNotes
CursorcursorAI-first editor
VS Codecode
ZedzedFast, modern editor
NeovimnvimUses cd && nvim . pattern
VimvimUses cd && vim . pattern
NanonanoUses cd && nano . pattern
EmacsemacsRuns in background
Sublime Textsubl
IntelliJ IDEAidea
PyCharmpycharm
WebStormwebstorm
GoLandgoland
RustRoverrustrover

Terminals

TerminalDetectionNew Tab Command
tmuxTMUX env vartmux new-window -c <path>
ZellijZELLIJ env varzellij action new-tab --cwd <path>
cmuxCMUX_WORKSPACE_ID env varcmux new-surface in a workspace named after the repo (created on demand)
KittyKITTY_WINDOW_IDkitten @ launch --type=tab
iTerm2ITERM_SESSION_IDAppleScript
Terminal.appTERM_PROGRAM=Apple_TerminalAppleScript + System Events *
WarpTERM_PROGRAM=WarpTerminalURI scheme + Launch Configurations
GNOME TerminalGNOME_TERMINAL_SERVICEgnome-terminal --tab

* Requires accessibility permissions in System Preferences > Privacy & Security > Accessibility.

Configuration

Add defaults to your ~/.config/agent-cli/config.toml. If you use agent-cli config init, the generated template already includes a commented-out starter block for [dev], [dev.agent_args], and [dev.agent_env.<agent>] settings like these:

[dev]
# Default flags for 'dev new' command
editor = true          # Always open editor (-e)
start_agent = true     # Always start agent (--start-agent)
auto_trust = true      # Auto-trust supported agents before launch
direnv = true          # Always generate .envrc (--direnv)

# Worktree creation behavior
setup = true           # Run project setup (npm install, etc.)
copy_env = true        # Copy env and local agent instruction files
fetch = true           # Git fetch before creating

# Branch naming behavior when BRANCH argument is omitted
branch_name_mode = "ai"        # random | auto | ai
branch_name_agent = "claude"   # claude | codex | gemini (optional)
branch_name_timeout = 20.0     # seconds

# Which editor/agent to use when flags are enabled
default_editor = "cursor"
default_agent = "claude"

# Per-agent arguments (applied automatically when launching agents)
[dev.agent_args]
claude = ["--dangerously-skip-permissions"]
codex = ["--dangerously-bypass-approvals-and-sandbox"]

# Per-agent environment variables (applied when launching agents)
[dev.agent_env.claude]
CLAUDE_CODE_USE_VERTEX = "1"
ANTHROPIC_MODEL = "claude-opus-4-5"

# Optional pre-launch hooks (run from the worktree directory)
[dev.hooks]
pre_launch = ["~/.config/agent-cli/hooks/pre-launch.sh"]

# Optional per-agent pre-launch hooks
[dev.hooks.codex]
pre_launch = ["~/.config/agent-cli/hooks/codex-setup.sh"]

Or per-project in agent-cli-config.toml:

[dev]
editor = true
start_agent = true
direnv = true
default_editor = "zed"
default_agent = "aider"

[dev.agent_args]
claude = ["--dangerously-skip-permissions", "--model", "opus"]

[dev.agent_env.claude]
ANTHROPIC_MODEL = "claude-sonnet-4-20250514"

[dev.hooks]
pre_launch = ["./scripts/prepare-worktree.sh"]

With this configuration, running agent-cli dev new will automatically open the editor, start the agent, and set up direnv.

Automatic Features

Project Setup

When creating a new dev environment, automatic setup is performed based on detected project type:

Project TypeDetectionSetup Command
Python (uv)pyproject.toml + uv.lockuv sync --all-extras
Python (unidep)requirements.yaml or [tool.unidep]unidep install -e . -n <env> *
Python (unidep monorepo)requirements.yaml in subdirsunidep install-all -e -n <env> *
Python (poetry)pyproject.toml + poetry.lockpoetry install
Python (pip)requirements.txtpip install -r requirements.txt
Node.js (pnpm)pnpm-lock.yamlpnpm install
Node.js (yarn)yarn.lockyarn install
Node.js (npm)package-lock.jsonnpm install
RustCargo.tomlcargo build
Gogo.modgo mod download
RubyGemfile or Gemfile.lockbundle install
Pixipixi.toml or pixi.lockpixi install

* For unidep projects, if conda-lock.yml is present, -f conda-lock.yml is also added.

Git Submodules

Git submodules are automatically initialized and updated when creating a new dev environment:

git submodule update --init --recursive

This ensures all submodule dependencies are available in the worktree.

Git LFS

If the repository uses Git LFS (detected via filter=lfs in .gitattributes), LFS files are automatically pulled:

git lfs pull

This ensures large files tracked by LFS are available in the worktree.

Local Setup Files

The following files are automatically copied to new dev environments:

  • .env
  • .env.local
  • .env.example
  • .envrc
  • AGENTS.local.md
  • CLAUDE.local.md

If the target branch already contains either local agent instruction file, its checked-out version is preserved.

Use --no-copy-env to skip this.

Direnv Integration

With --direnv, a .envrc file is automatically generated based on the detected project type:

Project TypeGenerated .envrc Content
Nix (flake.nix)use flake
Nix (shell.nix)use nix
Python (uv)source .venv/bin/activate
Python (unidep)micromamba activate <dirname> (with conda fallback)
Python (poetry)source "$(poetry env info --path)/bin/activate"
Python (pip/venv)source .venv/bin/activate (or detected venv path)
Node.js (with .nvmrc)use node
Golayout go
Rubylayout ruby
Pixiwatch_file pixi.lock + eval "$(pixi shell-hook)"

Multiple directives can be combined. For example, a Python project with shell.nix will get:

use nix
source .venv/bin/activate

The generated .envrc is automatically trusted with direnv allow.

Agent Launch

When launching an AI agent, the dev command automatically:

  1. Detects if you're in tmux/zellij and opens a new tab there
  2. With -m tmux, creates or reuses a detached tmux session even when you're not already inside tmux
  3. Outside tmux, uses a deterministic repo-scoped tmux session by default for explicit tmux launches
  4. Inside tmux, opens a new window in the current tmux session unless --tmux-session <name> is provided
  5. Returns the tmux pane handle and an attach command for explicit tmux launches
  6. Falls back to supported terminals (kitty, iTerm2)
  7. Prints instructions if no terminal is detected

Before launching an agent, agent-cli dev can also run launch preparation:

  • Built-in preparation for supported agents. Currently this means Codex auto-trust: when [dev].auto_trust = true (the default), agent-cli ensures the repository root is trusted in ~/.codex/config.toml before launch.
  • User-defined pre_launch hooks from [dev.hooks] and [dev.hooks.<agent>]. Global hooks run first, then agent-specific hooks.
  • Hook config follows the same config source as the rest of dev, including agent-cli dev --config path/to/config.toml ....
  • Hooks run synchronously in the worktree directory and receive:
    • AGENT_CLI_AGENT
    • AGENT_CLI_WORKTREE
    • AGENT_CLI_REPO_ROOT
    • AGENT_CLI_BRANCH
    • AGENT_CLI_NAME
    • AGENT_CLI_TASK_FILE
    • AGENT_CLI_PROMPT_FILE (alias of AGENT_CLI_TASK_FILE)
  • Hook commands are executed directly, not through a shell. For pipelines or more complex setup, point pre_launch at a script.
  • Use --no-hooks to bypass both built-in preparation and configured pre-launch hooks for a single launch.

Multi-agent Workflows

Use dev agent -m tmux when you want multiple agents on the same worktree instead of multiple worktrees:

# Create the worktree once. This is setup only; no agent starts yet.
agent-cli dev new review-auth --from HEAD

# Launch multiple reviewers into the same worktree
agent-cli dev agent review-auth -m tmux --prompt-file .claude/review-security.md
agent-cli dev agent review-auth -m tmux --prompt-file .claude/review-performance.md
agent-cli dev agent review-auth -m tmux --prompt-file .claude/review-tests.md

This is useful for:

  • Multiple reviewers on the same branch
  • Parallel validation agents working on one codebase
  • Headless orchestration from scripts or other assistants

Outside tmux, explicit tmux launches for the same repository are grouped into the same deterministic tmux session (agent-cli-<repo>-<hash>), which keeps related windows together across headless or scripted launches.

When already inside tmux, -m tmux opens a new window in the current session unless you pass --tmux-session <name>. That flag reuses or creates a specific tmux session instead. tmux session names cannot contain . or :.

For fully headless orchestration, combine --prompt-file with -m tmux:

for section in 1 2 3 4; do
  agent-cli dev new "validate-$section" --from HEAD --agent codex -m tmux \
    --prompt-file ".claude/validate-$section.md"
done

If multiple agents share one worktree, do not have them all write to .claude/REPORT.md because they will overwrite each other. Instead, assign unique report paths such as .claude/REPORT-security-<run-id>.md and .claude/REPORT-tests-<run-id>.md. If you rerun the same prompt repeatedly, use a timestamp or other run id so later runs do not replace earlier results. Each agent launch also gets its own .claude/TASK-{timestamp}-{hex}.md file, so prompt files no longer overwrite each other.

Shell Integration

Add a function to quickly navigate to dev environments:

# ~/.bashrc or ~/.zshrc
dcd() {
    cd "$(agent-cli dev path "\$1")"
}

# Usage: dcd my-feature

Tips

  • Use agent-cli dev new without arguments for quick experimentation
  • Run agent-cli dev doctor to verify your setup
  • Combine -e --start-agent to immediately start coding with AI assistance
  • Use --from to branch from a specific tag or commit