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>
31 lines
1.2 KiB
TypeScript
31 lines
1.2 KiB
TypeScript
import { defineConfig } from "vite";
|
|
import react from "@vitejs/plugin-react";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
|
|
// The dev server proxies to a `glance serve` running on its default address.
|
|
//
|
|
// Going through the proxy rather than pointing the browser straight at :7717
|
|
// keeps the app same-origin in development, which is not cosmetic: the session
|
|
// cookie is `__Host-` prefixed and `SameSite=Strict`, so a cross-origin dev
|
|
// setup would never send it and every authenticated call would 401.
|
|
export default defineConfig({
|
|
plugins: [react(), tailwindcss()],
|
|
server: {
|
|
port: 5173,
|
|
proxy: {
|
|
// `ws: true` covers /api/ws and /api/acp/agent; both are upgrades, and a
|
|
// proxy that only forwards plain HTTP would fail the handshake.
|
|
"/api": { target: "http://127.0.0.1:7717", ws: true },
|
|
},
|
|
},
|
|
build: {
|
|
// Emptying is what keeps a stale bundle from being embedded after a rename;
|
|
// the Makefile restores web/dist/.gitkeep afterwards so `go build` still has
|
|
// a directory to embed.
|
|
emptyOutDir: true,
|
|
// The server sets `Cache-Control: immutable` on hashed assets only, so
|
|
// leaving the default hashed names in place is load-bearing.
|
|
chunkSizeWarningLimit: 900,
|
|
},
|
|
});
|