Torna agli aggiornamenti
New releaseJul 14, 2026

phone-deck v3.0.1

Pannello di controllo self-hosted e desktop remoto per workstation Linux tramite Tailscale, con streaming WebRTC, controllo vocale con LLM locale, macro di scena, input virtuale, trasferimento file e telemetria di sistema in tempo reale.

Condividi

phone-deck

Trasforma un vecchio telefono Android (o qualsiasi dispositivo con un browser) in un pannello di controllo self-hosted e desktop remoto per la tua workstation Linux — sulla tua rete Tailscale privata, senza app di terze parti.

È iniziato come "cosa faccio con un vecchio telefono?" ed è diventato un piano di controllo per un setup Hyprland: controllo di finestre/workspace, macro di scena, un router vocale push-to-talk con un assistente LLM locale, controlli contestuali nell'app, streaming audio+video bidirezionale, un desktop remoto tattile, una tastiera/mouse virtuali, trasferimento file + condivisione telefono→PC, e telemetria live — tutto servito come una PWA installata con un aspetto da terminale fosforico.

Nota sulla portabilità. Questo è stato costruito per una configurazione specifica: Arch-based Linux (Garuda) + Hyprland + PipeWire + NVIDIA + Tailscale, con i dotfiles end-4 / illogical-impulse. L'architettura è generica, ma diverse integrazioni sono specifiche dell'ambiente (nomi dei monitor, binding dei workspace, il percorso del tema matugen, cpupower/nvidia-smi). Trattalo come un riferimento funzionante da adattare, non un pacchetto già pronto.


Caratteristiche

L'interfaccia è un'app web scura, a schede, in orizzontale (sincronizzata con il tema del desktop):

SchedaCosa fa
WorkspaceGriglia di workspace live per monitor (tocca per cambiare), elenco finestre live (tocca per mettere a fuoco), attivazione/disattivazione DPMS per monitor + luminosità con ddcutil
RemotoTrackpad sullo schermo (trascina/tocca/due dita) + tastiera virtuale con modificatori e combinazioni, tramite un dispositivo kernel uinput
ModalitàMacro di scena con un tocco — avvia/chiudi/disponi interi layout di app su più monitor (es. "Lavoro" / "Libero")
VoceRouter vocale push-to-talk (faster-whisper, CPU): corsie di parole chiave — macro (esegui una modalità/comando), type (dettatura), input (frase → combinazione di tasti) — con conferma prima dell'esecuzione, più "friday", un risponditore LLM locale in sola lettura (Ollama + Qwen) con ricerca web self-hosted e consapevolezza dello stato live del sistema
AudioDisattivazione microfono/altoparlante, volume, selettori dispositivi di uscita e ingresso, trasporto playerctl + copertina album (traccia il player MPRIS attivo)
StreamAudio WebRTC bidirezionale (PC↔telefono, con telefono come microfono e uscita solo telefono) + video dello schermo, e tocca per controllare lo schermo in streaming = un vero desktop remoto
SistemaAttivazione/disattivazione modalità prestazioni, cambio tema live, stato Tailscale, processi principali (tocca per uccidere), blocco, riavvio NetworkManager, sospensione/riavvio/spegnimento
FileScreenshot di un monitor → visualizza/scarica sul telefono; trascina un file telefono→PC
ConfigurazioneModifica la configurazione commands.json / modes.json (e contesto/voce) dal telefono (convalidata JSON)

Sempre visibile, sopra le schede — una barra contestuale che mostra cosa sta succedendo in tempo reale: una chiamata attiva (silenzia / vai ad essa), media in riproduzione + trasporto, e controlli tastiera in-app per l'app focalizzata (YouTube / Brave / Teams), forniti senza rubare il focus.

Due altre, oltre le schede:

  • Send-to-Rig — la PWA si registra come destinazione di condivisione Android: condividi un'immagine, del testo o un link da qualsiasi app sul tuo telefono e atterra sul rig — le immagini vengono salvate in una directory di drop e poste negli appunti come PNG pronto per l'incolla, il testo negli appunti, un link nudo aperto.
  • Ambient Cogitator — dopo alcuni minuti di inattività, il deck diventa un pannello strumenti fosforico: telemetria con lancette e tenuta del picco ("è stato al massimo mentre ero via?"), orologio, ora in riproduzione.

In più: login PIN con tastierino numerico sullo schermo, wake-lock dello schermo, PWA a schermo intero orizzontale, e blocco anti-forza bruta sul login.


Architettura

   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, …)

Due processi:

  • app/ — l'app web viene eseguita come utente normale. Fa tutto ciò che non necessita di root: controllo Hyprland, audio, luminosità, cattura schermo, input virtuale, streaming WebRTC, trasferimento file.
  • deckd/ — un piccolo helper root (solo stdlib, nessuna dipendenza) per le poche azioni privilegiate. L'app web non gli invia mai stringhe di shell — solo nomi di azioni da una allowlist fissa (governor_performance, gpu_power_limit, suspend, …), convalidata in deckd/actions.py prima che qualsiasi cosa venga eseguita. Anche se l'app web fosse completamente compromessa, il raggio di esplosione è esattamente le azioni consentite, senza iniezione di argomenti. Il socket ha modalità root:<gruppo> 0660.

Modello di sicurezza

  • Raggiungibile solo all'interno della tua tailnet — tailscale serve lo espone sul tuo nome MagicDNS con un certificato Let's Encrypt reale; non si lega mai a 0.0.0.0.
  • Login JWT (PIN → cookie firmato), con blocco a backoff esponenziale dopo fallimenti ripetuti.
  • Le azioni privilegiate sono isolate dietro il demone helper con allowlist.
  • I caricamenti sono sanificati per basename (non possono uscire dalla directory di drop).

L'app web può eseguire i tuoi comandi shell configurati e iniettare input come tuo utente — è, per progettazione, un controllo remoto per la tua macchina. Tienilo nella tua tailnet, dietro il PIN, e non esporlo pubblicamente.


Requisiti

  • Linux con Hyprland (wlroots), PipeWire (con compatibilità pactl/PulseAudio)
  • Python ≥ 3.11 e uv
  • Tailscale (con certificati HTTPS abilitati per la tua tailnet)
  • Strumenti CLI usati da varie funzionalità (installa quelli che vuoi usare): hyprctl, pactl / pw-record / pw-play, playerctl, ddcutil, wf-recorder, grim, cpupower, nvidia-smi, kitty (o il tuo terminale)
  • Il tuo utente nel gruppo input (per /dev/uinput) e nel gruppo i2c (per ddcutil)
  • aiortc + PyAV (installati tramite uv) per lo streaming audio/video

Installazione

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. L'helper root (deckd)

Modifica prima systemd/deckd.service — imposta i percorsi e DECK_SOCKET_GROUP su un gruppo a cui appartiene il tuo utente (di solito il tuo gruppo principale):

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

deckd utilizza il Python di sistema (solo stdlib — nessun venv necessario).

2. L'app web

Esegui direttamente per sviluppo:

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

Categorie