Codeman can drive Grok Build (xAI's grok
CLI, the agent behind docs.x.ai/build) as a session backend, alongside Claude Code,
OpenCode, Codex, Gemini, Antigravity and Pi. grok is a seventh run mode: its own
PTY, its own tmux session, its own tab identity (monochrome charcoal, gk badge). It
is not a location overlay like Docker or remote-SSH cases, and it is not a web tab.
The design rationale behind each decision below lives in
grok-integration-plan.md. Everything here was verified
against grok 1.0.5.
curl -fsSL https://x.ai/cli/install.sh | bashThe installer places the binary in ~/.grok/bin and symlinks it into ~/.local/bin
(it also installs an agent alias Codeman ignores). grok update self-updates.
Codeman resolves the binary via the server PATH and then the usual install locations,
~/.grok/bin first. grok is a name with known squatters (the unrelated
@vibe-kit/grok-cli npm package also installs a grok bin), so like pi the
resolver does not trust a PATH hit on its own: it runs grok --version once and
requires version-shaped output (grok 1.0.5 (5115b46bc9)). Check what it resolved:
curl -s localhost:3000/api/grok/status | jq
# { "available": true, "path": "/home/you/.grok/bin", "version": "1.0.5" }The endpoint carries version on top of the sibling /api/*/status shape precisely
so a misresolution is visible rather than presenting as "the mode just doesn't work".
- Browser OAuth (default): the first
grokrun opens a sign-in flow; in a Codeman pane you get the device-code screen with a URL to open elsewhere. Credentials land in~/.grok/auth.json(0600) and refresh automatically. - Device code:
grok login --device-auth, made for SSH boxes and headless hosts. - API key:
export XAI_API_KEY="xai-..."(console.x.ai). Used as a fallback when no session token exists. As a per-session CodemanenvOverrideit flows through socket-scopedtmux setenv, never the spawn command line. - Enterprise OIDC:
GROK_OIDC_ISSUER/GROK_OIDC_CLIENT_ID.
GrokConfig (per session, persisted in state.json, round-trips through respawn):
| Field | Flag | Notes |
|---|---|---|
model |
--model <v> |
e.g. grok-4.5, or a custom [model.<name>] from config.toml |
alwaysApprove |
--always-approve |
Grok's bypassPermissions mode; deny rules still apply on top |
continueSession |
--continue |
Most recent session for the working directory; skipped when resuming |
resumeSessionId |
--resume <v> |
Ids only, never titles (grok's own --resume also matches titles) |
Every value is regex-validated and dropped (not escaped) if it fails, because the
result is interpolated into the pane's bash -c "..." command.
The Run button sends grokConfig: { alwaysApprove: true }, the same product decision
as Claude's --dangerously-skip-permissions default and Antigravity's
--dangerously-skip-permissions: Codeman sessions exist for autonomous work. Keep
hard limits as deny rules in ~/.grok/config.toml (they apply in every mode), and
in multi-user mode a non-granted owner's alwaysApprove is forced off
server-side; a bare grok spawn is grok's own ask-mode default.
Env overrides: the GROK_* prefix (GROK_HOME, GROK_CONFIG, GROK_MEMORY,
GROK_WORKFLOWS, GROK_SANDBOX, GROK_OIDC_*, ...) plus the XAI_* vendor
namespace (XAI_API_KEY) are allowlisted. Foreign provider keys are not, as ever.
--permission-mode,--allow/--deny. The boolean covers the autonomous case; the full rule surface is a follow-up with UI.-p/headless,--output-format,--json-schema. Codeman drives the TUI.--worktree,--sandbox,--reasoning-effort,-s/--session-id,--fork-session,--agent/--agents. Tracked as follow-ups in the plan doc.
Grok renders a fullscreen alternate-screen TUI (scrollback pane + prompt, mouse
supported). Under Codeman it runs inside tmux like every external CLI, so the
fullscreen rendering stays inside the pane and the browser terminal shows tmux's
repaints; grok stays out of the alt-screen strip list on purpose (the opencode case,
not the Ink case). If a pane renders oddly, grok doctor checks terminal, color and
input support without starting a session, and ~/.grok/pager.toml can force
alt_screen = "inline".
On touch devices grok currently gets the buffered local-echo overlay like Claude,
Gemini, OpenCode and Pi. This is the fallthrough default and has not been measured
against an authenticated grok composer; if grok turns out per-keystroke reactive the
way codex was (issues #218/#219/#220/#222), the fix is the 'off' branch in
_updateLocalEchoState (terminal-ui.js).
The agent image installs grok in its own Dockerfile step (not npm; xAI's installer
targets $HOME/.grok/bin with no --dir override, so the binary is copied to
/usr/local/bin). Rebuild with the mandatory --no-cache:
node scripts/build-agent-image.mjs --no-cacheCredentials are seeded, not shared: auth.json, config.toml and pager.toml
are copied into the container's own ~/.grok, so an in-container grok never writes
refreshed OAuth tokens back to the host and docker commit exports stay secret-free.
Only those three files, because ~/.grok also holds sessions/, memory/ and the
~160MB binary under downloads/. Trade-off, same as pi: in-container sessions are
invisible host-side, so grok -c inside a Docker case only sees that container's own
history.
grok mode is routed through an interactive login shell
(exec "$SHELL" -i -l -c 'grok'), because sshd's remote-command PATH does not include
~/.grok/bin. Per-session config and envOverrides do not cross ssh and are rejected
rather than silently ignored; use the per-host command override instead. For auth on
the remote host, grok login --device-auth exists for exactly this.
- No idle/completion hook yet. Idle detection falls back to output-stabilization
like the other external CLIs. Grok has a hooks system, so a Codeman hook POSTing to
/api/hook-eventis the highest-value follow-up. - No response viewer. Grok writes ACP JSONL sessions under
~/.grok/sessions/<encoded-cwd>/<session-id>/updates.jsonl; nothing reads them yet. - Cron jobs mis-detect readiness. The readiness poll looks for
❯or a token count, neither of which grok prints, so a grok cron job burns its poll budget and then sends the prompt anyway. It works; it is just slower to start. - Ralph, respawn heuristics, token/CLI-info parsing and the
❯readiness probe are off for grok, as for every external CLI.