SIGN IN SIGN UP

feat(grok): add first-class Grok Build integration (#81)

* feat: add first-class Grok Build (grok) integration

`hcom grok` (alias `grok-build`) launches Grok Build as an hcom agent with
automatic delivery, status, resume/fork and transcripts. hcom installs no
Grok hooks: Grok discards hook output on most events, so binding, status
and delivery all go through Grok's own ACP instead. `hcom hooks` and
`hcom status` list Grok as "no hooks".

Transport:
- The TUI runs against a private leader socket (`--leader --leader-socket
  <tmp>`). The delivery thread attaches a second client through the stdio
  bridge (`grok agent --leader --leader-socket <sock> stdio`), which handles
  framing and reconnects. hcom stops the leader once the TUI exits, since
  leaders run with --no-exit-on-disconnect and would outlive the agent.
- Leader flags are rejected (hcom owns the leader), as are --allow, --deny,
  --allowedTools, --disallowedTools and --disable-web-search, which Grok
  ignores in leader mode. --no-subagents reaches the leader as
  GROK_SUBAGENTS=0.

Binding:
- Every visible session in the leader roster belongs to the TUI. hcom loads
  each with noReplay and binds to the first one, then to any that newly
  appears idle (/new, /resume from disk). Switching to an already-open
  session emits nothing, so hcom follows that switch when a user prompt
  starts there. Subagent sessions never bind.
- A new launch gets `--session-id <uuid>`. Without it the TUI sits on its
  welcome screen over a hidden session and never draws turns queued there.
- The launch is ready only once the bound session has loaded. If the ACP
  connection or the session load keeps failing past the setup timeout, the
  launch is reported blocked with the error, and it clears to ready when
  the cause goes away.

Delivery:
- Each mailbox batch is queued as an ordinary prompt (sendNow:false) with
  an hcom-prefixed promptId. Nothing is typed into the composer, so user
  drafts are untouched, and a busy session runs the batch after its current
  work.
- A batch is acked only on evidence that it ran: its promptId running in
  x.ai/queue/changed, its exact text inside a merged turn, a prompt
  result, or the text in the session's updates.jsonl after a transport
  loss. A batch dropped before it ran stays unread and is queued again:
  at-least-once, never silently dropped.
- `hcom send` from a Grok agent no longer appends its unread messages
  inline; they may already be queued as a prompt and would show twice.
- The bootstrap goes in at launch via --rules (hook output never reaches
  the model), merged into any user --rules. hcom's --system-prompt is
  folded into --rules the same way.

Status:
- Taken from the bound session's broadcasts: queue turn starts, tool calls,
  turn ends (a stop reason other than end_turn/cancelled is
  failure:<reason>), and blocked while a permission, question or plan
  approval request is open. Approvals Grok decides itself never show as
  blocked. Subagents only report for the session that spawned them.
- With `hcom config auto_approve 1`, hcom's ACP client answers "allow once"
  for a single safe hcom shell command. Nothing is written to Grok's config.

Safe-command matching:
- New shared `is_safe_hcom_command` accepts exactly one `hcom <safe cmd>`
  (or `uvx hcom`) and rejects unquoted ; & | < > ( ), backticks, newlines
  and `$` outside single quotes. Copilot's permission handler now uses it,
  closing prefix-match approval of `hcom send @x -- hi; rm -rf ~`. Copilot
  applies it to POSIX shells only, not PowerShell.

Launch, resume, config:
- Rejected one-shot args: -p, --single, --prompt-file, --prompt-json.
- The initial prompt is passed after `--`, so a prompt that looks like a
  flag stays a prompt.
- Resume/fork use --resume / --fork-session. merge_grok_args drops session
  selectors, one-shot flags, --cwd, worktree flags and the old prompt, and
  keeps --rules, --model and the like. `hcom r <session-id>` finds sessions
  under $GROK_HOME/sessions and recovers the cwd from summary.json.
- New `grok_args` / HCOM_GROK_ARGS config. GROK_HOME is honoured for the
  config dir and isolated tool-config launches.
- Tool detection: GROK_SESSION_ID / GROK_HOOK_EVENT identify a Grok host,
  and GROK_AGENT marks its shell children for same-tool nested launches.

Transcripts:
- New parser for $GROK_HOME/sessions/<url-encoded cwd>/<id>/updates.jsonl.
  Turns end at turn_completed, and timestamps are carried into the
  timeline. `hcom transcript`, search --all and path detection all
  recognise it.

Also:
- hcom.log writes each line in one write_all, so concurrent processes stop
  gluing records together (`…}{…`).
- README, help, the agent-messaging skill and cross-tool.md document Grok.

---------

Co-authored-by: aannoo <aannoo@users.noreply.github.com>
K
kiala9 committed
84eb5823ac912f8bf19729702c857b7b7b6b19b6
Parent: e85efe4
Committed by GitHub <noreply@github.com> on 9/29/2026, 8:13:44 PM