Files
grok-glance/skills/glance/SKILL.md
T
iceBear67andClaude Opus 5 3cfa011d0c Ship prebuilt, so a git URL is the whole install
Grok Build loads plugins out of ~/.grok/plugins/ and clones marketplace sources
straight from git; it never runs npm install or a build for you. So a plugin that
ships TypeScript is a plugin you have to build by hand before it does anything,
and the SessionStart hook's first act is to print "not built yet".

dist/ is now committed, and the tree is arranged so that a bare clone can run:

- The daemon is bundled to a single ESM file with rolldown, platform node. Its one
  runtime dependency (@simplewebauthn/server, plus the asn1/cbor tree under it) is
  inlined; the only imports left in the output are node: builtins. Not minified —
  a committed blob nobody can read is worse than no committed blob.
- tsc no longer emits for the server, it only typechecks (noEmit). rolldown emits.
- dist/web was already a self-contained static bundle.
- The hook scripts under bin/ were stdlib-only from the start.

.grok-plugin/marketplace.json makes the repo its own one-entry catalog with a local
source of "./", so `grok plugin marketplace add <git-url>` followed by
`grok plugin install grok-glance` works without pinning a SHA of itself.

`npm run check:dist` rebuilds and fails if the committed output is stale — the one
real hazard of checking in build output.

Also drops the daemon's "non-default port, run `glance sync-hooks`" startup note,
which the previous commit should have taken with the rest of that scheme; the hook
scripts read config.json themselves, so a non-default port needs nothing.

The e2e suite now takes GLANCE_ROOT and was run twice: once against the repo, once
against a copy containing only tracked files plus dist/ and no node_modules — which
is what actually demonstrates the claim, passkey registration and assertion
included. 233 checks, both runs green.

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

108 lines
5.0 KiB
Markdown

---
name: glance
description: 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 is started automatically by the `SessionStart` hook. 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
```sh
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:
```sh
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.