feat(types): add grok-build agent type (xAI Grok Build CLI)#216
Merged
Conversation
Add an agmsg agent type for xAI's official Grok Build CLI (binary 'grok',
x.ai/cli) so it can join a team alongside Claude Code, Codex, Gemini, Cursor,
and Hermes. Grok Build deliberately adopts Claude-Code-style conventions, so
this is a manifest + path/detect remap rather than new infrastructure — the
existing Stop-hook delivery script reads session_id from the hook input JSON on
stdin, which Grok Build emits the same way, so no env remap is needed.
- scripts/drivers/types/grok-build/{type.conf,template.md,_delivery.sh}: a
turn/off type (no Monitor-tool equivalent, so delivery_modes='turn off',
default turn). detect=GROK_SESSION_ID for whoami; cli=grok. The _delivery.sh
writes a dedicated .grok/hooks/agmsg.json (copilot model).
- install.sh: ship the skill to ~/.grok/skills/<name>/ and accept
--agent-type grok-build, both via the type registry.
- tests: grok-build delivery (turn/off/reject), install (skill drop +
--agent-type), join, and the registry's nine-built-ins count.
C-GATED (#214): the hook filename and JSON schema in _delivery.sh and the
delivery tests are the assumed Claude-Code shape — xAI's official schema page
was not directly fetchable. They are scaffolded and must be confirmed against a
real install with 'grok inspect' before release; everything else (manifest,
template, whoami detect, install placement, join) is schema-independent.
Confirmed the Grok Build hook contract against a real install (xAI local
docs ~/.grok/docs/user-guide/10-hooks.md) and finalize the type:
- _delivery.sh: write the confirmed nested Claude hook shape
{ hooks: { Stop: [ { hooks: [ { type:command, command:<abs>, timeout:N } ] } ] } }
at .grok/hooks/agmsg.json (no top-level version), command as the
absolute check-inbox.sh path. Replaces the provisional copilot-flat scaffold.
- session-start.sh / check-inbox.sh: resolve the session id from snake_case
session_id (Claude) -> camelCase sessionId (Grok Build / Cursor) ->
$GROK_SESSION_ID env. Additive and snake-first, so claude-code is unchanged.
Grok emits camelCase stdin, which previously degraded to a synthesized id
and broke per-session dedup (#93) and the delivery watermark.
- type.conf: spawnable=yes. spawn.sh already launches direct-CLI types via
`grok "/agmsg actas <name>"` and skips the readiness wait for monitor=no
types, so no spawn.sh change is needed.
- install.sh: infer grok-build on --update from an existing grok-typed SKILL.md.
- tests: nested hook shape, session-id resolution (camelCase / env / snake-wins),
status detection, --update inference, and grok-build in the spawnable set.
Refs #214.
Real-machine dogfood found Grok Build's passive hooks (SessionStart/Stop) discard their stdout — they cannot inject context. A Stop hook running check-inbox.sh would therefore deliver nothing while still marking messages read = silent loss. Grok's only delivery path is the agent reading a tool's output, so switch to the existing rule-file self-poll model (gemini/opencode): - _delivery.sh: write a .grok/rules/agmsg.md rule (which Grok always scans into context each turn) telling the agent to poll inbox.sh each turn. inbox.sh prints unread messages and marks them read in the same call the agent sees = loss-safe; check-inbox.sh's hook-control JSON and cooldown are wrong for agent-read tool output. - type.conf: hooks_file .grok/hooks/agmsg.json -> .grok/rules/agmsg.md. Rule files need no folder-trust (Grok's trust gate is for execution, not rules) and are read even outside a git repo, so spawn works with a plain launch. - template.md: describe turn mode as rule-driven self-poll. - tests: rule-file assertions; grok-build spawns the plain grok CLI (no flag). Session-id resolution (camelCase / GROK_SESSION_ID) and spawnable=yes are kept. Refs #214.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an agmsg agent type for xAI's official Grok Build CLI (binary
grok, from x.ai/cli), so Grok Build can join a team alongside Claude Code, Codex, Gemini, Cursor, and Hermes. Refs #214.Disambiguation: the target is the official xAI Grok Build terminal agent, not the unrelated community
superagent-ai/grok-cli.Delivery model — rule-file self-poll (confirmed on a real install)
Real-machine dogfood (xAI local docs
~/.grok/docs/) established that Grok Build's passive hooks (SessionStart/Stop) discard their stdout — they cannot inject anything into the conversation. A Stop hook runningcheck-inbox.shwould deliver nothing while still marking messages read = silent loss. So Grok delivers the same way as gemini / antigravity / opencode: a markdown rule file under<project>/.grok/rules/(which Grok always scans into context each turn) that tells the agent to poll its own inbox. The agent runs the check as a tool call and reads the output — the one delivery path Grok actually supports.inbox.sh(prints unread messages and marks them read in the same call the agent sees = loss-safe), not the hook-onlycheck-inbox.sh.What's in this PR
scripts/drivers/types/grok-build/—type.conf(cli=grok,detect=GROK_SESSION_ID,spawnable=yes,delivery_modes="turn off"defaultturn,hooks_file=.grok/rules/agmsg.md),template.md(the/agmsgSKILL), and_delivery.sh(writes the.grok/rules/agmsg.mdself-poll rule;agmsg_delivery_status= rule-file presence).scripts/session-start.sh/scripts/check-inbox.sh— session-id resolution now tries snake_casesession_id(Claude) → camelCasesessionId(Grok Build / Cursor) →$GROK_SESSION_ID. Additive and snake-first, so Claude Code is unchanged. (Forward-looking for Grok + Cursor compat.)install.sh— ships the skill to~/.grok/skills/<name>/SKILL.md, accepts--agent-type grok-build, and infersgrok-buildon--updatefrom an existing grok-typed SKILL.md.groklaunch), install (skill drop +--agent-type+--update), join, and the registry's nine-built-ins / spawnable set.Grok Build has no Monitor-tool equivalent (
monitor=no), so there is nomonitor/bothmode (turn = self-poll rule; off = manual).spawnworks via the existing direct-CLI launch (grok "/agmsg actas <name>"); spawn's readiness wait is skipped formonitor=notypes.Verification
grok inspectauto-loads.grok/rules/agmsg.mdas Project Instructions (no folder-trust). An authenticated grok session followed the rule —whoami.sh→ resolved its agent name →inbox.sh→ surfaced a teammate's message verbatim. Zero-delivery → reliable delivery confirmed.Note on per-turn approval: a headless
grok -prun needs--yoloto execute the inbox tool; an interactive (tmux) session prompts for approval each turn, the same feel as a spawned Claude Code agent. Pre-approving the inbox command via a Grok allow-rule is a possible follow-up (matching how the other rule-file types handle it).Closes #214.