Voltar às atualizações
New releaseJul 14, 2026

phone-deck v3.0.1

Plataforma de controle auto-hospedada e área de trabalho remota para estações de trabalho Linux via Tailscale, com streaming WebRTC, controle por voz com LLM local, macros de cena, entrada virtual, transferência de arquivos e telemetria de sistema ao vivo.

Compartilhar

phone-deck

Transforme um telefone Android sobressalente (ou qualquer dispositivo com navegador) em um painel de controle auto-hospedado e área de trabalho remota para sua estação de trabalho Linux — através de sua rede Tailscale privada, sem aplicativos de terceiros.

Começou como "o que fazer com um telefone antigo?" e se tornou um plano de controle para um rig Hyprland: controle de janela/workspace, macros de cena, um roteador de voz push-to-talk com assistente LLM local, controles contextuais no aplicativo, áudio bidirecional + streaming de tela, uma área de trabalho remota por toque, um teclado/mouse virtual, transferência de arquivos + compartilhamento telefone→PC, e telemetria ao vivo — tudo servido como um PWA instalado com aparência de terminal fósforo.

Nota sobre portabilidade. Isto foi construído para uma configuração específica: Linux baseado em Arch (Garuda) + Hyprland + PipeWire + NVIDIA + Tailscale, com os dotfiles end-4 / illogical-impulse. A arquitetura é genérica, mas várias integrações são específicas do ambiente (nomes de monitores, vinculações de workspaces, o caminho do tema matugen, cpupower/nvidia-smi). Trate como uma referência funcional para adaptar, não um pacote chave na mão.


Funcionalidades

A interface é um aplicativo web com abas, escuro, em modo paisagem (sincronizado com o tema do seu desktop):

AbaO que faz
WorkspacesGrade de workspaces ao vivo por monitor (toque para alternar), lista de janelas ao vivo (toque para focar), alternância DPMS por monitor + brilho ddcutil
RemoteTouchpad na tela (arrastar/tocar/dois dedos) + teclado virtual com modificadores e combinações, via dispositivo uinput do kernel
ModesMacros de cena com um toque — iniciar/fechar/organizar layouts completos de aplicativos entre monitores (ex: 'Trabalho' / 'Lazer')
VoiceRoteador de voz push-to-talk (faster-whisper, CPU): faixas de palavra-chave — macro (executar um modo/comando), type (ditar), input (frase → acorde de teclas) — com confirmar-antes-executar, mais "friday", um respondedor LLM local somente leitura (Ollama + Qwen) com pesquisa web auto-hospedada e consciência de estado do sistema ao vivo
AudioMudo de microfone/auto-falante, volume, seletores de dispositivo de saída e entrada, transporte playerctl + capa do álbum (rastreia o player MPRIS ativo)
StreamÁudio WebRTC bidirecional (PC↔telefone, com telefone como microfone e saída apenas no telefone) + vídeo da tela, e toque para controlar a tela transmitida = uma verdadeira área de trabalho remota
SystemAlternância de modo de desempenho, troca de tema ao vivo, status do Tailscale, principais processos (toque para matar), bloqueio, reiniciar NetworkManager, suspender/reiniciar/desligar
FilesCaptura de tela de um monitor → visualizar/baixar no telefone; soltar um arquivo telefone→PC
ConfigEditar as configurações commands.json / modes.json (e contexto/voz) do telefone (validado JSON)

Sempre ativa, acima das abas — uma faixa de contexto que mostra o que está acontecendo agora: uma chamada ativa (mudo / pule para ela), mídia reproduzindo agora + transporte, e controles de teclado no aplicativo para o aplicativo focado (YouTube / Brave / Teams), entregues sem roubar o foco.

Dois recursos adicionais, além das abas:

  • Send-to-Rig — o PWA se registra como um destino de compartilhamento do Android: compartilhe uma imagem, um texto ou um link de qualquer aplicativo no seu telefone e ele chega ao rig — imagens salvas em um diretório de drop e colocadas na área de transferência como PNG pronto para colar, texto na área de transferência, um link simples aberto.
  • Ambient Cogitator — após alguns minutos de inatividade, o painel se torna um painel de instrumentos fósforo: telemetria com mostrador de agulha e pico retido ("esteve no máximo enquanto eu estava longe?"), relógio, reprodução agora.

Além disso: login com PIN numérico na tela, wake-lock de tela, PWA em tela cheia paisagem e bloqueio de força bruta no login.


Arquitetura

   phone / laptop (browser PWA)
            │  HTTPS + WSS  (Tailscale-only)
            ▼
   tailscale serve  ──►  FastAPI web app   ── Unix socket ──►  deckd
   (real TLS cert)       (runs as your user)   (action names)   (runs as root)
                              │                                  │
              hyprctl · pactl · ddcutil · grim ·          fixed allowlist of
              wf-recorder · uinput · WebRTC               privileged commands
                                                          (cpupower, nvidia-smi,
                                                           systemctl, …)

Dois processos:

  • app/ — o aplicativo web é executado como seu usuário normal. Ele faz tudo que não precisa de root: controle do Hyprland, áudio, brilho, captura de tela, entrada virtual, streaming WebRTC, transferência de arquivos.
  • deckd/ — um pequeno helper root (apenas stdlib, sem dependências) para as poucas ações privilegiadas. O aplicativo web nunca envia strings de shell para ele — apenas nomes de ações de uma lista de permissões fixa (governor_performance, gpu_power_limit, suspend, …), validados em deckd/actions.py antes de qualquer execução. Mesmo que o aplicativo web seja totalmente comprometido, o raio de explosão é exatamente as ações permitidas, sem injeção de argumentos. O socket é root:<group> modo 0660.

Modelo de segurança

  • Acessível apenas dentro da sua tailnet — tailscale serve expõe no seu nome MagicDNS com um certificado Let's Encrypt real; nunca liga em 0.0.0.0.
  • JWT login (PIN → cookie assinado), com bloqueio com backoff exponencial após falhas repetidas.
  • Ações privilegiadas são isoladas atrás do daemon helper com lista de permissões.
  • Uploads são sanitizados por basename (não podem escapar do diretório de drop).

Nota: O aplicativo web pode executar seus comandos de shell configurados e injetar entrada como seu usuário — é, por design, um controle remoto para sua máquina. Mantenha-o em sua tailnet, atrás do PIN, e não o exponha publicamente.


Requisitos

  • Linux com Hyprland (wlroots), PipeWire (com compatibilidade pactl/PulseAudio)
  • Python ≥ 3.11 e uv
  • Tailscale (com certificados HTTPS habilitados para sua tailnet)
  • Ferramentas CLI usadas por vários recursos (instale o que deseja usar): hyprctl, pactl / pw-record / pw-play, playerctl, ddcutil, wf-recorder, grim, cpupower, nvidia-smi, kitty (ou seu terminal)
  • Seu usuário no grupo input (para /dev/uinput) e i2c (para ddcutil)
  • aiortc + PyAV (instalado via uv) para streaming de áudio/vídeo

Instalação

git clone <your-repo-url> phone-deck
cd phone-deck
uv sync                          # creates .venv and installs dependencies
uv run python -m app.set_pin     # set your unlock PIN

1. O helper root (deckd)

Edite systemd/deckd.service primeiro — defina os caminhos e DECK_SOCKET_GROUP para um grupo ao qual seu usuário pertence (geralmente seu grupo primário):

sudo cp systemd/deckd.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now deckd

deckd é executado com o Python do sistema (apenas stdlib — sem necessidade de venv).

2. O aplicativo web

Execute diretamente para desenvolvimento:

uv run uvicorn app.main:app --host 127.0.0.1 --port 8765

Categorias