Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ vp run codex
vp run vibe # alias of devstral
```

Extra arguments after the agent are forwarded to the agent process. Use `--`
before agent flags so VibePod does not parse them as its own options:

```bash
vp run <agent> -- <agent-args>
```

## IKWID Mode (`--ikwid`)

Use `--ikwid` to append each agent's auto-approval / permission-skip flag when supported.
Expand Down
17 changes: 17 additions & 0 deletions docs/agents/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,23 @@ agents:
MY_VAR: value
```

## Passing arguments to the agent

Any extra arguments after the agent name are appended to the agent command inside the container:

```bash
vp run <agent> <agent-args>
```

Use `--` before agent flags so VibePod does not parse them as its own options:

```bash
vp run <agent> -- <agent-flag> <value>
```

For concrete syntax, check the agent's own CLI help. For example, Claude and
Codex both accept model flags, but their exact flag names and values differ.

## Init scripts before startup

Use `agents.<agent>.init` to run shell commands in the container before the agent launches. This is useful for installing extra tools in a custom image workflow.
Expand Down
14 changes: 14 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ Use `-w` / `--workspace` to target any directory:
vp run claude -w ~/other-project
```

## Pass arguments to the agent

Arguments after the agent name are forwarded to the agent command inside the container:

```bash
vp run <agent> <agent-args>
```

When forwarding flags to the agent, use `--` to stop VibePod option parsing:

```bash
vp run <agent> -- <agent-flag> <value>
```

## Bootstrap a project config

Create a project-level config file that you can extend later:
Expand Down
3 changes: 2 additions & 1 deletion src/vibepod/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ def run(
"""Start an agent container.

Any trailing arguments after the agent name are forwarded to the agent's
command inside the container, e.g. `vp run claude setup-token`.
command inside the container. Use `--` before agent flags when they could
be parsed as VibePod flags.
"""
click_ctx = click.get_current_context(silent=True)
passthrough_args: list[str] = (
Expand Down
18 changes: 18 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,21 @@ def _fake_run(agent=None, **kwargs) -> None: # noqa: ANN001, ANN003, ARG001
assert result.exit_code == 0
assert called["agent"] == "claude"
assert called["passthrough"] == ["setup-token"]


def test_alias_forwards_extra_option_args_after_delimiter(monkeypatch) -> None:
called: dict[str, object] = {"agent": None, "passthrough": None}

def _fake_run(agent=None, **kwargs) -> None: # noqa: ANN001, ANN003, ARG001
import click

ctx = click.get_current_context(silent=True)
called["agent"] = agent
called["passthrough"] = list(ctx.args) if ctx and ctx.args else []

monkeypatch.setattr(run_cmd, "run", _fake_run)

result = runner.invoke(app, ["claude", "--", "--model", "sonnet", "hello"])
assert result.exit_code == 0
assert called["agent"] == "claude"
assert called["passthrough"] == ["--model", "sonnet", "hello"]
58 changes: 58 additions & 0 deletions tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

import pytest
import typer
from typer.testing import CliRunner

from vibepod.cli import app
from vibepod.commands import run as run_cmd
from vibepod.constants import EXIT_DOCKER_NOT_RUNNING
from vibepod.core.docker import DockerClientError, DockerManager
Expand Down Expand Up @@ -470,6 +472,62 @@ def _make_config(
}


def test_cli_run_forwards_extra_args_to_agent_command(monkeypatch, tmp_path: Path) -> None:
"""Extra args after -- are appended to the agent command as-is."""
captured: dict = {}

class _CapturingDockerManager:
def ensure_network(self, name: str) -> None:
pass

def networks_with_running_containers(self) -> list[str]:
return []

def pull_image(self, image: str) -> None:
pass

def ensure_proxy(self, **kwargs) -> None: # type: ignore[no-untyped-def]
pass

def run_agent(self, **kwargs) -> object: # type: ignore[no-untyped-def]
captured.update(kwargs)
container = type(
"_Container",
(),
{
"name": "vibepod-claude-test",
"id": "abc123",
"status": "running",
"attrs": {"NetworkSettings": {"Networks": {}}},
"reload": lambda self: None,
"labels": {},
"logs": lambda self, **kw: b"",
},
)()
return container

monkeypatch.setattr(run_cmd, "get_config", lambda: _make_config())
monkeypatch.setattr(run_cmd, "DockerManager", _CapturingDockerManager)

result = CliRunner().invoke(
app,
[
"run",
"-d",
"-w",
str(tmp_path),
"claude",
"--",
"--model",
"sonnet",
"hello world",
],
)

assert result.exit_code == 0, result.output
assert captured["command"] == ["claude", "--model", "sonnet", "hello world"]


def test_auto_pull_global_triggers_pull(monkeypatch, tmp_path: Path) -> None:
"""Global auto_pull=true causes image pull on run."""
stub = _StubDockerManager()
Expand Down
Loading