Files
grok-glance/skills/glance/SKILL.md
T
iceBear67andClaude Opus 5 966133eeda Start the daemon from whichever hook fires first
A plugin's SessionStart hook never runs, so nothing was starting the
daemon: no daemon.log, nothing on :8791, and a manual `glance up`
working perfectly.

Grok Build dispatches SessionStart from inside session creation
(xai-grok-shell, agent_ops.rs -> DispatchSessionStartHook) and resolves
it against the session's hook registry as it stands at that moment.
That registry comes from discover_hooks(), whose sources are the config
layers and the global/project settings files; plugin directories are not
among them. Plugin hooks are appended later, under a plugin/ prefix, by
reload_hooks_impl and reload_plugins_impl - which run in response to a
plugin action, a /hooks reload, or a folder-trust grant. So the entry is
always registered after the event it subscribes to has been dispatched.
The other thirteen events work because they happen later in the session.

There is no boot event to move to, so every recorder boots the daemon
instead and whichever fires first wins. The cost is one loopback request
to /healthz per event once it is up, which is the steady state. A
daemon.lock (O_EXCL, 15s staleness takeover) keeps a burst of concurrent
events from starting five daemons and leaving four to die on EADDRINUSE.

glance-up.mjs stays wired: it costs nothing when it does not fire, and
it is the right hook for the job if that ordering is ever fixed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 08:04:03 +00:00

5.3 KiB

name, description
name description
glance Set up, inspect, or control grok-glance — the passkey-guarded phone dashboard for this Grok Build session. Use when the user asks to watch one or several sessions from their phone, enrol a device, expose the dashboard over Tailscale, or turn remote approve/deny on or off.

grok-glance

A local daemon plus web dashboard that shows what Grok Build is doing, readable from a phone behind a WebAuthn passkey. It can also pause risky tool calls until someone taps approve.

One daemon covers every session on the machine, so several agents running at once all appear on the same dashboard — no per-session setup.

The daemon starts itself: every recording hook boots it if it is not already up, so the first prompt or tool call of a session brings it back. (Not the SessionStart hook — a plugin's SessionStart entry is registered after the event has already fired, so it never runs. If someone reports an empty :8791 and no daemon.log, that is the reason, and any hook firing will fix it.)

Everything below is done through the glance CLI at $GROK_PLUGIN_ROOT/bin/glance.

No build step

The plugin ships prebuilt: dist/ is committed, and the daemon is a single dependency-free bundle. A clone is ready to run. Only reach for npm install && npm run build in $GROK_PLUGIN_ROOT if glance status actually says it is not built, which means dist/ was deleted from the checkout.

The commands

glance status                      # is it running, which origin, how many devices
glance up                          # start the daemon in the background
glance stop                        # stop it
glance logs                        # last 60 lines of the daemon log
glance enroll                      # mint a one-time code + URL for a new phone
glance set-origin <https-url>      # set the public origin and WebAuthn RP ID
glance devices                     # list enrolled devices
glance revoke <id-prefix>          # revoke one
glance approval <off|risky|all>    # remote approve/deny policy

Watching several agents

Nothing to configure — every session that runs the hooks shows up. glance status reports the roster and what each agent is doing:

  sessions      : 4 (1 waiting on you, 1 error, 2 working)

Points worth passing on to the user:

  • Agents are identified by a coloured badge (●1, ●2) as well as the workspace name, because two agents in the same repo carry the same label. The badge is stable across daemon restarts.
  • The list is ordered by who needs attention (waiting → error → working → idle → ended) and never re-sorts underneath a tap.
  • Approval cards say which agent is asking; with approval risky on and several agents, expect several cards.
  • One noisy agent will not push the others out of the timeline — the event ring is trimmed from whichever session is using the most of it.

Getting it onto a phone

The dashboard listens on 127.0.0.1 only. Passkeys need a real hostname with valid TLS — a bare IP can never be a WebAuthn RP ID — so the supported path is Tailscale Serve:

tailscale serve --bg 127.0.0.1:8791
tailscale serve status                      # read the https://<box>.<tailnet>.ts.net URL
glance set-origin https://<box>.<tailnet>.ts.net
glance enroll

Then open the printed URL on the phone, type the code, and create the passkey. The phone must be on the same tailnet.

Changing the origin changes the RP ID, which invalidates existing passkeys. Say so before running set-origin on a working setup.

Remote approve/deny

glance approval risky makes Bash, Write, Edit, MultiEdit and NotebookEdit calls pause and wait for a tap on the phone. Defaults that matter:

  • Nothing waits unless a phone is actually watching the dashboard (requireWatcher).
  • If nobody answers within 90s the call is allowed, not denied. Flip that on the phone's settings panel if you want the opposite.
  • Every failure path is fail-open: daemon down, timeout, bad JSON, a rejected hook secret — the tool call proceeds. This is a convenience gate, not a security boundary.

glance approval off (the default) means Grok Build never blocks on the phone.

When something does not work

  • "not running"glance up, then glance logs.
  • Passkey prompt fails with a security error → the phone is on a hostname the RP ID does not cover. Compare glance status's rp id with the hostname in the phone's address bar.
  • Dashboard loads but shows nothing → hooks are not firing. glance status warns if the hook secret in $GLANCE_HOME/hook.secret no longer matches the one the daemon loaded (events are being dropped with a 403); glance stop && glance up fixes that. Otherwise check that hooks/hooks.json exists and that the plugin is registered with Grok Build.
  • Page says "run npm install && npm run build"dist/web is missing from the checkout, which should not happen in a clone. Re-clone, or build it.
  • Only one agent shows up → the others were started before the plugin was installed, or in an environment where the hooks are not registered. A session appears on its next hook event; nothing can be back-filled for one that already ran.

What it deliberately does not do

Read-only plus approve/deny. It cannot send prompts, edit files, run tools, or resume a session. Do not tell the user otherwise.