diff --git a/.claude-plugin/skills/agent-cli-dev/SKILL.md b/.claude-plugin/skills/agent-cli-dev/SKILL.md index b175fc77..a2daf30b 100644 --- a/.claude-plugin/skills/agent-cli-dev/SKILL.md +++ b/.claude-plugin/skills/agent-cli-dev/SKILL.md @@ -20,7 +20,7 @@ If `agent-cli` is not available, install it first: uv tool install agent-cli -p 3.13 # Or run directly without installing -uvx --python 3.13 agent-cli dev new --agent --prompt "..." +uvx --python 3.13 agent-cli dev new --prompt "..." ``` ## When to spawn parallel agents @@ -40,17 +40,17 @@ Do NOT spawn when: For new features (starts from origin/main): ```bash -agent-cli dev new --agent --prompt "Implement the new feature..." +agent-cli dev new --prompt "Implement the new feature..." ``` For work on current branch (review, test, fix) - use `--from HEAD`: ```bash -agent-cli dev new --from HEAD --agent --prompt "Review/test/fix..." +agent-cli dev new --from HEAD --prompt "Review/test/fix..." ``` For longer prompts (recommended for multi-line or complex instructions): ```bash -agent-cli dev new --from HEAD --agent --prompt-file path/to/prompt.md +agent-cli dev new --from HEAD --prompt-file path/to/prompt.md ``` This creates: @@ -67,10 +67,10 @@ This creates: When an assistant is executing this workflow on the user's behalf, the spawn is not complete unless the agent receives a prompt at launch time. - Prefer `--prompt-file`; create the prompt file first, then launch the agent -- Use `dev new ... --agent --prompt-file ...` for a new delegated task +- Use `dev new ... --prompt-file ...` for a new delegated task - Use `dev agent ... --prompt-file ...` for another agent in an existing worktree - Do not stop after `dev new ...` alone if the user's intent was to delegate work immediately -- Do not run `dev new ... --agent` or `dev agent ... -m tmux` without `--prompt` or `--prompt-file` unless the user explicitly wants an interactive session that they will drive manually +- Do not run `dev new ... --start-agent`, `dev new ... --agent `, or `dev agent ... -m tmux` without `--prompt` or `--prompt-file` unless the user explicitly wants an interactive session that they will drive manually ## Writing effective prompts for spawned agents @@ -92,7 +92,7 @@ Example workflow: ```bash # 1. Write prompt to file # 2. Spawn agent with the file -agent-cli dev new my-feature --agent --prompt-file .claude/spawn-prompt.md +agent-cli dev new my-feature --prompt-file .claude/spawn-prompt.md # 3. Optionally clean up rm .claude/spawn-prompt.md ``` @@ -144,7 +144,7 @@ agent-cli dev agent review-auth -m tmux --prompt-file .claude/review-tests.md Key rules for same-worktree launches: - Use `dev agent`, not `dev new`, after the worktree already exists -- Use `dev agent -a ` to select a specific agent for an existing worktree; `--with-agent` remains a deprecated alias on this subcommand +- Use `dev agent --agent ` to select a specific agent for an existing worktree; `--with-agent` remains a deprecated alias on this subcommand - Use `-m tmux` for headless or scripted launching; it works even when not already inside tmux - Each launch joins the same deterministic repo-scoped tmux session, so related agents stay grouped together - Ask each agent to write to a unique report path such as `.claude/REPORT-security-.md` or `.claude/REPORT-tests-.md` @@ -171,7 +171,7 @@ When complete, write findings to .claude/REPORT-security-20260319-153045-123.md For non-interactive contexts (scripts, cron jobs, other assistants), combine `--prompt-file` with `-m tmux`: ```bash -agent-cli dev new validation-a --from HEAD --agent --with-agent codex -m tmux \ +agent-cli dev new validation-a --from HEAD --agent codex -m tmux \ --prompt-file .claude/validation-a.md ``` @@ -183,9 +183,9 @@ If asked to implement auth, payments, and notifications: ```bash # Spawn three parallel agents -agent-cli dev new auth-feature --agent --prompt "Implement JWT authentication..." -agent-cli dev new payment-integration --agent --prompt "Add Stripe payment processing..." -agent-cli dev new email-notifications --agent --prompt "Implement email notification system..." +agent-cli dev new auth-feature --prompt "Implement JWT authentication..." +agent-cli dev new payment-integration --prompt "Add Stripe payment processing..." +agent-cli dev new email-notifications --prompt "Implement email notification system..." ``` Each agent works independently in its own branch. Results can be reviewed and merged separately. @@ -194,11 +194,11 @@ Each agent works independently in its own branch. Results can be reviewed and me | Option | Description | |--------|-------------| -| `--agent` / `-a` | Start AI coding agent after creation | +| `--start-agent` | Start the default/auto-detected agent without an initial prompt | | `--prompt` / `-p` | Initial prompt for the agent (short prompts only) | | `--prompt-file` / `-P` | Read prompt from file (recommended for longer prompts) | | `--from` / `-f` | Base ref (default: origin/main). **Use `--from HEAD` when reviewing/testing current branch!** | -| `--with-agent` | Specific agent: claude, aider, codex, gemini | +| `--agent` | Specific agent (or `auto`): claude, aider, codex, gemini | | `--agent-args` | Extra arguments for the agent | @examples.md diff --git a/.claude-plugin/skills/agent-cli-dev/examples.md b/.claude-plugin/skills/agent-cli-dev/examples.md index 505767f4..29d9d433 100644 --- a/.claude-plugin/skills/agent-cli-dev/examples.md +++ b/.claude-plugin/skills/agent-cli-dev/examples.md @@ -6,7 +6,7 @@ Real-world scenarios for spawning parallel AI coding agents, optimized for Claud > > ```bash > # Write prompt to file, then spawn -> agent-cli dev new my-feature --agent --prompt-file .claude/spawn-prompt.md +> agent-cli dev new my-feature --prompt-file .claude/spawn-prompt.md > ``` > > When an assistant is executing these commands, do not launch `dev new` or `dev agent` without `--prompt` or `--prompt-file` unless the user explicitly wants a manual interactive session. @@ -31,7 +31,7 @@ Each prompt for a spawned agent should follow this structure: ```bash # Review the current branch - MUST use --from HEAD -agent-cli dev new review-changes --from HEAD --agent --prompt "Review the code changes on this branch. +agent-cli dev new review-changes --from HEAD --prompt "Review the code changes on this branch. - Run git diff origin/main...HEAD to identify all changes @@ -91,7 +91,7 @@ Write your review to .claude/REPORT.md: **Strategy**: Three independent features → spawn three agents. ```bash -agent-cli dev new auth-feature --agent --prompt "Implement JWT-based user authentication. +agent-cli dev new auth-feature --prompt "Implement JWT-based user authentication. - Read multiple files in parallel when exploring the codebase @@ -144,7 +144,7 @@ How to verify the implementation works Any items needing review " -agent-cli dev new payment-integration --agent --prompt "Integrate Stripe payment processing. +agent-cli dev new payment-integration --prompt "Integrate Stripe payment processing. - Read multiple files in parallel when exploring the codebase @@ -195,7 +195,7 @@ After verifying tests pass, write to .claude/REPORT.md: [Any items for review] " -agent-cli dev new email-notifications --agent --prompt "Implement email notification system. +agent-cli dev new email-notifications --prompt "Implement email notification system. - Read multiple files in parallel when exploring the codebase @@ -240,7 +240,7 @@ After verifying tests pass, write to .claude/REPORT.md with summary, files chang **Strategy**: One agent writes tests first, another implements. ```bash -agent-cli dev new cache-tests --agent --prompt "Write comprehensive tests for a caching layer. +agent-cli dev new cache-tests --prompt "Write comprehensive tests for a caching layer. Create a complete test suite that drives the implementation of a caching system. The tests define the interface - write them as if the implementation already exists. @@ -306,7 +306,7 @@ When complete, write to .claude/REPORT.md: After reviewing the tests: ```bash -agent-cli dev new cache-impl --from cache-tests --agent --prompt "Implement the caching layer to pass existing tests. +agent-cli dev new cache-impl --from cache-tests --prompt "Implement the caching layer to pass existing tests. - Read all test files first to understand the complete interface @@ -360,7 +360,7 @@ After ALL tests pass, write to .claude/REPORT.md: **Strategy**: Split by module, each agent handles one area. ```bash -agent-cli dev new refactor-users-errors --agent --prompt "Refactor error handling in the users module. +agent-cli dev new refactor-users-errors --prompt "Refactor error handling in the users module. - Read all relevant files in parallel before making any changes @@ -428,7 +428,7 @@ After tests pass and linting is clean, write to .claude/REPORT.md: **Strategy**: One agent implements, another writes docs simultaneously. ```bash -agent-cli dev new plugin-system --agent --prompt "Implement a plugin system. +agent-cli dev new plugin-system --prompt "Implement a plugin system. - Read existing codebase structure in parallel before designing @@ -483,7 +483,7 @@ class Plugin: [How to create and register a plugin] " -agent-cli dev new plugin-docs --agent --prompt "Write documentation for the plugin system. +agent-cli dev new plugin-docs --prompt "Write documentation for the plugin system. Implementation is happening in parallel in another branch. Write documentation based on a standard plugin system design. The implementation agent will adapt if needed, or you can update docs after reviewing their work. @@ -595,7 +595,7 @@ Write findings to .claude/REPORT-tests-$run_id.md: ```bash for section in 1 2 3 4 5 6 7 8; do - agent-cli dev new "test-section-$section" --from HEAD --agent --with-agent codex -m tmux \ + agent-cli dev new "test-section-$section" --from HEAD --agent codex -m tmux \ --prompt-file ".claude/test-section-$section.md" done ``` diff --git a/.claude/skills/agent-cli-dev/SKILL.md b/.claude/skills/agent-cli-dev/SKILL.md index b175fc77..a2daf30b 100644 --- a/.claude/skills/agent-cli-dev/SKILL.md +++ b/.claude/skills/agent-cli-dev/SKILL.md @@ -20,7 +20,7 @@ If `agent-cli` is not available, install it first: uv tool install agent-cli -p 3.13 # Or run directly without installing -uvx --python 3.13 agent-cli dev new --agent --prompt "..." +uvx --python 3.13 agent-cli dev new --prompt "..." ``` ## When to spawn parallel agents @@ -40,17 +40,17 @@ Do NOT spawn when: For new features (starts from origin/main): ```bash -agent-cli dev new --agent --prompt "Implement the new feature..." +agent-cli dev new --prompt "Implement the new feature..." ``` For work on current branch (review, test, fix) - use `--from HEAD`: ```bash -agent-cli dev new --from HEAD --agent --prompt "Review/test/fix..." +agent-cli dev new --from HEAD --prompt "Review/test/fix..." ``` For longer prompts (recommended for multi-line or complex instructions): ```bash -agent-cli dev new --from HEAD --agent --prompt-file path/to/prompt.md +agent-cli dev new --from HEAD --prompt-file path/to/prompt.md ``` This creates: @@ -67,10 +67,10 @@ This creates: When an assistant is executing this workflow on the user's behalf, the spawn is not complete unless the agent receives a prompt at launch time. - Prefer `--prompt-file`; create the prompt file first, then launch the agent -- Use `dev new ... --agent --prompt-file ...` for a new delegated task +- Use `dev new ... --prompt-file ...` for a new delegated task - Use `dev agent ... --prompt-file ...` for another agent in an existing worktree - Do not stop after `dev new ...` alone if the user's intent was to delegate work immediately -- Do not run `dev new ... --agent` or `dev agent ... -m tmux` without `--prompt` or `--prompt-file` unless the user explicitly wants an interactive session that they will drive manually +- Do not run `dev new ... --start-agent`, `dev new ... --agent `, or `dev agent ... -m tmux` without `--prompt` or `--prompt-file` unless the user explicitly wants an interactive session that they will drive manually ## Writing effective prompts for spawned agents @@ -92,7 +92,7 @@ Example workflow: ```bash # 1. Write prompt to file # 2. Spawn agent with the file -agent-cli dev new my-feature --agent --prompt-file .claude/spawn-prompt.md +agent-cli dev new my-feature --prompt-file .claude/spawn-prompt.md # 3. Optionally clean up rm .claude/spawn-prompt.md ``` @@ -144,7 +144,7 @@ agent-cli dev agent review-auth -m tmux --prompt-file .claude/review-tests.md Key rules for same-worktree launches: - Use `dev agent`, not `dev new`, after the worktree already exists -- Use `dev agent -a ` to select a specific agent for an existing worktree; `--with-agent` remains a deprecated alias on this subcommand +- Use `dev agent --agent ` to select a specific agent for an existing worktree; `--with-agent` remains a deprecated alias on this subcommand - Use `-m tmux` for headless or scripted launching; it works even when not already inside tmux - Each launch joins the same deterministic repo-scoped tmux session, so related agents stay grouped together - Ask each agent to write to a unique report path such as `.claude/REPORT-security-.md` or `.claude/REPORT-tests-.md` @@ -171,7 +171,7 @@ When complete, write findings to .claude/REPORT-security-20260319-153045-123.md For non-interactive contexts (scripts, cron jobs, other assistants), combine `--prompt-file` with `-m tmux`: ```bash -agent-cli dev new validation-a --from HEAD --agent --with-agent codex -m tmux \ +agent-cli dev new validation-a --from HEAD --agent codex -m tmux \ --prompt-file .claude/validation-a.md ``` @@ -183,9 +183,9 @@ If asked to implement auth, payments, and notifications: ```bash # Spawn three parallel agents -agent-cli dev new auth-feature --agent --prompt "Implement JWT authentication..." -agent-cli dev new payment-integration --agent --prompt "Add Stripe payment processing..." -agent-cli dev new email-notifications --agent --prompt "Implement email notification system..." +agent-cli dev new auth-feature --prompt "Implement JWT authentication..." +agent-cli dev new payment-integration --prompt "Add Stripe payment processing..." +agent-cli dev new email-notifications --prompt "Implement email notification system..." ``` Each agent works independently in its own branch. Results can be reviewed and merged separately. @@ -194,11 +194,11 @@ Each agent works independently in its own branch. Results can be reviewed and me | Option | Description | |--------|-------------| -| `--agent` / `-a` | Start AI coding agent after creation | +| `--start-agent` | Start the default/auto-detected agent without an initial prompt | | `--prompt` / `-p` | Initial prompt for the agent (short prompts only) | | `--prompt-file` / `-P` | Read prompt from file (recommended for longer prompts) | | `--from` / `-f` | Base ref (default: origin/main). **Use `--from HEAD` when reviewing/testing current branch!** | -| `--with-agent` | Specific agent: claude, aider, codex, gemini | +| `--agent` | Specific agent (or `auto`): claude, aider, codex, gemini | | `--agent-args` | Extra arguments for the agent | @examples.md diff --git a/.claude/skills/agent-cli-dev/examples.md b/.claude/skills/agent-cli-dev/examples.md index 505767f4..29d9d433 100644 --- a/.claude/skills/agent-cli-dev/examples.md +++ b/.claude/skills/agent-cli-dev/examples.md @@ -6,7 +6,7 @@ Real-world scenarios for spawning parallel AI coding agents, optimized for Claud > > ```bash > # Write prompt to file, then spawn -> agent-cli dev new my-feature --agent --prompt-file .claude/spawn-prompt.md +> agent-cli dev new my-feature --prompt-file .claude/spawn-prompt.md > ``` > > When an assistant is executing these commands, do not launch `dev new` or `dev agent` without `--prompt` or `--prompt-file` unless the user explicitly wants a manual interactive session. @@ -31,7 +31,7 @@ Each prompt for a spawned agent should follow this structure: ```bash # Review the current branch - MUST use --from HEAD -agent-cli dev new review-changes --from HEAD --agent --prompt "Review the code changes on this branch. +agent-cli dev new review-changes --from HEAD --prompt "Review the code changes on this branch. - Run git diff origin/main...HEAD to identify all changes @@ -91,7 +91,7 @@ Write your review to .claude/REPORT.md: **Strategy**: Three independent features → spawn three agents. ```bash -agent-cli dev new auth-feature --agent --prompt "Implement JWT-based user authentication. +agent-cli dev new auth-feature --prompt "Implement JWT-based user authentication. - Read multiple files in parallel when exploring the codebase @@ -144,7 +144,7 @@ How to verify the implementation works Any items needing review " -agent-cli dev new payment-integration --agent --prompt "Integrate Stripe payment processing. +agent-cli dev new payment-integration --prompt "Integrate Stripe payment processing. - Read multiple files in parallel when exploring the codebase @@ -195,7 +195,7 @@ After verifying tests pass, write to .claude/REPORT.md: [Any items for review] " -agent-cli dev new email-notifications --agent --prompt "Implement email notification system. +agent-cli dev new email-notifications --prompt "Implement email notification system. - Read multiple files in parallel when exploring the codebase @@ -240,7 +240,7 @@ After verifying tests pass, write to .claude/REPORT.md with summary, files chang **Strategy**: One agent writes tests first, another implements. ```bash -agent-cli dev new cache-tests --agent --prompt "Write comprehensive tests for a caching layer. +agent-cli dev new cache-tests --prompt "Write comprehensive tests for a caching layer. Create a complete test suite that drives the implementation of a caching system. The tests define the interface - write them as if the implementation already exists. @@ -306,7 +306,7 @@ When complete, write to .claude/REPORT.md: After reviewing the tests: ```bash -agent-cli dev new cache-impl --from cache-tests --agent --prompt "Implement the caching layer to pass existing tests. +agent-cli dev new cache-impl --from cache-tests --prompt "Implement the caching layer to pass existing tests. - Read all test files first to understand the complete interface @@ -360,7 +360,7 @@ After ALL tests pass, write to .claude/REPORT.md: **Strategy**: Split by module, each agent handles one area. ```bash -agent-cli dev new refactor-users-errors --agent --prompt "Refactor error handling in the users module. +agent-cli dev new refactor-users-errors --prompt "Refactor error handling in the users module. - Read all relevant files in parallel before making any changes @@ -428,7 +428,7 @@ After tests pass and linting is clean, write to .claude/REPORT.md: **Strategy**: One agent implements, another writes docs simultaneously. ```bash -agent-cli dev new plugin-system --agent --prompt "Implement a plugin system. +agent-cli dev new plugin-system --prompt "Implement a plugin system. - Read existing codebase structure in parallel before designing @@ -483,7 +483,7 @@ class Plugin: [How to create and register a plugin] " -agent-cli dev new plugin-docs --agent --prompt "Write documentation for the plugin system. +agent-cli dev new plugin-docs --prompt "Write documentation for the plugin system. Implementation is happening in parallel in another branch. Write documentation based on a standard plugin system design. The implementation agent will adapt if needed, or you can update docs after reviewing their work. @@ -595,7 +595,7 @@ Write findings to .claude/REPORT-tests-$run_id.md: ```bash for section in 1 2 3 4 5 6 7 8; do - agent-cli dev new "test-section-$section" --from HEAD --agent --with-agent codex -m tmux \ + agent-cli dev new "test-section-$section" --from HEAD --agent codex -m tmux \ --prompt-file ".claude/test-section-$section.md" done ``` diff --git a/agent_cli/dev/cli.py b/agent_cli/dev/cli.py index 12577be0..68c690e6 100644 --- a/agent_cli/dev/cli.py +++ b/agent_cli/dev/cli.py @@ -51,9 +51,9 @@ **Common workflows:** -- `dev new feature-x -a` — Create worktree + start AI agent in new terminal tab -- `dev new feature-x -e -a` — Create worktree + open editor + start agent -- `dev new -a -p "Fix the auth bug"` — Create worktree + start agent with prompt +- `dev new feature-x --start-agent` — Create worktree + start AI agent in new terminal tab +- `dev new feature-x -e --start-agent` — Create worktree + open editor + start agent +- `dev new --prompt "Fix the auth bug"` — Create worktree + start agent with prompt - `dev status` — See all worktrees with uncommitted changes - `dev clean --merged` — Remove worktrees whose PRs are merged @@ -157,6 +157,36 @@ def _resolve_prompt_text( return prompt +def _resolve_dev_new_agent_request( + *, + start_agent: bool, + start_agent_deprecated: bool, + agent_name: str | None, + agent_name_deprecated: str | None, + prompt: str | None, +) -> tuple[bool, str | None]: + """Normalize launch-related flags for `dev new`.""" + if start_agent_deprecated: + warn("-a is deprecated for 'dev new', use --start-agent instead") + start_agent = True + + explicit_agent_requested = agent_name is not None or agent_name_deprecated is not None + if agent_name_deprecated is not None: + warn("--with-agent is deprecated for 'dev new', use --agent instead") + agent_name = agent_name or agent_name_deprecated + + if agent_name is not None: + normalized_agent = agent_name.strip().lower() + if not normalized_agent: + error("--agent cannot be empty") + agent_name = None if normalized_agent == "auto" else normalized_agent + + if prompt or explicit_agent_requested: + start_agent = True + + return start_agent, agent_name + + def _resolve_branch_name( branch: str | None, branch_name_mode: str, @@ -280,19 +310,34 @@ def new( help="Open the worktree in an editor. Uses --with-editor, config default, or auto-detects", ), ] = False, - agent: Annotated[ + start_agent: Annotated[ + bool, + typer.Option( + "--start-agent", + help="Start an AI coding agent in a new terminal tab without providing an initial prompt. Uses config default or auto-detects.", + ), + ] = False, + start_agent_deprecated: Annotated[ bool, typer.Option( - "--agent", "-a", - help="Start an AI coding agent in a new terminal tab. Uses --with-agent, config default, or auto-detects. Implied by --prompt", + hidden=True, + help="[Deprecated: use --start-agent] Start an AI coding agent in a new terminal tab", ), ] = False, agent_name: Annotated[ + str | None, + typer.Option( + "--agent", + help="Which AI agent to start: claude, codex, gemini, aider, copilot, cn (Continue), opencode, cursor-agent, or auto. Implies starting the agent", + ), + ] = None, + agent_name_deprecated: Annotated[ str | None, typer.Option( "--with-agent", - help="Which AI agent to start: claude, codex, gemini, aider, copilot, cn (Continue), opencode, cursor-agent", + hidden=True, + help="[Deprecated: use --agent] Which AI agent to start", ), ] = None, editor_name: Annotated[ @@ -343,7 +388,7 @@ def new( str | None, typer.Option( "--branch-name-agent", - help="Headless agent for AI branch naming: claude, codex, or gemini. If omitted, uses --with-agent when supported, otherwise tries available agents in that order", + help="Headless agent for AI branch naming: claude, codex, or gemini. If omitted, uses --agent when supported, otherwise tries available agents in that order", ), ] = None, branch_name_timeout: Annotated[ @@ -373,7 +418,7 @@ def new( typer.Option( "--prompt", "-p", - help="Initial task for the AI agent. Saved to a unique file in .claude/ to avoid conflicts. Implies --agent. Example: --prompt='Fix the login bug'", + help="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'", ), ] = None, prompt_file: Annotated[ @@ -381,7 +426,7 @@ def new( typer.Option( "--prompt-file", "-P", - help="Read the agent prompt from a file. Useful for long prompts to avoid shell quoting. Implies --agent", + help="Read the agent prompt from a file. Useful for long prompts to avoid shell quoting. Implies starting the agent", exists=True, readable=True, ), @@ -423,24 +468,27 @@ def new( 3. Runs project setup: npm install, uv sync, etc. (--setup) 4. Sets up direnv if installed (--direnv) 5. Opens editor if requested (-e/--editor) - 6. Starts AI agent in new terminal tab if requested (-a/--agent or --prompt) + 6. Starts AI agent in new terminal tab if requested (--start-agent, --agent, --prompt, or --prompt-file) **Examples:** - `dev new feature-x` — Create worktree, branching from origin/main (default) - - `dev new feature-x -a` — Create + start Claude/detected agent - - `dev new feature-x -e -a` — Create + open editor + start agent - - `dev new -a --prompt "Fix auth bug"` — Auto-named branch + agent with task - - `dev new --branch-name-mode ai -a --prompt "Refactor auth flow"` — AI-generated branch name + - `dev new feature-x --start-agent` — Create + start Claude/detected agent + - `dev new feature-x -e --start-agent` — Create + open editor + start agent + - `dev new --prompt "Fix auth bug"` — Auto-named branch + agent with task + - `dev new --branch-name-mode ai --prompt "Refactor auth flow"` — AI-generated branch name - `dev new hotfix --from v1.2.3` — Branch from a tag instead of main - `dev new feature-x --from origin/develop` — Branch from develop instead - - `dev new feature-x --with-agent aider --with-editor cursor` — Specific tools + - `dev new feature-x --agent aider --with-editor cursor` — Specific tools """ prompt = _resolve_prompt_text(prompt, prompt_file=prompt_file) - - # If a prompt is provided, automatically enable agent mode - if prompt: - agent = True + start_agent, agent_name = _resolve_dev_new_agent_request( + start_agent=start_agent, + start_agent_deprecated=start_agent_deprecated, + agent_name=agent_name, + agent_name_deprecated=agent_name_deprecated, + prompt=prompt, + ) repo_root = _ensure_git_repo() @@ -455,8 +503,8 @@ def new( from_ref, ) - resolved_agent = resolve_agent(agent, agent_name, default_agent) - if agent: + resolved_agent = resolve_agent(start_agent, agent_name, default_agent) + if start_agent: resolved_agent = _require_available_agent(resolved_agent, requested_name=agent_name) # Create the worktree @@ -1185,7 +1233,7 @@ def list_terminals_cmd( Shows supported terminals: tmux, zellij, kitty, iTerm2, Terminal.app, Warp, GNOME Terminal. - These are used to open new tabs when launching AI agents with `dev new -a`. + These are used to open new tabs when launching AI agents with `dev new --start-agent`. The current terminal (if detectable) is marked. """ current = terminals.detect_current_terminal() diff --git a/agent_cli/dev/skill/SKILL.md b/agent_cli/dev/skill/SKILL.md index b175fc77..a2daf30b 100644 --- a/agent_cli/dev/skill/SKILL.md +++ b/agent_cli/dev/skill/SKILL.md @@ -20,7 +20,7 @@ If `agent-cli` is not available, install it first: uv tool install agent-cli -p 3.13 # Or run directly without installing -uvx --python 3.13 agent-cli dev new --agent --prompt "..." +uvx --python 3.13 agent-cli dev new --prompt "..." ``` ## When to spawn parallel agents @@ -40,17 +40,17 @@ Do NOT spawn when: For new features (starts from origin/main): ```bash -agent-cli dev new --agent --prompt "Implement the new feature..." +agent-cli dev new --prompt "Implement the new feature..." ``` For work on current branch (review, test, fix) - use `--from HEAD`: ```bash -agent-cli dev new --from HEAD --agent --prompt "Review/test/fix..." +agent-cli dev new --from HEAD --prompt "Review/test/fix..." ``` For longer prompts (recommended for multi-line or complex instructions): ```bash -agent-cli dev new --from HEAD --agent --prompt-file path/to/prompt.md +agent-cli dev new --from HEAD --prompt-file path/to/prompt.md ``` This creates: @@ -67,10 +67,10 @@ This creates: When an assistant is executing this workflow on the user's behalf, the spawn is not complete unless the agent receives a prompt at launch time. - Prefer `--prompt-file`; create the prompt file first, then launch the agent -- Use `dev new ... --agent --prompt-file ...` for a new delegated task +- Use `dev new ... --prompt-file ...` for a new delegated task - Use `dev agent ... --prompt-file ...` for another agent in an existing worktree - Do not stop after `dev new ...` alone if the user's intent was to delegate work immediately -- Do not run `dev new ... --agent` or `dev agent ... -m tmux` without `--prompt` or `--prompt-file` unless the user explicitly wants an interactive session that they will drive manually +- Do not run `dev new ... --start-agent`, `dev new ... --agent `, or `dev agent ... -m tmux` without `--prompt` or `--prompt-file` unless the user explicitly wants an interactive session that they will drive manually ## Writing effective prompts for spawned agents @@ -92,7 +92,7 @@ Example workflow: ```bash # 1. Write prompt to file # 2. Spawn agent with the file -agent-cli dev new my-feature --agent --prompt-file .claude/spawn-prompt.md +agent-cli dev new my-feature --prompt-file .claude/spawn-prompt.md # 3. Optionally clean up rm .claude/spawn-prompt.md ``` @@ -144,7 +144,7 @@ agent-cli dev agent review-auth -m tmux --prompt-file .claude/review-tests.md Key rules for same-worktree launches: - Use `dev agent`, not `dev new`, after the worktree already exists -- Use `dev agent -a ` to select a specific agent for an existing worktree; `--with-agent` remains a deprecated alias on this subcommand +- Use `dev agent --agent ` to select a specific agent for an existing worktree; `--with-agent` remains a deprecated alias on this subcommand - Use `-m tmux` for headless or scripted launching; it works even when not already inside tmux - Each launch joins the same deterministic repo-scoped tmux session, so related agents stay grouped together - Ask each agent to write to a unique report path such as `.claude/REPORT-security-.md` or `.claude/REPORT-tests-.md` @@ -171,7 +171,7 @@ When complete, write findings to .claude/REPORT-security-20260319-153045-123.md For non-interactive contexts (scripts, cron jobs, other assistants), combine `--prompt-file` with `-m tmux`: ```bash -agent-cli dev new validation-a --from HEAD --agent --with-agent codex -m tmux \ +agent-cli dev new validation-a --from HEAD --agent codex -m tmux \ --prompt-file .claude/validation-a.md ``` @@ -183,9 +183,9 @@ If asked to implement auth, payments, and notifications: ```bash # Spawn three parallel agents -agent-cli dev new auth-feature --agent --prompt "Implement JWT authentication..." -agent-cli dev new payment-integration --agent --prompt "Add Stripe payment processing..." -agent-cli dev new email-notifications --agent --prompt "Implement email notification system..." +agent-cli dev new auth-feature --prompt "Implement JWT authentication..." +agent-cli dev new payment-integration --prompt "Add Stripe payment processing..." +agent-cli dev new email-notifications --prompt "Implement email notification system..." ``` Each agent works independently in its own branch. Results can be reviewed and merged separately. @@ -194,11 +194,11 @@ Each agent works independently in its own branch. Results can be reviewed and me | Option | Description | |--------|-------------| -| `--agent` / `-a` | Start AI coding agent after creation | +| `--start-agent` | Start the default/auto-detected agent without an initial prompt | | `--prompt` / `-p` | Initial prompt for the agent (short prompts only) | | `--prompt-file` / `-P` | Read prompt from file (recommended for longer prompts) | | `--from` / `-f` | Base ref (default: origin/main). **Use `--from HEAD` when reviewing/testing current branch!** | -| `--with-agent` | Specific agent: claude, aider, codex, gemini | +| `--agent` | Specific agent (or `auto`): claude, aider, codex, gemini | | `--agent-args` | Extra arguments for the agent | @examples.md diff --git a/agent_cli/dev/skill/examples.md b/agent_cli/dev/skill/examples.md index 505767f4..29d9d433 100644 --- a/agent_cli/dev/skill/examples.md +++ b/agent_cli/dev/skill/examples.md @@ -6,7 +6,7 @@ Real-world scenarios for spawning parallel AI coding agents, optimized for Claud > > ```bash > # Write prompt to file, then spawn -> agent-cli dev new my-feature --agent --prompt-file .claude/spawn-prompt.md +> agent-cli dev new my-feature --prompt-file .claude/spawn-prompt.md > ``` > > When an assistant is executing these commands, do not launch `dev new` or `dev agent` without `--prompt` or `--prompt-file` unless the user explicitly wants a manual interactive session. @@ -31,7 +31,7 @@ Each prompt for a spawned agent should follow this structure: ```bash # Review the current branch - MUST use --from HEAD -agent-cli dev new review-changes --from HEAD --agent --prompt "Review the code changes on this branch. +agent-cli dev new review-changes --from HEAD --prompt "Review the code changes on this branch. - Run git diff origin/main...HEAD to identify all changes @@ -91,7 +91,7 @@ Write your review to .claude/REPORT.md: **Strategy**: Three independent features → spawn three agents. ```bash -agent-cli dev new auth-feature --agent --prompt "Implement JWT-based user authentication. +agent-cli dev new auth-feature --prompt "Implement JWT-based user authentication. - Read multiple files in parallel when exploring the codebase @@ -144,7 +144,7 @@ How to verify the implementation works Any items needing review " -agent-cli dev new payment-integration --agent --prompt "Integrate Stripe payment processing. +agent-cli dev new payment-integration --prompt "Integrate Stripe payment processing. - Read multiple files in parallel when exploring the codebase @@ -195,7 +195,7 @@ After verifying tests pass, write to .claude/REPORT.md: [Any items for review] " -agent-cli dev new email-notifications --agent --prompt "Implement email notification system. +agent-cli dev new email-notifications --prompt "Implement email notification system. - Read multiple files in parallel when exploring the codebase @@ -240,7 +240,7 @@ After verifying tests pass, write to .claude/REPORT.md with summary, files chang **Strategy**: One agent writes tests first, another implements. ```bash -agent-cli dev new cache-tests --agent --prompt "Write comprehensive tests for a caching layer. +agent-cli dev new cache-tests --prompt "Write comprehensive tests for a caching layer. Create a complete test suite that drives the implementation of a caching system. The tests define the interface - write them as if the implementation already exists. @@ -306,7 +306,7 @@ When complete, write to .claude/REPORT.md: After reviewing the tests: ```bash -agent-cli dev new cache-impl --from cache-tests --agent --prompt "Implement the caching layer to pass existing tests. +agent-cli dev new cache-impl --from cache-tests --prompt "Implement the caching layer to pass existing tests. - Read all test files first to understand the complete interface @@ -360,7 +360,7 @@ After ALL tests pass, write to .claude/REPORT.md: **Strategy**: Split by module, each agent handles one area. ```bash -agent-cli dev new refactor-users-errors --agent --prompt "Refactor error handling in the users module. +agent-cli dev new refactor-users-errors --prompt "Refactor error handling in the users module. - Read all relevant files in parallel before making any changes @@ -428,7 +428,7 @@ After tests pass and linting is clean, write to .claude/REPORT.md: **Strategy**: One agent implements, another writes docs simultaneously. ```bash -agent-cli dev new plugin-system --agent --prompt "Implement a plugin system. +agent-cli dev new plugin-system --prompt "Implement a plugin system. - Read existing codebase structure in parallel before designing @@ -483,7 +483,7 @@ class Plugin: [How to create and register a plugin] " -agent-cli dev new plugin-docs --agent --prompt "Write documentation for the plugin system. +agent-cli dev new plugin-docs --prompt "Write documentation for the plugin system. Implementation is happening in parallel in another branch. Write documentation based on a standard plugin system design. The implementation agent will adapt if needed, or you can update docs after reviewing their work. @@ -595,7 +595,7 @@ Write findings to .claude/REPORT-tests-$run_id.md: ```bash for section in 1 2 3 4 5 6 7 8; do - agent-cli dev new "test-section-$section" --from HEAD --agent --with-agent codex -m tmux \ + agent-cli dev new "test-section-$section" --from HEAD --agent codex -m tmux \ --prompt-file ".claude/test-section-$section.md" done ``` diff --git a/agent_cli/docs_gen.py b/agent_cli/docs_gen.py index 5dc8ddd8..49002f1a 100644 --- a/agent_cli/docs_gen.py +++ b/agent_cli/docs_gen.py @@ -80,6 +80,9 @@ def _extract_options_from_click(cmd: click.Command) -> list[dict[str, Any]]: options = [] for param in cmd.params: if isinstance(param, click.Option): + if getattr(param, "hidden", False): + continue + # Get long and short option names long_opts = [n for n in param.opts if n.startswith("--")] short_opts = [n for n in param.opts if n.startswith("-") and not n.startswith("--")] diff --git a/agent_cli/example-config.toml b/agent_cli/example-config.toml index 0ff60e65..68818996 100644 --- a/agent_cli/example-config.toml +++ b/agent_cli/example-config.toml @@ -190,7 +190,7 @@ enable_tts = true [dev] # Defaults for `agent-cli dev new` # editor = true -# agent = true +# start_agent = true # auto_trust = true # direnv = true # setup = true diff --git a/docs/commands/dev.md b/docs/commands/dev.md index 7d6a2488..794dc99c 100644 --- a/docs/commands/dev.md +++ b/docs/commands/dev.md @@ -23,16 +23,16 @@ Like [git-worktree-runner (gtr)](https://github.com/CodeRabbitAI/git-worktree-ru 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 -a --prompt "Refactor auth flow" +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 -a +agent-cli dev new my-feature -e --start-agent # Create a dev environment and launch the agent in a detached tmux session -agent-cli dev new my-feature -a -m tmux +agent-cli dev new my-feature --start-agent -m tmux # List all dev environments agent-cli dev list @@ -71,21 +71,19 @@ agent-cli dev new [BRANCH] [OPTIONS] |--------|---------|-------------| | `--from, -f` | - | Git ref (branch/tag/commit) to branch from. Defaults to origin/main or origin/master | | `--editor, -e` | `false` | Open the worktree in an editor. Uses --with-editor, config default, or auto-detects | -| `--agent, -a` | `false` | Start an AI coding agent in a new terminal tab. Uses --with-agent, config default, or auto-detects. Implied by --prompt | -| `--with-agent` | - | Which AI agent to start: claude, codex, gemini, aider, copilot, cn (Continue), opencode, cursor-agent | +| `--start-agent` | `false` | Start 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. | -| `--default-agent` | - | Default agent from config | -| `--default-editor` | - | Default editor from config | | `--setup/--no-setup` | `true` | Run project setup after creation: npm/pnpm/yarn install, poetry/uv sync, cargo build, etc. Auto-detects project type | | `--copy-env/--no-copy-env` | `true` | Copy .env, .env.local, .env.example from main repo to worktree | | `--fetch/--no-fetch` | `true` | Run 'git fetch' before creating the worktree to ensure refs are up-to-date | | `--branch-name-mode` | `random` | How 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 --with-agent when supported, otherwise tries available agents in that order | +| `--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-timeout` | `20.0` | Timeout 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 --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 --agent | +| `--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. When started outside tmux, creates or reuses a detached session and reports the pane handle | | `--hooks/--no-hooks` | `true` | Run built-in agent preparation (like Codex auto-trust) and configured pre-launch hooks before starting the agent | | `--verbose, -v` | `false` | Stream output from setup commands instead of hiding it | @@ -100,22 +98,25 @@ agent-cli dev new [BRANCH] [OPTIONS] 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 --with-agent claude +agent-cli dev new feature --with-editor cursor --agent claude # Quick interactive dev environment with defaults from config -agent-cli dev new -e -a +agent-cli dev new -e --start-agent # Create dev environment with an initial prompt for the agent -agent-cli dev new fix-bug -a --prompt "Fix the login validation bug in auth.py" +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 -a --prompt-file task.md +agent-cli dev new refactor --prompt-file task.md -# Launch the agent in tmux even when you're not already inside tmux -agent-cli dev new feature -a -m tmux --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 ``` -For automated or headless use, pass `--prompt` or `--prompt-file` so the agent starts working immediately. A bare `-a` or `-m tmux` launch is mainly useful when a human plans to attach and drive the session interactively. +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. ### `dev list` @@ -292,7 +293,6 @@ agent-cli dev agent NAME [--agent/-a AGENT] [--agent-args ARGS] [--prompt/-p PRO | Option | Default | Description | |--------|---------|-------------| | `--agent, -a` | - | Which agent: claude, codex, gemini, aider, copilot, cn, opencode, cursor-agent. Auto-detects if omitted | -| `--with-agent` | - | [Deprecated: use --agent/-a] Which agent to start | | `--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 | @@ -582,7 +582,7 @@ commented-out starter block for `[dev]`, `[dev.agent_args]`, and [dev] # Default flags for 'dev new' command editor = true # Always open editor (-e) -agent = true # Always start agent (-a) +start_agent = true # Always start agent (--start-agent) auto_trust = true # Auto-trust supported agents before launch direnv = true # Always generate .envrc (--direnv) @@ -624,7 +624,7 @@ Or per-project in `agent-cli-config.toml`: ```toml [dev] editor = true -agent = true +start_agent = true direnv = true default_editor = "zed" default_agent = "aider" @@ -771,7 +771,7 @@ For fully headless orchestration, combine `--prompt-file` with `-m tmux`: ```bash for section in 1 2 3 4; do - agent-cli dev new "validate-$section" --from HEAD --agent --with-agent codex -m tmux \ + agent-cli dev new "validate-$section" --from HEAD --agent codex -m tmux \ --prompt-file ".claude/validate-$section.md" done ``` @@ -795,5 +795,5 @@ dcd() { - Use `agent-cli dev new` without arguments for quick experimentation - Run `agent-cli dev doctor` to verify your setup -- Combine `-e -a` flags to immediately start coding with AI assistance +- Combine `-e --start-agent` to immediately start coding with AI assistance - Use `--from` to branch from a specific tag or commit diff --git a/tests/dev/test_cli.py b/tests/dev/test_cli.py index 6b05913b..9491835e 100644 --- a/tests/dev/test_cli.py +++ b/tests/dev/test_cli.py @@ -330,8 +330,8 @@ def test_new_uses_ai_branch_name_when_enabled(self, tmp_path: Path) -> None: mock_ai.assert_called_once() mock_random.assert_not_called() - def test_new_uses_with_agent_for_branch_naming_when_supported(self, tmp_path: Path) -> None: - """When --branch-name-agent is omitted, --with-agent is used if supported.""" + def test_new_uses_agent_for_branch_naming_when_supported(self, tmp_path: Path) -> None: + """When --branch-name-agent is omitted, --agent is used if supported.""" wt_path = tmp_path / "repo-worktrees" / "feat-login-retry" wt_path.mkdir(parents=True) @@ -355,8 +355,74 @@ def test_new_uses_with_agent_for_branch_naming_when_supported(self, tmp_path: Pa ), ), patch("agent_cli.dev.cli.resolve_editor", return_value=None), - patch("agent_cli.dev.cli.resolve_agent", return_value=None), + patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent, + patch("agent_cli.dev.cli.prepare_agent_launch"), + patch("agent_cli.dev.cli.merge_agent_args", return_value=None), + patch("agent_cli.dev.cli.get_agent_env", return_value={}), + patch("agent_cli.dev.cli.launch_agent", return_value=None), + ): + mock_agent = mock_resolve_agent.return_value + mock_agent.is_available.return_value = True + result = runner.invoke( + app, + [ + "dev", + "new", + "--branch-name-mode", + "ai", + "--agent", + "codex", + "--no-setup", + "--no-copy-env", + "--no-fetch", + "--no-direnv", + ], + ) + + assert result.exit_code == 0 + mock_random.assert_not_called() + mock_ai.assert_called_once_with( + Path("/repo"), + set(), + None, + None, + "codex", + 20.0, + ) + + def test_new_with_agent_alias_warns_and_uses_agent(self, tmp_path: Path) -> None: + """Deprecated --with-agent should still work for now.""" + wt_path = tmp_path / "repo-worktrees" / "feat-login-retry" + wt_path.mkdir(parents=True) + + with ( + patch("agent_cli.dev.cli._ensure_git_repo", return_value=Path("/repo")), + patch("agent_cli.dev.worktree.list_worktrees", return_value=[]), + patch( + "agent_cli.dev.cli.generate_ai_branch_name", + return_value="feat/login-retry", + ) as mock_ai, + patch( + "agent_cli.dev.cli.generate_random_branch_name", + return_value="happy-fox", + ) as mock_random, + patch( + "agent_cli.dev.worktree.create_worktree", + return_value=CreateWorktreeResult( + success=True, + path=wt_path, + branch="feat/login-retry", + ), + ), + patch("agent_cli.dev.cli.resolve_editor", return_value=None), + patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent, + patch("agent_cli.dev.cli.prepare_agent_launch"), + patch("agent_cli.dev.cli.merge_agent_args", return_value=None), + patch("agent_cli.dev.cli.get_agent_env", return_value={}), + patch("agent_cli.dev.cli.launch_agent", return_value=None), ): + mock_agent = mock_resolve_agent.return_value + mock_agent.is_available.return_value = True result = runner.invoke( app, [ @@ -374,6 +440,7 @@ def test_new_uses_with_agent_for_branch_naming_when_supported(self, tmp_path: Pa ) assert result.exit_code == 0 + assert "deprecated" in result.output.lower() mock_random.assert_not_called() mock_ai.assert_called_once_with( Path("/repo"), @@ -518,8 +585,47 @@ def test_new_uses_dev_config_defaults_for_branch_naming(self, tmp_path: Path) -> ) assert mock_create.call_args.kwargs["fetch"] is False + def test_new_uses_start_agent_from_dev_config(self, tmp_path: Path) -> None: + """[dev].start_agent should trigger an interactive launch by default.""" + config_path = tmp_path / "config.toml" + config_path.write_text( + """[dev] +start_agent = true +setup = false +copy_env = false +fetch = false +direnv = false +""", + ) + wt_path = tmp_path / "repo-worktrees" / "feature" + wt_path.mkdir(parents=True) + + with ( + patch("agent_cli.dev.cli._ensure_git_repo", return_value=Path("/repo")), + patch( + "agent_cli.dev.worktree.create_worktree", + return_value=CreateWorktreeResult( + success=True, + path=wt_path, + branch="feature", + ), + ), + patch("agent_cli.dev.cli.resolve_editor", return_value=None), + patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent, + patch("agent_cli.dev.cli.prepare_agent_launch"), + patch("agent_cli.dev.cli.merge_agent_args", return_value=None), + patch("agent_cli.dev.cli.get_agent_env", return_value={}), + patch("agent_cli.dev.cli.launch_agent", return_value=None), + ): + mock_agent = mock_resolve_agent.return_value + mock_agent.is_available.return_value = True + result = runner.invoke(app, ["dev", "--config", str(config_path), "new", "feature"]) + + assert result.exit_code == 0 + assert mock_resolve_agent.call_args.args == (True, None, None) + def test_new_shows_tmux_handle_when_requested(self, tmp_path: Path) -> None: - """`dev new -m tmux` shows the returned tmux handle in the summary.""" + """`dev new --start-agent -m tmux` shows the returned tmux handle.""" wt_path = tmp_path / "repo-worktrees" / "feature" wt_path.mkdir(parents=True) @@ -551,7 +657,7 @@ def test_new_shows_tmux_handle_when_requested(self, tmp_path: Path) -> None: "dev", "new", "feature", - "-a", + "--start-agent", "-m", "tmux", "--no-setup", @@ -567,6 +673,47 @@ def test_new_shows_tmux_handle_when_requested(self, tmp_path: Path) -> None: assert "%42" in result.output assert "tmux attach -t agent-cli-repo-1234" in result.output + def test_new_short_start_agent_alias_warns(self, tmp_path: Path) -> None: + """Legacy `-a` should still work but warn to use --start-agent.""" + wt_path = tmp_path / "repo-worktrees" / "feature" + wt_path.mkdir(parents=True) + + with ( + patch("agent_cli.dev.cli._ensure_git_repo", return_value=Path("/repo")), + patch( + "agent_cli.dev.worktree.create_worktree", + return_value=CreateWorktreeResult( + success=True, + path=wt_path, + branch="feature", + ), + ), + patch("agent_cli.dev.cli.resolve_editor", return_value=None), + patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent, + patch("agent_cli.dev.cli.prepare_agent_launch"), + patch("agent_cli.dev.cli.merge_agent_args", return_value=None), + patch("agent_cli.dev.cli.get_agent_env", return_value={}), + patch("agent_cli.dev.cli.launch_agent", return_value=None), + ): + mock_agent = mock_resolve_agent.return_value + mock_agent.is_available.return_value = True + result = runner.invoke( + app, + [ + "dev", + "new", + "feature", + "-a", + "--no-setup", + "--no-copy-env", + "--no-fetch", + "--no-direnv", + ], + ) + + assert result.exit_code == 0 + assert "deprecated" in result.output.lower() + def test_new_fails_before_creating_worktree_when_no_agent_is_available( self, tmp_path: Path, @@ -586,7 +733,6 @@ def test_new_fails_before_creating_worktree_when_no_agent_is_available( "dev", "new", "my-feature", - "--agent", "--multiplexer", "tmux", "--prompt-file", @@ -603,6 +749,48 @@ def test_new_fails_before_creating_worktree_when_no_agent_is_available( assert "Success" not in result.output mock_create.assert_not_called() + def test_new_agent_auto_uses_auto_resolution(self, tmp_path: Path) -> None: + """`--agent auto` should launch with default/auto-detected resolution.""" + wt_path = tmp_path / "repo-worktrees" / "feature" + wt_path.mkdir(parents=True) + + with ( + patch("agent_cli.dev.cli._ensure_git_repo", return_value=Path("/repo")), + patch( + "agent_cli.dev.worktree.create_worktree", + return_value=CreateWorktreeResult( + success=True, + path=wt_path, + branch="feature", + ), + ), + patch("agent_cli.dev.cli.resolve_editor", return_value=None), + patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent, + patch("agent_cli.dev.cli.prepare_agent_launch"), + patch("agent_cli.dev.cli.merge_agent_args", return_value=None), + patch("agent_cli.dev.cli.get_agent_env", return_value={}), + patch("agent_cli.dev.cli.launch_agent", return_value=None), + ): + mock_agent = mock_resolve_agent.return_value + mock_agent.is_available.return_value = True + result = runner.invoke( + app, + [ + "dev", + "new", + "feature", + "--agent", + "auto", + "--no-setup", + "--no-copy-env", + "--no-fetch", + "--no-direnv", + ], + ) + + assert result.exit_code == 0 + assert mock_resolve_agent.call_args.args == (True, None, None) + def test_new_fails_before_creating_worktree_when_requested_agent_is_unavailable(self) -> None: """Unavailable explicit agents should abort before worktree creation.""" with ( @@ -622,7 +810,6 @@ def test_new_fails_before_creating_worktree_when_requested_agent_is_unavailable( "new", "my-feature", "--agent", - "--with-agent", "codex", "--no-setup", "--no-copy-env", @@ -690,7 +877,7 @@ def test_new_skips_launch_preparation_when_hooks_are_disabled(self, tmp_path: Pa "dev", "new", "feature", - "--agent", + "--start-agent", "--no-hooks", "--no-setup", "--no-copy-env", @@ -744,7 +931,7 @@ def test_new_uses_hooks_from_explicit_config_file(self, tmp_path: Path) -> None: str(config_path), "new", "feature", - "--agent", + "--start-agent", "--no-setup", "--no-copy-env", "--no-fetch", diff --git a/tests/test_docs_gen.py b/tests/test_docs_gen.py index addea298..85c6565d 100644 --- a/tests/test_docs_gen.py +++ b/tests/test_docs_gen.py @@ -75,6 +75,16 @@ def test_get_command_options_subcommand() -> None: assert len(options) > 0 +def test_get_command_options_dev_new_uses_start_agent_and_agent_name() -> None: + """dev.new should expose --start-agent and --agent, but hide deprecated aliases.""" + options = _get_command_options("dev.new") + names = {opt["name"] for opt in options} + assert "--start-agent" in names + assert "--agent" in names + assert "-a" not in names + assert "--with-agent" not in names + + # --- Tests for _options_table ---