Fork of xenodrive/vis — an alternative web UI for OpenCode. This fork adds provider quota tracking, branch management, enhanced file tree, browser notifications, and a self-hosted proxy server.
From the original:
- Review-first floating windows keeping tool output and agent reasoning in context
- Session management with multi-project and worktree support
- Syntax-highlighted code and diff viewers
- Permission and question prompts for interactive agent workflows
- Embedded terminal powered by xterm.js
Fork additions:
- Provider Quota Viewer — real-time usage tracking for Claude, OpenAI, and Kimi via
/api/quota/* - Project Visibility Filter — filter the session dropdown by project
- Plugin Version Display — plugin versions shown in settings
- Branch Switcher — full git branch management (search, fork, delete, fetch, pull, push, merge/rebase)
- File Tree Improvements — git ls-files integration, status bar, reload, toggleable selection
- Floating Window Search — in-window text search using the CSS Custom Highlight API
- Bookmarks — bookmark sessions with toast feedback
- Browser Notifications — auto-close stale notifications, title badge, fallback transport
- SharedWorker Fallback —
directModeState.tshandles browsers without SharedWorker support - OpenCode Proxy Server — full HTTP + WebSocket proxy with CORS handling (
server/opencode-proxy.js,server/cors.js) - Quota API Server —
quota-api.jswith caching, auth file watching, and rate limit handling
Open the hosted version directly:
https://nguyentamdat.github.io/vis/
The hosted UI connects to your OpenCode server via CORS. Allow the origin:
opencode serve --cors https://nguyentamdat.github.ioOr in ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"server": {
"cors": ["https://nguyentamdat.github.io"]
}
}Runs Vite dev server with a built-in proxy to avoid CORS issues:
OPENCODE_BASE_URL=http://localhost:4096 bun devOpen http://localhost:3000. All OpenCode requests go through /api/opencode-proxy.
Build first, then serve from dist/:
bun run build
node server.js
# or
bun server.jsThe server proxies OpenCode API and WebSocket traffic. Configure with environment variables below.
docker compose -f docker-compose.tailscale.yml upOr build manually with the included Dockerfile.
For WebSocket support through Tailscale, use --tls-terminated-tcp instead of --https when configuring tailscale serve. Tailscale's --https mode negotiates HTTP/2, which does not support the 101 Switching Protocols upgrade needed for WebSocket.
# Correct — raw TCP with TLS termination (supports WebSocket)
tailscale serve --bg --tls-terminated-tcp=3456 3456
# Wrong — HTTP/2 breaks WebSocket upgrade
# tailscale serve --bg --https=3456 3456Bind Vis to 127.0.0.1 only and let Tailscale handle TLS:
VIS_HOST=127.0.0.1 VIS_PORT=3456 OPENCODE_BASE_URL=http://localhost:4095 NODE_ENV=production node server.jsA systemd user service at ~/.config/systemd/user/vis-server.service works well for persistent deployment. See start-tailscale-internal.sh for a script-based alternative.
Forward requests to a remote Vis instance:
bun run server.js proxy https://your-vis-host| Variable | Default | Description |
|---|---|---|
OPENCODE_BASE_URL |
http://localhost:4096 |
OpenCode server URL |
VIS_PORT |
3000 |
Server port |
VIS_HOST |
127.0.0.1 |
Server bind address |
VIS_CORS_ORIGINS |
— | Comma-separated allowed origins for proxy CORS |
VIS_CORS_ALLOW_ANY |
— | Set to true to allow any origin |
VIS_ALLOWED_HOSTS |
— | Comma-separated Vite dev server allowed hosts |
NODE_ENV |
— | Set to production for production mode |
bun install
bun dev # dev server with proxy
bun run build # production build to dist/Built on top of Vis by kikuchan / Xenodrive. Thanks for the excellent foundation.
MIT