Skip to content

feat: add built-in Grok CLI (xAI) agent plugin - #404

Open
djbclark wants to merge 1 commit into
subsy:mainfrom
djbclark:feat-grok-plugin
Open

feat: add built-in Grok CLI (xAI) agent plugin#404
djbclark wants to merge 1 commit into
subsy:mainfrom
djbclark:feat-grok-plugin

Conversation

@djbclark

@djbclark djbclark commented Aug 2, 2026

Copy link
Copy Markdown

Summary

Closes #402. Adds a built-in agent plugin for xAI's official grok CLI, following the project's own "Adding a New Agent Plugin" checklist in CONTRIBUTING.md.

  • src/plugins/agents/builtin/grok.ts — modeled on pi.ts/kimi.ts
  • Registered in builtin/index.ts, AGENT_ID_MAP in setup/skill-installer.ts
  • Docs (website/content/docs/plugins/agents/grok.mdx) + nav entry
  • 46 unit tests

Authenticates via the grok CLI's own OAuth session (SuperGrok subscription) — no separate API key required.

Test plan

  • bun run typecheck — clean
  • bun run build — clean
  • bun test src/plugins/agents/builtin/grok.test.ts — 46 pass
  • bun run dist/cli.js doctor --agent grok — HEALTHY (real preflight round-trip, not mocked)

Summary by CodeRabbit

  • New Features
    • Added support for the Grok CLI agent, including model selection, streaming output, tool calls, and platform-specific prompt handling.
    • Added Grok to built-in agent registration and skill installation.
  • Documentation
    • Added setup, authentication, configuration, usage, troubleshooting, and testing guidance for Grok.
    • Added the Grok agent page to the Plugins → Agents navigation.

Integrate xAI's official grok CLI as a built-in agent plugin for
ralph-tui autonomous loops. Uses --always-approve, streaming-json
output, and stdin prompt delivery via --prompt-file /dev/stdin.

Verified with: bun run typecheck, bun run build, unit tests, and
ralph-tui doctor --agent grok (HEALTHY).
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

@djbclark is attempting to deploy a commit to the plgeek Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a built-in Grok CLI agent with streaming JSONL parsing, tool-event handling, platform-specific prompt delivery, setup validation, registration, skill installation mapping, tests, and documentation.

Changes

Grok agent integration

Layer / File(s) Summary
Streaming event parsing and execution
src/plugins/agents/builtin/grok.ts, src/plugins/agents/builtin/grok.test.ts
Parses Grok JSONL events into text, tool-use, tool-result, and error events. Buffers incomplete lines and flushes pending output.
Plugin lifecycle and command construction
src/plugins/agents/builtin/grok.ts, src/plugins/agents/builtin/grok.test.ts
Adds metadata, detection, setup validation, sandbox requirements, model settings, CLI arguments, prompt transport, and lifecycle tests.
Built-in registration and skill mapping
src/plugins/agents/builtin/index.ts, src/setup/skill-installer.ts
Registers and exports the Grok plugin and adds its skill-installer mapping.
Grok agent documentation
website/content/docs/plugins/agents/grok.mdx, website/lib/navigation.ts
Adds Grok setup, configuration, execution, streaming, troubleshooting, smoke-test documentation, and navigation. Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RalphTUI
  participant GrokAgentPlugin
  participant GrokCLI
  RalphTUI->>GrokAgentPlugin: initialize and validate Grok setup
  GrokAgentPlugin->>GrokCLI: invoke grok with streaming JSON flags
  GrokAgentPlugin->>GrokCLI: send prompt through stdin or -p
  GrokCLI-->>GrokAgentPlugin: return JSONL events
  GrokAgentPlugin-->>RalphTUI: emit parsed display events
Loading

Possibly related PRs

  • subsy/ralph-tui#185: Both plugins buffer JSONL output from streaming CLI processes.
  • subsy/ralph-tui#306: Both changes add a built-in CLI agent with parsing, registration, skill mapping, tests, and documentation.
  • subsy/ralph-tui#344: Both changes add a built-in CLI agent with JSONL handling, registration, tests, skill mapping, and documentation.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding a built-in Grok CLI agent plugin.
Linked Issues check ✅ Passed The implementation satisfies issue #402 by adding, registering, testing, and documenting native Grok CLI support with detection, model passthrough, and streaming output parsing.
Out of Scope Changes check ✅ Passed The changes are limited to the Grok plugin, registration, skill mapping, tests, documentation, and navigation required by issue #402.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
src/plugins/agents/builtin/grok.ts (3)

407-413: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify validateModel.

Every path returns null. The empty-string branch has no effect. Reduce the body to a single return null and keep the comment that explains why Grok model IDs are not validated.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/plugins/agents/builtin/grok.ts` around lines 407 - 413, Simplify the Grok
validateModel method by removing the redundant empty-string check and retaining
a single return null statement. Preserve the existing comment explaining why
Grok model IDs are not validated.

309-340: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the shared emit logic.

flushBuffer and the wrapped onStdout contain the same parse-and-emit block. Extract one helper that accepts a string and emits onJsonlMessage, segments, and formatted text. This removes the duplication and keeps both paths in sync.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/plugins/agents/builtin/grok.ts` around lines 309 - 340, Extract the
duplicated parse-and-emit logic from flushBuffer and the wrapped onStdout into a
shared helper that accepts the output string and invokes onJsonlMessage,
onStdoutSegments, and onStdout as applicable. Update both paths to call this
helper, preserving their existing buffering and trimming behavior while keeping
event handling synchronized.

184-223: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Declare timer before safeResolve.

safeResolve reads timer, which is declared at Line 220. The current code is safe because the process events fire asynchronously. If a future change calls safeResolve synchronously, a temporal dead zone error occurs. Move the declaration above the handlers.

Also consider using process.platform and platform() consistently across the file; buildArgs uses platform() from node:os while this method uses process.platform.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/plugins/agents/builtin/grok.ts` around lines 184 - 223, Move the timer
declaration before safeResolve and the process event handlers so safeResolve
cannot access timer before initialization if invoked synchronously. In the same
file, make the platform check in this method consistent with buildArgs by
reusing the existing node:os platform() approach rather than process.platform.
src/plugins/agents/builtin/grok.test.ts (2)

346-404: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the streaming buffer in execute.

The tests cover the pure parsers only. The chunk-splitting buffer, the flushBuffer call on onEnd, and onJsonlMessage forwarding in execute carry the real risk in grok.ts. Add tests that feed a JSON object split across two onStdout chunks and assert that exactly one parsed event reaches the callback.

Do you want me to generate these tests?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/plugins/agents/builtin/grok.test.ts` around lines 346 - 404, Add tests
for execute that split one JSON object across two onStdout chunks and verify the
callback receives exactly one parsed event after buffering completes. Also cover
that onEnd invokes flushBuffer and that onJsonlMessage forwards parsed events,
using the existing parseGrokOutputToEvents test setup and execute-related
symbols.

187-201: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The Windows branch is never exercised.

This test branches on process.platform, so CI on Linux only covers the --prompt-file path. Extract the platform decision into an injectable or overridable member, then assert both branches deterministically.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/plugins/agents/builtin/grok.test.ts` around lines 187 - 201, Update the
platform-dependent logic used by testBuildArgs and testGetStdinInput in
TestableGrokPlugin to rely on an injectable or overridable platform value
instead of directly reading process.platform. Modify the test to instantiate or
configure the plugin for both Windows and non-Windows platforms, asserting each
branch deterministically.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/content/docs/plugins/agents/grok.mdx`:
- Around line 125-126: Update the Grok CLI command documentation to use the
supported -p/--prompt argument instead of --prompt-file /dev/stdin, including
the command construction and prompt-passing explanation near the later execution
example. Keep the prompt unescaped and ensure all documented command paths
consistently use the supported argument.
- Around line 137-143: Remove the trailing comments from the backslash-continued
Grok CLI lines in the command example, moving any needed explanations above the
command or omitting them. Ensure each continuation backslash is the final
character before the newline so the Bash command remains valid.

---

Nitpick comments:
In `@src/plugins/agents/builtin/grok.test.ts`:
- Around line 346-404: Add tests for execute that split one JSON object across
two onStdout chunks and verify the callback receives exactly one parsed event
after buffering completes. Also cover that onEnd invokes flushBuffer and that
onJsonlMessage forwards parsed events, using the existing
parseGrokOutputToEvents test setup and execute-related symbols.
- Around line 187-201: Update the platform-dependent logic used by testBuildArgs
and testGetStdinInput in TestableGrokPlugin to rely on an injectable or
overridable platform value instead of directly reading process.platform. Modify
the test to instantiate or configure the plugin for both Windows and non-Windows
platforms, asserting each branch deterministically.

In `@src/plugins/agents/builtin/grok.ts`:
- Around line 407-413: Simplify the Grok validateModel method by removing the
redundant empty-string check and retaining a single return null statement.
Preserve the existing comment explaining why Grok model IDs are not validated.
- Around line 309-340: Extract the duplicated parse-and-emit logic from
flushBuffer and the wrapped onStdout into a shared helper that accepts the
output string and invokes onJsonlMessage, onStdoutSegments, and onStdout as
applicable. Update both paths to call this helper, preserving their existing
buffering and trimming behavior while keeping event handling synchronized.
- Around line 184-223: Move the timer declaration before safeResolve and the
process event handlers so safeResolve cannot access timer before initialization
if invoked synchronously. In the same file, make the platform check in this
method consistent with buildArgs by reusing the existing node:os platform()
approach rather than process.platform.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4d33945a-210d-4033-bb70-6699f4bbdd11

📥 Commits

Reviewing files that changed from the base of the PR and between 8191b80 and 7c70c04.

📒 Files selected for processing (6)
  • src/plugins/agents/builtin/grok.test.ts
  • src/plugins/agents/builtin/grok.ts
  • src/plugins/agents/builtin/index.ts
  • src/setup/skill-installer.ts
  • website/content/docs/plugins/agents/grok.mdx
  • website/lib/navigation.ts

Comment on lines +125 to +126
1. **Build command**: Constructs `grok --always-approve --output-format streaming-json --prompt-file /dev/stdin [options]`
2. **Pass prompt via stdin**: Uses `--prompt-file /dev/stdin` (Grok does not read bare stdin) so the prompt is not shell-escaped

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 3 -- 'prompt-file|--single|-p|stdin' \
  src/plugins/agents/builtin/grok.ts \
  src/plugins/agents/builtin/grok.test.ts \
  website/content/docs/plugins/agents/grok.mdx

if command -v grok >/dev/null 2>&1; then
  grok --help 2>&1 | rg -n -C 3 -- 'prompt-file|--single|-p' || true
fi

Repository: subsy/ralph-tui

Length of output: 10606


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect Grok metadata/version constraints and any supported-CLI checks.
rg -n -C 2 -- 'grok|Grok|packageManager|pnpm|node-version|engine|required' \
  package.json pnpm-lock.yaml package-lock.json yarn.lock bun.lockb 2>/dev/null || true

printf '\n--- candidate files ---\n'
git ls-files | rg '(^|/)(package\.json|pnpm-lock\.yaml|package-lock\.json|yarn\.lock|bun\.lockb|.*[Gg]rok.*|.*agent.*)$' | sed -n '1,120p'

Repository: subsy/ralph-tui

Length of output: 40123


🌐 Web query:

xAI grok CLI --prompt-file /dev/stdin -p --single prompt-file

💡 Result:

The command xAI grok CLI --prompt-file /dev/stdin --single prompt-file does not exist as a standard command in the official xAI Grok Build CLI [1][2]. The official xAI Grok Build CLI uses the grok command [2]. For headless or scriptable execution, the standard method to pass a prompt is using the -p or --prompt flag [2]. If you are attempting to pass input from stdin, common patterns for CLI tools involve piping text or using specific flags, but the official Grok CLI does not support a --prompt-file flag [1][2]. Based on the official documentation, you can run prompts headlessly using: echo "Your prompt here" | grok -p "$(cat -)" or simply: grok -p "Your prompt here" It is important to note that many third-party community-developed CLI tools for Grok exist (e.g., grok-cli repositories on GitHub) [3][4][5][6][7]. These third-party tools are distinct from the official xAI Grok Build CLI and may have different syntax or features [7]. If you are using one of these community tools, please consult the --help output of your specific installed binary (e.g., grok-cli --help) to verify supported flags, as they do not share a unified interface [8][3][4].

Citations:


Use the supported Grok CLI prompt argument.

--prompt-file /dev/stdin is not a Grok Build CLI option. On Unix, pass the prompt with -p/--prompt instead, or add a required Grok version that supports --prompt-file; otherwise the documented execution path will fail on the supported CLI. Also applies to website/content/docs/plugins/agents/grok.mdx lines 140-142.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/content/docs/plugins/agents/grok.mdx` around lines 125 - 126, Update
the Grok CLI command documentation to use the supported -p/--prompt argument
instead of --prompt-file /dev/stdin, including the command construction and
prompt-passing explanation near the later execution example. Keep the prompt
unescaped and ensure all documented command paths consistently use the supported
argument.

Comment on lines +137 to +143
grok \
--always-approve \ # Auto-approve tool executions
--output-format streaming-json \ # Structured NDJSON for parsing
--prompt-file /dev/stdin \ # Read prompt from stdin (Unix)
--model grok-4.5 \ # If model specified
< prompt.txt
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf 'File excerpt:\n'
sed -n '125,150p' website/content/docs/plugins/agents/grok.mdx | cat -n

printf '\nBackslash-newline behavior probe:\n'
bash -c '
line1="grok \ \ \ \ --always-approve"
line2="  --output-format streaming-json"
printf "%s\n%s\n" "$line1" "$line2"
bash -n <<BASH
$line1
$line2
BASH
status=$?
if [ "$status" -eq 0 ]; then
  echo "parse succeeded"
else
  echo "parse failed"
fi
' 2>&1 || true

printf '\nRelevant line backslash context:\n'
python3 - <<'PY'
from pathlib import Path
path = Path("website/content/docs/plugins/agents/grok.mdx")
lines = path.read_text().splitlines()
for i in [138,139,140,141,142]:
    if 1 <= i <= len(lines):
        s = repr(lines[i-1])
        print(f"{i}: {s}")
PY

Repository: subsy/ralph-tui

Length of output: 1951


🏁 Script executed:

#!/bin/bash
set -e
printf 'Markdown code fence line before artifact:\n'
sed -n '115,125p' website/content/docs/plugins/agents/grok.mdx | cat -n

printf '\nLine lengths and trailing whitespace around snippet:\n'
python3 - <<'PY'
from pathlib import Path
lines = Path("website/content/docs/plugins/agents/grok.mdx").read_text().splitlines()
for i in range(120, 155):
    s = lines[i-1]
    print(f"{i:4}: len={len(s):3} rws={len(s)-len(s.rstrip()):2} trail_mark={((s.rstrip() if s.strip() else '')}.rstrip())[-10:] if s.strip() else '<empty>'")
PY

Repository: subsy/ralph-tui

Length of output: 1063


🏁 Script executed:

#!/bin/bash
set -e
exec 3>&1

printf 'Markdown code fence line before artifact:\n'
sed -n '115,135p' website/content/docs/plugins/agents/grok.mdx | cat -n >&3

printf '\nLine lengths and trailing behavior around snippet:\n'
python3 - <<'PY'
from pathlib import Path
lines = Path("website/content/docs/plugins/agents/grok.mdx").read_text().splitlines()
for i in range(120, 155):
    s = lines[i-1]
    rws = len(s) - len(s.rstrip())
    trailing = s.rstrip()[-12:] if s.strip() else '<empty>'
    print(f"{i:4}: len={len(s):3} trailing_ws={rws:2} trailing_mark={trailing}")
PY

printf '\nMinimal bash continuation examples:\n'
bash <<'BASH'
set -v
echo 'case with comment after backslash:'
cmd="/bin/echo"
cmd="/bin/echo" \      # comment
  "hello" \
  "world"
"$cmd" "$cmd"
echo "status=$?"
BASH

bash <<'BASH'
set -v
echo 'case without comment after backslash:'
cmd="/bin/echo"
cmd="/bin/echo" \
  "hello" \
  "world"
"$cmd" "$cmd"
echo "status=$?"
BASH

bash <<'BASH'
set -v
echo 'case with comment without spaces before newline:'
cmd="/bin/echo"
cmd="/bin/echo" \
# comment
  "hello" \
  "world"
"$cmd" "$cmd"
echo "status=$?"
BASH

Repository: subsy/ralph-tui

Length of output: 3808


Remove trailing comments from continued lines.

Bash only treats a backslash as a newline when it appears before the newline. Lines 138-141 keep the continuation backslash, so the shell continues to the next text line as a new command. Move the # comments above these lines or remove them from the continued lines.

Proposed fix
 grok \
-  --always-approve \                 # Auto-approve tool executions
-  --output-format streaming-json \   # Structured NDJSON for parsing
-  --prompt-file /dev/stdin \         # Read prompt from stdin (Unix)
-  --model grok-4.5 \                 # If model specified
+  --always-approve \
+  --output-format streaming-json \
+  --prompt-file /dev/stdin \
+  --model grok-4.5 \
   < prompt.txt
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
grok \
--always-approve \ # Auto-approve tool executions
--output-format streaming-json \ # Structured NDJSON for parsing
--prompt-file /dev/stdin \ # Read prompt from stdin (Unix)
--model grok-4.5 \ # If model specified
< prompt.txt
```
grok \
--always-approve \
--output-format streaming-json \
--prompt-file /dev/stdin \
--model grok-4.5 \
< prompt.txt
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/content/docs/plugins/agents/grok.mdx` around lines 137 - 143, Remove
the trailing comments from the backslash-continued Grok CLI lines in the command
example, moving any needed explanations above the command or omitting them.
Ensure each continuation backslash is the final character before the newline so
the Bash command remains valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add native agent plugin for Grok / xAI CLI

1 participant