dumbtv
dumbtv takes the ads, screen tracking and update nags out of your Fire TV over ADB. No root, none of your apps touched, every step can be undone. Free and open source.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Self-hosted team mesh control. No per-seat lock-in. A console on Headscale for workspaces, tags, keys, and Network Apps — people join with official Tailscale clients only.檢視完整 README ↗Self-hosted team mesh control. No per-seat lock-in. A console on Headscale for workspaces, tags, keys, and Network Apps — people join with official Tailscale clients only.
Website: robosushie.github.io/otterscale — features · deploy
Docs: docs/README.md · architecture · deployment · theme
{subdomain}.{APPS_BASE_DOMAIN} — HTTPS in front, traffic on 100.x. This is not Funnel.tailscale logout then tailscale up pointed at your login-server.The browser talks to the Otterscale console. Official Tailscale clients talk to Headscale (the coordinator). Edge (Caddy TLS + Go tsnet) publishes Network Apps onto mesh IPs.
Roles are Owner, Super admin, Admin, and Member. Workspaces isolate peers. Tags are labels (prod, uat, dev). Local login and TOTP are always on; OIDC buttons appear when issuer, client id, and client secret are set.
| Layer | Tools | Role |
|---|---|---|
| Console | Vite, React 19, Tailwind v4 | Static UI in packages/app |
| API | Go | packages/core: sessions, Headscale, SQLite or Postgres |
| Auth | Session cookie, Argon2id, TOTP, optional OIDC | Local login always on |
| Coordinator | Headscale 0.23 | Login-server, Noise, DERP map |
| Edge | Caddy, Go packages/edge (tailscale.com tsnet) | TLS + Network Apps hop |
| Clients | Official Tailscale apps | No custom VPN |
| Ship | Docker Compose, GHCR, GitHub Actions | Build, pull, Pages |
| Dev | pnpm 10, Node 22, TypeScript, Go 1.25, Vitest | CI console and CI Go |
Requires Node.js 22, pnpm 10.12.1, and an official Tailscale client to join a device.
Copy env and set secrets:
cp .env.example .env
Required: AUTH_SECRET (≥32 chars). DATABASE_URL may be empty (core creates a local SQLite file), a file:/sqlite: URL, or postgres://. Local auth is always on. Set AUTH_OIDC_ISSUER, AUTH_OIDC_CLIENT_ID, and AUTH_OIDC_CLIENT_SECRET to enable SSO.
Run the console and API:
pnpm dev
pnpm dev starts the Vite console. Run the Go API with go run ./cmd/core from packages/core (it applies migrations on startup).
Open /setup. Email, then username + password (min 8), then TOTP. The first account becomes Owner. Default tags: prod, uat, dev.
On Add device (/machines), run both printed commands. Login-server is OTTERSCALE_DOMAIN, or http://127.0.0.1:8080 when that env is unset:
tailscale logout
tailscale up --login-server=http://127.0.0.1:8080 --auth-key=<key>
Requires Docker and Compose.
pnpm deploy:stack
pnpm deploy:stack --keep-data
deploy:stack is the multi-container product (project otterscale). The default deletes that project's volumes and starts Headscale, then the init container, then the app and edge. --keep-data reuses those volumes. It generates AUTH_SECRET in .env when needed. Headscale API and edge pre-auth keys are minted onto the otterscale_secrets volume — not .env. Headscale only stores a hash, so plaintext cannot be read back from SQLite. Console: https://console.localhost.
One container (Caddy, Headscale, console, tsnet), project otterscale-standalone:
pnpm deploy:standalone
pnpm deploy:standalone --keep-data
Same wipe-or-keep rule, but only the standalone volume. Bootstrap writes keys under /data/secrets. The two products do not share volumes. Starting one stops the other so ports 80/443/8080 are free, and leaves the other product's volumes in place.
If *.localhost does not resolve:
127.0.0.1 console.localhost hs.localhost
Do not put HEADSCALE_API_KEY or APPS_EDGE_AUTHKEY in .env. APPS_EDGE_AUTHKEY is the pre-auth key the in-container tsnet proxy (tag:edge) uses to join this Headscale. Recreate with pnpm deploy:stack (or --keep-data if the secrets files are still on the volume).
pnpm deploy:stack and pnpm deploy:standalone build from this repo. They do not read OTTERSCALE_IMAGE_TAG.
Published images: ghcr.io/robosushie/otterscale/{headscale,core,app,edge,standalone}. Set OTTERSCALE_IMAGE_TAG to the tag from Actions → Publish GHCR. Unset, the pull files use latest. A semver tag also moves the Docker tag latest. Publishing the same tag again replaces those images. Pin AUTH_SECRET. Set OTTERSCALE_DOMAIN and AUTH_URL. The init container (stack) or the standalone entrypoint mints Headscale keys onto that product's volume.
Multi-container pull:
cp deployment/otterscale-stack.env.example .env
docker compose -f deployment/otterscale-stack.yaml --env-file .env up -d
One-container pull:
cp deployment/otterscale-standalone.env.example .env
docker compose -f deployment/otterscale-standalone.yaml --env-file .env up -d
Platform notes: deployment page.
Never commit .env. Copy from .env.example.
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL | No | Empty creates /data/otterscale.db. file:/sqlite: opens that file. postgres:// uses Postgres |
AUTH_SECRET | Yes | Session secret, ≥32 characters |
AUTH_URL | Production | Public console origin (https://console.localhost locally) |
AUTH_OIDC_ISSUER | Optional | OIDC issuer; SSO buttons stay off until all three OIDC vars are set |
AUTH_OIDC_CLIENT_ID | Optional | OIDC client id |
AUTH_OIDC_CLIENT_SECRET | Optional | OIDC client secret |
AUTH_SETUP_TOKEN | Yes for first-run | Required to create the first Owner on /setup. AUTH_SETUP_OPEN=1 allows that request only from a loopback TCP peer |
HEADSCALE_INTERNAL_URL | Docker | App → Headscale (http://headscale:8080) |
HEADSCALE_PUBLIC_URL | Docker | Public Headscale URL |
OTTERSCALE_DOMAIN | Production | Login-server for Add device (HTTPS). Unset → http://127.0.0.1:8080 |
OTTERSCALE_IMAGE_TAG | Production pull | GHCR tag for otterscale-stack.yaml and otterscale-standalone.yaml. Ignored by pnpm deploy:stack and pnpm deploy:standalone |
OTTERSCALE_IMAGE_PREFIX | Optional | Registry prefix. Default ghcr.io/robosushie/otterscale |
APPS_BASE_DOMAIN | Optional | Network Apps hostname suffix (default apps.localhost) |
Prereqs: Node 22, pnpm 10.12.1, Go 1.25, Docker for the stack.
| Command | Purpose |
|---|---|
pnpm dev | Vite console |
pnpm test | Vitest deploy contracts |
pnpm build | Vite production build |
pnpm deploy:stack | Wipe stack volumes, build, and run |
pnpm deploy:stack --keep-data | Rebuild stack on existing volumes |
pnpm deploy:standalone | Wipe standalone volume, build, and run |
pnpm deploy:standalone --keep-data | Rebuild standalone on existing volume |
docker compose -f deployment/otterscale-stack.yaml --env-file .env up -d | Pull GHCR stack images (OTTERSCALE_IMAGE_TAG) |
docker compose -f deployment/otterscale-standalone.yaml --env-file .env up -d | Pull GHCR standalone image (OTTERSCALE_IMAGE_TAG) |
Schema changes are goose SQL under packages/core/migrations. Core applies them on startup.
UI follows docs/theme.md: parchment canvas, Newsreader weight 400, IBM Plex Mono, one Lake Blue primary CTA.
Commits use conventional types: feat · fix · refactor · chore · docs · test · style. Pull requests must pass CI console, CI Go, and CI commits. Do not commit secrets.
Coding agents: AGENTS.md.
| Path | Purpose |
|---|---|
packages/app | Vite console |
packages/core | Go API, database, Headscale adapter |
packages/edge | Go tsnet Network Apps hop |
deployment/ | Compose, Caddy, Headscale, Dockerfiles |
site/ | GitHub Pages marketing site |
docs/ | Architecture, roadmap, deployment, theme |
tests/ | Vitest |
| Document | Purpose |
|---|---|
| docs/README.md | Doc index |
| Product overview | Vision, personas, scope |
| Architecture | Components, data model, flows |
| Roadmap | Delivery plan |
| Deployment | Images, topologies, operations |
| Security | Threat model, controls, audit integrity |
| Design theme | Console visual system |
| Design spec PDF | Source specification (draft v0.5) |
Treat the control plane like an identity provider: it decides who can reach what on the mesh. Details: docs/security.md. Never commit .env, API keys, or pre-auth keys.
GNU General Public License v3.0. You may run, study, and share Otterscale. If you distribute a modified version, you must also provide GPL-3.0 source. Selling is allowed; a closed-source fork is not.