Connect Grok Build as a first-class coding agent

SH
1d ago
+704-471

Grok Build can now be connected the same way Codex is.

hey setup grok copies the HEY skill into $GROK_HOME/skills/hey (default ~/.grok/skills/hey). hey skill install, skill refresh, hey doctor, hey setup agents, and --remove all include Grok. There is no Grok plugin. Health is skill presence only, matching Codex.

HEY_SETUP_AGENT accepts grok. all attempts every registered agent, including Grok. Detection uses $GROK_HOME or ~/.grok, or a grok binary on PATH, matching Codex.

Session-settled decisions carried from planning: Grok matches Codex, not Claude — no .grok-plugin (user-directed); detect via $GROK_HOME/~/.grok or the grok binary (user-approved); HEY_SETUP_AGENT=all uses AllAgents() so Grok is always attempted (user-approved).

Tests

  • make test passed locally (go test ./internal/...)

What changed since review

Rebased onto main twice. The first pass moved this PR's README paragraphs to where main put them (docs/agents.md, docs/cli.md; the README keeps a hey setup grok line beside hey setup codex). The second absorbed #385, which changed what "Grok matches Codex" means: Codex no longer gets a copy in ~/.codex/skills/hey — it discovers the shared ~/.agents/skills/hey directly, hey setup codex confirms that skill and migrates a hey-cli-marked legacy copy away, and doctor fails on a managed duplicate. xAI's docs say Grok reads ~/.agents/skills/ too, so Shawn's first commit is ported to that shape: hey setup grok installs the shared skill and confirms it; nothing is written under ~/.grok. His authorship and dates are intact; the commit body says how it was ported.

One follow-up commit folds the copy: Codex and Grok differ only in name, id, home env var, home directory and binary, so they are two rows of one harness.SkillAgent table (internal/harness/skill_agent.go) instead of two files, and everything in internal/cmd that touches a shared-skill agent — the setup handlers, hey skill install, refresh, --remove, the HEY_SETUP_AGENT values, #385's legacy-copy migration — loops over harness.SkillAgents() rather than naming each. AgentInfo gains FindBinary so setup's "binary not found" remediation reads the registry instead of a switch on ids. The tests fold the same way: one table-driven test per behavior, run once per agent, so Copilot's binary-only detection case and #385's migration cases now cover both.

Facts checked against xAI's sources, since the code models Grok on Codex:

  • GROK_HOME overrides ~/.grok — docs.x.ai/build/settings ("To configure the default home directory, you can set $GROK_HOME"); xai-org/grok-build xai-dirs: $GROK_HOME verbatim when non-empty, else <home>/.grok.
  • Grok reads the cross-agent ~/.agents/skills/ — docs.x.ai/build/features/skills-plugins-marketplaces, "Agents.md compatibility": Grok "discovers user-level skills and commands from ~/.agents/skills/"; the loader in xai-grok-agent/src/prompt/skills.rs adds home.join(".agents") alongside grok_home. That is why the shared skill is enough and no ~/.grok/skills/hey copy is made (Grok dedups skills by name, so a copy would be redundant rather than doubled, but it would still be a second file to keep in sync).
  • ~/.grok/skills/<name>/SKILL.md is also a documented user-level location, which is why a hey-cli-marked copy there is treated as a legacy duplicate the same way ~/.codex/skills/hey is.
  • Both official installers put the binary at ~/.grok/bin/grok (x.ai/cli/install.sh: BIN_DIR="${GROK_BIN_DIR:-$HOME/.grok/bin}"; the @xai-official/grok npm postinstall writes $GROK_HOME/bin), which is why FindBinary looks in the agent home's bin after PATH and ~/.local/bin — for both rows.
  • A .grok-plugin/plugin.json manifest exists as a fallback behind a root plugin.json, so "no Grok plugin yet" is a statement about this repo, not about Grok.

The five install_ssh_key.bats cases fail locally on macOS (stat -c) on main as well; unrelated to this PR and green on CI's Linux runners.


Summary by cubic

Connects Grok Build as a first-class coding agent, the same way Codex works. Codex and Grok now share one harness.SkillAgent table, so adding a new skill-only agent is a new row instead of a near-copy of the Codex file.

  • hey setup grok installs the shared skill; hey skill install, refresh, hey doctor, hey setup agents, and --remove all include Grok.
  • HEY_SETUP_AGENT accepts grok, and all now attempts every registered agent.
  • Grok is detected via $GROK_HOME/~/.grok or a grok binary on PATH, ~/.local/bin, or the agent home's bin.
  • Grok health is skill presence only — there is no Grok plugin yet.
  • Setup, hey skill install, refresh, and doctor treat a hey-cli-marked copy in either agent's own skills directory as a managed duplicate and migrate it away.