Connect Grok Build as a first-class coding agent
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 testpassed 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_HOMEoverrides~/.grok— docs.x.ai/build/settings ("To configure the default home directory, you can set$GROK_HOME");xai-org/grok-buildxai-dirs:$GROK_HOMEverbatim 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 inxai-grok-agent/src/prompt/skills.rsaddshome.join(".agents")alongsidegrok_home. That is why the shared skill is enough and no~/.grok/skills/heycopy 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.mdis 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/heyis.- 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/groknpm postinstall writes$GROK_HOME/bin), which is whyFindBinarylooks in the agent home'sbinafter PATH and~/.local/bin— for both rows. - A
.grok-plugin/plugin.jsonmanifest exists as a fallback behind a rootplugin.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 grokinstalls the shared skill;hey skill install, refresh,hey doctor,hey setup agents, and--removeall include Grok.HEY_SETUP_AGENTacceptsgrok, andallnow attempts every registered agent.- Grok is detected via
$GROK_HOME/~/.grokor agrokbinary on PATH,~/.local/bin, or the agent home'sbin. - 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.