run it
A terminal for any github repo, in the browser. Sign in with github, pick a repo, ask in plain words. Nothing is ever executed or written to github.
npm test runs vitest (grammar, preprocessing, providers, usage); npm run build builds for production.
first run
- Open http://localhost:3000. On a localhost dev server the first visit shows a one-time setup screen.
- Follow its link to a prefilled github oauth-app form and paste the client id and secret back.
- The screen writes them, a random
SESSION_SECRET, andAPP_URLtoweb/.env.local.
Sign-in asks for the repo scope so private repos appear in the picker; github has no read-only scope for private repos, and wh only ever reads.
hosted instances
The setup screen never appears in production or behind a proxy. A hosted instance without oauth configured says github oauth is not configured on this server; configure it through the environment below.
environment
web/.env.example has the same list.
| variable | meaning |
|---|---|
GITHUB_CLIENT_ID | oauth app; the callback must be $APP_URL/api/auth/callback |
GITHUB_CLIENT_SECRET | |
SESSION_SECRET | 32 or more random characters (openssl rand -hex 32) |
APP_URL | base url of this instance; https turns on secure cookies |
WH_ALLOWED_LOGINS | optional: github logins that may sign in, comma-separated |
GITHUB_API_URL | optional, for github enterprise (and GITHUB_GRAPHQL_URL) |
WH_ANTHROPIC_URL, WH_OPENAI_URL, WH_GROQ_URL | optional provider gateways, same names as the cli |
deploy
The app is stateless: no database, no volume. Keys and transcripts stay in each visitor's browser. Hosting it is one node process, or one container, and the environment above.
- Create a github oauth app (settings, developer settings, oauth apps) with the callback url set to exactly
$APP_URL/api/auth/callback. - Set
GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET,SESSION_SECRET, andAPP_URL. KeepSESSION_SECRETstable across restarts, or every session cookie dies with it. - Optionally set
WH_ALLOWED_LOGINS(comma-separated, case-insensitive). Unset, anyone with a github account can use the instance. Removing a login signs that account out on its next request.
behind a reverse proxy
APP_URL must be the public origin: it drives the oauth redirect uri, the same-origin guards, and the cookie secure flag. An https:// APP_URL sets secure cookies even though the node process speaks http; a mismatched scheme is the one way to break sign-in. Nothing trusts x-forwarded-* headers.
docker
Build from the repo root; the image needs ../shared/prompts.
sessions
- The session slides: every request renews it
- It ends after a week of silence or 30 days after sign-in, whichever comes first
- An ended session says so in the transcript;
sign in again →brings you back to the same repo with the transcript intact and reruns what failed
related
- What you can ask: the command grammar
- Keys, models, effort: how explanations are paid for