Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]

### Added

- Add the official xAI Grok Build CLI as the `grok_cli` provider, including
isolated per-terminal MCP configuration, native hard tool restrictions,
multi-turn TUI support, orchestration e2e coverage, and provider docs.

### Fixed

- tmux listing parse failures are retried once and reported as a distinct condition instead of surfacing as a bare `ValueError` that reads like "session not found" one layer up. libtmux 0.53.1+ zips `parse_output`'s fields with `strict=True`, so any short row (a pane or session vanishing mid-listing, or trailing fields tmux omits) raised `ValueError: zip() argument 2 is shorter than argument 1` — which propagated through `server.sessions`/`window.panes`, blocked launches outright, and left the pipe-liveness watchdog unable to tell a genuinely-gone session from a transient parse failure. Adds `TmuxLookupError` and routes the listing reads in `clients/tmux.py` through a single retry-and-classify wrapper; a failed `create_session` no longer leaves an orphaned tmux session that blocks relaunching the same name. Also caps `libtmux<0.53.1`, the last release that zips non-strict (caom-anv)
Expand Down Expand Up @@ -842,4 +848,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- accept optional U+03BB (λ) after % in kiro and q CLIs (#44)


10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ Install:
[Codex CLI](docs/codex-cli.md), [Antigravity CLI](docs/antigravity-cli.md),
[Hermes](docs/hermes.md), [Kimi CLI](docs/kimi-cli.md),
[GitHub Copilot CLI](docs/copilot-cli.md),
[OpenCode CLI](docs/opencode-cli.md), or
[Cursor CLI](docs/cursor-cli.md)
[OpenCode CLI](docs/opencode-cli.md),
[Cursor CLI](docs/cursor-cli.md), or
[Grok Build CLI](docs/grok-cli.md)

The focused provider guides contain installation, authentication, and
provider-specific behavior.
Expand Down Expand Up @@ -130,8 +131,9 @@ provider override while keeping the same sequence.
[Codex CLI](docs/codex-cli.md), [Antigravity CLI](docs/antigravity-cli.md),
[Hermes](docs/hermes.md), [Kimi CLI](docs/kimi-cli.md),
[GitHub Copilot CLI](docs/copilot-cli.md),
[OpenCode CLI](docs/opencode-cli.md), and
[Cursor CLI](docs/cursor-cli.md).
[OpenCode CLI](docs/opencode-cli.md),
[Cursor CLI](docs/cursor-cli.md), and
[Grok Build CLI](docs/grok-cli.md).
- [Security policy](SECURITY.md): vulnerability reporting and deployment
guidance.

Expand Down
6 changes: 3 additions & 3 deletions docs/agent-profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ Provider support for pass-through fields differs. Use the focused guides for
[Kiro CLI](kiro-cli.md), [Claude Code](claude-code.md),
[Codex CLI](codex-cli.md), [Antigravity CLI](antigravity-cli.md),
[Hermes](hermes.md), [Kimi CLI](kimi-cli.md),
[GitHub Copilot CLI](copilot-cli.md), [OpenCode CLI](opencode-cli.md), and
[Cursor CLI](cursor-cli.md) instead of relying on a duplicated compatibility
catalog here.
[GitHub Copilot CLI](copilot-cli.md), [OpenCode CLI](opencode-cli.md),
[Cursor CLI](cursor-cli.md), and [Grok Build CLI](grok-cli.md) instead of
relying on a duplicated compatibility catalog here.

## Tool restrictions

Expand Down
223 changes: 223 additions & 0 deletions docs/grok-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
# Grok Build CLI Provider

## Overview

The `grok_cli` provider runs the official [xAI Grok Build
CLI](https://docs.x.ai/build) as a long-lived, multi-turn agent in a tmux
window. Community Grok command-line clients and direct xAI API wrappers are
not supported by this provider.

CAO launches Grok's interactive TUI with inline rendering, adds the selected
agent profile and CAO skill catalog as rules, and exposes CAO orchestration
tools through MCP. Grok's own subagent system is disabled so `assign` and
`handoff` remain the only agent-delegation paths in a CAO session.

The integration was developed and tested with Grok Build `1.0.0` and the
`grok-4.5` model. Newer Grok versions may change TUI markers or native tool
names; report status or extraction regressions with `grok --version` output.

## Prerequisites

- tmux 3.3 or later
- The official `grok` executable on `PATH`
- An authenticated Grok account or an xAI API key

Install the CLI using xAI's installer:

```bash
curl -fsSL https://x.ai/cli/install.sh | bash
grok --version
```

Authenticate once in a normal terminal before launching it through CAO:

```bash
grok login
grok models
```

For a remote machine without a browser, use `grok login --device-auth`. Grok
also accepts an API key from `XAI_API_KEY`:

```bash
export XAI_API_KEY="xai-..."
grok models
```

Do not put an API key in an agent profile or commit it to a repository.

## Quick Start

Start `cao-server`, then install and launch a profile for Grok:

```bash
cao install developer --provider grok_cli
cao launch --agents developer --provider grok_cli
```

Profile instructions use the normal Markdown format. The body is appended to
Grok's native system prompt with `--rules`, together with the runtime CAO skill
catalog. This preserves Grok's coding-agent behavior while applying the
profile's role and protocols.

Set a default model in profile frontmatter:

```yaml
---
name: grok_developer
description: Developer backed by Grok Build
provider: grok_cli
model: grok-4.5
role: developer
---

Implement the requested change and verify it.
```

An explicit launch override takes precedence:

```bash
cao launch --agents grok_developer --provider grok_cli --model grok-4.5
```

Use `grok models` to discover model IDs available to the authenticated
account.

## Runtime Behavior

The command has this shape:

```text
grok --no-alt-screen --always-approve --no-subagents \
[--model MODEL] [--rules RULES] [--deny RULE ...]
```

- `--no-alt-screen` keeps the rendered conversation observable by CAO.
- `--always-approve` prevents ordinary tool approval prompts from blocking
unattended orchestration.
- Native `--deny` rules still override auto-approval and provide hard tool
restrictions.
- `--no-subagents` prevents Grok-native workers from bypassing CAO roles,
permissions, callbacks, or terminal accounting.
- A single Enter submits bracketed-paste input. `/quit` exits the session.

The empty `❯` composer may remain visible while Grok is working. CAO therefore
prioritizes current `Waiting for response…` and `Esc:cancel` markers over the
composer. A settled turn has a `Worked for ...` boundary, which CAO also uses
to extract only the latest response in a multi-turn session.

## MCP Isolation

CAO creates a private Grok home for every terminal and launches Grok with
`GROK_HOME` pointing to it. The terminal root is mode `0700`; CAO writes its
generated config atomically with mode `0600`. It does not run `grok mcp add`
and does not modify the user's `~/.grok/config.toml`.

The isolated config contains the profile's MCP servers. CAO injects the
terminal-specific `CAO_TERMINAL_ID` into stdio MCP server environments so
`cao-mcp-server` can route `assign`, `handoff`, and `send_message` correctly.
Existing login state is reused without copying credential contents into CAO
logs or the repository. Generated state is removed when the terminal is
cleaned up.

A newly isolated home can show Grok's `Help improve Grok` telemetry choice.
The banner is non-blocking and is ignored by CAO's status and response
extraction logic.

## Tool Restrictions

Grok is a hard-enforcement provider. CAO translates missing capabilities into
native Grok deny rules:

| CAO capability | Grok tools denied when absent |
|---|---|
| `execute_bash` | `Bash` |
| `fs_read` | `Read`, `NotebookRead` |
| `fs_write` | `Edit`, `Write`, `NotebookEdit` |
| `fs_list` | `Grep`, `Glob` |
| `web_fetch` | `WebFetch`, `WebSearch`, with web search disabled |

`allowedTools: ["*"]` adds no restrictive deny rules. For a restricted role,
deny rules are applied alongside `--always-approve`; auto-approval does not
turn a denied tool back on. The provider also always passes `--no-subagents`
to close the native-subagent escape path.

`@cao-mcp-server` follows CAO's current shared MCP limitation: it records the
profile's orchestration intent, but individual MCP tools are not blocked at
the provider level. See [Tool Restrictions](tool-restrictions.md).

## Assign and Handoff Example

Install all profiles for this provider before running the full orchestration
example:

```bash
cao install examples/assign/data_analyst.md --provider grok_cli
cao install examples/assign/report_generator.md --provider grok_cli
cao install examples/assign/analysis_supervisor.md --provider grok_cli
cao launch --agents analysis_supervisor --provider grok_cli --auto-approve
```

`--auto-approve` skips CAO's launch confirmation but retains role-based tool
restrictions. Do not substitute `--yolo` when validating supervisor safety.

## Known Limitations

- The provider targets Grok Build's interactive TUI and currently requires the
tmux backend. Headless `-p` and ACP modes are not CAO transports.
- TUI parsing is calibrated against Grok Build 1.0.0. A future layout change
may require updated status and extraction fixtures.
- CAO reuses existing Grok authentication. Complete interactive login first;
CAO does not drive account or device-code login screens.
- Per-tool MCP gating is not available. `@cao-mcp-server` does not selectively
hide `assign`, `handoff`, or `send_message`.
- Grok-created non-secret files inside the private `0700` home can use their
own modes; the `0600` guarantee applies to CAO-authored config files.

## Troubleshooting

### Login or model errors

Run `grok login` and `grok models` outside CAO. On a headless host, use
`grok login --device-auth` or set `XAI_API_KEY`. If a profile selects an
unavailable model, replace it with an ID printed by `grok models`.

### MCP tools are missing or time out

Confirm `cao-mcp-server` is installed in the same environment as `cao-server`.
Inspect the Grok terminal for an MCP startup error, then recreate the terminal
so CAO regenerates its isolated config and terminal ID.

### Terminal remains processing

Attach to the tmux session and check whether Grok still shows
`Waiting for response…` or `Esc:cancel`. If Grok is visibly settled but CAO
does not report completion, include a scrubbed pane capture and `grok --version`
in the bug report.

### Permission or telemetry prompt is visible

The telemetry banner is non-blocking. An actual permission picker should be
reported as waiting for user input; answer it in tmux. Restricted tool calls
should be denied automatically rather than prompting.

### Broken rendering

Use tmux 3.3 or later and a normal color terminal such as
`TERM=xterm-256color` or `TERM=tmux-256color`. Verify `grok --no-alt-screen`
works in a standalone tmux pane.

## Validation

```bash
# Provider unit tests
uv run pytest test/providers/test_grok_cli_unit.py -v -o "addopts="

# All Grok lifecycle, permissions, skills, and orchestration e2e tests
uv run pytest -m e2e test/e2e/ -k Grok -v -o "addopts="

# Maintainer-required three-analyst workflow
uv run pytest -m e2e \
test/e2e/test_supervisor_orchestration.py \
-k GrokCliSupervisorOrchestration -v -o "addopts="
```
27 changes: 19 additions & 8 deletions docs/tool-restrictions.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,15 @@ The confirmation prompt is a **review gate** — it shows the resolved role and

CAO defines a universal tool vocabulary (`execute_bash`, `fs_read`, `fs_write`, `fs_list`). However, not all providers understand this vocabulary natively. There are two categories:

**Providers that need translation** — Claude Code and Copilot CLI each have their own native tool names (e.g., Claude Code calls bash execution `Bash`, Copilot calls it `shell`). CAO uses an internal `TOOL_MAPPING` to translate the CAO vocabulary to provider-native names, then computes which native tools to block and passes them as CLI flags (e.g., `--disallowedTools Bash`, `--deny-tool shell`).
**Providers that need translation** — Claude Code, Copilot CLI, and Grok Build CLI each have their own native tool names (e.g., Claude Code and Grok call bash execution `Bash`, while Copilot calls it `shell`). CAO uses an internal `TOOL_MAPPING` to translate the CAO vocabulary to provider-native names, then computes which native tools to block and passes them as CLI flags (e.g., `--disallowedTools Bash`, `--deny-tool shell`, or `--deny Bash`).

| CAO Tool | Claude Code | Copilot CLI |
|----------|-------------|-------------|
| `execute_bash` | `Bash` | `shell` |
| `fs_read` | `Read` | `read` |
| `fs_write` | `Edit`, `Write` | `write` |
| `fs_list` | `Glob`, `Grep` | `list`, `grep` |
| `web_fetch` | `WebFetch`, `WebSearch` | (not mapped) |
| CAO Tool | Claude Code | Copilot CLI | Grok Build CLI |
|----------|-------------|-------------|----------------|
| `execute_bash` | `Bash` | `shell` | `Bash` |
| `fs_read` | `Read` | `read` | `Read`, `NotebookRead` |
| `fs_write` | `Edit`, `Write` | `write` | `Edit`, `Write`, `NotebookEdit` |
| `fs_list` | `Glob`, `Grep` | `list`, `grep` | `Grep`, `Glob` |
| `web_fetch` | `WebFetch`, `WebSearch` | (not mapped) | `WebFetch`, `WebSearch` + disabled web search |

**Providers that accept CAO vocabulary directly** — Kiro CLI accepts `allowedTools` in the agent JSON at install time, using the same vocabulary as CAO. No translation needed. Kimi CLI and Codex use system prompt instructions to enforce restrictions. For all three, CAO passes the `allowedTools` list directly without translation — so no `TOOL_MAPPING` entry exists for them, and none is needed.

Expand Down Expand Up @@ -251,6 +251,7 @@ As described in [How Tool Restrictions Are Enforced](#how-tool-restrictions-are-
| **Kiro CLI** | Hard | `allowedTools` in agent JSON at install time |
| **Copilot CLI** | Hard | `--deny-tool` flags override `--allow-all` |
| **OpenCode CLI** | Hard | `permission:` YAML frontmatter enforced natively at install time |
| **Grok Build CLI** | Hard | Native `--deny` rules override `--always-approve`; native subagents are disabled |
| **Kimi CLI** | Soft | Security system prompt only |
| **Codex** | Soft | Security system prompt only |
| **Antigravity CLI** | Soft | Security system prompt only |
Expand Down Expand Up @@ -280,6 +281,16 @@ claude --dangerously-skip-permissions --disallowedTools Bash --disallowedTools E
copilot --allow-all --deny-tool shell --deny-tool write
```

**Grok Build CLI** — Adds native `--deny` rules alongside auto-approval and
disables Grok-native subagents:

```bash
grok --always-approve --no-subagents --deny Bash --deny Edit --deny Write
```

See the [Grok Build CLI provider guide](grok-cli.md#tool-restrictions) for the
complete mapping and isolation behavior.

**Kimi CLI / Codex** — Prepends to the system prompt:
```
You may ONLY use these tools: @cao-mcp-server, fs_read, fs_list
Expand Down
3 changes: 2 additions & 1 deletion examples/assign/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ cao launch --agents analysis_supervisor --provider codex
cao launch --agents analysis_supervisor --provider copilot_cli
cao launch --agents analysis_supervisor --provider cursor_cli
cao launch --agents analysis_supervisor --provider kimi_cli
cao launch --agents analysis_supervisor --provider grok_cli
```

## Usage
Expand Down Expand Up @@ -327,7 +328,7 @@ T=33s: Present final report

## E2E Testing

The `data_analyst` and `report_generator` profiles from this directory are used in the E2E test suite to validate assign and handoff flows across all providers (codex, claude_code, kiro_cli, kimi_cli).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thuanlm215 why are we crossing out the existing providers ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No intent to cross out any provider. That wording was corrected in the merge update at 4b19e7c; the README now says the examples validate the supported providers, including grok_cli. Thanks for catching it.

The `data_analyst` and `report_generator` profiles from this directory are used in the E2E test suite to validate assign and handoff flows across supported providers, including `grok_cli`.

```bash
# Install profiles for E2E testing
Expand Down
1 change: 1 addition & 0 deletions src/cli_agent_orchestrator/api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,7 @@ async def list_providers_endpoint() -> List[Dict]:
"opencode_cli": "opencode",
"cursor_cli": "agent",
"antigravity_cli": "agy",
"grok_cli": "grok",
}
result = []
for provider, binary in provider_binaries.items():
Expand Down
1 change: 1 addition & 0 deletions src/cli_agent_orchestrator/cli/commands/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"codex",
"copilot_cli",
"cursor_cli",
"grok_cli",
"hermes",
"kimi_cli",
"kiro_cli",
Expand Down
1 change: 1 addition & 0 deletions src/cli_agent_orchestrator/models/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ class ProviderType(str, Enum):
HERMES = "hermes"
CURSOR_CLI = "cursor_cli"
ANTIGRAVITY_CLI = "antigravity_cli"
GROK_CLI = "grok_cli"
# Credentials-free mock provider for tests/CI (no real CLI binary).
MOCK_CLI = "mock_cli"
Loading
Loading