Files
iceBear67andClaude Opus 5 051efe8fec grok-glance: web control plane for grok's /rc remote control
A single Go binary that grok dials out to over a WebSocket, and a HeroUI
web UI for driving the session it is attached to.

The roles are inverted relative to the terminal: over the /rc link grok
is the ACP Agent and glance is the Client. That makes glance a stock ACP
client and the web Stop button a real session/cancel rather than a
bespoke control message.

Both notification rails are mirrored. The stable session/update rail
carries correctness; x.ai/session_notification is presentation only and
degrades rather than erroring, because its ~60 variants are grok
internal and drift with every upstream sync. _meta is forwarded
byte for byte so viewers can dedup and order.

Permissions race: the terminal and any browser may answer, first
responder wins, and the loser's UI retracts by itself. All three
interaction methods go through that path, not just permissions.

Auth is TOTP only, with no accounts to have. A bootstrap token printed
at first start gates /setup, which is a 404 without it; state lives in
one 0600 JSON file and history in an in-memory ring, so there is no
database and no recovery story beyond deleting the file.

ARCHITECTURE.md covers the topology and the limits of that auth model;
CLAUDE.md covers building, the fakeagent loop, and the end-to-end
checklist that unit tests cannot replace.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 10:07:33 +00:00

116 lines
3.8 KiB
Makefile

# grok-glance
#
# Two build systems, one binary: the frontend is compiled by Vite into web/dist
# and then embedded by `go build`. That ordering is not optional — `//go:embed`
# resolves at compile time, so a Go build always ships whatever `make web` last
# produced.
GO ?= go
NPM ?= npm
ADDR ?= :7717
BIN := bin/glance
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
LDFLAGS := -X main.version=$(VERSION)
# Vite's dev server. Its proxy sends /api to the Go server, which is what keeps
# the `__Host-` session cookie working in development: the cookie is
# SameSite=Strict and would never be sent cross-origin.
WEB_PORT ?= 5173
.PHONY: all
all: build
# ── build ────────────────────────────────────────────────────────────────────
.PHONY: build
build: web
@mkdir -p bin
$(GO) build -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/glance
@echo "built $(BIN) ($(VERSION))"
## Go binary without rebuilding the frontend — fast loop for server work.
.PHONY: server
server:
@mkdir -p bin
$(GO) build -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/glance
.PHONY: web
web: web/node_modules
cd web && $(NPM) run build
# Vite empties dist/ on every build, taking the .gitkeep with it. The file is
# what lets `go build` succeed on a clean clone that has never run npm, so it
# has to come back or the next contributor gets an unexplainable embed error.
@touch web/dist/.gitkeep
web/node_modules: web/package.json
cd web && $(NPM) install
@touch web/node_modules
# ── development ──────────────────────────────────────────────────────────────
## Go server + Vite with hot reload. Open http://localhost:$(WEB_PORT).
.PHONY: dev
dev: server web/node_modules
@echo "glance on $(ADDR), UI on http://localhost:$(WEB_PORT)"
@trap 'kill 0' EXIT INT TERM; \
$(BIN) serve --addr $(ADDR) & \
cd web && $(NPM) run dev -- --port $(WEB_PORT); \
wait
## Run the built binary against the embedded UI (production shape).
.PHONY: run
run: build
$(BIN) serve --addr $(ADDR)
## A fake grok on the agent socket -- UI work without rebuilding Rust.
## KEY comes from `glance apikey add dev`, or $$GLANCE_API_KEY.
KEY ?= $(GLANCE_API_KEY)
.PHONY: fakeagent
fakeagent:
$(GO) run ./cmd/fakeagent --key "$(KEY)"
# ── checks ───────────────────────────────────────────────────────────────────
.PHONY: test
test:
$(GO) test ./...
.PHONY: vet
vet:
$(GO) vet ./...
.PHONY: typecheck
typecheck: web/node_modules
cd web && $(NPM) run typecheck
.PHONY: fmt
fmt:
$(GO) fmt ./...
## Everything CI would run.
.PHONY: check
check: vet test typecheck
# ── housekeeping ─────────────────────────────────────────────────────────────
.PHONY: clean
clean:
rm -rf bin web/dist
@mkdir -p web/dist && touch web/dist/.gitkeep
.PHONY: distclean
distclean: clean
rm -rf web/node_modules
.PHONY: help
help:
@echo "grok-glance targets:"
@echo " make build frontend + binary -> $(BIN)"
@echo " make dev Go server + Vite dev server (hot reload)"
@echo " make run build, then serve on $(ADDR)"
@echo " make fakeagent connect a fake grok (KEY=glance_sk_...)"
@echo " make web frontend only"
@echo " make server binary only (keeps the last frontend build)"
@echo " make check vet + go test + tsc"
@echo " make clean drop bin/ and web/dist"