#cloud-config users: - name: grok shell: /bin/bash sudo: "ALL=(ALL) NOPASSWD:ALL" lock_passwd: true write_files: - path: /home/grok/.grok/AGENTS.md owner: "grok:grok" permissions: '0644' defer: true content: | # You are running inside a box (template: grok) A box is a trust-less, network-isolated, ephemeral VM created by the `box` CLI. Keep this context in mind: - **Creds-free by default.** The box starts with no xAI and no git credentials. If you need to authenticate, the operator runs `grok-build login` interactively (SuperGrok / X Premium+). For git, the operator adds their own credentials (a PAT or `gh auth login`). Never assume credentials are present; never ask for or store secrets on disk beyond what the operator sets up. - **Isolated.** The box reaches the public internet but nothing on the host or local network. There is no inbound path. - **Disposable.** Nothing here is backed up. State is discarded when the box is removed; the operator persists work via git push and via `box snapshot`. - **Bootstrap runbook.** If the repository you are working in contains a `.box/` folder (older repos may use `.claudebox/`), read it as your setup runbook — how to install dependencies, start services, template environment files, seed data, and smoke-test — and follow it. It is documentation for you, not a script the host runs. package_update: true packages: - git - gh - curl - ca-certificates - gnupg - ripgrep - jq - tmux - age - unzip - build-essential runcmd: - curl -fsSL https://get.docker.com | sh - usermod -aG docker grok # Grok Build's official installer (verified upstream: x.ai/cli). It drops the # binary under the invoking user's home, so run it AS grok, not root. - sudo -u grok bash -lc 'curl -fsSL https://x.ai/cli/install.sh | bash' # 'box exec -- grok-build …' runs a NON-interactive shell that reads no # rc files, so whatever the installer dropped must be symlinked onto the # system PATH — the same fix the claude template needed (#15). # # The FIRST cut of this hunted only for a regular file named exactly # 'grok-build' under /home/grok, and found nothing: the drill's grok box # minted fine and then failed '--version'. Two lessons, both applied here: # an installer's drop may be a SYMLINK (so -type f alone misses it), and its # binary name is upstream's to choose (so try the plausible names, and any # 'grok*' executable, before giving up). Then SAY what was found — a silent # miss is what cost the last run. - | bin="" for cand in grok-build grok; do for d in /home/grok/.local/bin /home/grok/.grok/bin /home/grok/bin /usr/local/bin /opt; do [ -x "$d/$cand" ] && { bin="$d/$cand"; break 2; } done done [ -n "$bin" ] || bin="$(find /home/grok /opt -maxdepth 5 \( -type f -o -type l \) -iname 'grok*' -perm -u+x 2>/dev/null | head -1)" if [ -n "$bin" ]; then ln -sf "$bin" /usr/local/bin/grok-build ln -sf "$bin" /usr/local/bin/grok echo "grok: linked $bin -> /usr/local/bin/{grok-build,grok}" else echo "grok: NO BINARY FOUND after x.ai/cli/install.sh — the box is up but the CLI is not on PATH." >&2 echo "grok: what the installer left under /home/grok:" >&2 find /home/grok -maxdepth 4 \( -type f -o -type l \) -perm -u+x 2>/dev/null | head -20 >&2 fi - echo 'export PATH="$HOME/.local/bin:$PATH"' >> /home/grok/.bashrc